基于STM32的USART、UART串口命令调制和解析(加密与解密)

2023-05-16

基于STM32的USART、UART串口命令调制和解析(加密与解密)

采用芯片为STM32F407ZG
调制后的命令采用USART1往外发送 发送至USART2
而后USART2接收命令后 进行解析 把命令中有用的部分提取出来 再向外发送控制命令
同时 USART1接收外部命令后 也可以转发给USART2

命令格式为:
起始位 2Byte 0x07 0xCD
数据长度位 2Byte 默认 0x00 0x08
数据流 16Byte 这里是用八个点的坐标值(x,y)来模拟
校验码 2Byte 前20位数据之和
停止位 2Byte 0x04 0xBC

资源:
https://download.csdn.net/download/weixin_53403301/86401762

在解析部分 要从结构体中将坐标提取出来

struct Point_Position{
	uint8_t x;
	uint8_t y;
	uint8_t vx;
	uint8_t vy;
	uint8_t angle;
};

即里面的x y

USART1_RX中断为发送接收的数据
USART2_RX中断为发送解析后的数据

代码如下:

#include "stm32f4xx.h"
#include "DELAY.h"

uint8_t rx_data_buf[24];
uint8_t send_data_buf[]={0,0,0,0,0x00,0x20,0xF8,0x00};
uint8_t usart2_flag=0;
uint8_t begain_data_buf[]={0x5a,0xa5,0x67,0x82,0x54,0x40,0x00,0x05,0x00,0x08};
uint8_t flag=0;
struct Point_Position{
	uint8_t x;
	uint8_t y;
	uint8_t vx;
	uint8_t vy;
	uint8_t angle;
};

struct Point_Position Point[8] = {
	{.x=5,		.y=10,		.vx=0,.vy=0,.angle=0},
	{.x=8,		.y=7,		.vx=0,.vy=0,.angle=0},
	{.x=14,		.y=9,		.vx=0,.vy=0,.angle=0},
	{.x=9,		.y=13,	.vx=0,.vy=0,.angle=0},
	{.x=25,		.y=23,		.vx=0,.vy=0,.angle=0},
	{.x=7,		.y=15,	.vx=0,.vy=0,.angle=0},
	{.x=12,	.y=22,	.vx=0,.vy=0,.angle=0},
	{.x=15,	.y=12,	.vx=0,.vy=0,.angle=0}
};

void init_USART1(uint32_t Baud)
{
	//定义GPIO结构体
	GPIO_InitTypeDef GPIO_KEEY_InitStruct;
	//使能GPIOF时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	//初始化结构体
	GPIO_KEEY_InitStruct.GPIO_Pin  = GPIO_Pin_9 | GPIO_Pin_10; //定义引脚
	GPIO_KEEY_InitStruct.GPIO_Mode = GPIO_Mode_AF;  //定义输出模式
	GPIO_KEEY_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;	//定义速度
	GPIO_KEEY_InitStruct.GPIO_OType = GPIO_OType_PP;		//定义推挽输出
	GPIO_KEEY_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;		//定义是否有上下拉电阻 普通
	//将结构体给GPIOF组
	GPIO_Init(GPIOA,&GPIO_KEEY_InitStruct);
	
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_USART1);  //复用功能
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_USART1);  //复用功能
	
	USART_InitTypeDef USART_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	//配置串口
	USART_InitStructure.USART_BaudRate = Baud;  //波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;  //8位数据位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;  //1个停止位
  USART_InitStructure.USART_Parity = USART_Parity_No;  //无校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  //无硬件流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  //支持收发数据
	USART_Init(USART1, &USART_InitStructure);
	//中断方式
	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);  //使能RX

	//中断优先级
	NVIC_InitTypeDef NVIC_InitStructure;
 
   /* Enable the USARTx Interrupt */
	NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	//使能串口
	USART_Cmd(USART1, ENABLE);
}

