一、串口初始化
1、开对应时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
2、配置GPIO
GPIO_InitTypeDef GPIO_InitStructure1;
GPIO_InitStructure1.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure1.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure1.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure1);
GPIO_InitStructure1.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure1.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure1.GPIO_Speed = GPIO_Speed_10MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure1);
3、配置USART
USART_InitTypeDef USART_InitStructure;
USART_InitStructure.USART_BaudRate = 9600;
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
USART_InitStructure.USART_Parity = USART_Parity_No;
USART_InitStructure.USART_StopBits = USART_StopBits_1;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
USART_Init(USART1, &USART_InitStructure);
4、开启串口接收中断、配置NVIC
//开启中断:开启RXNE标志位到NVIC的输出
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//配置NVIC
//分组
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//初始化NVIC的USART1通道
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_Init(&NVIC_InitStructure);
5、使能串口功能
//如果只需要发送的功能,直接开启USART就行了,如果需要接收的功能,还需要配置中断
USART_Cmd(USART1, ENABLE);
二、发送一个字节
void serial_sendbyte(uint8_t byte)
{
USART_SendData(USART1, byte);
//发送之后等待TDR数据 转移到 移位寄存器,这里判断标志位
while( USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
//这里不需要对标志位清零,下次发送时会自动清零
}
三、发送一个数组
void serial_sendarray(uint8_t *array, uint16_t length)
{
uint16_t i;
for(i = 0; i < length; i++)
{
serial_sendbyte(array[i]);
}
}
四、发送一个字符串
void serial_sendstring(char *string)
{
while( *string != '\0')
{
serial_sendbyte(*string);
string++;
}
}
五、获取一个数的N次方
int serial_pow(int x, int y)
{
int result = 1;
while(y--)
{
result *= x;
}
return result;
}
六、发送一个数字
void serial_sendnumber(int number, int length)
{
for(int i = 0; i < length; i++)
{
serial_sendbyte(number / serial_pow(10, length - 1 - i) % 10 + '0');
}
}
七、重写printf
int fputc(int ch, FILE *f)
{
serial_sendbyte(ch);
return ch;
}
八、封装sprintf
void serial_printf(char *format, ...)
{
char string[100];
va_list arg; //参数列表变量
va_start(arg, format); //从format位置开始接收参数表,放在arg里
vsprintf(string, format, arg); //参考sprintf函数定义
va_end(arg);//释放参数表
serial_sendstring(string); //发送string
}
九、串口中断接收处理函数
void USART1_IRQHandler(void)
{
if(USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET)
{
serial_rxdata = USART_ReceiveData(USART1);
//该标志位用于判断是否中断接收到数据
serial_rxflag = 1;
USART_ClearITPendingBit(USART1, USART_IT_RXNE);
}
}