stm32 串口连续接收 发送的出错的问题

发布者:快乐家庭最新更新时间:2016-09-24 来源: eefocus关键字:stm32  串口  连续接收  发送 手机看文章 扫描二维码
随时随地手机看文章
上代码:
 初始化部分:

/*
* 串口1 初始化
*/
void USART1_Initial(void)
{
USART_InitTypeDef USART_InitStruct;
GPIO_InitTypeDef GPIO_InitStructure;

// 设置复用到串口的IO口 PA10 PA11

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);//

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //USART1 TX
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
GPIO_Init(GPIOA, &GPIO_InitStructure); //A端口

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //USART1 RX
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; //复用开漏输入
GPIO_Init(GPIOA, &GPIO_InitStructure);


RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//

USART_DeInit(USART1); //首先复位

/*!< This member configures the USART communication baud rate.
The baud rate is computed using the following formula:
- IntegerDivider = ((PCLKx) / (16 * (USART_InitStruct->USART_BaudRate)))
- FractionalDivider = ((IntegerDivider - ((u32) IntegerDivider)) * 16) + 0.5 */
USART_InitStruct.USART_BaudRate=2400;

USART_InitStruct.USART_WordLength=USART_WordLength_8b;

USART_InitStruct.USART_StopBits=USART_StopBits_1;

USART_InitStruct.USART_Parity=USART_Parity_No;

USART_InitStruct.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;

USART_InitStruct.USART_HardwareFlowControl=USART_HardwareFlowControl_None;

USART_Init(USART1, &USART_InitStruct);

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); //USART1 接收中断使能

USART_Cmd(USART1,ENABLE); // USART1 模块使能
}

 
中断服务程序部分:

void USART1_IRQHandler(void)
{

ITStatus ItState=RESET;
ItState=USART_GetITStatus(USART1,USART_IT_RXNE);
if(ItState==SET)
{
ReceivedData=USART_ReceiveData(USART1);// 发送收到的数据
ReceiveFlag=1;
//USART_SendData(USART1,ReceivedData);// 注释掉,放到主函数中异步发送试试
USART_ClearITPendingBit(USART1,USART_IT_RXNE); // 清除标志位
}
}

程序的本意是 将收到的数据原样发送回去。
但是用串口调试助手调试时发现,一个字节一个字节发送没有问题,要是一次发送多个多个字节,返回的数据就会出错。
如下图:
stm32 串口连续接收 发送的出错的问题 - dzdesigned80 - dzdesigned80的博客
 
