stm32配合xshell串口输入

发布者:Meshulun最新更新时间:2025-02-05 来源: jianshu关键字:stm32  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*) 'rn', 2, 100);

        } else if (_comBuff[_comPrint] == 0x0D) {

            // TODO 命令处理--------------------------------------------------

            _comTop = -1;

            _comPrint = -1;

            HAL_UART_Transmit(_huart, (uint8_t*) 'rn', 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('rnrn');

    UART1_print('program is ready and running');

    UART1_print('rn');

    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();
    }}



关键字:stm32  xshell  串口输入 引用地址:stm32配合xshell串口输入

上一篇:STM32学习笔记(六)SysTick
下一篇:STM32 虚拟U盘

推荐阅读最新更新时间:2026-03-23 10:58

STM8 74hc165并口输入转为串口输入子程序
软件设计 /********************************************************************* 目 的: 建立74hc165操作库 目标系统: 基于STM8单片机 应用软件: Cosmic CxSTM8 *********************************************************************/ #include stm8s207s8.h #define HC165_IN_RXD cbi(PD_ODR,6);cbi(PD_CR1,6);cbi(PD_CR2,6); //数据口 #define HC165_GET_
[单片机]
使用74LS165将AVR的串口输入扩为并口输入
系统功能 使用74LS165将AVR的串口输入扩为并口输入。 硬件设计 AVR主控电路原理图 串行输入扩展为并行输入芯片74LS165控制电路原理图 软件设计 下面部分从TXT拷出,拷到网页,代码部分缺省了很多空格,比较凌乱,请谅解! //目标系统: 基于AVR单片机 //应用软件: ICC AVR /*01010101010101010101010101010101010101010101010101010101010101010101 ---------------------------------------------------------------------- 实验内容: 使用PA口
[单片机]
使用74LS165将AVR的<font color='red'>串口</font><font color='red'>输入</font>扩为并口<font color='red'>输入</font>
STM32F103 实验按键输入串口实验
正文 要进入按键输入,我们必须先明确,按键连在哪一个GPIO口,通过开发手册,如下 因此,我们可以在蜂鸣器和跑马灯的基础上,完成该实验。 按键输入 #include led.h #include delay.h #include key.h #include sys.h #include beep.h #define KEY0 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_4)//读取按键0 #define KEY1 GPIO_ReadInputDataBit(GPIOE,GPIO_Pin_3)//读取按键1 #define WK_UP GPIO_ReadInputDataBit(GP
[单片机]
STM32F103 实验按键<font color='red'>输入</font>与<font color='red'>串口</font>实验
at89c2051串口带校验输入指令最高数率并行输出数据.
;;;串口带校验;;; ;;at89c2051串口带校验最高数率并行输出数据;; ORG 0000H AJMP MAIN ORG 0003H AJMP EX00 RETI ORG 000BH RETI ORG 0013H AJMP EX11 RETI ORG 001BH RETI ORG 0023H CLR TI JBC RI,ES1 RETI ES1: AJMP ESRD ORG 0030H MAIN: MOV SP,#10H MOV TMOD,#21H ;;MOV TH1,#0EFH;;;16MHZ/2450BANDU/S MOV TH1,#0F3H;;;12MHA/2400BANDU/S MOV TCON,#55H MO
[单片机]
基于STM32的矿井作业环境监测系统设计与实现
针对煤矿开采中瓦斯爆炸等严重安全隐患,设计了一套矿井安全系统。该系统实时监测瓦斯浓度、温度、火情、粉尘等环境参数,自动控制除尘、灭火、通风等设备,以保障矿井安全。通过WiFi将数据传输至监控平台,并支持APP远程监控与操作,从而提升应急响应速度和管理效率。 PART 01 系统总体结构 系统实现了对矿井内甲烷气体体积分数、粉尘浓度、火焰及温湿度等关键参数的实时采集与分析;并通过预设的自动控制策略触发联动设备,实现安全隐患的快速响应与主动防控。同时,支持数据远程传输至云端平台,并通过机智云APP提供实时监控、报警及远程操控功能,为矿井安全管理提供高效、可靠的技术支撑。系统总体结构如图1所示。 PART 02 系统详细设计
[单片机]
基于<font color='red'>STM32</font>的矿井作业环境监测系统设计与实现
STM32外设使用中的五个易错技巧与避坑指南
STM32作为嵌入式开发领域的热门微控制器,功能极为丰富,几乎能够完成所有常见控制任务,如GPIO等外设应有尽有。然而,正因为其功能强大,开发过程中也更容易遇到各种陷阱。许多初学者甚至经验丰富的开发者,常在外设配置上浪费大量时间,调试许久仍难以定位问题。本文总结了5个STM32外设使用中最易出错的技巧,旨在帮助你少走弯路、提高开发效率。 1. GPIO 配置别忘了上拉/下拉 很多初学者在读取按键、外部或中断输入时,会发现输入状态总是不稳定,甚至出现抖动或误触发。这通常是因为 GPIO 输入口浮空造成的。 常见坑: 输入引脚未配置上拉/下拉,导致状态随机波动。 上拉/下拉和外部电路冲突,影响可靠性。 输入误
[嵌入式]
STM32外设开发中5个常见陷阱与规避方法
STM32作为嵌入式开发领域的热门微控制器,功能丰富,几乎能胜任所有常见控制任务,诸如GPIO、定时器、通信接口等外设一应俱全。然而,正因其强大的功能,开发中遭遇陷阱的几率也相应增加,不少初学者甚至经验丰富的开发者常在外设配置上耗费大量时间,调试许久仍难以解决问题。本文总结了5个STM32外设使用中最易出错的技巧,助你规避常见误区,提升开发效率。 1. GPIO 配置别忘了上拉/下拉 很多初学者在读取按键、外部或中断输入时,会发现输入状态总是不稳定,甚至出现抖动或误触发。这通常是因为 GPIO 输入口浮空造成的。 常见坑: 输入引脚未配置上拉/下拉,导致状态随机波动。 上拉/下拉和外部电路冲突,影响可靠性。
[嵌入式]
STM32单片机AD4630-24驱动程序
AD4630-24是亚德诺推出的一款24位双通道支持同步采样的ADC,高昂的售价注定了这不会是一款常用芯片,我在做驱动开发期间在中文互联网基本没有找到可以参考的资料或例程。但这次毕竟做的是一款高精度同步电压电流表,这款芯片是领导亲自选的,要求很明确,就是分辨率拉满,咱也只能硬着头皮开干。 这次也是分享以下驱动开发的思路和例程,希望能够帮助到相关人士,顺便,这款芯片要求5V和1.8V双电源供电也是让硬件同事疯狂吐槽。 1.通讯接口 AD4630-24支持串行通讯,为了提高采样结果的读取速率,SDO最高支持8通道同步输出,但很可惜这次使用的单片机是STM32F407,意法连QSPI都不给,只能使用标准的SPI接口通讯,例程也
[单片机]
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved