PDA

View Full Version : TM1637 - display module include example



longpole001
- 12th August 2018, 00:26
Hi guys ,

have had a need to use the TM1637 4 digit display module

please refer to link for the display module circuit and display unit used

http://www.picbasic.co.uk/forum/showthread.php?t=23968

Thanks to richard for help on the start/stop/ write timing section

hope it of use to save some time when using this module


cheers

Sheldon




'* Version : 0.0 *
'* Notes : Driver Libary for TM1637 chip *
'* : For use on 4 digit with centre colon only *
'* : Note: Driver does not support the keyscan option *
'************************************************* ******************************
' Description: *
' This include supports 4 digits, no Decimal Points on each digit *
' and 1 colon in centre of 4 digits only *
' No keyscan support setup on the TM1637 fuctions *
' *
' Operation: *
' min voltage for Red, Yellow LED digits is 3.3 volt *
' min voltage for Green , Blue LED digits is 5v *
' min clock width = 400ns *
' min data setup = 100ns + hold =100ns *
' The Clock and Data Pin have pull up 4k7 resitor, *
' with a 100pf cap to ground to reduce interfance buit into module *
' The 2 colon led segments are connected to anode Com2,cath= seg8 *
' *
' Features : *
' Use either raw segment values or decimal numbers *
' (with and without leading zero) *
' Set either the whole display or any digit independently *
' Control the brightness *
' Test display segments display *
'================================================= ============================='
' TM1637 4 DIGIT COMMON ANODE - 1 COLON DISPLAY MODULE *
' *
' Note: COLON = Grid2 - seg8(dp)- No other DP on this display *
' ----------------------------------------- DISPLAY FACING *
' | | *
' | ______ _____ _____ _____ | *
' | | A | | | | | | | | *
' | |F B| | | | | | | 0 ----- CLK *
' | |_____| |_____| O |_____| |_____| o ----- DIO *
' | | G | | | | | | | 0 ----- VCC *
' | |E C| | | O | | | | 0 ----- GND *
' | |__D__| |_____| |_____| |_____| | *
' | dig1 dig2 dig3 dig4 | *
' | grid1 grid2 grid3 grid4 | *
' ----------------------------------------- *
' *
' ================================================== ===========================*
' Command byte information TM1637 *
' Note: Bit5= 0 ,bit4 = 0 always *
' bit7 : Bit6 *
' 0 : 1 = Data Command *
' 1 : 0 = Display control Command *
' 1 : 1 = Address command '
' ++++++++++++++++++++++++++++++++++++++++++++++++++ +++++++++++++++++++++++++ *
' Data Command table ( bit7 = 1 , bit6 = 0 , bit5=0,bit4 =0) Hex value $4x *
' *
' Bit1:Bit0 *
' 0 : 0 = Write Data to display *
' 1 : 0 = Read key scan *
' 0 : 1 = reserved *
' 1 : 1 = reserved *
' Bit2 0 = Auto Address Adding , 1= Fixed Address *
' Bit3 0 = Normal Mode 1 = Test Mode *
' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*
' Display Control Commnad table ( bit7=1 , Bit6 =0) hex value $8x *
' Bit2:Bit1:Bit0 - display brightness control level 0 = low , level 7 = high *
' 0 : 0 : 0 Display Brightness 1/16 - level 0 *
' 0 : 0 : 1 Display Brightness 2/16 - level 1 *
' 0 : 1 : 0 Display Brightness 4/16 - level 2 *
' 0 : 1 : 1 Display Brightness 10/16 - level 3 *
' 1 : 0 : 0 Display Brightness 11/16 - level 4 *
' 1 : 0 : 1 Display Brightness 12/16 - level 5 *
' 1 : 1 : 0 Display Brightness 13/16 - level 6 *
' 1 : 1 : 1 Display Brightness 14/16 - level 7 *
' *
' Bit3 0 = Display Off 1 = Display On *
' *
' = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =*
' Grid Segment Address Command Table ( Bit7= 1 ,Bit6 = 1 ) Hex Value = $Cx *
' Display Adreess Registers *
' Bit3-Bit0 $C0 = Grid1(dig1), $C1 = Grid2(dig2+colon) ,$C2=Grid3 ,$C3=Grid4 *
' *
' Eech bit for each Grid byte controls a digit led Segment *
' Bit7=Seg8(DP,COlON),Bit6=Seg7(led-G),Bit5=Seg6(led-F),Bit4=Seg5(led-E) *
' Bit3=Seg3(led-D),Bit2=Seg2(led-C),Bit1=Seg1(led-B),Bit0=Seg1(led-A) *
' *
'================================================= =============================*

