利用LM35传感器和Atmega32 ADC进行温度测量
模拟数字转换每当我们处理产生模拟输出的传感器时,通常需要(例如:LM35温度传感器),这是各种传感器的情况。在处理此类传感器时,我们必须将其中的模拟信号转换为出来的数字词和零的数字词,以便我们的微控制器可以处理它并根据它做出决定。为此,我们需要一个名为ADC的设备(模拟到数字转换器)幸运的是,许多控制器现在拥有此设备内置。
在本文中,我们将学习如何使用Atmega32的ADC将模拟信号转换为数字信号。作为模拟信号的示例,我们将使用LM35温度传感器的输出信号。在本文结束时,我们将能够简单的火灾报警当温度超过某个极限(60℃)时,会触发蜂鸣器摄氏度(例如)。
ADC参考电压
参考电压是您期望从ADC输入通道上的传感器接收到的最大电压。在Atmega32中,您可以使用三种源之一作为参考电压:
- 来自Atmega32 MCU的内部电压。该电压设置为2.56V,无法更改。
- AVCC引脚可以是您的参考电压,但该引脚必须连接到VCC,在这种情况下,您的参考电压是VCC
- 最后,您可以使用您自己定制的参考电压,通过连接与您想要的参考电压相同的电压源到引脚AREF (pin32)。
在配置时,在这三个参考电压之间进行选择ADMUX注册,我们将在本文后面解释。我们将使用内部电压选项。
硬件要求:
在使用Atmeg32的ADC之前,电路中需要一些硬件连接,以便获得最佳结果:
- 你应该确保引脚(10和30)是连接的(VCC和AVCC)。这是因为ADC从AVCC引脚获得电源。
- 如果转换精度始终至关重要,最好在2个引脚之间连接一个线圈,在AVCC和GND之间连接一个电容器。这两种连接使ADC的电源电压更加稳定,并且不容易因噪声而波动。
- 此外,在AREF和GND之间连接一个电容是更好的,这样ADC的参考电压更稳定,不受噪声的影响。(即使您选择使用内部电压或AVCC)
- 如果您要使用外部参考电压,那么您应该将其连接到ISF引脚。在本文中,我们将使用内部参考电压,因此我们不需要此步骤。
ADC输入通道
Atmega32的ADC最多可以接受八个通道的输入。这意味着您可以将多达8个模拟输入信号连接到Atmega32 ADC,但在每次转换时,只有一个通道输入被转换。因此,在每次转换时,您应该在开始转换之前首先选择要转换的输入通道。这也是在ADMUX登记。
输入通道通过ATmega32端口A的引脚进行多路复用。这些是销(33至40)
lm35dz.
LM35D是一种温度传感器LM35温度传感器系列的一部分。如下图所示,它有3个管脚。其中Vs连接到高压(VCC),GND连接到GND,Vout连接到Atmega32 ADC的输入通道
重要的提示:上面的引脚图(与数据表相同)显示了底部视图中的传感器引脚。因此,注意不要以反向的引脚顺序连接传感器。
LM35输出电压与温度线性成比例。它将每个1摄氏度的程度代表10 mV,因此如果温度为20摄氏度,则LM35的输出电压将是(20 * 10mV = 200mV)。
当LM35如上所述连接时,它可以检测2到150摄氏度之间的温度,这意味着最大输出电压为(150*10mV=1500mV=1.5V)。这意味着我们应该使用1.5V的参考电压以获得最佳精度。但是,为了简单起见,我们可以使用内部电压(2.56V)这就是我们在本文中要做的。
温度计算
这个Atmega32模数转换器具有10位的分辨率,这意味着ADC的输出将是10位二进制字。这也意味着ADC的最大输出将是二进制1111.1111.11,对应于十进制1023的值。
现在,由于ADC的最大输出为1023,最大输入为2.56(参考电压),因此我们可以使用以下等式计算对应的ADC输出到10mV的输入:
因此,每10mV会使ADC输出一个值为4,由于10mV对应1摄氏度,那么每摄氏度会使ADC输出一个值为4。因此,如果温度是20摄氏度,ADC的输出将是(20*4=80),在二进制中是(0001.0100.00)。我们将从ADCH和ADCL寄存器读取这个值,我们将对此进行解释。
因此,作为我们案例中的结论,我们可以使用以下等式计算ADC输出的温度值:
软件要求
现在,让我们来了解Atmega32上的ADC软件配置
要在Atmeg32上启用模拟数字转换器,我们需要做以下步骤:
- 在ADMUX寄存器(ADC多路复用器选择寄存器):
- 将两个位(refs1&refs0)设置为一个。这告诉Atmega32使用2.56的内部电压作为参考电压。
- 将Adlar位清除为零。这将留下调整ADC输出(将在稍后解释读取ADC输出)
- 通过设置5位(MUX0…MUX4)的值来选择ADC输入通道。在本文中,我们将把它们全部清除为零,以选择第一个输入通道。这个通道是端口A的第一个引脚,是Atmega32 IC的引脚40,如果你想使用另一个通道,请查看下表,以知道这些位的正确值。
MUX0…MUX4 | ADC输入通道 |
00000 | ADC0. |
00001 | ADC1. |
00010 | ADC2. |
00011 | ADC3. |
00100 | ADC4. |
00101 | ADC5. |
00110 | ADC6. |
00111 | ADC7. |
ADMUX寄存器 | |||||||
REFS1 | REFS0 | 达尔 | MUX4 | MUX3 | MUX2 | MUX1 | MUX0 |
1. | 1. | 0 | 0 | 0 | 0 | 0 | 0 |
- 在ADCSRA寄存器(ADC状态寄存器A)中:
- 将位ADEN设置为1。这将启用ADC。
- ADC模块需要一个时钟来工作,它从MCU时钟中获取这个时钟。然而,MCU时钟在被馈送到ADC之前被除以一个因子。这个因子是由ADCSRA寄存器中的位(ADPS2, ADPS1, ADPS0)决定的。在本文中,我们将把这三位设为1,使除法因子为128。如果您想使用另一个除法因子,请检查下表中这些位的正确值。
ADPS2 | ADPS1 | ADPS0 | 划分因子 |
0 | 0 | 0 | 2. |
0 | 0 | 1. | 2. |
0 | 1. | 0 | 4. |
0 | 1. | 1. | 8. |
1. | 0 | 0 | 16 |
1. | 0 | 1. | 32 |
1. | 1. | 0 | 64 |
1. | 1. | 1. | 128 |
ADCSRA寄存器 | |||||||
亚丁 | Adsc. | ADATE | 阿迪夫 | 艾迪 | ADPS2 | ADPS1 | ADPS0 |
1. | 0 | 0 | 0 | 0 | 1. | 1. | 1. |
开始转换并读取ADC输出
要启动模拟到数字信号转换,我们将thADCSRA中的位(ADSC位)为1。ADC立即开始从输入通道读取模拟信号(如上所述,在ADMUX中指定),并将其转换为数字10位字。完成转换后,ADSC位再次清零,ADC模块将转换输出(10位)写入两个名为ADCH和ADCL的寄存器。位的组织如下图所示。
注意ADLAR=0和ADLAR=1之间的区别。在本文中,我们在ADMUX寄存器中设置ADLAR=0。
如果ADLAR=0:
– | – | – | – | – | – | ADC9. | ADC8. | ad |
ADC7. | ADC6. | ADC5. | ADC4. | ADC3. | ADC2. | ADC1. | ADC0. | ADCL. |
如果ADLAR=1:
ADC9. | ADC8. | ADC7. | ADC6. | ADC5. | ADC4. | ADC3. | ADC2. | ad |
ADC1. | ADC0. | – | – | – | – | – | – | ADCL. |
在读取ADC输出时,我们应该先读取ADCL,然后再读取ADCH。这是因为读取ADCL会通知ADC模块读取过程正在进行,因此在读取ADCH之前不会发生转换。
在我们的程序中,我们将使用第一个ADC通道将LM35的输出从模拟转换为数字,当温度超过60摄氏度时,我们将打开连接在D端口引脚5的蜂鸣器。
以下是用于演示的电路的原理图,程序代码,电路图片和视频。
线路图
程序/代码
#define get_bit(reg,bitnum) ((reg & (1<>bitnum) #include int main(void) {int ADCOut=0;char温度;DDRD = 0 b00010000;//设置端口D的引脚4作为输出来控制蜂鸣器DDRA&=~(1<<0);ADMUX = 0 b11000000;ADCSRA = 0 b10000111;而(1){ADCSRA | = (1 < < 6);//设置位6 n ADCSRA开始转换,同时(get_bit(ADCSRA,6)==1) //轮询位6 n ADCSRA直到它再次归零{}ADCOut=ADCL|(ADCH<<8);//将ADC读取保存为整型变量ADCOut。必须像这里写的那样首先读取ADCL。 Temperature=ADCOut/4; // Calculate Temperature if (Temperature>=60) // Check if temperature is above 60 Celsius degrees { PORTD|=(1<<4); //turn on the buzzer } else { PORTD&=~(1<<4); //turn off the buzzer } } }
输出照片
我在我的AVR开发板上实现了这个电路。如果您有任何疑问,请随时在评论部分提问。
演示视频
我希望你们都喜欢我的教程!
3.注释
这对我来说既有用又容易理解。谢谢。
是否可以通过Atmega32插入更多与使用不同传感器相关的项目?
很好的教程,您使用哪个IDE进行编码?