找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 7349|回复: 7
打印 上一主题 下一主题
收起左侧

多路无线分布式温度检测报警系统 单片机程序 论文 原理图 PCB资料下载

  [复制链接]
跳转到指定楼层
楼主
基于51单片机设计的多路无线温度检测报警系统.



Altium Designer画的原理图和PCB图如下:(51hei附件中可下载工程文件)


论文内容预览:


单片机源程序如下:
  1. #include <reg52.h>
  2. #include <nrf24l01.h>
  3. #include "intrins.h"
  4. #define  uchar unsigned char
  5. #define  uint          unsigned int

  6. unsigned pcb_id=0;
  7. unsigned char flag=0;
  8. int set_value,state;

  9.          
  10. sbit data_temp1 = P2^4;                                 //数据线
  11. sbit data_temp2 = P2^2;                                 //数据线
  12. sbit cs = P2^3;                                          //片选
  13. sbit sclk = P2^1;                                          //io口时钟

  14. sbit S1 = P1^0;                                 //
  15. sbit S2 = P1^1;                                 //
  16. sbit S3 = P1^2;                                 //
  17. //sbit LED1 = P1^3;                                 //
  18. sbit LED2 = P1^4;                                 //
  19. sbit LED3 = P1^5;                                 //

  20. sbit Relay1 = P1^7;                                 //
  21. sbit Relay2 = P2^0;                                 //  
  22. sbit Ring = P1^6;                                 //                     

  23. sbit LCD_RS = P2^5;           //数据命令选择端            
  24. sbit LCD_RW = P2^6;          //读写选择端
  25. sbit LCD_EP = P2^7;           //使能信号


  26. unsigned char code wendu1[] = "T1:";    //待显示的字符
  27. unsigned char code wendu2[] = "T2:";    //待显示的字符
  28. unsigned char code wendu3[] = "T3:";    //待显示的字符
  29. unsigned char code danger[] = "UNSF";         //待显示的字符
  30. unsigned char code anquan[] = "Safe";    //待显示的字符
  31. unsigned char anjian_flag1,anjian_flag2,anjian_flag3,anjian_flag4;
  32. unsigned char ad_temp1,        ad_temp2,ad_temp3,ad_temp4;
  33. unsigned char ring1_flag,ring2_flag,ring3_flag;
  34. unsigned char add_num;
  35. int aa;
  36. float wenduzhi;

  37. unsigned char nrf_tx_buff[4];          // 数据送到缓存
  38. unsigned char nrf_rx_buff[4];          // 数据送到缓存
  39. uchar bdata nrf_state;

  40. sbit  RX_DR_flag         = nrf_state^6;
  41. sbit  TX_DS_flag         = nrf_state^5;
  42. sbit  MAX_RT_flag = nrf_state^4;

  43. void delay(int ms)
  44. {                           // 延时子程序
  45.         int i;
  46.         while(ms--)
  47.         {
  48.           for(i = 0; i< 250; i++)
  49.           {
  50.            _nop_();
  51.            _nop_();
  52.            _nop_();
  53.            _nop_();
  54.           }
  55.     }
  56. }

  57. bit lcd_bz()           // 测试LCD忙碌状态
  58. {                          
  59.         bit result;
  60.         LCD_RS = 0;            //写指令
  61.         LCD_RW = 1;
  62.         LCD_EP = 1;            //为产生下降沿做好准备
  63.         _nop_();                //延时5ms
  64.         _nop_();
  65.         _nop_();
  66.         _nop_();
  67.         result = (bit)(P0 & 0x80);//判断状态字最高位STA7,确保STA7为0
  68.         LCD_EP = 0;            //将LED_EP拉低,产生下降沿,写入指令
  69.         return result;         //返回结果,为1禁止读写,为0可以读写
  70. }

  71. void lcd_wcmd(unsigned char cmd)                // 写入指令数据到LCD
  72. {                          
  73.         while(lcd_bz());                 //为1不能进行读写操作
  74.         LCD_RS = 0;                   //写指令
  75.         LCD_RW = 0;
  76.         LCD_EP = 0;
  77.         _nop_();
  78.         _nop_();
  79.         P0 = cmd;                      //将指令写到P0口
  80.         _nop_();
  81.         _nop_();
  82.         _nop_();
  83.         _nop_();
  84.         LCD_EP = 1;                  //使能端高电平,为产生下降沿准备
  85.         _nop_();
  86.         _nop_();
  87.         _nop_();
  88.         _nop_();
  89.         LCD_EP = 0;                  //产生下降沿,将指令写入LCD  
  90. }

  91. void lcd_pos(unsigned char pos)          //设定显示位置
  92. {                          
  93.         lcd_wcmd(pos | 0x80);             //LCD数据指针格式80H+地址
  94. }

  95. void lcd_wdat(unsigned char dat)          //写入字符显示数据到LCD
  96. {                          
  97.         while(lcd_bz());                 //LCD忙检测,为1不能进行读写,为0可以读写
  98.         LCD_RS = 1;                   //写数据
  99.         LCD_RW = 0;
  100.         LCD_EP = 0;
  101.         P0 = dat;                       //数据送入P0口
  102.         _nop_();
  103.         _nop_();
  104.         _nop_();
  105.         _nop_();
  106.         LCD_EP = 1;                   //使能端拉高。为产生下降沿做准备
  107.         _nop_();
  108.         _nop_();
  109.         _nop_();
  110.         _nop_();
  111.         LCD_EP = 0;                      //使能端拉低,将数据写入LCD
  112. }

  113. void lcd_init()          //LCD初始化设定
  114. {                        
  115.         lcd_wcmd(0x38);   //16*2显示,5*7点阵,8位数据
  116.         delay(1);          //延时1ms
  117.         lcd_wcmd(0x0c);   //显示开,关光标
  118.         delay(1);
  119.         lcd_wcmd(0x06);   //移动光标,当读或写一个字符后地址指针加1且光标加1
  120.         delay(1);
  121.         lcd_wcmd(0x01);   //清除LCD的显示内容,地址指针数据指针清零
  122.         delay(1);
  123. }


  124. uint ad_549()                           //TLC549处理
  125. {
  126.                   uchar i;
  127.                   ad_temp1=0;
  128.                   ad_temp2=0;
  129.                   ad_temp3=0;
  130.                   ad_temp4=0;
  131.                   cs = 1;                        //初始化,启动
  132.                   sclk = 0;
  133.                   cs = 0;

  134.                   _nop_();       
  135.                   _nop_();            
  136.                   for(i = 0;i < 8;i++)                //读取采集数据,读取的是上一次采集数据
  137.                     {

  138.                           sclk = 1;
  139.                           ad_temp1 = ad_temp1 << 1;  
  140.                           if(data_temp1)ad_temp1 |= 0x01;

  141.                           ad_temp2 = ad_temp2 << 1;  
  142.                           if(data_temp2)ad_temp2 |= 0x01;
  143.                           _nop_();
  144.                           _nop_();
  145.                           sclk = 0;
  146.                           _nop_();
  147.                         }        
  148.                   cs = 1;  
  149.                   for(i = 0;i < 14;i++)
  150.                   {
  151.                                     _nop_();
  152.                   }

  153. }

  154. void timer0_init (void)                            // timer0中断初始化函数
  155. {
  156.         EA = 0;                     
  157.         TMOD |= 0x01;            
  158.         TR0 = 0;                     
  159.         TL0 = (65536-50000)%256;
  160.         TH0 = (65536-50000)/256;                  
  161.         PT0 = 1;                     
  162.         ET0 = 1;                     
  163.         EA = 1;                     
  164.         TR0 = 1;                     
  165. }

  166. void anjian(void)
  167. {       
  168.         if(S1==0)
  169.         {
  170.                 if(anjian_flag1==0)
  171.                 {
  172.                         anjian_flag1=1;
  173.                         add_num=1;
  174.                 }
  175.         }
  176.         else
  177.         {
  178.                 anjian_flag1=0;
  179.         }

  180.         if(S2==0)
  181.         {
  182.                 if(anjian_flag2==0)
  183.                 {
  184.                         anjian_flag2=1;       
  185.                         add_num=2;       

  186.                 }
  187.         }
  188.         else
  189.         {
  190.                 anjian_flag2=0;
  191.         }

  192.         if(S3==0)
  193.         {
  194.                 if(anjian_flag3==0)
  195.                 {

  196.                         anjian_flag3=1;       
  197.                         add_num=3;               
  198.                 }
  199.         }
  200.         else
  201.         {
  202.                 anjian_flag3=0;
  203.         }
  204.                          
  205. }
  206. void uart_init()  
  207. {
  208.         TMOD |= 0x20;
  209.         TH1 = 0xf3;  
  210.         TL1 = 0xf3;
  211.         TR1 = 1; //启动定时器1,从而设定了串口通信的波特率
  212.         PCON=0X80;
  213.         SM0 = 0;  
  214.         SM1 = 1; //设定串口通信方式为十位异步收发器  
  215.         REN = 1; //打开串口通信  
  216.         EA = 1;  
  217.         ES = 1;
  218. }
  219. void uart_send(databuff)
  220. {
  221.         SBUF=(databuff/100)+0x30;//将接收到的数据放入到发送寄存器
  222.         while(!TI);                         //等待发送数据完成
  223.         TI=0;
  224.         SBUF=((databuff%100)/10)+0x30;//将接收到的数据放入到发送寄存器
  225.         while(!TI);                         //等待发送数据完成
  226.         TI=0;
  227.         SBUF=(databuff%10)+0x30;//将接收到的数据放入到发送寄存器
  228.         while(!TI);                         //等待发送数据完成
  229.         TI=0;

  230. }
  231.        
  232. void uart_sendone(onedata)
  233. {
  234.         SBUF=onedata;//将接收到的数据放入到发送寄存器
  235.         while(!TI);                         //等待发送数据完成
  236.         TI=0;
  237. }
  238. void main(void)                        //主程序
  239. {  
  240.         unsigned char zf;
  241.         int temp;
  242.         set_value=100;
  243. //        uart_init();  
  244.         timer0_init ();
  245.         init_io();                              // 初始化IO
  246.         RX_Mode();                              // 设置为接收模式
  247.         LED2=1;
  248.         LED3=1;
  249.         anjian_flag1=0;
  250.         anjian_flag2=0;
  251.         anjian_flag3=0;
  252.         Relay1=0;
  253.         Relay2=0;
  254.         Ring=0;
  255.         add_num=1;
  256.         if(pcb_id==1)                        //主机为1、从机为0初始化
  257.         {
  258.             lcd_init();     // 初始化LCD
  259.             delay(10);     //延时10ms
  260.             lcd_wcmd(0x06);              //向右移动光标
  261.             lcd_pos(0x00+0);                //设置显示位置为第一行的第17个字符
  262.             zf = 0;
  263.             while(wendu1[ zf ] != '\0')
  264.             {                           
  265.                lcd_wdat(wendu1[ zf ]);                   //显示字符"WLCOME  TO"
  266.                zf ++;
  267.             }

  268.             lcd_wcmd(0x06);              //向右移动光标
  269.             lcd_pos(0x00+9);                //设置显示位置为第一行的第17个字符
  270.             zf = 0;
  271.             while(wendu2[ zf ] != '\0')
  272.             {                           
  273.                lcd_wdat(wendu2[ zf ]);                   //显示字符"WLCOME  TO"
  274.                zf ++;
  275.             }


  276.             lcd_wcmd(0x06);              //向右移动光标
  277.             lcd_pos(0x40+0);                //设置显示位置为第一行的第17个字符
  278.             zf = 0;
  279.             while(wendu3[ zf ] != '\0')
  280.             {                           
  281.                lcd_wdat(wendu3[ zf ]);                   //显示字符"WLCOME  TO"
  282.                zf ++;
  283.             }       

  284.                 lcd_wcmd(0x06);              //向右移动光标
  285.             lcd_pos(0x40+9);                //设置显示位置为第一行的第17个字符
  286.             zf = 0;
  287.             while(anquan[ zf ] != '\0')
  288.             {                           
  289.                lcd_wdat(anquan[ zf ]);                   //显示字符"WLCOME  TO"
  290.                zf ++;
  291.             }
  292.         }

  293.         while(1)
  294.         {  
  295.                      if(pcb_id==1)
  296.                 {
  297.                           nrf_state = SPI_Read(STATUS);          // 读状态寄存器
  298.                     if(RX_DR_flag)                                  // 判断是否接受到数据
  299.                         {
  300.                                 SPI_Read_Buf(RD_RX_PLOAD, nrf_rx_buff, TX_PLOAD_WIDTH);  // 从RX FIFO读出数据
  301.                                 if(nrf_rx_buff[0]==0x01)
  302.                                 {
  303.                                         LED2=~LED2;               
  304.                                         aa=        (nrf_rx_buff[1]<<8)+ nrf_rx_buff[2];
  305.                                         lcd_wcmd(0x06);              //向右移动光标
  306.                                         lcd_pos(0x00+3);                //设置显示位置为第一行的第17个字符                 
  307.                                          lcd_wdat((aa/100)+0x30);
  308.                                         lcd_wdat((aa%100)/10+0x30);
  309.                                         lcd_wdat('.');
  310.                                         lcd_wdat((aa%10)+0x30);       
  311.                                         if(aa>500)
  312.                                         {
  313.                                                  ring1_flag=1;
  314.                                         }
  315.                                         else
  316.                                         {
  317.                                                   ring1_flag=0;
  318.                                         }

  319.                                  }
  320.                                  else if(nrf_rx_buff[0]==0x02)
  321.                                  {
  322.                                            LED2=~LED2;               
  323.                                         aa=        (nrf_rx_buff[1]<<8)+ nrf_rx_buff[2];
  324.                                         lcd_wcmd(0x06);              //向右移动光标
  325.                                         lcd_pos(0x00+12);                //设置显示位置为第一行的第17个字符                 
  326.                                          lcd_wdat((aa/100)+0x30);
  327.                                         lcd_wdat((aa%100)/10+0x30);
  328.                                         lcd_wdat('.');
  329.                                         lcd_wdat((aa%10)+0x30);       
  330.                                         if(aa>500)
  331.                                         {
  332.                                                  ring2_flag=1;
  333.                                         }
  334.                                         else
  335.                                         {
  336.                                                   ring2_flag=0;
  337.                                         }

  338.                                   }
  339.                                   else if(nrf_rx_buff[0]==0x03)
  340.                                   {
  341.                                                    LED2=~LED2;               
  342.                                                 aa=        (nrf_rx_buff[1]<<8)+ nrf_rx_buff[2];
  343.                                                 lcd_wcmd(0x06);              //向右移动光标
  344.                                                 lcd_pos(0x40+3);                //设置显示位置为第一行的第17个字符                 
  345.                                                  lcd_wdat((aa/100)+0x30);
  346.                                                 lcd_wdat((aa%100)/10+0x30);
  347.                                                 lcd_wdat('.');
  348.                                                 lcd_wdat((aa%10)+0x30);       
  349.                                                 if(aa>500)
  350.                                                 {
  351.                                                          ring3_flag=1;
  352.                                                 }
  353.                                                 else
  354.                                                 {
  355.                                                           ring3_flag=0;
  356.                                                 }                                  
  357.                                   }
  358.                                   else
  359.                                   {
  360.                                   
  361.                                   }
  362.                                 }

  363.                                 SPI_RW_Reg(WRITE_REG + STATUS, nrf_state);  // 清除RX_DS中断标志

  364.                                 if((ring1_flag==1)||(ring2_flag==1)||(ring3_flag==1))
  365.                                 {
  366.                                           lcd_wcmd(0x06);              //向右移动光标
  367.                                     lcd_pos(0x40+9);                //设置显示位置为第一行的第17个字符
  368.                                     zf = 0;
  369.                                     while(danger[ zf ] != '\0')
  370.                                     {                           
  371.                                        lcd_wdat(danger[ zf ]);                   //显示字符"WLCOME  TO"
  372.                                        zf ++;
  373.                                     }
  374.                                         Ring=1;
  375.                                         LED3=0;
  376.                                 }               
  377.                                 else
  378. ……………………

  379. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码


所有资料51hei提供下载(含完整论文,pcb 原理图工程和源码):
30022发送.rar (10.89 MB, 下载次数: 233)



评分

参与人数 1黑币 +5 收起 理由
LQL-LQL + 5 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏6 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:1 发表于 2017-5-19 04:03 | 只看该作者
好资料,51黑有你更精彩!!!
回复

使用道具 举报

板凳
ID:94068 发表于 2017-5-19 15:13 | 只看该作者
不知道做出来的效果是什么样子的,我看液晶屏也没给个显示结果
回复

使用道具 举报

地板
ID:203047 发表于 2017-5-21 10:35 | 只看该作者

 好资料
回复

使用道具 举报

5#
ID:271718 发表于 2018-1-4 23:30 | 只看该作者
很好!谢谢你的方案!!!
回复

使用道具 举报

6#
ID:609834 发表于 2019-9-17 08:47 | 只看该作者
很好!谢谢你的方案!!!
回复

使用道具 举报

7#
ID:400250 发表于 2020-2-29 17:47 | 只看该作者
附件已下载,资料很全,很有借鉴参考价值,非常不错,值得学习,赞!
回复

使用道具 举报

8#
ID:491577 发表于 2020-3-1 01:15 | 只看该作者
这个实用性不强,成本高,安装麻烦,装了一个无线模块好像就不用拉线了吗?电源呢?每个模块都要安装两条电源线吧,还不如直接安装温度探头,只要3条线而已。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表