void init_USART2(uint32_t Baud)
{
	//定义GPIO结构体
	GPIO_InitTypeDef GPIO_KEEY_InitStruct;
	//使能GPIOF时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	//初始化结构体
	GPIO_KEEY_InitStruct.GPIO_Pin  = GPIO_Pin_2 | GPIO_Pin_3; //定义引脚
	GPIO_KEEY_InitStruct.GPIO_Mode = GPIO_Mode_AF;  //定义输出模式
	GPIO_KEEY_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;	//定义速度
	GPIO_KEEY_InitStruct.GPIO_OType = GPIO_OType_PP;		//定义推挽输出
	GPIO_KEEY_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;		//定义是否有上下拉电阻 普通
	//将结构体给GPIOF组
	GPIO_Init(GPIOA,&GPIO_KEEY_InitStruct);
	
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource2, GPIO_AF_USART2);  //复用功能
	GPIO_PinAFConfig(GPIOA, GPIO_PinSource3, GPIO_AF_USART2);  //复用功能
	
	USART_InitTypeDef USART_InitStructure;
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
	//配置串口
	USART_InitStructure.USART_BaudRate = Baud;  //波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;  //8位数据位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;  //1个停止位
  USART_InitStructure.USART_Parity = USART_Parity_No;  //无校验位
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  //无硬件流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;  //支持收发数据
	USART_Init(USART2, &USART_InitStructure);
	//中断方式
	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);  //使能RX

	//中断优先级
	NVIC_InitTypeDef NVIC_InitStructure;
 
   /* Enable the USARTx Interrupt */
	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init(&NVIC_InitStructure);
	//使能串口
	USART_Cmd(USART2, ENABLE);
}

int main(void)
{
	init_USART1(115200);
	init_USART2(115200);
	USART_Cmd(USART2, DISABLE);
	uint8_t data_buf[24];
	uint16_t check_sum=0;
	uint8_t i=0;
	data_buf[0]=0x07;
	data_buf[1]=0xCD;
	data_buf[2]=0x00;
	data_buf[3]=0x08;
	data_buf[22]=0x04;
	data_buf[23]=0xBC;
	for(i=0;i<8;i++)
	{
		data_buf[4+i*2]=Point[i].x;
		data_buf[5+i*2]=Point[i].y;
	}
	for(i=0;i<20;i++)
	{
		check_sum = data_buf[i] + check_sum;
	}
	data_buf[20] = ((check_sum>>8)&0x00FF)&0xFF;
	data_buf[21] = ((check_sum>>0)&0x00FF)&0xFF;
	while(1)
	{
		USART_Cmd(USART2, ENABLE);
		for(i=0;i<24;i++)
		{
			flag=1;
			char DATA1=data_buf[i];
			USART_SendData(USART1,DATA1);
			while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);	
			while(flag);
		}	
		delay_ms(500);
		USART_Cmd(USART2, DISABLE);
		delay_ms(500);
	}
}

//串口1中断服务函数
void USART1_IRQHandler(void) 
{
	if(USART_GetITStatus(USART1,USART_IT_RXNE)==SET)
	{	
		char data = USART_ReceiveData(USART1);
		USART_SendData(USART1,data);
		USART_ClearITPendingBit(USART1,USART_IT_RXNE);//清空标志位
	}
}

void USART2_IRQHandler(void) 
{
	uint8_t k=0;
	uint8_t j=0;
	if(USART_GetITStatus(USART2,USART_IT_RXNE)==SET)
	{	
		flag=0;
		char DATA2=USART_ReceiveData(USART2);
		rx_data_buf[usart2_flag]=DATA2;
		usart2_flag++;
		if (usart2_flag==24)
		{
			usart2_flag=0;
			if(rx_data_buf[0]==0x07 && rx_data_buf[1]==0xCD && rx_data_buf[22]==0x04 && rx_data_buf[23]==0xBC )
			{
				for(k=0;k<10;k++)
				{
					USART_SendData(USART2,begain_data_buf[k]);
					while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
				}
				for(k=0;k<8;k++)
				{
					send_data_buf[1]=rx_data_buf[4+2*k];
					send_data_buf[3]=rx_data_buf[5+2*k];
					for(j=0;j<8;j++)
					{
						USART_SendData(USART2,send_data_buf[j]);
						while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
			//			USART_ClearITPendingBit(USART2,USART_IT_RXNE);//清空标志位
					}
				}
				USART_SendData(USART2,0xFF);
				while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
				USART_SendData(USART2,0x00);
				while(USART_GetFlagStatus(USART2,USART_FLAG_TXE)==RESET);
			}
		}
		USART_ClearITPendingBit(USART2,USART_IT_RXNE);//清空标志位
	}
}


