News:

Let's find out together what makes a PIC Tick!

Main Menu

TM1637 code

Started by RGV250, Jan 26, 2022, 12:24 AM

Previous topic - Next topic

RGV250

Hi,
Just making a tacho for my lathe and realised this code had been lost in the forum changeover.
It is for small seven segment displays like here https://www.ebay.co.uk/itm/191788118105?hash=item2ca7767059:g:S80AAOSwpRRWoFiL

Possibly needs a "Seven segment" area for it to go in under Displays??

Bob

'****************************************************************
'*  Name    : TM1637.BAS                                        *
'*  Author  : RGV250                                            *
'*  Notice  : Copyright (c) 2020 Bobby Garrett                  *
'*          : All Rights Reserved                               *
'*  Date    : 15/03/2020                                        *
'*  Version : 5.1                                              *
'*  Notes   : Procedures based on I2C code from Les             *
'*          : Key scan not used.                                *
'*          : Min voltage for Red, Yellow LED is 3.3 volts      *
'*          : Min voltage For Green, Blue LED is 5.0 volts      *
'*          :                                                   *
'****************************************************************

' 5.1 Min voltage comment added
' 5.0 Original version

    Include "Amicus18.inc"               'Setup the program to run on an Amicus18 board(PIC18F25K20 at 64MHz)
   
'Setup the default pins for SDA and SCL
$define TM1637_SDA_Pin PORTC.4           'Set the SDA pin
$define TM1637_SCL_Pin PORTC.3           'Set the SCL pin
   
'----------------------------------------------------------------------------------------------
'Delay a fixed number of microseconds
'
$define TM1637_hDelay() DelayUS 100      'It worked At 2 in ISIS VSM but didn't work at 50 on real hardware.
                                         'Unsure why it did not work but this is fast enough.
'----------------------------------------------------------------------------------------------   
'Variables
    Dim TestData As Word
    TestData = 0
'----------------------------------------------------------------------------------------------
'Send a start condition
'Input     : None
'Output    : None
'Notes     : A Start condition is high to low of SDA when SCL is high
'
Proc TM1637_Start()
    Input TM1637_SDA_Pin                 'Make the SDA pin an Input (High)
    Input TM1637_SCL_Pin                 'Make the SCL pin an Input (High)
    TM1637_hDelay()
    Output TM1637_SDA_Pin                'Make the SDA pin an Output (Low)
    TM1637_hDelay()
    Output TM1637_SCL_Pin                'Make the SCL pin an Output (Low)
EndProc

'----------------------------------------------------------------------------------------------
'Initiate an acknowledge
'Input     : None
'Output    : None
'Notes     : None
'
Proc TM1637_Ack()
    Output TM1637_SDA_Pin                'Make the SDA pin an Output (Low)
    Input TM1637_SCL_Pin                 'Make the SCL pin an Input (High)
    TM1637_hDelay()
    Output TM1637_SCL_Pin                'Make the SCL pin an Output (Low)
DelayUS 5                            'After the falling edge of the eighth clock delay for 5us.
    Input TM1637_SDA_Pin                 'Make the SDA pin an Input (High)
EndProc

'----------------------------------------------------------------------------------------------
'Send a stop condition
'Input     : None
'Output    : None
'Notes     : A Stop condition is low to high of SDA when SCL is high
'
Proc TM1637_Stop()
    Output TM1637_SDA_Pin                'Make the SDA pin an Output (Low)
    TM1637_hDelay()
    Input TM1637_SCL_Pin                 'Make the SCL pin an Input (High)
    TM1637_hDelay()
    Input TM1637_SDA_Pin                 'Make the SDA pin an Input (High)
    TM1637_hDelay()
EndProc

'----------------------------------------------------------------------------------------------
'Send single bytes to the TM1637 module.
'Input     : pData holds the byte to write
'Output    : None
'Notes     : LSB first
'
Proc TM1637_WriteByte(pData As Byte)

    Dim bIndex As Byte = 8
    Repeat                               'Create a loop for the 8-bits
        If pData.0 = 1 Then
            Input TM1637_SDA_Pin         'Make the SDA pin an Input (High)
        Else
            Output TM1637_SDA_Pin        'Make the SDA pin an Output (Low)
        EndIf
        TM1637_hDelay()
        Input TM1637_SCL_Pin             'Make the SCL pin an Input (High)
        TM1637_hDelay()
        Output TM1637_SCL_Pin            'Make the SCL pin an Output (Low)
        TM1637_hDelay()
        pData = pData >> 1
        Dec bIndex
    Until bIndex = 0

EndProc

