智能车制作

 找回密码
 注册

扫一扫,访问微社区

查看: 4212|回复: 11
打印 上一主题 下一主题

NRF24L01&S12

[复制链接]

16

主题

243

帖子

0

精华

常驻嘉宾

Rank: 8Rank: 8

积分
3024
威望
1478
贡献
922
兑换币
132
注册时间
2011-3-26
在线时间
312 小时
跳转到指定楼层
1#
发表于 2012-10-4 11:41:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 lcokenm 于 2012-10-4 11:40 编辑
  1. #include <hidef.h>      /* common defines and macros */
  2. #include "derivative.h"      /* derivative-specific definitions */
  3. #include"nrf24l01.h"
  4. /***********************************************************/
  5. char RxBuf[1]={0};

  6. //=======================NRF24L01_CE端口=========================================
  7. #define RF24L01_CE_0 PORTA_PA0=0
  8. #define RF24L01_CE_1 PORTA_PA0=1
  9. //=============================RF24L01_CSN端口==================================
  10. #define RF24L01_CSN_0 PORTA_PA1=0
  11. #define RF24L01_CSN_1 PORTA_PA1=1
  12. //=============================RF24L01_SCK端口======================================
  13. #define RF24L01_SCK_0 PORTA_PA2=0
  14. #define RF24L01_SCK_1 PORTA_PA2=1
  15. //============================= RF24L01_MOSI端口================================
  16. #define RF24L01_MOSI_0 PORTA_PA3=0
  17. #define RF24L01_MOSI_1 PORTA_PA3=1
  18. //=============================RF24L01_MISO端口=========================================
  19. #define RF24L01_MISO_0 PORTA_PA4=0
  20. #define RF24L01_MISO_1 PORTA_PA4=1

  21. //==========================IRQ状态============================================
  22. #define RF24L01_IRQ_0 PORTA_PA5=0
  23. #define RF24L01_IRQ_1 PORTA_PA5=1

  24. char TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //本地地址

  25. char RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x01}; //接收地址
  26. char sta;

  27. void RF24L01_IO_set(void);
  28. void ms_delay(void);
  29. void Delay(int s);
  30. char SPI_RW(char data);
  31. char SPI_Read(char reg);
  32. char SPI_RW_Reg(char reg, char value);
  33. char SPI_Read_Buf(char reg, char *pBuf, char uchars);
  34. char SPI_Write_Buf(char reg, char *pBuf, char uchars);
  35. void SetRX_Mode(void);
  36. char nRF24L01_RxPacket(char* rx_buf);
  37. void nRF24L01_TxPacket(char * tx_buf);
  38. void init_NRF24L01(void);
  39. //===========================RF24L01端口设置==========================================
  40. void RF24L01_IO_set(void)
  41. {
  42.       DDRA=0X0F;
  43. }

  44. //******************************************************************************

  45. //========================延时约5ms=============================================
  46. void ms_delay(void)
  47. {
  48.       unsigned int i=40000;
  49.       while (i != 0)
  50.       {
  51.           i--;
  52.       }
  53. }
  54. //========================================长延时================================
  55. void Delay(int s)
  56. {
  57.       unsigned int i,j;
  58.       for(i=0; i<s; i++);
  59.       for(j=0; j<s; j++);
  60. }
  61. //******************************************************************************************
  62. //延时函数
  63. //******************************************************************************************
  64. void inerDelay_us(char n)
  65. {
  66.       for(;n>0;n--);
  67. }
  68. //==============================================================================
  69. //函数:uint SPI_RW(uint uchar)
  70. //功能:NRF24L01的SPI写时序
  71. //******************************************************************************
  72. char SPI_RW(char data)
  73. {
  74.       char i,temp=0;
  75.       for(i=0;i<8;i++) // output 8-bit
  76.       {
  77.           if((data & 0x80)==0x80)
  78.           {
  79.             RF24L01_MOSI_1; // output 'uchar', MSB to MOSI
  80.           }
  81.           else
  82.           {
  83.             RF24L01_MOSI_0;
  84.           }
  85.           data = (data << 1); // shift next bit into MSB..
  86.           temp<<=1;
  87.           RF24L01_SCK_1; // Set SCK high..
  88.           if(PORTA_PA4==1)temp++; // capture current MISO bit
  89.           RF24L01_SCK_0; // ..then set SCK low again
  90.       }
  91.       return(temp); // return read uchar
  92. }
  93. //****************************************************************************************************
  94. //函数:uchar SPI_Read(uchar reg)
  95. //功能:NRF24L01的SPI时序
  96. //****************************************************************************************************
  97. char SPI_Read(char reg)
  98. {
  99.       char reg_val;
  100.       RF24L01_CSN_0; // CSN low, initialize SPI communication...
  101.       SPI_RW(reg); // Select register to read from..
  102.       reg_val = SPI_RW(0); // ..then read registervalue
  103.       RF24L01_CSN_1; // CSN high, terminate SPI communication
  104.       return(reg_val); // return register value
  105. }
  106. //****************************************************************************************************/
  107. //功能:NRF24L01读写寄存器函数
  108. //****************************************************************************************************/
  109. char SPI_RW_Reg(char reg, char value)
  110. {
  111.       char status1;
  112.       RF24L01_CSN_0; // CSN low, init SPI transaction
  113.       status1 = SPI_RW(reg); // select register
  114.       SPI_RW(value); // ..and write value to it..
  115.       RF24L01_CSN_1; // CSN high again
  116.       return(status1); // return nRF24L01 status uchar
  117. }
  118. //****************************************************************************************************/
  119. //函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
  120. //功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
  121. //****************************************************************************************************/
  122. char SPI_Read_Buf(char reg, char *pBuf, char chars)
  123. {
  124.       char status2,uchar_ctr;
  125.       RF24L01_CSN_0; // Set CSN low, init SPI tranaction
  126.       status2 = SPI_RW(reg); // Select register to write to and read status uchar
  127.       for(uchar_ctr=0;uchar_ctr<chars;uchar_ctr++)
  128.       {
  129.         pBuf[uchar_ctr] = SPI_RW(0);
  130.       }
  131.       RF24L01_CSN_1;
  132.       return(status2); // return nRF24L01 status uchar
  133. }
  134. //*********************************************************************************************************
  135. //函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
  136. //功能: 用于写数据 reg:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
  137. //*********************************************************************************************************/
  138. char SPI_Write_Buf(char reg, char *pBuf, char chars)
  139. {
  140.       char status1,uchar_ctr;
  141.       RF24L01_CSN_0; //SPI使能
  142.       status1 = SPI_RW(reg);
  143.       for(uchar_ctr=0; uchar_ctr<chars; uchar_ctr++)
  144.       {
  145.         SPI_RW(*pBuf++);
  146.       }
  147.       RF24L01_CSN_1; //关闭SPI
  148.       return(status1);
  149. }
  150. //****************************************************************************************************/
  151. //函数:void SetRX_Mode(void)
  152. //功能:数据接收配置
  153. //****************************************************************************************************/
  154. void SetRX_Mode(void)
  155. {
  156.       RF24L01_CE_0;
  157.       SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f); // IRQ收发完成中断响应,16位CRC,主接收
  158.       RF24L01_CE_1;
  159.       inerDelay_us(130); //注意不能太小
  160. }
  161. //******************************************************************************************************/
  162. //函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
  163. //功能:数据读取后放如rx_buf接收缓冲区中
  164. //******************************************************************************************************/
  165. char nRF24L01_RxPacket(char* rx_buf)
  166. {
  167.     char revale=0;
  168.     sta=SPI_Read(STATUS); //读取状态寄存其来判断数据接收状况
  169.     if(sta&0x40) // 判断是否接收到数据
  170.     {
  171.       RF24L01_CE_0 ; //SPI使能
  172.       SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH); // read receive payload from RX_FIFO buffer
  173.       revale =1; //读取数据完成标志
  174.     }
  175.       // SPI_RW_Reg(WRITE_REG+FIFO_STATUS, FLUSH_RX);//清空缓冲区
  176.       // SPI_RW(FLUSH_RX);
  177.       SPI_RW_Reg(WRITE_REG+STATUS,sta); //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志

  178.       return revale;
  179. }
  180. //***********************************************************************************************************
  181. //函数:void nRF24L01_TxPacket(char * tx_buf)
  182. //功能:发送 tx_buf中数据
  183. //**********************************************************************************************************/
  184. void nRF24L01_TxPacket(char * tx_buf)
  185. {
  186.       RF24L01_CE_0 ; //StandBy I模式
  187.       SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
  188.       SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH); // 装载数据
  189.       // SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); // IRQ收发完成中断响应,16位CRC,主发送
  190.       RF24L01_CE_1; //置高CE,激发数据发送
  191.       inerDelay_us(10);
  192. }
  193. //****************************************************************************************
  194. //NRF24L01初始化
  195. //***************************************************************************************/
  196. void init_NRF24L01(void)
  197. {
  198.       inerDelay_us(100);
  199.       RF24L01_CE_0 ; // chip enable
  200.       RF24L01_CSN_1; // Spi disable
  201.       RF24L01_SCK_0; // Spi clock line init high
  202.       SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // 写本地地址
  203.       SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
  204.       SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);                             // 频道0自动 ACK应答允许
  205.       SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);                         // 允许接收地址只有频道0,如果需要多频道可以参考Page21
  206.       SPI_RW_Reg(WRITE_REG + RF_CH, 0);                                // 设置信道工作为2.4GHZ,收发必须一致
  207.       SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH);                // 设置接收数据长度,本次设置为32字节
  208.       SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);                          // 设置发射速率为1MHZ,发射功率为最大值0dB
  209.       SPI_RW_Reg(WRITE_REG + CONFIG, 0x0E);                            // IRQ收发完成中断响应,16位CRC ,主接收}
  210. }


  211. //void main(void) {

  212. DisableInterrupts;
  213.   /* put your own code here */
  214. DDRB=0XFF;
  215. NRF24L01_IO_set();
  216. init_NRF24L01();
  217. SetRX_Mode();
  218. EnableInterrupts;
  219. while(1)
  220. {
  221.    
  222.     if(nRF24L01_RxPacket(RxBuf)) //判断是否收到数据
  223.                                  // NRF24L01在判断是否接收数据是可以通过中断引脚IRQ和内部 RX_DR,TX_DS,MAX_PT状态来判断,此处是后者,可以将IRQ引脚接到单片机中断口,通过中断来判断 推荐使用中断这样可以节约MCU消耗
  224.     {
  225.         receive=RxBuf[0];
  226.         speed=(receive & 0xf0)>>4;
  227.         PORTB=receive;
  228.            
  229.         SPI_RW_Reg(WRITE_REG+STATUS,0XFF);            
  230.     }  
  231.     _FEED_COP();
  232. }

  233.   
  234.   /* please make sure that you never leave main */
  235. }
  236. 2401跟K10的通信问题,发送和接收都可以,只是每次只能接收一次数据,接受完之后,接收端复位一次才能再次受到发送端的信数据,有人遇到这个问题没有?求教!是因为FIFO没有清空么?FIFO要在哪里清空?
