-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy path07_main_adc_trigger.c
109 lines (78 loc) · 1.95 KB
/
07_main_adc_trigger.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
* main_an_comp.c
*
* Created on: Oct 08, 2018
* Author: Renan Augusto Starke
* Instituto Federal de Santa Catarina
*/
#include <util/delay.h>
#include <avr/interrupt.h>
#include "avr_gpio.h"
#include "avr_adc.h"
#include "avr_timer.h"
#include "bits.h"
#include "avr_usart.h"
volatile uint16_t valor_adc = 0;
/**
* @brief Configura hardware do timer0 para IRQ em overflow.
* @param Nenhum
*
* @retval Nenhum.
*/
void timer0_hardware_init(){
/* Acesso indireto por struct e bit field: com avr_timer.h */
TIMER_0->TCCRA = 0;
TIMER_0->TCCRB = SET(CS02) | SET(CS00);
TIMER_IRQS->TC0.BITS.TOIE = 1;
}
void adc_init(){
/* Ref externa no pino AVCC com capacitor de 100n em VREF.
* Habiltiação apenas no Canal 0 */
ADCS->AD_MUX = SET(REFS0);
/* Habilita AD:
* Conversão contínua
* IRQ ativo
* Prescaler de 128 */
ADCS->ADC_SRA = SET(ADEN) | //ADC Enable
SET(ADSC) | // ADC Start conversion
SET(ADATE) | // ADC Auto Trigger
SET(ADPS0) | SET(ADPS1) | SET(ADPS2) | //ADPS[0..2] AD Prescaler selection
SET(ADIE); //AD IRQ ENABLE
/* Auto trigger in timer0 overflow */
ADCS->ADC_SRB = SET(ADTS2);
/* Desabilita hardware digital de PC0 */
ADCS->DIDr0.BITS.ADC0 = 1;
}
int main(){
/* PORTB como saída */
GPIO_B->DDR = 0xff;
/* Obtem o stream de depuração */
FILE *debug = get_usart_stream();
/* Inicializa hardware da USART */
USART_Init(B9600);
/* Inicializa o converor AD */
adc_init();
timer0_hardware_init();
/* Ativa todos IRQs */
sei();
/* Exbibe no terminal o valor do AD.
* A conversão é realizada conforme o prescaler
*/
while(1){
fprintf(debug, "%d\r", valor_adc);
_delay_ms(500);
}
}
ISR(ADC_vect)
{
/* Lê o valor do conversor AD na interrupção:
* ADC é de 10 bits, logo valor_adc deve ser
* de 16 bits
*/
valor_adc = ADC;
GPIO_CplBit(GPIO_B, 1);
}
/* Quando habilitado IRQ de overflow no timer 0*/
ISR(TIMER0_OVF_vect){
GPIO_CplBit(GPIO_B, 0);
}