在USART2中断中 值判断了起始位和停止位 没有判断数据长度和校验码 如果加上判断 可以更加精确

全局变量flag 是对时序用的 如果USART1用另外一个mcu来发送的话 则可以发出一个使能信号CS 来对时序

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

基于STM32的USART、UART串口命令调制和解析(加密与解密) 的相关文章

  • 前端浏览器渲染原理及优化

    文章目录 一 浏览器组成1 对浏览器内核的理解2 浏览器的主要组成部分 二 浏览器渲染原理1 浏览器的渲染过程步骤一 xff1a 步骤二 xff1a 步骤三 xff1a 步骤四 xff1a 步骤五 xff1a 2 相关概念 重排 更新元素的
  • Docker+github actions部署前端项目

    Docker 43 github actions部署前端项目 文章目录 Docker 43 github actions部署前端项目前言1 Docker相关文件配置2 创建自己的dokcer hub仓库3 yml文件配置 前言 在进行本篇实
  • pytorch可视化之:可视化网络结构+CNN可视化+TensorBorad使用

    Pytorch学习第五部分 xff1a pytorch可视化 Let 39 s go 一 可视化网络结构1 1 Resnet18结构1 2 使用torchinfo可视化网络结构1 2 1 torchinfo安装1 2 2 torchinfo
  • spring中用到的设计模式及应用场景

    spring中用到的设计模式及应用场景 1 工厂模式 xff1a 在Beanfactory和applicationContext创建中都用到了 2 单例模式 xff1a Bean默认就是单例模式 单例模式只允许创建一个对象 xff0c 获取
  • python架构之Django学习------流程总结

    python架构之Django学习 一 二 三 开发流程 xff1a step1 创建虚拟环境 mkvirtrualenv step2 安装django pip install django step3 创建项目 python manage
  • PDU 发送短信3

    T指令收发短信主要有两种模式 xff1a Text模式和PDU xff08 Protocol Data Unit xff0c 协议数据单元 xff09 模式 使用Text模式收发短信代码简单 xff0c 很容易实现 xff0c 最大缺点不支
  • Linux驱动---休眠与唤醒

    Linux 休眠与唤醒 文章目录 Linux 休眠与唤醒前言一 休眠 唤醒 机制二 重要的函数及其数据结构wait内核函数唤醒函数 三 驱动编程步骤附录 xff08 源码 xff09 前言 当应用程序必须等待某个时间发生 xff0c 比如必
  • 序列化Writable接口

    基本序列化类型往往不能满足所有需求 xff0c 比如在Hadoop框架内部传递一个自定义bean对象 xff0c 那么该对象就需要实现Writable序列化接口 实现Writable序列化步骤如下 xff08 1 xff09 必须实现Wri
  • MapReduce读取数据

    1 InputFormat 运行MapReduce程序时 xff0c 输入的文件格式包括 基于行的日志文件 二进制格式文件 数据库表等 那么 xff0c 针对不同的数据类型 xff0c MapReduce是如何读取这些数据的呢 InputF
  • Git的安装与配置,VScode如何连接Gitee?

    什么是gitee 要学gitee 你首先得知道gitee是什么 而且你得知道它的好处 首先它是国内最大的代码托管平台 国外GitHub的弟弟 然后 它能帮你 管理 昨天和今天 改动的文件 xff0c 还给你做 备份 xff1b 它能管理让你
  • 下载并使用Maven创建运行项目(配置Maven、tomcat、含idea实例)【精细教程】

    前言 xff08 重点 xff01 xff01 xff09 xff1a 很多人在安装好maven后 xff0c 遇到idea与maven版本不匹配的问题 xff0c 首先要根据自己的idea版本来选择maven版本 xff01 IDEA 2
  • 将本地项目commit到gitee上

    在新建的项目路径中 xff0c shift 43 右键 xff0c 打开powershell窗口 查看状态 xff1a git status 再执行 xff1a git add git commit m 34 add files 34 再次
  • docker搭建私有仓库

    一 宿主机安装 1 extras源中下载安装distributon包 编写源 extras name 61 extra baseurl 61 https mirrors aliyun com centos vault 7 9 2009 ex
  • HBase-API

    目录 引入的依赖 创建连接 命名空间 表 引入的依赖 lt dependencies gt lt dependency gt lt groupId gt org apache hbase lt groupId gt lt artifactI
  • 【嵌入式算法】学习笔记(一):数字滤波算法

    文章目录 摘要一 数字滤波简介二 常用数字滤波算法1 限幅滤波2 中值滤波3 算术平均滤波4 去极值平均滤波5 滑动平均滤波6 滑动加权滤波7 一阶滞后滤波 三 数字滤波小结 摘要 最近在做直流电机的毕设中 xff0c 由于需要采集转速 x
  • python架构之Django学习------mysql使用

    学习环境 xff1a ubuntu16 0 4 一 安装python包 pip install mysql python 二 使用mysql mysql uroot p show databases drop database test1
  • C语言经典面试题10道(五)

    41 什么是预编译 xff0c 何时需要预编译 xff1f 答案 xff1a xff11 总是使用不经常改动的大型代码体 xff12 程序由多个模块组成 xff0c 所有模块都使用一组标准的包含文件和相同的编译选项 在这种情况下 xff0c
  • ROS环境下的串口通讯

    目录 1 前言 2 内容 2 1 准备工作 2 1 1 连接外部USB设备 2 1 2 串口调试工具的下载 2 1 3 serial库的安装 2 2 代码部分 2 2 1 编写发布节点 2 2 2 编写发布节点 2 2 3 编辑checkl
  • 【线性控制理论】状态观测器—开环形式的状态观测器

    文章目录 前言一 开环形式的状态观测器 前言 在线性系统的各种综合问题中状态反馈展现了其优越性 xff0c 不管是系统的极点配置 xff0c 镇定以及解耦控制 xff0c 都有赖于引入适当的状态反馈才能实现 但是在状态反馈时 xff0c 我
  • 【状态观测器】全维状态观测器

    文章目录 前言一 全维状态观测器 前言 本文主要提到的是闭环形式状态观测器中的全维状态观测器 xff0c 建议有时间可以阅读上一篇开环形式的状态观测器 篇幅不长 以理解状态观测器 一 全维状态观测器 全维状态观测器是闭环状态观测器的一种 还