复制代码

21

主题

345

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2326

优秀会员奖章活跃会员奖章

QQ
威望
1487
贡献
701
兑换币
303
注册时间
2011-12-11
在线时间
69 小时
2#
发表于 2012-10-4 12:59:36 | 只看该作者
有遇到过,当时调整一下函数位置就搞定了
回复 支持 反对

使用道具 举报

0

主题

8

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
219
威望
141
贡献
64
兑换币
6
注册时间
2012-8-24
在线时间
7 小时
毕业学校
GD
3#
发表于 2012-10-4 13:28:20 | 只看该作者
野火出了k60版的,你出了 S12 版的,智能车的小孩有福了
回复 支持 反对

使用道具 举报

16

主题

243

帖子

0

精华

常驻嘉宾

Rank: 8Rank: 8

积分
3024
威望
1478
贡献
922
兑换币
132
注册时间
2011-3-26
在线时间
312 小时
4#
 楼主| 发表于 2012-10-4 16:35:48 | 只看该作者
ForgeHoo 发表于 2012-10-4 12:59
有遇到过,当时调整一下函数位置就搞定了

求问,调整哪个函数的位置?
回复 支持 反对

使用道具 举报

16

主题

243

帖子

0

精华

常驻嘉宾

Rank: 8Rank: 8

