#include "stc12c5a60s2.h" //单片机选型stc12c5a60s2-DIP40
#include "intrins.h"
#include<stdio.h>
#define nop() _nop_()
#define uchar unsigned char
#define uint unsigned int
#define ulong unsigned long
#define CMD_IDLE 0
#define CMD_READ 1
#define CMD_PROGRAM 2
#define CMD_ERASE 3
#define ENABLE_IAP 0x83
sbit DHT = P1^0; //DHT11
sbit LCD_SID = P0^0; //即LCD RW口
sbit LCD_CLK = P0^1; //即LCD E口
uint RH_data,RL_data,TH_data,TL_data,CK_data,R,T;//定义全局变量
uchar undata,shuju;
code uchar name1[] = {"温度"};
code uchar name2[] = {"湿度"};
code uchar name3[] = {"摆幅"};
code uchar name4[] = {"呼吸"};
code uchar name5[] = {"心率"};
code uchar name6[] = {"血氧"};
code uchar name7[] = {" -"}; //当使用DHT22时启用该句,温度零下时,显示负号
/*******************DHT11-22用***********************/
uchar read_8bit();
uchar read_data();
/*******************LCD12864用***********************/
void InitializeLcd12864();//初始化LCD
void InitializeDisplay1(); //初始化显示内容
void InitializeDisplay2(); //初始化显示内容
void displaystring(uchar add,uint num);//写入字符串
void WriteCommandLcd12864(uchar temp);//写入命令
/*******************主函数**************************/
void main()
{
InitializeLcd12864();
while(1)
{
//uint i;i++;Delay1ms();if(i==2200){i=0;read_data();}//按厂家要求间隔2秒时间采集温湿度传感器数据
read_data();
/*************12864各行列地址******************/
//列 1 2 3 4 5 6 7 8
//第一行:80H、81H、82H、83H、84H、85H、86H、87H
//第二行:90H、91H、92H、93H、94H、95H、96H、97H
//第三行:88H、89H、8AH、8BH、8CH、8DH、8EH、8FH
//第四行:98H、99H、9AH、9BH、9CH、9DH、9EH、9FH
/*************12864各行列地址******************/
if((TH_data&0x80)==0) //当使用DHT22时启用该句,温度零下时,显示负号
{InitializeDisplay1();displaystring(0x90,T);}//当使用DHT22时启用该句,温度零下时,显示负号
if((TH_data&0x80)!=0) //当使用DHT22时启用该句,温度零上时,熄灭负号
{InitializeDisplay2();displaystring(0x91,T);} //当使用DHT22时启用该句,温度数据第2行第12两列,4个半角字符即2个汉字长度
//displaystring(0x90,T); //当使用DHT11时启用该句,温度数据第2行第12两列,4个半角字符即2个汉字长度
displaystring(0x96,R); //湿度数据第2行第78两列,4个半角字符即2个汉字长度
displaystring(0x98,shuju); //未定数据第4行第12两列,4个半角字符即2个汉字长度
displaystring(0x9e,shuju); //未定数据第4行第68两列,4个半角字符即2个汉字长度
}
}
/*********************延时函数******************************/
void Delay_DHT35us() //1T mcu STC12c5a60s2@12MHz
{
uchar i;
i = 102;
while (--i);
}
void Delay_DHT30us() //1T mcu STC12c5a60s2@12MHz
{
uchar i;
i = 87;
while (--i);
}
void Delay_DHT18ms() //1T mcu STC12c5a60s2@12MHz
{
uchar i, j, k;
i = 1;
j = 211;
k = 24;
do
{
do
{
while (--k);
}
while (--j);
}
while (--i);
}
void Delay_LCD_ms(uint xms) //1T mcu STC12c5a60s2@12MHz
{
uint y=0;
for(;xms>0;xms--)
for(y=0;y<600;y++);
}
void Delay_LCD10us() //@12MHz
{
uchar i;
_nop_();
_nop_();
i = 27;
while (--i);
}
/*********************DHT部分*************************/
uchar read_8bit() //读一个字节8bit
{
uchar i;
uchar temp=0;
uchar dat;
//EA=0; //程序如有中断,关闭中断,防止在us级延时期间发生中断,影响数据读取
for(i = 0;i < 8;i++)
{
while(!DHT);
Delay_DHT30us();
temp = 0;
if(DHT == 1) temp = 1;
while(DHT);
dat<<=1;
dat = dat|temp;
}
//EA=1; //读完后打开中断
return dat;
}
uchar read_data()
{
// DHT = 1; //使用DHT11时启用该句
// Delay8us(); //使用DHT11时启用该句
DHT = 0;
Delay_DHT18ms(); //奥松DHTT1说明拉低大于18ms,DHTT22说明拉低大于800us即可。
DHT = 1;
EA=0;
Delay_DHT35us();
EA=1;
if(!DHT)
{
while(!DHT);
while(DHT);
RH_data = read_8bit();
RL_data = read_8bit();
TH_data = read_8bit();
TL_data = read_8bit();
CK_data = read_8bit();
undata = RH_data + RL_data + TH_data + TL_data;
}
if(CK_data != undata) return 0;
if(CK_data == undata)
//R=RH_data; //当使用DHT11时启用该句
//T=TH_data; //当使用DHT11时启用该句
//TH_data=TH_data|0x80; //当使用DHT22时启用该句时,模拟零下温度,测试完成后删除此句
if((TH_data&0x80)==0) //当使用DHT22时启用该句
T=TH_data*256+TL_data; //当使用DHT22时启用该句
if((TH_data&0x80)!=0) //当使用DHT22时启用该句,当温度零下时,温度数据最高位置1,用0x80去“与”,检测出这个1
T=(TH_data&0x7f)*256+TL_data;//当使用DHT22时启用该句,用0x7f去“与”,消去最高位上的1,得到真实温度数据
R=RH_data*256+RL_data; //当使用DHT22时启用该句
return 1;
}
/********************lcd12864显示部分*******************/
void InitializeLcd12864()//初始化LCD
{
WriteCommandLcd12864(0x30);//基本功能
WriteCommandLcd12864(0x0c);//显示开,光标关
WriteCommandLcd12864(0x01);//清屏
}
void WriteByteLcd12864(uchar temp)//写入一个字节
{
uchar i;
LCD_CLK = 0;
for(i=0;i<8;i++)
{
if(temp&0x80)
LCD_SID = 1;
else
LCD_SID = 0;
LCD_CLK = 1;
Delay_LCD10us();
temp <<= 1;
LCD_CLK = 0;
Delay_LCD10us();
}
}
void WriteCommandLcd12864(uchar temp)//写入功能
{
WriteByteLcd12864(0xf8);
WriteByteLcd12864(temp&0xf0);
WriteByteLcd12864(temp<<4);
}
void WriteDataLcd12864(uchar temp)//写入变量数值
{
WriteByteLcd12864(0xfa);
WriteByteLcd12864(temp&0xf0);
WriteByteLcd12864(temp<<4);
}
void WriteStringAddress(uchar add,uchar length,uchar *temp)//写入字符串及其地址
{
WriteCommandLcd12864(add);
for(;length>0;length--)
{
WriteDataLcd12864(*temp);
temp++;
}
}
/********************显示***************************/
void displaystring(uchar add,uint num)
{
unsigned char buf[10],i;
buf[0] = num/100;
buf[1] = num%100/10;
buf[2] = num%100%10; //请注意当使用DHT11时,此位被强制为0 显示3位带小数点的数字 好看些
WriteCommandLcd12864(add); //地址
for(i=0;i<3;i++)
{
WriteDataLcd12864(buf[i]+0x30);
if(i==1)WriteDataLcd12864('.');
}
}
/******************显示内容初始化***********************/
/*************12864各行列地址******************/
//列 1 2 3 4 5 6 7 8
//第一行:80H、81H、82H、83H、84H、85H、86H、87H
//第二行:90H、91H、92H、93H、94H、95H、96H、97H
//第三行:88H、89H、8AH、8BH、8CH、8DH、8EH、8FH
//第四行:98H、99H、9AH、9BH、9CH、9DH、9EH、9FH
/*************12864各行列地址******************/
void InitializeDisplay1()
{
WriteStringAddress(0x80,4,name1);//“温度” 第1行第12两列,4个半角字符长度即2个16*16汉字长度
WriteStringAddress(0x83,4,name3);//“幅度” 第1行第45两列,4个半角字符长度
WriteStringAddress(0x86,4,name2);//"湿度" 第1行第78两列,4个半角字符长度
WriteStringAddress(0x88,4,name5);//“心率” 第3行第12两列,4个半角字符长度
WriteStringAddress(0x8b,4,name4);//“呼吸” 第3行第45两列,4个半角字符长度
WriteStringAddress(0x8e,4,name6);//“血氧” 第3行第78两列,4个半角字符长度
Delay_LCD_ms(100);
}
void InitializeDisplay2() //当使用DHT22时启用改函数
{
WriteStringAddress(0x80,4,name1);//“温度” 第1行第12两列,4个半角字符长度
WriteStringAddress(0x83,4,name3);//“幅度” 第1行第45两列,4个半角字符长度
WriteStringAddress(0x86,4,name2);//"湿度" 第1行第78两列,4个半角字符长度
WriteStringAddress(0x90,2,name7);
WriteStringAddress(0x88,4,name5);//“心率” 第3行第12两列,4个半角字符长度
WriteStringAddress(0x8b,4,name4);//“呼吸” 第3行第45两列,4个半角字符长度
WriteStringAddress(0x8e,4,name6);//“血氧” 第3行第78两列,4个半角字符长度
Delay_LCD_ms(100);
}
|