#define __SFR_OFFSET 0 #define LED_PORT 7 #include "avr/io.h" // ~ #include "avr/iom328p.h" .section .bss lm35_port: .byte 0 .section .text .global init .global blink .global float_test .global lm35_init .global lm35_read init: sbi DDRD, LED_PORT ret analog_pin_mode_input: ; sets analog pin as input ; input: r24 - number of pin in DDRC I/O register ; output: - ; r31 mask to set 0 in I/O register ldi r31, 1 ; means port 0 cpi r24, 0 breq end_convert ; = 0 => no need to convert (already set mask to port 0) mov r30, r24 convert: lsl r31 ; logic shift left ~ r31 * 2 dec r30 cpi r30, 0 brne convert end_convert: com r31 ; inverting mask (00001000 -> 11110111) ; setting correct DDRC using mask in r30, DDRC and r30, r31 ; applying mask (11111111 and 11110111 = 11110111) out DDRC, r30 ret lm35_init: ; args: r24 to r20, where r24 is the lowest subi r24, 14 ; because A0 is D14 call analog_pin_mode_input sts lm35_port, r24 ret float_test: ldi r25, 0b00111110 ldi r24, 0b00100000 ldi r23, 0b01000000 ldi r22, 0b00000000 clr r1 ret blink: ldi r20, 250 call delay_n_ms ldi r20, 250 call delay_n_ms sbi PORTD, LED_PORT ; high ldi r20, 250 call delay_n_ms cbi PORTD, LED_PORT ; low ret lm35_read: ; return: r24 to r19, where r24 is the lowest cli ; forbids interruptions ldi r30, 0b00000000 sts PRR, r30 ; first two bits are for the ref voltage ; 11 means using internal 1.1v atmega voltage for adc ; last three bits are for the analog port number ldi r30, 0b11000000 lds r24, lm35_port or r30, r24 sts ADMUX, r30 ldi r30, 0b11000111 sts ADCSRA, r30 wait_adc: lds r30, ADCSRA ldi r31, 0b01000000 and r31, r30 cpi r31, 0 brne wait_adc lds r24, ADCL lds r25, ADCH ; clearing unused bits to be sure they're zero ldi r31, 0b00000011 and r25, r31 ; r25 high, r24 low - divident and then quotient ; r30 - res ldi r30, 0 division: cpi r24, 10 brlo division_low_end ; < continue_division: sbiw r24, 10 inc r30 rjmp division division_low_end: cpi r25, 0 brne continue_division cpi r24, 5 brlo not_inc ; < inc r30 not_inc: mov r24, r30 ; uint8_t return value adiw r24, 2 ; due to LM35 formula (2C to 150C) sei ; allow interruptions clr r1 ; c requirement ret delay_n_ms: ; delay for ~r20 * 1ms. r20, r30, and r31 are modified. ; 1 ms ~ 16000 cycles at 16MHz. ; The basic loop takes about 5 cycles, so we need about 3000 loops. ldi r31, 3000 >> 8 ; high byte of the 3000 ldi r30, 3000 & 255 ; low byte of the 3000 delaylp: sbiw r30, 1 ; sub word r30 1 brne delaylp ; jne delaylp subi r20, 1 brne delay_n_ms ret