状态机在物联网产品嵌入式开发中的应用

本文探讨了状态机在物联网产品嵌入式开发中的应用,特别是针对带有无线通信模组的产品,如WIFI、BLE、NB_IoT等。通过实例详细介绍了如何利用状态机处理蓝牙模组的初始化过程,包括设置蓝牙名称、读取蓝牙名称及MAC地址等操作,展示了不停止式延时的重要性。
摘要由CSDN通过智能技术生成

状态机在编程中很常见,而用好状态机却不容易,在网上也看到很多人有很多种用法,优缺点各有吧,主要配合自己的系统编写出适合自己的状态机,下面我主要记录一下状态机在物联网产品嵌入式开发中的应用。
我指的物联网产品是带无线通信模组的,比如WIFI、BLE、NB_IoT、4G模组等,这些模组在使用过程中需求AT指令驱动,此时个人觉得使用状态机的方式编写驱动代码更好更直观,当然此时需要另外一个知识点,那就是“不停止式延时”,解释一下什么是“不停止式延时”:一般我们使用延时系统的延时函数,其原理是程序暂停等待,这样如果延时的时间长,导致其他代码无法运行,因此在大型项目中,此延时方式不可采用,所以才出现了这种不暂停式延时,具体下一篇详细介绍。
言归正传,继续介绍状态机,具体以实例介绍,比如初始化蓝牙模组过程中设置蓝牙名称、读取蓝牙名称、读取MAC地址等,一个命令可以分为至少两个状态,设置蓝牙名称可以分为如下两个状态:SBLENAME_STAT、SBLENAME_STATACK,前一个状态可以发送具体的设置指令,发送完成后马上跳转到下一个等待应答状态SBLENAME_STATACK,此时可以检测串口中是否有数据返回,若有完整的数据,则进行判断是否为蓝牙返回值,若正确,则进入下一个状态,若错误,重复此设置指令。另外若串口中没有数据返回,则等待超时,重复此命令,再判断次数,达到最大执行次数以后,若还没有成功可能是模组出现问题,此时可以跳转到复位状态。好了,原理差不多就这么简单,贴一段代码;

		case BLE_SUBSTAT_SNAME:
			BLE_SnameStat();
			break;
			
		case BLE_SUBSTAT_SNAMEACK:
			BLE_SnameStatACK();
			break;
			
		case BLE_SUBSTAT_QMAC:
			BLE_QmacStat();
			break;
			
		case BLE_SUBSTAT_QMACACK:
			BLE_QmacStatACK();

以上代码以设置名称以及读取MAC地址,下面看具体函数:

static void BLE_SnameStat(void)
{
	#ifndef HOST
	char str[]="TTM:REN-GasSensor";
	#else
	char str[]="TTM:REN-HostMachine";
	#endif
	my_log("send-> %s\r\n",str);
	Uart_Drv_data.Uart2_sendFun((uint8_t *)&str,strlen(str));

//	BLE_Drv_data.Time = Gettick();
	BLE_Drv_data.Time = myDelay.gettick();
	BLE_Drv_data.Delay = SNAME_TIMEOUT;
	BLE_Drv_data.substat = BLE_SUBSTAT_SNAMEACK;
}

