历史上的今天
返回首页

历史上的今天

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

正在发生

2019年08月08日 | stm32的HAL库uart的注意点

2019-08-08 来源:eefocus

(一)、uart / usart 要注意的 API使用方法。

  1.__HAL_UART_GET_FLAG 是获取 SR 寄存器标志位状态

  2.__HAL_UART_CLEAR_FLAG 是清除 SR 寄存器标志位状态,不同于读改写的清零方式,这是直接清零。

  3.__HAL_UART_CLEAR_xxFLAG ,xx为PE FE NE ORE IDLE 共5个, 清除方式都是一样的,要先读取SR,再读取DR才能清除对应的标志位

  4.UART_Receive_IT或许有bug,tmp = (uint16_t*) huart->pRxBuffPtr;需要pRxBuffPtr十六位对齐,但是pRxBuffPtr类型是uint8_t *,是不一定对齐的。所以在声明buffer的时候要注意声明称16位以上对齐的数据。

  5.SR不能用软件置1,一般都是软件清零,通过读改写方式清零会导致中断请求丢失,推荐软件直接写0清除标志。

  6.注意UART_FLAG_xx和UART_IT_xx的区别

  7.串口发送只能一次,问题在于没有开启TC中断

 

(二)串口的框图需要理解透

 

 

 (三)代码如下

 

接收不定长的数据

/**
  * @brief  This function handles UART interrupt request.
  * @param  huart: pointer to a UART_HandleTypeDef structure that contains
  *                the configuration information for the specified UART module.
  * @retval None
  */
void user_Uart1Handler(void)
{

    if ( (__HAL_UART_GET_FLAG (&huart1, UART_FLAG_RXNE) != RESET) )//接收数据
    {
        if (uart1RxCounter < 99)
        {
            uart1RxBuf[uart1RxCounter] =(char)( huart1.Instance->DR & 0xff);
            uart1RxCounter++;
        }
        __HAL_UART_CLEAR_FLAG (&huart1, UART_FLAG_RXNE);

    }

    if(__HAL_UART_GET_FLAG (&huart1, UART_FLAG_TXE) != RESET) //可以发送下个字节
    {
        __HAL_UART_DISABLE_IT(&huart1, UART_IT_TXE);
        __HAL_UART_DISABLE_IT(&huart1, UART_IT_TC);
    }

    if ( (__HAL_UART_GET_FLAG (&huart1, UART_FLAG_IDLE) != RESET) ) //接收完一帧数据,空闲标志
    {
        __HAL_UART_CLEAR_IDLEFLAG(&huart1);
        rx1_cplt = SET;
        huart1.RxState = HAL_UART_STATE_READY;
    }
    
    if ( (__HAL_UART_GET_FLAG (&huart1, UART_FLAG_TC) != RESET) ) //发送完一帧数据,TC标志
    {
        __HAL_UART_CLEAR_PEFLAG (&huart1);
        __HAL_UART_CLEAR_PEFLAG (&huart1);
        huart1.gState = HAL_UART_STATE_READY;
    }
    
    {
        uint32_t state;
        state = __HAL_UART_GET_FLAG (&huart1, UART_FLAG_PE)| __HAL_UART_GET_FLAG (&huart1, UART_FLAG_FE)
        |__HAL_UART_GET_FLAG (&huart1, UART_FLAG_NE)|__HAL_UART_GET_FLAG (&huart1, UART_FLAG_ORE);
        if (state != RESET)
        {
            __HAL_UART_CLEAR_PEFLAG (&huart1);
            
        }
    }
    
    if(huart1.ErrorCode != HAL_UART_ERROR_NONE)
    {
        Error_Handler();
    }

}

printf回调 发送单个字节的程序如下,前提是打开dma和中断:

 

void Uart_PutChar(UART_HandleTypeDef *huart, char ch)
{
    if(__HAL_UART_GET_FLAG (huart, UART_FLAG_TXE) != RESET)
    {
        huart->Instance->DR = (uint16_t)ch &    (uint16_t)0x01FF;//每次写DR会清零TXE
        while(__HAL_UART_GET_FLAG(huart,UART_FLAG_TXE) != SET)
        {
        
        }
    }

}
void putchar_uart1_callback(char ch)
{   
    Uart_PutChar(&huart1,ch);
}

printf回调 ,发送多个字符串的程序如下,前提是打开dma和中断:

void putstring_uart1_callback(char *data, unsigned int size)
{
    HAL_UART_Transmit_DMA(&huart1,(uint8_t *)data,size);
}

还要记得在main循环之前,打开相关中断:
    __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
    
    __HAL_UART_ENABLE_IT(&huart1, UART_IT_TC);

    __HAL_UART_ENABLE_IT(&huart1, UART_IT_ERR);

    __HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);


推荐阅读

史海拾趣

FEMA Electronics Corporation公司的发展小趣事

FEMA在追求经济效益的同时,也积极履行社会责任。公司积极参与公益事业和慈善活动,为社会做出了积极贡献。同时,FEMA还注重环保和可持续发展,努力降低生产过程中的能耗和排放。这些举措不仅提升了公司的社会形象,也为公司的长期发展奠定了坚实的基础。在履行社会责任的过程中,FEMA实现了经济效益和社会效益的双赢。

地博电子(DIBO)公司的发展小趣事

随着公司业务的不断发展,地博电子在2010年成功投产了2条全自动化PC薄膜生产线。这一举措不仅大大提高了生产效率,降低了生产成本,还确保了产品质量的稳定性和一致性。全自动化生产线的投产,为地博电子在电子材料行业中的竞争地位奠定了坚实的基础。

Amperite Co公司的发展小趣事

为了进一步拓展市场,地博电子在2016年成立了湖南地博光学材料有限公司,并建立了覆盖全国的营销网络。这一举措使得地博电子的产品能够更快速地触达目标客户,提高了市场占有率和品牌影响力。同时,全国营销网络的建立也为地博电子的未来发展提供了更广阔的空间。

APC (APC by Schneider Electric)公司的发展小趣事

APC的产品和服务在全球范围内赢得了广泛认可。其InfraStruXure产品线因其集成式的电力、制冷、机架、管理和服务实现了一种开放、具有适应性且集成化的解决方案,赢得了近20个奖项。此外,APC还因其卓越的产品和业务表现,在多个年份赢得了全球100多个奖项。这些奖项不仅证明了APC在电子行业中的领先地位,也反映了其对于创新和质量的不懈追求。

ERNI公司的发展小趣事

进入20世纪60年代,ERNI开始关注连接器技术的发展。他们意识到,随着电子设备的日益复杂和多样化,对连接器技术的需求也将不断增长。因此,ERNI投入大量资源进行研发,终于在1967年成功开发出第一个背板连接器,这一创新技术迅速成为公司的核心产品,也为ERNI在连接器市场赢得了声誉。

Aerotronics Marketing Inc公司的发展小趣事

Aerotronics Marketing Inc公司在电子行业中崭露头角,源于其一项革命性的无人机技术。公司研发团队历经数年努力,成功开发出一款具有高精度导航和稳定飞行能力的无人机,广泛应用于农业监测、地质勘探等领域。这一技术的推出,不仅填补了市场空白,还为公司赢得了大量订单和合作伙伴,推动了公司的快速发展。

问答坊 | AI 解惑

关于MISRA-C,你知道多少?

学习MISRA C之一:“安全第一”的C语言编程规范 C语言是开发嵌入式应用的主要工具,然而C语言并非是专门为嵌入式系统设计,相当多的嵌入式系统较一般计算机系统对软件安全性有更苛刻的要求。1998 年,MISRA指出,一些在C看来可以接受,却存在安全隐 ...…

查看全部问答>

EVC下如何实现程序自删除

搜了一些自删除的程序和思路,全都是PC的,在EVC下不能运行,请问有谁做过EVC下程序的自删除…

查看全部问答>

51单片机 扩展19根地址线的SRAM````怎么做?

小弟课题实验,512K*8的内存,采用19地址线的SRAM,不想借用P1口,因为还有别的用处```关于页面管理的方法也不是很懂``` 初步采用8255.但是没有什么概念```8155可以么? 在线等待,谢谢 …

查看全部问答>

【求助】为DELL PowerEdge 860添加硬盘,什么样的sata盘都可以吗?

被朋友托了下周去IDC为DELL PowerEdge 860的服务器加块硬盘,但之前我没有去过IDC. RT,想了解一下是不是什么样的sata盘都可以吗,需要单买盘架吗? 另外,去之前要注意些什么事情?…

查看全部问答>

pelco-d协议的特殊指令如何使用?

想做一个云台解码器,看到pelco-d的官方文档时,并没有发现有诸如“巡航”等功能的指令。那么这些功能要执行,究竟要接收到什么命令?还是这些指令的“解释权”由产品的厂家实现?望不吝赐教…

查看全部问答>

cache与内存地址的转换问题

cache与内存地址的转换问题,大家帮忙下。是数工中的一个题: 高速缓存Cache与主存间采用全相联地址映像方式,高速缓存的容量为4MB,分为4块,每块IMB,主存容量为256MB。若主存读写时间为30ns,高速缓存的读写时间为3ns,平均读写时间为3.27ns, ...…

查看全部问答>

STM32内部内存SRAM如何化分一部分自定义使用

                                 现在想在STM32上的内存上化分一部分空间来自定义使用,不知如何做起,有哪位兄弟对这一块比较熟悉,望不吝赐教,谢 ...…

查看全部问答>

LM337电源模块电压变小

又到了一年一度的电子设计大赛时刻,可是电源模块实在是最简单,又是最基础最重要的模块。 目的:希望用线性稳压芯片LM337.LM317搭建可调模块,它具有纹波小,效率低特点 问题:搭建的LM317电路接负载时,输入正常,电压幅度不变。搭建的LM337电 ...…

查看全部问答>