Code:
' 12F1840 Pinout:
' -------------------------------------------------------
' VDD VSS
' PortA.5 = Not_used PortA.0 = LED
' PortA.4 = Not_used PortA.1 = DIO
' PortA.3 = Not_used PortA.2 = CLK
' -------------------------------------------------------
#CONFIG
__config _CONFIG1, _FOSC_INTOSC & _MCLRE_ON & _CP_OFF & _CPD_OFF
__config _CONFIG2, _PLLEN_OFF & _LVP_OFF
#ENDCONFIG
OSCCON = %01111000 '16MHz HF, software PLL disabled
DEFINE OSC 16
'Port direction
TRISA = %001000 'A.3 is input, rest are outputs.
ANSELA = 0 'Disable A to D
CM1CON0 = 0 'Disable comparator
USERCOMMAND "DISPLED" ; BUFFER{,COLON } TAKES 150uS FOR 4 DIGITS
USERCOMMAND "STRLEN" ; BUFFER
USERCOMMAND "RJUSTBUFF" ; BUFFER
;ALL NEED TO BE IN SAME BANK
TM_BIT VAR BYTE BANK0
TM_DAT VAR BYTE BANK0
TM_NAK VAR BYTE BANK0 ;set to $80 if tx error occured
TM_DIG VAR BYTE BANK0
TM_BRIGHT VAR BYTE BANK0 ;display pwm level 0 to 7
TM_COLON VAR BYTE BANK0 ;display colon 0/1
TM_TMP VAR BYTE[2] BANK0
str_len VAR BYTE BANK0
;tm1637 CONSTANTS
CMD_AUTO_ADDR CON $40
START_ADDR CON $c0
NUM_DIGITS CON 4 ;number of 7seg leds
COLON_FLAG CON $80
DISPLAY_ON CON $88
;tm1637 DIO AND CLK NEED TO BE ON SAME PORT
@TM_OUT_PORT = LATA ;TM_DIO OUT
@TM_IN_PORT = PORTA ;TM_DIO IN
@TM_CLK = 2 ;PIN
@TM_DIO = 1 ;PIN
@TM_TRIS = TRISA
BLINK VAR BYTE
LEDBUFF VAR BYTE[NUM_DIGITS +1]
COUNTER VAR byte
Cnt var byte ;for use in loops
LED var LATA.0
'Diagnostic routine
DiagRoutine:
for cnt = 1 to 3 'Blink LED 3 times.
led = 1 : pause 500
led = 0 : pause 500
next cnt
GOTO OVERASM
ASM
DISPLED?B macro BUFFER
movlw low BUFFER
movwf FSR0L
movlw high BUFFER
movwf FSR0H
L?CALL _TM_DISP4
endm
DISPLED?BC macro BUFFER ,COLON
movlw low BUFFER
movwf FSR0L
movlw high BUFFER
movwf FSR0H
CHK?RP _TM_COLON
MOVE?CB COLON ,_TM_COLON
L?CALL _TM_DISP4
endm
DISPLED?BB macro BUFFER ,COLON
movlw low BUFFER
movwf FSR0L
movlw high BUFFER
movwf FSR0H
CHK?RP _TM_COLON
MOVE?BB COLON ,_TM_COLON
L?CALL _TM_DISP4
endm
STRLEN?B macro BUF
MOVE?CB high BUF, FSR0H ;load highbyte
MOVE?CB low BUF, FSR0L ;load low byte
L?CALL STRlen
endm
RJUSTBUFF?B macro BUF
MOVE?CB high BUF, FSR0H ;load highbyte
MOVE?CB low BUF, FSR0L ;load low byte
CHK?RP _TM_TMP
MOVE?CB low BUF, _TM_TMP ;load low byte
MOVE?CB HIGH BUF, _TM_TMP+1 ;load low byte
L?CALL STRlen
L?CALL _strpad
endm
STRlen ;get buffer usage size
CHK?RP _str_len
CLRF _str_len
str_tok_chr
MOVIW FSR0 ++ ; Get character
btfsC STATUS,Z
goto exit_str_null ; EXIT ON Null char
INCF _str_len,F ; not null so increment index
goto str_tok_chr
exit_str_null
BANKSEL 0
return
_strpad ;right justify by padding with spaces " "
CHK?RP _str_len
movlw _NUM_DIGITS+1 ;buffer size
subwf _str_len,f ;tx string size
btfsc STATUS, C ;tx string size gotcha
goto expd ;if positive difference then exit buffer overrun will occur ;tx string size gotcha
comf _str_len,f ;the difference is number of spaces to SHIFT in
btfsc STATUS, Z
goto expd ;if zero difference then exit
movlw _NUM_DIGITS ;buffer size
addwf _TM_TMP,f ;add NUM_DIGITS to addr of buffer
nxpd
movf _TM_TMP,w ;low (addr of buffer + NUM_DIGITS )
MOVWF FSR0L
movwf FSR1L
movf _TM_TMP+1,w ;high (addr of buffer + NUM_DIGITS )
MOVWF FSR0H
movwf FSR1H
DECF FSR0L,F ;offset pointer 0
movlw _NUM_DIGITS
movwf _TM_BIT
nxby ;buffer shift right x 1
MOVIW FSR0 --
MOVWI FSR1 --
DECFSZ _TM_BIT,F
GOTO nxby
movlw 0x20
MOVWI FSR1 -- ;poke a space in buff[0]
DECFSZ _str_len,F ;need another one ?
goto nxpd
expd ;nah!
BANKSEL 0
return
SEG_val ;VALID INPUT 0-9 ,A-F, a-f ," " ,-
CHK?RP _TM_TMP
MOVWF _TM_TMP
SUBLW 0x21
btfsc STATUS, C
retlw 0 ;" "
MOVF _TM_TMP,W
SUBLW 0x2f
btfsc STATUS, C
retlw 64 ;"-"
MOVF _TM_TMP,W
MOVLW 0X40
SUBWF _TM_TMP,W
btfsC STATUS, C
GOTO TM_ALPHA
MOVF _TM_TMP,W
ANDLW 0X0F
GOTO TM_LU
TM_ALPHA
ANDLW 0xdf ;ucase
SUBLW 6
btfsS STATUS, C
retlw 0 ;ERROR
MOVLW 0X37
SUBWF _TM_TMP,W
ANDLW 0xdf ;ucase
TM_LU
BRW
retlw 0X3F ;0
retlw 6
retlw 0X5B
retlw 0X4F
retlw 0X66
retlw 0X6D
retlw 0X7D
retlw 7
retlw 0X7F
retlw 0X67 ;9
retlw 0X77 ;A
retlw 0X7C ;b
retlw 0X39 ;C
retlw 0X5E ;d
retlw 0X79 ;E
retlw 0X71 ;F
TM_START
CHK?RP TM_OUT_PORT
BSF TM_OUT_PORT,TM_CLK
BSF TM_OUT_PORT,TM_DIO
NOP
BCF TM_OUT_PORT,TM_DIO
NOP
BCF TM_OUT_PORT,TM_CLK
;NOP
RETURN
TM_STOP
CHK?RP TM_OUT_PORT
BCF TM_OUT_PORT,TM_CLK
BCF TM_OUT_PORT,TM_DIO
NOP
BSF TM_OUT_PORT,TM_CLK
NOP
BSF TM_OUT_PORT,TM_DIO
;NOP
RETURN
TM_WRITE
MOVLW 8
CHK?RP _TM_BIT
MOVWF _TM_BIT
NXBT
CHK?RP TM_OUT_PORT
BCF TM_OUT_PORT,TM_CLK
CHK?RP _TM_DAT
BTFSS _TM_DAT,0
GOTO TM_0
CHK?RP TM_OUT_PORT
BSF TM_OUT_PORT,TM_DIO
GOTO TM_NB
TM_0
CHK?RP TM_OUT_PORT
BCF TM_OUT_PORT,TM_DIO
TM_NB
CHK?RP _TM_DAT
RRF _TM_DAT,F
CHK?RP TM_OUT_PORT
BSF TM_OUT_PORT,TM_CLK
CHK?RP _TM_BIT
DECFSZ _TM_BIT,F
GOTO NXBT
CHK?RP TM_OUT_PORT
BCF TM_OUT_PORT,TM_CLK
CHK?RP TM_TRIS
BSF TM_TRIS,TM_DIO
CHK?RP TM_IN_PORT
BTFSC TM_IN_PORT,TM_DIO
BSF _TM_NAK,7
CHK?RP TM_OUT_PORT
BSF TM_OUT_PORT,TM_CLK
NOP
NOP
NOP
NOP
BCF TM_OUT_PORT,TM_CLK
CHK?RP TM_TRIS
BCF TM_TRIS ,TM_DIO
BANKSEL 0
RETURN
_TM_INIT
CHK?RP _TM_COLON
CLRF _TM_COLON
CLRF _TM_BRIGHT
CHK?RP TM_TRIS
BCF TM_TRIS ,TM_DIO
BCF TM_TRIS ,TM_CLK
BANKSEL 0
RETURN
_TM_DISP4
CHK?RP _TM_DAT
MOVLW _CMD_AUTO_ADDR
MOVWF _TM_DAT
CLRF _TM_NAK
CALL TM_START
CALL TM_WRITE
CALL TM_STOP
MOVLW _NUM_DIGITS
CHK?RP _TM_DIG
MOVWF _TM_DIG
MOVLW _START_ADDR
CHK?RP _TM_DAT
MOVWF _TM_DAT
CALL TM_START
CALL TM_WRITE
NXDIG
MOVIW FSR0 ++
CALL SEG_val
CHK?RP _TM_DAT
IORWF _TM_COLON ,W
movwf _TM_DAT
CALL TM_WRITE
CHK?RP _TM_DIG
DECFSZ _TM_DIG,F
GOTO NXDIG
CALL TM_STOP
CHK?RP _TM_BRIGHT
MOVF _TM_BRIGHT ,W
ANDLW 7
IORLW _DISPLAY_ON
CHK?RP _TM_DAT
MOVWF _TM_DAT
CALL TM_START
CALL TM_WRITE
CALL TM_STOP
BANKSEL 0
RETURN
ENDASM
OVERASM:
CALL TM_INIT
ALOOP:
TM_BRIGHT=TM_BRIGHT-1
if TM_BRIGHT>7 then TM_BRIGHT=7
ARRAYWRITE LEDBUFF ,["b- ",#TM_BRIGHT,0]
DISPLED LEDBUFF,0
PAUSE 500
FOR COUNTER=0 TO 255
ARRAYWRITE LEDBUFF ,[dec COUNTER,0]
RJUSTBUFF LEDBUFF
DISPLED LEDBUFF,0
PAUSE 50
NEXT
FOR COUNTER=0 TO 255
IF !(COUNTER//20) THEN BLINK = TM_COLON ^ COLON_FLAG
ARRAYWRITE LEDBUFF ,[sdec COUNTER,0]
RJUSTBUFF LEDBUFF
DISPLED LEDBUFF,BLINK
PAUSE 50
NEXT
GOTO ALOOP
Bookmarks