7 segment 4 digits with PIC 16F877

Thread Starter

pronto

Joined Nov 6, 2017
12
Hi everyone, i made a program in assembly langage with the pic 16F877 to control the speed and position of a stepper motor bipolar
the code work fine but when i want to count the numbers of turn of the stepper motor, it stop in the value '255' and restart from '0'. I want to count from 0 to 999. i'm putting the code right there if any one can help me please.
Sorry the comments are in french

Code:
    list        p=16f877A    ; list directive to define processor
    #include    <p16f877A.inc>    ; processor specific variable definitions
   
    __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON & _RC_OSC & _WRT_OFF & _LVP_ON & _CPD_OFF



;*************************** ASSIGNATION*************************************
INTCONVAL EQU 0xC0        ; 1100 0000

;*************************** VARIABLE *************************************
    CBLOCK     0x30
    COMPT1
    COMPT2
    COMPT3
    COMPT4 
    COMPT5 
    RECHARGE
    w_temp 
    status_temp
    COMP
    RECH
    RESULTAT
    RE
    CO
    RESUL
    CT1,CT2,CT3,         ; compteur pour les temporisation 
    COMPT_CONV            ; registre de conversion 
    UNI,DECI,CENTI,        ; sortie du convertisseur Hexa --> DEC 
    COMPT_TOUR            ; compteur tour 
    ENDC

;**************************  MACRO **************************************
BANK0 MACRO
    BCF STATUS, RP0
    BCF STATUS, RP1
    ENDM
BANK1 MACRO
    BSF STATUS,RP0
    BCF STATUS,RP1
    ENDM
BANK2 MACRO
    BCF STATUS, RP0
    BSF STATUS, RP1
    ENDM
BANK3 MACRO
    BSF STATUS,RP0
    BSF STATUS,RP1
    ENDM

;*************************** RESET ***************************************
    ORG 0x000
    GOTO INIT
;***************************** zone d'interuption *************************
   ORG 0X004
    movwf w_temp ; sauver registre W
    swapf STATUS,w ; swap status avec résultat dans w
    movwf status_temp ; sauver status swappé


BACKUP
      BCF        INTCON,T0IF
      swapf status_temp,w ; swap ancien status, résultat dans w
      movwf STATUS ; restaurer status
      swapf w_temp,f ; Inversion L et H de l'ancien W
                     ; sans modifier Z
      swapf w_temp,w ; Ré-inversion de L et H dans W
                     ; W restauré sans modifier status
      retfie ; retour de l'interruption

;============= l'enregistrement  des valeur 7 seg de l'afficheur dans la RAM ===========   
INIT       
        MOVLW        0X40           
        MOVWF        0X20           
   
        MOVLW        0X79
        MOVWF        0X21 

        MOVLW        0X24
        MOVWF        0X22 

        MOVLW        0X30
        MOVWF        0X23 

        MOVLW        0X19
        MOVWF        0X24 

        MOVLW        0X12
        MOVWF        0X25 

        MOVLW        0X02
        MOVWF        0X26 

        MOVLW        0X78
        MOVWF        0X27 

        MOVLW        0X00
        MOVWF        0X28

        MOVLW        0X10
        MOVWF        0X29 
;**************************** INIT ***************************************

    MOVLW D'38'
    MOVWF CO
    MOVLW D'5'
    MOVWF RE
    MOVLW D'50'
    MOVWF RECH
    MOVLW D'20'
    MOVWF COMP
    CLRF PORTA
   
BANK1
        CLRF TRISA
        BSF TRISA,5

        CLRF TRISB
        CLRF TRISC

        CLRF TRISD

        MOVLW B'00000111'
        MOVWF TRISE

        MOVLW 0x02 ; 0000 0010
        MOVWF ADCON1 ; all A analog; E digital format : 6 lower bit of ADRESL =0
       

        MOVLW B'00000010'
        MOVWF OPTION_REG

       
       MOVLW B'10000000'
       MOVWF INTCON
BANK0
       
       ; BCF INTCON,GIE ;disable interrupts
        MOVLW b'10100001'  ;
        MOVWF ADCON0 ;Fosc/8; channel_4; ADC on

        CLRF TMR0

     BANK1
      MOVLW D'197'
      MOVWF PR2
BANK0
        CLRF PORTB
        CLRF PORTD
       CLRF T2CON
       GOTO START




;***************************** CONVERSION A/D *************************

CONVERSION     
     CALL d_20 ;Delay TACQ
     
       BSF ADCON0,GO ;start conversion
waitc: BTFSC ADCON0,GO ;wait end of conversion
       GOTO waitc
       CALL d_4
       
       MOVF ADRESH,W
       MOVWF COMPT1
     
       RETURN
