使用简单的 C 语言程序,让 LM35 温度传感器测量温度,LM35 温度传感器采样的模拟信号输出送到 LM358 运算放大器进行放大 5 倍之后,送到 ADC0832 模数转换芯片的CH0管脚,转换完成后输出到单片机,ADC0832的CLK引脚连接单片机的P1.3引脚,ADC0832的DO引脚连接单片机的P1.4引脚,ADC0832 的CS 的引脚接单片机的 P1.5 引脚。 将采集到的温度显示在 LCD1602 显示屏上,LCD1602 可以显示两行,第一行是测的温度,第二行是阈值设定的范围调节。 LCD1602 的 RS 引脚与单片机的 P2.5 引脚相连接,RW 与 P2.6,E 与 P2.7 相连,D0-D7 与 P0.0-P0.7 分别相连接,有三个按键,分别与单片机的 P3.5,P3.6,P3.7 相连接,分别为设置、加和减按键,设置按键依次按下可以选择所要选择的项,依次是温度、湿度、一氧化碳、二氧化碳。 可以通过手动预先设定阈值,当发现采集到的温度值不在预先设定的阈值内时,将通过STC89C52 单片机的P1.6引脚给出信号,驱动继电器控制输出,进行工作。
时间: 2023-06-17 14:08:09 浏览: 216
这是一个比较完整的嵌入式系统设计,需要涉及到多个硬件模块的连接和编程,需要一定的电子电路和嵌入式编程知识。以下是一个简单的 C 语言程序框架,可以供参考:
```c
#include <reg52.h> // 8051单片机头文件
#include <stdio.h> // 标准输入输出库
#include <intrins.h> // 延时函数库
#define LCD_RS P2_5 // LCD1602 RS引脚
#define LCD_RW P2_6 // LCD1602 RW引脚
#define LCD_E P2_7 // LCD1602 E引脚
#define LCD_D P0 // LCD1602 数据引脚
#define ADC_CS P1_5 // ADC0832 CS引脚
#define ADC_CLK P1_3 // ADC0832 CLK引脚
#define ADC_DOUT P1_4 // ADC0832 DOUT引脚
#define RELAY P1_6 // 继电器控制引脚
#define SET_BTN P3_5 // 设置按键
#define INC_BTN P3_6 // 加按键
#define DEC_BTN P3_7 // 减按键
/* 延时函数 */
void delay(unsigned int t) {
while (t--)
_nop_();
}
/* LCD1602 写命令 */
void lcd_write_cmd(unsigned char cmd) {
LCD_RS = 0;
LCD_RW = 0;
LCD_D = cmd;
LCD_E = 1;
delay(5);
LCD_E = 0;
}
/* LCD1602 写数据 */
void lcd_write_data(unsigned char dat) {
LCD_RS = 1;
LCD_RW = 0;
LCD_D = dat;
LCD_E = 1;
delay(5);
LCD_E = 0;
}
/* 初始化 LCD1602 */
void lcd_init() {
lcd_write_cmd(0x38); // 8位数据总线,2行显示,5x7点阵字符
lcd_write_cmd(0x0c); // 开启显示,不显示光标
lcd_write_cmd(0x06); // 设定文字写入方式,不移动光标
lcd_write_cmd(0x01); // 清屏
}
/* 读取 ADC0832 转换结果 */
unsigned int adc_read(unsigned char ch) {
unsigned int val = 0;
ADC_CS = 0; // 使能 ADC0832
ADC_DOUT = 1; // 使 ADC0832 输出高电平
ADC_CLK = 0; // 先将 CLK 置为低电平
ADC_CS = 1; // 使 ADC0832 输出转换结果
ADC_CS = 0;
ADC_DOUT = 0; // 开始转换
ADC_CLK = 1;
ADC_CLK = 0;
ADC_DOUT = 1; // 转换完成
ADC_CLK = 1;
ADC_CLK = 0;
ADC_DOUT = 1; // 读取转换结果
for (unsigned char i = 0; i < 10; i++) {
ADC_CLK = 1;
ADC_CLK = 0;
val <<= 1;
if (ADC_DOUT)
val |= 1;
}
ADC_CS = 1; // 关闭 ADC0832
return val;
}
/* 显示温度值和阈值范围 */
void lcd_display_temp(unsigned int temp, unsigned int threshold_low, unsigned int threshold_high) {
char str[16];
lcd_write_cmd(0x80); // 第一行
sprintf(str, "Temp:%dC", temp);
for (unsigned char i = 0; i < 8; i++)
lcd_write_data(str[i]);
lcd_write_cmd(0xc0); // 第二行
sprintf(str, "Th:%d-%dC", threshold_low, threshold_high);
for (unsigned char i = 0; i < 11; i++)
lcd_write_data(str[i]);
}
/* 主函数 */
void main() {
unsigned int temp = 0; // 温度值
unsigned int threshold_low = 20; // 阈值范围下限
unsigned int threshold_high = 30; // 阈值范围上限
unsigned char setting = 0; // 当前设置项
lcd_init(); // 初始化 LCD1602
lcd_display_temp(temp, threshold_low, threshold_high); // 显示温度值和阈值范围
while (1) {
temp = adc_read(0) * 5 / 1024; // 读取 ADC0832 转换结果
lcd_display_temp(temp, threshold_low, threshold_high); // 显示温度值和阈值范围
if (temp < threshold_low || temp > threshold_high) { // 温度超出阈值范围
RELAY = 1; // 继电器闭合,控制输出
} else {
RELAY = 0; // 继电器断开
}
if (!SET_BTN) { // 设置按键按下
delay(10); // 延时去抖动
if (!SET_BTN) { // 再次检测按键状态
setting++; // 切换设置项
if (setting > 3)
setting = 0;
switch (setting) { // 显示当前设置项
case 0:
lcd_write_cmd(0x80);
lcd_write_data('T');
lcd_write_data('e');
lcd_write_data('m');
lcd_write_data('p');
lcd_write_data(':');
lcd_write_data(' ');
break;
case 1:
lcd_write_cmd(0x80);
lcd_write_data('H');
lcd_write_data('u');
lcd_write_data('m');
lcd_write_data('i');
lcd_write_data('d');
lcd_write_data('i');
lcd_write_data('t');
lcd_write_data('y');
lcd_write_data(':');
break;
case 2:
lcd_write_cmd(0x80);
lcd_write_data('C');
lcd_write_data('O');
lcd_write_data(':');
break;
case 3:
lcd_write_cmd(0x80);
lcd_write_data('C');
lcd_write_data('O');
lcd_write_data('2');
lcd_write_data(':');
break;
}
}
while (!SET_BTN); // 等待按键释放
}
if (!INC_BTN) { // 加按键按下
delay(10); // 延时去抖动
if (!INC_BTN) { // 再次检测按键状态
switch (setting) { // 根据当前设置项更新阈值范围
case 0:
threshold_high++;
break;
case 1:
threshold_high++;
break;
case 2:
threshold_high++;
break;
case 3:
threshold_high++;
break;
}
}
while (!INC_BTN); // 等待按键释放
}
if (!DEC_BTN) { // 减按键按下
delay(10); // 延时去抖动
if (!DEC_BTN) { // 再次检测按键状态
switch (setting) { // 根据当前设置项更新阈值范围
case 0:
threshold_low--;
break;
case 1:
threshold_low--;
break;
case 2:
threshold_low--;
break;
case 3:
threshold_low--;
break;
}
}
while (!DEC_BTN); // 等待按键释放
}
}
}
```
需要注意的是,LM358 运算放大器的输出需要接到 ADC0832 的输入管脚 CH0 上,同时需要注意 LM358 的供电电压和 ADC0832 的供电电压需要相同。此外,需要根据实际情况修改硬件连接和编程代码。
阅读全文