;*************************************************************************** ; ATiny2313 Timer with LCD display GS 20.7.2009 ; counts 1 second up to 99h:59m:59s ; uses 4 MHz quartz, program fuses accordingly ; working ok ;*************************************************************************** ; ; This program is free software; you can redistribute it and/or ; modify it under the terms of the GNU General Public License. ; This program is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; ;*************************************************************************** ; ; * LCD-base routines for 4-Bit-interface of a 2-line LCD display ; Bits 7654=Data, Bit 2=RS, Bit3=E* GS ; * Gerhard Schmidt, code basis ; ******************************************************************** ; ; Hardware: LCD-Display on port B ; Pins ATtiny2313: ; R/S PortB 2 ; E PortB 3 ; DB4 PortB 4 ; DB5 PortB 5 ; DB6 PortB 6 ; DB7 PortB 7 ; ;;*************************************************************************** ; ATiny2313 PDIP ; ; (RESET/dW) PA2 1 20 VCC ; (RXD) PD0 2 19 PB7 (UCSK/SCK/PCINT7) ; (TXD) PD1 3 18 PB6 (MISO/DO/PCINT6) ; (XTAL2) PA1 4 17 PB5 (MOSI/DI/SDA/PCINT5) ; (XTAL1) PA0 5 16 PB4 (OC1B/PCINT4) ; (CKOUT/XCK/INT0)PD2 6 15 PB3 (OC1A/PCINT3) ; (INT1) PD3 7 14 PB2 (OC0A/PCINT2) ; (T0) PD4 8 13 PB1 (AIN1/PCINT1) ; (OC0B/T1) PD5 9 12 PB0 (AIN0/PCINT0) ; GND 10 11 PD6 (ICP) ;*************************************************************************** ; ; PA2 Reset button on pin1 ; PIND0 start button lo ; PIND1 short pulse out active high at end of timer ; PIND2 short pulse out active high when button pressed ; PD543 input , Pos and IncTime buttons diode wired or to ext int1 (GS) ; LedB1 = 1 PINB1 out heartbeat LedB1 ; PIND6 Time out active high ; .DEVICE ATtiny2313 ;for gavrasm .equ clock = 4000000 ; Definition for the LCD-port .equ cLcdWrite = 0b11111111 ; Data direction write the LCD .equ cLcdDummy = 0b00111000 ; Dummy-Function-Word .equ line1 = 0b10000000 .equ line2 = 0b11000000 ; Definition for the LCD-port Hardware .equ mLcdRs = 0b00000100 ; RS-Bit Mask ; Port B2 .equ bLcdEn = 3 ; Enable Bit Port B3 .equ pLcdDdr = DDRB ; LCD port .equ pLcdPort = PORTB ; PORTB .equ c1s = 200 ; Wait at start-up time (200 * 5 ms) .equ c5ms = clock/800 ; 5 ms Wait after each control word .equ c50us = clock/80000-4 ; 50 us Wait after each char ; more Definitions .equ c_value = 40000-1 ; Compare value for output compare interrupt ; 40000 cycles@4Mhz = 10000us = 10 ms .equ LedB1 = PINB1 ; PINB1 out heartbeat LedB1 .equ Apin = PIND6 ; timer output .equ ApinX = PIND1 .equ Tick = PIND2 ; Macro for Enable active time ; ; Version for 10 Mcs clock ;.MACRO enactive ; nop ; nop ; nop ; nop ; nop ;.ENDMACRO ; ; Version für 4 Mcs clock ; .MACRO enactive nop nop .ENDMACRO ; .def Tsec = r10 .def Tmin = r11 .def Thrs = r12 .def digits = r14 .def sr = r15 .def temp = r16 .def LCDout = r17 .def lo_byte = r18 .def hi_byte = r19 .def flag = r20 .def second = r23 .def minute = r24 .def hour = r25 .def Tpos = r26 .def timer = r27 .def count = r28 .cseg .org 0 rjmp RESET reti ; INT0 rjmp ExtInt1 .org 4 ;Initialize T1 Compare Match A interrupt vector rjmp OC1A ;***************Timer1 Compare Match A interrupt ******************************** ; 10 ms OC1A: in sr,sreg sbis PINB, LedB1 ; heartbeat Led sbi PORTB, LedB1 ; set output PORTB, PINB1 sbic PINB, LedB1 ; skip if set cbi PORTB, LedB1 inc count ; count up cpi count, 100 ; 100 * 10 ms = 1 s brlo OC1Ab clr count inc second cpi second,60 brne OC1Ab clr second inc minute cpi minute,60 brne OC1Ab clr minute inc hour cpi hour,100 brne OC1Ab clr hour OC1Ab: out SREG,sr reti ;********************************************************************** ; External Interrupt1 on PIND3, button pressed ; change position PIND4 (IncPos) or PIND5 (IncTime) ;********************************************************************** ExtInt1: in sr, SREG sbi PORTD, Tick rcall LcdDelay5ms ; debounce rcall LcdDelay5ms ; debounce sbis PIND, PIND5 ; check if button is high rcall IncTime ; if low, IncTime Target time sbis PIND, PIND4 ; check if button is high rcall IncPos ; if low, IncPos cbi PORTD, Tick out SREG, sr reti ;********************************************************************** IncPos: inc Tpos andi Tpos,0b00000011 ; Max 0...3 cpi Tpos, 0 breq IncPhrs cpi Tpos, 1 breq IncPmin cpi Tpos, 2 breq IncPsec clr Tpos IncPhrs: ldi LCDout,line1 + 12 ; start at position 12 rcall Lcd4Ctrl ldi ZH,high(2*T_hrs) ; setup Z pointer hi ldi ZL,low(2*T_hrs) ; setup Z pointer lo rcall Lcd4ZTxt1 ret IncPmin: ldi LCDout,line1 + 12 ; start at position 12 rcall Lcd4Ctrl ldi ZH,high(2*T_min) ; setup Z pointer hi ldi ZL,low(2*T_min) ; setup Z pointer lo rcall Lcd4ZTxt1 ret IncPsec: ldi LCDout,line1 + 12 ; start at position 12 rcall Lcd4Ctrl ldi ZH,high(2*T_sec) ; setup Z pointer hi ldi ZL,low(2*T_sec) ; setup Z pointer lo rcall Lcd4ZTxt1 ret ;********************************************************************** IncTime: cpi Tpos, 0 breq IncThrs cpi Tpos, 1 breq IncTmin cpi Tpos, 2 breq IncTsec IncThrs: inc Thrs mov temp, Thrs cpi temp,100 brne Incex clr Thrs ret IncTmin: inc TMin mov temp, Tmin cpi temp,60 brne Incex clr Tmin ret IncTsec: inc Tsec mov temp, Tsec cpi temp,60 brne Incex clr Tsec Incex: ret ;******************************************************************** reset: ldi temp,low(RAMEND) ;Initialize stackpointer out SPL,temp ;************** INT 0/1 *************************************************** ldi temp, 0b00000000 ;Disable INT before changing MCUCR out GIMSK, temp ldi temp, 0b00001010 ;Enable out MCUCR, temp ;falling edge ;ldi temp, 0b11000000 ;Enable INT0 and INT1 ldi temp, 0b10000000 ;Enable INT1 (buttons) out GIMSK, temp ;************** Timer1 *************************************************** ldi temp,high(c_value) ;Load compare high value out OCR1AH,temp ldi temp,low(c_value) ;Load compare low value out OCR1AL,temp ldi temp,0x00 out TCNT1H,temp ;Clear timer high byte out TCNT1L,temp ;Clear timer low byte out TCCR1A,temp ;Clear timer control reg A ldi temp,0x40 ;TOV1 OCF1A OCF1B – ICF1 OCF0B TOV0 OCF0A: TIFR out TIFR,temp ;Clear pending timer interrupt out TIMSK,temp ;Enable Timer compare interrupt ldi temp,0b00001001 ;0x9, start out TCCR1B,temp ;Clear timer on compare match,CK/1 ;TOIE1 OCIE1A OCIE1B – ICIE1 OCIE0B TOIE0 OCIE0A: TIMSK ;************** Ports ***************************************************** ; Port B ldi temp,0b11111111 ; LCD ports are output, 1 = output , 0 = input out DDRB,temp ; to data direction register ldi temp,0b11111110 ; set pullup and pins 0,1 hi out PORTB, temp ; 1 = pull-up , 0 = float ; Port D ldi temp,0b01000110 ; output PD1, PD2, PD6 out DDRD,temp ; to data direction register D ldi temp,0b00111001 ; set pullup out PORTD, temp ; 1 = pull-up , 0 = float ;*************** misc ***************************************************** ldi TEMP,(1<