也是使用HAL库进行配置,通过STMCube生成代码,可以通过这个简单的配置过程看到STMCube生成代码的一种规范;
从main函数入手观察其外设配置结构:
首先是HAL_Init()进行所有外设的复位、初始化Flash接口和SysTick时钟;
其次是对时钟系统(外接晶振、SYSCLK、外设时钟)的配置SystemClock_Config();
接下来是外设的配置,由于所用的GPIO都是用UART,因此MX_GPIO_Init()中配置GPIO时钟,MX_USART3_UART_Init()中配置串口外设和GPIO;
int main(void)
{
/* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init(); /* Configure the system clock */
SystemClock_Config(); /* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_USART3_UART_Init();
MX_USART1_UART_Init(); /* Infinite loop */
/* USER CODE BEGIN WHILE */
while ()
{
/* USER CODE END WHILE */
printf("AAAAA");
HAL_Delay();
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
看一下串口的配置,其配置本身和标准库函数相似,配置的内容相差不多,是互通的,只不过分成了两个部分;包含两个部分:
第一个部分是串口UART本身的配置:MX_USART1_UART_Init()
第二部部分是串口所用GPIO的配置:HAL_UART_MspInit()
void MX_USART2_UART_Init(void)
{
huart2.Instance = USART2;
huart2.Init.BaudRate = ;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
huart2.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart2.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
} void HAL_UART_MspInit(UART_HandleTypeDef* huart)
{
GPIO_InitTypeDef GPIO_InitStruct = {};
if(huart->Instance==USART1)
{
/* Peripheral clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART1 GPIO Configuration
PA9 ------> USART1_TX
PA10 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
else if(huart->Instance==USART2)
{
/* Peripheral clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF1_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
else if(huart->Instance==USART3)
{
/* Peripheral clock enable */
__HAL_RCC_USART3_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**USART3 GPIO Configuration
PB10 ------> USART3_TX
PB11 ------> USART3_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_11;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_USART3;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
}
这里采用了printf输出,因此有几点需要注意:
第一点:需要在CodeGeneration中设置勾选Use MicroLIB;
第二点:添加对printf函数的支持与修改
由于使用的是HAL_UART_Transmit()函数进行传输,因此其传输模式比较受限,在中断和DMA模式下传输需要单独的对寄存器操作而不是使用HAL自带的库;
#include "stdio.h" #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__ */
/**
* @brief Retargets the C library printf function to the USART.
* @param None
* @retval None
*/
PUTCHAR_PROTOTYPE
{
/* Place your implementation of fputc here */
/* e.g. write a character to the EVAL_COM1 and Loop until the end of transmission */
HAL_UART_Transmit(&huart1, (uint8_t *)&ch, , 0xFFFF);
return ch;
}
第三点:printf的用法在HAL库中依然可以适用,如下图:
printf("Final:%d \n", Module_Baudrate);