串口接收和发送机理
首先我们要知道的是串口的工作机理,串口是通过数据帧的发送,假定我们使用的如下设置,波特率为9600,8位数据。其它的什么奇偶校验都不用。那么它与PC机之间的通信流程是怎么样的呢?第一,数据帧的大小是10位,包含起始位和结束位,起始位固定为0,结束位固定为1。比如现在PC机要向单片机传递数据,首先单片机检测到数据开始位0,那么单片机开始接受后面的数据,通过移位寄存器,一位一位将数据送入,当8位后,接收到结束标志,这个时候RI置位,单片机进入中断程序,软件置零RI,在最快的时间将SBUF中的值读取了,然后退出中断,等待下一个数据接收完毕,就这样将数据一个一个的传送进来。那么发送又是怎么样的呢?首先单片机将数据发送,然后在最后一位发送完毕后,TI置位,进入中断服务程序,将TI清零,接着发送下一个字节的数据,并且退出中断,等待发送完毕,就这样将数据一位一位发送出去。
如下为代码分析
第一段代码:
GPIO_InitTypeDef GPIO_Structure;
USART_InitTypeDef USART_Structure;
NVIC_InitTypeDef NVIC_Structure;
作用:实例化三组对象,GPIO_InitTypeDef为结构体类型的别名,GPIO_Structure为结构体变量名。GPIO_InitTypeDef相当于模板,根据这个模板可以new出具体的对象。
第二段代码:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//USART1是挂在APB2总线上
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
作用:第一句,使能复用外设(串口1作为内置外设)时钟,相当于打开时钟电路开关。
第二句,此处用到的引脚是PA9 PA10,GPIOA挂载在AHB1总线上,自然就要使能GPIO时钟。
第三段代码:
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);
作用:端口(引脚)复用,串口1 的发送接收引脚是PA9,PA10,当我们把PA9,PA10不用作普通的GPIO口,而把它复用为串口1的发送(TXD)接收(RXD)引脚的时候,叫端口复用
补充一下映射:
串口1的TX,RX引脚是在PA9,和PA10端口,但是同时它有两个映射端口PB6,PB7。开启重映射,PB6和PB7同样可以使用串口1。
第四段代码:初始化GPIO
//GPIO初始化
GPIO_Structure.GPIO_Pin=GPIO_Pin_9|GPIO_Pin_10;//选择引脚 PA9 PA10
GPIO_Structure.GPIO_Mode=GPIO_Mode_AF;//复用功能
GPIO_Structure.GPIO_Speed=GPIO_Speed_50MHz;//传输速度
GPIO_Init(GPIOA,&GPIO_Structure); //按照以上的参数初始化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
第五段代码:初始化串口1
//USART1串口初始化
USART_Structure.USART_BaudRate=9600; //波特率 调试助手必须和此参数一致
USART_Structure.USART_WordLength=USART_WordLength_8b;//字长为8位
USART_Structure.USART_StopBits=USART_StopBits_1;//停止位为1
USART_Structure.USART_Parity=USART_Parity_No;//无奇偶校验位
USART_Structure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//无硬件数据流控制
USART_Structure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; //收发模式
USART_Init(USART1,&USART_Structure);//按照以上参数初始化USART1串口
第六段:使能串口
USART_Cmd(USART1,ENABLE);
作用:打开USART1串口开关,相当于电源开关
第七段:使能或者失能指定的USART1串口中断,开启串口1接受中断的功能
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
第一个参数为使用串口1
第二个参数为中断标志,串口有很多种中断,这里是使用USART_IT_RXNE中断
第三个参数为使能
第八段:串口1的初始化
//usart1 的中断初始化
NVIC_Structure.NVIC_IRQChannel=USART1_IRQn; //stm32f4xx.h开头找
NVIC_Structure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Structure.NVIC_IRQChannelPreemptionPriority=1;
NVIC_Structure.NVIC_IRQChannelSubPriority=1;
NVIC_Init(&NVIC_Structure);