大学生
最后登录1970-1-1
在线时间 小时
注册时间2015-4-15
|
发表于 2017-8-29 19:49:30
|
显示全部楼层
本帖最后由 马贞茂 于 2017-8-29 19:53 编辑
这里说明一点,火哥的这个NRF程序注重的是功能的实现,做开发的话还有待优化。- while(1)
- {
- //主机端 进入自应答发送模式
- NRF_TX_Mode();
- //开始发送数据
- status = NRF_Tx_Dat(txbuf);
- //判断发送状态
- switch(status)
- {
- case MAX_RT:
- // 主机端 没接收到应答信号,发送次数超过限定值,发送失败。
- LEDG_ON(); //绿灯
- break;
- case ERROR:
- //未知原因导致发送失败。
- LEDR_ON(); //红灯
- break;
- case TX_DS:
- // 主机端 接收到 从机端 的应答信号,发送成功!
- LEDB_ON(); //蓝灯
- break;
- }
- //主机端 进入接收模式。
- NRF_RX_Mode(); //(从以上程序可以看出来,不管主机数据是不是发送成功,都会进入接收模式)
- //等待接收数据
- status = NRF_Rx_Dat(rxbuf);
- //判断接收状态
- switch(status)
- {
- case RX_DR: //主机端 接收到 从机端 发送的数据为:rxbuf
- for(i=0;i<4;i++)
- {
- if(txbuf == rxbuf)
- {
- count++;
- }
- }
- if(count>=4)
- {
- count=0;
- LEDB_ON();
- Delay_MS(500);
- LEDB_OFF();
- Delay_MS(500);
- }
- else
- {
- count=0;
- LEDR_ON();
- Delay_MS(500);
- LEDR_OFF();
- Delay_MS(500);
- }
- break;
- case ERROR: //主机端 未接收任何数据
- {
- LEDR_ON();
- Delay_MS(500);
- LEDR_OFF();
- Delay_MS(500);
- }
- break;
- }
- }
- //这里面我自己定义了一个数组ceshi[],用来测试主机发给从机,从机接收到数据后再原样发回来,数据和之前的一不一样。用到中断的地方就是您说的发送完成中断和接收完成中断,程序贴在下面:
- u8 NRF_Tx_Dat(u8 *txbuf) //发送数据函数
- {
- u8 state;
- /*ce为低,进入待机模式1*/
- NRF_CE_LOW();
- /*写数据到TX BUF 最大 32个字节*/
- SPI_NRF_WriteBuf(WR_TX_PLOAD,txbuf,TX_PLOAD_WIDTH);
- /*CE为高,txbuf非空,发送数据包 */
- NRF_CE_HIGH();
- /*等待发送完成中断 */
- while(NRF_Read_IRQ()!=0);
- /*读取状态寄存器的值 */
- state = SPI_NRF_ReadReg(STATUS);
- /*清除TX_DS或MAX_RT中断标志*/
- SPI_NRF_WriteReg(NRF_WRITE_REG+STATUS,state);
- SPI_NRF_WriteReg(FLUSH_TX,NOP); //清除TX FIFO寄存器
- /*判断中断类型*/
- if(state&MAX_RT) //达到最大重发次数
- return MAX_RT;
- else if(state&TX_DS) //发送完成
- return TX_DS;
- else
- return ERROR; //其他原因发送失败
- }
- u8 NRF_Rx_Dat(u8 *rxbuf) //接收数据函数
- {
- u8 state;
- NRF_CE_HIGH(); //进入接收状态
- /*等待接收中断*/
- while(NRF_Read_IRQ()!=0); //(假如没接收到数据,程序是不是会死在这里?估计你先后上电得问题就出在这里)
- NRF_CE_LOW(); //进入待机状态
- /*读取status寄存器的值 */
- state=SPI_NRF_ReadReg(STATUS);
- /* 清除中断标志*/
- SPI_NRF_WriteReg(NRF_WRITE_REG+STATUS,state);
- /*判断是否接收到数据*/
- if(state&RX_DR) //接收到数据
- {
- SPI_NRF_ReadBuf(RD_RX_PLOAD,rxbuf,RX_PLOAD_WIDTH);//读取数据
- SPI_NRF_WriteReg(FLUSH_RX,NOP); //清除RX FIFO寄存器
- return RX_DR;
- }
- else
- return ERROR; //没收到任何数据
- }
- //是不是在把配置寄存器配置为0x0e,然后下面是从机的程序:
- while(1)
- {
- //从机端 进入接收模式
- NRF_RX_Mode();
- //等待接收数据
- status = NRF_Rx_Dat(rxbuf);
- //判断接收状态
- if(status == RX_DR)
- {
- for(i=0;i<4;i++)
- {
- //从机端 接收到 主机端 发送的数据为:rxbuf
- if(ceshi == rxbuf) //(这两个不变的数组指针在这里比较四次是什么意思?)
- {
- count++;
- txbuf = rxbuf;
- }
- }
- if(count>=4)
- {
- count=0;
- LEDG_ON(); LEDR_ON();LEDB_ON();
- Delay_MS(500);
- LEDG_OFF(); LEDR_OFF();LEDB_OFF();
- Delay_MS(500);
- }
- else
- {
- count=0;
- LEDB_ON();
- Delay_MS(500);
- LEDB_OFF();
- Delay_MS(500);
- }
- }
- if( Key_Scan(GPIOB,GPIO_Pin_8) == KEY_ON )
- {
- LEDG_OFF(); LEDR_OFF();LEDB_OFF();
- }
- //从机端 进入自应答发送模式
- NRF_TX_Mode();
- //不断重发,直至发送成功
- do
- {
- status = NRF_Tx_Dat(txbuf);
- }while(status == MAX_RT);
- }
- /***********分割线************/
- 这里贴出我的部分代码,仅供参考,不足的地方欢迎指正。
- extern uint8_t TX_End_Flag;
- void NRF_Tx_Dat(u8 *txbuf)
- {
- while(TX_End_Flag);
- SPI_NRF_WriteBuf(WR_TX_PLOAD,txbuf,PLOAD_WIDTH); /*写数据到TX BUF 最大 32个字节*/
- TX_End_Flag=1;
- }
- uint8_t RX_Buf[32];
- uint8_t TX_End_Flag=0;
- void EXTI4_IRQHandler(void)
- {
- uint8_t states;
- if((EXTI->PR&EXTI_Line4)==EXTI_Line4)
- {
- states = SPI_NRF_ReadReg(STATUS);
- SPI_NRF_WriteReg(NRF_WRITE_REG+STATUS,states);
- switch(states&0x70)
- {
- case RX_DR: //接收中断
- SPI_NRF_ReadBuf(RD_RX_PLOAD,RX_Buf,PLOAD_WIDTH);
- break;
- case TX_DS: //发送中断
- TX_End_Flag=0;
- break;
- case MAX_RT: //达到最大重发次数中断
- SPI_NRF_WriteReg(FLUSH_TX,NOP);
- TX_End_Flag=0;
- break;
- }
- EXTI->PR = EXTI_Line4;
- }
- }
复制代码
|
|