|
基于51單片機設計的多路無線溫度檢測報警系統.
Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)
論文內容預覽:
單片機源程序如下:
- #include <reg52.h>
- #include <nrf24l01.h>
- #include "intrins.h"
- #define uchar unsigned char
- #define uint unsigned int
- unsigned pcb_id=0;
- unsigned char flag=0;
- int set_value,state;
-
-
- sbit data_temp1 = P2^4; //數據線
- sbit data_temp2 = P2^2; //數據線
- sbit cs = P2^3; //片選
- sbit sclk = P2^1; //io口時鐘
- sbit S1 = P1^0; //
- sbit S2 = P1^1; //
- sbit S3 = P1^2; //
- //sbit LED1 = P1^3; //
- sbit LED2 = P1^4; //
- sbit LED3 = P1^5; //
-
- sbit Relay1 = P1^7; //
- sbit Relay2 = P2^0; //
- sbit Ring = P1^6; //
- sbit LCD_RS = P2^5; //數據命令選擇端
- sbit LCD_RW = P2^6; //讀寫選擇端
- sbit LCD_EP = P2^7; //使能信號
- unsigned char code wendu1[] = "T1:"; //待顯示的字符
- unsigned char code wendu2[] = "T2:"; //待顯示的字符
- unsigned char code wendu3[] = "T3:"; //待顯示的字符
- unsigned char code danger[] = "UNSF"; //待顯示的字符
- unsigned char code anquan[] = "Safe"; //待顯示的字符
- unsigned char anjian_flag1,anjian_flag2,anjian_flag3,anjian_flag4;
- unsigned char ad_temp1, ad_temp2,ad_temp3,ad_temp4;
- unsigned char ring1_flag,ring2_flag,ring3_flag;
- unsigned char add_num;
- int aa;
- float wenduzhi;
- unsigned char nrf_tx_buff[4]; // 數據送到緩存
- unsigned char nrf_rx_buff[4]; // 數據送到緩存
- uchar bdata nrf_state;
- sbit RX_DR_flag = nrf_state^6;
- sbit TX_DS_flag = nrf_state^5;
- sbit MAX_RT_flag = nrf_state^4;
- void delay(int ms)
- { // 延時子程序
- int i;
- while(ms--)
- {
- for(i = 0; i< 250; i++)
- {
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- }
- }
- }
- bit lcd_bz() // 測試LCD忙碌狀態
- {
- bit result;
- LCD_RS = 0; //寫指令
- LCD_RW = 1;
- LCD_EP = 1; //為產生下降沿做好準備
- _nop_(); //延時5ms
- _nop_();
- _nop_();
- _nop_();
- result = (bit)(P0 & 0x80);//判斷狀態字最高位STA7,確保STA7為0
- LCD_EP = 0; //將LED_EP拉低,產生下降沿,寫入指令
- return result; //返回結果,為1禁止讀寫,為0可以讀寫
- }
- void lcd_wcmd(unsigned char cmd) // 寫入指令數據到LCD
- {
- while(lcd_bz()); //為1不能進行讀寫操作
- LCD_RS = 0; //寫指令
- LCD_RW = 0;
- LCD_EP = 0;
- _nop_();
- _nop_();
- P0 = cmd; //將指令寫到P0口
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- LCD_EP = 1; //使能端高電平,為產生下降沿準備
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- LCD_EP = 0; //產生下降沿,將指令寫入LCD
- }
- void lcd_pos(unsigned char pos) //設定顯示位置
- {
- lcd_wcmd(pos | 0x80); //LCD數據指針格式80H+地址
- }
- void lcd_wdat(unsigned char dat) //寫入字符顯示數據到LCD
- {
- while(lcd_bz()); //LCD忙檢測,為1不能進行讀寫,為0可以讀寫
- LCD_RS = 1; //寫數據
- LCD_RW = 0;
- LCD_EP = 0;
- P0 = dat; //數據送入P0口
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- LCD_EP = 1; //使能端拉高。為產生下降沿做準備
- _nop_();
- _nop_();
- _nop_();
- _nop_();
- LCD_EP = 0; //使能端拉低,將數據寫入LCD
- }
- void lcd_init() //LCD初始化設定
- {
- lcd_wcmd(0x38); //16*2顯示,5*7點陣,8位數據
- delay(1); //延時1ms
- lcd_wcmd(0x0c); //顯示開,關光標
- delay(1);
- lcd_wcmd(0x06); //移動光標,當讀或寫一個字符后地址指針加1且光標加1
- delay(1);
- lcd_wcmd(0x01); //清除LCD的顯示內容,地址指針數據指針清零
- delay(1);
- }
- uint ad_549() //TLC549處理
- {
- uchar i;
- ad_temp1=0;
- ad_temp2=0;
- ad_temp3=0;
- ad_temp4=0;
- cs = 1; //初始化,啟動
- sclk = 0;
- cs = 0;
- _nop_();
- _nop_();
- for(i = 0;i < 8;i++) //讀取采集數據,讀取的是上一次采集數據
- {
- sclk = 1;
- ad_temp1 = ad_temp1 << 1;
- if(data_temp1)ad_temp1 |= 0x01;
- ad_temp2 = ad_temp2 << 1;
- if(data_temp2)ad_temp2 |= 0x01;
- _nop_();
- _nop_();
- sclk = 0;
- _nop_();
- }
- cs = 1;
- for(i = 0;i < 14;i++)
- {
- _nop_();
- }
- }
- void timer0_init (void) // timer0中斷初始化函數
- {
- EA = 0;
- TMOD |= 0x01;
- TR0 = 0;
- TL0 = (65536-50000)%256;
- TH0 = (65536-50000)/256;
- PT0 = 1;
- ET0 = 1;
- EA = 1;
- TR0 = 1;
- }
- void anjian(void)
- {
- if(S1==0)
- {
- if(anjian_flag1==0)
- {
- anjian_flag1=1;
- add_num=1;
- }
- }
- else
- {
- anjian_flag1=0;
- }
- if(S2==0)
- {
- if(anjian_flag2==0)
- {
- anjian_flag2=1;
- add_num=2;
- }
- }
- else
- {
- anjian_flag2=0;
- }
- if(S3==0)
- {
- if(anjian_flag3==0)
- {
- anjian_flag3=1;
- add_num=3;
- }
- }
- else
- {
- anjian_flag3=0;
- }
-
- }
- void uart_init()
- {
- TMOD |= 0x20;
- TH1 = 0xf3;
- TL1 = 0xf3;
- TR1 = 1; //啟動定時器1,從而設定了串口通信的波特率
- PCON=0X80;
- SM0 = 0;
- SM1 = 1; //設定串口通信方式為十位異步收發器
- REN = 1; //打開串口通信
- EA = 1;
- ES = 1;
- }
- void uart_send(databuff)
- {
- SBUF=(databuff/100)+0x30;//將接收到的數據放入到發送寄存器
- while(!TI); //等待發送數據完成
- TI=0;
- SBUF=((databuff%100)/10)+0x30;//將接收到的數據放入到發送寄存器
- while(!TI); //等待發送數據完成
- TI=0;
- SBUF=(databuff%10)+0x30;//將接收到的數據放入到發送寄存器
- while(!TI); //等待發送數據完成
- TI=0;
- }
-
- void uart_sendone(onedata)
- {
- SBUF=onedata;//將接收到的數據放入到發送寄存器
- while(!TI); //等待發送數據完成
- TI=0;
- }
- void main(void) //主程序
- {
- unsigned char zf;
- int temp;
- set_value=100;
- // uart_init();
- timer0_init ();
- init_io(); // 初始化IO
- RX_Mode(); // 設置為接收模式
- LED2=1;
- LED3=1;
- anjian_flag1=0;
- anjian_flag2=0;
- anjian_flag3=0;
- Relay1=0;
- Relay2=0;
- Ring=0;
- add_num=1;
- if(pcb_id==1) //主機為1、從機為0初始化
- {
- lcd_init(); // 初始化LCD
- delay(10); //延時10ms
- lcd_wcmd(0x06); //向右移動光標
- lcd_pos(0x00+0); //設置顯示位置為第一行的第17個字符
- zf = 0;
- while(wendu1[ zf ] != '\0')
- {
- lcd_wdat(wendu1[ zf ]); //顯示字符"WLCOME TO"
- zf ++;
- }
- lcd_wcmd(0x06); //向右移動光標
- lcd_pos(0x00+9); //設置顯示位置為第一行的第17個字符
- zf = 0;
- while(wendu2[ zf ] != '\0')
- {
- lcd_wdat(wendu2[ zf ]); //顯示字符"WLCOME TO"
- zf ++;
- }
- lcd_wcmd(0x06); //向右移動光標
- lcd_pos(0x40+0); //設置顯示位置為第一行的第17個字符
- zf = 0;
- while(wendu3[ zf ] != '\0')
- {
- lcd_wdat(wendu3[ zf ]); //顯示字符"WLCOME TO"
- zf ++;
- }
- lcd_wcmd(0x06); //向右移動光標
- lcd_pos(0x40+9); //設置顯示位置為第一行的第17個字符
- zf = 0;
- while(anquan[ zf ] != '\0')
- {
- lcd_wdat(anquan[ zf ]); //顯示字符"WLCOME TO"
- zf ++;
- }
- }
- while(1)
- {
- if(pcb_id==1)
- {
- nrf_state = SPI_Read(STATUS); // 讀狀態寄存器
- if(RX_DR_flag) // 判斷是否接受到數據
- {
- SPI_Read_Buf(RD_RX_PLOAD, nrf_rx_buff, TX_PLOAD_WIDTH); // 從RX FIFO讀出數據
- if(nrf_rx_buff[0]==0x01)
- {
- LED2=~LED2;
- aa= (nrf_rx_buff[1]<<8)+ nrf_rx_buff[2];
- lcd_wcmd(0x06); //向右移動光標
- lcd_pos(0x00+3); //設置顯示位置為第一行的第17個字符
- lcd_wdat((aa/100)+0x30);
- lcd_wdat((aa%100)/10+0x30);
- lcd_wdat('.');
- lcd_wdat((aa%10)+0x30);
- if(aa>500)
- {
- ring1_flag=1;
- }
- else
- {
- ring1_flag=0;
- }
- }
- else if(nrf_rx_buff[0]==0x02)
- {
- LED2=~LED2;
- aa= (nrf_rx_buff[1]<<8)+ nrf_rx_buff[2];
- lcd_wcmd(0x06); //向右移動光標
- lcd_pos(0x00+12); //設置顯示位置為第一行的第17個字符
- lcd_wdat((aa/100)+0x30);
- lcd_wdat((aa%100)/10+0x30);
- lcd_wdat('.');
- lcd_wdat((aa%10)+0x30);
- if(aa>500)
- {
- ring2_flag=1;
- }
- else
- {
- ring2_flag=0;
- }
- }
- else if(nrf_rx_buff[0]==0x03)
- {
- LED2=~LED2;
- aa= (nrf_rx_buff[1]<<8)+ nrf_rx_buff[2];
- lcd_wcmd(0x06); //向右移動光標
- lcd_pos(0x40+3); //設置顯示位置為第一行的第17個字符
- lcd_wdat((aa/100)+0x30);
- lcd_wdat((aa%100)/10+0x30);
- lcd_wdat('.');
- lcd_wdat((aa%10)+0x30);
- if(aa>500)
- {
- ring3_flag=1;
- }
- else
- {
- ring3_flag=0;
- }
- }
- else
- {
-
- }
- }
- SPI_RW_Reg(WRITE_REG + STATUS, nrf_state); // 清除RX_DS中斷標志
- if((ring1_flag==1)||(ring2_flag==1)||(ring3_flag==1))
- {
- lcd_wcmd(0x06); //向右移動光標
- lcd_pos(0x40+9); //設置顯示位置為第一行的第17個字符
- zf = 0;
- while(danger[ zf ] != '\0')
- {
- lcd_wdat(danger[ zf ]); //顯示字符"WLCOME TO"
- zf ++;
- }
- Ring=1;
- LED3=0;
- }
- else
- ……………………
- …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼
所有資料51hei提供下載(含完整論文,pcb 原理圖工程和源碼):
30022發送.rar
(10.89 MB, 下載次數: 233)
2017-5-15 19:31 上傳
點擊文件名下載附件
多路無線溫度檢測報警系統
|
評分
-
查看全部評分
|