1.Usart通过三根线外部来年再一起,TX、RX、CX,当他工作在异步串行模式时候,只需要TX、RX两根线就可以实现通信,同步模式下则要输出时钟,通过SCLK引脚输出。
2.一帧数据可编程选择为8位或者9位,一个数据字(8 或9位),最低有效位在前
3.可编程的停止位,停止位可以通过 编程设置成0.5,1,1.5,2 个的停止位,而其中并不是在每个模式下面都可以配置成这4种形式。
4.一个波特率寄存器(USART_BRR) ,12位的整数和4位小数,可以达到较高精度的波特率。
5.可以单独发送空闲符号,即包括停止位在内,全部是1;发送断开符号,包括停止位在内全是0.
6.分数波特率计算方法:
Tx / Rx 波特率 =fCK *16( USARTDIV)
USARTDIV是USART的分频因子,Fck是USART的系统输入时钟,它挂载在APB2上36M。
USARTDIV是USART的分频因子,Fck是USART的系统输入时钟,它挂载在APB2上36M。
上面就是配置比特率分频因子的寄存器,0~3位是小数部分的分频因子,4~15位整数部分的分频因子。
所以的到证书部分直接等于DIV_Mantissa,小数部分部分等于DIV_Fraction/16。
最高能达到的波特率是4.5Mbps,在参考手册525页中有典型条件下的波特率配置数据。
7.校验位
采用的是奇偶校验位的形式,PCE位来控制是否开启校验:
偶校验:校验位使得一帧中的7或8 个LSB 数据以及校验位中’1’ 的个数为偶数。
奇校验:此校验位使得一帧中的7或8个LSB 数据以及校验位中’1’ 的个数为奇数。
校验位也算作数据位中的一位,因此如果在8位模式下面开启了校验位,校验位占数据第8位,而实际数据位只有7位。
如果校验失败后将会产生校验失败的标志:PE标志被置’1’,如果USART_CR1 寄存器的PEIE在被预先设置的话,中断产生。
8.同步通信模式下面,sck发送主机的时钟,很类似SPI的通信方式。
9.数据发送和接收
数据发送:在TE(发送使能)位置1的情况下,想数据寄存器写数据,将会自动进入诗句移位发送的模式,并且此时TC=0,要进行下一次发送要等待TC(发送完成标志位)置位,TXE(发送寄存器位空)也会置位。如果使能了响应的中断,将会申请进入中断。
数据接收:在RE(接收使能)情况下,如果RXNE(接受寄存器非空)置位,表明有数据到,可以读取RDR处理数据。另外如果开启中断RXNEIE也可已进入中断服务函数来读取和处理数据
10.USART的中断映像
可见在所有的USART构成的中断中,只有一个中断通道连接到了CPU中断,而F103ZET共有三个USART所以有三个不同的通道。USART内部各种中断的优先级在中断函数通过软件实现。
11.基本的初始化步骤
挂载时钟,复用对应的TX,RX端口,初始化波特率分频的寄存器,设置位长,设置停止位的长度,设置校验位,通信方向,配置NVIC,使能需要的中断并设置中断服务函数
代码如下:
void USAR_start(u32 baud)
{
GPIO_InitTypeDef IO_USART; //Ìå
USART_InitTypeDef US1;
NVIC_InitTypeDef NVIC_InitStructure;
//¹ÒÔØIOʱÖÓ
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1,ENABLE);
USART_DeInit(USART1);
//½«TXDÒý½Å¸´ÓÃGPIOA9ÅäÖóÉÍÆÍìÊä³ö
IO_USART.GPIO_Pin = GPIO_Pin_9;
IO_USART.GPIO_Speed = GPIO_Speed_50MHz;
IO_USART.GPIO_Mode = GPIO_Mode_AF_PP;//±ð
GPIO_Init(GPIOA,&IO_USART);
//½«RXD½Å¸´ÓÃGPIO10ÅäÖóɸ¡¿ÕÊäÈë
IO_USART.GPIO_Pin = GPIO_Pin_10;
IO_USART.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA,&IO_USART);
//´®¿Ú²ÎÊý³õʼ»¯
US1.USART_BaudRate = baud;
US1.USART_WordLength = USART_WordLength_8b;
US1.USART_StopBits = USART_StopBits_1;
US1.USART_Parity = USART_Parity_No;
US1.USART_Mode =USART_Mode_Rx|USART_Mode_Tx;
US1. USART_HardwareFlowControl = USART_HardwareFlowControl_None;
USART_Init(USART1,&US1);
//¿ªÆôÖжÏ
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
//ÖжÏʹÄÜ
// USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//ʹÄÜ´®¿Ú
USART_Cmd(USART1, ENABLE);
}
//Êý¾Ý·¢ËÍ
void putchar(uint8_t ch)
{
USART_SendData(USART1, (uint8_t) ch); //ÏòDR¼ËÍ
while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET) //µ»
{
;
}
}
//Êý¾Ý½ÓÊÕ
uint8_t getchar(uint8_t ch)
{
while (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == RESET) //ÖÃλ
{
;
}
ch = USART_ReceiveData(USART1);
return ch;
}
void USART1_IRQHandler()
{
//在中断函数中接收和处理数据
}
USART使用和我之前使用SCI时很多是一样的,通信方式非常简单,可以相互套用。