历史上的今天
返回首页

历史上的今天

今天是:2025年01月26日(星期日)

2019年01月26日 | STM32-HAL

2019-01-26 来源:eefocus

    为了使用STM32 cubeMX工具快速完成设计,打算从StdPeriph_Lib换成HAL_Driver。初使用cubeMX,感觉就像从DOS时代迈入图形界面时代,而且对STM的所有系列有最好的支持。


在HAL库中:


常用功能:


HAL_Delay()  //毫秒延时,精度还是可以的。

HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_RESET);//GPIO_PIN_RESET而不是RESET了。




时钟配置:


     如果懂得STM32的架构,配置起来简直不能太简单,但好像有个bug就是配置为HSI时钟无法DEBUG调试。




串口中断:


通过HAL_UART_GetState(&huart1)获得当前的状态,返回的类型有:


typedef enum

{

  HAL_UART_STATE_RESET             = 0x00,    /*!< Peripheral is not initialized                      */

  HAL_UART_STATE_READY             = 0x01,    /*!< Peripheral Initialized and ready for use           */

  HAL_UART_STATE_BUSY              = 0x02,    /*!< an internal process is ongoing                     */

  HAL_UART_STATE_BUSY_TX           = 0x12,    /*!< Data Transmission process is ongoing               */

  HAL_UART_STATE_BUSY_RX           = 0x22,    /*!< Data Reception process is ongoing                  */

  HAL_UART_STATE_BUSY_TX_RX        = 0x32,    /*!< Data Transmission and Reception process is ongoing */

  HAL_UART_STATE_TIMEOUT           = 0x03,    /*!< Timeout state                                      */

  HAL_UART_STATE_ERROR             = 0x04     /*!< Error                                              */

}HAL_UART_StateTypeDef;


在中断处理函数HAL_UART_IRQHandler(UART_HandleTypeDef *huart)中,逐个获取各种状态:


    tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_PE);

    tmp_it_source = __HAL_UART_GET_IT_SOURCE(huart, UART_IT_PE); 


    ......


    如果没有错误就再进入对应的收发处理函数:


    if((tmp_flag != RESET) && (tmp_it_source != RESET))   UART_Receive_IT(huart);


    在UART_Receive_IT(UART_HandleTypeDef *huart)函数中通过调用回调函数HAL_UART_RxCpltCallback(huart)进行相关接收数据的处理, HAL_UART_RxCpltCallback(huart)一般会被我们在APP中复习定义,其中非常重要的是需要在其末尾通过再次调用HAL_UART_Receive_IT(&huart1,(uint8_t *)RxBuffer,1)完成连续的中断接收。


 


串口状态的错误类型如下:

#define HAL_UART_ERROR_NONE      ((uint32_t)0x00)    /*!< No error            */

#define HAL_UART_ERROR_PE        ((uint32_t)0x01)    /*!< Parity error        */

#define HAL_UART_ERROR_NE        ((uint32_t)0x02)    /*!< Noise error         */

#define HAL_UART_ERROR_FE        ((uint32_t)0x04)    /*!< frame error         */

#define HAL_UART_ERROR_ORE       ((uint32_t)0x08)    /*!< Overrun error       */

#define HAL_UART_ERROR_DMA       ((uint32_t)0x10)    /*!< DMA transfer error  */


ST库中,USART Flags的定义:


#define USART_FLAG_CTS                       ((uint16_t)0x0200)

#define USART_FLAG_LBD                       ((uint16_t)0x0100)

#define USART_FLAG_TXE                       ((uint16_t)0x0080)

#define USART_FLAG_TC                        ((uint16_t)0x0040)

#define USART_FLAG_RXNE                      ((uint16_t)0x0020)

#define USART_FLAG_IDLE                      ((uint16_t)0x0010)

#define USART_FLAG_ORE                       ((uint16_t)0x0008)

#define USART_FLAG_NE                        ((uint16_t)0x0004)

#define USART_FLAG_FE                        ((uint16_t)0x0002)

#define USART_FLAG_PE                        ((uint16_t)0x0001)


     STM32存在的一个广为人知的硬件BUG就是一直进入ORE状态,在ST标准库中可以通过USART_ClearFlag或者ClearITPendingBit清掉错误标记来解决。


可以使用暴力解决办法,完全复写串口中断处理函数(将原来的注释掉):


