串行口
一 串口基础知识
串行接口(Serial port)"同步/异步串行接收/发送器。"又称“串口”USART,也称串行通信接口(通常指COM接口),是采用串行通信方式的扩展接口。
2、USART的用处
基于ARM Cortex-M3内核的STM32微控制器有强大的仿真调试单元,通过标准的JTAG调试设备可以完成对其进行实时监控任务。但是即便如此,USART的存在仍然无法忽视,如在一些数据通信复杂的总线网络,只有使用**USART才可以实时地查看该网络内部的数据流。**退一步来说,众多的上位机软件,大多也都是通过USART与主控器完成通信的。
3、USART的用途
STM32的USART除了其最根本的串行通信功能之外,还可以用于LIN总线应用(一种总线,常用与汽车电子领域)、IRDA(红外通信)应用、Smart-Card(智能卡)应用等。配合STM32的DMA单元可以得到更为快速的串行数据传输,而众多的错误检测功能足以保证USART通信的稳定与可靠。
4、USART 与 UART的区别
同步(UART)、同步/异步(USART)区别:同步与异步的显著区别在于是否具有同一时钟源;
基本的通信方式有两种:并行通讯和串行通讯。
二、通信方式
1、并行通信(parallelcommunication)
所传送数据的各个位是同时发送或接收。其特点:在并行通信中,一个并行数据占多少位二进制数,就要多少根传输线,这种方式的特点是通信速度快,但传输线多,价格较贵,适合近距离传输。
2、串行通信(serial communication)
所传送数据的各位按顺序一位一位地发送或接收(如图1.1(b)所示)。其特点:串行通信仅需1~2根传输线,故在长距离传输数据时比较经济,但由于它每次只能传送1位,所以传送速度较慢(但在现代编码技术的加持下串行通信的传输速率也很高)
TX/RX:发送线/接收线
3、通信工作方式
三、异步通讯数据格式
在异步通信中数据或字符是逐帧(frame)传送的。帧定义为一个字符的完整的通信格式,通常也称为帧格式。最常见的帧格式一般是先用一个起始位(低电平“0”)表示字符的开始;然后是5~8位数据(D0-D7),规定低位在前,高位在后;其后是奇偶校验位;最后是停止位(高电平“1”),用以表示字符的结束。从起始位开始到停止位结束就构成完整的1帧。
① 起始位:使用1个位的低电平“0”来表示通信的开始。
② 数据位:串行通信所需要传输的数据,数据位的长度为5~8位(上位机决定)(常用的数据位长度为8位)。
③ 校验位:校验位在串行通信中是可选项,用于校验数据传输的正确性。校验方法为“奇校验”和“偶校验”,不校验。
- 奇校验:数据位加上校验位后,使得传输的数据中数字“1”的个数为奇数。
- 偶校验:数据位加上校验位后,使得传输的数据中数字“1”的个数为偶数。
④ 停止位:用来表示数据通信的结束,使用1个位的高电平“1”来表示,停止位长度为0.5位、1位、1.5位或2位(停止位长度是指停止位数据多占用的时间)。停止位的位数越大,不同时钟同步的容忍程度越高,但是传输的速度越慢。
四、 串行通信数据传输速度
1、波特率概述
串行通信数据传输的速度称为波特率(也称为比特率),是指一秒钟内所传输数据的位的个数(Bit Per Second),英文简称BPS。
2、波特率计算
假设数据传输的速率为120个字符每秒,每个字符由1个起始位、8个数据位、1个停止位构成,请问其传输的波特率是多少?
每个字符占用的位数:10bit(1+8+1)
每秒传输的位数:10 * 120 = 1200/S = 1200波特率
四、程序实现
1、串口程序编写步骤
串口设置的一般步骤可总结为以下步骤
- 1、串行口时钟使能,GPIO时钟使能
- 2、串行口复位
- 3、GPIO 端口模式设置
- 4、串口参数初始化
- 5、开启中断并且初始化 NVIC (如果需要开启才需要这个步骤)
- 6、使能端口
- 7、编写中断处理函数
2、串口初始化程序
void USART1_Config(unsigned int bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
/* 配置串口1 (USART1) 时钟*/
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 | RCC_APB2Periph_GPIOA, ENABLE);
/*串口GPIO端口配置*/
/* 配置串口1 (USART1 Tx (PA.09))*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 配置串口1 USART1 Rx (PA.10)*/
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
/* 串口1模式(USART1 mode)配置 */
USART_InitStructure.USART_BaudRate = bound;//一般设置为9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;
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);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断
USART_Cmd(USART1, ENABLE); //使能串口
}
3、串行口中断配置
/*Usart 中断 配置*/
void NVIC_Configuration(void) // 函数名不可改变
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0);
/* 使能串口1中断 */
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; // 子优先级 0
/*IRQ通道使能*/
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
/*根据NVIC_InitStruct中指定的参数初始化外设NVIC寄存器USART1*/
NVIC_Init(&NVIC_InitStructure);
}
4、主函数(发送接收到的数据)
#include "stm32f10x.h"
#include "usart1.h"
#include "LED.h"
#include "delay.h"
#include "stdio.h"
int main(void)
{
LED_GPIO_Config();
USART1_Config(115200);
NVIC_Configuration();
printf("请开始输入字符串:\n");
while(1)
{
GPIO_WriteBit(GPIOA, GPIO_Pin_8, (BitAction)(1-(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_8))));
Delay(0x1FFFFF);
}
}