diff --git a/.vscode/settings.json b/.vscode/settings.json index cce9b3b..1c07c9f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,6 +9,7 @@ "bitmanip.h": "c", "rush_header.h": "c", "twi.h": "c", - "header.h": "c" + "header.h": "c", + "adc.h": "c" } } diff --git a/headers/utils.h b/headers/utils.h index 1dfefcb..fc02e8d 100644 --- a/headers/utils.h +++ b/headers/utils.h @@ -12,9 +12,10 @@ // mathematics #define PERCENT(percent, total) (((float)percent / 100) * total) #define DIV_ROUND_CLOSEST(n, d) ((((n) < 0) == ((d) < 0)) ? (((n) + (d)/2)/(d)) : (((n) - (d)/2)/(d))) +#define INT_TO_HEX_CHAR(n) ((n) < 10 ? ('0' + (n)) : ('A' + ((n) - 10))) // text -#define SWITCH_CASE(ch) (((ch) >= 'A' && (ch) <= 'Z') || ((ch) >= 'a' && (ch) <= 'z') ? ((ch) ^ (1 << 5)) : (ch)) +#define SWITCH_CASE(ch) (((ch) >= 'A' && (ch) <= 'Z') || ((ch) >= 'a' && (ch) <= 'z') ? ((ch) ^ (1 << 5)) : (ch)) // boolean #define TRUE 1 diff --git a/module05/ex00/adc.c b/module05/ex00/adc.c new file mode 100644 index 0000000..12a2ccc --- /dev/null +++ b/module05/ex00/adc.c @@ -0,0 +1,27 @@ +#include "header.h" + +// Table 14-6. Port C Pins Alternate Functions +// - PC0 -> ADC0 (ADC Input Channel 0) +// -> PCINT8 (Pin Change Interrupt 8) +// +// 24.2 : The ADC generates a 10-bit result which is presented in the ADC Data Registers, ADCH and ADCL +// +// START A CONVERSTION in single conversion mode : +// - disabling the Power Reduction ADC bit, PRADC +// - writing a logical one to the ADC Start Conversion bit, ADSC + +#define ADC_PRESCALER 8 + +void adc_init() { + ADMUX = (1 << REFS0); // Table 24-3 : set voltage reference, AVCC with external capacitor at AREF pin + ADCSRA = (1 << ADEN) // 24.9.2 : enable ADC + | ADC_PRESCALE_SET(ADC_PRESCALER); // Table 24-5 : prescaler ADC +} + +uint16_t adc_read(uint8_t channel) { + CLEAR(PRR, PRADC); // 24.3 : ensure power reduction is disabled for ADC, (10.11.3 : PRR – Power Reduction Register) + ADMUX = (ADMUX & 0xF0) | (channel & 0x0F); // Select ADC channel + ADCSRA |= (1 << ADSC); // 24.9.2 : Start conversion, ADSC: ADC Start Conversion + while (ADCSRA & (1 << ADSC)); // Wait for completion + return ADC; +} diff --git a/module05/ex00/adc.h b/module05/ex00/adc.h new file mode 100644 index 0000000..7a11906 --- /dev/null +++ b/module05/ex00/adc.h @@ -0,0 +1,15 @@ +#ifndef ADC_H +#define ADC_H + +// Table 24-5 : prescaler ADC +#define ADC_PRESCALE_SET(value) \ + ((value) == 2 ? (0< ADC0 (ADC Input Channel 0) -// -> PCINT8 (Pin Change Interrupt 8) -// -// 24.2 : The ADC generates a 10-bit result which is presented in the ADC Data Registers, ADCH and ADCL - -#define INT_TO_HEX_CHAR(n) ((n) < 10 ? ('0' + (n)) : ('A' + ((n) - 10))) void int_to_hex_string(uint64_t value, char *out, uint8_t num_digits) { for (uint8_t i = 0; i < num_digits; ++i) { uint8_t shift = (num_digits - 1 - i) * 4; @@ -14,41 +7,19 @@ void int_to_hex_string(uint64_t value, char *out, uint8_t num_digits) { } out[num_digits] = '\0'; } -void word_to_hex(uint16_t value, char *out) { - out[0] = INT_TO_HEX_CHAR((value >> 8) & 0x0F); - out[1] = INT_TO_HEX_CHAR((value >> 4) & 0x0F); - out[2] = INT_TO_HEX_CHAR(value & 0x0F); - out[3] = '\0'; -} - -void adc_init() { - ADMUX = (1 << REFS0); // AVcc reference, ADC0 - ADCSRA = (1 << ADEN) // Enable ADC - | (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // Prescaler = 128 -} - -uint16_t adc_read(uint8_t channel) { - ADMUX = (ADMUX & 0xF0) | (channel & 0x0F); // Select ADC channel - ADCSRA |= (1 << ADSC); // Start conversion - while (ADCSRA & (1 << ADSC)); // Wait for completion - return ADC; -} // description int main() { - char buffer[4]; + const char buffer[4]; SREG |= ENABLE_GLOBAL_INTERRUPT; // 7.3.1 : Status Register, bit 7 : I – Global Interrupt Enable uart_init(); - adc_init(); while(1) { - uint16_t value = adc_read(0); // Read from ADC0 (A0) - // snprintf(buffer, sizeof(buffer), "ADC: %u\r\n", value); - word_to_hex(value, buffer); - uart_printstr(buffer); - uart_printstr("\r\n"); - _delay_ms(20); // Wait 20ms + uint16_t value = adc_read(0); // Read from ADC0 (A0) + int_to_hex_string(value, buffer, 3); + uart_printstr_endl(buffer); + _delay_ms(20); // Wait 20ms } } diff --git a/module05/ex00/uart.c b/module05/ex00/uart.c index 8ee5afe..f0231f0 100644 --- a/module05/ex00/uart.c +++ b/module05/ex00/uart.c @@ -34,6 +34,11 @@ void uart_printstr(const char* str) { } } +void uart_printstr_endl(const char* str) { + uart_printstr(str); + uart_printstr("\r\n"); +} + // ISR(USART_RX_vect) { // Table 12-6 : we select the code for USART Receive // char received_char = UDR0; // read received character // if (received_char == '\b' || received_char == 127) { // if backspace is received