;*********************
d_20: 
       MOVLW 0x20
       MOVWF COMPT3;0x22
loop1: DECFSZ COMPT3;0x22,1
       GOTO loop1
       RETURN
;******************
 d_4: 
       MOVLW 0x06
       MOVWF COMPT3;0x22
loop2: DECFSZ COMPT3;0x22,1
       GOTO loop2

       RETURN



;**************************** TEMPO ************************************

TEMPO 
    CLRF TMR2
    BCF PIR1,TMR2IF
    BSF T2CON,TMR2ON
TEST
    BTFSS PIR1,TMR2IF
    GOTO TEST
DECFSZ COMPT1,1
GOTO TEMPO
    BCF T2CON,TMR2ON

 RETURN



;***************************** SENS 1 ***********************************
SENS1   
        BCF PORTC,3

    ;-------------------
        BSF PORTC,4
        CALL CONVERSION
        CALL TEMPO
        BCF PORTC,4
        CALL CONVERSION
        CALL TEMPO
        DECFSZ COMPT4,1
        GOTO   HER4
        MOVLW D'8'
        MOVWF COMPT4
        INCF        COMPT_TOUR,f
     
HER4  RETURN
;***************************** SENS 2 ***********************************
SENS2 
        BSF PORTC,3
    ;-------------------
        BSF PORTC,4
        CALL CONVERSION
        CALL TEMPO
        BCF PORTC,4
        CALL CONVERSION
        CALL TEMPO
    ;-------------------
        DECFSZ COMPT5,1
        GOTO   HERO11
        MOVLW D'8'
        MOVWF COMPT5
    ;-------------------
        DECF        COMPT_TOUR,f
     
HERO11  RETURN



;****************************** PROGRAME *********************************

START

ICI99   
 ICI   
       CLRF PORTD
       MOVLW D'8'
       MOVWF COMPT4
       MOVWF COMPT5

       BTFSS PORTE,1
       GOTO  ICI5
       GOTO ICI3
 ICI5  BTFSS PORTE,0
       GOTO ICI100
       GOTO ICI1
ICI100 BTFSS PORTE,5
       GOTO  ICI
       GOTO  ICI99
       

       
 ICI1 
   
       CALL SENS1
       CALL        CONV_HEX            ; appelle le sous programme de conversion hex ---> BCD
       CALL        AFFICHAGE            ; sous programme d'affichage 
       BTFSS PORTE,1
       GOTO  ICI2
       GOTO  ICI3
 ICI2  BTFSS PORTE,2
       GOTO  ICI1
       GOTO  IZA
       

 ICI3  BSF PORTE,3
  
       CALL SENS2
       CALL        CONV_HEX            ; appelle le sous programme de conversion hex ---> BCD
       CALL        AFFICHAGE            ; sous programme d'affichage 
       BTFSS PORTE,0
       GOTO  ICI4
       GOTO  ICI1
 ICI4  BTFSS PORTE,2
       GOTO  ICI3
       GOTO IZA
IZA
        CLRF PORTD
       GOTO  ICI 

;============================ HEX TO BCD ===================================

CONV_HEX   
        MOVF        COMPT_TOUR,w
        MOVWF        COMPT_CONV
        CLRF        UNI
        CLRF        DECI
        CLRF        CENTI
       
        MOVF        COMPT_TOUR,W
        BTFSS        STATUS,Z
        GOTO        ET
        RETURN



ET        INCF        UNI,F
        MOVLW        0X0A
        SUBWF        UNI,W
        BTFSS        STATUS,Z
        GOTO        DEC
        CLRF        UNI

        INCF        DECI,F
        MOVLW        0X0A
        SUBWF        DECI,W
        BTFSS        STATUS,Z
        GOTO        DEC
        CLRF        DECI

        INCF        CENTI,F
        MOVLW        0X0A
        SUBWF        CENTI,W
        BTFSS        STATUS,Z
        GOTO        DEC
        CLRF        CENTI       

DEC        DECFSZ        COMPT_CONV,F
        GOTO        ET 
       

        RETURN



;=============================( affichage )=====================================
AFFICHAGE 
         
        MOVLW        d'7'        ; le temps est CTR=T/10 21
        MOVWF        CT3

        MOVLW        0X20    ; 0x20 dans w
        ADDWF        UNI,f    ; f = CU + 0x20 autrement j'ai posé l'adresse 0x20 dans cu 
        ADDWF        DECI,f    ; f = CD + 0x20
        ADDWF        CENTI,f    ; f = CC + 0x20


