diff --git a/src/avr_asm_lib/avr_asm_lib.S b/src/avr_asm_lib/avr_asm_lib.S index 9f08f07..080d3b6 100644 --- a/src/avr_asm_lib/avr_asm_lib.S +++ b/src/avr_asm_lib/avr_asm_lib.S @@ -3,16 +3,55 @@ #include "avr/io.h" // ~ #include "avr/iom328p.h" +.section .bss +lm35_port: .byte 0 + +.section .text + .global init .global blink -.global read_temp .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 @@ -34,42 +73,18 @@ blink: ret -read_temp: - ; args: r24 to r20, where r24 is the lowest +lm35_read: ; return: r24 to r19, where r24 is the lowest cli ; forbids interruptions - push r29 ldi r30, 0b00000000 sts PRR, r30 - - subi r24, 14 ; because A0 is D14 - - ; convert pin number to bitmask (r31 is resulting mask) - ldi r31, 1 ; means port 0 - cpi r24, 0 - breq end_convert - ldi r29, 2 - mov r30, r24 -convert: - mul r31, r29 - mov 31, r0 - dec r30 - cpi r30, 0 - brne convert -end_convert: - com r31 ; inverting mask - - ; setting correct DDRC using mask - in r30, DDRC - and r30, r31 - out DDRC, r30 - ; first two bits are for the ref voltage - ; 01 means AVcc with ext capacitor at aref + ; 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 @@ -86,13 +101,33 @@ wait_adc: lds r24, ADCL lds r25, ADCH - ; clearing unused bits ot be sure they're zero + ; 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 - pop r29 ; c requirement to preserve this register ret diff --git a/src/avr_asm_lib/avr_asm_lib.ino b/src/avr_asm_lib/avr_asm_lib.ino index 1efb75a..39ca17b 100644 --- a/src/avr_asm_lib/avr_asm_lib.ino +++ b/src/avr_asm_lib/avr_asm_lib.ino @@ -3,7 +3,8 @@ extern "C" { void blink(); float float_test(); - uint16_t read_temp(uint8_t port); + void lm35_init(uint8_t port); + uint8_t lm35_read(); } #define UNKNOWN_PIN 0xFF @@ -34,6 +35,16 @@ uint8_t getPinMode(uint8_t pin) return INPUT; } +void printPortsStatus() { + Serial.print(getPinMode(A0)); + Serial.print(getPinMode(A1)); + Serial.print(getPinMode(A2)); + Serial.print(getPinMode(A3)); + Serial.print(getPinMode(A4)); + Serial.print(getPinMode(A5)); + Serial.println(); +} + /* ADC Prescaler Select Bits (ADPS): ADPS2, ADPS1 and ADPS0 bits are used to set circuit clock frequency. For ADC circuitry to work at its maximum resolution needs to be supplied with 50 kHz to 200 kHz frequency as per the datasheet; @@ -47,7 +58,8 @@ uint8_t getPinMode(uint8_t pin) void setup() { Serial.begin(9600); - + + lm35_init(A3); // init(); } @@ -68,7 +80,7 @@ void loop() { // Serial.println((float)k * 0.43137254 + 2); // pinMode(A3, OUTPUT); - float *f = malloc(sizeof(f)); + /*float *f = malloc(sizeof(f)); *f = float_test(); for (int i = 0; i < 4; i++) { @@ -77,16 +89,14 @@ void loop() { } Serial.print(" => "); Serial.print(*f, 8); - Serial.println(); + Serial.println();*/ // uint16_t k = read_temp(A3); - /*Serial.print(getPinMode(A0)); - Serial.print(getPinMode(A1)); - Serial.print(getPinMode(A2)); - Serial.print(getPinMode(A3)); - Serial.print(getPinMode(A4)); - Serial.print(getPinMode(A5)); - Serial.println();*/ // Serial.println((float)k / 1023 * 1.1 * 1000 / 10 + 2); // Serial.println((float)k * 0.10752688 + 2); + + uint8_t t = lm35_read(); + printPortsStatus(); + Serial.println(t); + //Serial.print(" vs "); }