编写一个简单地碰撞检测示例程序:
void RF_SendProcedure_CSMA_CA(void)
{
static const u8 random_withdraw_time_table[] = {5,22,19,14,12,20,9,10,6,11,7,13,8,23,25,17,16,21,24,18};
static u8 random_withdraw_time_select = 0;
SI4432_SwitchState(SI4432_STATE_RX);
int timeout = 500;
printf("%d\r\n",SI4432_RSSI());
while(CCA == CCA_FAILED)
{
// printf("%d ",SI4432_RSSI());
LED = ~LED;
delay_ms(random_withdraw_time_table[random_withdraw_time_select]);
timeout -= random_withdraw_time_table[random_withdraw_time_select];
if(timeout < 0)
break;
random_withdraw_time_select++;
if(random_withdraw_time_select == sizeof(random_withdraw_time_table) / sizeof(random_withdraw_time_table[0]))
random_withdraw_time_select = 0;
}
LED = 1;
if(timeout < 0)
{
printf("CCA timeout\r\n");
}
else
{
SI4432_TxState(SI4432_STATE_IDLE_READY);
}
}
程序中直接判断CCA引脚的状态,如果为1表示信道忙,则进行随机退避,随机数使用的简单的随机数表,网页工具:http://www.99cankao.com/numbers/random-number-generator.php:
主程序收到串口发来的 ‘a’ 字符的时候发送一次数据。
while(1)
{
if(USART_GetFlagStatus(USART1,USART_FLAG_ORE) == SET)
USART_ClearFlag(USART1,USART_FLAG_ORE);
if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE) == SET)
{
uart_data = USART_ReceiveData(USART1);
if(uart_data == 'a')
{
printf("Send:%d\t",++sent);
// SI4432_TxState(SI4432_STATE_IDLE_READY);
RF_SendProcedure_CSMA_CA();
SI4432_SwitchState(SI4432_STATE_RX);
}
else
{
sent = 0;
got = 0;
}
}
if(SI4432_Flags & SI4432_FLAGS_NEW_PACKAGE)
{
SI4432_Flags &= ~SI4432_FLAGS_NEW_PACKAGE;
printf("Got:%d\r\n",++got);
SI4432_FETCH_DATA();
}
// delay_ms(100);
}
在后再来一个 “搅屎棍” :
这个 “搅屎棍” 设备没什么其它任务,高速循环发送数据即可,注意修改发送头码,不要和那两个节点的接收头码相同:
while(1)
{
printf("a");
SI4432_TX_MODE();
delay_ms(10);
}
“搅屎棍” 启动之前,两个节点的互相通讯是没有问题的,而且发送的时候RSSI的值都是正常值(信道通畅):
启动 “搅屎棍” 之后,的确有冲突现象发生(LED闪烁表示冲突退避),而且冲突退避算法有效果,收发都没有丢包:
有奇怪的偶然发生的现象发生,随机断开两个节点或者 “搅屎棍” 会发生两个节点发送不出去数据,信道一直处于忙碌状态,或者是一个节点1可以发送出去数据,节点2收不到数据(几乎收不到,发送500个收到6个),但是节点2发送数据节点1是能收到的,拔掉 “搅屎棍” 的电源,一切恢复正常。奇怪。还有件奇怪的事情,发送数据的时候我的耳机里面偶然会有非常微弱呲呲的声音(合适的角度认真听才听到),耳机的音圈尽然收到了433Mhz的信号了?还是电脑里面的某些器件收到信号了?
虽然有一个简单的冲突检测功能,但是还是需要应答的功能,设计一个简单的数据交互方式:
struct transaction
{
struct transaction *next;
int tid;
int flag;
int status;
u8 *tx_buff;
u8 *rx_buff;
};
每一个传输都以 transaction(事务) 为最小单位:
还有不少没考虑到的细节,可以继续优化,具体的软件程序就不在这更新了。