上位机图像处理和嵌入式模块部署(h750 mcu串口命令处理)

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

        前面学习103和407的时候,当时学过串口的收发。不过当时使用的主要是阻塞的方式。这一次,我们看下应该怎么利用中断的形式进行数据的收发。不仅如此,我们还可以看下,怎么把收到的数据放在一起,当成一个完整的命令去处理。

1、基本串口信息定义

        这边的串口主要还是利用a9、a10来实现数据的收发,其中a9负责数据的发送,a10负责数据的接收。除此之外,数据是采用中断的形式进行处理的。

#define DEBUG_USART                             USART1
#define DEBUG_USART_CLK_ENABLE()                __USART1_CLK_ENABLE();

#define DEBUG_USART_RX_GPIO_PORT                GPIOA
#define DEBUG_USART_RX_GPIO_CLK_ENABLE()        __HAL_RCC_GPIOA_CLK_ENABLE()
#define DEBUG_USART_RX_PIN                      GPIO_PIN_10
#define DEBUG_USART_RX_AF                       GPIO_AF7_USART1


#define DEBUG_USART_TX_GPIO_PORT                GPIOA
#define DEBUG_USART_TX_GPIO_CLK_ENABLE()        __HAL_RCC_GPIOA_CLK_ENABLE()
#define DEBUG_USART_TX_PIN                      GPIO_PIN_9
#define DEBUG_USART_TX_AF                       GPIO_AF7_USART1

#define DEBUG_USART_IRQHandler                  USART1_IRQHandler
#define DEBUG_USART_IRQ                 		USART1_IRQn

2、串口的初始化

        串口的初始化这边基本上就是八股文,基本上按照套路下就可以了。一般就是配置时钟、配置gpio、配置uart、配置中断。对于我们来说,最重要的baudrate,也就是波特率,就是在这里配置的。

void DEBUG_USART_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    RCC_PeriphCLKInitTypeDef RCC_PeriphClkInit;
        
    DEBUG_USART_RX_GPIO_CLK_ENABLE();
    DEBUG_USART_TX_GPIO_CLK_ENABLE();
    
	RCC_PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
	RCC_PeriphClkInit.Usart16ClockSelection = RCC_USART16CLKSOURCE_D2PCLK2;
	HAL_RCCEx_PeriphCLKConfig(&RCC_PeriphClkInit);

    DEBUG_USART_CLK_ENABLE();

    GPIO_InitStruct.Pin = DEBUG_USART_TX_PIN;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = DEBUG_USART_TX_AF;
    HAL_GPIO_Init(DEBUG_USART_TX_GPIO_PORT, &GPIO_InitStruct);
    

    GPIO_InitStruct.Pin = DEBUG_USART_RX_PIN;
    GPIO_InitStruct.Alternate = DEBUG_USART_RX_AF;
    HAL_GPIO_Init(DEBUG_USART_RX_GPIO_PORT, &GPIO_InitStruct); 
    
    UartHandle.Instance = DEBUG_USART;
    UartHandle.Init.BaudRate = 115200;
    UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
    UartHandle.Init.StopBits = UART_STOPBITS_1;
    UartHandle.Init.Parity = UART_PARITY_NONE;
    UartHandle.Init.Mode = UART_MODE_TX_RX;
    UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
    UartHandle.Init.OneBitSampling = UART_ONEBIT_SAMPLING_DISABLED;
    UartHandle.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
    HAL_UART_Init(&UartHandle);

    HAL_NVIC_SetPriority(DEBUG_USART_IRQ, 0, 0);
    HAL_NVIC_EnableIRQ(DEBUG_USART_IRQ);

    __HAL_UART_ENABLE_IT(&UartHandle,UART_IT_RXNE);  
}

3、函数重定向

        对于喜欢用getchar、printf进行数据收发的同学,一般还需要实现一下fputc、fgetc这两个函数。实现了这两个函数,后续就可以使用getchar和printf了。

void Usart_SendString(uint8_t *str)
{
	unsigned int k=0;
    do 
    {
        HAL_UART_Transmit( &UartHandle,(uint8_t *)(str + k) ,1,1000);
        k++;

    } while(*(str + k)!='\0');
  
}

int fputc(int ch, FILE *f)
{
	HAL_UART_Transmit(&UartHandle, (uint8_t *)&ch, 1, 1000);	
	
	return (ch);
}


int fgetc(FILE *f)
{	
	int ch;
	HAL_UART_Receive(&UartHandle, (uint8_t *)&ch, 1, 1000);	
	return (ch);
}

4、中断处理

        配置好了uart属性部分,下面就是中断处理。这里中断是一个数据、一个数据进行接收的,实际处理的时候,一般是进入中断之后循环接收数据,直到没有新的数据收到为止。

extern uint8_t Rxflag;
extern uint8_t ucTemp;