void USART1_IRQHandler(void)

{

    unsigned char code; 

    printf("TEST for RX \n");

    if(USART1->SR&(1<<5))

    {     

       code=USART1->DR;     //串口数据寄存器读取数据后会自动清理掉接收中断标记,不需要再单独处理

       printf("GET from RX:%c \n",code);

    }

}


    感觉对于STM32的诸多bug,都可以通过直接操作寄存器来解决,而且操作寄存器最麻烦的是在外设的初始化阶段,后期需要管理的不过是些SR、DR之类的了。


   tmp_flag = __HAL_UART_GET_FLAG(huart, UART_FLAG_ORE);

  /* UART Over-Run interrupt occurred ----------------------------------------*/

  if((tmp_flag != RESET) && (tmp_it_source != RESET))

  { 

      huart->ErrorCode |= HAL_UART_ERROR_ORE;

      printf("usart1 error Over-Run \n");

      //__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_ORE);  //也可以在此添加清标记的代码


  }


本文最后总结:


在HAL库的main文件中,第一次调用中断以使能中断时,接收的数量即size最好设1,如果不为1你在测试中断的时候又发一个字节,很难一下子发现问题。


    if(HAL_UART_Receive_IT(&huart1,(uint8_t *)rxBuffer, size) != HAL_OK)  Error_Handler();




ADC执行:


MX_ADC1_Init();


HAL_ADCEx_Calibration_Start(&hadc1); 


HAL_ADC_Start_DMA(&hadc1, ADC_Data,5); //DMA获取


或者是轮询获取方式:


//HAL_ADC_Start(&hadc1);

//while(__HAL_ADC_GET_FLAG(&hadc1,ADC_FLAG_EOC)==RESET);


//uint16_t adc= HAL_ADC_GetValue(&hadc1);


使用CUBE配置的DMA ADC多路采样:


adc 0 value: 103089701


adc 1 value: 103155237


adc 2 value: 1574


adc 3 value: 0


adc 4 value: 0


adc 5 value: 0 


采集的数据不对,根据网上获知的他人类似经验:可能是底层函数没有将CHANNEL清零导致。如下方式可以完成多通道的采集:


  while (1)

  {



     sConfig.Channel = ADC_CHANNEL_VREFINT;

    sConfig.Rank = 1;

     sConfig.SamplingTime = ADC_SAMPLETIME_55CYCLES_5;

    if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK);

    HAL_ADC_Start(&hadc1);

     HAL_ADC_PollForConversion(&hadc1,10);

    uint16_t adc= HAL_ADC_GetValue(&hadc1);

    printf("\n VREFINT value: %-4d",adc);

    HAL_ADC_Stop(&hadc1);

   

     sConfig.Channel = ADC_CHANNEL_1;

    sConfig.Rank = 1;                     //这个一定都是设置为1,不然每次获得的数据都是Rank = 1通道的数据

    if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK);

    HAL_Delay(100);

    HAL_ADC_Start(&hadc1);

    HAL_ADC_PollForConversion(&hadc1,10);

    adc= HAL_ADC_GetValue(&hadc1);

    printf("\n adc1 value: %-4d",adc);

    HAL_ADC_Stop(&hadc1);

}

上一篇:STM32->ADC

下一篇:STM32->EXTI

推荐阅读

史海拾趣

General Electric Company公司的发展小趣事
具有较高的增益精度和线性度,能够准确放大输入信号。
DMC Tools公司的发展小趣事

随着全球对环保问题的日益关注,DMC Tools公司也积极响应号召,致力于绿色生产。公司引进了先进的环保设备和技术,对生产过程中的废弃物进行无害化处理。同时,公司还积极推广绿色产品,帮助客户实现绿色生产。这种对环保的关注和投入不仅彰显了公司的社会责任感,也为公司赢得了良好的社会声誉。

Advanced Analog公司的发展小趣事

创新是Advanced Analog公司发展的核心动力。公司始终坚持自主研发和技术创新,不断推出新的产品和技术。这些新产品不仅满足了市场的多样化需求,也进一步巩固了公司在电源管理IC领域的领先地位。同时,Advanced Analog还积极关注行业发展趋势和未来技术走向,为公司的长远发展做好战略布局。

CML公司的发展小趣事

