Nucleo-F411RE (STM32F411)LL库体验 4 -Letter Shell移植与使用
1、串口的初始化
Nucleo-F411RE自带st-link,并支持虚拟串口的功能,根据原理图,st-link的rx tx接到了Nucleo-F411RE的PA2 PA3,所以我们要初始化PA2 PA3为串口功能,这样我们就可以直接用st-link抓取打印,而不用再接一个usb转串口的模块。
由于要用letter shell,所以要配置串口为tx rx模式,发送数据我们用普通轮询模式,接收数据用中断模式,中断函数每次接收到一个数据调用一次,我们在中断函数里调用 shellHandler(&shell, received_char)去处理数据即可。
a、串口时钟初始化
所有时钟的初始化,都放在了clock_init.c中的
void BOARD_ClockInit函数中
b、gpio 、usart初始化
// 初始化PA2 PA3作为打印串口使用
static void Board_ConsoleInit(void)
{LL_RCC_ClocksTypeDef rccClock;/* Configure Tx Pin as : Alternate function, High Speed, Push pull, Pull up */LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_2, LL_GPIO_MODE_ALTERNATE);LL_GPIO_SetAFPin_0_7(GPIOA, LL_GPIO_PIN_2, LL_GPIO_AF_7);LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_2, LL_GPIO_SPEED_FREQ_HIGH);LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_2, LL_GPIO_OUTPUT_PUSHPULL);LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_2, LL_GPIO_PULL_UP);/* Configure Rx Pin as : Alternate function, High Speed, Push pull, Pull up */LL_GPIO_SetPinMode(GPIOA, LL_GPIO_PIN_3, LL_GPIO_MODE_ALTERNATE);LL_GPIO_SetAFPin_0_7(GPIOA, LL_GPIO_PIN_3, LL_GPIO_AF_7);LL_GPIO_SetPinSpeed(GPIOA, LL_GPIO_PIN_3, LL_GPIO_SPEED_FREQ_HIGH);LL_GPIO_SetPinOutputType(GPIOA, LL_GPIO_PIN_3, LL_GPIO_OUTPUT_PUSHPULL);LL_GPIO_SetPinPull(GPIOA, LL_GPIO_PIN_3, LL_GPIO_PULL_UP);/* (3) Configure USART functional parameters ********************************//* Disable USART prior modifying configuration registers *//* Note: Commented as corresponding to Reset value */// LL_USART_Disable(USART2);NVIC_SetPriority(USART2_IRQn, 0); NVIC_EnableIRQ(USART2_IRQn);/* TX/RX direction */LL_USART_SetTransferDirection(USART2, LL_USART_DIRECTION_TX_RX);/* 8 data bit, 1 start bit, 1 stop bit, no parity */LL_USART_ConfigCharacter(USART2, LL_USART_DATAWIDTH_8B, LL_USART_PARITY_NONE, LL_USART_STOPBITS_1);LL_RCC_GetSystemClocksFreq(&rccClock);LL_USART_SetBaudRate(USART2, rccClock.PCLK1_Frequency, LL_USART_OVERSAMPLING_16, 115200); /* Enable RXNE and Error interrupts */LL_USART_EnableIT_RXNE(USART2);LL_USART_EnableIT_ERROR(USART2);/* (4) Enable USART *********************************************************/LL_USART_Enable(USART2);
}
c、中断处理函数
d、printf重定向
后面完善letter shell写函数的时候,跟这个类似,直接复制过去就行。
2、letter shell的移植
下载传送门
下载后,将src中所有的文件拷贝到我们的工程中,并新建shell_port.c shell_port.h文件,目录结构如图:
shell_port.c 中内容如下:
#include “shell_port.h”
#include "shell.h"
#include "shell_port.h"Shell shell;
char shell_buffer[512];short userShellWrite(char *data, unsigned short len)
{uint32_t i;for (i = 0; i < len; i++){while (!LL_USART_IsActiveFlag_TXE(USART2)){}/* If last char to be sent, clear TC flag */if (i == (len - 1)){LL_USART_ClearFlag_TC(USART2); }/* Write character in Transmit Data register.TXE flag is cleared by writing data in DR register */LL_USART_TransmitData8(USART2, data[i]);}return len;
}void User_Shell_Init(void)
{shell.write = userShellWrite;shellInit(&shell, shell_buffer, 512);
}
shell_port.h内容如下:
#ifndef __SHELL_PORT_H__
#define __SHELL_PORT_H__
#include "shell.h"
#include "main.h"extern Shell shell;
void User_Shell_Init(void);
#endif
main函数添加shell的初始化函数
如果此时编译报错,修改ld文件如下:
这样开机后,接到letter shell交互界面了。
3、Letter Shell的使用
我们添加一个命令,来控制LED灯,输入LED On灯亮,输入LED Off灯灭,
输入LED Blink 100,灯开始间隔100ms开始闪烁。
首先在shell_cfg.h使能支持外部命令的宏。
添加LED命令:
volatile static bool isBlinking = false;
volatile static long delay_time = 250;int LED_Control(int argc,char *argv[])
{if (argc == 2){if (!strncmp(argv[1],"On",2)){isBlinking = false;LED_ON();}else if (!strncmp(argv[1],"Off",3)){isBlinking = false;LED_OFF();}else{printf(" param error.please use LED On/LED Off/LED Blink 200\r\n");return -1;}}else if (argc == 3){if(!strncmp(argv[1],"Blink",5)){delay_time = strtol(argv[2],NULL,10);if (delay_time > 0){isBlinking = true;}else{isBlinking = false;printf("please LED Blink 200 \r\n");LED_OFF();return -1;}}else{printf(" param error.please use LED On/LED Off/LED Blink 200\r\n");return -1;}}else{printf(" param error.please use LED On/LED Off/LED Blink 200\r\n");return -1;}return 0;
}SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0)|SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), LED, LED_Control, LED_Control);
编译后重新烧录,在串口中输入相关命令,即可控制LED灯,这样调试是不是很方便。
4 、代码
代码下载