| 
 
新手上路 
 
	积分41金钱41 注册时间2015-11-13在线时间0 小时 | 
 
 
 楼主|
发表于 2015-11-22 14:04:27
|
显示全部楼层 
|  发现原因了。首先要再描述一下我的问题:大概每发送4个,接收方只能收到一个或两个,之后发送端就显示失败了。如果复位MCU,则又可以收到,但是收到的是之前发送的四个的后面内容,当然,这时候发送方又发出了新的四个。<br /> <br />
 问题来了:<br />
 ①发送方发送了四个,发送成功了吗?答:成功了,因为复位MCU可以收到前面的数据<br />
 ②接收方收到了多少?答:3个!!!如果小于3个,那么发送方在发送第三个的时候就会失败,不会显示4个字符。<br />
 ③为什么是复位MCU?猜测:程序跑飞了,或者卡住了。答:卡住了。<br />
 <br />
 看上面的代码是串口发送回PC的,我的串口设置了中断服务函数:<br />
 <div   style="background-color:#E8E8E8;">
 [mw_shl_code=c,true]// 串口接收
 void interrupt_uart() interrupt 4 //串口中断优先等级为4
 {
 if(TI) TI=0; // 发送完成,清除该标志位
 
 if(RI)
 {
 RI=0;                                 // 先把接收标志位清零
 Command=SBUF; // 将收到的指令
 GCFlag=1;                        // 收到指令
 }
 }
 [/mw_shl_code]
 </div>
 其中的<span style="line-height:1.5;">if(TI) TI=0; 在发送完成遇到TI置高时清零TI。而main函数中又有这样的代码:<br />
 <div   style="background-color:#E8E8E8;">
 [mw_shl_code=c,true]        while(1)
 {
 
 while(!nRF24L01_RxPacket(&Rx_Buf)); //等待接收数据 ,返回1则接收到数据 ,在等待接收数据期间,可以随时变成发送模式
 
 // 通过串口发送数据
 SBUF=Rx_Buf;
 //while(!TI);  // 死于此
 }
 [/mw_shl_code]
 </div>
 while(!TI)还在等待TI置高。这就是为什么显示出来的字符数是一个或两个或……3,4都有可能。但是就是无法连续接收。这就是因为……人品!!有些时候中断吧TI清0的早,就显示一个,清0得晚就多几个。毕竟中断发生的时机虽然说都是在发送完成之后,但是实际上在发送完成的这个时刻main出于什么状态是不确定的。有些时候中断发生的是瞬间while已经发现了TI为高就过去了,有些时候中断发生while还没执行到判断就被中断打断了,之后中断清0了TI,while永远都出不来了。<br />
 <br />
 虽然我之前也试过注释掉这个while,但也失败了,可以说是很多错误的集合吧。下面发出可用的RX_Mode函数和RxPacket函数,都是在C51下的代码。实际上这些代码也参照了原子哥的STM32的相关代码,看了他的接收模式配置和接收数据的流程。<br />
 <div   style="background-color:#E8E8E8;">
 [mw_shl_code=c,true]void RX_Mode(void)
 {
 uchar buf[5]={0};
 CE = 0;
 
 SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
 
 SPI_WR_Reg(WRITE_REG + EN_AA, 01);     //  频道0自动        ACK应答允许
 SPI_WR_Reg(WRITE_REG + EN_RXADDR,0x01);  //  允许接收地址只有频道0,如果需要多频道可以参考Page21
 SPI_WR_Reg(WRITE_REG + RF_CH, 40);        //   设置信道工作为2.4GHZ,收发必须一致
 SPI_WR_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
 SPI_WR_Reg(WRITE_REG + RF_SETUP, 0x0F);                   //设置发射速率为2MHZ,发射功率为最大值0dB
 
 SPI_WR_Reg(WRITE_REG + CONFIG, 0x0F);//0x0F);
 CE = 1;
 Delay_n10us(20); //200us
 }
 
 //******************************************************************************************************/
 //*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
 //*功能:数据读取后放如rx_buf接收缓冲区中
 //******************************************************************************************************/
 uchar nRF24L01_RxPacket(unsigned char* rx_buf)
 {
 uchar flag=0;
 uchar status;
 
 status=SPI_RD_Reg(NRFRegSTATUS);        // 读取状态寄存其来判断数据接收状况
 SPI_WR_Reg(WRITE_REG+NRFRegSTATUS, status);   //接收到数据后RX_DR,TX_DS,MAX_RT都置高为1,通过写1来清除中断标志
 
 if(status & RX_OK)                                // 判断是否接收到数据
 {
 SPI_Read_Buf(RD_RX_PLOAD,rx_buf,RX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
 delayms(10);
 SPI_WR_Reg(FLUSH_RX,0xff);//清除RX FIFO寄存器
 flag =1;                        //读取数据完成标志
 }
 return flag;
 }[/mw_shl_code]
 </div>
 以后会来发完整代码的。谢谢大家<br />
 <br />
 </span><br />
 <br />
 <br />
 | 
 |