;============================== AFFICHEUR 1 =====================================

ET1:      MOVF        UNI,W   
        MOVWF       FSR 
        MOVF        INDF,W
        MOVWF        PORTD
        MOVLW        0X01
        MOVWF        PORTA
        CALL        TEMPO_690us
        CLRF        PORTA
        CALL        TEMPO_130us
        MOVLW        0X01
        MOVWF        PORTA
        CALL        TEMPO_1.25ms
;============================== AFFICHEUR 2 =====================================
        MOVF        DECI,W   
        MOVWF       FSR 
        MOVF        INDF,W
        MOVWF        PORTD
          MOVLW        0X02
        MOVWF        PORTA
        CALL        TEMPO_690us
        CLRF        PORTA
        CALL        TEMPO_130us
        MOVLW        0X02
        MOVWF        PORTA
        CALL        TEMPO_1.25ms
;============================== AFFICHEUR 3 =====================================
        MOVF        CENTI,W   
        MOVWF       FSR 
        MOVF        INDF,W
        MOVWF        PORTD
        MOVLW        0X04
        MOVWF        PORTA
        CALL        TEMPO_690us
        CLRF        PORTA
        CALL        TEMPO_130us
        MOVLW        0X04
        MOVWF        PORTA
        CALL        TEMPO_1.25ms
;============================== AFFICHEUR 4 =====================================
        BTFSS        PORTE,0
        GOTO         S11
        MOVLW        0XBF
        MOVWF        PORTD
        GOTO        NEG
S11        MOVLW        0XFF
        MOVWF        PORTD
        GOTO        NEG

NEG        MOVLW        0X08
        MOVWF        PORTA
        CALL        TEMPO_690us
        CLRF        PORTA
        CALL        TEMPO_130us
        MOVLW        0X08
        MOVWF        PORTA
        CALL        TEMPO_1.25ms

        DECFSZ        CT3,F
        GOTO        ET1
        RETURN 

;=============================== Temporisations ==============================
TEMPO_690us:
        MOVLW        0X1A
        MOVWF        CT1
E211:    MOVLW        0X15
        MOVWF        CT2
E221:    DECFSZ        CT2,F             
        GOTO        E221
        DECFSZ        CT1,F
        GOTO        E211
        NOP
        NOP 
        NOP
        NOP
        RETURN


TEMPO_1.25ms:
        MOVLW        0X08
        MOVWF        CT1
E31:    MOVLW        0X32
        MOVWF        CT2
E32:    DECFSZ        CT2,F             
        GOTO        E32
        DECFSZ        CT1,F
        GOTO        E31
        NOP
        NOP 
        NOP
        RETURN


TEMPO_130us:
        MOVLW        0X29
        MOVWF        CT2
E42:    DECFSZ        CT2,F             
        GOTO        E42
        NOP
        NOP
        NOP 

        RETURN 
    END   
[code]
 

dl324

Joined Mar 30, 2015
16,916
Didn't read your code...

Using a byte as a signed integer would give you a range of 0-255. To get 999, you need a two byte variable.
 

Thread Starter

pronto

Joined Nov 6, 2017
12
Yes using 2 bytes i will get 999 but how can i use a variable of 2 bytes ? i know only how to use variable of one byte
 

MrChips

Joined Oct 2, 2009
30,802
There are two basic ways of doing this. One way is to use a 16-bit integer variable. This will occupy two bytes.
In order to convert from 16-bit integer to four decimal digits you will have to write a conversion routine.

If you are doing straight counting and are not required to do any calculations you can use binary coded decimal (BCD). For this, you will need four bytes, e.g. bcd4, bcd3, bcd2, bcd1. Each byte is a BCD digit with values from 0-9. When one digit overflows, increment the next digit. BCD can be easily displayed on 7-segment displays once you create a BCD-to-seven-segment look-up table.
 

takao21203

Joined Apr 28, 2012
3,702
you need to check the overflow, and each time increment another byte variable
then also you need to use a lookup table to convert the two 8 bits into 7segment
For this purpose it seems to be handy firstly to convert them into decimals

On consideration the codes needed for this are lengthy and youd be better off with C language,
ofcourse it can be done in assembly but in C language you have the basics builtin such as array,
different variable sizes, some conversions, and arithmetic such as division.

When you divide by ten in assembler basically you need to consider 16bits, dealing with 2 8bits at a time
Then you need to call your division routine multiple times

I have learned and used the PIC RISC, good thing is I understood a lot how a controller works at low level but bad thing is I spent a lot of time and others couldnt read my codes so when dealing with USB firstly, I switched to using C language
 

Thread Starter

pronto

