首页 > 系统相关 >stm32配合xshell串口输入

stm32配合xshell串口输入

时间:2024-05-17 12:40:36浏览次数:29  
标签:CODE huart UART stm32 comPrint USER 串口 xshell

前言

通过xshell对stm32f103c8t6芯片进行串口调试。

最近发现xshell也可以进行串口调试,但是在数据的输入上会有一些问题。
因为正常的串口调试助手都是统一输入,直接发送,但是xshell不同,正常情况下是字符逐一输入的。
所以在进行串口调试时,需要逐个字符分析计算,最后统一处理。

用xshell调试的优点就是软件优化好,使用起来很舒服。
缺点是,没法看16进制数据;不能自定义数据帧格式;也没有输入框,也显示不了用户输入数据。

整体来说,xshell用于这种串口调试,其实不是很明智的选择。

设计

思路

graph LR A(初始化) B(主函数处理) C(回调函数处理) A --> C C <--> B C --> C

初始化之后,回调函数接收用户输入,主函数处理用户输入的数据

同时,因为xshell不能显示用户的输入数据,所以需要在主函数中打印用户输入。
不建议在回调函数中打印,具体原因代码中会有表示。

分析

本来想做成一个类,这样所有的串口都可以同时使用,但是有一说一,C语言实现类确实有点麻烦。
可以用一个结构体保存参数,然后传递到函数中,这个方法要比类简单的多,而且也能实现所有串口都可以使用的功能。但是目前一个串口就够用,就没有实现了,有兴趣的可以自己实现一下。

初始化部分

初始化部分决定了整段代码的相对独立性,所以在初始化时应该输入一个参数,让这个库可以用于任何一个串口。

这个参数应该是串口的决定性参数,如&huart1这样的。

回调函数

回调函数应该做最少的处理,毕竟中断里面做大量计算,太占资源了。

主函数处理

这一部分可以做大量的计算和处理,毕竟主函数可以被打断,不会太耗费资源。

实现

实现这些功能,要解决几个问题

  1. 输入的命令需要存储下来,方便后面处理。
  2. 回调函数是运行在中断中,可以做到即时,但是主函数是在while中,不能做到即时相应。
  3. 需要一个特定的按键来出发判断机制,做对应的命令处理。

特定命令判断

先从最简单的开始,以使用者的习惯来说,回车做为确定符号是很自然的。
退格作为命令输入之后的取消,也是相对合理的。只是在做的时候和正常的取消有点不同。

输入命令的保存

保存采用的是栈的方式,定义一个数组,再定义一个坐标指针,通过坐标指针向数组写入数据。

不同步问题

数据无法完全实时同步,所以就需要一个输出指针。这样虽然输出和输入数据还是不同步,但可以做到延迟响应,不会让数据在输出时丢失。

代码

源码

H文件

/*
 * command.h
 *
 *  Created on: May 15, 2024
 *      Author: yangg
 */

#ifndef COMMAND_H_
#define COMMAND_H_

#include "stm32f1xx_hal.h"
#include "usart.h"

#define COMMAND_STACK_MAX 15//用户自行修改,命令的最大长度,比int16_t的最大范围小即可

void comInit(UART_HandleTypeDef *huart);
void comPrintManage();
void comCallback();

#endif /* COMMAND_H_ */

C文件

/*
 * command.c
 *
 *  Created on: May 15, 2024
 *      Author: yangg
 */

#include "command.h"

UART_HandleTypeDef *_huart;

static uint8_t _comBuff[COMMAND_STACK_MAX];
static uint8_t _temp;

static int16_t _comTop;
static int16_t _comPrint;

void comInit(UART_HandleTypeDef *huart) {
	_comTop = -1;
	_comPrint = -1;
	_huart = huart;
	HAL_UART_Receive_IT(_huart, &_temp, 1);
}

void comPrintManage() {
	while (_comPrint < _comTop || _comPrint == COMMAND_STACK_MAX - 1) {
		if (_comPrint < COMMAND_STACK_MAX - 1) {
			_comPrint++;
		}
		if (_comBuff[_comPrint] == 0x08) {
			_comTop = -1;
			_comPrint = -1;
			HAL_UART_Transmit(_huart, (uint8_t*) "\r\n", 2, 100);
		} else if (_comBuff[_comPrint] == 0x0D) {
			// TODO 命令处理--------------------------------------------------
			_comTop = -1;
			_comPrint = -1;
			HAL_UART_Transmit(_huart, (uint8_t*) "\r\n", 2, 100);
		} else {
			if (_comPrint < COMMAND_STACK_MAX - 1) {
				HAL_UART_Transmit(_huart, &_comBuff[_comPrint], 1, 100);
			} else {
				return;//超过最大长度不显示,
			}
		}

	}
}

void comCallback() {
	if (_comTop < COMMAND_STACK_MAX - 1) {
		_comTop++;
	}
	_comBuff[_comTop] = _temp;
	HAL_UART_Receive_IT(_huart, &_temp, 1);
}

在C文件中的TODO 命令处理部分可以写自己定义的命令和处理方式。

对退格的处理不是清除一个字符,因为如果清除一个字符,需要每次都对字符串进行刷新。所以对于退格就直接清除掉所有数据了。

示例

主函数