积分
3024
威望
1478
贡献
922
兑换币
132
注册时间
2011-3-26
在线时间
312 小时
5#
 楼主| 发表于 2012-10-4 16:36:49 | 只看该作者
特级小菜虫 发表于 2012-10-4 13:28
野火出了k60版的,你出了 S12 版的,智能车的小孩有福了

哈哈,到飞思卡尔社区去吧,还会开源一些东西
回复 支持 反对

使用道具 举报

21

主题

345

帖子

1

精华

金牌会员

Rank: 6Rank: 6

积分
2326

优秀会员奖章活跃会员奖章

QQ
威望
1487
贡献
701
兑换币
303
注册时间
2011-12-11
在线时间
69 小时
6#
发表于 2012-10-4 19:16:36 | 只看该作者
本帖最后由 ForgeHoo 于 2012-10-4 19:19 编辑
lcokenm 发表于 2012-10-4 16:35
求问,调整哪个函数的位置?




第一个是我做智能家居的无线通信部分写的,一对多加反馈,第二个是做GPRS交通灯通信的无线部分时写的,链式传递方式,你比较一下看看吧,可能没多大帮助
有的时候加点延时就好了,有的时候换一下函数位置就好了,去掉部分有加注释的是可以用的,没有加注释的是用不用都可

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

