前言
为了使不同器件封装的外设 IO 功能数量达到最优,可以把一些复用功能重新映射到其他一些引脚上。STM32 中有很多内置外设的输入输出引脚都具有重映射(remap)的功能。我们知道每个内置外设都有若干个输入输出引脚,一般这些引脚的输出端口都是固定不变的,为了让设计工程师可以更好地安排引脚的走向和功能,在 STM32 中引入了外设引脚重映射的概念,即一个外设的引脚除了具有默认的端口外,还可以通过设置重映射寄存器的方式,把这个外设的引脚映射到其它的端口。简单的讲就是把管脚的外设功能映射到另一个管脚,但不是可以随便映射的,具体对应关系《STM32 中文参考手册 V10》的 P116 页“8.3 复用功能和调试配置”有讲解。《STM32 中文参考手册 V10》在我前面的文章中也有提到,并提供了下载地址。
软件配置
本例程以战舰开发板,配合STM32CubeMX工具来生成代码,来验证USART1的重映射功能。USART1默认的引脚是PA9和PA10,要想使用重映射功能,需要在STM32CubeMX软件中,先手动选择PB6和PB7引脚,配置为串口1的TX和RX,然后选择USART1,配置为一步模式,重映射就配置完成了。其他时钟及下载方式的配置,不再赘述。
代码分析
主要分析usart.c中的代码,需要关注的是标注的重映射的代码。这是最关键的代码,这行代码完成了USART1从PA9/PA10到PB6/PB7的重映射。
#include "usart.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
UART_HandleTypeDef huart1;
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**USART1 GPIO Configuration
PB6 ------> USART1_TX
PB7 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
__HAL_AFIO_REMAP_USART1_ENABLE();//重映射代码,正常的情况没有这句
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspDeInit 0 */
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
/**USART1 GPIO Configuration
PB6 ------> USART1_TX
PB7 ------> USART1_RX
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
/* USART1 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspDeInit 1 */
/* USER CODE END USART1_MspDeInit 1 */
}
}
为了测试串口,在main.c中添加了测试代码,在电脑端通过串口调试器,可以看到USART1发送的数据。
串口调试及硬件连接
战舰开发板PB6/PB7引脚通过排针引出来了,并且是TTL信号,战舰开发板自带TTL转USB模块(CH340G芯片),用杜邦线将PB7与P4接口的TXD引脚连接,PB6与RXD引脚连接,PB7/PB6相当于原来的PA10/PA9引脚。通过串口调试软件即可看到USART1发送的数据。
注意:USB连接线要插在战舰开发板的USB_232接口。
可以看到,串口调试软件接收的数据与USART1发送的数据一致,测试成功。
前言
为了使不同器件封装的外设 IO 功能数量达到最优,可以把一些复用功能重新映射到其他一些引脚上。STM32 中有很多内置外设的输入输出引脚都具有重映射(remap)的功能。我们知道每个内置外设都有若干个输入输出引脚,一般这些引脚的输出端口都是固定不变的,为了让设计工程师可以更好地安排引脚的走向和功能,在 STM32 中引入了外设引脚重映射的概念,即一个外设的引脚除了具有默认的端口外,还可以通过设置重映射寄存器的方式,把这个外设的引脚映射到其它的端口。简单的讲就是把管脚的外设功能映射到另一个管脚,但不是可以随便映射的,具体对应关系《STM32 中文参考手册 V10》的 P116 页“8.3 复用功能和调试配置”有讲解。《STM32 中文参考手册 V10》在我前面的文章中也有提到,并提供了下载地址。
软件配置
本例程以战舰开发板,配合STM32CubeMX工具来生成代码,来验证USART1的重映射功能。USART1默认的引脚是PA9和PA10,要想使用重映射功能,需要在STM32CubeMX软件中,先手动选择PB6和PB7引脚,配置为串口1的TX和RX,然后选择USART1,配置为一步模式,重映射就配置完成了。其他时钟及下载方式的配置,不再赘述。
代码分析
主要分析usart.c中的代码,需要关注的是标注的重映射的代码。这是最关键的代码,这行代码完成了USART1从PA9/PA10到PB6/PB7的重映射。
#include "usart.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
UART_HandleTypeDef huart1;
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**USART1 GPIO Configuration
PB6 ------> USART1_TX
PB7 ------> USART1_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_6;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
__HAL_AFIO_REMAP_USART1_ENABLE();//重映射代码,正常的情况没有这句
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
{
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspDeInit 0 */
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
/**USART1 GPIO Configuration
PB6 ------> USART1_TX
PB7 ------> USART1_RX
*/
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_6|GPIO_PIN_7);
/* USART1 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspDeInit 1 */
/* USER CODE END USART1_MspDeInit 1 */
}
}
为了测试串口,在main.c中添加了测试代码,在电脑端通过串口调试器,可以看到USART1发送的数据。
串口调试及硬件连接
战舰开发板PB6/PB7引脚通过排针引出来了,并且是TTL信号,战舰开发板自带TTL转USB模块(CH340G芯片),用杜邦线将PB7与P4接口的TXD引脚连接,PB6与RXD引脚连接,PB7/PB6相当于原来的PA10/PA9引脚。通过串口调试软件即可看到USART1发送的数据。
注意:USB连接线要插在战舰开发板的USB_232接口。
可以看到,串口调试软件接收的数据与USART1发送的数据一致,测试成功。
举报