TM_DIO_OUT var LATB.2 ' Data Pin OUT TM1637 include - 4dig 7seg Display Module
TM_DIO_IN VAR PORTB.2 ' Data Pin In ( not used )
TM_CLK var LATB.3 ' Clock Pin- set in TM1637 include - 4dig 7seg Display Module
DIR_TM_DIO var TRISB.2 ' Direction control for tm_dio pin 0 = out 1 = in


TM1637_WR con $40 ' write data command , with auto Address adding , display mode = normal
TM1637_WR_fixed con $44 ' write data command , with fixed Address , display mode = normal
Cmd_Dig_Seg con $C0 ' Grid Segment Address Command $C0 - $C3 used on this module
TM1637_Dsp_CTL con $80 ' display bright control command , bit3-0=display off 1= on ,bit2-0 brightness 0 - low 7 = high

Dig_7seg var byte[4] ' 4 byte array byte for each digit in use
TM1637_Data var byte ' value for each digit / segment in send command
YY var byte ' geneeral loop varable
g_num var word ' reqested number or chr to be dipslayed
TM1637_Bright var byte ' display brightness value (0-7) 0=low to 7=high brighness
Colon_On var bit ' select if the colon segment is on/off
TM1637_On var bit ' select display on / off bit for command3
R_Justfy var bit ' set leading 0 if digit value 0 displayed over the digits


DIR_TM_DIO = 0 ' set direction output as start
TM_CLK = 1 ' SET HIGH AT START - modual has pullups
TM_DIO_out = 1 ' set high at start - module has pullups

goto Jumpover_TM1637
'======================================

TM1637_Startup:
' Command to do test pattern at device starup
'---- each digit turn on in seq, all digits

Dig_7seg(0) = 0
Dig_7seg(1) = 0
Dig_7seg(2) = 0
Dig_7seg(3) = 0
TM1637_on = 1
for g_num = 0 to 3
Dig_7seg(g_num) = $FF
TM1637_On = 1
TM1637_Bright = 7
gosub WR_4dig
pause 200
next g_num
gosub TM1637_flash ' flash the display 3 times
gosub TM1637_off ' turn off display
return


' -------------------------------
TM1637_flash:
' flash the display 3 times with current values and brightness
' if display was off prior to call , will leave it off after , visa versa if display was on prior
for g_num = 0 to 5 ' flash display on / off 3 times
toggle TM1637_On
TM1637_Bright = 7
gosub WR_Disp_Command3
pause 300
next g_num
return

'---------------------------------------------------------
TM1637_Off:
' turn off the tm1637 display

TM1637_On = 0 ' set bit to 0 turn off display
gosub WR_Disp_Command3 ' send the commands to display, other values dont care as display tuned off
return
'--------------------------------------

WR_4dig:
' assumes each digit data 7 segment info varable ( dig1_7seg,dig2_7seg, dig3_7seg dig4_7seg )
' assumes brightness setting value for command3 ( tm1637_bright)
' assumes colon bit,TM1637_ON Bit , Dig_7seg(0-3) value


' TM1637_On = 1
' Colon_On = 1
' TM1637_Bright = 7

gosub Start_data ' start seq
TM1637_Data = TM1637_WR ' set write data command1 , with auto Address increment , display mode = normal
Gosub Write_Tm1637 ' write to module
gosub Stop_data ' stop seq after data command1

gosub Start_data ' start seq for command2
TM1637_Data = Cmd_Dig_Seg ' grid1 start address for auto increment
Gosub Write_Tm1637 ' write to module

TM1637_Data = Dig_7seg(3) ' digit 4 Data on grid1
Gosub Write_Tm1637 ' write to module

TM1637_Data = Dig_7seg(2) ' digit 3 Data on Grid2
TM1637_Data = TM1637_Data + (Colon_On << 7) ' add colon bit setting (bit7) to digit2 data for grid2
Gosub Write_Tm1637 ' write to module

TM1637_Data = Dig_7Seg(1) ' digit 2 data for grid3
Gosub Write_Tm1637 ' write to module

TM1637_Data = Dig_7Seg(0) ' digit 1 data for grid4
Gosub Write_Tm1637 ' write to module
Gosub Stop_data ' send stop seq to show end of address data

