前言
製作一個UART的CLI模版,這只是一個最基本的架構,功能會依需求持續修改
操作環境
- Board:32F072BDISCOVERY
- IDE:STM32CubeIDE
- Code:STM32CubeMX
MCU I/O配置
- UART:TX(PA9),RX(PA10)
1. STM32CubeMX
勾選USART1,選 Asynchronous,bardrate:115200 bps
這裡的USART1不是公板上內建的介面,須要另外搭配UART模組
勾選中斷功能
2. STM32CubeIDE
在main.c加入下列程式
main.c
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <string.h>
/* USER CODE END Includes */
完善 printf 指令
/* USER CODE BEGIN PV */
#ifdef __GNUC__
/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf
set to 'Yes') calls __io_putchar() */
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__ */
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART1 and Loop until the end of transmission */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
return ch;
}
/* USER CODE END PV */
CLI函式所需用到的變數 buffer
/* USER CODE BEGIN PFP */
uint8_t uart_rx[2];
char cli_data[80];
char *cli_pointer = cli_data;
uint8_t cli_key_enter;
/* USER CODE END PFP */
CLI函式
/* USER CODE BEGIN 0 */
void CLI(void)
{
uint8_t values[10];
uint8_t i = 0;
char *token;
// extern USBD_HandleTypeDef hUsbDeviceFS;
if(cli_key_enter != 1) return;
cli_key_enter = 0;
token = strtok(cli_data, " ");
// while (token != NULL) {
// //printf("%s\n", token);
// token = strtok(NULL, " ");
// }
while(token != NULL)
{
//values[i++] = atoi( token );
values[i++] = strtol(token, NULL, 16);
token = strtok(NULL, " ");
}
if(i>0)
{
// USBD_HID_SendReport(&hUsbDeviceFS,values, i);
// HAL_Delay(15);
// memset(values, 0, i);
// USBD_HID_SendReport(&hUsbDeviceFS,values, i);
// HAL_Delay(15);
}else{
printf("--- CLI console ---\n\r");
printf("Key in multi hex values A0 00 10 and press ENTER to execute\n\r");
printf("-------------------\n\r");
printf("\n");
}
cli_pointer = cli_data;
memset(cli_data, 0, sizeof(cli_data));
}
/* USER CODE END 0 */
main loop
UART的中斷接收 HAL_UART_Receive_IT 要先執行一次
int main(void)
{
/* USER CODE BEGIN 2 */
HAL_UART_Receive_IT(&huart1, uart_rx, 1);
printf("Halo CLI\r\n");
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
CLI();
}
/* USER CODE END 3 */
}
UART接收中斷程序
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
HAL_UART_Receive_IT(&huart1, uart_rx, 1);
HAL_UART_Transmit(&huart1, uart_rx, 1, HAL_MAX_DELAY);
switch(uart_rx[0])
{
case '\r'://"Enter 0x13"
printf("\n");
cli_key_enter = 1;
break;
case 0x7F://"backspace"
if(cli_pointer > cli_data) cli_pointer--;
break;
case 0x1B://"ESC"
cli_pointer = cli_data;
printf("\r");
break;
default:
if((cli_pointer - cli_data) >=80) cli_pointer = cli_data;
*(cli_pointer++) = (char)uart_rx[0];
break;
}
// int size = (cli_pointer) - (cli_data);
}
/* USER CODE END 4 */
3. 成果
上電後先列印出"Halo CLI"
在沒有任何輸入時按下 Enter 則顯示CLI內容
可以輸入16進制的數值;但沒有任何功能