Initial commit

This commit is contained in:
KoroLion 2021-01-19 12:28:33 +03:00
commit 4f315bd287
6 changed files with 223 additions and 0 deletions

BIN
report.odt Normal file

Binary file not shown.

View File

@ -0,0 +1,111 @@
#define __SFR_OFFSET 0
#define LED_PORT 7
#include "avr/io.h" // ~ #include "avr/iom328p.h"
.global init
.global blink
.global read_temp
.global float_test
init:
sbi DDRD, LED_PORT
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
read_temp:
; args: r24 to r20, where r24 is the lowest
; 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
; last three bits are for the analog port number
ldi r30, 0b11000000
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 ot be sure they're zero
ldi r31, 0b00000011
and r25, r31
sei ; allow interruptions
clr r1 ; c requirement
pop r29 ; c requirement to preserve this register
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

View File

@ -0,0 +1,92 @@
extern "C" {
void init();
void blink();
float float_test();
uint16_t read_temp(uint8_t port);
}
#define UNKNOWN_PIN 0xFF
uint8_t getPinMode(uint8_t pin)
{
uint8_t bit = digitalPinToBitMask(pin);
uint8_t port = digitalPinToPort(pin);
// I don't see an option for mega to return this, but whatever...
if (NOT_A_PIN == port) return UNKNOWN_PIN;
// Is there a bit we can check?
if (0 == bit) return UNKNOWN_PIN;
// Is there only a single bit set?
if (bit & bit - 1) return UNKNOWN_PIN;
volatile uint8_t *reg, *out;
reg = portModeRegister(port);
out = portOutputRegister(port);
if (*reg & bit)
return OUTPUT;
else if (*out & bit)
return INPUT_PULLUP;
else
return INPUT;
}
/*
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;
but the system clock will be generally higher (8 MHz, 10 MHz, 16 MHz etc).
To reduce it to required frequency we use ADC prescaler bits. Suppose we have system clock with frequency 10Mhz (10000000 Hz) and set division factor to 64,
then ADC clock frequency is 10000000/64 = 156250Hz = 156.25 KHz, which is between 50 to 200 KHz as mentioned in the datasheet.
(http://www.robotplatform.com/knowledge/ADC/adc_tutorial_2.html)
16 MHz / 128 = 16000000 Hz / 128 = 125000 Hz = 125 KHz => OK!
*/
void setup() {
Serial.begin(9600);
// init();
}
void loop() {
// blink();
/*ADMUX = 0b01000011;
PRR = 0b00000000;
ADCSRA = 0b11000111;
while ((ADCSRA & 0b01000000) != 0);
short k = ADC;*/
// max value = 1023
// ref voltage is 1.1 V
// 1023 - max byte value
// +2 to 150, 10 mv/C
// k / 255 * 1.1 * 1000 / 10 + 2
// Serial.println((float)k * 0.43137254 + 2);
// pinMode(A3, OUTPUT);
float *f = malloc(sizeof(f));
*f = float_test();
for (int i = 0; i < 4; i++) {
Serial.print(((unsigned char*)f)[i]);
Serial.print(" ");
}
Serial.print(" => ");
Serial.print(*f, 8);
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);
}

20
src/float_manip.c Normal file
View File

@ -0,0 +1,20 @@
// https://rextester.com/l/c_online_compiler_gcc
#include <stdio.h>
int main(void)
{
unsigned char *fc = malloc(4 * sizeof(fc));
*((float*)fc) = 31.19;
fc[3] = 0b00111110;
fc[2] = 0b00100000;
fc[1] = 0b01000000;
fc[0] = 0b00000000;
printf("%f", *((float*)fc));
free(fc);
return 0;
}