AM2120单总线温湿度传感器移植与应用
基于STC8G1K08单片机和AM2120温湿度传感器单总线接口技术移植与应用
作者: 郑贤亨 金建强
浙江省江山江汇电气有限公司
摘要:温湿度控制器在高低压开关柜中的运用相当普遍,在控制器的输出接上相应负载,为高低压开关柜的安全运行提供环境温度与湿度的干预及良好的保障。本文主要论述一种单总线结构温湿度一体数字传感器与单片机的接口技术,实现开关柜内环境检测并送数码管进行数据显示,另外有效进行对负载(加热除湿器、风机)控制。
关建词
单片机 温湿度传感器 单总线接口 C语言 驱动移植
1、引言
温湿度控制器在高低压开关柜中的运用十分广泛,但究其各类原理各种控制器都大同小异。通过热敏和湿敏电阻变化采样,不同环境输出一定范围的模拟电压,通过单片机的ADC接口转换和运算对应的温度和湿度并作出相应的输出显示、控制负载等。在MCU的运算转换过程中增大了数据的误差和精度。本文采用的温湿度传感器AM2120是具有单总线结构、集温度、湿度采集的一体化数字器件,根本上提高了数据源的精度与准确度。
2、单片机及主要硬件简介
2.1单片机
江苏国芯科技的STC8K1G08-TSSOP20其封装体积小,IO接口丰富功能全面,引脚图如下:
该单片机具有1.9~5.5V的宽电压供电,8KFLASH存储、256DATARAM、1KSRAM和16PIN IO引脚均具有10位的ADC功能,不过在这里我们并不使用它的这一功能,是利用了普通IO的模拟串行接口特点。
2.2 AM2120温湿度传感
由AM2120温湿度传感器的官方文档描述,它是一款含有已校准数字信号输出的温湿度复合型传感器。采用专用的温湿度采集技术确保产品具有极高的可靠性与卓越的长其稳定性。利用单总线通信方式,小体积。具有20米远的传输距离,是苛刻场合的最佳选择。另外用户无需要温度补偿等即可得到准确的温湿度信息,广泛运用自动控制及湿度检测控制。产品的温度与湿度分辨率0.1,接口引脚信息:
AM2120的采集转换误差曲线图:
要获得AM2120所采信的数据,关键要利用单片机引脚的输入输出特性与传感器的2引脚进行数据的交互,软件件实现单总线通信时序要求和理解单总线读取的流程图,并将读数的数据进行保存、转换、送显示等。
2.3基本硬件电路结构图
在这里用微控制器的P1.1与AM2120的SDA引脚相连接,传感器供电5V,根据传感器规格书的要求并上拉4.7K电阻。
3、硬件电路程序移植与驱动
3.1准备工作
在做驱动之前需要准备的基本工具,如万用表,STC烧写器等,并且印制电路板确保正确无误。软件:KEIL4 并安装好添加好STC的型号及头文件到其中、STC-ISP-15XX-V6.87F下载工具安装与驱动等。
当然在做单总线驱动之前,必须要先做的事情就是LED(数码管)的驱动IC,在这里我们不作重点论述。根据电路的特点如果74HC595或MBI5024之类的芯片,可参照相应的规格书的要求以及《单片机的实验与实践教程3》的驱动方法做修改移植,编写及调试好测量界面与设置菜单界面的相应程序。
通过上面的程序基础上,再进一步添加移植以下程序,是我们的重点,单总线接法与微控制器的P1^1相连。
//接口定义
sbit ST=P3^4; //74HC595锁存
sbit DATOUT= P3^2; //74HC595串行
sbit CLK= P3^3; //74HC595时钟信号
sbit KEYIN=P1^5; //按键输入
sbit COOLJDQOUT= P1^3; //控制部分除湿输出1
sbit HOTJDQOUT= P3^5; //控制部分加热继电器2
sbit Sensor_SDA = P1^1; //单总线接口定义
接下来需要定义几个AM2120规格书需要基本延时
void Delay10us() //@11.0592MHz
{
unsigned char i;
i = 35;
while (--i);
}
void Delay1ms() //@11.0592MHz
{
unsigned char i, j;
i = 15;
j = 90;
do
{
while (--j);
} while (--i);
}
void Delay20ms() //@11.0592MHz
{
unsigned char i, j, k;
i = 2;
j = 32;
k = 60;
do
{
do
{
while (–k);
} while (–j);
} while (–i);
}
/***********************************************************************/
void delay(unsigned int x)//延时函数
{
unsigned int i,j;
for(i=0;i<x;i++)
for(j=0;j<1;j++);
}
3.2主要时序的驱动
有了基本的延时,接着重点移植或调节对传感器发启动、读传感器的函数,包括传感器发出数据接收、单总线接收字等子函数,总的流程:
/********************************************
|* 功能: 读传感器发送的单个字节 |
*******************************************/
unsigned char Read_SensorData(void)
{
unsigned char i,cnt;
unsigned char buffer,tmp;
buffer = 0;
for(i=0;i<8;i++)
{
cnt=0;
while(!Sensor_SDA) //检测上次低电平是否结束
{
if(++cnt >= 300)
{
break;
}
}
//延时Min=26us Max50us 跳过数据"0" 的高电平
Delay10us(); //延时30us
Delay10us();
Delay10us();
//判断传感器发送数据位
tmp =0;
if(Sensor_SDA)
{
tmp = 1;
}
cnt =0;
while(Sensor_SDA) //等待高电平 结束
{
if(++cnt >= 200)
{
break;
}
}
buffer <<=1;
buffer |= tmp;
}
return buffer;
}
/********************************************
|* 功能: 读传感器 |
*******************************************/
unsigned char Read_Sensor(void)
{
unsigned char i;
//主机拉低(Min=800US Max=20Ms)
Sensor_SDA = 0;
Delay1ms(); //延时2Ms
Delay1ms();
//释放总线 延时(Min=30us Max=50us)
Sensor_SDA = 1;
Delay10us();//延时30us
Delay10us();
Delay10us();
//主机设为输入 判断传感器响应信号
Sensor_SDA = 1;
Sensor_AnswerFlag = 0; // 传感器响应标志
//判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行
if(Sensor_SDA ==0)
{
Sensor_AnswerFlag = 1;//收到起始信号
Sys_CNT = 0;
//判断从机是否发出 80us 的低电平响应信号是否结束
while((!Sensor_SDA))
{
if(++Sys_CNT>300) //防止进入死循环
{
Sensor_ErrorFlag = 1;
return 0;
}
}
Sys_CNT = 0;
//判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
while((Sensor_SDA))
{
if(++Sys_CNT>300) //防止进入死循环
{
Sensor_ErrorFlag = 1;
return 0;
}
}
// 数据接收 传感器共发送40位数据
// 即5个字节 高位先送 5个字节分别为湿度高位 湿度低位 温度高位 温度低位 校验和
// 校验和为:湿度高位+湿度低位+温度高位+温度低位
for(i=0;i<5;i++)
{
Sensor_Data[i] = Read_SensorData();
}
}
else
{
Sensor_AnswerFlag = 0; // 未收到传感器响应
}
return 1;
}
/********************************************
|* 功能:单片机开始校验与接收传感器的数据 |
*******************************************/
void UARTSend_Nbyte(void)
{
unsigned char tempH;
if(Sensor_AnswerFlag == 1)
{
Sensor_Check = Sensor_Data[0]+Sensor_Data[1]+Sensor_Data[2]+Sensor_Data[3];
//校验成功
if(Sensor_Check ==Sensor_Data[4])
{
sd_adj = Sensor_Data[0]*256+Sensor_Data[1];
tempH=Sensor_Data[2]&0x7f;
FW_flag=Sensor_Data[2]&0x80;
wd_adj= tempH*256+Sensor_Data[3];
}else //校验失败 送上读到数据
{
Uart1_TxByte('e');
Uart1_TxByte('r');
Uart1_TxByte('r');
Uart1_TxByte('o');
Uart1_TxByte('r');
}
}// 传感器未连接
else
{
// Uart1_TxByte('n');
// Uart1_TxByte('o');
// Uart1_TxByte('c');
// Uart1_TxByte('o');
// Uart1_TxByte('n');
// Uart1_TxByte('n');
// Uart1_TxByte('e');
// Uart1_TxByte('c');
// Uart1_TxByte('t');
}
//Uart1_TxByte('e');
}
当然,做上面程序的移植需要示波器,最好的是扩展一些串口通信的基本功能,能够让采集的数据上传到STC-IP-15**-V6.87F的串口助手显示。
3.3主程序模块如下:
main()
{
unsigned int k,L1;
IO_Initial();
Sensor_SDA=1;
HOTJDQOUT=0;
COOLJDQOUT=0;
UART1_config();
EA = 1;
B_TX1_Busy = 0;
FW_flag=0;
for(k=0;k<1000;k++)
{
Clear_Data();
diplay_6led(wd_adj,sd_adj,m);
}
while(1)
{
Read_Sensor();
UARTSend_Nbyte(); //将读出的数据送给wd_adj sd_adj
//FW_flag=1; 负温度测试示志
Uart1_TxByte(‘W’);
Uart1_TxByte(‘D’);
Uart1_TxByte(’=’); //发送ADC读数
Uart1_TxByte(wd_adj/1000 + ‘0’);
Uart1_TxByte(wd_adj%1000/100 + ‘0’);
Uart1_TxByte(wd_adj%100/10 + ‘0’);
Uart1_TxByte(wd_adj%10 + ‘0’);
Uart1_TxByte(‘S’);
Uart1_TxByte(‘D’);
Uart1_TxByte(’=’); //发送ADC读数
Uart1_TxByte(sd_adj/1000 + ‘0’);
Uart1_TxByte(sd_adj%1000/100 + ‘0’);
Uart1_TxByte(sd_adj%100/10 + ‘0’);
Uart1_TxByte(sd_adj%10 + ‘0’);
Uart1_TxByte(’ ‘);
Uart1_TxByte(’ ');
for(k=0;k<50000;k++)
{
if(page==0)//常规显示
{
pwd=0;
diplay_6led(wd_adj,sd_adj,m);
L1=0;
// L2=0;
}
else//菜单显示
{
Menusetup();
L1++;
if(L1==25000)
{
page=0;
}
}
}//for for
}
}
3.4程序调试验证
我们在做主程时是做了串口数据输出业务的,通过调用Uart1_TxByte函数将接收到的温湿度数据送到上位机,通过KEIL编设正常通过并运行,以收到25.3度和66.5%RH会打印出如下:
WD=0253 SD=0665 WD=0253 SD=0665
WD=0253 SD=0665 WD=0253 SD=0665
WD=0253 SD=0665 WD=0253 SD=0665
当然要让微控制器运行,光用上面几行代码是远远不够的,需要付出更多的测量、修改而且对LED显示、按建驱动都是比较大的工作量,成品实际运行效果图
4、结论
本文采用AM2120单总线一体式温湿度传感器,大大简化传感器的接口外围电路,并且实现数据的更加精确,归避了市面上模拟感器的不良缺陷,主机与传感器之间具有更简洁的连接方式的特点。
参考文档
1、江苏国芯科技有限公司《STC8G系列单片机技术参考手册-20200529》
2、周立功等 《单片机实验与实践教程3》
3、广州乐享电子有限公司 AM2120规格书、C51单总线AM系列示例程序等
版权声明:本文为CSDN博主「zxh_1978」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zxh_1978/article/details/122894817
暂无评论