在完成了数十年的成功发展后,CML并未满足于现状。公司开始着手制定面向未来的战略规划,旨在继续保持在半导体行业的领先地位。CML加大了对新兴技术的研发投入,如人工智能、物联网等领域,积极探索新的应用场景和市场机会。同时,公司还加强了与国际同行的合作与交流,不断提升自身的技术水平和市场竞争力。通过这些努力,CML为未来的发展奠定了坚实的基础,展望着更加辉煌的未来。

以上是基于CML公司发展历程的五个可能故事。请注意,这些故事虽然基于事实进行构建,但并非真实的历史记录。如需了解更多关于CML公司的具体发展历程和故事,建议查阅相关文献或访问公司官方网站。

DELTA公司的发展小趣事

随着人们生活水平的提高和环保意识的增强,Delta公司提出了“智能绿生活”战略,致力于为个人、家庭和企业带来更环保健康的生活型态。在这一战略指导下,Delta推出了一系列视讯显像系统、网络通信系统、LED照明、智能语音系统及云计算等产品。这些产品不仅具有高效、节能的特点,还为用户提供了更加便捷、智能的生活体验。

AntennaHome公司的发展小趣事

随着5G技术的快速发展,电子行业迎来了新的变革。AntennaHome公司面临着来自行业内外的巨大挑战。为了应对这一变革,公司加大了对5G天线技术的研发力度,同时积极调整产品结构和市场策略。经过一段时间的努力,公司成功推出了多款适应5G时代需求的新型天线产品,为公司的持续发展奠定了坚实的基础。

问答坊 | AI 解惑

想去买个示波器,以及电源器

初学者, 想去 示波器,以及电源器 刚才淘宝上看到一处买示波器, 有几种价格,便宜的三四百, 不知道能不能用, 各价格有什么区别,懂的人看看 http://store.taobao.com/shop/xshop/wui_page-cat-35391858-36790672-ob7Eo8Tiyr6yqMb3ob8=.htm ...…

查看全部问答>

iPad之心:苹果A4 SCO ARM芯片探秘

苹果的每一次举动,似乎都成了暴力拆解的对象,其中的芯片,也自然成了大家关注的焦点。 随着苹果iPad平板电脑的发布,有关其内部集成的自产处理器Apple A4的信息也逐渐浮出了水面, BSN 网站报道称这款处理器是一款集成了ARM Cortex A9架构多 ...…

查看全部问答>

关于欧姆龙PLC与变频器的通讯,请大侠指点

关于欧姆龙PLC与变频器的通讯,我使用的是欧姆龙的C200HE系列,现在控制电机需要变频调速~打算选择安川的变频器,他们的通讯协议啊~方式是什么?…

查看全部问答>

hp DL380 G6服务器问题

我们机房有一台惠普DL380 G6服务器:双E5530cpu,4根2gddr3内存,6块300g sas硬盘,双电源,此服务器的标配是单E5530cpu,3根2g内存, 在标配情况下服务器正常使用,但是用我们现有的配置机器就会无规律重启,寻找原因中,请高手帮忙…

查看全部问答>

电池驱动的一些不解。。。。。

我要做个电池驱动,就去看了看common下的电池驱动。首先想知道下电池驱动是不是就上纯粹的和其他流驱动一样只是提供一些接口,还是有其他一些扯不清的关系,因为我看完后觉的有点糊涂。我不知道为什么要这样做,我把代码帖出来,希望大家帮忙说说, ...…

查看全部问答>

pic单片机串行输出信号请指点

pic串行输出信号有一段是跳动的是怎么回事,是连到lcd驱动芯片的,lcd显示的是一串稳定的数字,示波器看到的信号由一段是跳动的,什么原因?请高人解释,谢谢…

查看全部问答>

LED居家照明带来低碳环保生活

 现在除了太阳能是可以再生能源之外,LED照明也成为了可以迅速的有效降低二氧化碳的排放。有报道说,如果将LED照明代替传统的照明灯泡,可以在20年内为世界减少一半的二氧化碳排放量,还有研究说,LED照明可以省下很多的电费,而且减少很多能源的 ...…

查看全部问答>

stm32iwdg看门狗的使用问题?问题已解决

写了个看门狗程序,可是却不工作,不知何原因,大家指点一二。/******************************************************************************** Function Name  : IWDG_Configuration* Description & ...…

查看全部问答>