WR_Disp_Command3: ' Label to write display command3 only , assumes dig_7seg(0-3)+ colon setting, brightness , display on /off setting
gosub Start_data ' start seq for command 3 to start
TM1637_Data = TM1637_Dsp_CTL ' build display command3 byte
TM1637_Data = TM1637_Data +(TM1637_On <<3) ' add display on/off bit setting(bit3)to command3
TM1637_Data = TM1637_Data + TM1637_Bright ' add display brighness value ( 0-7 ) to byte command3
Gosub Write_Tm1637 ' write to module
gosub Stop_data ' stop seq

return


'-----------------------------------------------------------------------------
' digits placed and display left to right with 4th digit first 1digit last
' routine can set all 4 values
' assumes R_Justfy value, g_num
Put_4dig:
TM1637_Data = g_num DIG 3 ' get 4th digit value into temp varable
gosub lookup_dig ' convert value to 7seg display value
Dig_7seg(3) = TM1637_Data ' place 7seg value into digit1 including "0"
if TM1637_Data = $3F then ' if it 7seg "0" then
if R_Justfy = 0 then Dig_7seg(3) = 0 ' if flag not set dont show digit
endif

Put_3dig:
TM1637_Data = g_num DIG 2 ' get 3rd digit value into temp varable
gosub lookup_dig ' convert value to 7seg display value
Dig_7seg(2) = TM1637_Data ' place 7seg value into digit1 including "0"
if TM1637_Data = $3F then ' if it 7seg "0" then
if R_Justfy = 0 then Dig_7seg(2) = 0 ' if flag not set dont show digit
endif

Put_2dig:
TM1637_Data = g_num DIG 1 ' get 2nd digit value into temp varable
gosub lookup_dig ' convert value to 7seg display value
Dig_7seg(1) = TM1637_Data ' place 7seg value into digit1 including "0"
if TM1637_Data = $3F then ' if it 7seg "0" then
if R_Justfy = 0 then Dig_7seg(1) = 0 ' if flag not set dont show digit
endif

Put_1dig:
TM1637_Data = g_num DIG 0 ' get 1st digit value into temp varable
gosub lookup_dig ' convert value to 7seg display value
Dig_7seg(0) = TM1637_Data ' place 7seg value into digit1 including "0"

return
'------------------------------------------------------------------------------
lookup_dig:
' converts selected dec value to 7seg display value
' digits display 0 1 2 3 4 5 6 7 8 9
lookup TM1637_Data,[$3F,$06,$5B,$4F,$66,$6D,$7D,$07,$7F,$6F],TM1637_Data

return

'-----------------------------------------------------------------------------
test_txt:

' place "CH:" txt and current Rf CH value onto display ,
' use R_justfy leading 0 for 2 digits
Dig_7seg(3) = $39 '"C"
Dig_7seg(2) = $76 '"H"
Colon_On = 1 '":"
g_num = 1 ' get the current RF CH value
R_Justfy = 1 ' set leading 0 if single digit
gosub put_2dig ' put 2 digits values for location dig3, dig4

TM1637_Bright = 7 ' Set display to full brightness - value (0-7) 0=low to 7=high brighness
TM1637_On = 1 ' select display on in command3
gosub WR_4DIG ' write the values to display
return

'--------------------------------------------
' signal requirments at start of command
Start_data:
tm_CLK = 1
tm_DIO_out = 1
@ NOP
Tm_DIO_out = 0
@ NOP
tm_CLK = 0
return
'------------------------------------
' signal requirement after command is sent
Stop_data:
tm_CLK = 0
tm_DIO_out = 0
tm_CLK = 1
@ NOP
tm_DIO_out = 1
@ NOP
return

'--------------------------------------------
Write_TM1637:
' assumes TM1637_Data
' commands/ data sent LSbit first
yy= 0
for yy = 0 to 7 ' send 8 bits of data
tm_CLK = 0
tm_dio_out = TM1637_Data.0(yy)
tm_CLK = 1
@ NOP
Next yy
tm_CLK = 0 ' clock in data to look for the Ack from TM1637
DIR_TM_DIO = 1 ' set Data pin direction to input , release
tm_CLK = 1 ' clock in ACK data on rising edge from TM1637
@ NOP ; allow time for input of ACK
@ NOP
@ NOP
tm_CLK = 0 ' release DIO on oomplete 9th clock
@ NOP
DIR_TM_DIO = 0 ' set Data pin direction to output

return

