全面了解STM32微控制器的特性和应用
STM32&Letter Shell
前言
在进行调试程序(例如电机的角度速度、PID参数的整定、测试函数之间的联动等)时通常会使用串口来进行指令的收发,但是这个每个指令都需要进行单独的编写,并且编写出来的会拥有一个特定的格式,过一段时间再看程序的时候要傻眼很长时间。
所以一直在思考有没有一个程序可以直接在串口工具中输入函数(函数名就是更具其功能来设置的)然后直接执行。这就是本期的主角 Letter Shell
了。
关于Letter Shell
话不多说直接上链接,作者已经写到了3.1版本了,但是基础的功能2.x版本就可以实现了,所以最终我选择了2.x版本进行移植。这个是2.x版本的链接。注意!!!2.x版本和3.x版本的函数之间不通用,如果需要3.x版本的功能,需要重新移植对应版本
移植
既然是串口调试那么第一步就是打开串口了!
同时需要打开串口中断,设置中断优先级。
注意!!!这个串口的优先级,最好给它一个单独的中断!!!
有次我把它和定时器中断放在了一个优先级里面,它抢占优先级虽然比定时器高但是,在输入一些特殊字符方面还是会出出现问题。
接下来是Printf
的重定向,常规操作,我这里用的是Clion+Cmake编译的,Keil的可以参考我之前写的一篇文章
有了Printf
当然还不够,需要下载Letter-Shell-2.x,直接下载并且丢到对应使用STM32文件里面,添加好头文件路径就行。
这时候如果直接使用会出现错误,因为我的主文件用的是.cpp
文件,而Letter Shell
用的是.c
文件进行编写的,所以需要在Letter Shell
的.h
·中将函数使用下面的函数包裹起来这样就不会报错了。
#ifdef __cplusplus
extern "C" {
#endif
// 相关C语言函数
#ifdef __cplusplus
}
#endif
接下来就是需要给Letter Shell
分配一下串口,并且告诉它接受函数是什么,发送函数是什么。
先来搞一下发送函数,也就是单片机发送给上位机的函数,这里我是直接在shell.c
的文件下面创建了shell
的结构体以及发送函数
SHELL_TypeDef shell;
/**
* @brief shell写数据函数原型
*
* @param const char 需写的字符
*/
void ShellWrite(char data) {
HAL_UART_Transmit(&huart1, (uint8_t *)&data, 1, 0xFFFF);
}
注意这里需要添加串口的头文件,以及.h
文件中要声明一下。
然后回到主函数里,分配一下函数的作用,这样发送的函数就完成了。
shell.write = ShellWrite;
shellInit(&shell);
编译!!!!这时候发现报了个大错!
这个错在对应的说明文档里面写了,需要在.ld
文件中的只读数据区(建议)添加
如果使用的是Keil编译的话,需要在keil的target option中增加–keep shellCommand*,防止定义的命令被优化掉。
这时候在编译就没有问题了。烧录并且打开串口助手就可以看见输出出来的语言了。
// 串口中断
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
if (huart->Instance == USART1) {
shellInput(&shell, shellRxBuffer);
HAL_UART_Receive_IT(&huart1, (uint8_t *)&shellRxBuffer, 1);
}
}
这里的shellRxBuffer
定义在创建shell的文件下面。同时需要在shell_cfg.h
文件中#define SHELL_USING_TASK 0
把任务关闭。
串口上位机的选择
这里我使用的是MobaXterm这一款上位机。Letter Shell
库的串口是你每输入一个字符都会发送给单片机,单片机缓存这个字符直到输入Enter
再对输入的字符进行处理,所以需要选择一款按下一个按键就会发送的串口上位机。
OK!
这里放个github链接
作者:拉搜米搜拉搜