USARTx串口 编程步骤
USARTx串口编程步骤:
第一部分配置串口
步骤一加入以下头文件:
#include "stm32f10x_lib.h"
//若使用RCC_Configuration( ); 使能GPIO外设对应的时钟,还必须加入以下头文件。//若使用具体的使能外设命令(例如,RCC_APB2PeriphClockCmd( )等),则不需要加入以下命令。
#include "HelloRobot.h"
步骤二定义用于初始化USARTx串口参数的结构体变量,
同时定义用于初始化GPIOx 端口参数的结构体变量:
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
这里顺便也定义初始化GPIOx 端口参数的结构体变量。
!!原因是:串口是通过IO 口来进行发送和接收的。
步骤三使能USARTx串口外设对应的时钟(以使能USART1为例)同时使能GPIO端口外设对应的时钟:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 |RCC_APB2Periph_GPIOA,ENABLE);
详细说明见:“在使用USART串口时,首先要使能该外设对应的时钟.doc”
或
/* Configure the system clocks */
RCC_Configuration( ); //(mxchip公司该函数中,需手动加入上行语句,鸥鹏公司已有)
步骤四定义USARTx串口的波特率、字长、停止位、奇偶效验位、发送接收模
式和硬件流控制,即定义USARTx串口的初始化参数(通过为结构体变量USART _InitStructure 的成员赋值实现;
同时定义GPIOx端口管脚、响应速度、工作模式,即定义GPIO端口的初始化参数(通过为结构体变量GPIO_InitStructure 的成员赋值实现):
USART_https://www.360docs.net/doc/2910685504.html,ART_BaudRate = 115200;
USART_https://www.360docs.net/doc/2910685504.html,ART_WordLength = USART_WordLength_8b;
USART_https://www.360docs.net/doc/2910685504.html,ART_StopBits = USART_StopBits_1;
USART_https://www.360docs.net/doc/2910685504.html,ART_Parity = USART_Parity_No;
USART_https://www.360docs.net/doc/2910685504.html,ART_Mode = USART_Mode_Rx | USART_Mode_Tx; USART_https://www.360docs.net/doc/2910685504.html,ART_HardwareFlowControl =
USART_HardwareFlowControl_None;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
注意:
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;不能设置成为
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
否则,无法在PC显示屏上,输出欲显示的字符。
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
步骤五(调用函数USART_Init()来)初始化USARTx串口,(完成对串口中
的寄存器的设置。)
(调用函数GPIO_Init()来)初始化GPIOx端口,(完成对端口中的寄存器的设置。)
代码如下:
USART_Init(USART1, &USART_InitStructure);
GPIO_Init(GPIOx , &GPIO_InitStructure);
步骤六调用xxx_Cmd(xxx,ENABLE)函数,来使能USARTx串口外设:
这里只需要使能USART即可。GPIO端口外设,没有使能即可使用。
USART_Cmd(USART1,ENABLE);
【若使用中断方式来触发串口收发数据,则必须:
调用USART_ITConfig()函数,来使能串口发送和接收的中断:
由于使用中断方式来触发串口收发数据,因此,我们在使能串口之时,也使能串口发送和接收中断:
USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //使能串口接收中断:接收缓冲区非空中断使能,即当接收寄存器(RDR)接收到数据,即非空时,产生中断。USART_ITConfig(USART1,USART_IT_TXE,ENABLE);//使能串口发送中断:发送缓冲区空中断使能,即当发送寄存器(TDR)中的数据被硬件转移到移位寄存器,为空的时候,产生中断。】
第二部分操作串口,收发数据
步骤七通过串口收发数据:
【法一】通过USART_SendData( )或USART_ReceiveData()来收发串口数据USART_SendData(USART_TypeDef*USARTx, u8Data);
USART_ReceiveData(USART_TypeDef*USARTx);
例子,
例一发送数据:
我们的程序在初始化串口之后,马上就可以在电脑屏幕上输出信息。也就
是从STM32 的CPU 发送信息,在电脑屏幕上显示出来,只要如下操作即可:/*===============USART 打印欢迎信息=======================*/
for( i = 0; TxBuf1[i] != '\0'; i++) {
USART_SendData(USART1 , TxBuf1[i]);
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE)==RESET); //当USART_FLAG_TXE=0时,表示发送还未完成,继续while循环,直到USART_FLAG_TXE=1,发送完成,结束循环。
}
其中,①TxBuf1 是一个发送缓存。需要传送的数据放在这个数组里:
例如,unsigned char TxBuf1[100]= "这里可以自定义需要输出到串口的字符";
②每发送完或接收到一个字符后,必须查看状态标志(
发送数据寄存器空标志位USART_FLAG_TXE
或接收数据寄存器非空标志位:USART_FLAG_RXNE),
发送完标志:USART_FLAG_TC
当发送数据寄存器为空时(即USART_FLAG_TX E = 1),才可以发送下一个数据。
函数USART_GetFlagStatus():就是用来做这个判断的。
RESET = 0,SET =1
注意:不能用发送完成标志位USART_FLAG_TC,来判断是否可发送下一个数据,否则,会出现输出的第一个字符,始终无法显示,只能显示其它字符。
USART_SR寄存器(包括发送数据寄存器空标志位TXE,读数据寄存器非空标志位RXNE等)
对其中的标志位TXE、RXNE的说明:
i)标志位TXE:
①TXE位被置位:当TDR寄存器中的数据被硬件转移到移位寄存器的时候,该位被硬件置位。如果USART_CR1寄存器中的TXEIE为1,则产生中断。
②对TXE位清除:
对USART_DR的写操作,将该位清零。
ii)标志位RXNE:
①RXNE位被置位:它表明移位寄存器的内容被转移到RDR。换句话说,数据已经被接收并且可以被读出(包括与之有关的错误标志)。
②对RXNE位清0:
在单缓冲器模式里,【方法一】由软件读USART_DR寄存器完成对RXNE位清除。
【方法二】RXNE标志也可以通过对它写0来清除。
RXNE位必须在下一字符接收结束前被清零,以避免溢出错误。
数据只有当RXNE位被清零后才能从移位寄存器转移到RDR寄存器。RXNE标记
是接收到每个字节后被置位的。
例二接收数据
在键盘上,输入的字符,通过串口调试助手软件向STM32单片机发送字符;STM32单片机收到这些字符后,回传给PC机,在PC屏幕上显示出来。
注意:串口调试助手的单选项“HEX发送”的勾要去掉,如下图所示。
u8 i; //或 int i;
while(1)
{
if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE)==SET)
// if (USART_GetFlagStatus(USART1, USART_IT_RXNE))
{
i=USART_ReceiveData(USART1);
USART_SendData(USART1,i);//printf(“%c \n\r”, i); //echo the input character // USART_SendData(USART1, USART_ReceiveData(USART1));
}
}
或
u8 i; //或 int i;
while(1)
{
if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE)==SET)
// if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE))
{
USART_ClearFlag(USART1, USART_FLAG_TXE);
i=USART_ReceiveData(USART1);
USART_SendData(USART1,i);//printf("%c \n\r", i); //echo the input character
// USART_SendData(USART1, USART_ReceiveData(USART1));
USART_ClearFlag(USART1, USART_FLAG_RXNE);
}
}
【法二】使用printf( )函数,通过串口发送数据
必须重定向printf()函数,输出数据到串口USART。
printf()函数默认的输出设备是显示器,若我们想用这个标准的输出函数向串口(或LCD等其它设备)发送数据,
①首先,需要改写fputc()这个函数。改写后的fputc()函数如下:
/****************************************************************** * Function Name : fputc
* Description : Retargets the C library printf function to the USART.
* 重定向printf()函数,输出到串口USART。
*******************************************************************/ int fputc(int ch, FILE *f)
{
/* Place your implementation of fputc here */
/* e.g. write a character to the USART */
USART_SendData(USART1, (u8) ch);
/* Loop until the end of transmission */
while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET) ; return ch;
}
并把改写后的fputc()函数,放在main.c文件的尾处。
②在main.c文件的开始处,加入
#include “stdio.h”
③在main.c文件的头尾之间,加入printf( )函数。
除了以上外,还需要在工程中,添加以下红框中的文件:
←必须添加stm32f10x_lib.c
或加入stm32f10x_heads.h 文件(确认必须包括stm32f10x_lib.c)
若采用【法二】使用printf( )函数,通过串口发送数据必须在以下配置界面中,选中单选框“Use MicroLIB”
若你发现在Keil Real View MDK中,使用printf函数时,
不能向串口输出信息,
或者今后发现可以软件仿真,不能硬件仿真
解决办法:
在以上配置界面中,选中单选框“Use MicroLIB”。MicroLib提供了一个有限的stdio子系统,它仅支持未缓冲的stdin、stdout和stderr。这样,
即可使用printf()函数,来显示应用程序中的诊断消息。