本帖最后由 nightingale2003 于 2016-11-26 09:09 编辑
目的:
写了个程序,分为接收端和发送端,发送数据两位
发送端用while,持续发送一个数(A),直到A发送后才进行后续发送BCD
接收端则持续接收。
现象:
现在发现如果先给接收端上电,接收端正常接收,即A-B-C-D
但是如果先给发送端上电,则接收到的变成 (A-A)-A-B-C,
也就是刚上电马上收到两个A,之后的都慢一拍,最后一个数则丢失。
情况1(正常)
发送端 接收端
上电(接受中)
发A 收到A
发B 收到B
发C 收到C
情况2(有问题)
发送端 接收端
上电(发A)
---- 上电(收到A A)
发B 收到A
发C 收到B
进行查错发现的线索:
发送端先上电,数据发送不出去,查STATE寄存器为0x0f,也就是TX_FIFO寄存器满
用write_SPI(FLUSH_TX,0);清除TX_FIFO也没法清除FIFO以及标志位。造成的结果就是
发送端发送的是B,结果接收端接收到的是A;发送端发送C,接收端收到B,以此类推;
为了便于查看,只列出主要函数(用的STC15的单片机,12M频率)
发送函数:
uchar nRF24l01_txpacket(uchar dat1,uchar dat2) //发送数据包,发送成功返回1
{
uchar temp;
temp=0;
CE=0;
FIFO[0]=dat1;
FIFO[1]=dat2;
write_SPI(0x20+CONFIG,0x3e);
write_SPI_buf(W_TX_PAYLORD,FIFO,2);
CE=1;
delayms(1);
do
state=read_SPI(STATUS);
while((state&0x30)==0);
if(TX_DS)
temp=1;
else
temp=0;
CE=0;
write_SPI(0x20+STATUS,0xff);
rw_SPI(FLUSH_TX);
return temp;
}
接收函数
uchar nRF24l01_rxpacket(uchar *str)
{
uchar temp=0;
state=read_SPI(STATUS);
if(RX_DR)
{
CE=0;
write_SPI(0x20+STATUS,0xff);
read_SPI_buf(R_RX_PAYLORD,str,2);
temp=1;
}
CE=1;
return temp;
}
发送端主函数
void main()
{
init();
flag_sc=1;
TR0=1;
/*-----------------------------------------找寻匹配接收器阶段-------------------------------------------------------*/
//先取得随机数A 假设0x55
while(nRF24l01_txpacket(0x20,0x55)!=1) //待修改参数 11111111
{
if(T0_count>=250) //超时则完全休眠,等待重启
deep_sleep();
delayms(20);
}
TxSend(0x01);
/*-----------------------------------------确认该频道有无载波,没有则发送B作为频道-------------------------------------------------------*/
do
{
//再取随机数B 假设0x66
P0_ADDRESS[4]=0x55; //待修改参数 11111111
CE=0;
write_SPI_buf(0x20+TX_ADDR,P0_ADDRESS,5);
write_SPI_buf(0x20+RX_ADDR_P0,P0_ADDRESS,5);
write_SPI(0x20+RF_CH,0x66);
setrx_nRF24l01();
T0_count=0;
flag_cd=0;
delay(10);
while(T0_count<=40) //等待2S 或者检测到载波
{
flag_cd=(bit)read_SPI(CD);
if(flag_cd==1)
break;
}
delay(10); //do while时用?
}
while(flag_cd==1);
TxSend(0x02);
CE=0;
write_SPI(0x20+RF_CH,3); //回原始频率给接收端发信号
T0_count=0;
CE=1;
write_SPI(FLUSH_TX,0);
nRF24l01_txpacket(0x30,0x66);
while(nRF24l01_txpacket(0x30,0x66)!=1) //待修改参数 11111111
{
if(T0_count>=250) //超时则完全休眠,等待重启
deep_sleep();
}
CE=0;
write_SPI(0x20+RF_CH,0x66); //待修改参数 11111111
flag_sc=0; //匹配完毕
GREEN=0; //绿灯亮
TR0=0;
while(1)
{
delayms(2000);
while(nRF24l01_txpacket(0x30,0x77)!=1);
GREEN=1;
}
}
接收端的都在中断中处理,TxSend是串口发送的函数(调试用),FIFO数组用来存放发送接收的数据
void NRF_initerrupt() interrupt 0 //NRF发送完毕,中断
{
if(nRF24l01_rxpacket(FIFO))
{
#ifdef UARTtest
TxSend(FIFO[1]);
#endif
main_count=0;
if(flag_sc==1)
{
CE=0;
if((FIFO[0]&0x10)==0) //发送的是地址
{
P0_ADDRESS[4]=FIFO[1];
write_SPI_buf(0x20+TX_ADDR,P0_ADDRESS,5);
write_SPI_buf(0x20+RX_ADDR_P0,P0_ADDRESS,5);
}
else //发送的频道
{
write_SPI(0x20+RF_CH,FIFO[1]);
flag_sc=0;
#ifdef UARTtest
read_SPI_buf(TX_ADDR,FIFO_test,5);
TxSend(FIFO_test[4]);
read_SPI_buf(RF_CH,FIFO_test,1);
TxSend(FIFO_test[0]);
#endif
}
}
else //接收到的是移动数据
{
}
setrx_nRF24l01(); //前面关了CE,需要重新开启
}
} |