完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本帖最后由 MMCU5721167 于 2020-1-15 12:05 编辑 对于做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。 图1 串口硬件原理图 图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); //使能UART1 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); //开启GPIOA时钟 //>>>UART1 NVIC 配置>>> NVIC_InitStructure.NVIC_IRQChannel = UART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPriority = 3; //子优先级3 NVIC_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); //初始化串口1 UART_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.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出 GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10 GPIO_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,界面如下: |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
2255个成员聚集在这个小组
加入小组灵动微电子MM32全系列MCU产品应用手册,库函数和例程和选型表
11913 浏览 3 评论
【MM32 eMiniBoard试用连载】+基于OLED12864的GUI---U8G2
6015 浏览 1 评论
【MM32 eMiniBoard试用连载】移植RT-Thread至MM32L373PS
11149 浏览 0 评论
【MM32 eMiniBoard测评报告】+ 开箱 + 初探
4615 浏览 1 评论
灵动微课堂(第106讲) | MM32 USB功能学习笔记 —— WinUSB设备
4351 浏览 1 评论
[MM32软件] MM32F002使用内部flash存储数据怎么操作?
1557浏览 1评论
888浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-11 10:31 , Processed in 0.354257 second(s), Total 36, Slave 30 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号