16

主题

243

帖子

0

精华

常驻嘉宾

Rank: 8Rank: 8

积分
3024
威望
1478
贡献
922
兑换币
132
注册时间
2011-3-26
在线时间
312 小时
7#
 楼主| 发表于 2012-10-4 20:50:21 | 只看该作者
ForgeHoo 发表于 2012-10-4 19:16
第一个是我做智能家居的无线通信部分写的,一对多加反馈,第二个是做GPRS交通灯通信的无线部分时写 ...

好的,谢谢,我再试试
回复 支持 反对

使用道具 举报

0

主题

11

帖子

0

精华

高级会员

Rank: 4

积分
568
威望
305
贡献
157
兑换币
71
注册时间
2012-3-5
在线时间
53 小时
毕业学校
哈工程
8#
发表于 2013-1-29 21:23:36 | 只看该作者
楼主的程序是不是从没有SPI接口的单片机的程序里面拷的?看到有“SPI时序“这些字眼,“SPI时序“不是用I/O口模拟SPI吗?S12单片机自身有SPI模块,“SPI时序“这一块代码是不是可以用正统的SPI方法来代替?

楼主你最后成功了吗,能共享一下代码吗?小弟这两天想搞无线,24L01都在路上了
回复 支持 反对

使用道具 举报

3

主题

616

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
2029
QQ
威望
1114
贡献
433
兑换币
264
注册时间
2012-8-31
在线时间
241 小时
9#
发表于 2013-4-9 15:56:22 | 只看该作者
学习了
回复 支持 反对

使用道具 举报

16

主题

243

帖子

0

精华

常驻嘉宾

Rank: 8Rank: 8

积分
3024
威望
1478
贡献
922
兑换币
132
注册时间
2011-3-26
在线时间
312 小时
10#
 楼主| 发表于 2013-4-10 22:55:32 | 只看该作者
owenpcf1 发表于 2013-1-29 21:23
楼主的程序是不是从没有SPI接口的单片机的程序里面拷的?看到有“SPI时序“这些字眼,“SPI时序“不是用I/O ...

好久之前弄的无线模块了,最后只做到S12收数据,用K10发的数据,SPI时序是用IO口模拟的
回复 支持 反对

使用道具 举报

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

本版积分规则

关于我们|联系我们|小黑屋|智能车制作 ( 黑ICP备2022002344号

GMT+8, 2024-11-6 20:26 , Processed in 0.146394 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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