4 bit 7 segment display with two 74HC595


Closed Thread
Results 1 to 24 of 24

Hybrid View

  1. #1


    Did you find this post helpful? Yes | No

    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.

  2. #2
    Join Date
    Apr 2014
    Location
    OK
    Posts
    557


    Did you find this post helpful? Yes | No

    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.

  3. #3


    Did you find this post helpful? Yes | No

    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.

  4. #4
    Join Date
    Aug 2003
    Posts
    985


    Did you find this post helpful? Yes | No

    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

  5. #5
    Join Date
    Apr 2014
    Location
    OK
    Posts
    557


    Did you find this post helpful? Yes | No

    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.

  6. #6
    Join Date
    Aug 2011
    Posts
    416


    Did you find this post helpful? Yes | No

    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?

  7. #7
    Join Date
    May 2013
    Location
    australia
    Posts
    2,393


    Did you find this post helpful? Yes | No

    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
    Warning I'm not a teacher

  8. #8
    Join Date
    Apr 2014
    Location
    OK
    Posts
    557


    Did you find this post helpful? Yes | No

    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.

  9. #9


    Did you find this post helpful? Yes | No

    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?

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 : 1

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