目录
1.串口原理介绍
2.串口初始化
详情代码见最终的代码界面
2.1 开启串口时钟
方案里使用到的是USART1串口,然后查询单片机对应芯片型号的时钟图,时钟图详情以官方英文【数据手册】中14页图3为准。
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE);
2.2 串口信息配置
方法1:操纵对应寄存器实现串口初始化。
方法2:利用封装好库函数,查询库函数中文手册,或者在库函数文件中查询对应的结构体,在此基础上修改。(因为没找到中文库函数文件,所以我这里是在对应的.c库函数中查找的)
(库函数的很多操作其实是结构体以及函数的运用)
头部自定义一个结构体变量(名称尽量与库文件中的名称接近);中间六条语句是引用的前文,部分信息根据需求修改;尾部利用的是库函数中的串口初始化函数USART_Init(串口名称, &声明的串口结构体名称);
USART_InitTypeDef USART_InitStruct={0}; //声明结构体变量USART_InitStruct并赋初值0
USART_InitStruct.USART_BaudRate = 115200; //波特率115200,9600,4800
USART_InitStruct.USART_WordLength = USART_WordLength_8b; //数据长度为8位
USART_InitStruct.USART_StopBits = USART_StopBits_1; //停止位长度为1位
USART_InitStruct.USART_Parity = USART_Parity_No; //奇偶校验 不校验
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //发送和接收
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None; //硬件流失能
USART_Init(USART1, &USART_InitStruct);
2.3 使能串口
直接使用下列函数实现:
USART_Cmd(USART1,ENABLE); //使能串口
2.4 串口代码
//USART初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE); //开启USART1时钟
USART_InitTypeDef USART_InitStruct={0}; //声明结构体变量USART_InitStruct并赋初值0
USART_InitStruct.USART_BaudRate = 115200; //波特率115200,9600,4800
USART_InitStruct.USART_WordLength = USART_WordLength_8b; //数据长度为8位
USART_InitStruct.USART_StopBits = USART_StopBits_1; //停止位长度为1位
USART_InitStruct.USART_Parity = USART_Parity_No; //奇偶校验 不校验
USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx; //发送和接收
USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//硬件流失能
USART_Init(USART1, &USART_InitStruct);
USART_ITConfig(USART1, USART_IT_RXNE,ENABLE); //[使能串口接收中断]使能或者失能指定的USART中断,参数1:USARTx,参数2:USART_IT,参数3:ENABLE/DISABLE
USART_Cmd(USART1,ENABLE); //使能串口
}
3.编辑串口函数
知识点:
1.库函数:USART_GetFlagStatus检查标志位
详情可以参考固件库用户手册,或者参考一下截图
3.1 串口发送函数
因为串口发送数据是按照单个字节,也就是8位传输,所以带入了8位的一个形参uint8_t str;
利用数据发送函数,向USART1串口写入信息str。
void Usart1_Send(uint8_t str)
{
while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==0){}
USART_SendData(USART1,str);
}
3.2 串口接收函数
uint8_t Usart1_Receive(void)
{
uint8_t RxData = 0;
while(USART_GetFlagStatus(USART1,USART_FLAG_RXNE)==0){}
RxData = USART_ReceiveData(USART1); //接收USART1串口返回的数据
return RxData;
}
4.根据需求,开启相关中断。
4.1 中断初始化
可以和串口初始化放在一块
//中断初始化
NVIC_InitTypeDef NVIC_InitStructure = {0};
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //中断通道在stm32f10x.h里找
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //抢占优先级设置
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //响应优先级设置
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能
NVIC_Init(&NVIC_InitStructure);
4.2 中断函数
//中断服务函数(目前只开了一个串口接收中断)
void USART1_IRQHandler(void)
{
/*
1.判断是哪一个中断触发了
2.清理中断标志
3.执行的代码
*/
uint8_t data = 0;if(USART_GetITStatus(USART1,USART_IT_RXNE)==1)
{
USART_ClearITPendingBit(USART1,USART_IT_RXNE);
data=USART1->DR;
USART3->DR=data;
}
if(USART_GetITStatus(USART1,USART_IT_IDLE)==1)
{
data=USART1->SR; //寄存器先读SR,再读DR,清理标志。
data=USART1->DR;
}
}