'----------------
'show_number:
'send number example
g_num = 32
R_Justfy = 1 ' place leading 0 in display
gosub Put_4dig ' place 4 digit values

TM1637_On = 1
Colon_On = 0
TM1637_Bright = 7
gosub WR_4dig


'return
'-------------------------------------





'================================================= =========================

Jumpover_TM1637: 'Jumpover code for PBP compile requirements

Balachandar
- 30th September 2018, 14:30
Hi longpole001,
Thanks for posting some useful info on TM1637 display module. Based on your post and and some details obtained from the Net, I am trying to write code in PBP 2.60C for pic 12F1840. But so far, I have not been able to make the display work. I have checked the display connecting it to Arduino and it works fine.

I have tried at 32MHz and 16MHz (internal oscillator), but to no avail. Can you please post the complete working code including PBP version, Osc speed, PIC used and any other relevant information. Thanks.
- Bala

ShoKre
- 9th October 2018, 11:14
Hi,
i have module with TM1638 lot led buttons and 8 digit, it was really cheap,
but I didn't use it yet, if chip has similarity maybe it is good start point.

ChuckR
- 26th November 2019, 18:00
I've investigated PICBASIC's SHIFTOUT command and have found that it can be used to write to the TM1637, when used with bit-banged start, stop, and acknowledge sequences.

The attached demo code was developed on the MELabs Trainer Board (PIC16F1937) using PortB.0 (data) and PortB.1 (clock), and ported to a PIC12F1572 application without any problem. I've commented the code copiously to make it (hopefully) comprehensible and portable.

I've structured this code as a library file that can be inserted as an INCLUDE file in any main program. However, this library file is also executable by itself with the addition of a uC initialization INCLUDE and the un-commenting of the single line of code where so designated. "CompileProgram" and your LED display should light up all the segments "8.8.8.8.".

I suggest interested users run this file by itself as a means of testing the display, port assignments and connections before integrating it into a main program (reassign the clock and data pins as required). Once your display is functional, all that is necessary is to INCLUDE this file at the end of your main program, and insert GOSUB LEDOUT instruction(s) wherever required in your main program.

The user's main program should create a 4-digit decimal number, parse it into 4 separate digits, lookup the 7-segment hex code for each digit, and assign those hex codes to the 4 character variables CHR1 - CHR4. Then, GOSUB LEDOUT.

The subroutine LEDOUT sends the 4 digits, CHR1 - CHR4, to the display, preceded by the write command 0x40 (CMD1) and the address start command 0xC0 (CMD2), and proceeded by the end command 0x8A (CMD3). Each of the digits CHR1 - CHR4 and each of the commands CMD1 - CMD3 is sent using the SHIFTOUT command. Bracketing each SHIFTOUT command are the bit-banger start, acknowledge, and stop sequences, which are executed by the subroutines StartSeq, AckSeq, and StopSeq.

AN EXTREMELY IMPORTANT POINT: These TM1637 LED displays seem to be universally equipped with on-board capacitors that shunt the clock and data inputs, and render the displays non-functional (at least in my experience with them). I have had to remove these caps to make my displays work.

I hope this code proves useful. Comments and feedback are of course encouraged and welcome.



'************************************************* ***************
'* Name : TM1637_Include_File.PBP *
'* Author : Roberts *
'* Notice : Hack it as you wish *
'* : *
'* Date : 11/12/2019 *
'* Version : 1.0 *
'* Notes : Include File Library for TM1637 Write Subroutine *
'* : *
'************************************************* ***************
'
' The subroutine LEDOUT implements the write sequence consisting of a write command (CMD1=$40) followed by the address
' command (CMD2=$C0), the 4 digits CHR1 - CHR4, and terminating with CMD3=$8A which turns the display ON and sets its
' brightness level. The PBP command SHIFTOUT is used to send these commands and characters, thus avoiding bit-banging
' them.
'
' The 3 subroutines StartSeq, AckSeq, and StopSeq perform the requisite bit banging on the SDA and SCK outputs before
' and after the PBP SHIFTOUT command.
'
' This demo code writes to all 4 digits in the TM1637's "auto-increment" mode. The digits could be individually
' addressed using the TM1637's "fixed address" mode (see TM1637 spec sheet).

