基于STM32CubeMX 實作序列槽通信控制 LED 和蜂鳴器
本實驗基于STM32CubeMX實作對STM32開發闆的配置,通過序列槽發送指令控制 LED 和蜂鳴器的狀态,同時傳回指令資訊。并且通過預定義選擇是否保持其中一個LED保持閃爍。程式下載下傳
基于STM32CubeMX 實作序列槽通信控制 LED 和蜂鳴器
1. 軟體與硬體
1.1 硬體要求:
1.2 軟體要求:
2. STM32CubeMX配置開發闆
2.1 Pinout & Configuration
2.2 Clock Configuration
2.3 Project Manager
3. 程式代碼
3.1 usart.c
3.2 main.c
4. 程式分析
4.1 主要功能
4.2 程式流程
4.3 主要函數
1. 軟體與硬體
1.1 硬體要求:
(1)ALIENTEK ELITE STM32F103 開發闆 (STM32F103ZET6 晶片)
(2)USB轉TTL 子產品
1.2 軟體要求:
(1)Java Runtime Environment (JRE) 1.8.0 版本
(2)STM32CubeMX 5.6.1 版本
(3)IAR Embedded Workbench 8.0
(4)序列槽調試工具
2. STM32CubeMX配置開發闆
LED 0:PB5
LED 1:PE5
BEEP 蜂鳴器:PB8
USART1_TX:PA9
USART1_RX:PA10
2.1 Pinout & Configuration
(1) GPIO 配置
LED 0、LED1、蜂鳴器設定為Output Push Pull 并設定上拉電阻,使之維持在高電平。
(2) RCC(Reset and Clock Control)時鐘控制器配置
(3) USART1 配置
設定為異步模式并使能中斷
USART 參數設定
2.2 Clock Configuration
2.3 Project Manager
3. 程式代碼
程式下載下傳:https://download.csdn.net/download/frozennet/12587600
3.1 usart.c
實作printf的重定向
/* USER CODE BEGIN 0 */
/******************************************************************
*@brief Retargets the C library printf function to the USART.
*@param None
*@retval None
******************************************************************/
#include "stdio.h"
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int _io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif /* __GNUC__*/
PUTCHAR_PROTOTYPE
{
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF);
return ch;
}
/* USER CODE END 0 */
3.2 main.c
(1)添加頭檔案
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <string.h>
/* USER CODE END Includes */
(2)添加預定義
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* Uncomment this line to Disable LED Blink*/
//#define LED_BLINK_DISABLE
/* Uncomment this line to Enable LED Blink*/
#define LED_BLINK_ENABLE
#define Uart1_RxBufferSIZE 255 /* Define the size of buffer zone*/
/* USER CODE END PD */
(3)添加變量
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
__IO ITStatus UartReady = RESET; /* The flag of interruption*/
char Uart1_RxBuffer[Uart1_RxBufferSIZE]; /* The buffer zone */
uint8_t RxBuffer_IT; /* Receive a byte of data */
uint8_t Uart1_Rx_Count = 0; /* Count for receiving */
#ifdef LED_BLINK_ENABLE
uint32_t Prior_Tick = 0; /* Record prior tick */
uint32_t Current_Tick = 0; /* Record current tick */
uint32_t Delay_Time = 100; /* Delay time needed */
#endif
/* USER CODE END PV */
(4)接收第一個字元,并判斷是否接收正确
/* USER CODE BEGIN 2 */
/* Receive the first character */
printf("Hello world\r\n");
if(HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxBuffer_IT, 1)== HAL_OK)
{
}
/* USER CODE END 2 */
(5)程式主體
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
#ifdef LED_BLINK_ENABLE
Current_Tick = HAL_GetTick(); /* Get current system tick */
if(Current_Tick < Prior_Tick) /* System overflow */
{
if(HAL_MAX_DELAY - Prior_Tick + Current_Tick == Delay_Time)
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
Prior_Tick = Current_Tick;
printf("Break down\n");
}
}
if(Current_Tick-Prior_Tick == Delay_Time) /* Satisfy delay */
{
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5); /* Change LED0 status */
Prior_Tick = Current_Tick; /* Update prior tick with current tick */
}
#endif
/* UartReady SET by HAL_UART_RxCpltCallback */
if(UartReady == SET)
{
UartReady = RESET;
if(Uart1_Rx_Count >= Uart1_RxBufferSIZE) /* Judge for the overflow of buffer zone */
{
Uart1_Rx_Count = 0; /* Reset the count for receiving */
memset(Uart1_RxBuffer,0x00,sizeof(Uart1_RxBuffer)); /* Re-memorize the buffer zone */
}
Uart1_RxBuffer[Uart1_Rx_Count] = RxBuffer_IT; /* Save a character in the array */
HAL_UART_Transmit(&huart1, (uint8_t *)&RxBuffer_IT, 1, 0xFFFF);
Uart1_Rx_Count++;
HAL_UART_Receive_IT(&huart1, (uint8_t *)&RxBuffer_IT, 1); /* Continue to receiving */
if((Uart1_RxBuffer[Uart1_Rx_Count-4] == 0x30)&& (Uart1_RxBuffer[Uart1_Rx_Count-2] == 0x0D) && (Uart1_RxBuffer[Uart1_Rx_Count-1] == 0x0A))
{
switch(Uart1_RxBuffer[Uart1_Rx_Count-3])
{
#ifdef LED_BLINK_DISABLE
case 0x31:
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5); /* Change LED0 status */
break;
#endif
case 0x32:
HAL_GPIO_TogglePin(GPIOE, GPIO_PIN_5); /* Change LED1 status */
break;
case 0x33:
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8); /* Buzzer open */
HAL_Delay(500);
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8); /* Buzzer close */
HAL_Delay(3000);
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8); /* Buzzer open */
HAL_Delay(500);
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_8); /* Buzzer close */
break;
default:
break;
}
Uart1_Rx_Count = 0;
memset(Uart1_RxBuffer,0x00,sizeof(Uart1_RxBuffer));
}
} /* end if*/
} /* end while*/
/* USER CODE END WHILE */
(6)回調函數
/* USER CODE BEGIN 4 */
/* UART receives completely callback */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
UartReady = SET; /* Reset the flag of interruption */
}
/* USER CODE END 4 */
4. 程式分析
4.1 主要功能
通過序列槽通訊接收指令,控制 LED 和蜂鳴器,指令采取16進制,同時開發闆序列槽并傳回接收到的資訊。
(1)指令集
30 31 0D 0A:控制 LED 0
30 32 0D 0A:控制 LED 1
30 33 0D 0A:控制蜂鳴器
(2)通過預定義控制 LED 0是否保持閃爍
不閃爍,接受序列槽控制
/* Uncomment this line to Disable LED Blink*/
#define LED_BLINK_DISABLE
保持閃爍,不接受序列槽控制
/* Uncomment this line to Enable LED Blink*/
#define LED_BLINK_ENABLE
4.2 程式流程
4.3 主要函數
(1)HAL_UART_Transmit_IT
(2)HAL_UART_Receive_IT