diff --git a/module05/ex00/adc.c b/module05/ex00/adc.c index bba9287..de5d839 100644 --- a/module05/ex00/adc.c +++ b/module05/ex00/adc.c @@ -14,13 +14,19 @@ void adc_init(uint8_t prescaler_value) { ADMUX = (1 << REFS0); // Table 24-3 : set voltage reference, AVCC with external capacitor at AREF pin ADCSRA = (1 << ADEN); // 24.9.2 : enable ADC ADCSRA |= ADC_PRESCALE_SET(prescaler_value); // Table 24-5 : prescaler ADC + + ADCSRB = ADC_TRIGGER_TIMER_1_COMPARE_B; // Table 24-6 : ADC Auto Trigger Source + ADMUX = (ADMUX & 0b11110000) | (adc_channel & 0b1111); // Table 24-4 : Select ADC channel 0, (Table 14-6 : alternate function for RV1 on PC0 -> ADC0) } -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 & 0b11110000) | (channel & 0b1111); // Table 24-4 : Select ADC channel, (Table 14-6 : alternate function for RV1 on PC0 -> ADC0) - ADMUX |= (1 << ADLAR); // 24.9.1 : enable left adjust result - ADCSRA |= (1 << ADSC); // 24.9.2 : Start conversion, ADSC: ADC Start Conversion - while (ADCSRA & (1 << ADSC)); // Wait for completion - return ADCH; // 24.9.3 : ADC updated only when ADCH is read, not ADCL, so for 8 bits precision uses left adjust result to only read ADCH + +void adc_print_hex(uint8_t value) { + char buffer[3] = {0}; + int_to_hex_string(value, buffer, 2); + uart_printstr_endl(buffer); +} + +ISR(ADC_vect) { // Table 12-6 : interrupt vector for ADC Conversion Complete + uint16_t value = ADC; + adc_print_hex(value); } diff --git a/module05/ex00/header.h b/module05/ex00/header.h index 6b7ea32..c58a847 100644 --- a/module05/ex00/header.h +++ b/module05/ex00/header.h @@ -16,6 +16,9 @@ // PROTOTYPES // // main.c +// timer.c +void timer_1B_init(); +// math.c void int_to_hex_string(uint64_t value, char *out, uint8_t num_digits); // adc.c void adc_init(uint8_t prescaler_value); diff --git a/module05/ex00/main.c b/module05/ex00/main.c index b3ab81a..01ca708 100644 --- a/module05/ex00/main.c +++ b/module05/ex00/main.c @@ -14,13 +14,7 @@ #define ADC_PRESCALER 64 // Table 24-5 : can only be 2, 4, 8, 16, 32, 64, or 128 -void int_to_hex_string(uint64_t value, char *out, uint8_t num_digits) { // num_digits : number of digit of the output, ex 2 for 3FF (1023) -> FF - for (uint8_t i = 0; i < num_digits; ++i) { - uint8_t shift = (num_digits - 1 - i) * 4; - out[i] = INT_TO_HEX_CHAR((value >> shift) & 0x0F); - } - out[num_digits] = '\0'; -} +volatile uint8_t adc_channel = 0; // description int main() { diff --git a/module05/ex00/timer.c b/module05/ex00/timer.c new file mode 100644 index 0000000..f925572 --- /dev/null +++ b/module05/ex00/timer.c @@ -0,0 +1,12 @@ +#include "header.h" + +// Set up Timer1 in CTC mode to trigger every 20ms +// With 16MHz clock and prescaler of 8, and OCR1A = 39999: +// 16MHz/8/40000 = 50Hz = 20ms period +void timer_1B_init() { + TCCR1A = 0; // Normal operation, OC1A/OC1B disconnected + TCCR1B = (1 << WGM12) | (1 << CS11); // CTC mode, prescaler = 8 + OCR1A = 39999; // Compare match value for 20ms + + TIMSK1 = (1 << OCIE1B); // Enable Timer1 Compare B Match Interrupt +} \ No newline at end of file