Code:
	'********************************************************************
'*  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,$3F,$3F,$3F,$3F], CHR2   '2nd display digit
      LOOKUP KEYNO, [$7D,$6D,$4F,$66,$7F,$07,$6D,$7D,$5B,$06,$67,$3F,$66,$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.
'****************************************Subroutine 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
'****************************************Subroutine 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**********************************************
 
				
Bookmarks