历史上的今天
今天是: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
史海拾趣
|
初学者, 想去 示波器,以及电源器 刚才淘宝上看到一处买示波器, 有几种价格,便宜的三四百, 不知道能不能用, 各价格有什么区别,懂的人看看 http://store.taobao.com/shop/xshop/wui_page-cat-35391858-36790672-ob7Eo8Tiyr6yqMb3ob8=.htm ...… 查看全部问答> |
|
苹果的每一次举动,似乎都成了暴力拆解的对象,其中的芯片,也自然成了大家关注的焦点。 随着苹果iPad平板电脑的发布,有关其内部集成的自产处理器Apple A4的信息也逐渐浮出了水面, BSN 网站报道称这款处理器是一款集成了ARM Cortex A9架构多 ...… 查看全部问答> |
|
关于欧姆龙PLC与变频器的通讯,我使用的是欧姆龙的C200HE系列,现在控制电机需要变频调速~打算选择安川的变频器,他们的通讯协议啊~方式是什么?… 查看全部问答> |
|
我们机房有一台惠普DL380 G6服务器:双E5530cpu,4根2gddr3内存,6块300g sas硬盘,双电源,此服务器的标配是单E5530cpu,3根2g内存, 在标配情况下服务器正常使用,但是用我们现有的配置机器就会无规律重启,寻找原因中,请高手帮忙… 查看全部问答> |
|
我要做个电池驱动,就去看了看common下的电池驱动。首先想知道下电池驱动是不是就上纯粹的和其他流驱动一样只是提供一些接口,还是有其他一些扯不清的关系,因为我看完后觉的有点糊涂。我不知道为什么要这样做,我把代码帖出来,希望大家帮忙说说, ...… 查看全部问答> |
|
pic串行输出信号有一段是跳动的是怎么回事,是连到lcd驱动芯片的,lcd显示的是一串稳定的数字,示波器看到的信号由一段是跳动的,什么原因?请高人解释,谢谢… 查看全部问答> |
|
现在除了太阳能是可以再生能源之外,LED照明也成为了可以迅速的有效降低二氧化碳的排放。有报道说,如果将LED照明代替传统的照明灯泡,可以在20年内为世界减少一半的二氧化碳排放量,还有研究说,LED照明可以省下很多的电费,而且减少很多能源的 ...… 查看全部问答> |
|
写了个看门狗程序,可是却不工作,不知何原因,大家指点一二。/******************************************************************************** Function Name : IWDG_Configuration* Description & ...… 查看全部问答> |




