串行通信的通信方式:
STM32F4的串行通信接口
常见串行通信接口
通信标准 |
引脚说明 |
通信方式 |
通信方向 |
UART (通用异步收发器) |
TXD:发送端 RXD:接受端 GND:公共地 |
异步通信 |
全双工 |
单总线 (1-wire) |
DQ:发送/接受端 |
异步通信 |
半双工 |
SPI |
SCK:同步时钟 MISO:主机输入,从机输出 MOSI:主机输出,从机输入 |
同步通信 |
全双工 |
I2C |
SCL:同步时钟 SDA:数据输入/输出端 |
同步通信 |
半双工 |
STM32F4的通信引脚(适用于STM32F407ZGT6)
串口号 |
RXD |
TXD |
1 |
PA10(PB7) |
PA9(PB6) |
2 |
PA3(PD6) |
PA2(PD5) |
3 |
PB11(PC11/PD9) |
PB10(PC10/PD8) |
4 |
PC11(PA1) |
PC10(PA0) |
5 |
PD2 |
PC12 |
6 |
PC7(PG9) |
PC6(PG14) |
STM32F4异步通信方式特点:
STM32F4串口通信过程:
正常模式下:需要RX和TX引脚,并作如下配置
同步模式下需要连接SCLK引脚:该引脚用于输出发送器的数据时钟,以便按照SPI主模式进行同步发送。
空闲字符:整个帧周期内电平均为1(停止位电平也为1)
停止字符:一个帧周期内接收到的电平均为0
发送和接收由通用波特率发生器驱动。发送器和接收器的使能位分别置1时将生成相应的发送时钟和接收时钟。
发送器:发送器可以发送8位或9位的数据字,具体取决于M位的状态。发送使能位TE置1时,发送移位寄存器的数据在TX引脚输出,相应的时钟脉冲在SCLK引脚输出。
字符发送:每个字符前都有一个起始位,其逻辑电平在一个周期内均为低电平,字符由可配置数量的停止位停止。
配置步骤:
接收器:USART可以接收8位或9位的数据
起始位检测:16倍或8倍过采样时,起始位检测序列相同。在USRAT中检测到特定序列的采样时会检测到起始位。
字符接收:USART接收期间,首先通过RX引脚移入数据的最低有效位
配置步骤:
小数波特率生成:对USARTDIV的尾数值和小数值进行编程时,接收器和发送器(RX和TX)的波特率均设置为相同值
公式一:适用于标准USART(包括SPI模式)的波特率
公式二:适用于智能卡、LIN和IrDA模式下的波特率
USARTDIV是一个存放在USART_BRR寄存器中的无符号定点数
串口模式配置:
USART模式 |
USART1 |
USART2 |
USART3 |
USART4 |
USART5 |
USART6 |
异步模式 |
支持 |
支持 |
支持 |
支持 |
支持 |
支持 |
硬件流模式 |
支持 |
支持 |
支持 |
不支持 |
不支持 |
支持 |
多缓冲区通信 |
支持 |
支持 |
支持 |
支持 |
支持 |
支持 |
多处理器通信 |
支持 |
支持 |
支持 |
支持 |
支持 |
支持 |
同步 |
支持 |
支持 |
支持 |
不支持 |
不支持 |
支持 |
智能卡 |
支持 |
支持 |
支持 |
不支持 |
不支持 |
支持 |
半双工 |
支持 |
支持 |
支持 |
支持 |
支持 |
支持 |
IrDA |
支持 |
支持 |
支持 |
支持 |
支持 |
支持 |
LIN |
支持 |
支持 |
支持 |
支持 |
支持 |
支持 |
串口通信的实例设置:
串口作为STM32F4的一个外设,其时钟由外设时钟使能寄存器控制
串口号 |
时钟寄存器 |
使能命令 |
USART1 |
RCC_APB2ENR |
RCC->APB2ENR|=1<<4 |
USART2 |
RCC_APB1ENR |
RCC->APB1ENR|=1<<17 |
USART3 |
RCC_APB1ENR |
RCC->APB1ENR|=1<<18 |
USART4 |
RCC_APB1ENR |
RCC->APB1ENR|=1<<19 |
USART5 |
RCC_APB1ENR |
RCC->APB1ENR|=1<<20 |
USART6 |
RCC_APB2ENR |
RCC->APB2ENR|=1<< 5 |
通过给波特率寄存器赋值直接设置串口波特率,RCC->BRR=arr;
通过串口控制寄存器RCC_CR1对串口进行相应的设置:
UE:置1使能USART,该位为0则USART预分频器和输出将停止
M:设定字长(0:1起始位,8数据位,n停止位;1:1起始位,9数据位,n停止位;)
OVER:采样模式设置(0:16倍过采样;1:8倍过采样)
RXNEIE:
TE:发送使能位
RE:接收使能位
STM32F4的发送与接收是通过数据寄存器USART_DR来实现的,是一个双寄存器包含了TDR和RDR
串口状态通过串口状态寄存器获得,RXNE(读数据寄存器非空)该位为1时说明数据已经被接收到了USART_DR中,可以读取出来。
TC(发送完成)该位被置1说明USART_DR中的数据已经发送完成了。
void uart_init(u32 pclk2,u32 bound)
{
float temp;
u16 mantissa;
u16 fraction;
temp=(float)(pclk2*1000000)/(bound*16);//得到USARTDIV@OVER8=0
mantissa=temp; //得到整数部分
fraction=(temp-mantissa)*16; //得到小数部分@OVER8=0
mantissa<<=4;
mantissa+=fraction;
RCC->AHB1ENR|=1<<0; //使能PORTA口时钟
RCC->APB2ENR|=1<<4; //使能串口1时钟
GPIO_Set(GPIOA,PIN9|PIN10,GPIO_MODE_AF,GPIO_OTYPE_PP,GPIO_SPEED_50M,GPIO_PUPD_PU);//PA9,PA10,复用功能,上拉输出
GPIO_AF_Set(GPIOA,9,7); //PA9,AF7
GPIO_AF_Set(GPIOA,10,7);//PA10,AF7
//波特率设置
USART1->BRR=mantissa; //波特率设置
USART1->CR1&=~(1<<15); //设置OVER8=0
USART1->CR1|=1<<3; //串口发送使能
#if EN_USART1_RX //如果使能了接收
//使能接收中断
USART1->CR1|=1<<2; //串口接收使能
USART1->CR1|=1<<5; //接收缓冲区非空中断使能
MY_NVIC_Init(3,3,USART1_IRQn,2);//组2,最低优先级
#endif
USART1->CR1|=1<<13; //串口使能
}