void DEBUG_USART_IRQHandler(void)
{
	if(__HAL_UART_GET_IT( &UartHandle, UART_IT_RXNE ) != RESET)
	{		
        Rxflag=1;		
        HAL_UART_Receive(&UartHandle, (uint8_t *)&ucTemp, 1, 1000);        
	}
    
    HAL_UART_IRQHandler(&UartHandle);	  
}

        代码中Rxflag是标志位,ucTemp代表实际接收到的数据。

5、接收数据实际处理

        单个接收到的数据一般是没有办法直接处理的,通常都是收集到一块来处理。处理结束的标志一般就是回车换行符,或者是某个特殊的标志也可以的。

	while (1)
	{
		if(Rxflag)
		{
			if (usRxCount < sizeof(ucaRxBuf))
			{
				ucaRxBuf[usRxCount++] = ucTemp;
			}
			else
			{
				usRxCount = 0;
			}

			if (ucTemp == 0x0A)	
			{	
				HAL_UART_Transmit( &UartHandle, (uint8_t *)ucaRxBuf,usRxCount,1000 );
				usRxCount = 0;
			}

			Rxflag=0;
            __HAL_UART_ENABLE_IT(&UartHandle,UART_IT_RXNE);    
		}
	}

        这边做的比较简单,整个while(1)部分是放在main函数里面的。如果Rxflag为1,那么把接收到的数据放到ucaRxBuf里面。接着检查数据是不是0x0a,也就是换行,如果是,就把数据发送回去。最后把Rxflag重新置0,打开串口接收中断,准备新的数据进来。

        大家如果做的复杂一点,数据上面可以用queue的形式来处理,函数也可以抽象出来,实现部分做成parse command的形式,这样处理起来就会简单的多。另外,数据接收部分要尽快打开中断。

6、测试和验证

        测试就比较简单了,直接把代码编译、下载后,利用ATK-XCOM上位机打开串口,输入123、abc这样的内容,看看有没有回显就知道代码对不对了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/707061.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于flask的网站如何使用https加密通信

文章目录 内容简介网站目录示例生成SSL证书单独使用Flask使用WSGI服务器Nginx反向代理参考资料 内容简介 HTTPS 是一种至关重要的网络安全协议&#xff0c;它通过在 HTTP 协议之上添加 SSL/TLS 层来确保数据传输的安全性和完整性。这有助于防止数据在客户端和服务器之间传输时…

前端实现获取后端返回的文件流并下载

前端实现获取后端返回的文件流并下载 方法一&#xff1a;使用Axios实现文件流下载优点缺点 方法二&#xff1a;使用封装的Request工具实现文件流下载优点缺点 方法三&#xff1a;直接通过URL跳转下载优点缺点 结论 在前端开发中&#xff0c;有时需要从后端获取文件流&#xff0…

Android studio如何导入项目

打开解压好的安装包 找到build.gradle文件 打开查看gradle版本 下载对应的gradle版本Index of /gradle/&#xff08;镜像网站&#xff09; 下载all的对应压缩包 配置gradle的环境变量 新建GRADLE_HOME 将GRADLE_HOME加入到path中 将项目在Android studio中打开进行配置 将gr…

前端 CSS 经典:在 Vue3 中使用渐进式图片

1. 什么是渐进式图片 当我们网站会加载很多图片的时候&#xff0c;有些图片尺寸很大&#xff0c;加载就会很慢&#xff0c;会导致页面长时间陷入白屏状态&#xff0c;用户体验很不好。所以可以使用渐进式图片&#xff0c;先给用户展示模糊图&#xff0c;这些图尺寸小&#xff…

嵌入式硬件VS软件,到底哪个更难?

在嵌入式系统开发中&#xff0c;硬件和软件是密不可分的两个方面。但是&#xff0c;究竟是硬件开发更具挑战性&#xff0c;还是软件开发更难以应对呢&#xff1f;本文将就这一问题展开讨论&#xff0c;探究嵌入式硬件和软件在开发过程中的各种挑战与特点。 一、硬件开发&#…

5.7 Python内置函数

文章目录 1. 内置模块Aabs()all()any()ascii() Bbin()bool()bytearra()bytes() Ccallable()chr()classmethod()compile()complex() Ddelattr()dict()dir()divmod() Eenumerate()eval()exec()execfile() Ffile()filter()float()format()frozenset() Ggetattr()globals() Hhasatt…

C++ 23 之 构造函数和析构函数

c23构造函数和析构函数.cpp #include <iostream> #include <string> using namespace std;class Person2{ public:// 构造函数 没有返回值&#xff0c;不能写void;函数名和类名一致&#xff1b;可以设置参数&#xff0c;可以函数重载&#xff1b;系统自动调用&…

人工智能将成为数学家的“副驾驶”

人工智能将成为数学家的“副驾驶” 数学传统上是一门独立的科学。1986年&#xff0c;安德鲁怀尔斯为了证明费马定理&#xff0c;退到书房里呆了7年。由此产生的证明往往很难让同事们理解&#xff0c;有些至今仍有争议。但近年来&#xff0c;越来越多的数学领域被严格地分解为各…