Joined Nov 6, 2017
12
@MrChips i'm interested by the first method, can you explaine more how can i convert 16 bit to decimal , or if you have a video or a site where i can understand more please
 

MrChips

Joined Oct 2, 2009
30,802
@MrChips i'm interested by the first method, can you explaine more how can i convert 16 bit to decimal , or if you have a video or a site where i can understand more please
8-bit microcontrollers have been around for decades. Multi-byte arithmetic has been used ever since to perform extended precision arithmetic using both integer and floating point formats. There is no difference between asm programming or C programming in this regard except that in the latter someone else has written the math libraries for you.

For PIC asm programming, code is readily available on the internet. However, if the purpose is to learn how to roll your own, this is a perfectly doable exercise.

For starters, learn how to do multi-byte increment, decrement, addition, subtraction and comparison.
The next exercise is to write your own multi-byte multiplication and division.

Once you have accomplished all of the above, you have all the tools you need and on your way to meeting your goal.

For integer to BCD output, all you need is a simple divide-by-ten routine. That's it.
 

Thread Starter

pronto

Joined Nov 6, 2017
12
@MrChips thank you for your answer, i really love to learn how to roll my own but i'm really in a hurry because i must give this project to my prof monday i don't have enough time to learn that so please if you can propose me a readily code on internet or more guidance should be perfect :/
 

alfonsoM

Joined Nov 8, 2017
41
Don't apologize, French is a beautiful language in coding too.
In the routines SENS 1, SENS 2 replace COMPT_TOUR with a few lines that count the overflows of COMPT_TOUR to a new reg that is the HIGH BYTE.
In the routine of HEX TO BCD repeat the loop for each count of the HIGH BYTE. This will give you the BCD you need.
 

MrChips

Joined Oct 2, 2009
30,802
Here is a brute force technique for converting 16-bit integer to decimal, inefficient, but it works.
Create four BCD bytes.
Create two-byte integer (loop counter) and set to the 16-bit value..
Increment BCD bytes by 1. At the same time decrement the16-bit integer (loop counter).
When the 16-bit integer reaches zero your BCD bytes have the converted digits ready to be displayed.
 

Thread Starter

pronto

Joined Nov 6, 2017
12
@alfonsoM i like this idea it seems perfect but when i want to do it, i getting lost. Can you please modify the sens 1, sens2, and hex to bcd routine for me with what you said before pleaase i really need this work :s
 

WBahn

Joined Mar 31, 2012
30,052
@MrChips thank you for your answer, i really love to learn how to roll my own but i'm really in a hurry because i must give this project to my prof monday i don't have enough time to learn that so please if you can propose me a readily code on internet or more guidance should be perfect :/
@alfonsoM i like this idea it seems perfect but when i want to do it, i getting lost. Can you please modify the sens 1, sens2, and hex to bcd routine for me with what you said before pleaase i really need this work :s
So it sounds like you want someone to give you the code and then when it doesn't do what you want and you can't figure it out, you want them to modify it for you. All so that you can turn in someone else's work to claim credit for it.

Would you want to fly in an airplane that was designed by engineers that got through school this way? Or be operated on by a surgeon that got through medical school this way?
 

dl324

Joined Mar 30, 2015
16,916
Or be operated on by a surgeon that got through medical school this way?
I think one of my surgeons is in this category. Gave me several severe burns on my thigh while he was repairing a hernia. He must have had someone else taking notes for him when they were taught that the tools they use can cause severe injuries to their patients if they aren't careful. Either that or his feet are too big and he was tripping over the pedal that activated the tool.

At least I was anesthetized and couldn't smell my burning flesh.
 
Last edited:

Thread Starter

pronto

Joined Nov 6, 2017
12
@WBahn Yes effectively i want someone who had already did a similar code to show me how he did it and i will do like him because the code that i posted above is made by me and i still have only this little modification to do. i'm a mechanic student, i don't have enough knowledge in electronique for this reason i'm in this forum to find someone kind to help me with an exemple already done which i can take the idea to apply on my project that's all
 

alfonsoM

Joined Nov 8, 2017
41
@WBahn Yes effectively i want someone who had already did a similar code to show me how he did it and i will do like him because the code that i posted above is made by me and i still have only this little modification to do. i'm a mechanic student, i don't have enough knowledge in electronique for this reason i'm in this forum to find someone kind to help me with an exemple already done which i can take the idea to apply on my project that's all
Well said pronto but what the others are saying is that if they were your professors they would have given you the same marking for 99% finished work if you are honest. Professors are suckers for honesty.
We also think that you can finish your code, we did it and we know how good it feels.
 
Top