Can anyone explain the flow chart or algorithm of the program attach? The program is about LCD clock but I don't know how it works. I need it by tomorrow so please help me take a look. Thanks
Jiro90 0 Newbie Poster
The attachment preview is chopped off after the first 10 KB. Please download the entire file.
;< LCD Clock - PIC16F84A and HD44780 Liquid Crystal Display >;
;This code assumes a 4MHz Xtal and has been tested on a ;
;PIC16f84A-04 and a HD44780 compatible 16x2 Liquid Crystal ;
;Display Module. For some reason, the second line of the ;
;display in my module was at address 40 decimal (28 hex). All ;
;data sheets I could find state this to be 64 decimal, i.e., ;
;40 hex. I might have found an oddball display, or somebody ;
;somewhere might just have become hexed and confused the dec ;
;and hex formats. ;
; ;
;Evidently, if you run into difficulties with that second ;
;line, you might have to experiment with the address of that ;
;seventeenth character. ;
; ;
; Or maybe a hex inverter might help. ;
; ;
processor 16f84A
radix hex
__config 0x3ff1 ;WDT OFF, pwrup timer ON, XT osc
;
;---------------------------------------------------------------
; Parameter equates
POSITION equ 0x04 ;middle of first line
;
;---------------------------------------------------------------
; cpu equates (memory map)
indf equ 0x00
tmr0 equ 0x01
pcl equ 0x02
status equ 0x03
fsr equ 0x04
porta equ 0x05 ;five lines available
portb equ 0x06
portc equ 0x07 ;not available
eedata equ 0x08
eeadr equ 0x09
pclath equ 0x0a
intcon equ 0x0b
option_reg equ 0x81
trisa equ 0x85
trisb equ 0x86
trisc equ 0x87 ;not available
eecon1 equ 0x88
eecon2 equ 0x89
;
;---------------------------------------------------------------
; bit equates
c equ 0
dc equ 1
z equ 2
rp0 equ 5
gie equ 7
;
;---------------------------------------------------------------
; Variables in RAM.
;---------------------------------------------------------------
;
safe_w equ 0x0c ;w stored here during int service
safe_s equ 0x0d ;status stored here likewise
flags equ 0x0e ;array of bits as semaphores
hours equ 0x0f ;00 to 23 BCD, display format
minutes equ 0x10 ;00 to 59 BCD, display format
seconds equ 0x11 ;00 to 59 BCD, display format
timeout equ 0x12 ;notify int timeouts
tick_hi equ 0x13 ;incremented each interrupt
tick_lo equ 0x14 ;
count1 equ 0x15 ;delay counter and
count2 equ 0x16 ;temporary storage
lcdbuf equ 0x17 ;Start of Display buffer area
;
;---------------------------------------------------------------
;Port A definitions
;---------------------------------------------------------------
PORTA_CONF equ 0 ; all outputs
BLINK equ 4 ;Flashing LED for seconds - connect
;between Vcc and RA4 with a 470 ohm
;series resistor. Serves to check
;whether the PIC is running, if
;the display remains blank.
;
LCD_EN equ 1 ;Enable input of the LCD module
LCD_RS equ 0 ;Register Select of the LCD module
;---------------------------------------------------------------
; Port B definitions - keys for setting the time
;---------------------------------------------------------------
PORTB_CONF equ 0x0f
MIN_SET equ 0 ;Minutes set button----------- IN
TEN_SET equ 1 ;Set Tens of MIN-------------- IN
HR_SET equ 2 ;Hours set button------------- IN
TENH_SET equ 3 ;Set Tens of Hours------------ IN
;
; RB4 -- DB4 ;The higher nibble of Port B--OUT
; RB5 -- DB5 ;connects to the higher order-OUT
; RB6 -- DB6 ;four data lines of the-------OUT
; RB7 -- DB7 ;Liquid Crystal Display-------OUT
;===============================================================
;
; PROGRAM CODE STARTS HERE
;
;===============================================================
; Start of ROM
;---------------------------------------------------------------
org 0x00 ;Start of code space
call Ram_init ;set variables to nice values
call Timer_init ;start timer based interrupt
call Port_init ;set the ports as needed
goto Start ;the rest of the startup sequence
;---------------------------------------------------------------
; INTERRUPT SERVICE ROUTINE
;---------------------------------------------------------------
org 0x04 ;interrupt vector
Intsvc
movwf safe_w ;save w
swapf status,w ;exchange w and f
movwf safe_s ;save status with swapped nibbles
;---------------------------------------------------------------
; done saving, now start working
;---------------------------------------------------------------
movlw 0x08 ;****CHANGE FOR OTHER XTAL FREQ****
addwf tmr0,f ; 4MHz = 4 x 250 x 4000 Hz
incf tick_lo,f ; adjust timer reload value
btfsc status,z ; to make it count to 250 giving
incfsz tick_hi,f ; 4000 interrupts every second.
goto Tick_out ; Increment the tick each time.
;---------------------------------------------------------------
; here? tick has rolled over to zero and one second
; has passed. Reload tick and increment timeout counter
;---------------------------------------------------------------
movlw 0xf0 ;4000 = 0x0FA0
movwf tick_hi ;0 - 0x0FA0 = 0xF060
movlw 0x60
movwf tick_lo
incf timeout,f ;increment timeout counter
;---------------------------------------------------------------
; done working, start restoring
;---------------------------------------------------------------
Tick_out
swapf safe_s,w ;fetch status, reswap nibbles
movwf status ;restore status
swapf safe_w,f ;swap nibbles in preparation
swapf safe_w,w ;for the swap restoration of w
bcf intcon,2 ;clear interrupt flag before
retfie ;returning from interrupt
;===============================================================
; SUBROUTINES START HERE
;===============================================================
; clear important bits of ram
;---------------------------------------------------------------
Ram_init
movlw 0xf0
movwf tick_hi
movlw 0x60
movwf tick_lo
movlw 0x12 ;clocks always start
movwf hours ;at 12:00. It's official.
movlw 0x00
movwf minutes
movwf seconds
movwf flags
movwf timeout
return
;---------------------------------------------------------------
; get timer-based interrupts going
;---------------------------------------------------------------
Timer_init
bcf intcon,2 ;clear tmr0 int flag
bsf intcon,gie ;enable global interrupts
bsf intcon,5 ;enable tmr0 int
movlw 0x58 ;set up timer. No prescaler
option ;Port B pullups enabled - WARNING:
clrf tmr0 ;start timer - Use of this instruction
return ; - is not recommended
;---------------------------------------------------------------
; Port initialiser
;---------------------------------------------------------------
Port_init
bsf status,rp0 ;select correct bank
movlw PORTA_CONF
movwf trisa^80h ;flip highest bit of address
movlw PORTB_CONF ;to suppress that message about
movwf trisb^80h ;ensuring bank bits being correct
bcf status,rp0 ;back to bank zero
return
;---------------------------------------------------------------
; Initialise Liquid Crystal Display Module
;---------------------------------------------------------------
Lcd_init
bcf porta,LCD_EN ;E line low
bcf porta,LCD_RS ;RS line low, set up for control
movlw 0x3f ;8-bit, 5X7
call Pulse ;enable pulse, then wait some time
movlw 0x3f ;the previous instruction might have
call Pulse ;been ignored, so send the same thing
movlw 0x3f ;again two more times just to make
call Pulse ;sure the module gets the right idea.
movlw 0x2f ;4-bit, 5x7
call Pulse ;LCD is now in 4 bit mode. Succeeding
;instructions and data must be in
;two writes per transfer
;
movlw 0x0f
call Pulse
movlw 0xff ;display on - instruction 0F
call Pulse
;
movlw 0x0f
call Pulse
movlw 0x6f ;increment mode, no display shift - 06
call Pulse
;delay 5 milliseconds - required
goto del_5 ;before sending data
;---------------------------------------------------------------
; Fill Display Buffer area with Blanks
;---------------------------------------------------------------
Blank
movlw lcdbuf
movwf fsr
movlw 0x20 ;32 spaces to be stored starting at lcdbuf
movwf count1 ;0x20 happens to be the code for
;movlw ' ' ;ASCII space. Clever, huh?
loop
movwf indf
incf fsr,f
decfsz count1,f
goto loop
return
;===============================================================
; End of Initialise code. Main routines start here
;===============================================================
; increment seconds or minutes modulo 60 and hours modulo 24
;---------------------------------------------------------------
BCDCount
movlw 0x99
goto test ;modulo hundred for BCD Counter
Mod24
movlw 0x23
goto test
Mod60
movlw 0x59
test
xorwf indf,w
btfsc status,z
goto carry
movlw 0x07
addwf indf,w ;try adding 7
btfss status,dc ;digit carry?
addlw 0xfa ;no, take away six: 256 - 6 = 0xfa
movwf indf ;store
ret
wildgoose 420 Practically a Posting Shark
Sorry, too late for me tonight to pick this thing apart!
What flowchart?
The LCD is a 16x2,
The PIC uses 32 byte LCD shadow buffer in ram.
RA4 = LED L=On H=Off
RA1 = LCD Enable 1=Enable __/--\__
RA0 = RS 0=instruction 1=data
RB4...RB7 (out) are upper 4 bits of data to LCD
RB3 (in) Tens of hours Button
RB2 (in) Hours Button
RB1 (in) Tens minute Button
RB0 (in) Minutes Button
Has four buttons for setting time on PortB 0...3
Jiro90 0 Newbie Poster
Thanks, but that all the program works? It seems to be very long program. And also did the program mention about the LCD clock is in Parallel connection or Serial Connection?
wildgoose 420 Practically a Posting Shark
It'sin parallel. The Enable pin is more like a clock, as it clocks in the data. The part I didn't see is that it has eight data lines. The upper 8-bits are connected to Port B RB4-RB7. The chip has an 8-bit and 4-bit operation, and its being used in 4-bit mode. The upper four bits are transferred first, then the lower four bits. The chip uses pin RB7 as a handshake pin to indicate that write has been completed! The chip can read and write.
I'm not sure how the chip knows its in 4-bit versus 8-bit mode! It may be related to the timing sequence. It appears that its timing based, 8-bit uses one enable pulse, and 4-bit uses two enable pulse. The falling edge is the trigger to start the operration.
The LCD has a reprogrammable 256 character generator for changing the font characters.
The code stores its hour, min, second in BCD and then convert it to ASCII and store it in the LCD shadow. Then when a change occurs, clocks the 32 character data bytes from the shadow into the LCD display buffer. You set the write data address but the chip has an auto-increment so once a memory address has been clocked, it advances to the next.
Here's a link I found to the LCD chip.
Read the specs.
http://pdf1.alldatasheet.com/datasheet-pdf/view/63673/HITACHI/HD44780.html
Be a part of the DaniWeb community
We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.