【单片机】SI4432 Based Networking 2

编写一个简单地碰撞检测示例程序:

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:

【单片机】SI4432 Based Networking 2_第1张图片

主程序收到串口发来的 ‘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的值都是正常值(信道通畅):

【单片机】SI4432 Based Networking 2_第2张图片

启动 “搅屎棍” 之后,的确有冲突现象发生(LED闪烁表示冲突退避),而且冲突退避算法有效果,收发都没有丢包:

【单片机】SI4432 Based Networking 2_第3张图片
有奇怪的偶然发生的现象发生,随机断开两个节点或者 “搅屎棍” 会发生两个节点发送不出去数据,信道一直处于忙碌状态,或者是一个节点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(事务) 为最小单位:

【单片机】SI4432 Based Networking 2_第4张图片

还有不少没考虑到的细节,可以继续优化,具体的软件程序就不在这更新了。

你可能感兴趣的:(STM32)