' Decimal points are included in this demo -- the $FF hex code activates all 7 segments and the digit's decimal
' point ("8."). For any digit, add 0x80 as shown in the code table below.
'
' Some TM1637 displays are designed for clock applications (hour & minutes) and have a center colon instead of decimal
' points. The colon is activated by adding 0x80 to CHR2 (activating the decimal point for CHR2).
'
' This INCLUDE file can be used by itself to test activate the display to "8.8.8.8." or any other set of digits by
' setting the values for CHR1 - CHR4, and un-commenting the line of code designated below.
'
' A THORUGH READING AND COMPREHENSION OF THE TM1637 DATA SHEET IS HELPFUL!
'
' Below are the hexadecimal segment codes corresponding to decimal values
'
' 0 1 2 3 4 5 6 7 8 9 (digits only)
' 0x3F 0x06 0x5B 0x4F 0x66 0x6D 0x7D 0x07 0x7F 0x67
'
' 0. 1. 2. 3. 4. 5. 6. 7. 8. 9. (digit and decimal point)
' 0xBF 0x86 0xDB 0xCF 0xE6 0xED 0xFD 0x87 0xFF 0xE7 (digit and colon for CHR2 in clock displays)
'
'********************************Declare Variables and Constants***************************************** *****
'
' Place the PIC initialization INCLUDE file here to use this INCLUDE file by itself to test the LED display
' For Example:
' INCLUDE "TM1637_MELABS_Initializer.pbp"
'

SDA Var PORTB.0 'Serial data pin
SCK Var PORTB.1 'Serial clock pin

'These are the 3 commands used by the TM1637 controller:
CMD1 CON $40 'CMD1=$40 is the write command
CMD2 CON $C0 'CMD2=$C0 is the start digit position(left most)
CMD3 CON $8A 'CMD3=$8A is the end command that turns the display on and sets brightness
'(CMD3=$8F for max brightness - see TM1637 spec sheet)

'*******Un-comment the following line of code to use this INCLUDE file by itself to test the LED display*******

'CHR1 CON $FF : CHR2 CON $FF : CHR3 CON $FF : CHR4 CON $FF 'Activate all segments and decimal points "8.8.8.8"

'************************************Subrouting LEDOUT******************************************** *************

LEDOUT: 'This subrountine outputs all 4 characters to the LED
GOSUB StartSeq 'SHIFTOUT Mode 0 works - LSB first, clock normally low
SHIFTOUT SDA, SCK, 0, [CMD1] 'This shifts out the 8-bit write command character $40
GOSUB AckSeq
GOSUB StopSeq

GOSUB StartSeq
SHIFTOUT SDA, SCK, 0, [CMD2] 'This shifts out the 8-bit command character $C0 that places
GOSUB AckSeq 'the first character CHR1 in the leftmost digit location
'and then writes all 4 digits.

SHIFTOUT SDA, SCK, 0, [CHR1] 'SHIFTOUT CHR1-CHR4 to fill the display left to right
GOSUB AckSeq 'TM1637 auto-increment mode

SHIFTOUT SDA, SCK, 0, [CHR2]
GOSUB AckSeq

SHIFTOUT SDA, SCK, 0, [CHR3]
GOSUB AckSeq

SHIFTOUT SDA, SCK, 0, [CHR4]
GOSUB AckSeq
GOSUB StopSeq

GOSUB StartSeq
SHIFTOUT SDA, SCK, 0, [CMD3] 'The output sequence ends with CMD3 which turns on the display
GOSUB AckSeq 'and set the brightness duty cyle
GOSUB StopSeq

Return

'****************************************Subroutin e StartSeq****************************************** *************
StartSeq:
HIGH SCK
HIGH SDA 'The Start sequence takes SDA low and then SCK low 5 uSec later
PAUSEUS 5
LOW SDA
PAUSEUS 5
Return

'**************************************Subroutine AckSeq******************************************** *************
AckSeq:
LOW SCK 'The ACK waits for the TM1637 to assert low on SDA
PAUSEUS 5 'and then replies with a 5 uSec ACK pulse on SCK
IF SDA = 0 THEN
HIGH SCK
PAUSEUS 5
LOW SCK
ENDIF
Return

'****************************************Subroutin e StopSeq******************************************* ***********
StopSeq:
LOW SCK 'The stop sequence takes SCK high and then SDA high 5 uSec later
LOW SDA
PAUSEUS 5
HIGH SCK
PAUSEUS 5
HIGH SDA
PAUSEUS 5
LOW SDA
Return

'*****************************************End of Subroutine Programs****************************************** ****

ChuckR
- 24th February 2020, 22:30
Following my original post and code example, I hand-wired a 4x4 pushbutton keypad into the TM1637 to experiment with its key scanning capability. The attached photo shows how this turned out.
I interfaced this display keypad with a Microchip Curiosity Board for code development and discovered a problem with the original code that was apparently a collision between the change in uC, the PBP Shiftout command, bit-banging and port pin propagation delay. In other words, I think I encountered a "read-modify-write" episode.
In the code example provided here, I've remedied this problem by using the "LATx.x" function instead of "PORTx.x" in the bit-banging subroutines. This is explained a bit more in the header commentary.
The keypad code shifts in the key byte, derives a 2-digit number "01" through "16", and displays the number on the display.



'************************************************* *******************
'* Name : TM1637_Include_File_CB_Keys.PBP *
'* Author : Roberts *
'* Notice : Hack it as you wish *
'* : *
'* Date : 12/06/2019 *
'* Version : 1.0 *
'* Notes : Include File Library for TM1637 Write Subroutine *
'* : THIS VERSION FOR MICROCHIP CURIOSITY BOARD PIC16F1619 *
'* : This version adds TM1637 Key Scan Reading *
'************************************************* *******************
' THIS IS A REVISED TM1637 DEMO PROGRAM DEVELOPED WHILE PORTING THE ORIGINAL PROGRAM TO THE CURIOSITY BOARD AND ITS
' PIC16F1619. AS ORIGINALLY WRITTEN, THE PROGRAM DID NOT OUTPUT CORRECTLY TO THE DISPLAY DUE TO APPARENT INTERFERENCE
' ON THE SDA AND SCK PINS WHEN THESE PINS EXIST ON THE SAME PORT. THIS TURNED OUT TO BE A READ/MODIFY/WRITE PROBLEM
' THAT WAS AFFECTED BY THE STARTSEQ, ACKSEQ, AND STOPSEQ BIT BANGING. THIS PROBLEM WAS REMEDIED BY DECLARING ADDITIONAL
' VARIABLES SDA1 AND SCK1 AS LATX.X's WHILE KEEPING THE ORIGINAL VARIABLES USED BY THE SHIFTOUT COMMAND, SDA AND SCK,
' AS PORTX.X's. THIS ALLOWS THE BIT BANGING TO OCCUR WITHOUT THE READ/MODIFY/WRITE COMPLICATIONS.
' SOLVING THIS PROBLEM WAS EVASIVE BECAUSE THE ORIGINAL PROGRAM WORKED WHEN SDA AND SCK USED PORTS C.4 AND C.5 ON THE
' pic16F1619, BUT NOT WHEN ANY OTHER COMMON PORT PINS WERE USED. THE ORIGINAL PROGRAM DID WORK WHENEVER SDA AND SCK
' WERE ON DIFFERENT PORTS.
'
' The subroutine LEDOUT implements the write sequence consisting of a write command (CMD1=$40) followed by the address
' command (CMD2=$C0), the 4 digits CHR1 - CHR4, and terminating with CMD3=$8A which turns the display ON and sets its
' brightness level. The PBP command SHIFTOUT is used to send these commands and characters, thus avoiding bit-banging
' them.
'
' The 3 subroutines StartSeq, AckSeq, and StopSeq perform the requisite bit banging on the SDA and SCK outputs before
' and after the PBP SHIFTOUT command.
'
' This demo code writes to all 4 digits in the TM1637's "auto-increment" mode. The digits could be individually
' addressed using the TM1637's "fixed address" mode (see TM1637 spec sheet).
'
' This code works with a 4-digit TM1637 based LED display that has handwired into a 16 key keypad arranged in in an
' 8x2 wired matrix per the TM1637 spec sheet. LED and keypad assemblies are available in similar wiring arrangements
' (usually 6 digits and 6 switches), and this code should be adaptable. There are also TM1628 based displays and
' keypad assemblies, but the TM1638 uses a different 3-wire interface, so this code is not TM1638 compatible.
'
' This program initially writes "----" to the display. When any of the 16 keys are pressed, the key number (01 - 16)
' is display on the center 2 digit locations, such as "-06-" for switch number 6. The switch number remains on the
' display until the key is released, whereupon the display returns to "----".
'
' A utility LED flashes at 5/sec on/off to indicate looping. Key response can be altered by changing/deleting this.
'
' A THORUGH READING AND COMPREHENSION OF THE TM1637 DATA SHEET IS HELPFUL!
'
' Below are the hexadecimal segment codes corresponding to decimal values
'
' 0 1 2 3 4 5 6 7 8 9
' 0x3F 0x06 0x5B 0x4F 0x66 0x6D 0x7D 0x07 0x7F 0x67
'
'********************************Declare Variables and Constants***************************************** *****
'
' Place the PIC initialization INCLUDE file here (See PBP PIC Configuration Files)
INCLUDE "PIC16F1619_Initialize.pbp"
'