分析问题在于
发送的数据还没有发送完成,新的数据又发送过来,
改进了新的接收中断程序 当积累到一定的数据才发送。 
void USART1_IRQHandler(void)
{
int i=0;
static unsigned char counter=0;
ITStatus ItState=RESET; 
ItState=USART_GetITStatus(USART1,USART_IT_RXNE);
if(ItState==SET)
{
 USART_ClearITPendingBit(USART1,USART_IT_RXNE);  // 清除标志位
 ReceivedData[counter]=USART_ReceiveData(USART1); // 发送收到的数据 
 counter++;
 if(counter>=10)
 {
   ReceiveFlag=1;
counter=0;
for(i=0;i<10;i++)
{
  USART_SendData(USART1,ReceivedData[i]);
  while(USART_GetFlagStatus(USART1,USART_FLAG_TC)== RESET);
  //while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)== RESET);  
}
 
 }   // 注释掉,放到主函数中异步发送试试 
}
这样发送没有问题。
 
还有一个问题,stm32 的库函数  USART_SendData()  有缺陷,
里面没有判断发送完成的标志,

使用USART_SendData()函数非连续发送单个字符是没有问题的;当连续发送字符时(两个字符间没有延时),就会发现发送缓冲区有溢出现象。若发送的数据量很小时,此时串口发送的只是最后一个字符,当发送数据量大时,就会导致发送的数据莫名其妙的丢失。

如:

1
2
for(TxCounter = 0;TxCounter < RxCounter; TxCounter++)
USART_SendData(USART1, RxBuffer[TxCounter]);

解决办法 while(USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET)

 
或者

while(USART_GetFlagStatus(USARTx, USART_FLAG_TC) == RESET)

关键字:stm32  串口  连续接收  发送 引用地址:stm32 串口连续接收 发送的出错的问题

上一篇:stm32 SPI 接口
下一篇:stm32 Usart 初始化

推荐阅读最新更新时间:2024-03-16 15:11

STM32 RTC问题
STM32的RTC用纽扣电池供电,本来考虑将电池正极接到一个AD端口,采集电压值,但发现电池很快消耗殆尽,测量电流得到电流竟然高达20mA,而且单片机是工作的,还能驱动外围电路。 下图是设计的电路图: 下面是出现这种问题的原因:I/O接二极管到VCC。 RTC
[单片机]
<font color='red'>STM32</font> RTC问题
STM32的printf函数实现方法
今天调试了stm32f407的ADC,一切顺利,然而用串口发送ADC 结果时都是16进制数,看 着很不爽。于是打算用用牛B 的“printf”函数,按照以前的做法,在main 文件中添加了 “stdio.h”,写好了“printf”函数,沏杯茶,打算边品茶边坐等结果,然而这一坐竟坐了半天也 没见结果。一调试发现程序停在了printf 函数处,百思不得其解,百度之,得答案,不敢独 享,分享如下:STM32串口通信中使用printf 发送数据配置方法(开发环境Keil RVMDK)在STM32串口通信程序中使用printf 发送数据,非常的方便。可在刚开始使用的时候总是遇到问题,常见的是硬件访真时无法进入main 主函数,其实只要简单
[单片机]
STM32中定时器级联使用方法
TIM6&TIM7是基本定时器,而TIM10&TIM11&TIM13&TIM14不能工作在从模式下,因此没有以下表格 TIM1&TIM8工作在从模式时内部触发时钟可选项 TIM2&TIM3&TIM4&TIM5工作在从模式时内部触发时钟可选项 TIM9&TIM12工作在从模式时内部触发时钟可选项 ITRx由TS位确定,TIM1&TIM8工作在从模式下内部触发时钟的可选项,如果所选器件对应的定时器不存在则该选项也不存在,如TIM1可选择TIM5_TRGO/TIM2_TRGO/TIM3_TRGO/TIM4_TRGO。
[单片机]
<font color='red'>STM32</font>中定时器级联使用方法
基于TQ2440和Qemu的GDB+串口调试(1)
一、GDB基础知识 1、控制命令 n: 单步运行 c: 继续运行 q: 退出gdb 2、设置、查看和删除断点 (gdb) br start_kernel Breakpoint 6 at 0x809009b0: file ../init/main.c, line 483. (gdb) br __irq_svc Breakpoint 7 at 0x806e8e60: file ../arch/arm/kernel/entry-armv.S, line 219. (gdb) br gic_handle_irq Breakpoint 8 at 0x801014f4: file ../drivers/irqchip/i
[单片机]
STM32 GPIO工作原理详解
1.STM32引脚说明 GPIO是通用输入/输出端口的简称,是STM32可控制的引脚。GPIO的引脚与外部硬件设备连接,可实现与外部通讯、控制外部硬件或者采集外部硬件数据的功能。 以STM32F103ZET6芯片为例子,该芯片共有144脚芯片,包括7个通用目的的输入/输出口(GPIO)组,分别为GPIOA、GPIOB、GPIOC、GPIOD、GPIOE、GPIOF、GPIOG,同时每组GPIO口组有16个GPIO口。通常简略称为PAx、PBx、PCx、PDx、PEx、PFx、PGx,其中x为0-15。 STM32的大部分引脚除了当GPIO使用之外,还可以复用位外设功能引脚(比如串口),这部分在STM32端口复用和重映射(AFIO辅
[单片机]
单片机编码 无线模块发送接收 程序
模块型号,可在万能的某宝搜索【超再生无线模块】 接收距离:空旷200米 接收端在没有收到讯号,会生成间歇性尖状脉冲,data接LED负极,5V接LED正极,可看见闪烁 【科普知识】 无线收发,天线计算公式: 电磁波的速度,30W公里每秒,即3X10^8m/s 频率的单位有MHZ,(兆赫兹),KHZ(千赫兹)HZ(赫兹),相互之间关系是1MHZ=1000KHZ=1000000HZ, 波长=速度/频率 前辈们经验告诉我们,1/4波长的天线是较靠谱的 315M的1/4波长天线计算公式,导线传播高频信号的缩短率在0.98 (300000000/315000000)/4*0.98=0.23333(M)=23.3(
[单片机]
单片机编码 无线模块<font color='red'>发送</font>与<font color='red'>接收</font> 程序
基于STM32的工业循环水极化控制系统设计
0 引言 工业生产中的循环水系统在运行中对淡水消耗非常大,同时,为防止工业设备结垢等现象,需要对循环水不断添加各种化学药剂,且需要不断地排放污水、补充新鲜水,这样既对水资源造成了很大的浪费又污染环境。鉴此,笔者设计了一种基于ARM的工业循环水极化控制系统。该系统通过极化场对水的极化作用[1],实现对工业循环水的处理功能,达到减少水资源消耗、避免使用化学药剂、有效防止水资源污染的目的。 1 系统总体设计方案 基于ARM 的工业循环水极化控制系统采用ST公司的STM32F103微控制器作为主控制核心,由极化能量检测电路实时检测循环水水质参数,经STM32F103运算处理后,由极化能量输出电路调整极化能量的输出,由LCD显示电路实时显
[单片机]
基于<font color='red'>STM32</font>的工业循环水极化控制系统设计
散列DMA设计的高速串口驱动技术
  1  概  述   由于串口在电报通信、工控和数据采集等领域有着广泛的应用,绝大多数嵌入式处理器都内置了通用异步收发器(UART)。UART数据传输主要通过中断或DMA的方式实现。   中断方式是在接收到数据或需要发送数据时产生中断,在中断服务程序中读写UART的缓冲区(FIFO)实现数据传输。由于串口通信速率一般比较低(典型值不超过115 200 bps),大多数嵌入式系统都采用中断方式来传输串口数据。然而,中断服务程序需要占用CPU的时间,而串口速度的提升也必将导致CPU更频繁地响应UART中断,这势必会造成嵌入式系统的性能下降。   DMA数据传输无需CPU的参与,是一种更加高效的数据传输方式。现有的DMA数
[嵌入式]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved