一.基础知识
1.串口通信的分类
因为同步的是不管什么直接发送,通过一条时钟线来确定数据的先后关系,保持它的有序性。而异步则是一个一个的发送,不用时间线来确定数据的有序性。
所以:同步带时钟信号线,如SPI、IIC。异步不带时钟信号线,如UART。
搬出官方的一张表:
通信标准
| 引脚说明
| 通信方式
| 通信方向
|
UART
(通用异步收发器)
| TXD:发送端
RXD:接受端
GND:公共地
| 异步通信
| 全双工
|
单总线
(1-wire)
| DQ:发送/接受端
| 异步通信
| 半双工
|
SPI
| SCK:同步时钟
MISO:主机输入,从机输出
MOSI:主机输出,从机输入
| 同步通信
| 全双工
|
I2C
| SCL:同步时钟
SDA:数据输入/输出端
| 同步通信
| 半双工
|
2.中断的优先级
32的中断具有分级,以便管理。其有两个优先级:抢占优先级 & 响应优先级。抢占优先级>响应优先级,0~4的优先级,0最大,4最小。在SCB->AIRCR中配置(反正我还是不会配置)。
二.实例操作
1.中断的配置
中断的配置,需要遵循:先分组,再设置优先级
分组:(不知道为什么,默认分组2就可以了)
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
设置:
NVIC_InitTypeDef NVIC_InitStructure; //定义结构体
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//中断通道选择,我也不知道有哪些参数。串口1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;// 抢占优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 子优先级位2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能通道的设置,我也不知道。IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据上面指定的参数初始化NVIC寄存器
2.串口的配置
在正点原子的开发板里面提供了串口的配置文件Urat.c
如同官方PPT的内容:
①串口时钟使能,GPIO时钟使能:RCC_APB2PeriphClockCmd();
②串口复位:USART_DeInit(); 这一步不是必须的
③GPIO端口模式设置:GPIO_Init(); 模式设置为GPIO_Mode_AF_PP
④串口参数初始化:USART_Init();
⑤开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤)
NVIC_Init();
USART_ITConfig();
⑥使能串口:USART_Cmd();
⑦编写中断处理函数:USARTx_IRQHandler();
void uart_init(u32 bound){
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
//USART1_RX GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART1, &USART_InitStructure); //初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
USART_Cmd(USART1, ENABLE); //使能串口1
}
3.串口中断的实际操作:
void USART1_IRQHandler(void) //串口1中断服务程序
if(USART_GetITStatus(USART1, USART_IT_RXNE)
{这里面放置串口成功接收的代码}
u8 USART_ReceiveData(USART1); //这是一个读取缓存数据的代码
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//等待发送完成
USART_SendData(USART1,u8) //这是发送数据的代码
或者可以通过直接使用Usart库里面的通信协议,采用Usart.c的文件进行串口访问。其协议是文本的结束符为0x0D和0x0A
然后需要配置新的管脚,原管脚可以不用配置。并添加新的代码,故串口的配置可以将上文中的代码全部复制,然后更改管脚为映射后的管脚,然后添加:
重映射IO口时钟使能:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
重映射开启:
GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);
快捷模板:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);
一.基础知识
1.串口通信的分类
因为同步的是不管什么直接发送,通过一条时钟线来确定数据的先后关系,保持它的有序性。而异步则是一个一个的发送,不用时间线来确定数据的有序性。
所以:同步带时钟信号线,如SPI、IIC。异步不带时钟信号线,如UART。
搬出官方的一张表:
通信标准
| 引脚说明
| 通信方式
| 通信方向
|
UART
(通用异步收发器)
| TXD:发送端
RXD:接受端
GND:公共地
| 异步通信
| 全双工
|
单总线
(1-wire)
| DQ:发送/接受端
| 异步通信
| 半双工
|
SPI
| SCK:同步时钟
MISO:主机输入,从机输出
MOSI:主机输出,从机输入
| 同步通信
| 全双工
|
I2C
| SCL:同步时钟
SDA:数据输入/输出端
| 同步通信
| 半双工
|
2.中断的优先级
32的中断具有分级,以便管理。其有两个优先级:抢占优先级 & 响应优先级。抢占优先级>响应优先级,0~4的优先级,0最大,4最小。在SCB->AIRCR中配置(反正我还是不会配置)。
二.实例操作
1.中断的配置
中断的配置,需要遵循:先分组,再设置优先级
分组:(不知道为什么,默认分组2就可以了)
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
设置:
NVIC_InitTypeDef NVIC_InitStructure; //定义结构体
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//中断通道选择,我也不知道有哪些参数。串口1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;// 抢占优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 子优先级位2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//使能通道的设置,我也不知道。IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据上面指定的参数初始化NVIC寄存器
2.串口的配置
在正点原子的开发板里面提供了串口的配置文件Urat.c
如同官方PPT的内容:
①串口时钟使能,GPIO时钟使能:RCC_APB2PeriphClockCmd();
②串口复位:USART_DeInit(); 这一步不是必须的
③GPIO端口模式设置:GPIO_Init(); 模式设置为GPIO_Mode_AF_PP
④串口参数初始化:USART_Init();
⑤开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤)
NVIC_Init();
USART_ITConfig();
⑥使能串口:USART_Cmd();
⑦编写中断处理函数:USARTx_IRQHandler();
void uart_init(u32 bound){
//GPIO端口设置
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
//USART1_TX GPIOA.9
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
//USART1_RX GPIOA.10初始化
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
//USART 初始化设置
USART_InitStructure.USART_BaudRate = bound;//串口波特率
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART1, &USART_InitStructure); //初始化串口1
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
USART_Cmd(USART1, ENABLE); //使能串口1
}
3.串口中断的实际操作:
void USART1_IRQHandler(void) //串口1中断服务程序
if(USART_GetITStatus(USART1, USART_IT_RXNE)
{这里面放置串口成功接收的代码}
u8 USART_ReceiveData(USART1); //这是一个读取缓存数据的代码
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//等待发送完成
USART_SendData(USART1,u8) //这是发送数据的代码
或者可以通过直接使用Usart库里面的通信协议,采用Usart.c的文件进行串口访问。其协议是文本的结束符为0x0D和0x0A
然后需要配置新的管脚,原管脚可以不用配置。并添加新的代码,故串口的配置可以将上文中的代码全部复制,然后更改管脚为映射后的管脚,然后添加:
重映射IO口时钟使能:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
重映射开启:
GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);
快捷模板:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
GPIO_PinRemapConfig(GPIO_Remap_USART1,ENABLE);
举报