+ Reply to Thread
Results 1 to 24 of 24
  1. #1
    Join Date
    Mar 2016
    Posts
    48

    Default 4 bit 7 segment display with two 74HC595

    Hello All,
    I start to play with one of this cheap 4 digit 7 segment display. The display is driven by two 74HC595 which one is for segments and the other is for common cathodes (digits).
    Here is the schematic:
    Name:  4 bit 7 segment module.jpg
Views: 774
Size:  166.3 KB

    I writed a simple code using Darrel's interrupts. Code multiplexing the digits using TMR1 interrupt.
    It works OK, but I think that code is not as elegant. It looks rough, because I'm not a skilled programmer.
    Can someone explain to me a better way to do this task?

    Here is my code:
    Code:
    '****************************************************************
    '*  Name    : 4 bit 7 segment display                           *
    '*  Author  : LouisLouis                                        *
    '*  Notice  : Copyright (c) 2018                                *
    '*          : All Rights Reserved                               *
    '*  Date    : 18. 2. 2018                                       *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*  MCU     : PIC 12F1840                                       *
    '****************************************************************
    
    #CONFIG
      __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
      __config _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _BORV_19 & _LVP_OFF
    #ENDCONFIG
    
    DEFINE OSC 32            ; Use internal clock 
    OSCCON = %01110000
    CLKRCON = 0
    
    Include "modedefs.bas"
    INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
    INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts
    
    TRISA = %000000
    ANSELA = %0000  
    OPTION_REG.7=0           ; Enable internal pull-ups
    
    LPIN var porta.2         ; Latch
    DPIN var porta.4         ; Data
    CPIN var porta.5         ; Clock
    
    segment var byte
    value var word
    place var byte[4]
    ones var word
    tens var word
    hundreds var word
    thousands var word
    
    ASM
    INT_LIST macro ; IntSource, Label, Type, ResetFlag?
        INT_Handler TMR1_INT, _DISP, PBP, yes
      endm
      INT_CREATE ; Creates the interrupt processor
    ENDASM
    
    @ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
    T1CON = $1
    
    ;---[simple counter 0 - to 9999]------------------------------------------------ 
    Main:
    for value = 0 to 9999
    pause 100
    next value
    value = 0
    GOTO Main
    
    ;---[TMR1 - interrupt handler]--------------------------------------------------
    DISP:
    T1CON.0 = 0                ; stop timer
    TMR1H = %11111100
    TMR1L = %00011111
    T1CON.0 = 1                ; restart timer
    
    ;---[extract ones and show]-----------------------------------------------------  
    ones = value//10
    lookup ones, [%11000000,%11111001,%10100100,%10110000,%10011001,%10010010,%10000010,%11111000,%10000000,%10010000],segment
    LOW  LPIN
    Shiftout DPIN, CPIN, MSBFIRST,[segment,%0001] 
    high lpin
    
    pause 4
    
    ;---[extract tens and show]----------------------------------------------------- 
    tens =  value/10 
    tens = tens//10
    lookup tens, [%11000000,%11111001,%10100100,%10110000,%10011001,%10010010,%10000010,%11111000,%10000000,%10010000],segment
    LOW  LPIN
    Shiftout DPIN, CPIN, MSBFIRST,[segment,%0010] 
    high lpin
    
    pause 4
    
    ;---[extract hundreds and show]------------------------------------------------- 
    hundreds =   value/100
    hundreds = hundreds//10
    lookup hundreds, [%11000000,%11111001,%10100100,%10110000,%10011001,%10010010,%10000010,%11111000,%10000000,%10010000],segment
    LOW  LPIN
    Shiftout DPIN, CPIN, MSBFIRST,[segment,%0100] 
    high lpin
    
    pause 4
    
    ;---[extract thousands and show]------------------------------------------------ 
    thousands = value/1000
    place = %1000
    lookup thousands, [%11000000,%11111001,%10100100,%10110000,%10011001,%10010010,%10000010,%11111000,%10000000,%10010000,%10001000],segment
    LOW  LPIN
    Shiftout DPIN, CPIN, MSBFIRST,[segment,%1000] 
    high lpin
    
    @ INT_RETURN

  2. #2
    Join Date
    Aug 2003
    Location
    Australia
    Posts
    980

    Default Re: 4 bit 7 segment display with two 74HC595

    It’s not bad except you don’t need 4 copies of the same lookup table. That should be a subroutine.
    If possible, there should be four identical subroutines that you feed each digit to.

    You’d normally do the display multiplex in the main program, and only use the interrupt to set a flag
    that is being watched by the main program to know when a second, or whatever period ticks over.
    The interrupt handler should be the smaller routine.

  3. #3
    Join Date
    Mar 2016
    Posts
    48

    Default Re: 4 bit 7 segment display with two 74HC595

    Quote Originally Posted by Art View Post
    Itís not bad except you donít need 4 copies of the same lookup table. That should be a subroutine.
    If possible, there should be four identical subroutines that you feed each digit to.

    Youíd normally do the display multiplex in the main program, and only use the interrupt to set a flag
    that is being watched by the main program to know when a second, or whatever period ticks over.
    The interrupt handler should be the smaller routine.
    Hello Art,

    something like this:

    Code:
    '****************************************************************
    '*  Name    : 4 bit 7 segment display                           *
    '*  Author  : LouisLouis                                        *
    '*  Notice  : Copyright (c) 2018                                *
    '*          : All Rights Reserved                               *
    '*  Date    : 18. 2. 2018                                       *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*  MCU     : PIC 12F1840                                       *
    '****************************************************************
    
    #CONFIG
      __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
      __config _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _BORV_19 & _LVP_OFF
    #ENDCONFIG
    
    DEFINE OSC 32            ; Use internal clock 
    OSCCON = %01110000
    CLKRCON = 0
    
    Include "modedefs.bas"
    INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
    INCLUDE "ReEnterPBP.bas" ; Include if using PBP interrupts
    
    TRISA = %000000
    ANSELA = %0000  
    OPTION_REG.7=0           ; Enable internal pull-ups
    
    LPIN var porta.2         ; Latch
    DPIN var porta.4         ; Data
    CPIN var porta.5         ; Clock
    
    segment var byte
    value var word
    place var byte[4]
    ones var word
    tens var word
    hundreds var word
    thousands var word
    
    ASM
    INT_LIST macro ; IntSource, Label, Type, ResetFlag?
        INT_Handler TMR1_INT, _DISP, PBP, yes
      endm
      INT_CREATE ; Creates the interrupt processor
    ENDASM
    
    @ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
    T1CON = $1
    
    ;---[show HELO for 0,5sec.]----------------------------------------------------- 
    intro:
    segment=12
    gosub look
    ones=segment
    segment=11
    gosub look
    tens=segment
    segment=10
    gosub look
    hundreds=segment
    segment=13
    gosub look
    thousands=segment
    pause 500
    
    ;---[simple counter 0 - to 9999]------------------------------------------------
    Main:
    for value = 0 to 9999
    gosub setdisp
    pause 10
    next value
    value = 0
    GOTO Main
    
    setdisp:
    segment = value//10
    gosub look
    ones=segment            ; extract ones
    
    segment =  value/10 
    segment = segment//10
    gosub look
    tens=segment            ; extract tens
    
    segment =   value/100
    segment = segment//10
    gosub look
    hundreds=segment        ; extract hundreds
    
    segment = value/1000
    gosub look
    thousands=segment       ; extract thousands
    
    ;---[7 segment pattern 0123456789 and letters H E L O]--------------------------
    look:                 
    lookup segment, [%11000000,%11111001,%10100100,%10110000,%10011001,%10010010,%10000010,%11111000,%10000000,%10010000,%10000110,%11000111,%11000000,%10001001],segment
    return
    return
    
    ;---[TMR1 - interrupt handler]--------------------------------------------------
    DISP:
    T1CON.0 = 0                ; stop timer
    TMR1H = %11111100
    TMR1L = %00011111
    T1CON.0 = 1                ; restart timer
    
    ;---[multiplex and show]--------------------------------------------------------  
    LOW  LPIN
    Shiftout DPIN, CPIN, MSBFIRST,[ones,%0001] 
    high lpin
    pause 2
    LOW  LPIN
    Shiftout DPIN, CPIN, MSBFIRST,[tens,%0010] 
    high lpin
    pause 2
    LOW  LPIN
    Shiftout DPIN, CPIN, MSBFIRST,[hundreds,%0100] 
    high lpin
    pause 2
    LOW  LPIN
    Shiftout DPIN, CPIN, MSBFIRST,[thousands,%1000] 
    high lpin
    @ INT_RETURN
    It is a bit slower, but now I can display digits and letters.
    Otherwise, I don't think this is a more efficient and elegant code, it must be a better way.

  4. #4
    Join Date
    Apr 2014
    Location
    Northeast
    Posts
    234

    Default Re: 4 bit 7 segment display with two 74HC595

    At the bottom of look: you have RETURN listed twice.

    You turn TMR1 Off (T1CON = 0) in your Disp: Interrupt Handler but I don't see where you turn it back on.

    "segment = value/1000
    gosub look
    thousands=segment ; extract thousands"

    Leads right into your look: Interrupt Handler. If that was to be a subroutine, you need that extra RETURN relocated to the end of that grouping.

  5. #5
    Join Date
    Mar 2016
    Posts
    48

    Default Re: 4 bit 7 segment display with two 74HC595

    Quote Originally Posted by mpgmike View Post
    At the bottom of look: you have RETURN listed twice.
    yes I forgot to delete one return, but it doesn't matter.

    Quote Originally Posted by mpgmike View Post
    You turn TMR1 Off (T1CON = 0) in your Disp: Interrupt Handler but I don't see where you turn it back on.
    Here: T1CON.0 = 1 ; restart timer
    Code:
    ;---[TMR1 - interrupt handler]--------------------------------------------------
    DISP:
    T1CON.0 = 0                ; stop timer
    TMR1H = %11111100
    TMR1L = %00011111
    T1CON.0 = 1                ; restart timer
    Both codes which I posted works fine. I'm looking for more professional (easier, better, more skilled) example to do this.

  6. #6
    Join Date
    Aug 2003
    Location
    Australia
    Posts
    980

    Default Re: 4 bit 7 segment display with two 74HC595

    One of many ways to pull your counter value apart in BASIC is using DIG.
    Copy the counter to another buffer so it stays safe.
    This may be rough, and won't compile straight up.

    Code:
    destructobuffer = countervalue
    
    FOR loopcounter = 0 TO 3
    digitvalue = destructobuffer DIG 0
    print digitvalue
    shift out a digit
    delay for digit (if you must)
    destructobuffer = destructobuffer / 10
    NEXT loopcounter

  7. #7
    Join Date
    Apr 2014
    Location
    Northeast
    Posts
    234

    Default Re: 4 bit 7 segment display with two 74HC595

    Quote Originally Posted by louislouis View Post
    Here: T1CON.0 = 1 ; restart timer
    Code:
    TMR1H = %11111100
    TMR1L = %00011111
    T1CON.0 = 1                ; restart timer
    Most of the data sheets say that when you write to the TMRxH/L, you must declare the entire TxCON SFR. I personally have made a practice of using T1CON = %xxxxxxxx instead of isolating a single bit in the TxCON register after preloading the TMRx register. I actually had a bug that I couldn't figure out for the longest time. When I wrote to the entire Timer Register instead of just a single 1/0 bit, it started working. If it works now, you could leave it as is. If you have issues, try what I suggested here.

  8. #8

    Default Re: 4 bit 7 segment display with two 74HC595

    Most of the data sheets say that when you write to the TMRxH/L, you must declare the entire TxCON SFR
    Could you point to an example of that?

  9. #9
    Join Date
    May 2013
    Location
    australia
    Posts
    1,479

    Default Re: 4 bit 7 segment display with two 74HC595

    Could you point to an example of that?
    me too
    I have never had to do that and can find no mention of that short coming anywhere


    anyways here is my take on the 7 seg display
    if you have a chip with mssp why waste time and code space when the hardware can do it for you

    I cheated a bit and did it in asm for speed and size gains
    no nasty pauses , all gone
    my displays are common anode so the data is inverted see comments

    Code:
    '****************************************************************
    '*  Name    : 4 bit 7 segment display                           *
    '*  Author  : RICHARD                                           *
    '*  Notice  :                                                   *
    '*          :                                                   *
    '*  Date    : 18. 2. 2018                                       *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*  MCU     : PIC 16F1825 @32MHZ                                *
    '****************************************************************
    #CONFIG
                 __config        _CONFIG1,    _FOSC_INTOSC & _CP_OFF & _WDTE_ON  &  _PWRTE_ON  &  _MCLRE_ON  & _CLKOUTEN_OFF
                  __config      _CONFIG2, _PLLEN_OFF & _LVP_OFF
    #ENDCONFIG
    
     goto overasm
     asm
    timer1  = TMR1L 
     
    seg_val       
        addwf   PCL, F                  
        retlw  0xc0;0B11000000     0  
        retlw  0xf9;0B11111001     1     
        retlw  0xa4;0B10100100     2
        retlw  0xb0;0B10110000     3
        retlw  0x99;0B10011001     4
        retlw  0x92;0B10010010     5                     
        retlw  0x82;0B10000010     6
        retlw  0xf8;0B11111000     7
        retlw  0x80;0B10000000     8  
        retlw  0x90;0B10010000     9
     endasm
    
     overasm:
    DEFINE OSC 32            ; Use internal clock 
    ANSELC=0
    SSP1CON1=$22  
    SSP1STAT=$40
    OSCCON=$f0
    
    INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
    
    TRISC = %11101010
    LPIN var portc.4         ; Latch
    DPIN var portc.2         ; Data  SDO
    CPIN var portc.0         ; Clock SCK
    segment var byte
    value var word
    d_index var byte
    buff var byte[5]
    tmp var byte             
    d_pointer      var byte  
    timer1 var word ext
    timer1_reload con    1543      ;8mS
    ASM
    INT_LIST macro ; IntSource, Label, Type, ResetFlag?
        INT_Handler TMR1_INT, _DISP, ASM, yes
      endm
      INT_CREATE ; Creates the interrupt processor
    ENDASM
    @ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
    T1CON = $1
    d_index=0
    ;---[simple counter 0 - to 9999]------------------------------------------------ 
    Main:
    for value = 0 to 9999
    arraywrite buff ,[dec4 value]
    pause 100
    next value
    value = 0
    GOTO Main
    ;---[TMR1 - interrupt handler]--------------------------------------------------
    DISP:
    asm
        MOVE?CT 0, T1CON, TMR1ON ; 1 stop timer
        MOVLW LOW(_timer1_reload) ; 1 Add TimerReload to the 
        ADDWF TMR1L,F ; 1 value in Timer1
        BTFSC STATUS,C ; 1/2
        INCF TMR1H,F ; 1
        MOVLW HIGH(_timer1_reload) ; 1
        ADDWF TMR1H,F ; 1
        MOVE?CT 1, T1CON, TMR1ON ; 1 start timer
        MOVE?CB  high _buff, FSR0H         ;load highbyte 
        MOVE?CB  low  _buff, FSR0L         ;load low byte
        MOVE?BA  _d_index  
        ADDWF  FSR0L,F
        MOVLW 0X30
        SUBWF INDF0,W
        L?CALL seg_val
        MOVE?AB _segment
        MOVE?BB  _d_index ,_tmp
        BANKSEL   _tmp
        MOVLW 1
        ADDWF  _tmp,F
        BANKSEL   _d_pointer
        CLRF _d_pointer
        BSF STATUS ,C
    N_BIT 
        BANKSEL   _d_pointer
        RLF    _d_pointer,F
        BCF STATUS ,C
        BANKSEL   _tmp
        DECFSZ  _tmp,F
        GOTO N_BIT 
        MOVLW 1
        BANKSEL  _d_index
        ADDWF  _d_index,F
        MOVLW 3 
        ANDWF  _d_index,F
        BANKSEL  LATC
        BCF LATC ,4
        BANKSEL PIR1
        BCF     PIR1,3 
        BANKSEL  _segment
        COMF    _segment,W  ;COMMENT USED TO INVERT DATA FOR COMMON ANODE DISPLAY
        BANKSEL SSP1BUF
        movwf   SSP1BUF
        BANKSEL PIR1
        BTFSs   PIR1,3
        GOTO    $-1
        BANKSEL  _d_pointer
        COMF    _d_pointer,W ; ;COMMENT USED FOR COMMON ANODE DISPLAY
        BANKSEL PIR1
        BCF     PIR1,3 
        BANKSEL SSP1BUF
        movwf   SSP1BUF
        BANKSEL PIR1
        BTFSs   PIR1,3
        GOTO    $-1
        BANKSEL  LATC
        BSF LATC ,4
        BANKSEL 0
        INT_RETURN
    endasm
    Last edited by richard; - 19th February 2018 at 11:18. Reason: convert to english instead of gibberish
    This is more entertaining than Free to Air TV

  10. #10
    Join Date
    Apr 2014
    Location
    Northeast
    Posts
    234

    Default Re: 4 bit 7 segment display with two 74HC595

    OK, looked through a K50 and 16F1619 Data Sheet for that note or catch phrase indicating a full write to TxCON is recommended after writing to the TMRxH/L registers and cannot find it. It might be for an older processor, or maybe I read it on a forum somewhere and now it's that propagating myth. Sorry.

  11. #11
    Join Date
    Mar 2016
    Posts
    48

    Default Re: 4 bit 7 segment display with two 74HC595

    Quote Originally Posted by richard View Post
    anyways here is my take on the 7 seg display
    if you have a chip with mssp why waste time and code space when the hardware can do it for you

    I cheated a bit and did it in asm for speed and size gains
    no nasty pauses , all gone
    my displays are common anode so the data is inverted see comments
    Hello Richard, thanks for response. Your code is probably for 4 digit 7 segment display where the segments is driven via 74HC595 shift register, and the common anodes via transistors directly from MCU or for multiplexing a bare display whitout driver right?

    Look at mi first post, my display is driven by two 74HC595 shift register, one for segments, and the second for digits (like common anodes/cathodes).

    To send data I used:
    Code:
     
    SHIFTOUT DPIN, CPIN, MSBFIRST,[ones,%0001]  ;(segment pattern, digit position)
    Now I tring to find more elegant way to extract ones, tens, hundreds and thousands like my previous solution:
    Code:
     
    setdisp:
    segment = value//10
    gosub look
    ones=segment            ; extract ones
    
    segment =  value/10 
    segment = segment//10
    gosub look
    tens=segment            ; extract tens
    
    segment =   value/100
    segment = segment//10
    gosub look
    hundreds=segment        ; extract hundreds
    
    segment = value/1000
    gosub look
    thousands=segment       ; extract thousands
    Can you help me with it?

  12. #12
    Join Date
    May 2013
    Location
    australia
    Posts
    1,479

    Default Re: 4 bit 7 segment display with two 74HC595

    Your code is probably for 4 digit 7 segment display where the segments is driven via 74HC595 shift register, and the common anodes via transistors directly from MCU or for multiplexing a bare display whitout driver right
    wrong , my code is for your circuit but using a different pic chip . I don't have a 12f1840 on hand but I cannot see any reason for it not to work on that chip . if you use the right pins.
    your code is for common anode mine common cathode the commented lines can be changed to suit


    COMF _segment,W for common Anode becomes MOVF _segment,W
    COMF _d_pointer,W for common Anode becomes MOVF _d_pointer,W
    ie the current is reversed in the display
    This is more entertaining than Free to Air TV

  13. #13
    Join Date
    May 2013
    Location
    australia
    Posts
    1,479

    Default Re: 4 bit 7 segment display with two 74HC595

    here is a 12f1822 version
    with full hex [upper and lower case] space and - sign also
    note comments for common anode/cathode


    Code:
    '****************************************************************
    '*  Name    : 4 bit 7 segment display                           *
    '*  Author  : RICHARD                                           *
    '*  Notice  :                                                   *
    '*          :                                                   *
    '*  Date    : 18. 2. 2018                                       *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*  MCU     : PIC 12F1822 @32MHZ                                *
    '****************************************************************
    #CONFIG
      __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
      __config _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _BORV_19 & _LVP_OFF
    #ENDCONFIG
    
     goto overasm
    ASM
    timer1  = TMR1L    
    seg_val 
        CHK?RP  _TM_TMP
        MOVWF   _TM_TMP
        SUBLW   0x21
        btfsc   STATUS, C
        retlw   0   ;" "
        MOVF    _TM_TMP,W
        SUBLW   0x2f
        btfsc   STATUS, C
        retlw   64   ;"-"
        MOVF    _TM_TMP,W
        MOVLW   0X40
        SUBWF   _TM_TMP,W
        btfsC   STATUS, C
        GOTO    TM_ALPHA
        MOVF    _TM_TMP,W
        ANDLW   0X0F
        GOTO    TM_LU
    TM_ALPHA 
        ANDLW   0xdf    ;ucase
        SUBLW   6
        btfsS   STATUS, C
        retlw   0       ;ERROR
        MOVLW   0X37
        SUBWF   _TM_TMP,W
        ANDLW   0xdf    ;ucase
    TM_LU     
        BRW                                         
        retlw 	0X3F    ;0   
        retlw 	6            	
        retlw 	0X5B   
        retlw 	0X4F 
        retlw 	0X66
        retlw 	0X6D                        
        retlw 	0X7D  
        retlw 	7   
        retlw 	0X7F          
        retlw 	0X67    ;9
        retlw 	0X77    ;A
        retlw 	0X7C    ;b
        retlw 	0X39    ;C
        retlw 	0X5E    ;d
        retlw 	0X79    ;E
        retlw 	0X71    ;F 
    endasm 
    
    
    
     overasm:
    
    DEFINE OSC 32            ; Use internal clock 
    ANSELA=0
    SSP1CON1=$22  
    SSP1STAT=$40
    OSCCON=$70
    
    INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
    "
    TRISA = %11111000
    @LPORT=LATA 
    LPIN CON 2     ;var LATC.4         ; Latch
    DPIN var porta.0         ; Data  SDO
    CPIN var porta.1         ; Clock SCK
    
    segment var byte
    value var word
    d_index var byte
    buff var byte[5]
    tmp var byte 
    TM_TMP    var byte         
    d_pointer      var byte  
    timer1 var word ext
    timer1_reload con    1543  ;8mS
                           
    ASM
    INT_LIST macro ; IntSource, Label, Type, ResetFlag?
        INT_Handler TMR1_INT, _DISP, ASM, yes
      endm
      INT_CREATE ; Creates the interrupt processor
    ENDASM
    
    @ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
    T1CON = $1
    d_index=0
    ;---[simple counter 0 - to ffff]------------------------------------------------ 
    Main:
    for value = 0 to 65535
    arraywrite buff ,[HEX4 value,0]
    
    pause 100
    next value
    value = 0
    GOTO Main
    
    ;---[TMR1 - interrupt handler]--------------------------------------------------
    DISP:
    
    asm
        MOVE?CT 0, T1CON, TMR1ON ; 1 stop timer
        MOVLW LOW(_timer1_reload) ; 1 Add TimerReload to the 
        ADDWF TMR1L,F ; 1 value in Timer1
        BTFSC STATUS,C ; 1/2
        INCF TMR1H,F ; 1
        MOVLW HIGH(_timer1_reload) ; 1
        ADDWF TMR1H,F ; 1
        MOVE?CT 1, T1CON, TMR1ON ; 1 start timer
        MOVE?CB  high _buff, FSR0H         ;load highbyte 
        MOVE?CB  low  _buff, FSR0L         ;load low byte
        MOVE?BA  _d_index  
        ADDWF  FSR0L,F
        MOVF   INDF0,W
        L?CALL seg_val
        MOVE?AB _segment
        MOVE?BB  _d_index ,_tmp
        BANKSEL   _tmp
        MOVLW 1
        ADDWF  _tmp,F
        BANKSEL   _d_pointer
        CLRF _d_pointer
        BSF STATUS ,C
    N_BIT 
        BANKSEL   _d_pointer
        RLF    _d_pointer,F
        BCF STATUS ,C
        BANKSEL   _tmp
        DECFSZ  _tmp,F
        GOTO N_BIT 
        MOVLW 1
        BANKSEL  _d_index
        ADDWF  _d_index,F
        MOVLW 3 
        ANDWF  _d_index,F
        BANKSEL  LPORT
        BCF LPORT ,_LPIN
        BANKSEL PIR1
        BCF     PIR1,3 
        BANKSEL  _segment
        MOVF    _segment,W 
        ;COMF    _segment,W  ;COMMENT USED TO INVERT DATA FOR COMMON ANODE DISPLAY
        BANKSEL SSP1BUF
        movwf   SSP1BUF
        BANKSEL PIR1
        BTFSs   PIR1,3
        GOTO    $-1
        BANKSEL  _d_pointer
        COMF    _d_pointer,W 
        ;MOVF    _d_pointer,W  ;COMMENT USED FOR COMMON ANODE DISPLAY
        BANKSEL PIR1
        BCF     PIR1,3 
        BANKSEL SSP1BUF
        movwf   SSP1BUF
        BANKSEL PIR1
        BTFSs   PIR1,3
        GOTO    $-1
        BANKSEL  LPORT
        BSF LPORT ,_LPIN
        BANKSEL 0
        INT_RETURN
    endasm
    This is more entertaining than Free to Air TV

  14. #14
    Join Date
    Mar 2016
    Posts
    48

    Default Re: 4 bit 7 segment display with two 74HC595

    Quote Originally Posted by richard View Post
    here is a 12f1822 version
    with full hex [upper and lower case] space and - sign also
    note comments for common anode/cathode
    Thanks Richard, that code works, but that is a way more difficult understand to me because ASM and so on.
    A few things I've noticed when I tried the code:
    - your code is a way shorter in MCU memory like mine, which is good
    - multiplex is a bit slower I see some flickers
    - if I put in to the "value" variable mumber "1234" the display shows "4321"
    of course I changed this line
    arraywrite buff ,[HEX4 value,0]
    to
    arraywrite buff ,[DEC4 value,0]

    Anyway, it is a good example how the skilled programmer thinks, and how a beginner thinks.
    Last edited by louislouis; - 19th February 2018 at 22:49. Reason: My English is terrible, will we go to Hungarian :-)

  15. #15
    Join Date
    May 2013
    Location
    australia
    Posts
    1,479

    Default Re: 4 bit 7 segment display with two 74HC595

    multiplex is a bit slower I see some flickers
    the refresh rate is 8mS to speed it up to 4mS change timer1_reload to 33543


    if I put in to the "value" variable mumber "1234" the display shows "4321"
    sic

    the digit scan direction can be reversed easily and would result in even smaller code

    the difference with this method is that the mcu can now do other tasks and not spend all its time being just a display controller
    This is more entertaining than Free to Air TV

  16. #16
    Join Date
    May 2013
    Location
    australia
    Posts
    1,479

    Default Re: 4 bit 7 segment display with two 74HC595

    digit order reversed,scan 4mS
    and I moved the lookup out of the isr into the foreground (reduce isr overhead)





    Code:
    '****************************************************************
    '*  Name    : 4 bit 7 segment display                           *
    '*  Author  : RICHARD                                           *
    '*  Notice  :                                                   *
    '*          :                                                   *
    '*  Date    : 18. 2. 2018                                       *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*  MCU     : PIC 12F1822 @32MHZ                                *
    '****************************************************************
    #CONFIG
      __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
      __config _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _BORV_19 & _LVP_OFF
    #ENDCONFIG
    
     goto overasm
    ASM
       
    seg_val 
        CHK?RP  _TM_TMP
        MOVWF   _TM_TMP
        SUBLW   0x21
        btfsc   STATUS, C
        retlw   0   ;" "
        MOVF    _TM_TMP,W
        SUBLW   0x2f
        btfsc   STATUS, C
        retlw   64   ;"-"
        MOVF    _TM_TMP,W
        MOVLW   0X40
        SUBWF   _TM_TMP,W
        btfsC   STATUS, C
        GOTO    TM_ALPHA
        MOVF    _TM_TMP,W
        ANDLW   0X0F
        GOTO    TM_LU
    TM_ALPHA 
        ANDLW   0xdf    ;ucase
        SUBLW   6
        btfsS   STATUS, C
        retlw   0       ;ERROR
        MOVLW   0X37
        SUBWF   _TM_TMP,W
        ANDLW   0xdf    ;ucase
    TM_LU     
        BRW                                         
        retlw 	0X3F    ;0   
        retlw 	6            	
        retlw 	0X5B   
        retlw 	0X4F 
        retlw 	0X66
        retlw 	0X6D                        
        retlw 	0X7D  
        retlw 	7   
        retlw 	0X7F          
        retlw 	0X67    ;9
        retlw 	0X77    ;A
        retlw 	0X7C    ;b
        retlw 	0X39    ;C
        retlw 	0X5E    ;d
        retlw 	0X79    ;E
        retlw 	0X71    ;F 
    endasm 
    
    
    
     overasm:
    
    DEFINE OSC 32            ; Use internal clock 
    ANSELA=0
    SSP1CON1=$22  
    SSP1STAT=$40
    OSCCON=$70
    
    INCLUDE "DT_INTS-14.bas" ; Base Interrupt System
    
    TRISA = %11111000
    @LPORT=LATA 
    LPIN CON 2     ;var LATa.2         ; Latch
    DPIN var porta.0         ; Data  SDO
    CPIN var porta.1         ; Clock SCK
    
    segment var byte
    value var word
    d_index var byte
    buff var byte[5]
    seg_buff   var byte[4]
    seg_cnt    var byte
    seg_dat    var byte 
    tmp var byte 
    TM_TMP    var byte         
    d_pointer      var byte  
    
    timer1_reload con    33543  ;4mS
                           
    ASM
    INT_LIST macro ; IntSource, Label, Type, ResetFlag?
        INT_Handler TMR1_INT, _DISP, ASM, yes
      endm
      INT_CREATE ; Creates the interrupt processor
    ENDASM
    
    @ INT_ENABLE TMR1_INT ; enable Timer 1 interrupts
    T1CON = $1
    d_index=0
    ;---[simple counter 0 - to ffff]------------------------------------------------ 
    Main:
        for value = 0 to 65535
            arraywrite buff ,[HEX4 value,0]
            gosub load_seg
            pause 100
        next value
        value = 0
    GOTO Main
    
    load_seg :
        for seg_cnt=0 to 3
            seg_dat= buff[seg_cnt]
            asm
                MOVE?BA  _seg_dat 
                L?CALL seg_val
                MOVE?AB _seg_dat
            endasm
            seg_buff[seg_cnt]= seg_dat
        next
    return
    
    
    
    
    ;---[TMR1 - interrupt handler]--------------------------------------------------
    DISP:
    
    asm
        MOVE?CT 0, T1CON, TMR1ON ; 1 stop timer
        MOVLW LOW(_timer1_reload) ; 1 Add TimerReload to the 
        ADDWF TMR1L,F ; 1 value in Timer1
        BTFSC STATUS,C ; 1/2
        INCF TMR1H,F ; 1
        MOVLW HIGH(_timer1_reload) ; 1
        ADDWF TMR1H,F ; 1
        MOVE?CT 1, T1CON, TMR1ON ; 1 start timer
        MOVE?CB  high _seg_buff, FSR0H         ;load highbyte 
        MOVE?CB  low  _seg_buff, FSR0L         ;load low byte
        MOVE?BA  _d_index  
        ADDWF  FSR0L,F
        MOVF   INDF0,W
        ;L?CALL seg_val
        MOVE?AB _segment
        MOVE?BB  _d_index ,_tmp
        BANKSEL   _tmp
        MOVLW 1
        ADDWF  _tmp,F
        MOVLW 16
        BANKSEL   _d_pointer
        movwf _d_pointer
        BcF STATUS ,C
    N_BIT 
        BANKSEL   _d_pointer
        RRF    _d_pointer,F
        BANKSEL   _tmp
        DECFSZ  _tmp,F
        GOTO N_BIT 
        MOVLW 1
        BANKSEL  _d_index
        ADDWF  _d_index,F
        MOVLW 3 
        ANDWF  _d_index,F
        BANKSEL  LPORT
        BCF LPORT ,_LPIN
        BANKSEL PIR1
        BCF     PIR1,3 
        BANKSEL  _segment
        MOVF    _segment,W   ;COMMENT USED TO INVERT DATA FOR COMMON cathode DISPLAY
        ;COMF    _segment,W  ;COMMENT USED TO INVERT DATA FOR COMMON ANODE DISPLAY
        BANKSEL SSP1BUF
        movwf   SSP1BUF
        BANKSEL PIR1
        BTFSs   PIR1,3
        GOTO    $-1
        BANKSEL  _d_pointer
        COMF    _d_pointer,W   ;COMMENT USED FOR COMMON cathode DISPLAY
        ;MOVF    _d_pointer,W  ;COMMENT USED FOR COMMON ANODE DISPLAY
        BANKSEL PIR1
        BCF     PIR1,3 
        BANKSEL SSP1BUF
        movwf   SSP1BUF
        BANKSEL PIR1
        BTFSs   PIR1,3
        GOTO    $-1
        BANKSEL  LPORT
        BSF LPORT ,_LPIN
        BANKSEL 0
        INT_RETURN
    endasm
    Last edited by richard; - 19th February 2018 at 23:07.
    This is more entertaining than Free to Air TV

  17. #17
    Join Date
    Mar 2016
    Posts
    48

    Default Re: 4 bit 7 segment display with two 74HC595

    Quote Originally Posted by richard View Post
    the difference with this method is that the mcu can now do other tasks and not spend all its time being just a display controller
    Yes that's great, now the MCU has a way more time to do other tasks which I write using my poor skills in picbasic.
    Probably this piece of your code will be used in my future projects with that type of 7 segment displays.
    Thanks.

  18. #18
    Join Date
    May 2013
    Location
    australia
    Posts
    1,479

    Default Re: 4 bit 7 segment display with two 74HC595

    One further improvement is to ditch dt_ints

    it adds unnecessary bloat for this app

    Code:
    '****************************************************************
    '*  Name    : 4 bit 7 segment display                           *
    '*  Author  : RICHARD                                           *
    '*  Notice  :                                                   *
    '*          :                                                   *
    '*  Date    : 18. 2. 2018                                       *
    '*  Version : 1.0                                               *
    '*  Notes   :                                                   *
    '*  MCU     : PIC 12F1822 @32MHZ                                *
    '****************************************************************
    #CONFIG
      __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_OFF & _CPD_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_ON & _FCMEN_ON
      __config _CONFIG2, _WRT_OFF & _PLLEN_ON & _STVREN_ON & _BORV_19 & _LVP_OFF
    #ENDCONFIG
    
     goto overasm
    ASM
       
    seg_val 
        CHK?RP  _TM_TMP
        MOVWF   _TM_TMP
        SUBLW   0x21
        btfsc   STATUS, C
        retlw   0   ;" "
        MOVF    _TM_TMP,W
        SUBLW   0x2f
        btfsc   STATUS, C
        retlw   64   ;"-"
        MOVF    _TM_TMP,W
        MOVLW   0X40
        SUBWF   _TM_TMP,W
        btfsC   STATUS, C
        GOTO    TM_ALPHA
        MOVF    _TM_TMP,W
        ANDLW   0X0F
        GOTO    TM_LU
    TM_ALPHA 
        ANDLW   0xdf    ;ucase
        SUBLW   6
        btfsS   STATUS, C
        retlw   0       ;ERROR
        MOVLW   0X37
        SUBWF   _TM_TMP,W
        ANDLW   0xdf    ;ucase
    TM_LU     
        BRW                                         
        retlw 	0X3F    ;0   
        retlw 	6            	
        retlw 	0X5B   
        retlw 	0X4F 
        retlw 	0X66
        retlw 	0X6D                        
        retlw 	0X7D  
        retlw 	7   
        retlw 	0X7F          
        retlw 	0X67    ;9
        retlw 	0X77    ;A
        retlw 	0X7C    ;b
        retlw 	0X39    ;C
        retlw 	0X5E    ;d
        retlw 	0X79    ;E
        retlw 	0X71    ;F 
    endasm 
    
    
    
     overasm:
    
    DEFINE OSC 32            ; Use internal clock 
    ANSELA=0
    SSP1CON1=$22  
    SSP1STAT=$40
    OSCCON=$70
    DEFINE INTHAND   _DISP
    
    
    TRISA = %11111000
    @LPORT=LATA 
    LPIN CON 2     ;var LATa.2         ; Latch
    DPIN var porta.0         ; Data  SDO
    CPIN var porta.1         ; Clock SCK
    
    segment var byte
    value var word
    d_index var byte
    buff var byte[5]
    seg_buff   var byte[4]
    seg_cnt    var byte
    seg_dat    var byte 
    tmp var byte 
    TM_TMP    var byte         
    d_pointer      var byte  
    
    timer1_reload con    33543  ;4mS
                           
    
    PIR1.0=0
    INTCON=$C0
    PIE1.0=1
    
    
    T1CON = $1
    d_index=0
    ;---[simple counter 0 - to ffff]------------------------------------------------ 
    Main:
        for value = 0 to 65535
            arraywrite buff ,[HEX4 value,0]
            gosub load_seg
            pause 100
        next value
        value = 0
    GOTO Main
    
    load_seg :
        for seg_cnt=0 to 3
            seg_dat= buff[seg_cnt]
            asm
                MOVE?BA  _seg_dat 
                L?CALL seg_val
                MOVE?AB _seg_dat
            endasm
            seg_buff[seg_cnt]= seg_dat
        next
    return
    
    
    
    
    ;---[TMR1 - interrupt handler]--------------------------------------------------
    DISP:
    
    asm
        MOVE?CT 0, T1CON, TMR1ON ; 1 stop timer
        MOVLW LOW(_timer1_reload) ; 1 Add TimerReload to the 
        ADDWF TMR1L,F ; 1 value in Timer1
        BTFSC STATUS,C ; 1/2
        INCF TMR1H,F ; 1
        MOVLW HIGH(_timer1_reload) ; 1
        ADDWF TMR1H,F ; 1
        MOVE?CT 1, T1CON, TMR1ON ; 1 start timer
        MOVE?CB  high _seg_buff, FSR0H         ;load highbyte 
        MOVE?CB  low  _seg_buff, FSR0L         ;load low byte
        MOVE?BA  _d_index  
        ADDWF  FSR0L,F
        MOVF   INDF0,W
        ;L?CALL seg_val
        MOVE?AB _segment
        MOVE?BB  _d_index ,_tmp
        BANKSEL   _tmp
        INCF  _tmp,F
        MOVLW 16
        BANKSEL   _d_pointer
        movwf _d_pointer
        BcF STATUS ,C
    N_BIT 
        BANKSEL   _d_pointer
        RRF    _d_pointer,F
        BANKSEL   _tmp
        DECFSZ  _tmp,F
        GOTO N_BIT
        BANKSEL  _d_index
        INCF  _d_index,F
        MOVLW 3 
        ANDWF  _d_index,F
        BANKSEL  LPORT
        BCF LPORT ,_LPIN
        BANKSEL PIR1
        BCF     PIR1,3 
        BANKSEL  _segment
        MOVF    _segment,W   ;COMMENT USED TO INVERT DATA FOR COMMON cathode DISPLAY
        ;COMF    _segment,W  ;COMMENT USED TO INVERT DATA FOR COMMON ANODE DISPLAY
        BANKSEL SSP1BUF
        movwf   SSP1BUF
        BANKSEL PIR1
        BTFSs   PIR1,3
        GOTO    $-1
        BANKSEL  _d_pointer
        COMF    _d_pointer,W   ;COMMENT USED FOR COMMON cathode DISPLAY
        ;MOVF    _d_pointer,W  ;COMMENT USED FOR COMMON ANODE DISPLAY
        BANKSEL PIR1
        BCF     PIR1,3 
        BANKSEL SSP1BUF
        movwf   SSP1BUF
        BANKSEL PIR1
        BTFSs   PIR1,3
        GOTO    $-1
        BANKSEL  LPORT
        BSF LPORT ,_LPIN
        BANKSEL PIR1
        BCF PIR1   ,0
        RETFIE
    endasm
    Last edited by richard; - 19th February 2018 at 23:59. Reason: USED INCF INSTEAD OF ADDING 1
    This is more entertaining than Free to Air TV

  19. #19
    Join Date
    May 2013
    Location
    australia
    Posts
    1,479

    Default Re: 4 bit 7 segment display with two 74HC595

    Final version after a bit of a clean up
    Attached Files Attached Files
    This is more entertaining than Free to Air TV

  20. #20
    Join Date
    Apr 2003
    Location
    Cambridge - UK
    Posts
    881

    Default Re: 4 bit 7 segment display with two 74HC595

    Lester - Forum Administrator
    -----------------------------------
    www.crownhill.co.uk

  21. #21
    Join Date
    May 2013
    Location
    australia
    Posts
    1,479

    Default Re: 4 bit 7 segment display with two 74HC595

    Published in the WiKI
    lester
    the two small code windows are blank in the wiki article , i'm sure that was not the intention

    might also add that a decimal point can be lit in the appropriate display using

    Main:
    for value = 0 to 65535
    arraywrite buff ,[HEX4 value]
    gosub load_seg
    seg_buff[2]=seg_buff[2]|128 ; place a dp in digit 2
    pause 100
    next value
    value = 0
    GOTO Main
    Last edited by richard; - 20th February 2018 at 23:20.
    This is more entertaining than Free to Air TV

  22. #22
    Join Date
    Apr 2003
    Location
    Cambridge - UK
    Posts
    881

    Default Re: 4 bit 7 segment display with two 74HC595

    Thank you Richard, the editor went a little funky and added some crazy formatting, causing the blank code boxes. Its fixed now.

    Thank you for your generous contribution.
    Lester - Forum Administrator
    -----------------------------------
    www.crownhill.co.uk

  23. #23
    Join Date
    Mar 2016
    Posts
    48

    Default Re: 4 bit 7 segment display with two 74HC595

    Quote Originally Posted by lester View Post
    Thank you Richard, the editor went a little funky and added some crazy formatting, causing the blank code boxes. Its fixed now.

    Thank you for your generous contribution.
    there are still something wrong, because missing "%" character in the codes published on wiki

    Orig. code:
    TRISA = %111000

    Code on wiki:
    TRISA = 111000

  24. #24
    Join Date
    Apr 2003
    Location
    Cambridge - UK
    Posts
    881

    Default Re: 4 bit 7 segment display with two 74HC595

    OK thanks for that

    I think the % is displayed correctly now.
    Lester - Forum Administrator
    -----------------------------------
    www.crownhill.co.uk

Similar Threads

  1. 7 segment display
    By lerameur in forum mel PIC BASIC Pro
    Replies: 6
    Last Post: - 13th January 2015, 13:24
  2. 1 Pin 7-Segment Display
    By Mike, K8LH in forum Schematics
    Replies: 0
    Last Post: - 23rd November 2009, 12:35
  3. 7-segment display with P16F84
    By spitfire in forum mel PIC BASIC Pro
    Replies: 16
    Last Post: - 3rd March 2009, 19:22
  4. Display Using Cascaded 74hc595
    By charudatt in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 7th December 2004, 06:05
  5. Multiplex two 7 segment display
    By Fernando Santos in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 20th July 2003, 13:26

Members who have read this thread : 34

You do not have permission to view the list of names.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts