历史上的今天
返回首页

历史上的今天

今天是:2025年05月30日(星期五)

正在发生

2019年05月30日 | STM32L0xx_HAL_Driver库的使用——UART续

2019-05-30 来源:eefocus

单片机型号:STM32L051C8T6


开发环境MDK5.12


库版本:STM32L0xx_HAL_Driver V1.1.0


主机环境:Windows XP


承接上文,为采用双缓冲机制,重新开辟一个500字节的空间aTxBuffer来存放所需发送的字节,初始化uart_snd的指针


uart_snd.front = aTxBuffer;

uart_snd.rear = aTxBuffer; //两个指针指向相同的地址空间


编辑发送单字节的函数uart_char

/**********************************************************************

函数:uart_char()

函数作用:发送一个字节数据

参数:

uint8_t *fmt--------------------------------需要发送的数据

返回值:

上一版本:无

当前版本:1.0

作者:

最后修改时间:2015-04-08

说明: 

**********************************************************************/

 

void uart_char(uint8_t fmt)

{

uint8_t ret = HAL_OK;

if(uart_snd.rear == uart_snd.front)

{

//队首指针和队尾指针相等表明当前没有数据需要发送,这里需要手动开启发送请求

*uart_snd.rear = fmt;

uart_snd.rear++;

if(uart_snd.rear >= aTxBuffer + BUFFSIZE)

uart_snd.rear = aTxBuffer;

do

{

ret = HAL_UART_Transmit_IT(&UartHandle,uart_snd.front,1);//请求发送下一个数据

}while(ret != HAL_OK);

}

else

{

*uart_snd.rear = fmt;

uart_snd.rear++;

if(uart_snd.rear >= aTxBuffer + BUFFSIZE)

uart_snd.rear = aTxBuffer;

}

}

在此判断是否是重新启动发送请求,如果是重新启动则需要手动发起请求,即调用HAL_UART_Transmit_IT()发送函数,如果已经在发送数据过程中则只需要更新rear指针即可。我们的uart_send函数也需要更改不再调用printf而是调用uart_char函数来实现

int8_t uart_send(uint8_t *fmt, uint8_t len)

{

while(len)

{

uart_char(*fmt);

fmt++;

len--;

}

return 0;

}

当数据发送成功后中断函数会调用HAL_UART_TxCpltCallback()回调函数来处理串口发送流程,

/**

  * @brief  Tx Transfer completed callback

  * @param  UartHandle: UART handle. 

  * @note   This example shows a simple way to report end of IT Tx transfer, and 

  *         you can add your own implementation. 

  * @retval None

  */

void HAL_UART_TxCpltCallback(UART_HandleTypeDef * huart)

{

uint8_t ret = HAL_OK;

uart_snd.front++; //更新rear指针

if(uart_snd.front >= (aTxBuffer + BUFFSIZE))

uart_snd.front = aTxBuffer;

if(uart_snd.front != uart_snd.rear)

{

//如果队首指针和队尾指针不同表明缓冲区中有数据还未发送

do

{

ret = HAL_UART_Transmit_IT(&UartHandle,uart_snd.front,1);//请求发送下一个数据

}while(ret != HAL_OK);

}

}

这里我们要判断缓冲区中的数据是否已经发送完毕即判断front指针和rear指针是否相等,如果相等,则表明数据发送完毕,无需再调用HAL_UART_Transmit_IT()发送函数。至此发送流程编辑完毕,在主函数中调用uart_send()函数来进行测试

uint8_t *abc = "abcdefghijklmnopqrstuvwxyz0123456789rn";

 

while(1)

{

uart_send(abc,strlen(abc));

}

经测试发送正常,结果如下


一切显得顺风顺水,就在我以为大功告成之时,从PC机的串口工具向单片机发送了一些数据,结果单片机卡住了,串口输出也没得了。。。跟想象中的结果不一样那,之前采用单缓冲机制是完全没问题的,怎么使用双缓冲就有问题了呢,串口接收流程没有改动,只是改动了串口发送,而且单独测试串口发送也没问题,调试了半天看下是否有串口错误产生呢。因此增加了串口出错回调函数


/**

  * @brief  UART error callbacks

  * @param  UartHandle: UART handle

  * @note   This example shows a simple way to report transfer error, and you can

  *         add your own implementation.

  * @retval None

  */

 void HAL_UART_ErrorCallback(UART_HandleTypeDef *UartHandle)

{

    printf("error code:%Xrn",UartHandle->ErrorCode);

}

在里面输出错误码,测试结果如下


输出的错误码为0x08,查找错误码的定义发现该错误码是ORE错误


/** 

  * @brief  HAL UART Error Code structure definition  

  */ 

typedef enum

{

  HAL_UART_ERROR_NONE      = 0x00,    /*!< No error            */

  HAL_UART_ERROR_PE        = 0x01,    /*!< Parity error        */

  HAL_UART_ERROR_NE        = 0x02,    /*!< Noise error         */

  HAL_UART_ERROR_FE        = 0x04,    /*!< frame error         */

  HAL_UART_ERROR_ORE       = 0x08,    /*!< Overrun error       */

  HAL_UART_ERROR_DMA       = 0x10     /*!< DMA transfer error  */

}HAL_UART_ErrorTypeDef;

而我们知道ORE错误是只会出现在串口接收中,难道打开串口发送中断会影响到串口接收中断?想想总觉得不可能,这应该是全双工串口的那,两者应该是相互独立的才对那。这让我陷入了深深的纠结中。。。而且在测试结果中一旦出现了ORE错误会一直输出该错误,很明显该错误标志一直没有被清零,同时我也没有往单片机发送串口数据之前使用STM32F030C8T6型号单片机时会有串口乱进的情况是因为打开串口接收中断时会同时开启ORE中断,最后解决办法是在中断处理函数中增加错误标志的检测并清除相应的标志。本以为STM32L0xx_Hal_Driver库封装了这么多,会帮助我们减少这类错误呢,结果还是出现了,查看HAL_UART_Receive_IT()函数代码会发现该函数同样使能了各个错误中断

    /* Enable the UART Parity Error Interrupt */

    __HAL_UART_ENABLE_IT(huart, UART_IT_PE);

 

    /* Enable the UART Error Interrupt: (Frame error, noise error, overrun error) */

    __HAL_UART_ENABLE_IT(huart, UART_IT_ERR);

 

查看源代码中中断处理函数HAL_UART_IRQHandle()里面也进行了各个错误的判断以及清除标志操作。


推荐阅读

史海拾趣

ENERGIZER公司的发展小趣事

为了配合全球业务的发展,ENERGIZER在亚太地区设立了8个厂房和18个国家的办事处。其中,劲量(中国)有限公司于1992年开始进驻中国,并在1998年在天津设立了生产工厂。这一举措不仅促进了中国与国际间的技术交流与合作,还为中国的电池制造业带来了新的发展机遇。随着中国市场的不断扩大,ENERGIZER在中国的业务也逐渐壮大,成为了中国电池市场的重要参与者。

ESPROS [Espros Photonics corp]公司的发展小趣事

ESPROS Photonics corp(以下简称ESPROS)于2006年由Beat De Coi先生创立,总部位于瑞士。公司成立之初,就专注于芯片设计、集成与制造领域,依托其独特的光学工艺技术,为客户提供高性能的光电传感器解决方案。在中国上海,ESPROS设立了专门的芯片设计中心及技术支持部门,以更好地服务亚洲市场。

昆泰芯微电子(CONNTEK)公司的发展小趣事

随着物联网技术的快速发展,昆泰芯微电子紧跟时代步伐,深度布局物联网应用领域。公司专注于面向物联网应用的传感器芯片研发、生产和销售,致力于成为传感器信号链及物联网芯片的行业领导者。在消费电子、智能制造、智能交通、智能家居以及新能源汽车等多个领域,昆泰芯微电子的产品得到了广泛应用,为这些领域的发展提供了强有力的技术支持。

Holtek(合泰)公司的发展小趣事