'----------------------------------------------------------------------------------------------   
'Set brightness
'Send a single byte to the TM1637 module for the brightness.
'Input     : pData1 holds the brightness data, pData2 is the "On/Off" control.
'Output    : None
'Notes     :     
'Values > 7 will turn display off.
'Address bits b7 / b6 = 10
'b5 / b4 don't care, fill with 0
'b3 On / Off control - 1 = On / 0 = Off
'b2 - b0 is the data
'000 = 1/16
'001 = 2/16
'010 = 4/16
'011 = 10/16
'100 = 11/16
'101 = 12/16
'110 = 13/16
'111 = 14/16
Proc SetBrightness(pData1 As Byte, pData2 As Byte) 
Dim DataByte As Byte
Dim ControlBit As Byte
DataByte = pData1
Controlbit = pData2

'Check if the display should be On or Off.
    If ControlBit = 1 Then
    DataByte = Databyte | %10001000 
    Else
    DataByte = %10000000
    EndIf
'Send the data   
TM1637_Start()
TM1637_WriteByte(DataByte)         
TM1637_Ack()
TM1637_Stop()
EndProc

'---------------------------------------------------------------------------------------------
Proc UpdateDisplay(pData As Word)        'Write display register
    Dim index As Byte
    Dim BitPattern As Byte
    Dim TempArray[4] As Byte             'Create a temporary array for individual characters

'Split the value into individual numbers for writing to display.
    If Dig pData,3 = 0 Then
    TempArray#3 = 0
    Else
    TempArray#3 = Dig pData,3
    EndIf
   
    If Dig pData,2 = 0 Then
    TempArray#2 = 0
    Else
    TempArray#2 = Dig pData,2
    EndIf   
   
    If Dig pData,1 = 0 Then
    TempArray#1 = 0
    Else
    TempArray#1 = Dig pData,1
    EndIf   
   
    If Dig pData,0 = 0 Then
    TempArray#0 = 0
    Else
    TempArray#0 = Dig pData,0
    EndIf
   
'Set data command mode.
'40H is automatic increment by 1.
'44H is fixed address.
TM1637_Start()
TM1637_WriteByte(0x40) 
TM1637_Ack()
TM1637_Stop()
'Set the first address
TM1637_Start()
TM1637_WriteByte(0xc0) 
TM1637_Ack()
'Send the data
    For Index = 3 To 0 Step -1           'Will need to modify if using displays with more than 4 digits.
        BitPattern = LRead SegmentData + TempArray[Index]
TM1637_WriteByte(BitPattern) 
TM1637_Ack()
Next index

TM1637_Stop()
EndProc

'---------------------------------------------------------------------------------------------
'Start   
    Low TM1637_SDA_Pin                   'Make the TM1637 SDA pin an output low
    Low TM1637_SCL_Pin                   'Make the TM1637 SCL pin an output low

'Zero the display at the start.
'Send data to the TM1637 module
    UpdateDisplay(TestData)         
       
'---------------------------------------------------------------------------------------------
Main: 
SetBrightness(4,1)                   'Set the brightness 0 - 7, 1 = On, 0 = Off.

'Send data to the TM1637 module
    UpdateDisplay(TestData)         
   
    DelayMS 10
    Inc TestData
   
    If TestData > 2222 Then              'Rollover to test the preceeding zeroes
    TestData = 0
    EndIf
   
    GoTo Main                            'Do forever.
   
'---------------------------------------------------------------------------------------------   
   
'Bit patterns for numbers 0 - 9
'Some of my TM1637 modules do not have a DP but have a colon, I will not be using either
'so I have not done the code for that at the moment.
'This was copied from some other code somewhere.
'       __A__
'      |     |
'      F     B
'      |__G__|
'      |     |
'      E     C
'      |__D__| X
'     
'XGFEDCBA             0          1          2          3          4          5          6          7         8           9
SegmentData:
    LData As Byte %00111111, %00000110, %01011011, %01001111, %01100110, %01101101, %01111101, %00000111, %01111111, %01101111

       

shantanu@india

Nice and neat coding Bob. Your generous use of 'Proc.. EndProc' makes it very systematic indeed.
I make my own 7-segment displays by cascading 4094's and using three pins to connect to the strobe, data and clock lines.
Regards
Shantanu

See_Mos

I bought several of those displays.The description says 'display module with clock display' and that is usually what you get instead of the one shown in the picture with the decimal point LED's.  I ended up buying some LED displays with decimal points and swapping them over.

Rizwan s shaikh

#3
Successfully done TM1637

midali

I can't open the rar archive .

Rizwan s shaikh

#5
6 Digit 7 sigment & 16 key scan
Successfully done

m.kaviani

hi rezwan
thank for sharing the code. i made a little change in your code for 4 digit I2C TM1637.
a simple incremental counter.

Device = 18F66K80

Config_Start
  RETEN = OFF    ;Ultra low-power regulator is Disabled (Controlled by REGSLP bit)
  INTOSCSEL = Low    ;LF-INTOSC in Low-power mode during Sleep
  SOSCSEL = Dig    ;High Power SOSC circuit selected
  XINST = Off    ;Enabled
  FOSC = HS1    ;HIGH SPEED oscillator
  PLLCFG = On    ;Enabled
  FCMEN = OFF    ;Disabled
  IESO = OFF    ;Disabled
  PWRTEN = off    ;Disabled
  BOREN = SBORDIS    ;Enabled in hardware, SBOREN disabled
  BORV = 3    ;1.8V
  BORPWR = ZPBORMV    ;ZPBORMV instead of BORMV is selected
  WDTEN = Off    ;WDT disabled
  WDTPS = 4096    ;16.384s
  CANMX = PORTB    ;ECAN TX and RX pins are located on RB2 and RB3, respectively
