基于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库配置
/**
* 函数功能: 重定向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;
}