qt中获取串口号试验中 为什么(USART

STM32的串口函数_库函数USART_SendData问题和解决方法
个人记录:
昨天做串口实验的时候一直没有成功的原因,连续调用USART_SendData总是会出现前一个被后一个覆盖的情况。
之前觉得ST的官方库应该没有问题就没往这方面想,现在查查,确实有库的问题,还是自己对库不太理解。
还有遇到的硬件复位以后,发送第一个字符丢失的情况。
1、后字节覆盖前字节 &
-----------------加判断while(USART_GetFlagStatus(USARTx,
USART_FLAG_TXE) == RESET){}&
2、硬件复位之后第一个字符丢失
-----------------USART_ClearFlag(USART2,USART_FLAG_TC);
-----------------USART_SendData(USART2,0x01);
-----------------while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET);
转载正文:
1. 问题及现象
使用USART_SendData()函数非连续发送单个字符是没有问题的;当连续发送字符时(两个字符间没有延时),就会发现发送缓冲区有溢出现象。若发送的数据量很小时,此时串口发送的只是最后一个字符,当发送数据量大时,就会导致发送的数据莫名其妙的丢失。
for(TxCounter
= 0;TxCounter & RxC TxCounter++)
USART_SendData(USART1, RxBuffer[TxCounter]);
此API函数不完善,函数体内部没有一个判断一个字符是否发送完毕的语句,而是把数据直接放入发送缓冲区,当连续发送数据时,由于发送移位寄存器的速度限制(与通信波特率有关),导致发送缓冲区的数据溢出,老的数据还未及时发送出去,新的数据又把发送缓冲区的老数据覆盖了。
3. 解决方法
发送后等待一段时间延迟的方法就不说了,等待时间不确定,此为下下策。提供下面2种方案:
方案1. 在每一个字符发送后检测状态位
USART_SendData(USART1, RxBuffer[TxCounter]);
while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET){}
//等待发送缓冲区空才能发送下一个字符
方案2. 修改库函数
修改USART_SendData()函数,在其内部加入发送缓冲区的USART_FLAG_TXE状态检测语句,确保一个字符完全发送出去,才进行下一个字符的发送。
实现方法:每发送一个字符都检测状态寄存器,确保数据已经发送完毕。具体操作步骤如下所示。
修改前的函数定义体
USART_SendData(USART_TypeDef* USARTx, u16 Data)
assert_param(IS_USART_ALL_PERIPH(USARTx));
assert_param(IS_USART_DATA(Data));
USARTx-&DR = (Data & (u16)0x01FF);
修改后的函数定义体
USART_SendData(USART_TypeDef* USARTx, u16 Data)
assert_param(IS_USART_ALL_PERIPH(USARTx));
assert_param(IS_USART_DATA(Data));
USARTx-&DR = (Data & (u16)0x01FF);
while(USART_GetFlagStatus(USARTx,
USART_FLAG_TXE) == RESET){}
//等待发送缓冲区空才能发送下一个字符
可能有人认为,为什么不预先在库函数中处理这个问题,而把解决方法抛给用户。个人认为ST这么做的原因是:使用发送中断功能。
4.&TXE和TC标志位详细说明
在USART的发送端有2个寄存器,一个是程序可以看到的USART_DR寄存器(下图中阴影部分的TDR),另一个是程序看不到的移位寄存器(下图中阴影部分Transmit
Shift Register)。
对应USART数据发送有两个标志,一个是TXE=发送数据寄存器空,另一个是TC=发送结束;对照下图,当TDR中的数据传送到移位寄存器后,TXE被设置,此时移位寄存器开始向TX信号线按位传输数据,但因为TDR已经变空,程序可以把下一个要发送的字节(操作USART_DR)写入TDR中,而不必等到移位寄存器中所有位发送结束,所有位发送结束时(送出停止位后)硬件会设置TC标志。
另一方面,在刚刚初始化好USART还没有发送任何数据时,也会有TXE标志,因为这时发送数据寄存器是空的。
TXEIE和TCIE的意义很简单,TXEIE允许在TXE标志为'1'时产生中断,而TCIE允许在TC标志为'1'时产生中断。
至于什么时候使用哪个标志,需要根据你的需要自己决定。但我认为TXE允许程序有更充裕的时间填写TDR寄存器,保证发送的数据流不间断。TC可以让程序知道发送结束的确切时间,有利于程序控制外部数据流的时序。
下图是STM32技术参考手册中的一页:
stm32 串口发送数据第一字节丢失
使用stm32f10x调试串口通讯时,发现一个出错的现象,硬件复位重启之后,发送测试数据0x01 0x02 0x03
0x04..接收端收到的数据为:0x02 0x03 0x04,第一个数据丢失。
查阅stm32f10x参考手册,找到这样一句话:&
TC:发送完成&
当包含有数据的一帧发送完成后,由硬件将该位置位。如果USART_CR1中的TCIE为1,则产生中断。由软件序列清除该位(先读USART_SR,然后写入USART_DR)。TC位也可以通过写入0来清除,只有在多缓存通讯中才推荐这种清除程序。&
0:发送还未完成;&
1:发送完成。&
注意到这一句:由软件序列清除该位(先读USART_SR,然后写入USART_DR)。 也就是说,要先read
USART_SR,然后write USART_DR,才能完成TC状态位的清除。而硬件复位后,串口发送的首个数据之前没有read
SR的操作,是直接write DR,也就是说,TC没有被清除掉。&
硬件复位后,串口发送首个数据之前,先读取一下USART_SR,则能够保证首个数据发送时,不出现覆盖的情况。当然,也有别的方法,比如先清除TC状态位,USART_ClearFlag(USART1,
USART_FLAG_TC);或USART1-&SR&=~(1&&7);
stm32串口第一字节丢失问题分析
STM32串口发送必须先检测状态,否则第一个字节无法发出,发送完毕,必须检测发送状态是否完成,否则,发送不成功,
使用stm32f10x调试串口通讯时,发现一个出错的现象,硬件复位重启之后,发送测试数据0x010x020x030x04..接收端收到的数据为:0x020x030x04,第一个数据丢失。换成发送别的数值的数据,如0x060x0ff,则接收到0x0ff,0x06丢失。错误依旧。
故障排除过程:
<font COLOR="#、刚开始怀疑是接收端的错误,我是使用电脑串口,运行串口辅助调试工具接收,换成其他软件后,发现故障依旧,而且电脑软件一直是开启状态,不像和电脑软件有关。
<font COLOR="#、使用单步调试,单步运行各个发送指令,都正常。能收到0x010x020x030x04的数据。间接的排除了不是电脑软件的问题,而是其他的错误。
<font COLOR="#、单步调试运行虽然正常了,但连续运行时,错误依旧。现在有点摸不到头绪了,单步运行正常,看起来编程没有出错,那故障在哪里呢?测试程序如下
USART_SendData(USART2,0x01);//A
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET);//B
USART_SendData(USART2,0x02);//C
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET);
USART_SendData(USART2,0x03);
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET);
USART_SendData(USART2,0x04);
while(USART_GetFlagStatus(USART2,USART_FLAG_TC)==RESET);
<font COLOR="#、猜测,也许是因为某个特殊原因,使第二个数据覆盖了首个数据,使得首个数据丢失。假设:在执行B指令时,USART的TC状态位==SET,那么就会紧接着执行C指令,也就有可能发生数据的覆盖。于是,在A指令前,加入如下指令:USART_ClearFlag(USART2,USART_FLAG_TC);
<font COLOR="#、加入上一条指令后,运行,错误消失了。说明上一个假设,应该是成立的。
<font COLOR="#、查阅stm32f10x参考手册,找到这样一句话:TC:发送完成
当包含有数据的一帧发送完成后,由硬件将该位置位。如果USART_CR1中的TCIE为1,则产生中断。由软件序列清除该位(先读USART_SR,然后写入USART_DR)。TC位也可以通过写入0来清除,只有在多缓存通讯中才推荐这种清除程序。0:发送还未完成;1:发送完成。
<font COLOR="#、注意到这一句:由软件序列清除该位(先读USART_SR,然后写入USART_DR)。也就是说,要先readUSART_SR,然后writeUSART_DR,才能完成TC状态位的清除。而硬件复位后,串口发送的首个数据之前没有readSR的操作,是直接writeDR,也就是说,TC没有被清除掉。说明第4步的猜测是对的。
<font COLOR="#、那么,应该把指令A前面加的USART_ClearFlag(USART2,USART_FLAG_TC);改为USART_GetFlagStatus(USART2,USART_FLAG_TC);,应该也能消除错误。测试后证实,确实如此,在发送首个数据之前,先读取一下USART_SR,那么就不会出现首个数据丢失的情况了。
<font COLOR="#、总结:硬件复位后,串口发送首个数据之前,先读取一下USART_SR,则能够保证首个数据发送时,不出现覆盖的情况。当然,也有别的方法,比如先清除TC状态位,或是,在writeUSART_DR之后,加入一个小延时,让数据发送完毕,应该也能间接排除这个错误。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。CC2530--串口实验的回显
今天做了一个下面的实验,注释都有了,所以就不过多解释了,主要就是总结一下
1.串口收发要初始化串口,(设置时钟频率--&选择用来当做串口的IO--&设置波特率--&发送中断设为0--&打开数据接收的中断)
2.字符串发送函数(U0DBUF填充字符--&等待串口发送完毕--&发送中断标志设为0,准备下次发送)
3.按键中断服务程序中,除了P1IFG要清零以外,P1IF也要清零。哎,忘记为什么了,有谁知道的,可以告诉我一下。反正我试了一下,不加上P1IF清零,程序就死循环了。
/****************************
* project: 串口实验的回显
描述:在PC机中的串口软件中发送数据给cc2530,
当发生以下其中一个条件时,cc2530就将数
据发回给PC机,PC端的串口软件显示该数据
a)cc2530接收到“#”
b)接收到的数据长度等于50
c)按下按键s3
作者:林少游
***************************/
#include &ioCC2530.h&
#include &string.h&
#define YLED P1_0
#define BLED P1_1
#define KEY3 P1_2
#define uchar unsigned char
#define uint unsigned int
#define LIGHTOPEN 1
#define LIGHTCLOSE 0
uint DataNumber=0;
//接收到的数据的长度
char temp=0;
//接收到的字符
char ReceiveData[50]; //接收到的数据
char TXRXFlag=1;
//发送标志,1代表接收数据,3代表发送数据
void Delay(uint n);
void Init_Io();
void Init_Usart0();
void Usart0_Send_String(char *Data,int len);
/****************************
* @brief : 延时函数
****************************/
void Delay(uint n)
for(i=0;i&n;i++);
for(i=0;i&n;i++);
for(i=0;i&n;i++);
for(i=0;i&n;i++);
for(i=0;i&n;i++);
/****************************
* @brief : IO端口初始化
描述 :Led灯的作用是标志数据接收或发送的状态
****************************/
void Init_Io()
P1DIR |= 0X03;
//P1.0,P1.1设置为输出
YLED = LIGHTOPEN;
BLED = LIGHTCLOSE;
P1DIR &= ~0X40;
//P1.2设置为输入
P1IEN |= 0X04;
//P1.2设置为允许中断
PICTL |= 0X02;
//下降沿触发
//打开总中断
IEN2 |= 0X10;
//P1允许中断
P1IFG = 0X00;
//P1中断标志清零
/****************************
* @brief : 串口初始化函数
****************************/
void Init_Usart()
CLKCONCMD &= ~0X40;
//设置系统时钟源为32MHz
while(CLKCONSTA&0X40);//等待晶振稳定
CLKCONCMD &= ~0X47;
//设置系统主时钟为32MHz
PERCFG = 0X00;
//选择P0做串口
P0SEL |= 0X3C;
//P0.2,P0.3,P0.4,P0.5设置为外设
P2DIR &= ~0XC0;
//选择UART0优先
U0CSR |= 0X80;
//USART模式选择UART
U0GCR |= 9;
U0BAUD|= 59;
//波特率设置为19200
U0CSR |= 0X40;
//允许接收
IEN0 |= 0X84;
//开总中断,接收中断使能
/****************************
* @brief :Uart0发送字符串函数
* @param :Data - 要发送的数据
len - 数据的长度
****************************/
void Usart0_Send_String(char *Data,int len)
for(i=0;i&i++)
U0DBUF = *Data++;
//每次填充一个字符,即8位
while(UTX0IF==0);
//等待发送完毕
//发送终端清零,准备下一个发送
/****************************
* @brief : 主函数
****************************/
Init_Io();
Init_Usart();
YLED = LIGHTOPEN;
//发送数据时亮黄灯
if(TXRXFlag == 1)
if(temp!= 0)
if(temp!='#')
ReceiveData[DataNumber++]=
TXRXFlag = 3;
//发送数据
if(DataNumber==50)
TXRXFlag = 3;
//发送数据
if(TXRXFlag == 3)
BLED = LIGHTOPEN;
YLED = LIGHTCLOSE;//发送数据标志
U0CSR &= ~0X40;
//停止接收数据
Usart0_Send_String(ReceiveData,DataNumber); //发送数据
U0CSR |= 0X40;
//允许数据接收
DataNumber=0;
//数据长度置0
TXRXFlag = 1;
//接收数据
//接收数据标志
/****************************
* @brief : 中断服务程序--接收数据
****************************/
#pragma vector = URX0_VECTOR
__interrupt void URX0_ISR(void)
temp = U0DBUF;
//保存数据
URX0IF = 0;
//接收中断标志清零,准备下一个数据接收
/****************************
* @brief : 中断服务程序--按键s3中断
:当按下按键的时候也可以将接收到的数据发回给PC机
****************************/
#pragma vector = P1INT_VECTOR
__interrupt void P1INT_ISR(void)
P1IFG = 0;
//P1中断状态标志清零
TXRXFlag = 3; //发送数据
//P1中断标志清零
没有更多推荐了,低温试验为什么串口不能用了_百度知道
低温试验为什么串口不能用了
是被试件的串口不能用了吗?那就说明被试件耐低温能力不够,低温试验不合格啊。
采纳率:94%
为您推荐:
其他类似问题
低温试验的相关知识
&#xe675;换一换
回答问题,赢新手礼包&#xe6b9;
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。查看: 4603|回复: 9
原子哥,串口试验中,为什么要PE中断使能呢?
主题帖子精华
初级会员, 积分 67, 距离下一级还需 133 积分
在线时间0 小时
#ifdef EN_USART1_RX&&& //如果使能了接收
&//使能接收中断
&USART1-&CR1|=1&&8;&&& //PE中断使能
&USART1-&CR1|=1&&5;&&& //接收缓冲区非空中断使能
PE是校验错误才使能,但是这个实验没有使用校验位啊。。。。。。不太明白。。
主题帖子精华
金钱128888
在线时间1149 小时
回复【楼主位】一米阳光:
---------------------------------
你可以去掉试试。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
主题帖子精华
初级会员, 积分 67, 距离下一级还需 133 积分
在线时间0 小时
回复【2楼】正点原子:
---------------------------------
我去掉了。。。。好像没什么影响。。。。。还有那个串口调试助手总是出现乱码。。。。请教原子哥是怎么回事啊。。。
主题帖子精华
金钱128888
在线时间1149 小时
回复【3楼】一米阳光:
---------------------------------
哪个串口助手?
我写的那个?还是哪个?
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
主题帖子精华
初级会员, 积分 67, 距离下一级还需 133 积分
在线时间0 小时
回复【4楼】正点原子:
---------------------------------
恩恩&&就是你那个。。。。有的时候会出现乱码,
主题帖子精华
金钱128888
在线时间1149 小时
回复【5楼】一米阳光:
---------------------------------
换丁丁的那个试试.sscom
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
主题帖子精华
初级会员, 积分 67, 距离下一级还需 133 积分
在线时间0 小时
回复【6楼】正点原子:
---------------------------------
好一会儿试试。。。那个PE中断使能到底是什么意思啊。。。。
主题帖子精华
金钱128888
在线时间1149 小时
看&&STM32参考手册&&
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺:
主题帖子精华
新手入门, 积分 25, 距离下一级还需 -5 积分
在线时间0 小时
是否为了接收的到数据奇偶出错的判断?
主题帖子精华
新手上路, 积分 29, 距离下一级还需 21 积分
在线时间0 小时
当USART_SR中的PE为’1’时,产生USART中断,它是串口的中断使能位
Powered byStudying……
STM32学习笔记(7):USART串口的使用
STM32学习笔记(7):USART串口的使用
2011年4月19日USART串口通信
1.串口的基本概念
在STM32的参考手册中,串口被描述成通用同步异步收发器(USART),它提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。USART利用分数波特率发生器提供宽范围的波特率选择。它支持同步单向通信和半双工单线通信,也支持LIN(局部互联网),智能卡协议和IrDA(红外数据组织)SIR
ENDEC规范,以及调制解调器(CTS/RTS)操作。它还允许多处理器通信。还可以使用DMA方式,实现高速数据通信。
USART通过3个引脚与其他设备连接在一起,任何USART双向通信至少需要2个引脚:接受数据输入(RX)和发送数据输出(TX)。
RX:接受数据串行输入。通过过采样技术来区别数据和噪音,从而恢复数据。
TX:发送数据输出。当发送器被禁止时,输出引脚恢复到它的I/O端口配置。当发送器被激活,并且不发送数据时,TX引脚处处于高电平。在单线和智能卡模式里,此I/O口被同时用于数据的发送和接收。
2.串口的如何工作的
一般有两种方式:查询和中断。
(1)查询:串口程序不断地循环查询,看看当前有没有数据要它传送。如果有,就帮助传送(可以从PC到STM32板子,也可以从STM32板子到PC)。
(2)中断:平时串口只要打开中断即可。如果发现有一个中断来,则意味着要它帮助传输数据——它就马上进行数据的传送。同样,可以从 PC到STM3板子,也可以从STM32板子到PC。
3.串口的硬件连接
我用的奋斗STM32 V3开发板拥有二路RS-232接口,CPU的PA9-US1-TX(P68)、PA10-US1-RX(P69)、PA9-US2-TX(P25)、PA10-US2-RX(P26)通过MAX3232实现两路RS-232接口,分别连接在XS5和XS17接口上。
USART1在系统存储区启动模式下,将通过该口通过PC对板上的CPU进行ISP,该口也可作为普通串口功能使用,JP3,JP4的短路冒拔去,将断开第二路的RS232通信,仅作为TTL通信通道。
4.编程实例
我们要对串口进行操作,首先要将STM32的串口和CPU进行连接。在Windows操作系统中,有一个自带的系统软件叫“超级终端”。VISTA以上的操作系统去掉了这个软件,不过可以从XP的系统中,复制“hypertrm.dll”和“hypertrm.exe”到“windows/system32”文件夹下,然后双击运行hypertrm.exe,就可以看见超级终端的运行界面了。
运行超级终端以后,会弹出“连接描述”,输入名称和选择图标,这个地方随便写个什么名称都可以。然后弹出“连接到”设置,在“连接时使用”选择你自己PC和STM32连接的COMx,如果不知道是哪个COM口的话,可以在PC的设备管理器中找到。在选择好COM口之后,会弹出一个“属性”对话框,在“位/秒”选择和你STM32中设置的波特率一致就好,数据位也是按照STM32的设置来选择,奇偶校验选择无,停止位选择1,数据流控制选择无。注意,以上的选项都必须和STM32中的串口设置相匹配,要不然可能会出现一些未知错误。
配置好超级终端之后,我们便可以开始对STM32进行编程了。编程一般按照如下步骤进行:
(1)RCC配置;
(2)GPIO配置;
(3)USART配置;
(4)NVIC配置;
(5)发送/接收数据。
在RCC配置中,我们除了常规的时钟设置以外,要记得打开USART相对应的IO口时钟,USART时钟,还有管脚功能复用时钟。
在GPIO配置中,将发送端的管脚配置为复用推挽输出,将接收端的管脚配置为浮空输入。
在USART的配置中,通过USART_InitTypeDef结构体对USART进行初始化操作,按照自己所需的功能配置好就可以了。注意,在超级终端的设置中,需要和这个里面的配置相对应。由于我是采用中断接收数据的方式,所以记得在USART的配置中药打开串口的中断,同时最后还要打开串口。
在NVIC的配置中,主要是USART1_IRQChannel的配置,和以前的笔记中讲述的中断配置类似,不会配置的可以参考以前的笔记。
全部配置好之后就可以开始发送/接收数据了。发送数据用USART_SendData()函数,接收数据用USART_ReceiveData()函数。具体的函数功能可以参考固件库的参考文件。根据USART的配置,在发送和接收时,都是采用的8bits一帧来进行的,因此,在发送的时候,先开辟一个缓存区,将需要发送的数据送入缓存区,然后再将缓存区中的数据发送出去,在接收的时候,同样也是先接收到缓存区中,然后再进行相应的操作。
注意在对数据进行发送和接收的时候,要检查USART的状态,只有等到数据发送或接收完毕之后才能进行下一帧数据的发送或接收。采用USART_GetFlagStatus()函数。
同时还要注意的是,在发送数据的最开始,需要清除一下USART的标志位,否则,第1位数据会丢失。因为在硬件复位之后,USART的状态位TC是置位的。当包含有数据的一帧发送完成之后,由硬件将该位置位。只要当USART的状态位TC是置位的时候,就可以进行数据的发送。然后TC位的置零则是通过软件序列来清除的,具体的步骤是“先读USART_SR,然后写入USART_DR”,只有这样才能够清除标志位TC,但是在发送第一帧数据的时候,并没有进行读USART_SR的操作,而是直接进行写操作,因此TC标志位并没有清空,那么,当发送第一帧数据,然后用USART_GetFlagStatus()检测状态时返回的是已经发送完毕(因为TC位是置1的),所以程序会马上发送下一帧数据,那么这样,第一帧数据就被第二帧数据给覆盖了,所以看不到第一帧数据的发送。
按照上面的方法编程后,我们便可以在超级终端上查看串口通信的具体状态了。我的这个例程,在硬件复位以后,可以马上在超级终端上看见“Welcome to my STM32! Please press any key!”字样,然后如果在超级终端中通过PC机键盘按下相应的键,则这个键会发送到STM32中,并且马上返回到PC机的超级终端上,因此可以马上从超级终端的页面中看到按下的相应的键。
5.程序源代码
#include"stm32f10x_lib.h"
FlagStatus RX_
void RCC_cfg();
void GPIO_cfg();
void USART_cfg();
void NVIC_cfg();
int main()
unsigned char TxBuf1[] = "Welcome to mySTM32! Please press any key!";
RCC_cfg();
GPIO_cfg();
NVIC_cfg();
USART_cfg();
//清除标志位,否则第1位数据会丢失
USART_ClearFlag(USART1,USART_FLAG_TC);
//发送数据
//PB5的作用是显示正在发送数据
//当有数据在发送的时候,PB5会亮
for( i=0;TxBuf1[i]!='\0';i++)
USART_SendData(USART1,TxBuf1[i]);
GPIO_SetBits(GPIOB,GPIO_Pin_5);
//等待数据发送完毕
while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET);
GPIO_ResetBits(GPIOB,GPIO_Pin_5);
//RCC时钟配置
void RCC_cfg()
//定义错误状态变量
ErrorStatus HSEStartUpS
//将RCC寄存器重新设置为默认值
RCC_DeInit();
//打开外部高速时钟晶振
RCC_HSEConfig(RCC_HSE_ON);
//等待外部高速时钟晶振工作
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if(HSEStartUpStatus == SUCCESS)
//设置AHB时钟(HCLK)为系统时钟
RCC_HCLKConfig(RCC_SYSCLK_Div1);
//设置高速AHB时钟(APB2)为HCLK时钟
RCC_PCLK2Config(RCC_HCLK_Div1);
//设置低速AHB时钟(APB1)为HCLK的2分频
RCC_PCLK1Config(RCC_HCLK_Div2);
//设置FLASH代码延时
FLASH_SetLatency(FLASH_Latency_2);
//使能预取指缓存
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
//设置PLL时钟,为HSE的9倍频8MHz
* 9 = 72MHz
RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);
RCC_PLLCmd(ENABLE);
//等待PLL准备就绪
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) ==RESET);
//设置PLL为系统时钟源
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
//判断PLL是否是系统时钟
while(RCC_GetSYSCLKSource() != 0x08);
//打开GPIO时钟,复用功能,串口1的时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO | RCC_APB2Periph_USART1, ENABLE);
//IO口配置
void GPIO_cfg()
GPIO_InitTypeDef GPIO_InitS
//PA9作为US1的TX端,打开复用,负责发送数据
GPIO_StructInit(&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA , &GPIO_InitStructure);
//PA10作为US1的RX端,负责接收数据
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_IN_FLOATING;
GPIO_Init(GPIOA, &GPIO_InitStructure);
//LED显示串口正在发送/接收数据
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
//串口初始化
void USART_cfg()
USART_InitTypeDef USART_InitS
//将结构体设置为缺省状态
USART_StructInit(&USART_InitStructure);
//波特率设置为115200
USART_InitStructure.USART_BaudRate = 115200;
//一帧数据的宽度设置为8bits
USART_InitStructure.USART_WordLength =USART_WordLength_8b;
//在帧结尾传输1个停止位
USART_InitStructure.USART_StopBits =USART_StopBits_1;
//奇偶失能模式,无奇偶校验
USART_InitStructure.USART_Parity =USART_Parity_No;
//发送/接收使能
USART_InitStructure.USART_Mode = USART_Mode_Rx| USART_Mode_Tx;
//硬件流控制失能
USART_InitStructure.USART_HardwareFlowControl= USART_HardwareFlowControl_N
//设置串口1
USART_Init(USART1, &USART_InitStructure);
//打开串口1的中断响应函数
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
//打开串口1
USART_Cmd(USART1, ENABLE);
//配置中断
void NVIC_cfg()
NVIC_InitTypeDef NVIC_InitS
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
//选择中断分组2
NVIC_InitStructure.NVIC_IRQChannel =USART1_IRQC
//选择串口1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 0;
//抢占式中断优先级设置为0
NVIC_InitStructure.NVIC_IRQChannelSubPriority= 0;
//响应式中断优先级设置为0
NVIC_InitStructure.NVIC_IRQChannelCmd =ENABLE;
//使能中断
NVIC_Init(&NVIC_InitStructure);
然后在stm32f10x_it.c文件中找到相应的中断处理函数,并填入一下内容。注意在stm32f10x_it.c中,要声明一下外部变量RX_status
extern FlagStatusRX_
voidUSART1_IRQHandler(void)
GPIO_SetBits(GPIOB, GPIO_Pin_5);
//确认是否接收到数据
RX_status = USART_GetFlagStatus(USART1,USART_FLAG_RXNE);
//接收到数据
if(RX_status == SET)
//将数据回送至超级终端
USART_SendData(USART1,USART_ReceiveData(USART1));
//等待数据发送完毕
while(USART_GetFlagStatus(USART1, USART_FLAG_TC)== RESET);
GPIO_ResetBits(GPIOB, GPIO_Pin_5);
没有更多推荐了,}

我要回帖

更多关于 串口 使用中 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信