4 bit 7 segment display with two 74HC595


Closed Thread
Results 1 to 24 of 24

Hybrid View

  1. #1

    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: 12744
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
    Posts
    985


    Did you find this post helpful? Yes | No

    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


    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.

  4. #4
    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.

  5. #5


    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.

  6. #6
    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

  7. #7
    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.

  8. #8
    Join Date
    Apr 2003
    Location
    Cambridge - UK
    Posts
    1,030


    Did you find this post helpful? Yes | No

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

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

  9. #9
    Join Date
    May 2013
    Location
    australia
    Posts
    2,380


    Did you find this post helpful? Yes | No

    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; - 21st February 2018 at 00:20.
    Warning I'm not a teacher

  10. #10
    Join Date
    Apr 2003
    Location
    Cambridge - UK
    Posts
    1,030


    Did you find this post helpful? Yes | No

    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

  11. #11


    Did you find this post helpful? Yes | No

    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

  12. #12
    Join Date
    Apr 2003
    Location
    Cambridge - UK
    Posts
    1,030


    Did you find this post helpful? Yes | No

    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, 14:24
  2. 1 Pin 7-Segment Display
    By Mike, K8LH in forum Schematics
    Replies: 0
    Last Post: - 23rd November 2009, 13:35
  3. 7-segment display with P16F84
    By spitfire in forum mel PIC BASIC Pro
    Replies: 16
    Last Post: - 3rd March 2009, 20:22
  4. Display Using Cascaded 74hc595
    By charudatt in forum mel PIC BASIC Pro
    Replies: 4
    Last Post: - 7th December 2004, 07:05
  5. Multiplex two 7 segment display
    By Fernando Santos in forum mel PIC BASIC Pro
    Replies: 0
    Last Post: - 20th July 2003, 14:26

Members who have read this thread : 2

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