基于F411 标准库

第一步:配置对应GPIO口的结构体初始化,TX连RX、RX连TX,引脚复用功能

void Uart_GPIO_Config(void)
{
	/*串口GPIO配置函数*/
	GPIO_InitTypeDef GPIO_InitStruct;
	/*UART ->TX ->PA9*/
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
	
	GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_9;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
	
	/*UART ->RX ->PA10*/
	GPIO_InitStruct.GPIO_Pin  = GPIO_Pin_10;
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
}

第二步:中断配置

当接收到1个字节,就会产生RXNE中断;当接收到一帧数据,就会产生IDLE中断

void Uart_IT_Config(void)
{
	/*串口中断初始化函数*/
	USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
	USART_ITConfig(USART1,USART_IT_IDLE,ENABLE);
	
	NVIC_SetPriority(USART1_IRQn,NVIC_EncodePriority(7-2,1,2));
	NVIC_EnableIRQ(USART1_IRQn);
}

第三步:串口配置

包括GPIO初始化,中断初始化;波特率、位宽、停止位、校验位、模式、流控等

void Uart_Config(uint32_t Baud)
{
	Uart_GPIO_Config();
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
	
	USART_InitTypeDef USART_InitStruct;
	USART_InitStruct.USART_BaudRate = Baud;
  USART_InitStruct.USART_WordLength = USART_WordLength_8b;
  USART_InitStruct.USART_StopBits = USART_StopBits_1;
  USART_InitStruct.USART_Parity = USART_Parity_No ;
  USART_InitStruct.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
  USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;  
	USART_Init(USART1,&USART_InitStruct);

	Uart_IT_Config();
	
	USART_Cmd(USART1,ENABLE);
}

其他相关函数:

/*串口Usart1 发送单个字节函数*/
void Uart1_Sendbyte(uint8_t Byte)
{
	while(!(USART1->SR & (1<<7)));//当TDR忙->等待
	USART1->DR = Byte;
}

/*串口Usart1发送字符串*/
void Uart1_Sendstr(uint8_t *pstr)
{
		// 指针方式打印字符串
		while(*pstr != '\0') //循环体,若p指向数组中的值不为结束位则进入循环体打印
		{
			Uart1_Sendbyte(*pstr);
			pstr++;		//p指向后移,于第一句重指向数组首位
		}
}
/**************************
	串口Usart1 接受单个字节函数
***************************/
uint8_t Uart1_Recbyte(void)
{
	uint8_t byte  = 0;
	while(!(USART1->SR & (1<<5)));
	byte = USART1->DR;
	
	return byte;
}

/**************************
	串口Usart1 中断服务函数(标准库提供,不能改变)
***************************/
Usart1_recv_t Usart1_recv;//外部声明在.h声明,.c同时调用
void USART1_IRQHandler(void)
{
	if(USART_GetFlagStatus(USART1,USART_FLAG_RXNE))//判断标志
		{
			USART_ClearFlag(USART1,USART_FLAG_RXNE);
			Usart1_recv.recvbuff[Usart1_recv.recvcnt] = USART1->DR;
			Usart1_recv.recvcnt++;//移位复制存储
		}
	if(USART_GetFlagStatus(USART1,USART_FLAG_IDLE))//判断标志
		{
			USART1->SR;//读寄存器清楚标志
			USART1->DR;//读寄存器清楚标志
			Usart1_recv.recvbuff[Usart1_recv.recvcnt] = '\0';//结束标志
			Usart1_recv.recvflag = 1;//结束标志位
			Usart1_recv.recvcnt = 0; //重发字符串用
		}
}

/**************************
	重定向使用串口输出
***************************/
int fputc(int ch, FILE *f)
{
		Uart1_Sendbyte((uint8_t)ch);
		return ch;
}

基于F407 HAL库配置

串口配置(标准库、HAL库)_初始化串口配置(标准库、HAL库)_串口_02

串口配置(标准库、HAL库)_初始化_03

/**
  * 函数功能: 重定向c库函数printf到DEBUG_USARTx
  */
int fputc(int ch, FILE *f)
{
  HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xffff);
  return ch;
}
 
/**
  * 函数功能: 重定向c库函数getchar,scanf到DEBUG_USARTx
  */
int fgetc(FILE *f)
{
  uint8_t ch = 0;
  HAL_UART_Receive(&huart1, &ch, 1, 0xffff);
  return ch;
}