;*************************************************************************** ; ATiny2313 clock with 12 leds inner and 12 leds outer ring ; ATiny2313 GS 10-2011 ; Charlieplex 12 Leds + 12 Leds on PORTB, use Led table ; 12 hour clock for leds, 24 for NightOn ; PORTB 0 1 2 3 outer leds 12 green, minutes ; PORTB 4 5 6 7 inner leds 12 orange, hours ; PORTD 3 4 5 small panel leds, 0..4 minutes binary ; The timing is adapted for 4 MHz ; ;;*************************************************************************** ; 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) ;*************************************************************************** .DEVICE ATtiny2313 ;for gavrasm .equ clock = 4000000 .equ baudrate = 9600 .equ baudval = clock/(16*baudrate)-1 ; more Definitions .equ c_value = 40000-1 ;Compare value for output compare interrupt .equ Nighton = PIND6 ; PIND6 out Nighton 18h-6h .equ Led0 = PIND5 ; small panel Leds .equ Led1 = PIND4 ; .equ Led2 = PIND3 ; .equ Poweron = PIND1 ; use txd ; use r0, r1 to set leds .def zero = r14 .def sr = r15 .def temp = r16 .def count = r17 .def Mincnt = r18 .def next_step = r19 .def LedcntMin = r20 .def LedcntHrs = r21 .def second = r23 .def minute = r24 .def hour = r25 .def LedPD0 = r26 .def LedPD1 = r27 .def ScratchH = r26 ; use in bcd2bin .def ScratchL = r27 ; use in bcd2bin .def cnt24h = r28 .def test2 = r29 .cseg .org 0 rjmp RESET rjmp ExtInt0 ; INT0 set hour reti ; INT1 reti rjmp T1OC1A ; Initialize T1 Compare Match A interrupt vector .org 7 rjmp RX_COMPLETE_INT ;********************************************************************** ; Timer1 Compare Match A interrupt ********************** ; 10 ms ;********************************************************************** T1OC1A: in sr,sreg inc count ; count up cpi count, 100 ; 100 * 10 ms = 1 s brlo OC1Ab clr count inc next_step inc second cpi second,60 brne OC1Ab clr second inc minute inc Mincnt cpi Mincnt,5 ; 12 leds, 60min/12 brne OC1min clr Mincnt inc LedcntMin OC1min: cpi minute,60 brne OC1Ab clr minute clr LedcntMin clr Mincnt inc hour inc cnt24h ; 24 h inc LedcntHrs cpi hour,12 ; leds 12 h clock brne OC1hr1 clr hour clr LedcntHrs OC1hr1: cpi cnt24h,24 ; 24 h brne OC1Ab clr cnt24h OC1Ab: out SREG,sr reti ;********************************************************************** ; External Interrupt0 on PIND2, button pressed ; (Inc hour) ;********************************************************************** ExtInt0: in sr, SREG clr count EI0_1: dec count ; debounce brne EI0_1 sbic PIND, PIND2 ; check if button is still low rjmp EI0_x clr Mincnt clr LedcntMin clr count clr second ; counters clr minute inc hour inc LedcntHrs inc cnt24h cpi hour,12 ; 12 h leds brne EI0_2 clr hour clr LedcntHrs EI0_2: cpi cnt24h,24 ; 24 h brne EI0_x clr cnt24h EI0_x: out SREG, sr reti ;********************************************************************** ;* ;* "BCD2bin8" - BCD to 8-bit binary conversion BCD2bin8: BCDb8_0: subi ScratchH,1 ; fBCDH = fBCDH - 1 brcs BCDb8_1 ; if carry not set subi ScratchL,-10 ; result = result + 10 rjmp BCDb8_0 ; loop again BCDb8_1: ret ;else return ;********************************************************************** ; Interrupt routine for incoming bytes on the RS232 link ;********************************************************************** RX_COMPLETE_INT: in sr, SREG push temp in temp,UDR cpi temp,'h' ; hour => h21 brne rx_2 rcall SerIn ; read hr hi subi temp, 48 ; make BCD mov ScratchH, temp rcall SerIn ; read hr lo subi temp, 48 ; make BCD mov ScratchL, temp rcall BCD2bin8 mov cnt24h, ScratchL mov hour, ScratchL mov LedcntHrs, ScratchL cpi hour, 12 brlo rx_exit subi hour, 12 mov LedcntHrs, hour rjmp rx_exit rx_2: cpi temp,'m' ; minute brne rx_3 rcall SerIn ; read hr hi subi temp, 48 ; make BCD mov ScratchH, temp rcall SerIn ; read hr lo subi temp, 48 ; make BCD mov ScratchL, temp rcall BCD2bin8 mov minute, ScratchL mov LedcntMin, ScratchL clr Mincnt rjmp rx_exit rx_3: cpi temp,'s' ; main timer speed => s+binary brne rx_4 rcall SerIn out OCR1AH,temp rcall SerIn out OCR1AL,temp rjmp rx_exit rx_4: cpi temp,'1' ; hour brne rx_5 rcall SerIn ; read mov hour, temp mov LedcntHrs, temp mov cnt24h, temp rjmp rx_exit rx_5: cpi temp,'2' ; min brne rx_6 rcall SerIn ; read mov minute, temp mov LedcntMin, temp rjmp rx_exit rx_6: cpi temp,'D' ; brne rx_7 rjmp rx_exit rx_7: cpi temp,'?' ; send brne rx_15 ldi temp,'H' ; reply with H hms rcall send_char mov temp,hour rcall send_char mov temp,minute rcall send_char mov temp,second rcall send_char rjmp rx_exit ; unknown command, just ignore it rx_15: rx_exit: pop temp out SREG, sr reti ;********************************************** ;* SerIn Returns serial port input in temp * ;********************************************** SerIn: sbis USR,RXC ;wait for a character rjmp SerIn in temp,UDR ;read value ret ; ; send char in temp ; send_char: sbis UCSRA, UDRE ; wait for UDR rjmp send_char ; no, wait some more out UDR,temp ; send char ret ; and return ;******************************************************************** reset: ldi temp,low(RAMEND) ;Initialize stackpointer out SPL,temp ;************** Ports ***************************************************** ; Port B ldi temp,0b00000000 ; LED ports are output, 1 = output , 0 = input out DDRB,temp ; to data direction register ldi temp,0b00000000 ; set pullup and pins 0,1 hi out PORTB, temp ; 1 = pull-up , 0 = float ; Port D ldi temp,0b01111000 ; output PD6543 out DDRD,temp ; to data direction register D ldi temp,0b00000101 ; set pullup out PORTD, temp ; 1 = pull-up , 0 = float ;************** RS 232 *************************************************** ldi temp,low(baudval) ; UBRRL set uart speed out UBRRL,temp ldi temp,high(baudval) ; UBRRH set uart speed out UBRRH,temp ; 98 = 10011000 ldi temp,0x90 ; UCSRB=UCR enable RXint and enable rx only out UCSRB,temp ; UCSRB: RXCIE TXCIE UDRIE RXEN TXEN UCSZ2 RXB8 TXB8 ;************** 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, 0b01000000 ;Enable INT0 (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 ;TOIE1 OCIE1A OCIE1B – ICIE1 OCIE0B TOIE0 OCIE0A: TIMSK ldi temp,(1<