| CODE |
; ;* Description: Counter with AT90S1200 AVR RISC Processor and LCD display, ;* with memory backup,Using 4-wire interface ;* Version: 1.0 ;* First writing: 02-01-2000 ;* Last Updated: 14-09-2001 ;* Target: AT 90s2313 ;* Author: Serasidis Vasilis ;* Support E-mail: info@serasidis.gr ;* Home page: http://www.serasidis.gr ;* ;* ;* ;* ;* ;*************************************************************************** .nolist ;Suppress listing of include file .include "1200def.inc" ;Define chip particulars .list ;***** Global register variables .def wreg =R16 ;General use working register .def timeout =R17 ;Timeout value passed to subroutine .def lcdstat =R18 ;LCD busy/wait status .def longtime=R19 ;Long timer for powerup .def monada=R20 ;monades .def deka=R21 ;dekades .def ekato=R22 ;ekatontades .def xilia=R23 ;xiliades .def test2=R24 ;Test2 register .def temp =R25 .def monada2=R26 ;monades from eeprom .def deka2=R27 ;dekades from eeprom .def ekato2=R28 ;ekatontades from eeprom .def xilia2=R29 ;xiliades from eeprom .def test=R30 ;test register ;***** Other equates .equ lcdrs =PD6 ;LCD rs pin connected to PD6 .equ lcdrw =PD5 ;LCD r/w pin connected to PD5 .equ lcde =PD4 ;LCD e pin connected to PD4 ; ;D4-D7 FROM LCD IS CONNECTED TO PORTD PD0-PD3 ; Timer/Counter prescaler values .equ EEMWE =2 .equ TCK256 =4 ;Timer/Counter runs from CK / 256 ;EEPROM related variables .def EErtmp =r25 ;temporary storage of address .def EEdrd_s =r1 ;result data byte .def EEwtmp =r24 ;temporary storage of address .def EEdwr_s =r31 ;data to write ; Main program entry point on reset reset: out TCCR0,wreg;Stop timer ldi wreg,0b00000010;Enable Timer 0 interrupt out TIMSK,wreg sei ;Enable interrupts ldi wreg,0xFF;Turn off all LEDs out PORTB,wreg ldi wreg,0xFF;Make port B pin all outputs out DDRB,wreg sbi ACSR,ACD;shut down comparator to save power ldi longtime,10;Wait 1.5 second for LCD power up ldi timeout,255;Delay 15 mS puwait: rcall delay dec longtime brne puwait main: rcall lcdinit ;Initialize LCD module rcall type_msg2 ldi longtime,200;Wait 1.5 second ldi timeout,255;Delay 15 mS puwait2: rcall delay dec longtime brne puwait2 ;============================================================= ldi EErtmp,0x3b ;Clear the temporary address out EEAR,EErtmp;Move the temporary address to EEAR rcall EERead_seq ;Get the data from EEPROM to xilia2 mov xilia,EEdrd_s rcall EERead_seq ;Get the data from EEPROM to ekato2 mov ekato,EEdrd_s rcall EERead_seq ;Get the data from EEPROM to deka2 mov deka,EEdrd_s rcall EERead_seq ;Get the data from EEPROM to monada2 mov monada,EEdrd_s from_telos: ldi EErtmp,0x04 ;Clear the temporary address out EEAR,EErtmp;Move the temporary address to EEAR rcall EERead_seq ;Get the data from EEPROM to xilia2 mov xilia2,EEdrd_s rcall EERead_seq ;Get the data from EEPROM to ekato2 mov ekato2,EEdrd_s rcall EERead_seq ;Get the data from EEPROM to deka2 mov deka2,EEdrd_s rcall EERead_seq ;Get the data from EEPROM to monada2 mov monada2,EEdrd_s rcall lcdclr ;Clear LCD screen rjmp pbwait f_pgm: ldi monada,0x30 ldi deka, 0x30 ldi ekato, 0x30 ldi xilia, 0x30 rcall lcdclr ;Clear LCD screen pbwait: rcall type_msg;Type the message keys: ldi wreg,0xc7;Set address to line 2,but 11 points right rcall lcdcmd sbis PINB,3 ;Check for PB4 (Power off ) rjmp store2 ;If the power its off, go to "store2" sbis PINB,5 ;Check for button PB5 (^)"programm" rjmp pgm ;If pressed goto programming (pgm) sbis PINB,6 ;Check for button PB6 "Reset" rjmp f_pgm ; sbic PINB,7 ; Pressed button PB7 ? rjmp keys ;If no check again cpi monada,0x39;Check if monada is overflowed breq zero_monada;If yes go to zero_monada mov wreg,xilia rcall lcdput ;Print on LCD the xilia mov wreg,ekato rcall lcdput ;Print on LCD the ekato mov wreg,deka rcall lcdput ;Print on LCD the deka inc monada mov wreg,monada rcall lcdput ;Print on LCD the monada rcall check_counts;Go to check if the current revolutions are ;the same with the stored. debounce: sbis PINB,7 ;Wait for button release PB7 rjmp debounce rjmp keys zero_monada: ldi monada,0x2f cpi deka,0x39 breq zero_deka inc deka rjmp pbwait zero_deka: ldi deka,0x30 cpi ekato,0x39 breq zero_ekato inc ekato rjmp pbwait zero_ekato: ldi ekato,0x30 cpi xilia,0x39 breq te ;zero_xilia inc xilia rjmp pbwait zero_xilia: ldi xilia,0x30 cpi xilia,0x3b breq te rjmp pbwait te: rjmp telos ;=============================================================== ; The messages table ;=============================================================== type_msg: ldi wreg,0x80;Set address to line 1 rcall lcdcmd ldi EErtmp,0x08 ;Clear the temporary address out EEAR,EErtmp;Move the temporary address to EEAR again: rcall EERead_seq ;Get the data from EEPROM to xilia2 mov wreg,eedrd_s rcall lcdput dec eedrd_s brne again ldi wreg,0xC0;Set address to line 2 rcall lcdcmd ldi WREG,' ' rcall lcdput mov wreg,xilia2 rcall lcdput ;print on LCD mov wreg,ekato2 rcall lcdput ;print on LCD mov wreg,deka2 rcall lcdput ;print on LCD mov wreg,monada2 rcall lcdput ;print on LCD ldi wreg,' ' rcall lcdput ;print on LCD ldi wreg,' ' rcall lcdput ;print on LCD mov wreg,xilia rcall lcdput ;print on LCD mov wreg,ekato rcall lcdput ;print on LCD mov wreg,deka rcall lcdput ;print on LCD mov wreg,monada rcall lcdput ;print on LCD ldi wreg,' ' rcall lcdput ;print on LCD ldi wreg,'1' rcall lcdput ;print on LCD ldi wreg,'.' rcall lcdput ;print on LCD ldi wreg,'0' rcall lcdput ;print on LCD ret ;return ;============================================================= ;*************************************************************************** ;* ;* EERead_seq ;* ;* This subroutine increments the address stored in EEAR and reads the ;* EEPROM into the register variable "EEdrd_s". ;* ;* ;*************************************************************************** EERead_seq: in EErtmp,EEAR ;get address out EEAR,EErtmp ;output address sbi EECR,EERE ;set EEPROM Read strobe ;This instruction takes 4 clock cycles since ;it halts the CPU for two clock cycles sbi EECR,EERE ;set EEPROM Read strobe 2nd time ;This instruction takes 4 clock cycles since ;it halts the CPU for two clock cycles in EEdrd_s,EEDR ;get data in EErtmp,EEAR ;get address inc EErtmp ;increment address out EEAR,EErtmp ;store it ret ;============================================================== ;*************************************************************************** ;* ;* EEWrite_seq ;* ;* This subroutine increments the EEPROM address by one and waits until the ;* EEPROM is ready for programming. It then programs the EEPROM with ;* register variable "EEdwr_s". ;* Number of words :1200; 7 + return ;* :8515; 10 + return ;* Number of cycles :1200; 10 + return (if EEPROM is ready) ;* :8515; 15 + return (if EEPROM is ready) ;* Low Registers used :None ;* High Registers used: :3 (EEdwr_s,EEwtmp,EEwtmph) ;* ;*************************************************************************** EEWrite_seq: ; Write sequence for 90S1200 sbic EECR,EEWE;if EEWE not clear rjmp EEWrite_seq; wait more out EEAR,EEwtmp out EEDR,EEdwr_s;output data sbi EECR,EEMWE;set master write enable sbi EECR,EEWE;set EEPROM Write strobe ;This instruction takes 4 clock cycles since ;it halts the CPU for two clock cycles inc EEwtmp ;increment address 8515 ret ;========================================================================= ; Clear entire LCD and delay for a bit lcdclr: ldi wreg,1 ;Clear LCD command rcall lcdcmd ldi timeout,255;Delay 15 mS for clear command rcall delay ret ; Initialize LCD module ;========================================================================= lcdinit: ldi wreg,0 ;Setup port pins out PORTD,wreg;Pull all pins low ldi wreg,0xff;All pins are outputs out DDRD,wreg ldi timeout,255;Wait at least 15 mS at power up rcall delay ldi wreg,3 ;Function set out PORTD,wreg ; rcall strobe ;Toggle enable line sbi PORTD,lcde;Toggle enable line cbi PORTD,lcde ldi timeout,65;Wait at least 4.1 mS rcall delay ldi wreg,3 ;Function set out PORTD,wreg ; rcall strobe ;Toggle enable line sbi PORTD,lcde;Toggle enable line cbi PORTD,lcde ldi timeout,2;Wait at least 100 uS rcall delay ldi wreg,3 ;Function set out PORTD,wreg ; rcall strobe ;Toggle enable line sbi PORTD,lcde;Toggle enable line cbi PORTD,lcde ldi wreg,2 ;Function set, 4 line interface out PORTD,wreg ; rcall strobe ;Toggle enable line sbi PORTD,lcde;Toggle enable line cbi PORTD,lcde ldi wreg,0b11110000;Make 4 data lines inputs out DDRD,wreg ; At this point, the normal 4 wire command routine can be used ldi wreg,0b00100000;Function set, 4 wire, 2 line, 5x7 font rcall lcdcmd ldi wreg,0b00001110;Display on, cursor on, blink off rcall lcdcmd ldi wreg,0b00000110;Address increment, no scrolling rcall lcdcmd ret ; Wait for LCD to go unbusy lcdwait: ldi wreg,0xF0;Make 4 data lines inputs out DDRD,wreg sbi PORTD,lcdrw;Set r/w pin to read cbi PORTD,lcdrs;Set register select to command waitloop: ;;rcall strobe sbi PORTD,lcde;Toggle enable line cbi PORTD,lcde in lcdstat,PIND;Read busy flag ;;rcall strobe ;Read, and ignore lower nibble sbi PORTD,lcde;Toggle enable line cbi PORTD,lcde sbrc lcdstat,3;Loop until done rjmp waitloop ret ; Send command in wreg to LCD lcdcmd: mov test,wreg rcall lcdwait ldi wreg,0xFF out DDRD,wreg mov wreg,test mov test,wreg swap wreg andi wreg,0X0F out portD,wreg sbi PORTD,lcde;Toggle enable line cbi PORTD,lcde mov wreg,test andi wreg,0x0F;Strip off upper bits out PORTD,wreg;Put on port sbi PORTD,lcde;Toggle enable line cbi PORTD,lcde ldi wreg,0xF0;Make 4 data lines inputs out DDRD,wreg ret ; Send character data in wreg to LCD lcdput: mov test,wreg ;Save character rcall lcdwait ;Wait for LCD to be ready ldi wreg,0xFF;Make all port D pins outputs out DDRD,wreg mov wreg,test ;Get character back mov test,wreg ;Save another copy swap wreg ;Get upper nibble andi wreg,0x0F;Strip off upper bits out PORTD,wreg;Put on port sbi PORTD,lcdrs;Register select set for data sbi PORTD,lcde;Toggle enable line cbi PORTD,lcde mov wreg,test ;Recall character andi wreg,0x0F;Strip off upper bits out PORTD,wreg;Put on port sbi PORTD,lcdrs;Register select set for data sbi PORTD,lcde;Toggle enable line cbi PORTD,lcde ldi wreg,0xF0;Make 4 data lines inputs out DDRD,wreg ret ;***** Delay n*64 microseconds using timer 0, delay time passed in timeout delay: ldi test,64 cagain: dec test brne cagain dec timeout brne delay ret ;================================================================= ; Here is the programming of revolutions ;================================================================= pgm: rcall delay sbis PINB,5 ;Wait for button release PB5 (^)"increase" rjmp pgm ;If didnt relish goto "pgm" rcall lcdclr ;Clear LCD screen ldi test2,0xc6 ldi wreg,0x80;Set address to line 1 rcall lcdcmd ldi wreg,'S' rcall lcdput ;print on LCD the xilia ldi wreg,'E' rcall lcdput ;print on LCD the xilia ldi wreg,'L' rcall lcdput ;print on LCD the xilia ldi wreg,'.' rcall lcdput ;print on LCD the xilia ldi wreg,' ' rcall lcdput ;print on LCD the xilia ldi wreg,'R' rcall lcdput ;print on LCD the xilia ldi wreg,'E' rcall lcdput ;print on LCD the xilia ldi wreg,'V' rcall lcdput ;print on LCD the xilia ldi wreg,'O' rcall lcdput ;print on LCD the xilia ldi wreg,'L' rcall lcdput ;print on LCD the xilia ldi wreg,'U' rcall lcdput ;print on LCD the xilia ldi wreg,'T' rcall lcdput ;print on LCD the xilia ldi wreg,'I' rcall lcdput ;print on LCD the xilia ldi wreg,'O' rcall lcdput ;print on LCD the xilia ldi wreg,'N' rcall lcdput ;print on LCD the xilia ldi wreg,'S' rcall lcdput ;print on LCD the xilia loop2: ldi wreg,0xc6;Set address to line 2 + 6 rcall lcdcmd mov wreg,xilia2 rcall lcdput ;print on LCD the xilia mov wreg,ekato2 rcall lcdput ;print on LCD the xilia mov wreg,deka2 rcall lcdput ;print on LCD the xilia mov wreg,monada2 rcall lcdput ;print on LCD the xilia ldi wreg,0xc6;Set address to line 2 + 6 rcall lcdcmd loop: sbic PINB,5 ;wait for button press PB5 (^)"increase" rjmp here ;If didnt pressed goto here cpi test2,0xc9 breq inc_monada2 cpi test2,0xc8 breq inc_deka2 cpi test2,0xc7 breq inc_ekato2 cpi test2,0xc6 breq inc_xilia2 here: sbis PINB,6 ;wait for button press PB6 (Reset) rjmp store ;If pressed go to "store" sbic PINB,4 ;Wait for button press PB4 (->)scroll the cersor rjmp loop ;if not go to next inc test2 mov wreg,test2;Set address to line 2 + 4 rcall lcdcmd cpi test2,0xca breq zero_test rel: rcall delay sbis PINB,4 ;Wait for button release PB4 (->)scroll the cersor rjmp rel rjmp loop zero_test: ldi test2,0xc5 rjmp rel inc_monada2: rcall delay sbis PINB,5 ;Wait for button relish PB5 (^)"increase" rjmp inc_monada2;If didnt release goto inc_monada2 inc monada2 mov wreg,monada2 rcall lcdput ;print on LCD the monada2 mov wreg,test2;Set address to line 2 + 4 rcall lcdcmd cpi monada2,0x39 breq zero_monada2 rjmp loop zero_monada2: ldi monada2,0x2f rjmp loop inc_deka2: rcall delay sbis PINB,5 ;Wait for button relish PB5 (^)"increase" rjmp inc_deka2;If didnt release goto inc_monada2 inc deka2 mov wreg,deka2 rcall lcdput ;print on LCD the monada2 mov wreg,test2;Set address to line 2 + 4 rcall lcdcmd cpi deka2,0x39 breq zero_deka2 rjmp loop zero_deka2: ldi deka2,0x2f rjmp loop inc_ekato2: rcall delay sbis PINB,5 ;Wait for button relish PB5 (^)"increase" rjmp inc_ekato2;If didnt release goto inc_monada2 inc ekato2 mov wreg,ekato2 rcall lcdput ;print on LCD the monada2 mov wreg,test2;Set address to line 2 + 4 rcall lcdcmd cpi ekato2,0x39 breq zero_ekato2 rjmp loop zero_ekato2: ldi ekato2,0x2f rjmp loop inc_xilia2: rcall delay sbis PINB,5 ;Wait for button release PB5 (^)"increase" rjmp inc_xilia2;If didnt release goto inc_monada2 inc xilia2 mov wreg,xilia2 rcall lcdput ;print on LCD the monada2 mov wreg,test2;Set address to line 2 + 4 rcall lcdcmd cpi xilia2,0x39 breq zero_xilia2 rjmp loop zero_xilia2: ldi xilia2,0x2f rjmp loop ;======================================================================= ; Store to EEprom routine ;======================================================================= store: ldi eewtmp,0x04 mov eedwr_s,xilia2 rcall eewrite_seq mov eedwr_s,ekato2 rcall eewrite_seq mov eedwr_s,deka2 rcall eewrite_seq mov eedwr_s,monada2 rcall eewrite_seq rjmp f_pgm ;if pressed goto "f_pgm"(its meen From_Pgm) store2: ldi eewtmp,0x3b mov eedwr_s,xilia rcall eewrite_seq mov eedwr_s,ekato rcall eewrite_seq mov eedwr_s,deka rcall eewrite_seq mov eedwr_s,monada rcall eewrite_seq ldi temp,0x30 ;turn on sleep mode (Power down mode) out MCUCR,temp ;interrupt on low level. ldi temp,0x40 ;enable external interrupts out GIMSK,temp sei ;enable global interrupts ready sleep ;go to sleep mode ;======================================================================= ; Its for reset the monada,deka.... ;====================================================================== ;======================================================================= ; This routine is to check if the current resisters (monada,xilia...) ; is the same with monada2,xilia2 ect. ;======================================================================= check_counts: cp monada,monada2 breq check_deka ret check_deka: cp deka,deka2 breq check_ekato ret check_ekato: cp ekato,ekato2 breq check_xilia ret check_xilia: cp xilia,xilia2 breq telos ret ;======================================================================= telos: rcall lcdclr ;Clear LCD screen ldi wreg,0x80;Set address to line 1 rcall lcdcmd ldi wreg,'R' rcall lcdput ;print on LCD the xilia ldi wreg,'E' rcall lcdput ;print on LCD the xilia ldi wreg,'V' rcall lcdput ;print on LCD the xilia ldi wreg,'O' rcall lcdput ;print on LCD the xilia ldi wreg,'L' rcall lcdput ;print on LCD the xilia ldi wreg,'U' rcall lcdput ;print on LCD the xilia ldi wreg,'T' rcall lcdput ;print on LCD the xilia ldi wreg,'I' rcall lcdput ;print on LCD the xilia ldi wreg,'O' rcall lcdput ;print on LCD the xilia ldi wreg,'N' rcall lcdput ;print on LCD the xilia ldi wreg,'S' rcall lcdput ;print on LCD the xilia ldi wreg,' ' rcall lcdput ;print on LCD the xilia ldi wreg,'E' rcall lcdput ;print on LCD the xilia ldi wreg,'N' rcall lcdput ;print on LCD the xilia ldi wreg,'D' rcall lcdput ;print on LCD the xilia ldi wreg,' ' rcall lcdput ;print on LCD the xilia ldi wreg,0xc6;Set address to line 2 + 6 rcall lcdcmd mov wreg,xilia2 rcall lcdput ;print on LCD the xilia2 mov wreg,ekato2 rcall lcdput ;print on LCD the ekato2 mov wreg,deka2 rcall lcdput ;print on LCD the deka2 mov wreg,monada2 rcall lcdput ;print on LCD the monada2 halt2: sbic PINB,6 ;Wait for button pressed PB6 "Reset" rjmp halt2 rjmp f_pgm ; ;===================================================================== power_off: ;==================================================================== type_msg2: ldi wreg,0x80;Set address to line 1 rcall lcdcmd ldi EErtmp,0x19 ;Clear the temporary address out EEAR,EErtmp;Move the temporary address to EEAR again2: rcall EERead_seq ;Get the data from EEPROM to xilia2 mov wreg,eedrd_s rcall lcdput dec eedrd_s brne again2 ldi wreg,0xc0;Set address to line 2 + 6 rcall lcdcmd ldi EErtmp,0x2A ;Clear the temporary address out EEAR,EErtmp;Move the temporary address to EEAR again3: rcall EERead_seq ;Get the data from EEPROM to xilia2 mov wreg,eedrd_s rcall lcdput dec eedrd_s brne again3 ret ;return ;********************************************************************* ;**** EEPROM Data ;**** ;********************************************************************* .eseg ;EmptyPos:.db 00 ;leave eeprom location 00 empty due to bug ;in AVR that randomly erases the contens InitString1:.db 0x30,0x30,0x30,0x35 InitString2:.db 0x30,0x30,0x31,0x32 InitString3:.db "TARGET DONE Ver ",1;Strings are 0 ended InitString4:.db " GREECE ",1;Strings are 0 ended InitString5:.db " THESSALONIKI ",1;Strings are 0 ended InitString6:.db 0x30,0x30,0x30,0x32 |