bananasiong
New Member
Hi,
I'm using PIC16F628A for displaying the LCD clock. I've just started and I'm using timer2 interrupt for counting the real time. I've set the interrupt rate to be 40 ms. So I need to count for 25 times to get 1 second accurate.
Postscale 10
Prescale 16
4 MHz crystal = 1 us per instruction
PR2 249
So, 10 * 16 * 250 * 1 us = 40 ms
When I turn on the power, the clock is running, faster than as expected which is almost 2 to 3 times faster.
This is the code I have:
Besides, I've found that the content of the general purpose registers are not zero as default. I thought that they are I have to clear them in initialize.
Thanks
I'm using PIC16F628A for displaying the LCD clock. I've just started and I'm using timer2 interrupt for counting the real time. I've set the interrupt rate to be 40 ms. So I need to count for 25 times to get 1 second accurate.
Postscale 10
Prescale 16
4 MHz crystal = 1 us per instruction
PR2 249
So, 10 * 16 * 250 * 1 us = 40 ms
When I turn on the power, the clock is running, faster than as expected which is almost 2 to 3 times faster.
This is the code I have:
Code:
LIST P=16F628A
#include <P16F628A.inc>
ERRORLEVEL 0, -302
__config 0x3101
cblock 0x20
count
count1
counta
countb
templcd
CountL1
CountL2
count1sec
HourTen
HourOne
MinTen
MinOne
SecTen
SecOne
L1C0 ;line1, column 0, and so on..
L1C1
L1C2
L1C3
L1C4
L1C5
L1C6
L1C7
L1C8
L1C9
L1C10
L1C11
L1C12
L1C13
L1C14
L1C15
L2C0
L2C1
L2C2
L2C3
L2C4
L2C5
L2C6
L2C7
L2C8
L2C9
L2C10
L2C11
L2C12
L2C13
L2C14
L2C15
w_temp
s_temp
p_temp
endc
LCD_PORT Equ PORTA
LCD_TRIS Equ TRISA
LCD_RS Equ 0x04 ;LCD handshake lines
LCD_E Equ 0x00
org 0x0000
goto Initialize
org 0x0004
Interrupt
movwf w_temp
swapf STATUS, w
clrf STATUS
movwf s_temp
movf PCLATH, w
movwf p_temp
clrf PCLATH
Check1sec
decf count1sec, f
btfss STATUS, Z ;interrupt happens 25 times?
goto Display ;if no display with the same value
movlw d'25' ;if yes count for 1 second
movwf count1sec
StartCount
movf SecOne, w
xorlw d'9'
btfss STATUS, Z
goto ISO
goto ReSO
ISO
incf SecOne, f
goto CValue
ReSO
clrf SecOne
movf SecTen, w
xorlw d'5'
btfss STATUS, Z
goto IST
goto ReST
IST
incf SecTen, f
goto CValue
ReST
clrf SecTen
movf MinOne, w
xorlw d'9'
btfss STATUS, Z
goto IMO
goto ReMO
IMO
incf MinOne, f
goto CValue
ReMO
clrf MinOne
movf MinTen, w
xorlw d'5'
btfss STATUS, Z
goto IMT
goto ReMT
IMT
incf MinTen, f
goto CValue
ReMT
clrf MinTen
movf HourTen, w
btfss STATUS, Z
goto CHO
movf HourOne, w
xorlw d'9'
btfss STATUS, Z
goto IHO
goto ReHO
IHO
incf HourOne, f
goto CValue
ReHO
clrf HourOne
incf HourTen, f
goto CValue
CHO
movf HourOne, w
xorlw d'2'
btfss STATUS, Z
goto IHO
clrf HourOne
decf HourOne, f
goto CValue
CValue
movf HourTen, w
movwf L2C4
movf HourOne, w
movwf L2C5
movlw 0x0A
movwf L2C6
movf MinTen, w
movwf L2C7
movf MinOne, w
movwf L2C8
movlw 0x0A
movwf L2C9
movf SecTen, w
movwf L2C10
movf SecOne, w
movwf L2C11
Display
movf CountL2, w
xorlw d'12'
btfsc STATUS, Z
call RestoreCL2
movf CountL2, w
call LCD_Line2
movf INDF, w
call ILCD_Char
incf CountL2, f
incf FSR
call LCD_Line1
goto Int_Re
RestoreCL2
movlw d'4'
movwf CountL2
movlw L2C4
movwf FSR
return
ILCD_Cmd movwf templcd
swapf templcd, w ;send upper nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bcf LCD_PORT, LCD_RS ;RS line to 0
call Pulse_e ;Pulse the E line high
movf templcd, w ;send lower nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bcf LCD_PORT, LCD_RS ;RS line to 0
call Pulse_e ;Pulse the E line high
call Delay5
return
ILCD_Char
addlw 0x30
movwf templcd
swapf templcd, w ;send upper nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bsf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_e ;Pulse the E line high
movf templcd, w ;send lower nibble
andlw 0x0f ;clear upper 4 bits of W
movwf LCD_PORT
bsf LCD_PORT, LCD_RS ;RS line to 1
call Pulse_e ;Pulse the E line high
call Delay5
return
Int_Re
movf p_temp, w
movwf PCLATH
swapf s_temp, w
movwf STATUS
swapf w_temp, f
swapf w_temp, w
retfie
Initialize
movlw 0x07
movwf CMCON
bsf STATUS, RP0 ;bank1
movlw 0x00
movwf TRISA
movwf TRISB
bcf STATUS, RP0 ;bank0
call Delay100
LCD_Init
movlw 0x20 ;Set 4 bit mode
call LCD_Cmd
movlw 0x28 ;Set display shift
call LCD_Cmd
movlw 0x06 ;Set display character mode
call LCD_Cmd
movlw 0x0C ;Set display on and cursor off
call LCD_Cmd
call LCD_Clr ;clear display
clrf PORTA
movlw d'25' ;interrupt for 25 times = 1 second
movwf count1sec
movlw d'4'
movwf CountL2
movlw HourTen
movwf FSR
NEXT
clrf INDF
movf FSR, w
xorlw L2C15
btfsc STATUS, Z
goto $+3
incf FSR, f
goto NEXT
movlw L2C4
movwf FSR
movlw 0x0A
movwf L2C6
movwf L2C9
movlw b'01001111' ;postscale 10, prescale 16, tmr2 on
movwf T2CON
bsf STATUS, RP0
movlw d'249' ;1 us x 10 x 16 x 250 = 40 ms interrupt rate
movwf PR2
bsf PIE1, TMR2IE
bcf STATUS, RP0
bsf INTCON, PEIE
bsf INTCON, GIE
Start
;main program here
.
.
LCD_Line1 movlw 0x80 ;move to 1st row, first column
call LCD_Cmd
return
LCD_Line2 addlw 0xc0 ;move to 2nd row, first column
call LCD_Cmd
return
Delay255 movlw 0xff ;delay 255 mS
goto d0
Delay100 movlw d'100' ;delay 100mS
goto d0
Delay50 movlw d'50' ;delay 50mS
goto d0
Delay20 movlw d'20' ;delay 20mS
goto d0
Delay5 movlw 0x05 ;delay 5.000 ms (4 MHz clock)
goto d0
Delay4 movlw 0x04
goto d0
d0 movwf count1
d1 movlw 0xC7 ;delay 1mS
movwf counta
movlw 0x01
movwf countb
Delay_0
decfsz counta, f
goto $+2
decfsz countb, f
goto Delay_0
decfsz count1 ,f
goto d1
return
Pulse_e bsf PORTB, LCD_E
nop
bcf PORTB, LCD_E
return
LCD_Clr movlw 0x01 ;Clear display
call LCD_Cmd
return
end
Besides, I've found that the content of the general purpose registers are not zero as default. I thought that they are I have to clear them in initialize.
Thanks