一个简单的基础通信协议的设计与实现


不同设备之间的通信,都需要设计自己的通信协议。为了保证设备与设备之间的数据的稳定传输,通信协议的设计需要考虑很多的问题。当然应对不同的应用场景,可以有针对性的设计不同的通信协议。

一种常见的通信协议格式

这是一种我们比较常见的通信协议格式

帧头 地址位 功能位 帧序号 数据长度 数据内容 校验位 帧尾
1/2字节 1字节 1字节 2字节 2字节 n字节 1/2字节 1/2字节

而为了应对不同的情况,可以依照情况做删改,例如减少帧头和帧尾,减少帧序号等等。

而本篇实现的通信协议如下,这里将几个部分都做了,实际中可能并不需要这么冗余的帧,可以按需求适当删改:

地址位 功能位 帧序号 数据长度 数据内容 校验位
1字节 1字节 1字节 1字节 n字节 1字节

本篇例程使用的开发板是STM32F103VET6,应用工具是MDK-ARM v5.33STM32CubeMX V6.1.1
注:STM32CubeMX需要安装JAVA环境(JRE)

搭建串口收发环境

参考:https://blog.csdn.net/u014470361/article/details/79206352#comments
使用串口1,DMA方式收发数据

注:DMA,全称为:Direct Memory Access,即直接存储器访问。DMA 传输方式无需 CPU 直接控制传输,也没有中断处理方式那样保留现场和恢复现场的过程,通过硬件为 RAM 与 I/O 设备开辟一条直接传送数据的通路,能使 CPU 的效率大为提高。

配置STM32CubeMX

打开STM32CubeMX,File->New Project->Start Project

20210130162818-2021-01-30

RCC->打开外部时钟

20210130162940-2021-01-30

USART1->Asynchronous 异步通信

20210130163105-2021-01-30

下面NVIC Settings->Enabled 使能串口中断

20210130163235-2021-01-30

还是下面DMA Setthing->ADD->USART1_RX/USART_TX->Priority 使能DMA收发模式,高优先级

20210130163530-2021-01-30

SYS->Dubug-Serial Wire 启用调试引脚,因为我使用ST-Link进行调试,不使能调试引脚的话没法调试。

20210130163854-2021-01-30

上面的Clock Configuration时钟配置可以忽略,使用默认8MHz即可,然后是第三个选项Project Manager->Project Name设置工程名->Project Location设置工程路径,然后选择IDE->MDK-ARM
注意工程名和路径都不要出现中文字符

20210130164447-2021-01-30

最后点击GENERATE CODE生成工程文件,如果失败的话,可以尝试更换JAVA环境。

添加USART部分代码

在main.h宏定义一个最大接收字节数1024

#define UART_RX_LEN 1024

打开工程,并在main.c中添加部分代码

定义接收数组,接收数据长度以及标识。UART_RX_STA的0-14位存储数据长度,第15位表示接收状态。

  /* USER CODE BEGIN PV */
  uint8_t UART_RX_BUF[UART_RX_LEN];
  __IO uint16_t UART_RX_STA;
  /* USER CODE END PV */

注意位置DMA初始化需在MX_USART1_UART_Init();串口初始化之后。

  /* USER CODE BEGIN 2 */
  HAL_UART_Receive_DMA(&huart1, UART_RX_BUF, UART_RX_LEN);  // 启动DMA接收
  __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);              // 使能空闲中断
  /* USER CODE END 2 */

在while循环中添加DMA发送指令,将接收到的数据发送回去

if(UART_RX_STA & 0X8000)
{
   
  HAL_UART_Transmit_DMA(&huart1, UART_RX_BUF, UART_RX_STA & 0X7FFF);    // 将接收到的数据发送回去
  UART_RX_STA = 0;
}
/* USER CODE END WHILE */

打开stm32f1xx_it.c文件添加代码

/* USER CODE BEGIN PD */
extern uint8_t UART_RX_BUF[UART_RX_LEN];
extern __IO uint16_t UART_RX_STA;
/* USER CODE END PD */

拉到底,找到USART1中断。修改如下

