历史上的今天
返回首页

历史上的今天

今天是:2025年07月27日(星期日)

正在发生

2019年07月27日 | STM32串口第一字节消失或者误码的原因和解决方案

2019-07-27 来源:eefocus

现象:stm32复位之后串口打印的第一个字节误码或者消失。


误码原因:误码多是由于端口初始化有问题。使用ST官方v3.5的标准库时,对串口输出端口进行了重复初始化。


如下代码:


    /* PA[15:0] 设置为推挽输出 */

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

    GPIO_Init(GPIOA, &GPIO_InitStructure);


    /* 串口TX端口PA9 设置为复用推挽输出 */

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOA, &GPIO_InitStructure);

 可以看到串口TX端口所在的PA9引脚被进行了两次初始化,这种情况会导致第一字节误码。


误码解决方案:上面的程序明显是为了偷懒用了GPIO_Pin_All,如果挨个写就没问题了。或者直接操作寄存器也是可以的。


第一字节消失原因:


先看数据手册


 

 一般我们的串口查询方式的发送代码如下,包括ST官方例程里的printf串口打印的实现也是这样的代码。


{

    USART_SendData(USART1, dat);

    /* Loop until the end of transmission */

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

    {}

}

 结合上面的图和程序很容易发现问题。


‘TXE’和‘TC’ 标志位复位值都是‘1’。

 那么当我们复位之后通过USART_SendData函数向USART_DR寄存器写入第一个字节,然后通过while查询TC标志的时候,因为TC初始值是‘1’,所以直接就跳出了while,哪怕此时串口并没有开始发送!第一字节就是这样被跳过去了。。


第一字节消失的解决方案:调用USART_SendData函数之前,先将‘TC’标志位清‘0’就OK,代码如下


 


{

    USART_ClearFlag(USART1, USART_FLAG_TC);

    USART_SendData(USART1, dat);

    /* Loop until the end of transmission */

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

    {}

}

 


 ----------------------------------------------------------------printf-----------------------------------------------------------------


 


在keil中使用printf函数,ST官方有例程,需要在main.c中添加如下代码:


 


#include


#ifdef __GNUC__

/* With GCC/RAISONANCE, small printf (option LD Linker->Libraries->Small printf

   set to 'Yes') calls __io_putchar() */

#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)

#else

#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)

#endif /* __GNUC__ */


/**

  * @brief  Retargets the C library printf function to the USART.

  * @param  None

  * @retval None

  */

PUTCHAR_PROTOTYPE

{

    /* Place your implementation of fputc here */

    /* e.g. write a character to the USART */

    USART_ClearFlag(USART1, USART_FLAG_TC);

    USART_SendData(USART1, (uint8_t) ch);


    /* Loop until the end of transmission */

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

    {}


    return ch;

}

 注意:还需要在设置中添加MicroLib才能够正常使用printf函数!!!如下图





推荐阅读

史海拾趣

ELECTRONIC ASSEMBLY公司的发展小趣事

在电子组装领域,跨界合作成为了一种新的发展趋势。一家名为“创新电子组装”的公司通过与多家知名企业开展跨界合作,实现了资源共享、优势互补。公司不仅从合作伙伴那里学到了先进的技术和管理经验,还成功拓展了业务领域和市场渠道。通过跨界合作,创新电子组装实现了跨越式发展,成为了行业内的佼佼者。

Actel公司的发展小趣事

在电子组装领域,跨界合作成为了一种新的发展趋势。一家名为“创新电子组装”的公司通过与多家知名企业开展跨界合作,实现了资源共享、优势互补。公司不仅从合作伙伴那里学到了先进的技术和管理经验,还成功拓展了业务领域和市场渠道。通过跨界合作,创新电子组装实现了跨越式发展,成为了行业内的佼佼者。

Forge Europa Ltd公司的发展小趣事

Forge Europa Ltd公司自成立以来,始终将技术创新视为企业发展的核心驱动力。早期,公司便投入大量资源研发高效能LED灯带技术,成功推出了具有行业领先地位的5050型号LED灯带。这款产品在市场上迅速获得认可,不仅因为其出色的光效和节能性能,更在于其独特的散热设计,有效延长了产品的使用寿命。Forge Europa的这一技术创新不仅为公司赢得了市场份额,也奠定了其在LED灯带领域的领先地位。