'  T0CKMX = PORTB    ;Timer0 gets its clock input from the RB5/T0CKI pin on 64-pin packages
'  T3CKMX = PORTG    ;Timer3 gets its clock input from the RG2/T3CKI pin on 64-pin packages
'  MSSPMSK = MSK7    ;7 Bit address masking mode
  MCLRE = On    ;MCLR Enabled, RE3 Disabled
  STVREN = On    ;Enabled
  BBSIZ = BB1K    ;2K word Boot Block size
  Cp0 = OFF    ;Disabled
  CP1 = OFF    ;Disabled
  CP2 = OFF    ;Disabled
  CP3 = OFF    ;Disabled
  CPB = OFF    ;Disabled
  CPD = OFF    ;Disabled
  WRT0 = OFF    ;Disabled
  WRT1 = OFF    ;Disabled
  WRT2 = OFF    ;Disabled
  WRT3 = OFF    ;Disabled
  WRTC = OFF    ;Disabled
  WRTB = OFF    ;Disabled
  WRTD = OFF    ;Disabled
  EBTR0 = OFF    ;Disabled
  EBTR1 = OFF    ;Disabled
  EBTR2 = OFF    ;Disabled
  EBTR3 = OFF    ;Disabled
  EBTRB = OFF    ;Disabled
Config_End

;**** End of Fuse Configurator Settings ****
;-------------------------------------------------------------------------------
    Declare Xtal 64
    Declare Optimiser_Level = 2
    Declare Dead_Code_Remove = 1
    Declare HSerout2_Pin PORTE.7
    Declare Hserial2_Baud = 9600
   
    Declare HSDA_Pin PORTC.4
    Declare HSCL_Pin PORTC.3
    Declare Hbus_Bitrate 100
    Declare Reminders = On
    Declare Hints = off
   
    Clear TRISC.1
   
    Set ADCON0.0         ' TURN OF THE A/D CONVERTER
    ADCON1 = 0
    ADCON2 = %10000000
    ANCON0 = %00000011
    ANCON1 = 0

'****************************************************************
Dim DIG1_DATA1 As Byte
Dim DIG2_DATA2 As Byte
Dim DIG3_DATA3 As Byte
Dim DIG4_DATA4 As Byte
Dim DIG5_DATA5 As Byte
Dim DIG6_DATA6 As Byte
Dim OP_VAR1    As Dword
Dim DIGIT      As Byte
Dim PATTERN    As Byte

'***************************************************************
OP_VAR1 = 0
'****************************************************************
MAIN:
Inc OP_VAR1
GoSub Update_Display
DelayMS 100
If OP_VAR1 > 1000 Then
    OP_VAR1 = 0
EndIf


GoTo MAIN
'****************************************************************
Update_Display:
DIGIT = Dig OP_VAR1,3
GoSub CONVERT
DIG1_DATA1 = PATTERN
'----------------------------------------------------------------
DIGIT = Dig OP_VAR1,2
GoSub CONVERT
DIG2_DATA2 = PATTERN
'----------------------------------------------------------------
DIGIT = Dig OP_VAR1,1
GoSub CONVERT
DIG3_DATA3 = PATTERN
'----------------------------------------------------------------
DIGIT = Dig OP_VAR1,0
GoSub CONVERT
DIG4_DATA4 = PATTERN

HBStart                   
HBusOut %00100010      'Data command setting
'HBusOut %01000100      'Data command setting
HBusAck
HBStop

HBStart               
HBusOut %10010001     'Display control  2/16 pulse wide. bit7 & bit6 & bit5 are for controlling the segments brightness
'HBusOut %10001111     'Display control
HBusAck
HBStop

HBStart               
HBusOut %00000011    'dig 1
HBusOut DIG1_DATA1
HBusAck
HBStop
'----------------------------------------------------------------
HBStart               
HBusOut %10000011     'dig 2
'HBusOut DIG2_DATA2 + 1
HBusOut DIG2_DATA2
HBusAck
HBStop
'----------------------------------------------------------------
HBStart               
HBusOut %01000011     'dig 3
HBusOut DIG3_DATA3
HBusAck
HBStop
'----------------------------------------------------------------
HBStart               
HBusOut %11000011     'dig 4
HBusOut DIG4_DATA4
HBusAck
HBStop


Return
'****************************************************************
CONVERT:               ' 0  1   2   3   4   5   6  7   8   9
PATTERN=LookUpL DIGIT,[$FC,$60,$DA,$F2,$66,$B6,$BE,$E0,$FE,$F6]
Return
'****************************************************************