|
经过几天的努力,终于搞出了89C51单片机控制AM2302湿度温度传感器+lcd1602+蓝牙上显示!
被店家坑死喽,还好我会改电路,把传感器模块的电路改为单总线模式,接法如图:(一定记得接地哦)
实物图:
实物图
手绘电路原理图:
接线方法
电路板封装图
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
电路原理图
这是部分程序:
- /*
- humidity RH就是相对湿度 日常生活中所指的湿度为相对湿度,%rh表示
- 温度(temperature)
- */
- #include<reg52.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- //uchar code table[]=" WELCOME ";
- uchar code table0[]="T: 'C";
- uchar code table1[]="RH: %";
- uchar code table2[]="Sensor Not";
- uchar code table3[]="Connected";
- uchar code table4[]="Check wrong";
- sbit Sensor_SDA = P3^4;
- sbit lcdrs=P1^3;
- sbit lcdwr=P1^4;
- sbit lcden=P1^5;
- /*
- sbit lcdrs=P2^6;
- sbit lcdwr=P2^5;
- sbit lcden=P2^7;
- */
- uchar Sensor_Data[5]={0x00,0x00,0x00,0x00,0x00};
- uchar Sensor_AnswerFlag; //收到起始标志位
- uchar Sensor_ErrorFlag; //读取传感器错误标志
- uchar Sensor_Check; //校验和
- uint Sys_CNT;
- uint Tmp;
- uint T;
- uint Rh;
- uint t0;
- uchar num;
- uchar flag;
- void sendDataToProcessing(char symbol, int dat); //串发送数据
- void Init_Timer0(void);//定时器初始化
- //串口发送函数
- void sendDataToProcessing(char symbol, int dat )
- {
- putchar(symbol);
- printf("%d\r\n",dat);
- }
- void UART_Init(void)
- {
- SCON=0X50; //设置为工作方式1
- TMOD=0X20; //设置计数器工作方式2
- PCON=0X80; //波特率加倍
- TH1=0XF3; //计数器初始值设置,注意波特率是4800的
- TL1=0XF3;
- // ES=1; //打开接收中断
- // EA=1; //打开总中断
- TR1=1; //打开计数器
- }
- char putchar(unsigned char dat)
- {
- TI=0;
- SBUF=dat;
- while(!TI);
- TI=0;
- return SBUF;
- }
- //延时函数
- void delay(uint z)
- {
- uint x,y;
- for(x=z;x>0;x--)
- for(y=123;y>0;y--);
- }
- /********************************************\
- |* 功能: 延时 晶振为12M时 *|
- |* t = 1 为 20us 然后成倍增加10us左右 *|
- \********************************************/
- void Delay_N10us(unsigned char t)
- {
- while(t--)
- {
- _nop_();
- }
- }
- /********************************************\
- |* 功能: 延时 晶振为12M时 *|
- |* 延时大约 1ms *|
- \********************************************/
- void Delay_N1ms(unsigned int t)
- {
- unsigned int i;
- unsigned int j;
- for(j=t;j>0;j--)
- for(i=124;i>0;i--); //延时大约 1ms
- }
- void write_com(uchar com) //写入命令
- {
- lcdrs=0;
- P0=com;
- lcden=1;
- delay(5);
- lcden=0;
- }
- void write_date(uchar date) //写入数据
- {
- lcdrs=1;
- P0=date;
- lcden=1;
- delay(5);
- lcden=0;
- }
- void diyihang(uint z) //第一行
- {
- z--;
- write_com(0x80+z);
- }
- void dierhang(uint z) //第二行
- {
- z--;
- write_com(0x80+0x40+z);
- }
- void init_1602() //1602初始化
- {
- lcdwr=0;
- lcden=0;
- write_com(0x38);//模式
- write_com(0x0c);//无光标不闪
- write_com(0x01);//清屏
- diyihang(1); //显示位置 第一行
- for(num=0;num<11;num++)
- {
- write_date(table0[num]); //显示" 温度 ";
- //delay(10);
- }
-
- dierhang(1); //换行显示 第二行
- for(num=0;num<10;num++)
- {
- write_date(table1[num]); //显示"RH: %";
- //delay(10);
- }
- }
- void Clear_Data (void)
- {
- int i;
- for(i=0;i<5;i++)
- {
- Sensor_Data[i] = 0x00;
- } //接收数据清零
- }
- /********************************************\
- |* 功能: 读传感器发送的单个字节 *|
- \********************************************/
- 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" 的高电平
- Delay_N10us(2); //延时30us
-
- //判断传感器发送数据位
- 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;
- Delay_N1ms(2); //延时2Ms
-
- //释放总线 延时(Min=30us Max=50us)
- Sensor_SDA = 1;
- Delay_N10us(2);//延时30us
- //主机设为输入 判断传感器响应信号
- 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 display() //显示
- {
- Tmp = Sensor_Data[2]*256+Sensor_Data[3]; // 温度高位 温度低位
- T=Tmp/10;
- diyihang(5); //第一行第5个位置开始显示
- write_date(Tmp/100%10 + '0'); //十位
- write_date(Tmp/10%10 + '0'); //个位
- write_date('.'); //小数点
- write_date(Tmp%10 + '0'); //小数位
- Tmp = Sensor_Data[0]*256+Sensor_Data[1]; //湿度高位 湿度低位
- Rh=Tmp/10;
- dierhang(5); //第二行第5个位置开始显示
- write_date(Tmp/100%10 + '0'); //十位
- write_date(Tmp/10%10 + '0'); //个位
- write_date('.'); //小数点
- write_date(Tmp%10 + '0'); //小数位
- }
- void check_and_display()
- {
- if(Sensor_AnswerFlag == 1)
- {
- Sensor_Check = Sensor_Data[0]+Sensor_Data[1]+Sensor_Data[2]+Sensor_Data[3];
-
- if(Sensor_Check ==Sensor_Data[4]) /*校验成功 */
- {
- if(flag == 1)
- {
- flag = 0;
- write_com(0x01);//清屏
- diyihang(1);//显示位置
- for(num=0;num<11;num++)
- {
- write_date(table0[num]); //显示温度
- //delay(10);
- }
- dierhang(1);//换行显示
- for(num=0;num<10;num++)
- {
- write_date(table1[num]); //显示RH:....%
- //delay(10);
- }
- }
- display(); //显示温度 湿度
- }
- else /*校验失败*/
- {
- write_com(0x01);//清屏
- diyihang(1);//显示位置
- for(num=0;num<10;num++)
- {
- write_date(table4[num]); //显示 Check wrong
- //delay(10);
- }
- flag=1;
- }
- }
- else /*没有连接上 */
- {
- write_com(0x01);//清屏
- diyihang(1);//显示位置
- for(num=0;num<10;num++)
- {
- write_date(table2[num]); //显示 Sensor Not
- //delay(10);
- }
- dierhang(1);//换行显示
- for(num=0;num<8;num++)
- {
- write_date(table3[num]); //显示 Connected
- //delay(10);
- }
- flag=1;
- }
- }
- /*void init_t0()
- {
- TMOD=0x01;
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- EA=1;
- ET0=1;
- TR0=1;
- }*/
- void main()
- { Init_Timer0();
- UART_Init(); //串口初始化
- init_1602();
- while(1)
- {
-
- Delay_N1ms(2000); // 延时 2S(两次读取间隔至少2S)
- Clear_Data(); // 清除收到数据
- Read_Sensor(); // 读取传感器数据
- check_and_display(); // 检测并显示数据
- sendDataToProcessing('T',T); //发送脉率值
- sendDataToProcessing('H',Rh); //发送脉率值
- }
- }
- /*------------------------------------------------
- 定时器初始化子程序
- ------------------------------------------------*/
- void Init_Timer0(void)
- {
- TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
- //TH0=0x00; //给定初值
- //TL0=0x00;
- EA=1; //总中断打开
- ET0=1; //定时器中断打开
- TR0=1; //定时器开关打开
- }
- /*------------------------------------------------
- 定时器中断子程序
- ------------------------------------------------*/
- void Timer0_isr(void) interrupt 1
- {
- static unsigned int num;
- TH0=(65536-2000)/256; //重新赋值 2ms
- TL0=(65536-2000)%256;
- num++;
- if(num==300)
- {
- num=0;
- }
- }
复制代码
全部资料51hei下载地址:
|
评分
-
查看全部评分
|