找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机无线防丢器程序设计中的一些问题

[复制链接]
跳转到指定楼层
楼主
ID:467318 发表于 2019-1-13 22:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
同学的无线防丢器,利用2个52单片机+2个NRF24L01无线模块做的分从机主机,主机的板子上面有蜂鸣器,能够报警,从机放在防丢失的目标上

我的理解:
从机 开机后亮灯,初始化单片机电平,重复下面步骤
发送信息,发送成功则灯亮一下,发送超时则灯不亮
                Tx_Buf[0] = 0xa1;  
                Tx_Buf[1] = 1;   
                Tx_Buf[2] = 1;   
                Transmit(Tx_Buf);
                led = 0;
                delay_1ms(100);
                sta=SPI_Read(READ_REG +  STATUS);
                if(TX_DS)         //当前STATUS状态  发送中断应使bit5 = 1
                {
                        SPI_RW_Reg(WRITE_REG + STATUS,sta);
                }

还有
               SPI_RW_Reg(WRITE_REG + STATUS,sta);看不懂
主机  开机后亮灯,初始化单片机电平,接收模式,重复下面步骤:
接收到信号并核对,如果正确就亮灯,3秒内没有接到就报警

if(nRF24L01_RxPacket(Rx_Buf))
这段的意思不太清楚

还有就是主机接收到信号后是不是在三秒后才会再次开始接收信号

希望各位能够指点一下,感激不尽!

