我试图在我的arduino Pro mini上简单地从A0获取模拟读数,但我无法获得存储在adc寄存器中的值。 应该发生的是模拟信号将被放入寄存器ADCL& ADCH然后ADC中断将触发。 我在A0上设置了一个分压器,它应该读取2.5V,但我的中断没有触发,我无法从ADCH或ADCL获取值。我可以用arduino阅读,所以我知道硬件有效。当我运行这个程序时,我得到一个连续打印0到我的终端,告诉我低和高的值永远不会改变,因为他们应该在中断。
这是我的代码:
# define F_CPU 16000000L
#include "time.h"
#include <avr/io.h>
#include <math.h>
#include <util/delay.h> // including the avr delay lib
#include <util/delay.h> // Including the avr delay lib
#include "usart.h"
#include "usart.cpp"
#include <stdio.h>
#include <avr/interrupt.h>
uint8_t low,high;
int main(void)
{
TCCR0B = (1<<CS02) | (1<<CS00);
USART_Init(MYUBRR);
DDRC = 0x0 ;
ADCSRA = (1<<ADEN) | (0<<ADIF); //activate adc & clear ADIF
ADMUX = (0<<ADLAR); //keep right adjusted
ADMUX = (1<<REFS0) | (0<<MUX2) | (0<<MUX1) | (0<<MUX0);//set ref as vcc, input as 0
ADCSRA = (1<<ADIE) | (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);//enable adc interrupt & divide clock by 124
DIDR0 = (0<<ADC0D);
sei();
ADCSRA = (1<<ADSC);//begin conversion
while (1)
{
while(ADSC==1)//wait for conversion to complete
{
sei();
}
USART_Send_int(low);
USART_Send_int(high);
_delay_ms(100);
ADCSRA = (1<<ADSC);
}
}
ISR(ADC_vect) //interrupt to trigger when conversion is complete
{
low = ADCL;
high = ADCH;
//ADCSRA = (1<<ADSC);
}
答案 0 :(得分:1)
您应该将low
和high
声明为volatile,因为您正在从中断和主循环访问它们:
volatile uint8_t low;
volatile uint8_t high;
否则,编译器可以通过将这些变量的读数移动到循环之前来自由优化循环。
或者,您可以尝试在循环中设置一个内存屏障,但这是一条不太常见的道路:大多数嵌入式开发人员倾向于使用volatile
。
我没有测试您的代码,因此可能还有其他错误。
为了进一步调试,您应该尝试将low = 44;
和high += 1;
放在中断中,以确保中断正在运行。