我正在尝试使用ATmega16构建一个自动植物浇水系统。我们正在为我们的项目使用湿度传感器。以下是我们使用的湿度传感器的图像。
以下是我们使用的代码片段:
#include<avr/io.h>
int adc(void);
void pump(void);
int adc_value;
int main(void)
{
DDRC=0x01; //Defining PC0 as output
ADCSRA=0x87; //Setting the mode of operation
ADMUX=0x00; //Selection of channel and bit alignment
while(1)
{
adc_value=adc(); //reading moisture level
pump(); //Pump activator routine
}
return 0;
}
int adc(void)
{
int lower_bits,higher_bits,result;
ADCSRA|=(1<<6); //Turning on conversion
while(ADIF==0);
lower_bits=ADCL;
higher_bits=ADCH;
result=lower_bits|higher_bits<<8; //Accessing converted value by shifting
return result;
}
void pump(void)
{
if(adc_value>=700) //Pump ON trigger point
{
PORTC|=(1<<0);
}
else if(adc_value<=600) //Pump Off trigger point
{
PORTC&=~(1<<0);
}
}
代码有什么问题吗?因为在燃烧之后,我从模拟传感器输入获得湿土的低电压和干燥土壤的高电压,这是好的...但问题是,我总是在高压下在PC0处获得高电压......没有变化在干燥和潮湿的土壤的价值..在这种情况下,实际问题..电路设计或代码有什么问题吗?还有一件事,有人可以告诉我从PC0测量输出值的正确方法,而PC0又可以打开/关闭泵吗?
答案 0 :(得分:1)
转换开始前,您无法清除ADIF
标记。它将在第一次通过后始终读为1。添加一行来清除标志(通过向标志位写入1。是的,写1使其成为0.它不是常规寄存器。)
此外,您没有正确阅读旗帜。 ADIF
有点像素,因此您需要使用位掩码读取该字节。 (您实际上测试的是2==0
,因为ADIF
被定义为2。)
int adc(void)
{
int lower_bits,higher_bits,result;
ADCSRA |= (1 << ADIF); // <<<<<< Add this to clear flag
ADCSRA |= (1 << ADSC); //ADCSRA|=(1<<6); //Turning on conversion
while(ADCSRA & (1 << ADIF) == 0); //while(ADIF==0); <<<<<< Change this
lower_bits=ADCL;
higher_bits=ADCH;
result=lower_bits|(higher_bits<<8); //Accessing converted value by shifting
return result;
}
实际上,你已经无意中清除了旗帜。如果它是1,那么ADCSRA
在ADIF
位置有一个1,它会再次被写入。但是,更明确地表达你的意思。同样,您可以将这两个操作合并为一个任务。
int adc(void)
{
int lower_bits,higher_bits,result;
ADCSRA |= (1 << ADSC)|(1 << ADIF); //Turn on conversion and clear flag
while(ADCSRA & (1 << ADIF) == 0); //wait for flag
lower_bits=ADCL;
higher_bits=ADCH;
result=lower_bits|(higher_bits<<8); //Accessing converted value by shifting
return result;
}
我无法确认您的其余代码和接线是否正确,因为我看不到,这是第一个明显的问题。修复它,如果仍有问题,请更新您的问题。