本系列的库函数学习教程都是基于HAL库的,并且这个HAL库使用的是M7内核的库函数,如果使用的STM32型号低于STM32H7XX的时候发现有些HAL库函数在这些型号上没有也不用感到奇怪。
STM32H7的ADC位数是16位的。
1、HAL_StatusTypeDef HAL_ADC_Init (ADC_HandleTypeDef * hadc)
ADC的初始化函数。
ADC_HandleTypeDef ADC1_Handler;
ADC1_Handler.Instance = ADC1;
ADC1_Handler.Init.Resolution = ADC_RESOLUTION_16B; //分辨率为16位
ADC1.....
HAL_ADC_Init(&ADC1_Handler);
2、HAL_StatusTypeDef HAL_ADC_DeInit (ADC_HandleTypeDef * hadc)
ADC的复位函数,使用方法同上。
3、void HAL_ADC_MspInit (ADC_HandleTypeDef * hadc)
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
GPIO_InitTypeDef GPIO_Initure;
if(hadc->Instance == ADC1)
{ __HAL_RCC_ADC12_CLK_ENABLE(); //使能 ADC1 时钟
__HAL_RCC_GPIOA_CLK_ENABLE(); //开启 GPIOA 时钟
__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP); //ADC 外设时钟选择
GPIO_Initure.Pin=GPIO_PIN_5; //PA5
GPIO_Initure.Mode=GPIO_MODE_ANALOG; //模拟
GPIO_Initure.Pull=GPIO_NOPULL; //不带上下拉
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
}
}
初始化ADC底层硬件IO的函数,被HAL_ADC_Init()自动调用。
4、void HAL_ADC_MspDeInit (ADC_HandleTypeDef * hadc)
复位ADC底层硬件的函数。
5、HAL_StatusTypeDef HAL_ADC_Start (ADC_HandleTypeDef * hadc)
开启ADC转换的函数。
ADC_HandleTypeDef ADC1_Handler;
HAL_ADC_Start(&ADC1_Handler);
6、HAL_StatusTypeDef HAL_ADC_Stop (ADC_HandleTypeDef * hadc)
停止ADC转换的函数。
ADC_HandleTypeDef ADC1_Handler;
HAL_ADC_Stop(&ADC1_Handler);
7、HAL_StatusTypeDef HAL_ADC_PollForConversion (ADC_HandleTypeDef * hadc, uint32_t Timeout)
等待ADC在规定的时间内转化结束。
ADC_HandleTypeDef ADC1_Handler;
HAL_ADC_Start(&ADC1_Handler);
HAL_ADC_PollForConversion (&ADC1_Handler,10); //等待ADC转换结束最长等待10毫秒的时间
8、HAL_StatusTypeDef HAL_ADC_PollForEvent (ADC_HandleTypeDef * hadc, uint32_t EventType, uint32_t Timeout)
9、HAL_StatusTypeDef HAL_ADC_Start_IT (ADC_HandleTypeDef * hadc)
打开ADC中断。应用在ADC中断模式的时候。
ADC_HandleTypeDef ADC1_Handler;
HAL_ADC_Start_IT (&ADC1_Handler)
10、void HAL_ADC_IRQHandler (ADC_HandleTypeDef * hadc)
ADC中断请求,此函数被ADC_IRQHandler()调用,它自动启动回调函数 HAL_ADC_ConvCpltCallback ()。
11、 void HAL_ADC_ConvCpltCallback (ADC_HandleTypeDef * hadc)
ADC中断转换结束的回调函数(用于中断和DMA模式)。在ADC中断模式下,此函数需要自己重写,并且本函数会被函数10调用。ADC使用中断的时候注意点较多,这里指出其中之一是单次转化下ADC中断完成一次之后就会关闭,需要用户再次使用函数9打开。
void HAL_ADC_ConvCpltCallback (ADC_HandleTypeDef * hadc)
{
uint16_t adctemp=12;
char temps[16];
uint8_t temp =0 ;
HAL_ADC_Stop_IT(hadc); //关闭ADC中断转换
if(hadc->Instance == ADC1)
{
adctemp = HAL_ADC_GetValue (hadc);
sprintf(temps,"ADC:%d\r\n",adctemp);
HAL_UART_Transmit(&huart1,&temps,strlen(temps),20);
sprintf(temps,"VOL:%f\r\n",(adctemp*3.3/65536));
HAL_UART_Transmit(&huart1,&temps,strlen(temps),20);
}
//HAL_ADC_Stop_IT(hadc); //此处选择性的打开ADC采集
}
12、HAL_StatusTypeDef HAL_ADC_Start_DMA (ADC_HandleTypeDef * hadc, uint32_t * pData, uint32_t Length)
开启DMA采集ADC数据。
STM32其他系列的芯片在使用DMA传输ADC采集的数据的时候使用比较简单。
STM32 H7系列的ADC在DMA采集的模式下比较复杂,要注意的地方比较多。需要说明的是DMA存放数据的数组内存地址不能在0x24000000之前,另外需要打开CPU的透写支持,还有是需要使用函数HAL_ADC_ConvHalfCpltCallback和函数HAL_ADC_ConvCpltCallback进行数据无效化操作。另外存放ADC数据的数组长度应该为32字节的倍数,地址要进行32字节对齐。
//DMA存放数据的地方不能是0X24000000之前
#define ADC_CONVERTED_DATA_BUFFER_SIZE ((uint32_t) 32)
//指定地址并且32字节对齐
ALIGN_32BYTES (static uint16_t aADCxConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE]) __attribute__((section(".ARM.__at_0x24000000")));
HAL_ADC_Start_DMA(&hadc1, (uint32_t *)aADCxConvertedData, ADC_CONVERTED_DATA_BUFFER_SIZE);
// 主程序中需要打开透写配合DMA使用
/* Enable I-Cache---------------------------------------------------------*/
SCB_EnableICache();
/* Enable D-Cache---------------------------------------------------------*/
SCB_EnableDCache();
void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc)
{
/* Invalidate Data Cache to get the updated content of the SRAM on the first half of the ADC converted data buffer: 32 bytes */
SCB_InvalidateDCache_by_Addr((uint32_t *) &aADCxConvertedData[0], ADC_CONVERTED_DATA_BUFFER_SIZE);
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{
/* Invalidate Data Cache to get the updated content of the SRAM on the second half of the ADC converted data buffer: 32 bytes */
SCB_InvalidateDCache_by_Addr((uint32_t *) &aADCxConvertedData[ADC_CONVERTED_DATA_BUFFER_SIZE/2], ADC_CONVERTED_DATA_BUFFER_SIZE);
}
13、HAL_StatusTypeDef HAL_ADC_Stop_DMA (ADC_HandleTypeDef * hadc)
停止ADC的DMA模式
ADC_HandleTypeDef hadc1;
HAL_ADC_Stop_DMA (&hadc1)
14、uint32_t HAL_ADC_GetValue (ADC_HandleTypeDef * hadc)
获取ADC转换的值,在中断模式和阻塞模式下可以使用本函数获取ADC转换的结果,如果使用的是DMA模式不用这个函数获取结果,直接读取数组的指定位置的值就可以。
15、void HAL_ADC_ConvHalfCpltCallback (ADC_HandleTypeDef * hadc)
非阻塞模式下的转换DMA半传输回调函数,作用是在函数12中。
16、void HAL_ADC_LevelOutOfWindowCallback (ADC_HandleTypeDef * hadc)
非阻塞模式下的模拟看门狗1回调。ADC的看门狗功能是需要建立一个电压阈值区间,分为上限电压和下限电压,在ADC转换的电压值在此范围之内的情况本函数不会执行,如果ADC电压转换值不在此范围中会调用函数十六。此函数需要打开ADC转换中断。
ADC_AnalogWDGConfTypeDef AnalogWDGConfig = {0};
AnalogWDGConfig.WatchdogNumber = ADC_ANALOGWATCHDOG_1;
AnalogWDGConfig.WatchdogMode = ADC_ANALOGWATCHDOG_SINGLE_REG;
AnalogWDGConfig.Channel = ADC_CHANNEL_3;
AnalogWDGConfig.ITMode = ENABLE; //启动ADC中断
AnalogWDGConfig.HighThreshold = 2000; //ADC转换值上限
AnalogWDGConfig.LowThreshold = 500; //ADC转换值下限
if (HAL_ADC_AnalogWDGConfig(&ADC1_Handler, &AnalogWDGConfig) != HAL_OK)
{
// Error_Handler();
}
//对应的ADC中断打开
HAL_NVIC_SetPriority(ADC1_2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(ADC1_2_IRQn);
//
void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef * hadc)
{
if(hadc->Instance == ADC1)
{
//触发对应的ADC看门狗异常标志位
}
}
17、HAL_ADC_StateTypeDef HAL_ADC_GetState (ADC_HandleTypeDef * hadc)
获取当前ADC转换的状态。
18 、uint32_t HAL_ADC_GetError (ADC_HandleTypeDef * hadc)
获取当前ADC转换的错误状态码。