上位机图像处理和嵌入式模块部署(mcu项目1:实现协议)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

这种mcu的嵌入式模块理论上都是私有协议,因为上位机和下位机都是自己开发的,所以只需要自己保证上、下位机可以通讯上,没有问题就行。但是现在有一个情况,那就是如何实现这个协议。现在我们是选择了ttl作为通信的方式,下面要做的就是如何用ttl实现通信协议。

1、上、下位机分开测试

前面准备好了通信的协议,各自就可以独立开发了。上位机可以用利用虚拟com进行测试,自己写一个假的下位机。而下位机呢,则可以通过串口工具来进行测试。一般来说,下位机如果测试没有问题了,才会去找上位机进行联合调试,不然调试的效率就太低了。

对于下位机来说,只要串口工具ok了,那么上位机不管是qt,还是mfc、c# wpf,只要按照协议把数据发下来,那就应该没问题的。

2、调试的时候一般都是通过16进制调试的

通常来说,发送的协议就是8位无符号数据,不是字符串。所以这个时候调试的时候,不管是接收命令,还是发送命令,最好都是通过16进制进行调试。

3、上位机一般是主动的那一方

通常来说,上位机都是主动的那一方。不管是去读数据,还是写数据,上位机都是主动发起请求的一方。这个时候,对于下位机来说,回复好上位机的问题,给出相应的答案就可以了。

4、压力测试是一定要的

协议解析的过程有可能出现不对的地方,这是很常见的。而且,随着开发的进行,有可能添加各种不同样的协议内容。所以不管哪一种协议,我们在实现和验证的时候,一定要进行压力测试,即通过串口工具周期性发送一些命令,这些都是可以的。单挑发送、多条发送、随机发送,一般的上位机工具都会支持这样的测试。

5、使用fsm去解析协议

串口的属性,决定了我们是一个、一个去接收数据的。这个时候就要求我们,需要根据这些单个的数据来判断它是否符合协议的要求。要做到这一点,最好的方法就是用有限状态机fsm去实现。比如说,首先是什么状态,接收到一个数据,应该是什么状态,是继续维持,还是说继续走向下一个状态。一般来说,只要状态机设计好,基本上固件都是非常稳定的。

复制代码
void receiveUartData(void) // receive data and parse data here
{
	    int index = 0;

        if (USART_ReadIntFlag(USART_UX, USART_INT_RXBNE) == SET)
		{
                g_rx_buffer[0] = USART_RxData(USART_UX);    /* receive one byte data*/

				switch(uartState)
				{
					case HEAD_STATE1: // wait 0x55
						if(g_rx_buffer[0] == 0x55)
						{
							g_usart_rx_buf[0] = g_rx_buffer[0];
							g_usart_rx_sta ++;
							uartState = HEAD_STATE2;
						}
						else
						{
							g_usart_rx_sta = 0;
						}
						break;

					case HEAD_STATE2: // wait another 0x55
						if(g_rx_buffer[0] == 0x55)
						{
							g_usart_rx_buf[1] = g_rx_buffer[0];
							g_usart_rx_sta ++;
							uartState = TAIL_STATE1;
						}
						else
						{
							g_usart_rx_sta = 0;
							uartState = HEAD_STATE1;
						}
						break;

					case TAIL_STATE1: // wait 0xaa
					  if(g_usart_rx_sta >= 32)
                        {
							g_usart_rx_sta = 0;
							uartState = HEAD_STATE1;
							break;
						}

						g_usart_rx_buf[g_usart_rx_sta] = g_rx_buffer[0];
						g_usart_rx_sta ++;

						if(g_rx_buffer[0] == 0xaa)
						{
							uartState = TAIL_STATE2;
						}
						break;

					case TAIL_STATE2: // wait another 0xaa
						g_usart_rx_buf[g_usart_rx_sta] = g_rx_buffer[0];
						g_usart_rx_sta ++;

						if(g_rx_buffer[0] == 0xaa && useFlag == 0) /* if useFlag = 0 or not qualified data, just drop it directly*/
						{
							for(index = 0; index < g_usart_rx_sta; index++)
							{
								transferBuf[index] = g_usart_rx_buf[index];
							}
							bufLen = g_usart_rx_sta;
							useFlag = 1;
						}

						g_usart_rx_sta = 0;
						uartState = HEAD_STATE1;
						break;

					default:
						break;
				}

                USART_ClearIntFlag(USART_UX, USART_INT_RXBNE);
      }
}

