前言
製作一個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進制的數值;但沒有任何功能
留言
張貼留言