[大模型]Phi-3-mini-4k-instruct langchain 接入

环境准备 在 autodl 平台中租赁一个 3090 等 24G 显存的显卡机器&#xff0c;如下图所示镜像选择 PyTorch–>2.0.0–>3.8(ubuntu20.04)–>11.8 。 接下来打开刚刚租用服务器的 JupyterLab&#xff0c;并且打开其中的终端开始环境配置、模型下载和运行演示。 创建工作…

C++ | Leetcode C++题解之第150题逆波兰表达式求值

题目&#xff1a; 题解&#xff1a; class Solution { public:int evalRPN(vector<string>& tokens) {int n tokens.size();vector<int> stk((n 1) / 2);int index -1;for (int i 0; i < n; i) {string& token tokens[i];if (token.length() >…

Siemens-NXUG二次开发-创建平面(无界非关联)、固定基准面[Python UF][20240614]

Siemens-NXUG二次开发-创建平面&#xff08;无界非关联&#xff09;、固定基准面[Python UF][20240614] 1.python uf函数1.1 NXOpen.UF.Modeling.CreatePlane1.2 NXOpen.UF.ModlFeatures.CreateFixedDplane 2.示例代码2.1 pyuf_plane.py 3.运行结果3.1 内部模式3.1.1 NXOpen.UF…

DTU为何应用如此广泛?

1.DTU是什么 DTU(数据传输单元)是一种无线终端设备&#xff0c;它的核心功能是将串口数据转换为IP数据或将IP数据转换为串口数据&#xff0c;并通过无线通信网络进行传送。DTU通常内置GPRS模块&#xff0c;能够实现远程数据的实时传输&#xff0c;广泛应用于工业自动化、远程监…

【MySQL】日志详解

本文使用的MySQL版本是8 日志概览 它们记录了数据库系统中的不同操作和事件&#xff0c;以便于故障排除、性能优化和数据恢复。本文将介绍MySQL中常见的几种日志&#xff0c;同时也会介绍一点常用的选项。 官方文档&#xff1a;MySQL :: MySQL 8.0 Reference Manual :: 7.4 M…

Golang | Leetcode Golang题解之第149题直线上最多的点数

题目&#xff1a; 题解&#xff1a; func maxPoints(points [][]int) (ans int) {n : len(points)if n < 2 {return n}for i, p : range points {if ans > n-i || ans > n/2 {break}cnt : map[int]int{}for _, q : range points[i1:] {x, y : p[0]-q[0], p[1]-q[1]if…

字符串的复杂操作(字符串的下标和切片、以及字符串的相关操作函数方法)

如果使用不符合标准的标识符,将会报错 SyntaxError: incalid syntax(无效语法) 文章目录 一、字符串的复杂操作1.1 下标&#xff08;也叫索引&#xff09;1.2 切片 一、字符串的复杂操作 1.1 下标&#xff08;也叫索引&#xff09; 下标代表着第几个数据&#xff0c;从0开始计…

C语言 | Leetcode C语言题解之第150题逆波兰表达式求值

题目&#xff1a; 题解&#xff1a; int evalRPN(char** tokens, int tokensSize) {int n tokensSize;int stk[(n 1) / 2];memset(stk, 0, sizeof(stk));int index -1;for (int i 0; i < n; i) {char* token tokens[i];if (strlen(token) > 1 || isdigit(token[0])…

生命在于学习——Python人工智能原理(3.4)

三、深度学习 7、过拟合与欠拟合 过拟合和欠拟合是所有机器学习算法都要考虑的问题。 &#xff08;1&#xff09;基本定义 a、欠拟合 欠拟合是指机器学习模型无法完全捕获数据集中的复杂模式&#xff0c;导致模型在新数据上的表现不佳&#xff0c;这通常是由于模型过于简单…

SemanticKITTI 拼接语义点云帧

文章目录 KITTISemanticKITTISemantic Segmentation and Panoptic SegmentationSemantic Scene Completion 数据转换语义标签和点云拼接 KITTI The odometry benchmark consists of 22 stereo sequences, saved in loss less png format: We provide 11 sequences (00-10) wit…

群体优化算法----多乌鸦搜寻算法介绍,找多目标函数组解,Pareto前沿

介绍 乌鸦搜寻算法&#xff08;Crow Search Algorithm&#xff0c;CSA&#xff09;是一种新型的群体智能优化算法&#xff0c;其灵感来源于乌鸦的行为特性&#xff0c;尤其是乌鸦在食物搜寻和藏匿过程中的智能行为。乌鸦是一种高度聪明的鸟类&#xff0c;它们展示出复杂的社会…

对补码的理解:两种求法

课本的结论是&#xff1a;二进制数的最高位是符号位。符号位为 0 表示正数和 零 &#xff0c;符号位为 1 表示负数。 正数是原码反码补码都是一样的。负数的反码是&#xff1a;符号位不变&#xff0c;剩下位取反。 负数的补码是&#xff1a;符号位不变&#xff0c;剩下位取反&a…