6、协议的处理可以放到main里面继续进行

中断部分只是负责数据的接收,具体命令的解析可以放到main函数里面继续执行。毕竟接收数据本身是在中断函数处理的,这部分花的时间越少越好。而具体的数据解析,实时性没那么高,慢一点都是没有关系的。

复制代码
extern uint16_t voltage; // add by feixiaoxing
int parseData() // use app tool to test the data
{
	    unsigned char str[32] = {0};
		if(useFlag == 0)
		{
			return -1;
		}
	
		if(0 == bufLen)
		{
			setFlag();
			return -1;
		}
		
		if(bufLen < 4)
		{
			setFlag();
			return -1;
		}
		
		if(transferBuf[0] != 0x55 || transferBuf[1] != 0x55)
		{
			setFlag();
			return -1;
		}
		
		if(transferBuf[bufLen-2] != 0xaa || transferBuf[bufLen-1] != 0xaa)
		{
			setFlag();
			return -1;
		}
		
		if(bufLen != 10) // header + length + commandid + crc + tail
		{
			setFlag();
			return -1;
		}
		
		// restore flag
		setFlag();
		
		// prepare data
		str[ 0] = 0x55; // header
		str[ 1] = 0x55;
		str[ 2] = 0x00; // length
		str[ 3] = 0x08;
		str[ 4] = 0x00; // command id;
		str[ 5] = 0x00;
		str[ 6] = voltage / 1000; // data
		str[ 7] = voltage % 1000;
		str[ 8] = 0x00; // crc
		str[ 9] = 0x00;
		str[10] = 0xaa; // tail
		str[11] = 0xaa;
		outputData((char*)str, 12);
		return 0;
}
相关推荐
国科安芯3 小时前
立方星与微纳卫星综合电子微型化趋势下的抗辐射MCU选型综述
人工智能·单片机·嵌入式硬件·mcu·risc-v·抗辐射
xunyan62343 小时前
3-1 独立按键控制LED亮灭(SDCC + Notepad++ + STC-ISP/普中ISP)
单片机·嵌入式硬件·接口隔离原则
WD137298015574 小时前
WD5030L,为充电桩、工业设备、5G 基站、车载系统、消费电子提供电源,7-30V 的宽压输入
stm32·单片机·嵌入式硬件·5g·车载系统·51单片机
创界工坊工作室6 小时前
30-基于STM32的小麦烘干塔温度控制系统设计
stm32·单片机·嵌入式硬件·proteus
Zwawa7 小时前
先把轮子转稳,才不会烧心:编码器速度环 PID 怎么接回 PWM
c语言·单片机·嵌入式
单片机仿真设计7 小时前
【proteus仿真设计】基于 STM32 的开荒机器人遥控控制系统设计(仿真图+程序)
stm32·嵌入式硬件·机器人·proteus
smartpi_ai7 小时前
51 单片机写好了,大模型语音怎么接?17T 全驱动的现成方案、双板串口分工的边界与画板前的三项硬件确认
单片机·嵌入式硬件·学习
我先去打把游戏先8 小时前
NimBLE是什么-ESP32蓝牙协议栈详解
单片机·嵌入式硬件·ubuntu
木子n19 小时前
车载以太网与SOME/IP服务化通信实战-02.状态机与订阅:SOME/IP-SD的三态迁移、重传账与上电风暴
嵌入式硬件·网络协议·车载系统·车载以太网·some/ip
Gongsion9 小时前
30V输入耐压|1.5μA超低静态电流|200mA输出,CSM52系列:线性稳压器LDO,12V母线转3.3V/5V传感器、MCU弱电支路可靠稳压方案
单片机·嵌入式硬件·车载系统·无人机·智能家居