ANSELB = 000000
TRISB = 000000




SDA Var PORTB.4 'Serial data port pin
SCK Var PORTB.6 'Serial clock port pin
SDA1 Var LATB.4 'Serial data latch
SCK1 Var LATB.6 'Serial clock latch
HIGH SDA


'These are the 4 commands used by the TM1637 controller:
CMD1 CON $40 'CMD1=$40 is the write command
CMD2 CON $C0 'CMD2=$C0 is the start digit position(left most)
CMD3 CON $8A 'CMD3=$8A is the end command that turns the display on and sets brightness
'(CMD3=$8F for max brightness - see TM1637 spec sheet)
CMD4 CON $42 'CMD4=$42 is the read key command



KEYNO VAR BYTE 'KEYNO is the byte value from the keypad
CHR1 CON $40 'Characters 1 and 4 are set to "-"
CHR4 CON $40
CHR2 VAR BYTE 'The key number 1 through 16 are displayed as characters 2 and 3
CHR3 VAR BYTE
CHR2 = $40 : CHR3 = $40 'Characters 2 and 3 are initialized as "-"
'
'************************************Subrouting LEDOUT******************************************** *************
'
LEDOUT: 'This subrountine outputs all 4 characters to the LED
GOSUB StartSeq 'SHIFTOUT Mode 0 works - LSB first, clock normally low
SHIFTOUT SDA, SCK, 0, [CMD1] 'This shifts out the 8-bit write command character $40
GOSUB AckSeq
GOSUB StopSeq

GOSUB StartSeq 'This shifts out the 8-bit command character $C0 that places
SHIFTOUT SDA, SCK, 0, [CMD2] 'the first character CHR1 in the leftmost digit location
GOSUB AckSeq 'and then writes all 4 digits.

SHIFTOUT SDA, SCK, 0, [CHR1] 'SHIFTOUT CHR1-CHR4 to fill the display left to right
GOSUB AckSeq 'TM1637 auto-increment mode

SHIFTOUT SDA, SCK, 0, [CHR2]
GOSUB AckSeq

SHIFTOUT SDA, SCK, 0, [CHR3]
GOSUB AckSeq

SHIFTOUT SDA, SCK, 0, [CHR4]
GOSUB AckSeq
GOSUB StopSeq

GOSUB StartSeq
SHIFTOUT SDA, SCK, 0, [CMD3] 'The output sequence ends with CMD3 which turns on the display
GOSUB AckSeq 'and set the brightness duty cyle
GOSUB StopSeq

HIGH PortA.2 'Flash utility LED to indicate program is looping while idle
PAUSE 100 'Delete, change port assignment or comment out if not desired
LOW PORTA.2
PAUSE 100

'The following section of code reads the keypad byte. If no key is pressed the KEYNO byte default value is $FF
'Delete this section of code if keypad reading is not required
'************************************************* ************************************************** **************
GOSUB StartSeq 'Send StartSeq to TM1637
SHIFTOUT SDA, SCK, 0, [CMD4] 'Send the Read keypad command CMD4 = $42
GOSUB AckSeq 'Send AckSeq
SHIFTIN SDA, SCK, 0, [KEYNO] 'Shiftin the byte value as variable KEYNO (see TM1637 Data Sheet)
GOSUB AckSeq 'Send AckSeq
GOSUB StopSeq 'Send StopSeq

IF KEYNO = $FF THEN 'KEYNO = $FF means no key is pressed
CHR2 = $40 : CHR3 = $40 'Set 2nd & 3rd display characters to "-"
GOTO LEDOUT 'LEDOUT outputs "----" to the display
ELSE
KEYNO = KEYNO >> 4 'If KEYNO is not $FF, shift keypad matrix value right 4 bits
'Lookup characters 2 and 3 from keypad matrix value
'CHR2 will be either "0" or "1"
'CHR3 will be a value "0" through "9"
'Together CHR2 and CHR3 will display "01" through "16"

' Lookup command lists map the 4-bit keypad code to the 7-segment hex codes (see header comments) for key numbers
' "01" through "16" (see map table below)

