找回密码
 立即注册

QQ登录

只需一步,快速开始

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

遥控器接收温湿度的单片机源码

[复制链接]
跳转到指定楼层
楼主
ID:314426 发表于 2018-4-23 13:57 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
单片机源程序如下:
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #include "nrf24l01.h"
  4. #include "12864.h"
  5. /***************************************************
  6. *This file is distributed in the hope that it will be useful, but WITHOUT ANY WARRANT;
  7. *
  8. *UART:9600BPS
  9. /***************************************************/
  10. #define uchar unsigned char
  11. #define uint  unsigned int
  12. #define TX_ADR_WIDTH    5   // 5 bytes TX(RX) address width
  13. #define TX_PLOAD_WIDTH  20  // 20 bytes TX payload         发送的字节数

  14. uchar quanshu=0; //用来记录圈数
  15. uchar xian=0; //用来记录经过了几条线

  16. uchar const TX_ADDRESS[TX_ADR_WIDTH]  = {0x34,0x43,0x10,0x10,0x86}; // Define a static TX address 静态地址

  17. uchar code dis1[] = {0xc8,0xa6,0xca,0xfd};          //圈数

  18. uchar code dis2[] = {"湿度  初始化中"};

  19. //uchar code dis3[] = {"无障碍物"};

  20. uchar code dis4[10]={0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8,0xb9};
  21. uchar code dis5[] = {"黑线"};
  22. uchar code dis6[]={"温度  初始化中"};
  23. uchar code digit[10]={"0123456789"};
  24. uchar code dis7[]={"传感器异常"};

  25. uchar rx_buf[TX_PLOAD_WIDTH];
  26. uchar tx_buf[TX_PLOAD_WIDTH];
  27. uchar flag;
  28. /**************************************************/
  29. sbit CE =  P1^0;
  30. sbit CSN=  P1^4;
  31. sbit SCK=  P1^7;
  32. sbit MOSI= P1^5;
  33. sbit MISO= P1^6;
  34. sbit IRQ = P3^2;
  35. /**************************************************/
  36. uchar         bdata   sta;
  37. sbit        RX_DR        =sta^6;
  38. sbit        TX_DS        =sta^5;
  39. sbit        MAX_RT        =sta^4;
  40. /**************************************************/
  41. sbit LED1=P2^5;
  42. sbit LED2=P2^6;
  43. /**************************************************
  44. Function: Init_IO();

  45. Description:
  46.   flash led one time,chip enable(ready to TX or RX Mode),
  47.   Spi disable,Spi clock line init high
  48. 描述:
  49.   闪光灯一次,芯片使能(准备进入TX或RX模式)
  50.   Spi禁用,Spi时钟线初始化高
  51. /**************************************************/
  52. #define KEY 0x60  // 0x60 0110 0000
  53. void dislap(uchar q);
  54. void Init_IO(void)
  55. {
  56.         P0=KEY;                    // led light
  57.         CE=0;                        // chip enable
  58.         CSN=1;                        // Spi disable        
  59.         SCK=0;                        // Spi clock line init high
  60.         P0=0xff;                // led close
  61. }
  62. /**************************************************
  63. Function: Init_uart();

  64. Description:
  65.   set uart working mode
  66. 描述:
  67.   设置定时计数器工作模式
  68. /**************************************************/
  69. void Init_uart(void)
  70. {
  71.         TMOD = 0x20;                                //timer1 working mode 1
  72.         TL1 = 0xfd;                                        //f7=9600 for 16mhz Fosc,and ...
  73.         TH1 = 0xfd;                                        //...fd=19200 for 11.0592mhz Fosc
  74.         SCON = 0xd8;                                //uart mode 3,ren==1
  75.         PCON = 0x80;                                //smod=0
  76.         TR1 = 1;                                        //start timer1
  77. }
  78. /**************************************************
  79. Function: Init_int0();

  80. Description:
  81.   enable int0 interrupt;
  82.   中断0使能
  83. /**************************************************
  84. void Init_int0(void)
  85. {
  86.         EA=1;
  87.         EX0=1;                                                // Enable int0 interrupt.
  88. }
  89. /**************************************************/

  90. /**************************************************
  91. Function: delay100();

  92. Description:
  93.   delay 100ms
  94.   延时100毫秒
  95. /**************************************************
  96. void delay100(void)
  97. {
  98.         uchar  x;
  99.         uchar  y;
  100.         for(x=0;x<100;x++)
  101.         {
  102.                 for(y=0;y<100;y++)
  103.                 _nop_();
  104.         }
  105. }
  106. /**************************************************/

  107. /**************************************************
  108. Function: delay_ms();

  109. Description:
  110.   delay x ms
  111.   延时X毫秒
  112. /**************************************************/

  113. void delay_ms(unsigned int x)
  114. {
  115.     unsigned int i,j;
  116.     i=0;
  117.     for(i=0;i<x;i++)
  118.     {
  119.        j=108;
  120.            ;
  121.        while(j--);
  122.     }
  123. }

  124. /**************************************************
  125. Function: SPI_RW();

  126. Description:
  127.   Writes one byte to nRF24L01, and return the byte read
  128.   from nRF24L01 during write, according to SPI protocol
  129.   根据SPI协议写一个字节到nRF24L01,
  130.   并在写期间返回从nRF24L01读取的字节
  131. /**************************************************/
  132. uchar SPI_RW(uchar byte)
  133. {
  134.         uchar bit_ctr;
  135.            for(bit_ctr=0;bit_ctr<8;bit_ctr++)   // output 8-bit  输出8位
  136.            {
  137.                    MOSI = (byte & 0x80);            // output 'byte', MSB to MOSI  最高位写入主输出从输入
  138.                    byte = (byte << 1);              // shift next bit into MSB..        将下一位移到最高位
  139.                    SCK = 1;                         // Set SCK high..           同步时钟置高位
  140.                    byte |= MISO;                            // capture current MISO bit         捕获主输入从输出位
  141.                    SCK = 0;                                 // ..then set SCK low again         同步时钟置0
  142.            }
  143.     return(byte);                                // return read byte
  144. }
  145. /**************************************************
  146. Function: SPI_RW_Reg();

  147. Description:
  148.   Writes value 'value' to register 'reg'
  149. /**************************************************/
  150. uchar SPI_RW_Reg(uchar reg, uchar value)
  151. {
  152.         uchar status;

  153.           CSN = 0;                   // CSN low, init SPI transaction                   SPI片选
  154.           status = SPI_RW(reg);      // select register
  155.           SPI_RW(value);             // ..and write value to it..
  156.           CSN = 1;                   // CSN high again

  157.           return(status);            // return nRF24L01 status byte
  158. }
  159. /**************************************************
  160. Function: SPI_Read();

  161. Description:
  162.   Read one byte from nRF24L01 register, 'reg'
  163. /**************************************************/
  164. uchar SPI_Read(uchar reg)
  165. {
  166.         uchar reg_val;

  167.           CSN = 0;                // CSN low, initialize SPI communication...
  168.           SPI_RW(reg);            // Select register to read from..
  169.           reg_val = SPI_RW(0);    // ..then read registervalue
  170.           CSN = 1;                // CSN high, terminate SPI communication

  171.           return(reg_val);        // return register value
  172. }
  173. /**************************************************
  174. Function: SPI_Read_Buf();

  175. Description:
  176.   Reads 'bytes' #of bytes from register 'reg'
  177.   Typically used to read RX payload, Rx/Tx address
  178. /**************************************************/
  179. uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes)
  180. {
  181.         uchar status,byte_ctr;

  182.           CSN = 0;                                    // Set CSN low, init SPI tranaction                SPI片选
  183.           status = SPI_RW(reg);                       // Select register to write to and read status byte

  184.           for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)
  185.             pBuf[byte_ctr] = SPI_RW(0);     // Perform SPI_RW to read byte from nRF24L01         从nRF24L01读取字节

  186.           CSN = 1;                            // Set CSN high again

  187.           return(status);                     // return nRF24L01 status byte
  188. }
  189. /**************************************************
  190. Function: SPI_Write_Buf();

  191. Description:
  192.   Writes contents of buffer '*pBuf' to nRF24L01         将缓冲区'* pBuf'的内容写入nRF24L01
  193.   Typically used to write TX payload, Rx/Tx address
  194. /**************************************************/
  195. uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
  196. {
  197.         uchar status,byte_ctr;

  198.           CSN = 0;                   // Set CSN low, init SPI tranaction           SPI片选
  199.           status = SPI_RW(reg);      // Select register to write to and read status byte           
  200.          
  201.         for(byte_ctr=0; byte_ctr<bytes; byte_ctr++) // then write all byte in buffer(*pBuf)                将所有字节写入缓冲区
  202.             SPI_RW(*pBuf++);
  203.          
  204.         CSN = 1;                   // Set CSN high again
  205.          
  206.         return(status);            // return nRF24L01 status byte
  207. }
  208. /**************************************************
  209. Function: RX_Mode();

  210. Description:
  211.   This function initializes one nRF24L01 device to
  212.   RX Mode, set RX address, writes RX payload width,
  213.   select RF channel, datarate & LNA HCURR.
  214.   After init, CE is toggled high, which means that
  215.   this device is now ready to receive a datapacket.
  216.   该函数将一个nRF24L01器件初始化为RX模式,设置RX地址,
  217.   写入RX有效负载宽度,选择RF通道,数据速率和LNA HCURR。
  218.   在init之后,CE被切换为高电平,这意味着该设备现在准备好
  219.   接收数据包
  220. /**************************************************/
  221. void RX_Mode(void)
  222. {
  223.         CE=0;

  224.           SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // Use the same address on the RX device as the TX device 在RX设备上使用与TX设备相同的地址

  225.           SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      // Enable Auto.Ack:Pipe0
  226.           SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // Enable Pipe0
  227.           SPI_RW_Reg(WRITE_REG + RF_CH, 40);        // Select RF channel 40
  228.           SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH); // Select same RX payload width as TX Payload width 数据宽度相同
  229.           SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR          发射功率,数据率
  230.           SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);     // Set PWR_UP bit, enable CRC(2 bytes) & Prim:RX. RX_DR enabled..

  231.           CE = 1; // Set CE pin high to enable RX device         使能接受

  232.   //  This device is now ready to receive one packet of 16 bytes payload from a TX device sending to address
  233.   //  '3443101001', with auto acknowledgment, retransmit count of 10, RF channel 40 and datarate = 2Mbps.
  234.   //此设备现在准备好从发送到地址'3443101001'的TX设备接收一个16字节有效载荷的包,其具有自动确认,重传计数为10,RF信道40和数据速率= 2Mbps。


  235. }
  236. /**************************************************
  237. Function: TX_Mode();

  238. Description:
  239.   This function initializes one nRF24L01 device to
  240.   TX mode, set TX address, set RX address for auto.ack,
  241.   fill TX payload, select RF channel, datarate & TX pwr.
  242.   PWR_UP is set, CRC(2 bytes) is enabled, & PRIM:TX.

  243.   ToDo: One high pulse(>10us) on CE will now send this
  244.   packet and expext an acknowledgment from the RX device.
  245.   该函数将一个nRF24L01器件初始化为TX模式,设置TX地址,
  246.   为auto.ack设置RX地址,填充TX有效负载,选择RF通道,
  247.   数据和TX pwr。 PWR_UP置1,CRC(2字节)使能,&PRIM:TX。
  248.   ToDo:CE上的一个高脉冲(> 10us)现在将发送此数据包,并从RX设备展开确认。
  249. /**************************************************/
  250. void TX_Mode(void)
  251. {
  252.         CE=0;
  253.         
  254.           SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // Writes TX_Address to nRF24L01  将发送地址写入nRF24L01
  255.           SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 same as TX_Adr for Auto.Ack
  256.           SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // Writes data to TX payload  将数据写到发送区

  257.           SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      // Enable Auto.Ack:Pipe0
  258.           SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // Enable Pipe0
  259.           SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 retrans...
  260.           SPI_RW_Reg(WRITE_REG + RF_CH, 40);        // Select RF channel 40
  261.           SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   // TX_PWR:0dBm, Datarate:2Mbps, LNA:HCURR
  262.           SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);     // Set PWR_UP bit, enable CRC(2 bytes) & Prim:TX. MAX_RT & TX_DS enabled..

  263.         CE=1;
  264.         xian=0;

  265. }
  266. /**************************************************
  267. Function: check_ACK();

  268. Description:
  269.   check if have "Data sent TX FIFO interrupt",if TX_DS=1,
  270.   all led light and after delay 100ms all led close
  271.   检查是否有“数据发送TX FIFO中断”,如果TX_DS = 1,
  272.   所有LED指示灯和延时100ms后全部LED关闭
  273. /**************************************************
  274. void check_ACK()
  275. {
  276.         uchar test;
  277.         test=SPI_Read(READ_REG+STATUS);        // read register STATUS's
  278.         test=test&0x20;                                        // check if have Data sent TX FIFO interrupt (TX_DS=1)
  279.         if(test==0x20)                                        // TX_DS =1
  280.         {
  281.                 P0=0x00;                                        // turn on all led
  282.             delay100();                                        // delay 100ms
  283.                 P0=0xff;
  284.         }
  285. }
  286. /**************************************************/

  287. /**************************************************
  288. Function: TxData();

  289. Description:
  290.   write data x to SBUF
  291. /**************************************************
  292. void TxData (uchar x)
  293. {
  294.         SBUF=x;                        // write data x to SBUF
  295.         while(TI==0);
  296.                 TI=0;
  297. }
  298. /**************************************************/

  299. /**************************************************
  300. Function: CheckButtons();

  301. Description:
  302.   check buttons ,if have press,read the key values,
  303.   turn on led and transmit it;  after transmition,
  304.   if received ACK, clear TX_DS interrupt and enter RX Mode;
  305.   turn off the led
  306.   检查按钮,如果有按下,读取键值,打开led并发送;
  307.   发送后,如果收到ACK,清除TX_DS中断并进入RX模式;关闭led
  308. /**************************************************/
  309. void CheckButtons()
  310. {
  311.         uchar Temp,Tempi;

  312.         Temp=P3&KEY;                                 //读键值
  313.         if (Temp!=KEY)
  314.         {        
  315.                 delay_ms(10);
  316.                 Temp=P3&KEY;                                // 读键值
  317.                 if (Temp!=KEY)
  318.                 {
  319.                         switch(Temp)
  320.                         {
  321.                                 case 0x20:Tempi=0x01;   
  322.                                                   break;
  323.                                 case 0x40:Tempi=0x02;dislap(++quanshu);
  324.                                             break;
  325.                                 default:Tempi=0xff;
  326.                         }
  327.                         tx_buf[0]=Tempi;        
  328.                         TX_Mode();                        // 置发射模式并开始发射数据
  329.                         delay_ms(10);
  330.                         SPI_RW_Reg(WRITE_REG+STATUS,SPI_Read(READ_REG+STATUS));        // 清除(TX_DS)中断标志
  331.                         delay_ms(500);                                       
  332.                         RX_Mode();                        // 置位接收模式

  333.                         while((P3&KEY)!=KEY);
  334.                 }
  335.         }
  336. }
  337. /**************************************************
  338. Function: main();

  339. Description:
  340.   control all subprogrammes;
  341. /**************************************************/

  342. void displayInist()
  343. {           
  344.         uchar i;
  345.         lcd_pos(0,0);             //设置显示位置为第一行的第1个字符
  346.         i = 0;
  347.         while(i<5)
  348.         {                                                         //显示圈数
  349.                 lcd_wdat(dis1[i]);
  350.                 i++;
  351.         }

  352.         lcd_pos(1,0);             //设置显示位置为第二行的第1个字符
  353.         i = 0;
  354.         while(dis5[i] != '\0')
  355.         {
  356.                 lcd_wdat(dis5[i]);      //显示经过了几条线
  357.                 i++;                                       
  358.         }
  359.         lcd_wdat('0');

  360.         lcd_pos(2,0);             //设置显示位置为第三行的第1个字符
  361.         i = 0;
  362.         while(dis2[i] != '\0')
  363.         {
  364.                 lcd_wdat(dis2[i]);      //显示湿度初始化
  365.                 i++;
  366.     }

  367.         lcd_pos(3,0);             //设置显示位置为第四行的第1个字符
  368.         i = 0;
  369.         while(dis6[i] != '\0')
  370.         {
  371.                    lcd_wdat(dis6[i]);      //显示温度初始化
  372.                 i++;
  373.     }
  374. }
  375. //显示圈数的数字
  376. void dislap(uchar q)
  377. {
  378.         uchar tq;
  379.         if(q<10)
  380.         {
  381.                 lcd_pos(0,2);
  382.                 lcd_wdat(0xa3);
  383.                 lcd_wdat(dis4[q]);        
  384.         }
  385.         else
  386.         {
  387.                 tq=q/10;
  388.                 lcd_pos(0,2);
  389.                 lcd_wdat(0xa3);
  390.                 lcd_wdat(dis4[tq]);
  391.                 tq=q%10;
  392.                 lcd_pos(0,3);
  393.                 lcd_wdat(0xa3);
  394.                 lcd_wdat(dis4[tq]);
  395.         }
  396. }
  397. //判断接收的数据给出反应
  398. void display(uchar xx,uchar yy)
  399. {
  400.         uchar i,T,H;
  401.         uchar t=0;
  402.         if(xx==0xff)
  403.                 return;
  404.         if(xx==0x01)
  405.         {
  406.                 lcd_pos(1,2);
  407.                 lcd_wdat(0xa3);
  408.                 lcd_wdat(dis4[++xian]);
  409.         }
  410.         if(xx==0x02)
  411.         {
  412.                 lcd_pos(2,0);             //设置显示位置为第三行的第1个字符
  413.                 i = 0;
  414.                 while(dis2[i] != '\0')
  415.                 {
  416.                         lcd_wdat(dis2[i]);      //显示有挡板
  417.                         i++;
  418.              }
  419.         }
  420.         if(xx==0x03)
  421.         {
  422.                 lcd_pos(3,2);
  423.                 for(i=0;i<12;i++)
  424.                 {
  425.                         lcd_wdat(' ');      //清除“初始化中”
  426.                 }
  427.                 lcd_pos(3,3);             //设置显示位置为第三行的第1个字符
  428.                 i = 0;
  429.                 while(dis7[i] != '\0')
  430.                 {
  431.                         lcd_wdat(dis7[i]);      //显示传感器异常
  432.                         i++;
  433.              }
  434.         }
  435.         if(xx!=0x01&&xx!=0x02&&xx!=0x03)                //显示温度情况
  436.         {        
  437.             T=xx%100;
  438.                  H=yy%100;
  439.                 lcd_pos(2,2);
  440.                 for(i=0;i<12;i++)
  441.                 {
  442.                         lcd_wdat(' ');      //清除内容以便显示湿度
  443.                 }
  444.                 lcd_pos(3,2);
  445.                 for(i=0;i<12;i++)
  446.                 {
  447.                         lcd_wdat(' ');      //清除内容以便显示温度
  448.                 }
  449.                 lcd_pos(2,2);
  450.                 lcd_wdat(digit[H/10]);
  451.                 lcd_wdat(digit[H%10]);
  452.                 lcd_wdat(0xa3);
  453.                 lcd_wdat(0xa5);
  454.                 lcd_pos(3,2);
  455.                 lcd_wdat(digit[T/10]);
  456.                 lcd_wdat(digit[T%10]);
  457.                 lcd_wdat(0xa1);
  458.                 lcd_wdat(0xe6);
  459.         }
  460. }

  461. void main(void)
  462. {
  463.         uchar xx,yy;
  464.         Init_IO();                    // Initialize IO port  初始化IO端口
  465.         Init_uart();                // Initialize 232 uart
  466.         //Init_int0();            // enable int0 interrupt
  467.         RX_Mode();                    // set RX mode
  468.         delay_ms(20);                 //延时
  469.         lcd_init();                //初始化LCD
  470.         displayInist();                                //初始化显示界面。
  471.         while(1)
  472.         {
  473.                 CheckButtons();         // scan key value and transmit 扫描键值和发送
  474.                 sta=SPI_Read(STATUS);        // read register STATUS's value          读寄存器STATUS的值
  475. //---------------------------------- 余下见附件-----------------------//

复制代码

所有资料51hei提供下载:
遥控器接收温湿度.rar (53.99 KB, 下载次数: 6)



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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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