PIC TIMER0 and 7-segment multiplexing problem

Discussion in 'Embedded Systems and Microcontrollers' started by thejmh, Jul 3, 2009.

  1. thejmh

    Thread Starter Member

    Jul 3, 2009
    12
    0
    Hi! I'm trying to get this program work but haven't succeeded yet. I have a 3-digit common cathode 7-segment display and three transistors to turn the digits on. I'm using a PIC16F877A with a 4MHz crystal. Timer0 sets an interrupt after 1ms. I tried the multiplexing part of the code with 1ms counters written into code, without the interrupts and it worked perfectly. When I try to get the timing from TIMER0 it doesn't work. What's wrong with my code?

    Code ( (Unknown Language)):
    1.  
    2. PC                    EQU 02h
    3. TRISA                EQU 85h
    4. PORTA                EQU 05h
    5. TRISB                EQU 86h    
    6. PORTB                EQU 06h
    7. TRISC                EQU 87h
    8. PORTC                EQU 07h
    9. TRISD                EQU 88h
    10. PORTD                EQU 08h
    11. TRISE                EQU 89h
    12. PORTE                EQU 09h
    13.  
    14. STATUS              EQU 03h
    15. TXSTA                EQU 98h
    16. TXREG                EQU 19h
    17. SPBRG                EQU 99h
    18. PCLATH               EQU 0Ah
    19. INTCON              EQU 0Bh
    20. OPTION_REG      EQU 81h
    21. TMR0                 EQU 01h
    22.  
    23. W_TEMP             EQU 70h
    24. STATUS_TEMP     EQU 71h
    25. PCLATH_TEMP     EQU 72h
    26.  
    27. BCD0                EQU 39h            ; result of binary to bcd conversion in these 3 registers.
    28. BCD1                EQU 3Ah
    29. BCD2                EQU 3Bh
    30.  
    31.  
    32.  
    33.  
    34.             ORG        000h
    35.             goto        INIT
    36.  
    37.  
    38.             ORG        004h                ; Interrupt routine
    39.            
    40.  
    41.             movwf    W_TEMP            ; Copy W to TEMP register
    42.             swapf    STATUS,0        ; Swap status to be saved into W
    43.             clrf        STATUS             ; bank 0, regardless of current bank, Clears IRP,RP1,RP0
    44.             movwf    STATUS_TEMP    ; Save status to bank zero STATUS_TEMP register
    45.             movf        PCLATH,0        ; Only required if using pages 1, 2 and/or 3
    46.             movwf    PCLATH_TEMP    ; Save PCLATH into W
    47.             clrf        PCLATH            ; Page zero, regardless of current page
    48.            
    49.  
    50. ; 7-SEGMENT MULTIPLEXING
    51.        
    52.             btfss        PORTE,0            ; Is ones transistor on?
    53.             goto        $+6
    54.             movlw    b'100'
    55.             movwf    PORTE            ; Set hundreds transistor on.
    56.             movf        BCD2,0            ; Move hundreds to 7-seg digit
    57.             movwf    PORTC
    58.             goto        INT_EXIT
    59.  
    60.             btfss        PORTE,1            ; Is tens transistor on?
    61.             goto        $+6
    62.             movlw    b'001'
    63.             movwf    PORTE            ; Set ones transistor on.
    64.             movf        BCD0,0            ; Move ones to 7-seg digit
    65.             movwf    PORTC
    66.             goto        INT_EXIT
    67.  
    68.             btfss        PORTE,2            ; Is hundreds transistor on?
    69.             goto        $+5
    70.             movlw    b'010'
    71.             movwf    PORTE            ; Set tens transistor on.
    72.             movf        BCD1,0            ; Moves tens to 7-seg digit
    73.             movwf    PORTC
    74.            
    75.  
    76. INT_EXIT   movf        PCLATH_TEMP,0    ; Restore PCLATH
    77.             movwf    PCLATH            ; Move W into PCLATH
    78.             swapf    STATUS_TEMP,0    ; Swap STATUS_TEMP register into W
    79.             movwf    STATUS            ; Move W into STATUS register
    80.             swapf    W_TEMP,1        ; Swap W_TEMP
    81.             swapf    W_TEMP,0        ; Swap W_TEMP into W
    82.            
    83.             movlw     b'11111010'        ; FAh (=250)
    84.             movwf    TMR0
    85.             bcf        INTCON,2            ; TMR0_INT
    86.             retfie
    87.  
    88.  
    89.  
    90.  
    91. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    92.  
    93.  
    94. INIT      bsf        STATUS,5        ; To bank 1
    95.             movlw    b'000000'            
    96.             movwf    TRISA            
    97.             movlw    b'00001111'    
    98.             movwf    TRISB        
    99.             movlw    b'00000000'
    100.             movwf    TRISC            
    101.             movlw    b'00000000'
    102.             movwf    TRISD            
    103.             movlw    b'000'
    104.             movwf    TRISE            
    105.  
    106.             movlw    b'001'
    107.             movwf    PORTE            ; Sets the first digit on for multiplexing.
    108.            
    109.             ; SETUP TMR0
    110.  
    111.             movlw    b'01000001'        ; Also sets PORTB pull-ups
    112.             movwf    OPTION_REG
    113.             bcf        STATUS,5             ; return to page 0
    114.  
    115.             movlw    b'10100000'
    116.             movwf    INTCON              ; GIE enable interrupts.
    117.    
    118.  
    119. MAIN
    120.  
    121.             ; Main program here, I didn't include it this time...
    122.  
    123.  
    124.  
    125.  
     
    Last edited: Jul 6, 2009
  2. SgtWookie

    Expert

    Jul 17, 2007
    22,182
    1,728
    Just some general thoughts....

    When an interrupt occurs, consider immediately turning off interrupts while the current interrupt is being serviced; otherwise if your service routine takes longer than you thought, you'll get stuck in a loop.

    Then clear the flag that caused the initial interrupt.

    Then perform your interrupt service routine.

    Then re-initialize the timer.

    Lastly, re-enable interrupts.

    Note that your MAIN portion doesn't have any statements; it should be at least branching back to MAIN. Otherwise the program counter may just run off the end of your code, and attempt to execute arbitrary data that was left from the last programming exercise.
     
  3. thejmh

    Thread Starter Member

    Jul 3, 2009
    12
    0
    Thanks for your tips. I did those and also found some errors and it works now!:) But now there's a new problem. If I want to display for example 0 on ones display, then there is also very dim 0 on hundreds display, which is the next digit in multiplexing sequence. I tried messing with the timing but it didn't help.
     
    Last edited: Jul 6, 2009
  4. SgtWookie

    Expert

    Jul 17, 2007
    22,182
    1,728
    It's because you're putting the cart before the horse. ;)

    Right now, you're turning off the prior digit and turning on the new digit - the prior value is still loaded in the port.

    You need to turn the prior and current digit off before loading in the new value, or you'll get "ghosting" on other digits.


    1) Turn the transistor for the last digit OFF.
    2) Load the port with data for the new segments to be displayed.
    3) Turn the transistor for the new digit ON.
    4) Return after resetting interrupt status;etc.

    Also, I see you're using "goto $+6" etc.
    You'll be better off to branch to labels instead of hard-coded PC offsets. As things are now, you'll have to adjust those hard-coded offsets to compensate for the instructions you'll have to add. If you'd used labels, the assembler would take care of the adjustment automatically.

    Here's an example of what I'm talking about:
    Code ( (Unknown Language)):
    1. ; 7-SEGMENT MULTIPLEXING
    2.        
    3. TestOnes    btfss    PORTE,0          ; Is ones transistor on?
    4.             goto     TestTens
    5.             movlw    b'000'
    6.             movwf    PORTE            ; Set all transistors off.
    7.             movf     BCD2,0           ; Move hundreds to 7-seg digit
    8.             movwf    PORTC
    9.             movlw    b'100'
    10.             movwf    PORTE            ; Set hundreds transistor on.
    11.             goto     INT_EXIT
    12.  
    13. TestTens    btfss    PORTE,1          ; Is tens transistor on?
    14.             goto     DispTens
    15.             movlw    b'000'
    16.             movwf    PORTE            ; Set all transistors off.
    17.             movf     BCD0,0           ; Move ones to 7-seg digit
    18.             movwf    PORTC
    19.             movlw    b'001'
    20.             movwf    PORTE            ; Set ones transistor on.
    21.             goto     INT_EXIT
    22.  
    23. DispTens    movlw    b'000'           ; Displaying tens.
    24.             movwf    PORTE            ; Set all transistors off.
    25.             movf     BCD1,0           ; Moves tens to 7-seg digit
    26.             movwf    PORTC
    27.             movlw    b'010'
    28.             movwf    PORTE            ; Set tens transistor on.
    29.  
     
    Last edited: Jul 7, 2009
  5. thejmh

    Thread Starter Member

    Jul 3, 2009
    12
    0
    Thanks!:) It works perfectly now, no ghosting anymore!
     
  6. walid el masry

    Active Member

    Mar 31, 2009
    132
    0
    iam so lucky iam working on the same circuit but unfortunately there is some thing wrong
    i can reset only the 1st digit on number 10 of course but other 2 digits doesn't affected at all , i tested the logic of code and i guess it is fine but on testing the circuit on Proteus 7.4 i found this problem


    see that my code

    Code ( (Unknown Language)):
    1.  
    2.     LIST P=16F876
    3.     #INCLUDE<P16F876.INC>
    4.     __CONFIG    _CP_OFF&_LVP_OFF&_BODEN_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC
    5. TIME EQU 0X20                   ;used to delay code
    6. ; if we have a 100 in decimal then DIG0 = 0 , DIG1 = 0 , DIG2 = 1
    7. DIG0 EQU 0X21
    8. DIG1 EQU 0X22
    9. DIG2 EQU 0X23
    10.     ORG 0X00
    11.     GOTO INTIATION
    12.     ORG 0X04
    13. ;INTERRUPT SUBRUTINE
    14.     ;CLRF TIME                    ;clear delay if i want to reset delay
    15.     CALL SCAN                    ;make a count
    16.     BCF INTCON,INTF        ;STOP THE INTERRUPT
    17.     BSF INTCON,GIE          ;ALLOW OTHER INTERRUPT TO BE ABLE OCCUR
    18.     RETFIE
    19. INTIATION
    20. ;INTERRUPT INTIATION
    21.     MOVLW 0X90
    22.     MOVWF INTCON           ;Enable External Interrupt & Enable Global Interrupt Gate
    23.     MOVLW 0X47
    24.     MOVWF OPTION_REG  ;Intrrupt Start At Falling Edge
    25. ;INTIATION PORTS
    26.     MOVLW 0X01
    27.     TRIS PORTB
    28.     MOVLW 0X00
    29.     TRIS PORTC
    30. ;MOVLW 0X09                     ;used to test program at this point on the 7 segments
    31.     MOVWF PORTB            ;to clear any value stored in portb after chipt boot
    32.     MOVWF PORTC            ;to clear any value stored in portc after chipt boot
    33.     MOVWF DIG0
    34.     MOVWF DIG1
    35.     MOVWF DIG2
    36. START
    37.     CALL DELAY
    38.     BCF PORTC,2
    39.     BSF PORTC,0
    40.     BCF PORTC,1
    41.     SWAPF DIG0,W
    42.     MOVWF PORTB
    43.     CALL DELAY
    44.     BCF PORTC,0
    45.     BSF PORTC,1
    46.     BCF PORTC,2
    47.     SWAPF DIG1,W
    48.     MOVWF PORTB
    49.     CALL DELAY
    50.     BCF PORTC,1
    51.     BSF PORTC,2
    52.     BCF PORTC,0
    53.     SWAPF DIG2,W
    54.     MOVWF PORTB
    55.     GOTO START
    56. SCAN                       ;counter increment code
    57. CDIG0                      ;CALCULATION FOR DIGIT 0
    58.     INCF DIG0,DIG0
    59.     MOVLW 0X0A          ;OVER FLOW TEST FOR DIGIT >9 AT COUNTING 10
    60.     XORWF DIG0,W
    61.     BTFSC STATUS,Z
    62.     GOTO CDIG1;NO     ;OVER FLOW FOR DIG0 OCCUR
    63.     GOTO FIN;YES
    64. ;----------------------------------------
    65. CDIG1                      ;CALCULATION FOR DIGIT 1
    66.     MOVLW 0X00
    67.     MOVWF DIG0
    68.     INCF DIG1,DIG1
    69.     MOVLW 0X0A          ;OVER FLOW TEST FOR DIGIT >9 AT COUNTING 100
    70.     XORWF DIG1,W
    71.     BTFSC STATUS,Z
    72.     GOTO CDIG2;NO     ;OVER FLOW FOR DIG1 OCCUR
    73.     GOTO FIN;YES
    74. ;----------------------------------------
    75. CDIG2                      ;CALCULATION FOR DIGIT 2
    76.     MOVLW 0X00
    77.     MOVWF DIG1
    78.     INCF DIG2,DIG2
    79.     MOVLW 0X0A          ;OVER FLOW TEST FOR DIGIT >9 AT COUNTING 1000
    80.     XORWF DIG2,W
    81.     BTFSC STATUS,Z
    82.     GOTO CLR;NO         ;OVER FLOW FOR DIG2 OCCUR
    83.     GOTO FIN;YES
    84. ;----------------------------------------
    85.     MOVLW 0XFF
    86.     MOVWF PORTC
    87. CLR                          ;CALCULATION FOR OVER FLOW > 999 CONT
    88.     MOVLW 0X00
    89.     MOVWF DIG0
    90.     MOVWF DIG1
    91.     MOVWF DIG2
    92. ;----------------------------------------
    93. FIN
    94. ;MOVLW 0XFF       ;used to test program at this point on the 7 segments
    95. ;MOVWF PORTC    ;used to test program at this point on the 7 segments
    96.     RETURN
    97. DELAY ;1 sec delay
    98.     CLRF TIME
    99.     MOVLW 0XF4
    100.     MOVWF TMR0
    101.     BSF STATUS,RP0
    102.     MOVLW 0X47
    103.     MOVWF OPTION_REG
    104.     BCF STATUS,RP0
    105. WAIT
    106.     BTFSS INTCON,T0IF
    107.     GOTO WAIT
    108.     BCF INTCON,T0IF
    109.     INCF TIME
    110.     MOVLW 0X04
    111.     XORWF TIME,W
    112.     BTFSS STATUS,Z
    113.     GOTO WAIT
    114.     RETURN
    115.     END
    116.  


    and that is the circuit i built virtually on Proteus

    [​IMG]

    counter count on switch pressing which make interrupt with that and then continue the 7 segment multiplexing
     
  7. walid el masry

    Active Member

    Mar 31, 2009
    132
    0
    i intend to reduce the circuit in future by using just 1 decoder and make the multiplexing on the unused pins in portb instead of the pins of portc i used of course after solving the problem
     
  8. millwood

    Guest

    looks like you have enough pins on the mcu so you shouldn't use any decoder (just 7 pins to the led + 3 pins to the commons).
     
  9. walid el masry

    Active Member

    Mar 31, 2009
    132
    0
    you are wright but think if you can use the port c to do another job then you can understand the importance of wasted 3 pin of it except that i have reduced the pcb to take smaller size
     
  10. SgtWookie

    Expert

    Jul 17, 2007
    22,182
    1,728
    The 7448 has built-in pull-up resistors. You don't need resistors on the outputs.
    On the other hand, you DO need resistors to limit current on the bases of Q1 through Q3; I suggest 1k Ohms.

    You don't seem to be doing any multiplexing in your code; just incrementing the counters.
    You'll need to turn the current display off via portc, move the new digit's data to display into portb, and then turn the new digit on in portc.

    It is not necessary to use the large font size for your text. The regular font works just fine.
     
  11. walid el masry

    Active Member

    Mar 31, 2009
    132
    0


    i miss it and it will make it smaller

    you are wright but in simulation every thing works fine :):)

    i do the multiplexing but i found Proteus can't handle time smaller than this in code (200mSEC) but in real life at (1mSEC) or smaller it works fine
    and multiplexing code

    Code ( (Unknown Language)):
    1.  
    2. START
    3.     CALL DELAY        ;multiplexing delay
    4.     BCF PORTC,2       ;turn third display off
    5.     BSF PORTC,0       ;turn first display on
    6.     BCF PORTC,1       ;ensure turning second display off
    7.     SWAPF DIG0,W
    8.     MOVWF PORTB       ;move the vaule to displayed on PORTB
    9. ;--------------------------------------
    10.     CALL DELAY        ;multiplexing delay
    11.     BCF PORTC,0       ;turn first display off
    12.     BSF PORTC,1       ;turn second display on
    13.     BCF PORTC,2       ;ensure turning third display off
    14.     SWAPF DIG1,W
    15.     MOVWF PORTB       ;move the vaule to displayed on PORTB
    16. ;--------------------------------------
    17.     CALL DELAY        ;multiplexing delay
    18.     BCF PORTC,1       ;turn second display off
    19.     BSF PORTC,2       ;turn third display on
    20.     BCF PORTC,0       ;ensure turning first display off
    21.     SWAPF DIG2,W
    22.     MOVWF PORTB       ;move the vaule to displayed on PORTB
    23.     GOTO START
    24.  
    i agree with you :):):)
     
  12. walid el masry

    Active Member

    Mar 31, 2009
    132
    0
    that is improved one but i use the common anode but let us discuss the common cathode code up there

    and for multiplexing i used the code
    MOVLW B'XXXXXXXX'
    MOVWF PORTB

    from
    thejmh , it reduce code

    [​IMG]
     
    Last edited: Jul 10, 2009
  13. walid el masry

    Active Member

    Mar 31, 2009
    132
    0
  14. millwood

    Guest

    10k for r1/r2/r3 may be too much.

    the LED will likely take 3-5ma each to light up. so that means a total of 35ma if all segments are lit up.

    the LEDs will also have a forward drop of about 1.5 - 2v, at least. plus one Vbe, you are talking about a base current of only (5-2-.7)/10k=.2ma. with a beta of 100 for small signal transistors, that means those transistors can source about 20ma. a little bit on the low side.

    I would use 1k resistors instead.
     
  15. millwood

    Guest

    this is what I have, in a similar set-up. it is a 16f628a driving 3 7-segments. programmed in picc-lite / hi-tide.

    Code ( (Unknown Language)):
    1.  
    2. #include <htc.h>
    3.  
    4. #define S0  RA0
    5. #define S1  RA1
    6. #define S2  RA2
    7. #define LED PORTB
    8. #define SEG_A   (ON<<0)
    9. #define SEG_B   (ON<<1)
    10. #define SEG_C   (ON<<2)
    11. #define SEG_D   (ON<<3)
    12. #define SEG_E   (ON<<4)
    13. #define SEG_F   (ON<<5)
    14. #define SEG_G   (ON<<6)
    15. #define ON  1
    16. #define OFF 0
    17. #define Chr_0   SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F
    18. #define Chr_1           SEG_B | SEG_C                              
    19. #define Chr_2   SEG_A | SEG_B |         SEG_D | SEG_E |         SEG_G
    20. #define Chr_3   SEG_A | SEG_B | SEG_C | SEG_D |                 SEG_G
    21. #define Chr_4           SEG_B | SEG_C |                 SEG_F | SEG_G
    22. #define Chr_5   SEG_A |         SEG_C | SEG_D |         SEG_F | SEG_G
    23. #define Chr_6   SEG_A |         SEG_C | SEG_D | SEG_E | SEG_F | SEG_G
    24. #define Chr_7   SEG_A | SEG_B | SEG_C                                
    25. #define Chr_8   SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G
    26. #define Chr_9   SEG_A | SEG_B | SEG_C | SEG_D |         SEG_F | SEG_G
    27. #define Chr_A   SEG_A | SEG_B | SEG_C |         SEG_E | SEG_F | SEG_G
    28. #define Chr_B   SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G
    29. #define Chr_C   SEG_A |                 SEG_D | SEG_E | SEG_F | SEG_G
    30. #define Chr_D   SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F        
    31. #define Chr_E   SEG_A |                 SEG_D | SEG_E | SEG_F | SEG_G
    32. #define Chr_F   SEG_A |                         SEG_E | SEG_F | SEG_G
    33. #define Disp_0  LED=Chr_0
    34. #define Disp_1  LED=Chr_1
    35. #define Disp_2  LED=Chr_2
    36. #define Disp_3  LED=Chr_3
    37. #define Disp_4  LED=Chr_4
    38. #define Disp_5  LED=Chr_5
    39. #define Disp_6  LED=Chr_6
    40. #define Disp_7  LED=Chr_7
    41. #define Disp_8  LED=Chr_8
    42. #define Disp_9  LED=Chr_9
    43. #define Disp_A  LED=Chr_A
    44. #define Disp_B  LED=Chr_B
    45. #define Disp_C  LED=Chr_C
    46. #define Disp_D  LED=Chr_D
    47. #define Disp_E  LED=Chr_E
    48. #define Disp_F  LED=Chr_F
    49. #define DELAY   1000000
    50.  
    51. __CONFIG( XT & WDTDIS & PWRTDIS & BORDIS & LVPDIS & UNPROTECT );
    52.  
    53. void mcu_init(void) {
    54. //initialize the mcu
    55.     CMCON=0x07; //turn off coomparators;
    56.     TRISA=0x00; //turn port A to output
    57.     TRISB=0x00; //turn port b to output
    58.     OPTION=0b00000000;  //disable PortB pull-up.
    59. //  INTCON=0x00;        //disable interrupts
    60. //  RCSTA=0x00; //disable usart
    61. }
    62.  
    63. void delay(long int dly) {
    64.     for(; dly==0; dly--)
    65.         ;
    66. }
    67.  
    68. void display_chr(char chr) {
    69.     switch (chr) {
    70.     case '0':   Disp_0; break;
    71.     case '1':   Disp_1; break;
    72.     case '2':   Disp_2; break;
    73.     case '3':   Disp_3; break;
    74.     case '4':   Disp_4; break;
    75.     case '5':   Disp_5; break;
    76.     case '6':   Disp_6; break;
    77.     case '7':   Disp_7; break;
    78.     case '8':   Disp_8; break;
    79.     case '9':   Disp_9; break;
    80.     case 'A':   Disp_A; break;
    81.     case 'B':   Disp_B; break;
    82.     case 'C':   Disp_C; break;
    83.     case 'D':   Disp_D; break;
    84.     case 'E':   Disp_E; break;
    85.     case 'F':   Disp_F; break;
    86.     }
    87. }
    88.  
    89.  
    90. void main(void)
    91. {
    92.     int i;
    93.     const char *str="02A";
    94.     mcu_init();
    95.     while (1){
    96.         //TODO Auto-generated main function
    97.         display_chr('4');
    98.         S0=0; delay(DELAY); S0=1;
    99.         display_chr('5');
    100.         S1=0; delay(DELAY); S1=1;
    101.         display_chr('A');
    102.         S2=0; delay(DELAY); S2=1;
    103.     }
    104. }
    105.  
    you can write a function to display a string and then it will be mostly done!
     
  16. walid el masry

    Active Member

    Mar 31, 2009
    132
    0
    yes you are 100% wright in real life
    but in simulation it doesn't matter every thing works fine
    but what am asking for is the logic of the code cause i think it must work fine
    but when i tried to simulate it , it just increment the 1st display and reset it on over flow but nothing happen for the other displays

    see that is the code for the above circuit

    Code ( (Unknown Language)):
    1.  
    2.     LIST P=16F876
    3.     #INCLUDE<P16F876.INC>
    4.     __CONFIG    _CP_OFF&_LVP_OFF&_BODEN_OFF&_PWRTE_ON&_WDT_OFF&_XT_OSC
    5. TIME EQU 0X20                   ;used to delay code
    6. ; if we have a 100 in decimal then DIG0 = 0 , DIG1 = 0 , DIG2 = 1
    7. DIG0 EQU 0X21
    8. DIG1 EQU 0X22
    9. DIG2 EQU 0X23
    10.     ORG 0X00
    11.     GOTO INTIATION
    12.     ORG 0X04
    13. ;INTERRUPT SUBRUTINE
    14.     ;CLRF TIME                    ;clear delay if i want to reset delay
    15.     CALL SCAN                    ;make a count
    16.     BCF INTCON,INTF        ;STOP THE INTERRUPT
    17.     BSF INTCON,GIE          ;ALLOW OTHER INTERRUPT TO BE ABLE OCCUR
    18.     RETFIE
    19. INTIATION
    20. ;INTERRUPT INTIATION
    21.     MOVLW 0X90
    22.     MOVWF INTCON           ;Enable External Interrupt & Enable Global Interrupt Gate
    23.     MOVLW 0X47
    24.     MOVWF OPTION_REG  ;Intrrupt Start At Falling Edge
    25. ;INTIATION PORTS
    26.     MOVLW 0X01
    27.     TRIS PORTB
    28.     MOVLW 0X00
    29.     TRIS PORTC
    30. ;MOVLW 0X09                     ;used to test program at this point on the 7 segments
    31.     MOVWF PORTB            ;to clear any value stored in portb after chipt boot
    32.     MOVWF PORTC            ;to clear any value stored in portc after chipt boot
    33.     MOVWF DIG0
    34.     MOVWF DIG1
    35.     MOVWF DIG2
    36. START
    37.     CALL DELAY
    38.     SWAPF DIG0,W
    39.     MOVWF PORTB
    40.     COMF PORTB,PORTB
    41.     BCF PORTB,3
    42.     BSF PORTB,1
    43.     CALL DELAY
    44.     SWAPF DIG1,W
    45.     MOVWF PORTB
    46.     COMF PORTB,PORTB
    47.     BCF PORTB,1
    48.     BSF PORTB,2
    49.     CALL DELAY
    50.     SWAPF DIG2,W
    51.     MOVWF PORTB
    52.     COMF PORTB,PORTB
    53.     BCF PORTB,2
    54.     BSF PORTB,3
    55.     GOTO START
    56. SCAN                       ;counter increment code
    57. CDIG0                      ;CALCULATION FOR DIGIT 0
    58.     INCF DIG0,DIG0
    59.     MOVLW 0X0A          ;OVER FLOW TEST FOR DIGIT >9 AT COUNTING 10
    60.     XORWF DIG0,W
    61.     BTFSC STATUS,Z
    62.     GOTO CDIG1;NO     ;OVER FLOW FOR DIG0 OCCUR
    63.     GOTO FIN;YES
    64. ;----------------------------------------
    65. CDIG1                      ;CALCULATION FOR DIGIT 1
    66.     MOVLW 0X00
    67.     MOVWF DIG0
    68.     INCF DIG1,DIG1
    69.     MOVLW 0X0A          ;OVER FLOW TEST FOR DIGIT >9 AT COUNTING 100
    70.     XORWF DIG1,W
    71.     BTFSC STATUS,Z
    72.     GOTO CDIG2;NO     ;OVER FLOW FOR DIG1 OCCUR
    73.     GOTO FIN;YES
    74. ;----------------------------------------
    75. CDIG2                      ;CALCULATION FOR DIGIT 2
    76.     MOVLW 0X00
    77.     MOVWF DIG1
    78.     INCF DIG2,DIG2
    79.     MOVLW 0X0A          ;OVER FLOW TEST FOR DIGIT >9 AT COUNTING 1000
    80.     XORWF DIG2,W
    81.     BTFSC STATUS,Z
    82.     GOTO CLR;NO         ;OVER FLOW FOR DIG2 OCCUR
    83.     GOTO FIN;YES
    84. ;----------------------------------------
    85.     MOVLW 0XFF
    86.     MOVWF PORTC
    87. CLR                          ;CALCULATION FOR OVER FLOW > 999 CONT
    88.     MOVLW 0X00
    89.     MOVWF DIG0
    90.     MOVWF DIG1
    91.     MOVWF DIG2
    92. ;----------------------------------------
    93. FIN
    94. ;MOVLW 0XFF       ;used to test program at this point on the 7 segments
    95. ;MOVWF PORTC    ;used to test program at this point on the 7 segments
    96.     RETURN
    97. DELAY ;1 sec delay
    98.     CLRF TIME
    99.     MOVLW 0XF4
    100.     MOVWF TMR0
    101.     BSF STATUS,RP0
    102.     MOVLW 0X47
    103.     MOVWF OPTION_REG
    104.     BCF STATUS,RP0
    105. WAIT
    106.     BTFSS INTCON,T0IF
    107.     GOTO WAIT
    108.     BCF INTCON,T0IF
    109.     INCF TIME
    110.     MOVLW 0X04
    111.     XORWF TIME,W
    112.     BTFSS STATUS,Z
    113.     GOTO WAIT
    114.     RETURN
    115.     END
    116.  
     
  17. walid el masry

    Active Member

    Mar 31, 2009
    132
    0
    that is the code of increment

    Code ( (Unknown Language)):
    1.  
    2. SCAN                       ;counter increment FUNCTION
    3. CDIG0                      ;CALCULATION FOR DIGIT 0 (1st display)
    4.     INCF DIG0,DIG0     ;increment 1st display
    5.     MOVLW 0X0A          ;OVER FLOW TEST FOR DIGIT >9 AT COUNTING 10
    6.     XORWF DIG0,W
    7.     BTFSC STATUS,Z
    8.     GOTO CDIG1;NO     ;OVER FLOW FOR DIG0 OCCUR
    9.     GOTO FIN;YES
    10. ;----------------------------------------
    11. CDIG1                      ;CALCULATION FOR DIGIT 1 (2nd display)
    12.     MOVLW 0X00        ;reset 1st display due to over flow
    13.     MOVWF DIG0
    14.     INCF DIG1,DIG1     ;increment 2nd display
    15.     MOVLW 0X0A          ;OVER FLOW TEST FOR DIGIT >9 AT COUNTING 100
    16.     XORWF DIG1,W
    17.     BTFSC STATUS,Z
    18.     GOTO CDIG2;NO     ;OVER FLOW FOR DIG1 OCCUR
    19.     GOTO FIN;YES
    20. ;----------------------------------------
    21. CDIG2                      ;CALCULATION FOR DIGIT 2 (3rd display)
    22.     MOVLW 0X00        ;reset 2nd display due to over flow
    23.     MOVWF DIG1
    24.     INCF DIG2,DIG2       ;increment 3rd display
    25.     MOVLW 0X0A          ;OVER FLOW TEST FOR DIGIT >9 AT COUNTING 1000
    26.     XORWF DIG2,W
    27.     BTFSC STATUS,Z
    28.     GOTO CLR;NO         ;OVER FLOW FOR DIG2 OCCUR
    29.     GOTO FIN;YES
    30. ;----------------------------------------
    31.     MOVLW 0XFF
    32.     MOVWF PORTC
    33. CLR                          ;CALCULATION FOR OVER FLOW > 999 CONT
    34.     MOVLW 0X00          ;reset 3rd display due to over flow
    35.     MOVWF DIG0
    36.     MOVWF DIG1
    37.     MOVWF DIG2
    38. ;----------------------------------------
    39. FIN
    40.     RETURN
    41.  
     
  18. SgtWookie

    Expert

    Jul 17, 2007
    22,182
    1,728
    Now that you've changed to a common anode, and replaced the 7448 with a 7447, you'll have to add the resistors back in (one per the 7447's current sink), value depends on Vf and current desired per segment. The NPN transistors should be replaced with PNP transistors. The base resistors should be anywhere from 330 Ohms to 1k Ohms.

    In your code, I don't know why you're performing a COMF PortB,PortB (inverting all bits) and then individually setting/clearing bits.

    You should instead be:
    1) Turning off the previously lit segment.
    2) Moving the new value to be displayed into the port.
    3) Turning on the new segment.
    4) Delaying.

    In your interrupt service routine, you should first turn off interrupts, THEN call scan, and then turn interrupts back on.
     
  19. SgtWookie

    Expert

    Jul 17, 2007
    22,182
    1,728
    Change:
    INCF DIG0,DIG0
    to:
    INCF DIG0,1
    Change:
    INCF DIG1,DIG1
    to:
    INCF DIG1,1
    Change:
    INCF DIG2,DIG2
    to:
    INCF DIG2,1
     
  20. walid el masry

    Active Member

    Mar 31, 2009
    132
    0
    you are wright it was stupid step of me

    i do it to do multiplexing on RB1,RB2,RB3

    i corrected the code to this sequence

    Code ( (Unknown Language)):
    1.  
    2. START
    3.     BCF PORTB,3
    4.     SWAPF DIG0,W
    5.     MOVWF PORTB
    6.     BSF PORTB,1
    7.     CALL DELAY
    8.     BCF PORTB,1
    9.     SWAPF DIG1,W
    10.     MOVWF PORTB
    11.     BSF PORTB,2
    12.     CALL DELAY
    13.     BCF PORTB,2
    14.     SWAPF DIG2,W
    15.     MOVWF PORTB
    16.     BSF PORTB,3
    17.     CALL DELAY
    18.     GOTO START
    19.  
    Code ( (Unknown Language)):
    1.  
    2. ;INTERRUPT SUBRUTINE
    3.     ;CLRF TIME                    ;clear delay if i want to reset delay
    4.     BCF INTCON,GIE          ;DENAY OTHER INTERRUPT TO BE ABLE OCCUR
    5.     CALL SCAN                    ;make a count
    6.     BCF INTCON,INTF        ;STOP THE INTERRUPT
    7.     BSF INTCON,GIE          ;ALLOW OTHER INTERRUPT TO BE ABLE OCCUR
    8.     RETFIE
    9.  
    in the end no thing just the 1st display which work with me

    here the project files if any one want to check it him self

    http://rapidshare.com/files/254248062/7_segment.rar.html
    or
    http://www.2shared.com/file/6638073/ca3d7c42/7_segment.html

    and i will include link to Proteus 7
     
Loading...