void USART1_IRQHandler(void)
{
   
  /* USER CODE BEGIN USART1_IRQn 0 */
    if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET&&(UART_RX_STA&0x8000==0))  // 空闲中断标记被置位,并且拆包完成
    {
   
      __HAL_UART_CLEAR_IDLEFLAG(&huart1);  // 清楚中断标记
      HAL_UART_DMAStop(&huart1);           // 停止DMA接收
      UART_RX_STA = UART_RX_LEN - __HAL_DMA_GET_COUNTER(huart1.hdmarx);  // 总数据量减去未接收到的数据量为已经接收到的数据量
      UART_RX_BUF[UART_RX_STA] = 0;  // 添加结束符
      UART_RX_STA |= 0X8000;         // 标记接收结束
      HAL_UART_Receive_DMA(&huart1
  • 12
    点赞
  • 94
    收藏
    觉得还不错? 一键收藏
  • 12
    评论
### 回答1: 充电桩与有序充电模块的通信协议是指在电动汽车充电过程中,充电桩与有序充电模块之间的通信规则和数据交换方式。为了确保设备之间的互操作性和通信的稳定性,通信协议实现至关重要。 C语言是一种比较高效的编译型编程语言,具有强大的处理能力和广泛的应用领域。因此,使用C语言来实现充电桩与有序充电模块的通信协议,也是一种可行的选择。 具体实现过程需要根据通信协议的具体规范进行开发。一般而言,需要定义通信协议的数据格式、命令指令以及通信过程中的错误处理等方面的内容。 此外,为了确保通信过程的稳定性和安全性,还需要对通信数据进行校验和加密处理。针对这些需求,C语言中提供了多种加密和校验函数,可以根据实际需要进行选择和调用。 综上所述,使用C语言实现充电桩与有序充电模块的通信协议需要进行详细的规范设计和开发工作,涉及到的领域较为广泛。只有在严格遵守规范和设计原则的基础上,才能保证通信协议的高效性和稳定性。 ### 回答2: 充电桩与有序充电模块的通信协议是一种重要的通信方式,这需要有一定的编程实现技巧,下面对该通信协议的 C 语言实现做出如下解释。 通信协议中的数据包结构通常是由头部和数据体两部分组成,C 语言中可以将其定义为结构体,即: typedef struct { unsigned char head; // 头部内容 unsigned char data[]; // 数据体内容,可以是可变长度的数组 } CommPacket; 通信协议中需要有标识符,以告诉接收方发送的数据包属于何种类型。比如可以在头部中定义一个标识符(Command ID),告诉接收方这是一条控制命令还是一条状态信息。 为了保证通信协议中的数据完整性,在数据包传输过程中应当包含一定的校验位。通常使用 CRC 校验或者奇偶校验来检测数据传输过程中的出错情况。 在实现通信协议时,需要定义发送数据包和接收数据包的函数。在发送数据包的函数中,需要将待发送的数据包按照协议格式进行打包,并调用串口发送函数进行数据传输。在接收数据包的函数中,需要检测数据包是否符合协议格式,并进行校验,以确保数据传输的完整性。 总之,实现充电桩与有序充电模块的通信协议需要考虑数据包的结构、标识符、校验等因素,并通过定义发送、接收函数来实现协议。 ### 回答3: 充电桩是新能源汽车的重要充电设施,而有序充电模块则是为了使充电桩变得更加智能化、高效化而开发出的通信协议通信协议是基于现有的充电桩和有序充电模块两者之间的通信规范。可以说,通信协议实现充电桩与有序充电模块之间信息交换和数据传输的重要基础。 为实现通信协议的功能,需编写相应的C语言程序代码。其编写过程包括了多种要素,如通信协议的数据字段、数据传输方式、数据校验等。C语言程序的核心目标是将数据传输的规范转化为具体的充电桩和有序充电模块之间的通信实现。 在开发充电桩与有序充电模块之间的通信协议时,需要考虑到诸多技术问题。例如,需要确定通信协议中的各种数据类型、数据传输过程中采用的计算方式和校验方法等。同时,还需要设计错误处理方式,以确保在通信过程中出错时,也能及时地进行数据重发或者其他方式的处理。 在C语言程序实现通信协议的过程中,需要注意遵循软件开发规范和代码编写规范。尽管C语言程序本身的开发难度较高,但只要在规范、标准和最佳实践方面下功夫,就可以成功地开发出高质量的通信协议

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值