昆泰芯微电子坚持以人为本,践行合作共赢的企业文化。公司注重员工的个人发展和团队协作,鼓励员工积极参与公司的各项活动和决策。同时,公司也积极与合作伙伴建立良好的合作关系,共同推动行业的发展。公司以正直、求实、进取、创新、协同、分享的十二字箴言作为公司从上至下贯彻的做人做事理念,让员工和企业共同成长,共创前程,共享收获。

以上五个故事概述了昆泰芯微电子在电子行业中的重要发展历程和成就。这些故事不仅展现了公司的技术实力和市场竞争力,也体现了公司的企业文化和发展理念。

FEIG ELECTRONIC公司的发展小趣事

FEIG ELECTRONIC始终将技术创新作为企业发展的核心动力。公司不断投入大量资源进行技术研发和产品升级,以保持其在RFID领域的领先地位。近年来,FEIG推出了多款具有高性能、高可靠性、高安全性的RFID产品,如长距离读写器、智能门禁系统等。这些产品的推出不仅满足了客户的多样化需求,还进一步巩固了FEIG在RFID领域的市场地位。

以上五个故事大纲简要概述了FEIG ELECTRONIC在电子行业中的发展历程和关键事件。虽然每个故事的具体细节可能有所不同,但它们共同展示了FEIG在技术创新、市场拓展、合作创新、战略合作和持续创新方面的努力和成就。

BAE Systems公司的发展小趣事

电子行业是一个充满竞争和挑战的领域。面对不断变化的市场环境和客户需求,BAE Systems公司不断调整自身的战略和业务结构。公司注重市场调研和客户需求分析,根据市场变化及时调整产品线和市场策略。同时,公司也加强了对内部管理和流程的优化,提高了运营效率和成本控制能力。这些举措使得公司能够在激烈的市场竞争中保持领先地位,实现稳健发展。

问答坊 | AI 解惑

protuse中文教程

超详细的中文教程,很好啊,…

查看全部问答>

直流调速

本帖最后由 paulhyde 于 2014-9-15 09:07 编辑 直流调速  …

查看全部问答>

EVC4.0编程环境,如何把变量文件名传入fopen?

两个菜鸟问题: 1. 找到别人的代码: int   order=0;      AnsiString   fileName,path=\"c:\\\\temp\\\\\";      FILE   *fp;      fileName= ...…

查看全部问答>

2440板ROM剩余空间不准

使用QQ2440v3开发板,原机配置系统中可以看到FRIENDLYFlash盘符有16M的空间,自己定制系统后FRIENDLYFlash名称变为ResidentFlash,容量只有1.96M,不知道怎么回事,如何实现完全将所有剩余空间生成一个盘符…

查看全部问答>

uCOS-II 在keil 下能不能仿真

uCOS-II  在keil 下能不能仿真 有什么地方要注意. 谢谢!…

查看全部问答>

MPC8260与FPGA在VXWORKS下的通信

各位大哥,我刚接触VXWORKS不久,请大家指教。实验室有块powerpc104开发板(含有MPC8260+FPGA),8260与FPGA通过64位数据总线和32位地址总线(好像就是60X总线)连接,购买板子已自带BSP,怎么实现8260与FPGA在VXWORKS下的通信(中断,数据传递)啊 ...…

查看全部问答>

LM3S9B96的i2c设置问题?

各位用过的说说怎么设置,我设置的没有反应。              SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);           &nbs ...…

查看全部问答>

关于调整op07集成运放的精度

小弟最近用OP07做了一块信号调理的板子,但是输入信号和输出信号的电压不成比例关系,测得的数据离散性很大,望各位前辈不吝赐教。…

查看全部问答>

launchpad学习心得随便聊聊

今天学习了EEWORLD论坛中的launchpad课程,感觉讲得蛮详细的,介绍的很全面,学到了不少东西。可惜我还只是一个新手,有些东西还没彻底弄明白。好吧,就这些了,希望有高手能帮忙指导,谢谢。…

查看全部问答>

求大神帮我分析一下这两个电路

看资料说是什么巴特沃斯型滤波器,但是我找不到他们的截止频率的算法~~ 求各位大神帮忙分析一下~~~…

查看全部问答>