int main(void) {

	/* USER CODE BEGIN 1 */

	/* USER CODE END 1 */

	/* MCU Configuration--------------------------------------------------------*/

	/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
	HAL_Init();

	/* USER CODE BEGIN Init */

	/* USER CODE END Init */

	/* Configure the system clock */
	SystemClock_Config();

	/* USER CODE BEGIN SysInit */

	/* USER CODE END SysInit */

	/* Initialize all configured peripherals */
	MX_GPIO_Init();
	MX_I2C1_Init();
	MX_SPI1_Init();
	MX_USART1_UART_Init();
	MX_USART2_UART_Init();
	MX_USB_PCD_Init();
	/* USER CODE BEGIN 2 */
	UART1_print("\r\n\r\n");
	UART1_print("program is ready and running");
	UART1_print("\r\n");
	ledInit(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET);
	comInit(&huart1);//-----------这里初始化
	/* USER CODE END 2 */

	/* Infinite loop */
	/* USER CODE BEGIN WHILE */
	while (1) {
		ledToggle();
		comPrintManage();//----------这里是主函数调用
		/* USER CODE END WHILE */

		/* USER CODE BEGIN 3 */
	}
	/* USER CODE END 3 */
}

回调函数

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
	if (huart->Instance == USART1) {
		comCallback();
	}
}

标签:CODE,huart,UART,stm32,comPrint,USER,串口,xshell
From: https://www.cnblogs.com/yswnotes/p/18197612

相关文章

  • stm32f103c8t6对flash进行操作,Hal库,擦除1页数据大小,写入128字节大小,读取指定地址128字
    参考这篇:STM32IAP应用开发——自制BootLoader-CSDN博客把工程转到HAL库使用的函数,用HAL自带的HAL_FLASHEx_EraseHAL_FLASH_Program 串口显示结果 验证没问题flash在hal库使用的驱动程序#include"flash.h"externvoidFLASH_PageErase(uint32_tPageAddress);//......
  • 串口通信原理
          异步串行:异步说明不带时钟信号,串行说明是按位(一位=8bit),一位一位传输       ......
  • XShell执行systemctl stop network命令后断开连接,并重连失败
    在XShell中执行命令systemctlstopnetwork后,断开了与虚拟机的连接,进行重新连接,显示连接失败,停止虚拟机网络服务后,XShell无法继续连接。需要重启虚拟机的网络服务【1】重启解决systemctlstopnetwork是暂时关闭服务,不是永久的,所以重启后会自启。在主机有网络的情况下,重启......
  • 记录一下在KEIL中修改STM32的栈顶地址
    STM32的启动文件中定义的栈和堆的大小,由于栈是向下生长的。所以我们一般希望将栈顶设置为RAM的最高有效地址。这样就可以最大限度保护栈不会溢出。但是STM32的启动文件居然不是这样的思路。那STM32的启动文件的分配思路是怎么样的呢。它其实是先确定用户使用RAM的情况,然后在未使......
  • 野火指南者STM32F103+STM32CubeMX FSMC实现LCD屏幕显示
    MCU:STM32F103VET6开发环境:STM32CubeMX+MDK5最近针对STM32的LCD进行复习,顺便展开一下笔记。 STM32LCD液晶屏(ILI9341)本文章使用STM32F103VET6,野火指南者的3.2寸电阻屏,进行学习。 LCD液晶显示针对野火指南者配套资料:3.2寸LCD电阻屏,屏幕里自带ILI9341液晶控制器芯片,......
  • STM32Cube-10 | 使用ADC读取气体传感器数据(MQ-2)
    本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的ADC外设,读取MQ-2气体传感器的数据并通过串口发送本质就是ADC采集MQ-2的原理图如下: 生成MDK工程选择芯片型号打开STM32CubeMX,打开MCU选择器:搜索并选中芯片STM32L431RCT6:配置时钟源如果选择使用外......
  • ..\HAL_LIB\Inc\stm32l4xx_hal_rcc_ex.h(2424): error: #20: identifier "HAL_Sta
    stm32工程编译时遇到这个错误,显示HAL_StatusTypeDef没有被定义,但是go todefinition又能找到定义 后来在网上寻找解决办法,结果发现竟然是#include"stm32l4xx_hal_spi.h"#include"stm32l4xx_hal.h"这两个的顺序问题,#include"stm32l4xx_hal.h"头文件包含必须在最前面,真是......
  • FlexibleButton - 一个小巧灵活的C语言按键处理库+SerialChart - 能将串口数据实时绘
    1、FlexibleButton-一个小巧灵活的C语言按键处理库FlexibleButton是一个基于标准C语言的小巧灵活的按键处理库,支持单击、连击、短按、长按、自动消抖,可以自由设置组合按键,可用于中断和低功耗场景。项目主页:https://github.com/murphyzhao/FlexibleButton该按键库解耦了......
  • 串口U盘 - 基于STM32+CH375的郁闷的工程师利器+Arduino Laser Infrared Thermometer -
    1、串口U盘-基于STM32+CH375的郁闷的工程师利器辛勤地打工的工程师们,你们是否曾经有过这样的经历,自己辛辛苦苦为公司写的代码和设计的PCB,却无论如何都不能据为己有?因为公司不允许个人电脑上网,因为公司的电脑居然把USB口也封闭了!这时候,我们是万般地郁闷,但是,作为一个以电子开发......
  • stm32 出现 hard fault 的排查记录
    参考链接:https://blog.csdn.net/qq_43118572/article/details/1327596261、先验知识先验知识1:cortexm3在中断/异常时,会把8个寄存器(xPSR、PC、LR、R12以及R3-R0)的值压入栈。入栈顺序以及入栈后堆栈中的内容如下(CM4是从低地址到搞地质):地址寄存器被保存的顺序......