|
經過幾天的努力,終于搞出了89C51單片機控制AM2302濕度溫度傳感器+lcd1602+藍牙上顯示!
被店家坑死嘍,還好我會改電路,把傳感器模塊的電路改為單總線模式,接法如圖:(一定記得接地哦)
實物圖:
6C98A623ADF47A4C30D244A9C18164C8.jpg (1.67 MB, 下載次數: 56)
下載附件
實物圖
2018-1-1 19:34 上傳
手繪電路原理圖:
C46EC89A98249AB9A36FF28E0058F59A.jpg (43.36 KB, 下載次數: 58)
下載附件
接線方法
2018-1-1 19:34 上傳
3A2F6BC6D65B5126214F3C6582857197.jpg (1.73 MB, 下載次數: 52)
下載附件
電路板封裝圖
2018-1-1 19:33 上傳
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
X91H{XX}0QGI6YBP{NB5@PQ.png (19.92 KB, 下載次數: 60)
下載附件
電路原理圖
2018-1-1 19:35 上傳
這是部分程序:
- /*
- 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下載地址:
|
-
-
濕度 溫度 藍牙 lcd1602.zip
2018-1-1 19:36 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
44.64 KB, 下載次數: 77, 下載積分: 黑幣 -5
程序
-
-
電路.zip
2018-1-1 19:43 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
160.99 KB, 下載次數: 40, 下載積分: 黑幣 -5
原理圖,封裝圖
-
-
AM2302模塊資料.zip
2018-1-1 19:43 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
2.77 MB, 下載次數: 35, 下載積分: 黑幣 -5
單總線方式
評分
-
查看全部評分
|