本帖最后由 lisingch 于 2018-10-5 16:09 编辑
这个温湿度测试仪以SC92F8003作为主控MCU,对AM2302采集的室内温、湿度数据进行处理,并驱动4位液晶显示模块PDC401分时显示温、湿度数据。温度显示为“XX.X口”;湿度显示为“XX.XH”;AM2302故障时显示为“Erro”。电源采用3节“AAA”电池供电,本打算设置为“IDLE”或者“STOP”工作方式减少电池消耗,便于长时间待机。最后考虑只是短暂室内温、湿度测试,便选用了通过开关控制,需要测试时打开电源开关,测试完成后即可切断电源。下面是整体实验过程:
一、实验环境及资源
1、Keil MDK51 9.59
2、SC-LINK
3、SC92F8003的DEMO硬件板
4、PDC401模块
5、AM2302模块
二、硬件
1、PDC401模块。该模块采用HD44100控制,可显示4位数字,字符高度与0.56数码管相近,模块整体外围尺寸为:35*60。模块与外部通过4位2.54的排针相连,即:Pin1 GND、Pin2 CLK、Pin3 DI、Pin4 VCC。手里没有模块的资料,有两份HD44100的,有兴趣的可以看看;(详附件)
2、AM2302温、湿度传感器。这个也叫DHT22,比之前的DHT11性能要好,体积也大,当然价格也相对贵一些;(资料详附件)
3、PCB。PCB采用Sprint-Layout 6.0 绿色汉化版绘制,尺寸同PDC401;(资料详附件)
4、电源。电源采用带开关三节“AAA”电池盒,其宽尺寸较PDC401稍大一点。成品采用三层结构,PCB与PDC401通过两只15mm铜柱连接;PCB背面用胶与电池合粘结;
三、软件
1、PDC401驱动。程序比较简单,主要是对HD44100的操控。另外为了显示温度、湿度以及错误“Erro”写了三个显示函数,不知有没有更好的处理办法?请朋友们指教!
/******************************************************
函数功能: 显示温度
输入参数: temp
返 回 值: 无
说 明:最后一位显示温度标志“口”
******************************************************/
void DispTemp(unsigned int temp)
{
unsigned char w1,w2,w3;
w1 = temp / 100;
w2 = temp % 100 / 10;
w3 = temp % 10;
WriteBuf();
DispBuff[0]= tab[w1];
DispBuff[1]= tab[w2] & 0xfe; //加显小数点
DispBuff[2]= tab[w3];
DispBuff[3]= 0X39; //显示温度标志“口”
}
/******************************************************
函数功能: 显示错误“Erro”
输入参数: 无
返 回 值: 无
说 明:如果AM2302没有连接显示“Erro”
******************************************************/
void DispErro(void)
{
WriteBuf();
DispBuff[0]= 0X61;//E
DispBuff[1]= 0XF5;//r
DispBuff[2]= 0XF5;//r
DispBuff[3]= 0XC5;//o
}
2、AM2302数据处理。这个采集处理程序移植、修改自硬石YS-F1Pro相关例程,在此表示感谢!/************************AM2302数据类型定义**********************/
typedef struct
{
unsigned char humH8bit; //湿度高8位
unsigned char humL8bit; //湿度低8位
unsigned char temH8bit; //温度高8位
unsigned char temL8bit; //温度高8位
unsigned char check; //校验和
float hum; //实际湿度
float tem; //实际温度
} AM2302_TypeDef;
/******************************************************
函数功能: 从AM2302读取一个字节,MSB先行
输入参数: 无
返 回 值: temp从AM2302读取的数据8位数据
说 明:1、每bit以50us低电平标置开始,轮询直到从机发出的50us低电平结束
2、AM2302 以26~28us的高电平表示“0”,以70us高电平表示“1”
******************************************************/
static unsigned char AM2302_ReadByte(void)
{
unsigned char i, temp=0;
for(i=0; i<8; i++)
{
while(AM2302_Port == 0);
Delay10us(); //延时40us
Delay10us();
Delay10us();
Delay10us();
if(AM2302_Port == 1) //40us后仍为高电平表示数据“1”
{
while(AM2302_Port == 1); //等待数据1的高电平结束
temp |= (unsigned char)(0x01<<(7-i)); //把第7-i位置1,MSB先行
}
else
{
temp &= (unsigned char)~(0x01<<(7-i));//把第7-i位置0,MSB先行
}
}
return temp;
}
/*************************************************************************
函数功能: 一次完整的数据传输为40bit,高位先出
输入参数: AM2302
返 回 值: 0:读取出错;1:读取成功
说 明:8bit湿度整数 + 8bit湿度小数 + 8bit温度整数 + 8bit温度小数 + 8bit校验和
**************************************************************************/
unsigned char ReadAM2302(AM2302_TypeDef *AM2302)
{
unsigned char temp;
unsigned int hum_temp,tem_temp;
AM2302_OUT(); //将AM2302端口设置为输出模式
AM2302_Port_L(); //将AM2302端口拉低
Delayms(18); //延时18ms
AM2302_Port_H(); //将AM2302端口拉高,主机延时30us
Delay10us(); //延时30us
Delay10us();
Delay10us();
AM2302_IPU(); //将AM2302端口设置为输入,判断AM2302响应信号*/
if(AM2302_Port == 0) //判断AM2302是否有低电平响应信号,如不响应则跳出,响应则向下运行*/
{
while(AM2302_Port == 0);//等待AM2302发出的80us低电平响应信号结束*/
while(AM2302_Port == 1);//等待AM2302发出的80us高电平标置信号结束*/
AM2302->humH8bit = AM2302_ReadByte();//接收AM2302返回的数据
AM2302->humL8bit = AM2302_ReadByte();
AM2302->temH8bit = AM2302_ReadByte();
AM2302->temL8bit = AM2302_ReadByte();
AM2302->check = AM2302_ReadByte();
AM2302_OUT(); //读取AM2302返回的数据后将AM2302端口改为输出模式
AM2302_Port_H(); //将AM2302端口置高
hum_temp = AM2302->humH8bit * 256 + AM2302->humL8bit;//处理湿度数据
AM2302->hum = (float)hum_temp;
tem_temp = AM2302->temH8bit * 256 + AM2302->temL8bit;//处理温度数据
AM2302->tem = (float)tem_temp;
temp = AM2302->humH8bit + AM2302->humL8bit +
AM2302->temH8bit + AM2302->temL8bit;//校验读取的数据
if(AM2302->check == temp)
{
return 1;
}
else
return 0;
}
else
return 0;
}
3、延时。之所以在这里谈到延时程序,首先是因为AM2302对于时序的要求比较严格,再有是因为在keil中测试正确但下载到芯片后误差偏大,最后采用逻辑分析仪在AM2302驱动管脚上测试得到以下数据“。
void Delayms(unsigned int ms)//毫秒延时,16MHz下用逻辑分析仪测试
{
unsigned int i;
for(; ms>0; ms--)
for(i=1065; i>0; i--);
}
void Delay10us(void)//10微秒延,16MHz下用逻辑分析仪测试
{
unsigned char i;
_nop_();
i = 29;
while (--i);
}
四、实验结果
1、SC92F8003芯片配置
2、硬件整体外观
3、温度显示效果
4、湿度显示效果
5、“错误”显示效果
五、总结
首先,再次感谢21ic及赛元公司组织的这次活动!
通过几次如GPIO、UART、ADC、PWM等小实验,对赛元的 SC92F8003这款单片机有了更深入的了解,接下来还要对其它的几个外设进行实验学习,以便更好地掌握这款单片机。
在之前实验中发现UART与SC LINK有端口冲突的现象,在本案中软件仿真与实际测试中的延时时间不相符的问题,期待能得到各位朋友的指教和帮助。
最后祝愿赛元公司在“中国芯”的道路上勇往直前、开拓进取!事业发展、如日中天!
水平有限,请各位朋友指教!
六、附件
本附件包含了完整的工程文件、所用到的硬件资料及PCB文件。本案实验中PDC401引脚与PCB文件中有所不同。
PDC401 AM2302.rar
(859.75 KB)
|