485调试助手_基于MM32 MCU的shell调试教程(一)

对于做linux开发的研发人员来说,大家都喜欢通过输入指令符来执行一些命令操作,如果在MCU编程过程中有一个类似linux的shell命令工具可以通过串口调试助手输入命令然后运行一些调试函数,将会为编程提供极大的帮助。

对于MCU来说,每次修改程序调试就需要重新下载,有时候仅仅是调试修改几个参数,这样反复修改程序编译下载就显得很繁琐,浪费时间,而且在调试电机、电源等高压电源类应用时,如果出现操作错误,有可能会造成炸机毁坏电脑等危险,如果有一个类似linux的命令行操作,这样就可以省出很多时间,但是由于MCU存储资源和运算速度等限制,所以想实现一个同样功能的操作,就需要做一些处理优化。

目前有很多类似的shell代码,本次介绍如何在MM32 MCU上使用shell来辅助开发,由于篇幅过长,所以将分三个章节讲述实现方式,本章节将教大家基础的软件配置,后面章节将带领大家学习如何配置Jlink RTT和shell的程序配置。 硬件资源如下: 本次实验将在基于MM32L073的MiniBoard上进行测试验证,实现shell的通信端口可以使用任意通信方式,如UART、USB、SPI、IIC、485等方式,本次使用MM32L073PF的UART1作为shell输入输出通道,如图2。PA15作为状态指示 LED1的控制引脚,如图3。 71d1b381528b1cb639e9d5b01adc4000.png

图1 串口硬件原理图

d45539e4b710ac725c4d440981c7cde3.png 图2  LED硬件原理图 软件资源如下: 结合上述使用到的硬件资源,下面我们着重介绍软件实现流程以及相关配置代码,主要涉及如何移植shell的输入输出以及如何执行命令。 以下为主函数初始化配置及相关全局变量定义内容,代码如下:
//>>>状态指示 LED1的初始化配置>>>void LED_Init(void){GPIO_InitTypeDef  GPIO_InitStructure;RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); //开启GPIOA时钟GPIO_InitStructure.GPIO_Pin  =  GPIO_Pin_15;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_Init(GPIOA, &GPIO_InitStructure);LED1_OFF();}void uart_nvic_init(u32 bound){//>>>GPIO端口设置>>>GPIO_InitTypeDef GPIO_InitStructure;UART_InitTypeDef UART_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;//>>>使能外设时钟>>>RCC_APB2PeriphClockCmd(RCC_APB2Periph_UART1, ENABLE); //使能UART1RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);  //开启GPIOA时钟//>>>UART1 NVIC 配置>>>NVIC_InitStructure.NVIC_IRQChannel = UART1_IRQn;NVIC_InitStructure.NVIC_IRQChannelPriority = 3;  //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化NVIC寄存器//>>>UART的GPIO复用功能配置>>>GPIO_PinAFConfig(GPIOA, GPIO_PinSource9, GPIO_AF_1);GPIO_PinAFConfig(GPIOA, GPIO_PinSource10, GPIO_AF_1);//>>>UART 初始化设置>>>UART_InitStructure.UART_BaudRate = bound;//串口波特率UART_InitStructure.UART_WordLength = UART_WordLength_8b;//字长为8位数据格式UART_InitStructure.UART_StopBits = UART_StopBits_1;//一个停止位UART_InitStructure.UART_Parity = UART_Parity_No;//无奇偶校验位UART_InitStructure.UART_HardwareFlowControl = UART_HardwareFlowControl_None;//无硬件数据流控制UART_InitStructure.UART_Mode = UART_Mode_Rx | UART_Mode_Tx; //收发模式UART_Init(UART1, &UART_InitStructure); //初始化串口1UART_ITConfig(UART1, UART_IT_RXIEN, ENABLE);//开启串口接受中断UART_Cmd(UART1, ENABLE);                    //使能串口1//>>>UART1_TX   GPIOA.9>>> UART1_RX    GPIOA.10>>>GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10}//>>>UART发送一个字节 >>>void Uart_PutChar(char chByte){while ((UART1->CSR & UART_IT_TXIEN) == 0);UART1->TDR = (chByte & (uint16_t)0x00FF);}//>>>UART 发送字符串>>>void Uart_PutBuff(uint8_t *pchBuff, uint32_t wLen){while (wLen--) {Uart_PutChar(*pchBuff);pchBuff++;}}//>>>main主函数 >>>int main(void){delay_init();LED_Init();uart_nvic_init(115200);  //串口初始化为115200//uart_shell.read = shellRead;uart_shell.write = Uart_PutChar;shellInit(&uart_shell);//shell初始化while (1){}}
移植的步骤先定义一个shell对象,即:SHELL_TypeDef uart_shell; 然后实例化对象的操作接口,对于本次我们采用中断接收,所以不用调用读取接口函数,所以接收接口如下修改:
//uart_shell.read = shellRead; 注释掉读取接口,采用中断处理代码如下:void UART1_IRQHandler(void)                 //串口1中断服务程序{u8 Res;if (UART_GetITStatus(UART1, UART_IT_RXIEN)  != RESET){UART_ClearITPendingBit(UART1, UART_IT_RXIEN);Res = UART_ReceiveData(UART1);//读取接收到的数据shellHandler(&uart_shell, Res);//shell处理函数}}

然后实例化发送接口,代码如下:uart_shell.write = Uart_PutChar;

最后实例化对象,代码如下:shellInit(&uart_shell); 完成shell对象的全部实例化,那么我们如何加入我们需要的命令函数呢?很简单,有多种方式,本次我们介绍最简单的一个,即SHELL_EXPORT_CMD();其它参考源码,本次我们加入测试代码如下:
void led1_on(void){LED1_ON();}SHELL_EXPORT_CMD(led1_on, led1_on, led1_on);//三个变量:命令,功能,描述void led1_off(void){LED1_OFF();}SHELL_EXPORT_CMD(led1_off, led1_off, led1_off);//同上void led1_toggle(void){LED1_TOGGLE();}SHELL_EXPORT_CMD(led1_toggle, led1_toggle, led1_toggle);void reboot(void){NVIC_SystemReset();}SHELL_EXPORT_CMD(reboot, reboot, reboot);
如上完成所有代码后下载烧写进入,然后打开PuTTY,设置为115200,界面如下:

1ae86f1f52bd4faf1528e69e7d96c3c4.png

图3  命令列表 选择输入对应的指令命令,MCU执行对应的指令操作;比如输入led1_on即可打开led1,输入led1_off关闭led1,输入led1_toggle反转led1亮灭,输入reboot则MCU重启,输入cls清除当前窗口。   73c7e64255fc3b6841b58a25853699ea.png 图4  控制LED1亮

本次实验的的外设配置及操作如上所述,在下一章节将带领大家学习shell的程序和Jlink RTT的配置等。

来源:灵动MM32

MCU开发加油站

关注MCU开发最新资讯及相关技术应用,交流MCU创新设计心得、与MCU开发达人结网同行!

2eb0f0758ed84a8bdd9db3e25be64151.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值