; This microcontroller will read an artifical NASA time code. This code is 1 100pps signal ; with 0 denoted by a 2ms pulse and 1 by a 6 ms pulse. The format is as such: ;The encoding is as follows: ; ; |-------- Elapsed Time in 10s of microseconds ----- ; 0 1 2 3 4 5 ; ...111110xxxx000001xxxx000001xxxx000001xxxx000001xxxx000001 ; 1248 1248 1248 1248 1248 ; Units Tens Units Tens Units ; Seconds Seconds Minutes Minutes Hours ; ; --------- Elapsed Time in 10s of microseconds --->| ; 5 6 7 8 9 0 ; 1xxxx000001xxxx000001xxxx000001xxxx000001xxxx111110... ; 1248 1248 1248 1248 ???? ; Tens Units Tens Hundreds ID ; Hours Days Days Days Bits ;Note the 5 consecutive bits followed by zero which unambiguously identifies ;the 1pps reference pulse ( since all the units/tens/hundreds are binary-coded ;decimal values and thus will never be 1111.) ;The code is best interpreted by a microprocessor as the time encoded is always ;identifying the reference time at the start of the frame ie. to have the time ;coincident with a given reference pulse you must add 1 second to the time that ;was decoded from the previous frame :-) ; The starter module is on a common serial bus with the master controller, and ; initiates the start of an observation. .INCLUDE "c:\utils\Atmel\AVR Studio\Appnotes\8535def.inc" .LIST .LISTMAC ;------------------------------------------------------------- ; Setting up the Data Segment - SRAM .DSEG Seconds_Unit: .byte 1 Seconds_Tens: .byte 1 Minutes_Unit: .byte 1 Minutes_Tens: .byte 1 Hours_Unit: .byte 1 Hours_Tens: .byte 1 Days_Unit: .byte 1 Days_Tens: .byte 1 Days_Hund: .byte 1 ID: .byte 1 Set_Scnd_Unit_Holder: .byte 1 Set_Scnd_Tens_Holder: .byte 1 Set_Min_Unit_Holder: .byte 1 Set_Min_Tens_Holder: .byte 1 Set_Hr_Unit_Holder: .byte 1 Set_Hr_Tens_Holder: .byte 1 Set_Day_Unit_Holder: .byte 1 Set_Day_Tens_Holder: .byte 1 Set_Day_Hndrd_Holder: .byte 1 Set_Scnd_Unit: .byte 1 Set_Scnd_Tens: .byte 1 Set_Min_Unit: .byte 1 Set_Min_Tens: .byte 1 Set_Hr_Unit: .byte 1 Set_Hr_Tens: .byte 1 Set_Day_Unit: .byte 1 Set_Day_Tens: .byte 1 Set_Day_Hndrd: .byte 1 ; ------------------------------------------------------------- .ESEG .equ Zero = 0x00 .equ Colon = 0x3A .equ Space = 0x20 .equ Letter_T = 0x54 .equ Letter_E = 0x45 .equ Letter_n = 0x6E .equ Letter_D = 0x44 ;.def Half_Reg = r13 .def Zero_Reg = r12 .def Full_Reg = r11 .def X_Low = r26 .def X_High = r27 .def Y_Low = r28 .def Y_High = r29 .def Z_Low = r30 .def Z_High = r31 .def Bit_Value = r17 .def Start_Found = r20 .def Temp_Counter = r21 .def Frame_Counter = r22 .def SixorFour = r23 .def Bit_Counter = r24 .def Frame_Value = r25 .def LCD_Write = r18 .def LCD_Read = r19 .def LCD_Instruction = r14 .def Delay1 = r8 .def Delay2 = r9 .def Delay3 = r10 .def Timer_Status = r6 .def Holder_Count = r7 .def Modulo_Reg = r13 ; ------------------------------------------------------ .CSEG ; -------------------------------------------- ; Setup reset and interupt vectors .org 0x00 RJMP RESET .org 0x01 RJMP EXT_INT0 .org 0x02 RJMP EXT_INT1 .org 0x03 RJMP TIM2_COMP .org 0x0b RJMP UART_RXC BCDTable: .dw 0x05ed ;10 .dw 0xeace ;32 .dw 0xab63 ;54 .dw 0xe02f ;76 .dw 0xe3ef ;98 ; --------------------------------------------------------- ; Start of program RESET: ; Setup stack at the end of SRAM ldi r16,low(RAMEND) out SPL,r16 ldi r16,high(RAMEND) out SPH,r16 ; Setup some useful registers ldi r16,0x00 mov Zero_Reg,r16 ldi r16,0xff mov Full_Reg,r16 ; ldi r16,0xf0 ; mov Half_Reg,r16 mov Modulo_Reg,Zero_Reg dec Modulo_Reg inc Modulo_Reg mov Start_Found,Zero_Reg ;If this is zero, then start frame not found ldi Temp_Counter,0x14 ldi SixorFour,0x00 ;6= 1, 4 = 0 ldi Bit_Counter,0x04 mov Frame_Value,Zero_Reg ldi Frame_Counter,0x0A ; Now, need to set up the input pins. Will use port A for output. ; Port D will be use for the output signals (clear and enable), external interupts out DDRA,Full_Reg out PORTA,Full_Reg ;Output out DDRC,Full_Reg out PORTC,Full_Reg ;Output ldi r16,0xFC ;External 1PPS out DDRB,r16 ; Bottom 2 bits input, top 6bits output out PORTB,Full_Reg cbi PORTB,4 out DDRD,Full_Reg ;Output out PORTD,Full_Reg ; UART SETUP ================================ ldi r16,0x99 ;Enables Transmitter and Receiver,RX Complete int. out UCR,r16 ldi r16,0x33 out UBRR,r16 ;9800 Baud ; Now to set up interupts. First, there are external interupts 1/0 which are connected to the ; push button/latched signal. ldi r16,0xC0 out GIMSK,r16 ;Enable External interrupt 0 and 1 ldi r16,0x0F out MCUCR,r16 ;00001111 => Rising edges will generate ;interrupts INT0 and INT1 ; Now set pointers at beginning of time data ldi X_Low,low(Seconds_Unit) ldi X_High,high(Seconds_Unit) ldi Y_Low,low(Seconds_Unit) ldi Y_High,high(Seconds_Unit) st Y+,Zero_Reg st Y+,Zero_Reg st Y+,Zero_Reg st Y+,Zero_Reg st Y+,Zero_Reg st Y+,Zero_Reg st Y+,Zero_Reg st Y+,Zero_Reg st Y+,Zero_Reg ldi Y_Low,low(Seconds_Unit) ldi Y_High,high(Seconds_Unit) ; Timer setup ; Timer 2 to be used for 100pps signal, Timer0 to be used for PWM bits (2ms 0, 6ms 1) out ASSR,Zero_Reg ;Clear bit 3 - Timer2 clocked internally ldi r16,0x0F out TCCR2,r16 ;Timer 2 prescale ck/1024 ;for 0.05s (+/-), load 39 = 0x27 ;load OCR2 to compare value ldi r16,0x27 out OCR2,r16 ; Other Setups cbi PORTB,2 ;making CE low sbi PORTD,6 ;Vcc for Starter latch ;This will allow for the latch to be reset to ;0 by toggling the Vcc ldi Z_Low,low(Set_Scnd_Unit_Holder) ;New ldi Z_High,high(Set_Scnd_Unit_Holder) ;New st Z+,Full_Reg st Z+,Full_Reg st Z+,Full_Reg ;Minute st Z+,Full_Reg st Z+,Full_Reg ;Hour st Z+,Full_Reg st Z+,Full_Reg ;Day st Z+,Full_Reg st Z+,Full_Reg ldi Z_Low,low(Set_Scnd_Unit) ;New ldi Z_High,high(Set_Scnd_Unit) ;New st Z+,Full_Reg st Z+,Full_Reg st Z+,Full_Reg ;Minute st Z+,Full_Reg st Z+,Full_Reg ;Hour st Z+,Full_Reg st Z+,Full_Reg ;Day st Z+,Full_Reg st Z+,Full_Reg ; Setup LCD ;Need to wait 15 ms mov Delay1,Full_Reg mov Delay2,Full_Reg ldi r16,0x02 mov Delay3,r16 Delay_Loop1: dec Delay1 cpse Delay1,Full_Reg rjmp Delay_Loop1 dec Delay2 mov Delay1,Full_Reg cpse Delay2,Full_Reg rjmp Delay_Loop1 dec Delay3 mov Delay2,Full_Reg cpse Delay3,Full_Reg rjmp Delay_Loop1 ldi r16,0x02 mov Delay3,r16 cbi PORTA,2 ;E cbi PORTA,1 ;R/W cbi PORTA,0 ;RS sbi PORTA,0 nop nop ldi LCD_Write,0x30 out PORTC,LCD_Write nop nop cbi PORTA,0 mov Delay3,Zero_Reg ldi r16,0xA0 mov Delay2,r16 mov Delay1,Full_Reg Delay_Loop2: ;Wait for 5 ms dec Delay1 cpse Delay1,Full_Reg rjmp Delay_Loop2 dec Delay2 mov Delay1,Full_Reg cpse Delay2,Full_Reg rjmp Delay_Loop2 ldi r16,0xA0 mov Delay2,r16 cbi PORTA,2 ;E cbi PORTA,1 ;R/W cbi PORTA,0 ;RS sbi PORTA,0 nop nop ldi LCD_Write,0x30 out PORTC,LCD_Write nop nop cbi PORTA,0 mov Delay1,Full_Reg ldi r16,0x20 mov Delay2,r16 Delay_Loop3: ;Wait for 1 ms dec Delay1 cpse Delay1,Full_Reg rjmp Delay_Loop3 dec Delay2 mov Delay1,Full_Reg cpse Delay2,Full_Reg rjmp Delay_Loop3 ldi r16,0x20 mov Delay2,r16 cbi PORTA,2 ;E cbi PORTA,1 ;R/W cbi PORTA,0 ;RS sbi PORTA,0 nop nop ldi LCD_Write,0x30 out PORTC,LCD_Write nop nop cbi PORTA,0 rcall Busy cbi PORTA,1 cbi PORTA,2 ;E cbi PORTA,1 ;R/W cbi PORTA,0 ;RS sbi PORTA,0 nop nop ldi LCD_Write,0x38 out PORTC,LCD_Write ;2 lines, 8 bit nop nop cbi PORTA,0 rcall Busy cbi PORTA,1 cbi PORTA,2 ;E cbi PORTA,1 ;R/W cbi PORTA,0 ;RS sbi PORTA,0 nop nop ldi LCD_Write,0x0C out PORTC,LCD_Write ;Display on nop nop cbi PORTA,0 rcall Busy cbi PORTA,1 cbi PORTA,2 ;E cbi PORTA,1 ;R/W cbi PORTA,0 ;RS sbi PORTA,0 nop nop ldi LCD_Write,0x01 out PORTC,LCD_Write ;Clear Display, goto Address(0) nop nop cbi PORTA,0 rcall Busy cbi PORTA,1 cbi PORTA,2 ;E cbi PORTA,1 ;R/W cbi PORTA,0 ;RS sbi PORTA,0 nop nop ldi LCD_Write,0x06 out PORTC,LCD_Write ;Set shift mode nop nop cbi PORTA,0 mov Timer_Status,Zero_Reg ;Timer is disable at the moment SEI ; Program loop LOOP1: ldi Y_Low,low(Days_Hund) ;Y reg at beginning of time code ldi Y_High,high(Days_Hund) ld r4,Y sbiw Y_Low,0x01 rcall Busy ldi LCD_Write,0x80 ; cbi PORTA,2 ;E cbi PORTA,1 ;R/W nop nop sbi PORTA,0 ;RS nop nop nop nop out PORTC,LCD_Write ;Changes address DDRAM to 0x00 nop nop cbi PORTA,0 ;RS rcall Busy ldi LCD_Write,0x02 cbi PORTA,2 ;E cbi PORTA,1 ;R/W sbi PORTA,0 ;RS nop nop nop nop out PORTC,LCD_Write ;Set cursor = Address(0) nop nop cbi PORTA,0 ;RS ldi LCD_Write,0x30 add LCD_Write,r4 ;Value has loaded ;Now, check if busy rcall Busy rcall LCD_Write_Data ;Days Hundreds rcall Busy ld r4,Y sbiw Y_Low,0x01 ldi LCD_Write,0x30 add LCD_Write,r4 rcall LCD_Write_Data ;Days Tens rcall Busy ld r4,Y sbiw Y_Low,0x01 ldi LCD_Write,0x30 add LCD_Write,r4 rcall LCD_Write_Data ;Days Units rcall Busy ldi LCD_Write,Colon rcall LCD_Write_Data ;Colon rcall Busy ld r4,Y sbiw Y_Low,0x01 ldi LCD_Write,0x30 add LCD_Write,r4 rcall LCD_Write_Data ;Hours Tens rcall Busy ld r4,Y sbiw Y_Low,0x01 ldi LCD_Write,0x30 add LCD_Write,r4 rcall LCD_Write_Data ;Hours Units rcall Busy ldi LCD_Write,Colon rcall LCD_Write_Data ;Colon rcall Busy ld r4,Y sbiw Y_Low,0x01 ldi LCD_Write,0x30 add LCD_Write,r4 rcall LCD_Write_Data ;Minutes Tens ;Need to change DDRAM to 0x40 ;After 8 digits, need to changed DDRAM ;address to 0x40 rcall Busy ldi LCD_Write,0xC0 cbi PORTA,2 ;E cbi PORTA,1 ;R/W sbi PORTA,0 ;RS nop nop nop nop out PORTC,LCD_Write ;Changes address CGRAM to 0x40 nop nop cbi PORTA,0 ;RS rcall Busy ld r4,Y sbiw Y_Low,0x01 ldi LCD_Write,0x30 add LCD_Write,r4 rcall LCD_Write_Data ;Minutes Units rcall Busy ldi LCD_Write,Colon rcall LCD_Write_Data rcall Busy ld r4,Y sbiw Y_Low,0x01 ldi LCD_Write,0x30 add LCD_Write,r4 rcall LCD_Write_Data ;Seconds Tens rcall Busy ld r4,Y sbiw Y_Low,0x01 ldi LCD_Write,0x30 add LCD_Write,r4 rcall LCD_Write_Data ;Seconds Units rcall Busy ldi LCD_Write,Space rcall LCD_Write_Data ;Space rcall Busy ldi LCD_Write,Letter_T rcall LCD_Write_Data ;T cpse Timer_Status,Zero_Reg rjmp Timer_Status_Enabled rcall Busy ldi LCD_Write,Letter_D rcall LCD_Write_Data ;D rcall Busy ldi LCD_Write,Space rcall LCD_Write_Data ;Space rjmp LOOP1 Timer_Status_Enabled: rcall Busy ldi LCD_Write,Letter_E rcall LCD_Write_Data ;E rcall Busy ldi LCD_Write,Letter_n rcall LCD_Write_Data ;n rjmp LOOP1 EXT_INT0: ; push r16 in r16,SREG push r16 ldi r16,0x80 out TIMSK,r16 ;Enables Timer2 ;interrupts. ldi r16,0x00 ;Loads counter with 0x00, Timer2 out TCNT2,r16 ;will begin to count now ;Should count 5 ms! out TIFR,Full_Reg ;Clearing timer flags dec Temp_Counter cpse Temp_Counter,Zero_Reg rjmp Exit_Int0 cbi PORTD,7 cbi PORTB,2 ;for external CE flipflop Exit_Int0: pop r16 out SREG,r16 pop r16 RETI EXT_INT1: ;Legacy code push r16 in r16,SREG push r16 cbi PORTD,6 nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop sbi PORTD,6 pop r16 out SREG,r16 pop r16 RETI TIM2_COMP: push r16 in r16,SREG push r16 push Z_Low push Z_High in Bit_Value,PIND ;New out TIMSK,Zero_Reg ;Disables Timer2 ;interrupts. out TIFR,Full_Reg ;Clearing timer flags andi Bit_Value,0x04 ;New lsr Bit_Value ;New lsr Bit_Value ;New ;First need to check if startframe ;has been found... if not, then check ;if this is start frame. cpse Start_Found,Zero_Reg rjmp Locked_In ;If you are this far, then startframe ;has not been found... lsr Bit_Value ;Bit pattern test ror Frame_Value ;Bit pattern test ldi r16,0x7C ;If exiting, then read a 1 cpse Frame_Value,r16 ; <011111> Start Frame <00> ID rjmp Exit ;Test mov Frame_Value,Zero_Reg inc Start_Found sbi PORTD,7 ;Debug - to check that start frame is being ;found ldi Temp_Counter,0x10 rjmp Exit Locked_In: lsr Bit_Value ;Going to shift into frame value ror Frame_Value dec Bit_Counter cpse Bit_Counter,Zero_Reg rjmp Exit cpse SixorFour,Zero_Reg rjmp Dont_Store inc SixorFour ;Next time we won't store ldi Bit_Counter,0x06 ;need to store here, first need to shift down 4 bits lsr Frame_Value lsr Frame_Value lsr Frame_Value lsr Frame_Value st X+,Frame_Value dec Frame_Counter cpse Frame_Counter,Zero_Reg rjmp Exit ldi X_Low,low(Seconds_Unit) ;Setting back to beginning ldi X_High,high(Seconds_Unit) ldi Frame_Counter,0x0A ldi SixorFour,0x00 ldi Bit_Counter,0x04 dec Start_Found ;Forces micro to look for start ;frame again! ;Finally, set CE high for duration of ;of startframe and first 4 bits if ;time = set_time - 1 second ;We decrease the set time by 1 second since ;the enable pin must go high just before ;the second changes to set_scnd_unit ld r16,X ldi Z_Low,low(Set_Scnd_Unit) ldi Z_High,high(Set_Scnd_Unit) ld r3,Z+ cpse r3,r16 rjmp Exit ;Exit if seconds units aren't equal adiw X_Low,0x01 ld r16,X sbiw X_Low,0x01 ld r3,Z+ cpse r3,r16 rjmp Exit ;Exit if seconds tens aren't equal adiw X_Low,0x02 ;Looking at minutes now ld r16,X sbiw X_Low,0x02 ld r3,Z+ cpse r3,r16 rjmp Exit ;Exit if minutes units aren't equal adiw X_Low,0x03 ld r16,X sbiw X_Low,0x03 ld r3,Z+ cpse r3,r16 rjmp Exit ;Exit if minutes tens aren't equal adiw X_Low,0x04 ld r16,X sbiw X_Low,0x04 ld r3,Z+ cpse r3,r16 rjmp Exit ;Exit if hrs unit aren't equal adiw X_Low,0x05 ld r16,X sbiw X_Low,0x05 ld r3,Z+ cpse r3,r16 rjmp Exit ;Exit if hrs tens aren't equal adiw X_Low,0x06 ld r16,X sbiw X_Low,0x06 ld r3,Z+ cpse r3,r16 rjmp Exit ;Exit if days units aren't equal adiw X_Low,0x07 ld r16,X sbiw X_Low,0x07 ld r3,Z+ cpse r3,r16 rjmp Exit ;Exit if days tens aren't equal adiw X_Low,0x08 ld r16,X sbiw X_Low,0x08 ld r3,Z cpse r3,r16 rjmp Exit ;Exit if days hndrd aren't equal ;If got this far, set CE high sbi PORTB,2 mov Timer_Status,Full_Reg ;Timer Status Enabled rjmp Exit Dont_Store: dec SixorFour ldi Bit_Counter,0x04 mov Frame_Value,Zero_Reg rjmp Exit Exit: pop Z_High pop Z_Low pop r16 out SREG,r16 pop r16 RETI UART_RXC: push r16 in r16,SREG push r16 push Z_Low push Z_High in r16,UDR ;Reading value nop out UDR,r16 subi r16,0x30 ;Need to subtract 0x30 to convert ascii ;to binary (0x30) brmi ignore_key ;Will ignore non digit key presses cpi r16,0x0a brge ignore_key ;Will ignore non digit key presses ;Save stuff here ldi Z_Low,low(Set_Day_Hndrd_Holder) ldi Z_High,high(Set_Day_Hndrd_Holder) push r16 ldi r16,0x08 mov Holder_Count,r16 ;Will use this to keep track of pop r16 ;holder values being stepped through ld r3,Z cpse r3,Full_Reg ; rjmp Continue_UART_RXC_5 rjmp Continue_Holder_Check st Z,r16 ;Set_Day_Hndrd_Holder=r16 rjmp ignore_key Continue_Holder_Check: ;This loop will run through the Holder variables dec Holder_Count ;and check which have not been filled with a value. cp Holder_Count,Zero_Reg ;The RS232 data will be saved into the first holder breq Set_Sec_Unit ; = 0xFF.The Holder_Count is used so that if sbiw Z_Low,0x01 ;Set_Seconds_Tens_Holder isn't equal to 0xFF, ld r3,Z ;the program automatically goes to Set_Sec_Unit cpse r3,Full_Reg ;branch and the Holder values are saved and rjmp Continue_Holder_Check ;reset. st Z,r16 rjmp ignore_key Set_Sec_Unit: sbiw Z_Low,0x01 st Z,r16 ;Saves into Set_Scnd_Unit_Holder ldi Z_Low,low(Set_Day_Hndrd_Holder) ldi Z_High,high(Set_Day_Hndrd_Holder) rcall Store_and_Swop ;r3=Set_Day_Hndrd_Holder ;Set_Day_Hndrd_Holder=0xFF ;Set_Day_Hndrd=r3 ldi Z_Low,low(Set_Day_Tens_Holder) ldi Z_High,high(Set_Day_Tens_Holder) rcall Store_and_Swop ;r3=Set_Day_Tens_Holder ;Set_Day_Tens_Holder=0xFF ;Set_Day_Tens=r3 ldi Z_Low,low(Set_Day_Unit_Holder) ldi Z_High,high(Set_Day_Unit_Holder) rcall Store_and_Swop ;r3=Set_Day_Unit_Holder ;Set_Day_Unit_Holder=0xFF ;Set_Day_Unit=r3 ldi Z_Low,low(Set_Hr_Tens_Holder) ldi Z_High,high(Set_Hr_Tens_Holder) rcall Store_and_Swop ;r3=Set_Hr_Tens_Holder ;Set_Hr_Tens_Holder=0xFF ;Set_Hr_Tens=r3 ldi Z_Low,low(Set_Hr_Unit_Holder) ldi Z_High,high(Set_Hr_Unit_Holder) rcall Store_and_Swop ;r3=Set_Hr_Unit_Holder ;Set_Hr_Unit_Holder=0xFF ;Set_Hr_Unit=r3 ; mov Set_Scnd_Tens,Set_Scnd_Tens_Holder ldi Z_Low,low(Set_Scnd_Tens_Holder) ldi Z_High,high(Set_Scnd_Tens_Holder) rcall Store_and_Swop ;r3=Set_Scnd_Tens_Holder ;Set_Scnd_Tens=r3 ; mov Set_Scnd_Unit,Set_Scnd_Unit_Holder ldi Z_Low,low(Set_Scnd_Unit_Holder) ldi Z_High,high(Set_Scnd_Unit_Holder) rcall Store_and_Swop ;r3=Set_Scnd_Unit_Holder ;Set_Scnd_Unit_Holder=0xFF ;Set_Scnd_Unit=r3 ; mov Set_Min_Tens,Set_Min_Tens_Holder ldi Z_Low,low(Set_Min_Tens_Holder) ldi Z_High,high(Set_Min_Tens_Holder) rcall Store_and_Swop ;r3=Set_Min_Tens_Holder ;Set_Min_Tens_Holder=0xFF ;Set_Min_Tens=r3 ; mov Set_Min_Unit,Set_Min_Unit_Holder ldi Z_Low,low(Set_Min_Unit_Holder) ldi Z_High,high(Set_Min_Unit_Holder) rcall Store_and_Swop ;r3=Set_Min_Unit_Holder ;Set_Min_Unit_Holder=0xFF ;Set_Min_Unit=r3 rjmp ignore_key ignore_key: ; Check if reset key = 'r' mov r5,r16 ldi r16,0x42 cpse r5,r16 rjmp ignore_key_Exit cbi PORTD,6 ; If reset key 'r', will reset nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop nop sbi PORTD,6 mov Timer_Status,Zero_Reg ;Timer status disabled ;Should reset time aswell ldi Z_Low,low(Set_Scnd_Unit_Holder) ldi Z_High,high(Set_Scnd_Unit_Holder) st Z+,Full_Reg ;Set_Scnd_Unit_Holder = 0xFF st Z+,Full_Reg ;Set_Scnd_Tens_Holder = 0xFF st Z+,Full_Reg ;Set_Min_Unit_Holder = 0xFF st Z+,Full_Reg ;Set_Min_Tens_Holder = 0xFF st Z+,Full_Reg ;Set_Hr_Unit_Holder = 0xFF st Z+,Full_Reg ;Set_Hr_Tens_Holder = 0xFF st Z+,Full_Reg ;Set_Day_Unit_Holder = 0xFF st Z+,Full_Reg ;Set_Day_Tens_Holder = 0xFF st Z+,Full_Reg ;Set_Day_Hndrd_Holder = 0xFF ldi Z_Low,low(Set_Scnd_Unit) ldi Z_High,high(Set_Scnd_Unit) st Z+,Full_Reg ;Set_Scnd_Unit = 0xFF st Z+,Full_Reg ;Set_Scnd_Tens = 0xFF st Z+,Full_Reg ;Set_Min_Unit = 0xFF st Z+,Full_Reg ;Set_Min_Tens = 0xFF st Z+,Full_Reg ;Set_Hr_Unit = 0xFF st Z+,Full_Reg ;Set_Hr_Tens = 0xFF st Z+,Full_Reg ;Set_Day_Unit = 0xFF st Z+,Full_Reg ;Set_Day_Tens = 0xFF st Z+,Full_Reg ;Set_Day_Hndrd = 0xFF ignore_key_Exit: pop Z_High pop Z_Low pop r16 out SREG,r16 pop r16 RETI ;=========================== SUB-ROUTINES =================================== Store_and_Swop: ld r3,Z st Z,Full_Reg adiw Z_Low,0x09 st Z,r3 ret Busy: ;First, Need to check if LCD is busy cbi DDRC,7 ;Setting pin 7 to an input ;in order to read busy flag Busy_Loop1: cbi PORTA,2 ;E sbi PORTA,1 ;R/W nop nop nop sbi PORTA,0 ;RS nop nop nop in LCD_Read,PINC ;Busy flag is on pin 7 nop nop cbi PORTA,0 ;E andi LCD_Read,0x80 ;Mask off top bit cpse LCD_Read,Zero_Reg ;If Zero, then not busy rjmp Busy_Loop1 ;If busy, then carry on checking ;Not busy now sbi DDRC,7 ret LCD_Write_Data: sbi PORTA,2 ;E cbi PORTA,1 ;R/W sbi PORTA,0 ;RS nop nop nop nop out PORTC,LCD_Write ;Write data to LCD nop nop cbi PORTA,0 ret