AvrAsmLib/src/avr_asm_lib/avr_asm_lib.S

147 lines
2.7 KiB
ArmAsm
Raw Normal View History

2021-01-19 12:28:33 +03:00
#define __SFR_OFFSET 0
#define LED_PORT 7
#include "avr/io.h" // ~ #include "avr/iom328p.h"
2021-01-21 18:27:54 +03:00
.section .bss
lm35_port: .byte 0
.section .text
2021-01-19 12:28:33 +03:00
.global init
.global blink
.global float_test
2021-01-21 18:27:54 +03:00
.global lm35_init
.global lm35_read
2021-01-19 12:28:33 +03:00
init:
sbi DDRD, LED_PORT
ret
2021-01-21 18:27:54 +03:00
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
2021-01-19 12:28:33 +03:00
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
2021-01-21 18:27:54 +03:00
lm35_read:
2021-01-19 12:28:33 +03:00
; 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
2021-01-21 18:27:54 +03:00
; 11 means using internal 1.1v atmega voltage for adc
2021-01-19 12:28:33 +03:00
; last three bits are for the analog port number
ldi r30, 0b11000000
2021-01-21 18:27:54 +03:00
lds r24, lm35_port
2021-01-19 12:28:33 +03:00
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
2021-01-21 18:27:54 +03:00
; clearing unused bits to be sure they're zero
2021-01-19 12:28:33 +03:00
ldi r31, 0b00000011
and r25, r31
2021-01-21 18:27:54 +03:00
; 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)
2021-01-19 12:28:33 +03:00
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