我是这个领域的初学者。我的目标是根据电位计更改8个LED(连接到PORTA)的输出。我已将电位计的中线连接到PF0,即ADC0。我还将另外两条线连接到5V和地。
我知道芯片或连接没有问题,因为LED正常工作。
但是,无论我如何更改下面的代码(通过更改ADMUX和ADCSRA寄存器来表示更改的意思),都不会显示输出!
我正在使用带有16MHZ时钟的atmega128。以下是我要解决的代码。
#include <asf.h>
#include <avr/io.h>
#define F_CPU 16000000L
int init_board(void)
{
DDRA=0xff;
PORTA=0x01;
}
int ADC_init(void)
{
//ADCSRA
ADCSRA = 0b10000111;
//ADMUX
ADMUX = 0b01100000; // middle line connected to ADC0
}
int main (void)
{
init_board();
ADC_init();
ADCSRA |= (ADSC >> 1);
while(1)
{
if(ADSC == 0)
{
uint8_t disp_value = ADCL;
PORTA = disp_value;
delay_ms(200);
ADCSRA |= (ADSC >> 1);
}
}
}
我不知道为什么代码不起作用。
我想是因为它没有正确设置我的寄存器,但是我遵循了atmega128数据表上的所有说明。
最佳答案
第一个问题是您的移位,应该为ADCSRA |= (1 << ADSC)
。
下一个问题是结果阅读。您将ADMUX的第五位设置为1,因此ADLAR = 1,并且在该模式下,对结果进行了调整,因此您应该读取ADCH。
此外,当您切换到10位分辨率时,即开始处理多字节结果时,请注意仅读取ADCL是不够的,请参见数据表23.3进行解释:“一旦读取ADCL,就会阻止ADC对数据寄存器的访问。这意味着,如果已经读取ADCL,并且在读取ADCH之前完成转换,则不会更新任何寄存器,并且转换结果将丢失。读取ADCH时,将重新启用对ADCH和ADCL寄存器的ADC访问。”
最后,使用硬编码的延迟进行读取不是一种好习惯,尤其是当您稍后更改代码以尽可能快地读取ADC时。在这种情况下,转换开始后,您应该检查是否设置了ADIF标志或在设置ADEN时与Interrup进行了反应。有关详细信息,请参见数据表。