Directed Energy Inc公司的发展小趣事

在电子行业中,产品质量是企业生存和发展的关键。Directed Energy Inc深知这一点,因此始终将品质保障作为公司的核心竞争力之一。公司建立了严格的质量管理体系,从原材料采购到生产制造、再到产品检验和售后服务,每一个环节都严格把控,确保产品的高品质。这种对品质的执着追求赢得了客户的广泛信赖和好评,为公司赢得了更多的市场份额。

B&F;公司的发展小趣事

在B&F公司的早期发展阶段,Peter Funk和Dirk Breitkreutz先生意识到,要想在竞争激烈的航空市场中脱颖而出,必须依赖技术创新。他们决定研发一款具有独特设计和高性能的轻型飞机——FK系列。这款飞机在电子系统上进行了大量创新,如采用先进的导航系统和通信设备,提高了飞行的安全性和舒适性。这些技术创新为B&F公司赢得了良好的声誉,也为公司的快速发展奠定了基础。

Cybernetic Micro Systems公司的发展小趣事

Cybernetic Micro Systems(简称CMS)的创始人李华,是一位热衷于电子技术的天才工程师。他在大学期间就研发出了一款高效能、低功耗的微处理器原型,这一成果引起了业界的广泛关注。毕业后,李华决定创业,将他的研究成果商业化。于是,Cybernetic Micro Systems应运而生,专注于研发和生产高性能的微处理器和配套设备。凭借独特的技术优势,CMS很快在电子行业中崭露头角。

问答坊 | AI 解惑

DSP和FPGA在汽车电子中的广泛应用

1 引言   20世纪末,全球范围内兴起的信息革命浪潮,为汽车工业的突破性发展提供了千载难逢的机遇,信息技术的广泛应用是解决汽车带来的诸如交通拥挤、交通安全、环境污染、能源枯竭等问题的最佳途径。同时,随着汽车电子技术的发展,电子组件 ...…

查看全部问答>

最近有关单片机中断的问题,大家帮忙看看

最近用164做了个倒计时,我用的是定时器1的方式1,倒计时可以跑起来,而且完全正常,我现在想用两个外部中断来调整时和分,但是一加上外部中断定时中断都不在响应了,我把外部中断的入口屏蔽了,倒计时正常了。如果我把定时器换为定时器0所有中断都 ...…

查看全部问答>

史上最全的IGBT资料下载

哈哈 上午清闲 传些资料 留作学习 …

查看全部问答>

ARM7 NXP236串口问题,请教高手

串口0为片内自带的,初始化的时候,U0FCR这个寄存器总是写不进去值,请教高手~~~ 附代码:[code] INT8U UART0_Init( INT32U baudrate) {     INT32U Fdiv;                 PINSEL0 &= 0 ...…

查看全部问答>

如何使用NdisAllocateIoWorkItem函数

ndis5.1中对应的函数为 VOID   NdisInitializeWorkItem(     IN PNDIS_WORK_ITEM  WorkItem,     IN NDIS_PROC  Routine,     IN PVOID  Context     ); n ...…

查看全部问答>

谁有VGA-DB15的封装资料帮我发一份

现在要画一个DB15的封装不知道参数,知道的大侠帮下!!!!!!!!!!!…

查看全部问答>

帮忙把下段程序转为c语言!跪求!!!

;*******************************;        主   程   序;*******************************MAINPG:        ANL        PCA0MD,#0 ...…

查看全部问答>

下载程序出现了这样的错误,麻烦大神帮忙看看

MSP430: Trouble Writing Memory Block at 0x0 on Page 0 of Length 0x4: Could not perform access, BSL memory segments are protected. MSP430: GEL: File: D:\\workspace_v5_2\\12864\\Debug\\12864.out: Load failed.…

查看全部问答>

fatfs 文件系统的操作步骤

请问各位大侠,fatfs文件系统读写操作步骤有没有,读写代码晒晒…

查看全部问答>