LOOKUP KEYNO, [$06,$06,$06,$06,$3F,$3F,$3F,$3F,$06,$06,$3F,$06,$3 F,$3F,$3F,$3F], CHR2 '2nd display digit
LOOKUP KEYNO, [$7D,$6D,$4F,$66,$7F,$07,$6D,$7D,$5B,$06,$67,$3F,$6 6,$4F,$06,$5B], CHR3 '3rd display digit
ENDIF

' Each key has a unique 4-bit value KEYNO that is used to derive its decimal key number. Lookup commands map the KEYNO
' value (0000 to 1111) to the key number (1 to 16) 7-segment hex code. For example, S5's KEYNO value is 7, and requires
' "05" to be displayed. The 8th values in the Lookup lists are therefore CHR2 = 0x3F ("0") and CHR3 = 0x7D ("5").
'

' Key: S1 S2 S3 S4 S5 S6 S7 S8 Switch Numbers 1 - 8
' Matrix Loc: K1/SG1 K2/SG1 K2/SG5 K1/SG5 K1/SG2 K2/SG2 K2/SG6 K1/SG6 TM1637 Matrix Location
' Key Hex Code: 0xEF 0xF7 0xD7 0xCF 0x6F 0x77 0x57 0x4F Non-reversed hex code
' 4-bit Value: 0x0E 0x0F 0x0D 0x0C 0x06 0x07 0x05 0x04 Hex Code shifted right 4-bits
' CHR2: 0 0x3F 0 0x3F 0 0x3F 0 0x3F 0 0x3F 0 0x3F 0 0x3F 0 0x3F Digit value and LED 7 Seg Code
' CHR3: 1 0x06 2 0x5B 3 0x4F 4 0x66 5 0x6D 6 0x7D 7 0x07 8 0x7F Digit value and LED 7 Seg Code
' Lookup: 15 16 14 13 7 8 6 5 Place in Lookup List
' = DEC[4-bit value +1]


' Key: S9 S10 S11 S12 S13 S14 S15 S16 Switch Numbers 9 - 16
' Matrix Loc: K1/SG3 K2/SG3 K2/SG7 K1/SG7 K1/SG4 K2/SG4 K2/SG8 K1/SG8 TM1637 Matrix Location
' Key Hex Code: 0xAF 0xB7 0x97 0x8F 0x2F 0x37 0x17 0x0F Non-reversed hex code
' 4-bit Value: 0x0A 0x0B 0x09 0x08 0x02 0x03 0x01 0x00 Hex Code shifted right 4-bits
' CHR2: 0 0x3F 1 0x06 1 0x06 1 0x06 1 0x06 1 0x06 1 0x06 1 0x06 Digit value and LED 7 Seg Code
' CHR3: 9 0x67 0 0x3F 1 0x06 2 0x5B 3 0x4F 4 0x66 5 0x6D 6 0x7D Digit value and LED 7 Seg Code
' Lookup: 11 12 10 9 3 4 2 1 Place in Lookup List
' = DEC[4-bit value +1]

'************************************** End of Keypad Reading ************************************************** **

GOTO LEDOUT 'Loop forever and display the keypad number being pressed

'Subroutines StartSeq, AckSeq and StopSeq write to the port latches to avoid read/modify/write problems.
'****************************************Subroutin e StartSeq****************************************** *************
StartSeq:
HIGH SCK1
HIGH SDA1 'The Start sequence takes SDA1 low and then SCK1 low 5 uSec later
PAUSEUS 5
LOW SDA1
PAUSEUS 5
Return


'**************************************Subroutine AckSeq******************************************** *************
AckSeq:
SDA = PORTB.4
LOW SCK1 'The ACK waits for the TM1637 to assert low on SDA1
PAUSEUS 5 'and then replies with a 5 uSec ACK pulse on SCK1
IF SDA = 0 THEN
HIGH SCK1
PAUSEUS 5
LOW SCK1
ENDIF
Return


'****************************************Subroutin e StopSeq******************************************* ***********
StopSeq:
LOW SCK1 'The stop sequence takes SCK1 high and then SDA1 high 5 uSec later
LOW SDA1
PAUSEUS 5
HIGH SCK1
PAUSEUS 5
HIGH SDA1
PAUSEUS 5

Return


'*****************************************End of Subroutine Programs****************************************** ****

dtbarber
- 13th April 2020, 18:19
Thanks to all who posted code and provided comment. More informative than the datasheet.