随机推荐

  • Linux 安装zsh和zsh的配置

    1 在安装之前 xff0c 需要了解一些自己的shell是什么 命令 xff1a echo SHELL 这里是bash shell环境 2 安装zsh 输入命令 xff1a sudo pacman S zsh 直接安装zsh 3 安装zsh
  • Linux 对整个系统备份和还原

    对系统进行备份非常的重要 xff0c 如果有一天 xff0c 系统崩溃了 xff0c 可以重装系统 xff0c 但是重装系统后又需要进行相关的配置 xff0c 这会显得非常的麻烦 xff0c 又会浪费很多的时间 备份的方式 xff1a 分两
  • 计算机网络地址划分及子网掩码计算

    一 点分十进制记法 8 位的二进制数 转为 十进制数 注意 xff1a 1 与有分类的ip地址的区别 这里的 n 不是固定的数 是可以在0 32位之间任意的 xff0c 所以 CIDR 斜线记法 xff1a IP地址后面加上 斜线后面的是网
  • axios简介

    Axios 对原生的 AJAX 进行封装 xff0c 简化书写 get请求如下 xff1a xff08 get请求地址栏传参 xff09 axios method 34 get 34 url 34 http localhost 8080 a
  • 安装OpenCV、cython、numpy和h5py

    安装OpenCV xff1a 一 系统烧录 Raspberry Pi Imager 烧录步骤 xff1a 软件下载地址 xff1a Raspberry Pi OS Raspberry Pi xff08 建议提前准备一张容量在8G以上的SD卡
  • 优秀!他历时三个月终于拿到阿里offer,在这里分享一下阿里的社招面经!

    前言 这也是我第二次进入三面了 xff0c 也不知道这次能不能进呢 xff1f 球球阿里爸爸了 xff0c 许愿一个 hr 面可以吗 xff1f wwwww 本人双非本科大三 xff0c 基础不强 xff0c 有一个简单的秒杀项目 xff0
  • wireshark-----过滤使用方法

    1 ip过滤 ip addr 61 61 10 239 4 160
  • MySQL数据库安装步骤及报错1251解决方法

    MySQL数据库安装 MySQL是一种关系数据库管理系统 xff0c 所使用的 SQL 语言是用于访问数据库的最常用的标准化语言 xff0c 其特点为体积小 速度快 总体拥有成本低 xff0c 尤其是开放源码这一特点 xff0c 在 Web
  • Docker 安装问题

    Docker 安装问题 出现了Failed to start docker service Unit docker service not found 这个图在图上的链接处拿的 xff0c 我自己之前出现的错误图找不到了 这个错误 xff0
  • vscode配置ros开发环境

    前言 xff1a 其实有两种方法来配置vscode里的ros环境 xff0c 第一种就是先通过终端创建工作空间 xff0c 并编译后然后选择vscode打开catkin ws xff0c 然后在vscode中配置ros的编译环境 xff1b
  • 判断IP地址是否在同一个网段

    一 什么是子网掩码 xff1f 在了解ip地址的网段之前 xff0c 我们先来了解子网掩码 xff0c 很多对网络了解不深的朋友都对子网掩码有些迷惑 xff0c 不了解它是用来干什么的 xff1f 子网掩码不能单独存在 xff0c 它必须结
  • 理解MySQL七种连接

    如上图是MySQL的七种连接 由于MySQ对于外连接支持SQL99语法 xff0c 我们就以JOIN ON举例 表t dept 表t emp 1 内连接 xff1a A表 xff0c B表交叉的部分 SELECT FROM t dept d
  • IP地址的分类和规划

    每日分享 xff1a 你拼命奔跑的样子 xff0c 终究会在风中留下痕迹 xff01 文章目录 一 IP地址的格式二 私有IP地址三 IP地址分类 xff1a 四 子网掩码五 IP地址的规划 一 IP地址的格式 1 主机唯一的标识 xff0
  • QT5+TCP/IP多线程传输图片

    先上实现结果 一 概述 QT中设计TCP IP通信主要使用QTCPServer和QTCPSocket两个类 xff0c 功能分为服务器端和客户端 xff0c 服务器端负责接收图片 xff0c 客户端发送图片 多线程设计主要有两种方法 xff
  • ubuntu建立新用户

    1 新建testuser用户 sudo adduser testuser 2 设置root密码 sudo passwd root 3 更改sudoers编辑权限 sudo chmod u 43 w etc sudoers 4 给testus
  • Error: Flash Download failed - “Cortex-M3“错误解决办法

    在使用STM32F103的时候 xff0c 使用DAP仿真器下载程序 xff0c 出现下载不了的情况 xff0c 错误信息如下 xff1a 输出框里打印信息如下 xff1a No Algorithm found for 08000000H
  • 浏览器自定义滚动条样式

    当一段文本过长 xff0c 使用overflow auto属性后 xff0c 这段文本所在区域将会出现滚动条 有时候 xff0c 我们需要自定义浏览器的滚动条样式 xff0c 可以使用css3的scrollbar thumb属性来实现 首先
  • linux rpm安装讲解

    1 安装rpm安装包 rpm ivh rpm 2 删除rpm安装包 rpm evv rpm 注意 xff1a 使用 e不能完全删除
  • Linux多进程/线程编程之【fork()和exec()】

    目录 一 fork系统调用创建子进程 1 1 为什么要创建子进程 1 2 fork系统调用的内部原理 1 3 关于子进程 1 4 线程和fork 二 exec族函数及实战 2 1 为什么需要exec族函数 2 2 exec族的6个函数介绍
  • 基于STM32的USART、UART串口命令调制和解析(加密与解密)

    基于STM32的USART UART串口命令调制和解析 xff08 加密与解密 xff09 采用芯片为STM32F407ZG 调制后的命令采用USART1往外发送 发送至USART2 而后USART2接收命令后 进行解析 把命令中有用的部分