static void BLE_SnameStatACK(void)
{
	uint8_t  packet_tmp[0xFF];
	uint8_t  ret_tmp[20] = {0};			//蓝牙名称长度,可以调整,这里为GasSensor

	if (Uart_Drv_data.WriteRingBuff2Len > 0)
	{
		//检测有数据的时候进行读数据
		my_rb_readbytes(&Uart_Drv_data.Ring2, packet_tmp, Uart_Drv_data.WriteRingBuff2Len, FORCE);
		//长度清零,以便下次接收
		Uart_Drv_data.WriteRingBuff2Len = 0;

		sscanf((char *)packet_tmp,"TTM:%[^\r\n]",ret_tmp);
		my_log("Set Name is : %s\r\n",ret_tmp);
		
	
		if (Strcmp((uint8_t *) ret_tmp, (uint8_t *) "OK", strlen("OK")))
		{
			//读取成功,进入下一个状态前将CNT清零
			BLE_Drv_data.Cnt = 0;
			BLE_Drv_data.substat = BLE_SUBSTAT_QNAME;
		}

	}
	else if (myDelay.waitTime(BLE_Drv_data.Time, BLE_Drv_data.Delay))
	{
		//等待超时,次数增加,若大于限制次数,进行硬件复位
		if (BLE_Drv_data.Cnt ++ > DEFAULT_CNT)
		{
			BLE_Drv_data.Cnt = 0;
			BLE_Drv_data.substat = BLE_SUBSTAT_SWREST;
			my_log("BLE QNAME ERR,Will Reset BLE Modele!\r\n");
		}

		else
		{
			//若没有大于限制次数,重新软件复位
			BLE_Drv_data.substat = BLE_SUBSTAT_SNAME;
			my_log("BLE Reset TimeOut! Current Cnt : %d \r\n",BLE_Drv_data.Cnt);

		}
	}

}
static void BLE_QmacStat(void)
{
	char str[]="TTM:MAC-?";

	my_log("send-> %s\r\n",str);
	Uart_Drv_data.Uart2_sendFun((uint8_t *)&str,strlen(str));

	BLE_Drv_data.Time = myDelay.gettick();
	BLE_Drv_data.Delay = DEFAULT_TIMEOUT;
	BLE_Drv_data.substat = BLE_SUBSTAT_QMACACK;
}

static void BLE_QmacStatACK(void)
{
	uint8_t  packet_tmp[0xFF];
	uint8_t mac_tmp[MAC_STR_LEN];
	uint8_t mac_hex[MAC_STR_LEN];
	if (Uart_Drv_data.WriteRingBuff2Len > 0)
	{
		//检测有数据的时候进行读数据
		my_rb_readbytes(&Uart_Drv_data.Ring2, packet_tmp, Uart_Drv_data.WriteRingBuff2Len, FORCE);
		//长度清零,以便下次接收
		Uart_Drv_data.WriteRingBuff2Len = 0;
		sscanf((char *)packet_tmp,"TTM:MAC-0x%[^\r\n]",mac_tmp);
		str_hex(mac_tmp,mac_hex);
		mac2str(mac_hex,(char *)BLE_Drv_data.mac_str,MAC_STR_LEN);
		my_log("Read BLE MAC is OK! The MAC is : %s\r\n",BLE_Drv_data.mac_str);
		
		//读取成功,进入下一个状态前将CNT清零
		BLE_Drv_data.Cnt = 0;

		//如果是从设备,则直接准备接收数据
		#ifndef HOST
		BLE_Drv_data.stat = BLE_RECV_STAT;

		//如果是主机需要扫描当前广播的从设备
		#else
		BLE_Drv_data.substat = BLE_SUBSTAT_QMODE;
		#endif

	}
	else if (myDelay.waitTime(BLE_Drv_data.Time, BLE_Drv_data.Delay))
	{
		//等待超时,次数增加,若大于限制次数,进行硬件复位
		if (BLE_Drv_data.Cnt ++ > DEFAULT_CNT)
		{
			BLE_Drv_data.Cnt = 0;
			BLE_Drv_data.substat = BLE_SUBSTAT_SWREST;
			my_log("BLE QNAME ERR,Will Reset BLE Modele!\r\n");
		}

		else
		{
			//若没有大于限制次数,重新软件复位
			BLE_Drv_data.substat = BLE_SUBSTAT_QMAC;
			my_log("BLE Reset TimeOut! Current Cnt : %d \r\n",BLE_Drv_data.Cnt);

		}
	}

}

好了,具体介绍就到这里,欢迎大家吐槽,一起进步;
源码下载地址:https://download.csdn.net/download/weixin_41003780/12517892

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HeartRain_大西瓜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值