下面是从机程序
  1. #include <reg52.h>                 //调用单片机头文件
  2. #define uchar unsigned char  //无符号字符型 宏定义        变量范围0~255
  3. #define uint  unsigned int         //无符号整型 宏定义        变量范围0~65535

  4. sbit led   = P2^7;           //信号发射指示灯发光二极管定义

  5. //****************************************IO端口定义***************************************
  6. sbit CE   = P2^2;
  7. sbit SCK  = P2^1;
  8. sbit MISO = P2^0;
  9. sbit CSN  = P2^3;
  10. sbit MOSI = P2^4;
  11. sbit IRQ  = P2^5;

  12. //******************************************************************************************
  13. uchar  bdata sta;   //状态标志
  14. sbit RX_DR =sta^6;
  15. sbit TX_DS =sta^5;
  16. sbit MAX_RT =sta^4;
  17. //*********************************************NRF24L01*************************************
  18. #define TX_ADR_WIDTH    5    // 5 uints TX address width
  19. #define RX_ADR_WIDTH    5    // 5 uints RX address width
  20. #define TX_PLOAD_WIDTH  32   // 32 uints TX payload
  21. #define RX_PLOAD_WIDTH  32   // 32 uints TX payload
  22. uchar code TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x11,0x05}; //本地地址
  23. uchar code RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x00,0x05}; //接收地址
  24. uchar idata Tx_Buf[TX_PLOAD_WIDTH]={0x01,0x02,0x03,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,
  25. 0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xee,0xff};//发送数据
  26. uchar Rx_Buf[RX_PLOAD_WIDTH];//接收数据
  27. //***************************************NRF24L01寄存器指令*******************************************************
  28. #define READ_REG        0x00   // 读寄存器指令
  29. #define WRITE_REG       0x20  // 写寄存器指令
  30. #define RD_RX_PLOAD     0x61   // 读取接收数据指令
  31. #define WR_TX_PLOAD     0xA0   // 写待发数据指令
  32. #define FLUSH_TX        0xE1  // 冲洗发送 FIFO指令
  33. #define FLUSH_RX        0xE2   // 冲洗接收 FIFO指令
  34. #define REUSE_TX_PL     0xE3   // 定义重复装载数据指令
  35. #define NOP             0xFF   // 保留
  36. //*************************************SPI(nRF24L01)寄存器地址****************************************************
  37. #define CONFIG          0x00  // 配置收发状态,CRC校验模式以及收发状态响应方式
  38. #define EN_AA           0x01  // 自动应答功能设置
  39. #define EN_RXADDR       0x02  // 可用信道设置
  40. #define SETUP_AW        0x03  // 收发地址宽度设置
  41. #define SETUP_RETR      0x04  // 自动重发功能设置
  42. #define RF_CH           0x05  // 工作频率设置
  43. #define RF_SETUP        0x06  // 发射速率、功耗功能设置
  44. #define STATUS          0x07  // 状态寄存器
  45. #define OBSERVE_TX      0x08  // 发送监测功能
  46. #define CD              0x09  // 地址检测           
  47. #define RX_ADDR_P0      0x0A  // 频道0接收数据地址
  48. #define RX_ADDR_P1      0x0B  // 频道1接收数据地址
  49. #define RX_ADDR_P2      0x0C  // 频道2接收数据地址
  50. #define RX_ADDR_P3      0x0D  // 频道3接收数据地址
  51. #define RX_ADDR_P4      0x0E  // 频道4接收数据地址
  52. #define RX_ADDR_P5      0x0F  // 频道5接收数据地址
  53. #define TX_ADDR         0x10  // 发送地址寄存器
  54. #define RX_PW_P0        0x11  // 接收频道0接收数据长度
  55. #define RX_PW_P1        0x12  // 接收频道0接收数据长度
  56. #define RX_PW_P2        0x13  // 接收频道0接收数据长度
  57. #define RX_PW_P3        0x14  // 接收频道0接收数据长度
  58. #define RX_PW_P4        0x15  // 接收频道0接收数据长度
  59. #define RX_PW_P5        0x16  // 接收频道0接收数据长度
  60. #define FIFO_STATUS     0x17  // FIFO栈入栈出状态寄存器设置
  61. /******************************************延时函数********************************************************/

  62. /***********************1ms延时函数*****************************/
  63. void delay_1ms(uint q)
  64. {
  65.         uint i,j;
  66.         for(i=0;i<q;i++)
  67.                 for(j=0;j<120;j++);
  68. }

  69. /************************************IO 口模拟SPI总线 代码************************************************/
  70. uchar SPI_RW(uchar byte)
  71. {
  72.         uchar i;
  73.         for(i=0;i<8;i++)
  74.         {
  75.                 MOSI=(byte&0x80);               
  76.                 byte=(byte<<1);
  77.                 SCK=1;
  78.                 byte|=MISO;
  79.                 //led=MISO;Delay(150);
  80.                 SCK=0;
  81.         }
  82.         return(byte);
  83. }
  84. uchar SPI_RW_Reg(uchar reg,uchar value) // 向寄存器REG写一个字节,同时返回状态字节
  85. {
  86.         uchar status;
  87.         CSN=0;
  88.         status=SPI_RW(reg);
  89.         SPI_RW(value);
  90.         CSN=1;
  91.         return(status);
  92. }
  93. uchar SPI_Read (uchar  reg )
  94. {
  95.         uchar reg_val;
  96.         CSN=0;
  97.         SPI_RW(reg);
  98.         reg_val=SPI_RW(0);
  99.         CSN=1;
  100.         return(reg_val);
  101. }

  102. uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
  103. {
  104.         uchar status,byte_ctr;
  105.         CSN = 0;                   // Set CSN low, init SPI tranaction
  106.         status = SPI_RW(reg);    // 选择寄存器写入和读取状态字节
  107.         for(byte_ctr=0; byte_ctr<bytes; byte_ctr++) // 然后写所有字节在缓冲区(* pBuf)
  108.         SPI_RW(*pBuf++);
  109.         CSN = 1;                 // Set CSN high again
  110.         return(status);          // nRF24L01返回状态字节
  111. }

  112. /*******************************发*****送*****模*****式*****代*****码*************************************/
  113. void TX_Mode(void)
  114. {
  115.         CE=0;
  116.         SPI_RW_Reg(FLUSH_TX,0x00);
  117.         SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // tx地址来nRF24L01写道
  118.         SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // RX_Addr0 tx adr一样为自动ack
  119.         SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      // Enable Auto.Ack:Pipe0
  120.         SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a); // 500us + 86us, 10 重发...1a
  121.         SPI_RW_Reg(WRITE_REG + RF_CH, 40);        // 选择RF信道40
  122.         SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   // TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR
  123.         SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为2字节
  124.         SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);
  125.         CE=1;
  126.         delay_1ms(100);
  127. }

  128. void Transmit(unsigned char * tx_buf)  
  129. {         //传输
  130.         CE=0;   //StandBy I模式
  131.         SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
  132.         SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH);     // 装载数据
  133.         SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);      // IRQ收发完成中断响应,16位CRC,主发送
  134.         CE=1;   //置高CE,激发数据发送
  135.         delay_1ms(150);
  136. }


  137. /******************主程序**********************/           
  138. void main()
  139. {
  140.         led = 0;      //开机点亮一下红灯
  141.         delay_1ms(200);
  142.         P0 = P1 = P2 = P3 = 0xff;  //初始化单片机IO口为高电平
  143.         while(1)
  144.         {

  145.                 Tx_Buf[0] = 0xa1;  
  146.                 Tx_Buf[1] = 1;   
  147.                 Tx_Buf[2] = 1;   
  148.                 Transmit(Tx_Buf);
  149.                 led = 0;
  150.                 delay_1ms(100);
  151.                 sta=SPI_Read(READ_REG +  STATUS);
  152.                 if(TX_DS)         //当前STATUS状态  发送中断应使bit5 = 1
  153.                 {
  154.                         SPI_RW_Reg(WRITE_REG + STATUS,sta);
  155.                 }
  156.                 if(MAX_RT)  //如果是发送超时
  157.                 {
  158.                         SPI_RW_Reg(WRITE_REG + STATUS,sta);
  159.                 }
  160.                 led = 1;
  161.                 delay_1ms(800);

  162.         }
  163. }
  164. 下面是主机程序
  165. #include <reg52.h>                 //调用单片机头文件
  166. #define uchar unsigned char  //无符号字符型 宏定义        变量范围0~255
  167. #define uint  unsigned int         //无符号整型 宏定义        变量范围0~65535

  168. sbit beep=P2^6;
  169. sbit led = P2^7;

  170. /***********************1ms延时函数*****************************/
  171. void delay_1ms(uint q)
  172. {
  173.         uint i,j;
  174.         for(i=0;i<q;i++)
  175.                 for(j=0;j<120;j++);
  176. }

  177. //****************************************IO端口定义***************************************
  178. sbit CE   = P2^2;
  179. sbit SCK  = P2^1;
  180. sbit MISO = P2^0;
  181. sbit CSN  = P2^3;
  182. sbit MOSI = P2^4;
  183. sbit IRQ  = P2^5;

  184. //******************************************************************************************
  185. uchar  bdata sta;   //状态标志
  186. sbit RX_DR =sta^6;
  187. sbit TX_DS =sta^5;
  188. sbit MAX_RT =sta^4;
  189. //*********************************************NRF24L01*************************************
  190. #define TX_ADR_WIDTH    5    // 5 uints TX address width
  191. #define RX_ADR_WIDTH    5    // 5 uints RX address width
  192. #define TX_PLOAD_WIDTH  32   // 32 uints TX payload
  193. #define RX_PLOAD_WIDTH  32   // 32 uints TX payload
  194. uchar code TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x00,0x10,0x05}; //本地地址
  195. uchar code RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x41,0x10,0x10,0x05}; //接收地址
  196. uchar Tx_Buf[TX_PLOAD_WIDTH]={0x01,0x02,0x03,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,
  197. 0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xaa,0xbb,0x11,0x22,0x33,0xee,0xff};//发送数据
  198. uchar Rx_Buf[RX_PLOAD_WIDTH];//接收数据
  199. //***************************************NRF24L01寄存器指令*******************************************************
  200. #define READ_REG        0x00   // 读寄存器指令
  201. #define WRITE_REG       0x20  // 写寄存器指令
  202. #define RD_RX_PLOAD     0x61   // 读取接收数据指令
  203. #define WR_TX_PLOAD     0xA0   // 写待发数据指令
  204. #define FLUSH_TX        0xE1  // 冲洗发送 FIFO指令
  205. #define FLUSH_RX        0xE2   // 冲洗接收 FIFO指令
  206. #define REUSE_TX_PL     0xE3   // 定义重复装载数据指令
  207. #define NOP             0xFF   // 保留
  208. //*************************************SPI(nRF24L01)寄存器地址****************************************************
  209. #define CONFIG          0x00  // 配置收发状态,CRC校验模式以及收发状态响应方式
  210. #define EN_AA           0x01  // 自动应答功能设置
  211. #define EN_RXADDR       0x02  // 可用信道设置
  212. #define SETUP_AW        0x03  // 收发地址宽度设置
  213. #define SETUP_RETR      0x04  // 自动重发功能设置
  214. #define RF_CH           0x05  // 工作频率设置
  215. #define RF_SETUP        0x06  // 发射速率、功耗功能设置
  216. #define STATUS          0x07  // 状态寄存器
  217. #define OBSERVE_TX      0x08  // 发送监测功能
  218. #define CD              0x09  // 地址检测           
  219. #define RX_ADDR_P0      0x0A  // 频道0接收数据地址
  220. #define RX_ADDR_P1      0x0B  // 频道1接收数据地址
  221. #define RX_ADDR_P2      0x0C  // 频道2接收数据地址
  222. #define RX_ADDR_P3      0x0D  // 频道3接收数据地址
  223. #define RX_ADDR_P4      0x0E  // 频道4接收数据地址
  224. #define RX_ADDR_P5      0x0F  // 频道5接收数据地址
  225. #define TX_ADDR         0x10  // 发送地址寄存器
  226. #define RX_PW_P0        0x11  // 接收频道0接收数据长度
  227. #define RX_PW_P1        0x12  // 接收频道0接收数据长度
  228. #define RX_PW_P2        0x13  // 接收频道0接收数据长度
  229. #define RX_PW_P3        0x14  // 接收频道0接收数据长度
  230. #define RX_PW_P4        0x15  // 接收频道0接收数据长度
  231. #define RX_PW_P5        0x16  // 接收频道0接收数据长度
  232. #define FIFO_STATUS     0x17  // FIFO栈入栈出状态寄存器设置

  233. /************************************IO 口模拟SPI总线 代码************************************************/
  234. uchar SPI_RW(uchar byte)
  235. {
  236.         uchar i;
  237.         for(i=0;i<8;i++)
  238.         {
  239.                 MOSI=(byte&0x80);               
  240.                 byte=(byte<<1);
  241.                 SCK=1;
  242.                 byte|=MISO;
  243.                 //led=MISO;Delay(150);
  244.                 SCK=0;
  245.         }
  246.         return(byte);
  247. }
  248. uchar SPI_RW_Reg(uchar reg,uchar value) // 向寄存器REG写一个字节,同时返回状态字节
  249. {
  250.         uchar status;
  251.         CSN=0;
  252.         status=SPI_RW(reg);
  253.         SPI_RW(value);
  254.         CSN=1;
  255.         return(status);
  256. }
  257. uchar SPI_Read (uchar  reg )
  258. {
  259.         uchar reg_val;
  260.         CSN=0;
  261.         SPI_RW(reg);
  262.         reg_val=SPI_RW(0);
  263.         CSN=1;
  264.         return(reg_val);
  265. }

  266. uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes)
  267. {
  268.         uchar status,byte_ctr;
  269.         CSN = 0;                   // Set CSN low, init SPI tranaction
  270.         status = SPI_RW(reg);    // 选择寄存器写入和读取状态字节
  271.         for(byte_ctr=0; byte_ctr<bytes; byte_ctr++) // 然后写所有字节在缓冲区(* pBuf)
  272.         SPI_RW(*pBuf++);
  273.         CSN = 1;                 // Set CSN high again
  274.         return(status);          // nRF24L01返回状态字节
  275. }

  276. /*******************************接*****收*****模*****式*****代*****码*************************************/
  277. uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
  278. {
  279.         uchar status,i;                                                                   // 交易
  280.         CSN = 0;                      // Set CSN low, init SPI tranaction
  281.         status = SPI_RW(reg);         // 选择寄存器写入和读取的状态 uchar
  282.         for(i=0;i<uchars;i++)
  283.                 pBuf[i] = SPI_RW(0);    //
  284.         CSN = 1;      
  285.         return(status);                    // return nRF24L01 status uchar
  286. }
  287. /******************************************************************************************************/
  288. /*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
  289. /*功能:数据读取后放如rx_buf接收缓冲区中
  290. /******************************************************************************************************/
  291. unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
  292. {
  293.         unsigned char revale=0;
  294.         sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况
  295.         if(RX_DR)             // 判断是否接收到数据
  296.         {
  297.                 //CE = 0;    //SPI使能
  298.                 SPI_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
  299.                 revale =1;   //读取数据完成标志
  300.                 //Delay(100);
  301.         }
  302.         SPI_RW_Reg(WRITE_REG+STATUS,sta);   //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
  303.         return revale;
  304. }
  305. /****************************************************************************************************/
  306. /*函数:void RX_Mode(void)
  307. /*功能:数据接收配置
  308. /****************************************************************************************************/
  309. void RX_Mode(void)
  310. {
  311.         CE=0;
  312.         SPI_RW_Reg(FLUSH_RX,0x00);
  313.         SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      // Enable Auto.Ack:Pipe0
  314.         SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  // Enable Pipe0
  315.         SPI_RW_Reg(WRITE_REG + RF_CH, 40);        // Select RF channel 40
  316.         SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
  317.         SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);   // TX_PWR:0dBm, Datarate:1Mbps, LNA:HCURR
  318.         SPI_RW_Reg(WRITE_REG + CONFIG, 0x0F);
  319.         CE=1;
  320.         delay_1ms(130);
  321. }



  322. /******************主程序**********************/           
  323. void main()
  324. {        
  325.         static uchar value=8;
  326.         led = 0;      //开机点亮一下红灯
  327.         delay_1ms(200);
  328.         P0 = P1 = P2 = P3 = 0xff;  //初始化单片机IO口为高电平        
  329.         RX_Mode();                                
  330.         while(1)
  331.         {
  332.                 if(nRF24L01_RxPacket(Rx_Buf))
  333.                 {        
  334.                         if(Rx_Buf[1] == 1)        
  335.                         {
  336.                                 led = 0 ;         
  337.                                 value = 15;          //3秒
  338.                         }
  339.                 }
  340.                 delay_1ms(200);
  341.                 led = 1 ;   //关闭接收指示灯
  342.                 if(value == 0)   //报警
  343.                 {
  344.                         beep = ~beep;
  345.                 }
  346.                 else
  347.                 {
  348.                         value --;   //减1
  349.                         beep = 1;        //关闭报警
  350.                 }
  351.         }
  352. }
复制代码


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

使用道具 举报

沙发
ID:258164 发表于 2019-1-14 10:01 | 只看该作者
你的代码不是有注释吗
SPI_RW_Reg(WRITE_REG+STATUS,sta);   //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
if(nRF24L01_RxPacket(Rx_Buf)) 这个是判断是否接受完一帧数据,你看看这个函数的返回值就清楚了
回复

使用道具 举报

板凳
ID:517463 发表于 2019-4-21 22:01 | 只看该作者
楼主解决了吗
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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