STM32 HAL库学习系列第1篇 ADC配置 及 DAC配置

ADC工作均为非阻塞状态

轮询模式

中断模式

DMA模式


 

库函数:

 1 HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc);//轮询模式,需放在循环中不断开启
 2 
 3 HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc);
 4 
 5 HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc, uint32_t Timeout);//等待转换结束,只适用于轮询
 6 
 7 HAL_StatusTypeDef HAL_ADC_PollForEvent(ADC_HandleTypeDef* hadc, uint32_t EventType, uint32_t Timeout);//
 8 
 9 HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc);//中断模式
10 
11 HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc);
12 
13 void HAL_ADC_IRQHandler(ADC_HandleTypeDef* hadc);//中断
14 
15 HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length);//DMA模式
16 
17 HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc);
18 
19 uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc); //读取ADC的值
20 
21 void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc);//结束后回调
22 
23 void HAL_ADC_ConvHalfCpltCallback(ADC_HandleTypeDef* hadc);//转换过程中回调
24 
25 void HAL_ADC_LevelOutOfWindowCallback(ADC_HandleTypeDef* hadc);
26 
27 void HAL_ADC_ErrorCallback(ADC_HandleTypeDef *hadc);

 

 

校准模式:

校准ADC(HAL_ADCEx_Calibration_Start(&hadc);有些芯片不支持校准,F4不支持

----------------------------------------------------------------------------------------------------------------------------------

可变占空比设置

 1 /*
 2 
 3 实际使用时空置引脚状态下会飘动,大致为3.3V的一半,是芯片内部的原因
 4 
 5 解决方式:引脚设置为下拉输入,F4没有这个设置
 6 
 7 */
 8 
 9 /* USER CODE BEGIN 2 */
10 
11 //  HAL_ADC_Start_IT(&hadc1);//开启ad转换
12 
13     HAL_TIM_Base_Start_IT(&htim3);//定时器中断
14 
15   HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_2);//开启输出pwm
16 
17   /* USER CODE END 2 */
18 
19   /* Infinite loop */
20 
21   /* USER CODE BEGIN WHILE */
22 
23   while (1)
24 
25   {
26 
27   /* USER CODE END WHILE */
28 
29   /* USER CODE BEGIN 3 */
30 
31         float pwmOut ;
32 
33         float dutyRatio;
34 
35         int lastTickMs=0;
36 
37         HAL_ADC_Start(&hadc1);
38 
39         
40 
41         if(HAL_GetTick() - lastTickMs >= 1000)
42 
43     {
44 
45         HAL_GPIO_TogglePin(RUNNING_LED_GPIO_Port,RUNNING_LED_Pin);
46 
47         lastTickMs = HAL_GetTick();      
48 
49     }
50 
51     HAL_Delay(1000);
52 
53         adcConvertedValue=HAL_ADC_GetValue(&hadc1);//获取AD转换值
54 
55     adcConvertedVoltage =(double)adcConvertedValue*3.3/4096;        
56 
57         
58 
59         pwmOut = adcConvertedValue*2400/4096;
60 
61         dutyRatio = pwmOut/2400 ;
62 
63         TIM3->CCR2 = pwmOut;    //(pwmOut)/ 2400    change Duty ratio
64 
65         
66 
67         printf("AD转换原始值 = %d\r\n", adcConvertedValue);
68 
69         printf("计算得出电压值 = %f V \r\n",adcConvertedVoltage);
70 
71         printf("实际输出pwm值 = %f\r\n", pwmOut);
72 
73         printf("占空比 = %f%%\r\n",dutyRatio*100);
74 
75   }
76 
77   /* USER CODE END 3 */
78 
79 }

 

 

手动更改占空比

TIM3->CCR2   改变占空比

TIM3->ARR 改变频率

TIM3->PSC 

ADC_EXIT  触发引脚

 

32芯片自带的温度传感器,在16或者18通道

可以用来做对比

代码:

 1 //对于12位的ADC,3.3V的ADC值为0xfff,温度为25度时对应的电压值为1.43V即0x6EE
 2 #define V25  0x6EE
 3 //斜率 每摄氏度4.3mV 对应每摄氏度0x05
 4 #define AVG_SLOPE 0x05
 5   
 6 
 7 /* 启动AD转换并使能DMA传输和中断 */
 8   HAL_ADC_Start_DMA(&hadcx,(uint32_t *)&ADC_ConvertedValue,sizeof(ADC_ConvertedValue)); 
 9  
10   /* 无限循环 */
11   while (1)
12   {
13     HAL_Delay(1000);
14     Current_Temperature = (V25-ADC_ConvertedValue)/AVG_SLOPE+25;  //计算公式   
15       /* 10进制显示 */
16     printf("The IC current temperature = %d->%3d ℃\n",ADC_ConvertedValue,Current_Temperature);
17 //    /* 16进制显示 */                        
18 //    printf("The current temperature= %04x \n", Current_Temperature);  
19   }

 

应用:测量压敏电阻阻值---还是测电压

 1   while (1)
 2   {
 3     HAL_Delay(1000);
 4     /* 3.3为AD转换的参考电压值,stm32的AD转换为12bit,2^12=4096,
 5        即当输入为3.3V时,AD转换结果为4096 */
 6     ADC_ConvertedValueLocal =(float)ADC_ConvertedValue*3.3/4096;
 7     flexiforce_R = 3.3*20/ADC_ConvertedValueLocal; // V(out) = Rref * Vcc / R;  Rref=20K  Vcc=3.3V
 8         printf("AD转换原始值 = 0x%04X \r\n", ADC_ConvertedValue);
 9         printf("计算得出电压值 = %f V \r\n",ADC_ConvertedValueLocal);
10     printf("计算得出电阻值 = %f KR\n",flexiforce_R);
11   }

 

DMA多通道采集-----开启多通道设置,定义一个数组存放转换值

 1   while (1)
 2   {
 3     HAL_Delay(1000);
 4     /* 3.3为AD转换的参考电压值,stm32的AD转换为12bit,2^12=4096,
 5        即当输入为3.3V时,AD转换结果为4096 */   
 6     ADC_ConvertedValueLocal[0] =(float)(ADC_ConvertedValue[0]&0xFFF)*3.3/4096; // ADC_ConvertedValue[0]只取最低12有效数据
 7       ADC_ConvertedValueLocal[1] =(float)(ADC_ConvertedValue[1]&0xFFF)*3.3/4096; // ADC_ConvertedValue[1]只取最低12有效数据
 8     ADC_ConvertedValueLocal[2] =(float)(ADC_ConvertedValue[2]&0xFFF)*3.3/4096; // ADC_ConvertedValue[2]只取最低12有效数据
 9     ADC_ConvertedValueLocal[3] =(float)(ADC_ConvertedValue[3]&0xFFF)*3.3/4096; // ADC_ConvertedValue[3]只取最低12有效数据
10    
11     printf("CH1_PC0 value = %d -> %fV\n",ADC_ConvertedValue[0]&0xFFF,ADC_ConvertedValueLocal[0]);
12     printf("CH2_PC1 value = %d -> %fV\n",ADC_ConvertedValue[1]&0xFFF,ADC_ConvertedValueLocal[1]);
13     printf("CH3_PC2 value = %d -> %fV\n",ADC_ConvertedValue[2]&0xFFF,ADC_ConvertedValueLocal[2]);
14     printf("CH4_PC3 value = %d -> %fV\n",ADC_ConvertedValue[3]&0xFFF,ADC_ConvertedValueLocal[3]);
15 
16     printf("已经完成AD转换次数:%d\n",DMA_Transfer_Complete_Count);
17     DMA_Transfer_Complete_Count=0;
18     printf("\n");  
19   }

 

交叉模式---目的是两路ADC采集一路信号,可以获取双倍速度

 1 /* 启动AD转换并使能DMA传输和中断 */
 2   HAL_ADC_Start(&hadcx2);
 3   HAL_ADCEx_MultiModeStart_DMA(&hadcx1,&ADC_ConvertedValue,sizeof(ADC_ConvertedValue)); //开启
 4  
 5   /* 无限循环 */
 6   while (1)
 7   {
 8     HAL_Delay(1000);
 9     /* 3.3为AD转换的参考电压值,stm32的AD转换为12bit,2^12=4096,
10        即当输入为3.3V时,AD转换结果为4096 */
11     ADC_ConvertedValueLocal[0] =(float)(ADC_ConvertedValue&0xFFF)*3.3/4096;  //ADC1
12     ADC_ConvertedValueLocal[1] =(float)((ADC_ConvertedValue>>16)&0xFFF)*3.3/4096;   //ADC2
13    
14     printf("ADC1转换原始值 = 0x%04X --> 电压值 = %f V \n", ADC_ConvertedValue&0xFFFF,ADC_ConvertedValueLocal[0]);   
15     printf("ADC2转换原始值 = 0x%04X --> 电压值 = %f V \n", (ADC_ConvertedValue>>16)&0xFFFF,ADC_ConvertedValueLocal[1]);     
16     printf("已经完成AD转换次数:%d\n",DMA_Transfer_Complete_Count);
17     printf("\r\n");   
18     DMA_Transfer_Complete_Count=0;
19   }

 

DAC---数据转换

基本配置:

初始化

设置通道

启动DAC

在循环中改变dac_value值即可

 

库函数:

 1 /* IO operation functions *****************************************************/
 2 HAL_StatusTypeDef HAL_DAC_Start(DAC_HandleTypeDef* hdac, uint32_t Channel);
 3 HAL_StatusTypeDef HAL_DAC_Stop(DAC_HandleTypeDef* hdac, uint32_t Channel);
 4 HAL_StatusTypeDef HAL_DAC_Start_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t* pData, uint32_t Length, uint32_t Alignment); //需要函数中不断开启
 5 HAL_StatusTypeDef HAL_DAC_Stop_DMA(DAC_HandleTypeDef* hdac, uint32_t Channel);
 6 HAL_StatusTypeDef HAL_DAC_SetValue(DAC_HandleTypeDef* hdac, uint32_t Channel, uint32_t Alignment, uint32_t Data);
 7 uint32_t HAL_DAC_GetValue(DAC_HandleTypeDef* hdac, uint32_t Channel);
 8 
 9   /* 初始化DAC */
10   MX_DAC_Init();
11   /* 设置DAC通道值 */
12   HAL_DAC_SetValue(&hdac, DACx_CHANNEL, DAC_ALIGN_8B_R, dac_value);
13   /* 启动DAC */
14   HAL_DAC_Start(&hdac, DACx_CHANNEL);
15  
16   /* 无限循环 */
17   while (1)
18   {
19     /* KEY1增加输出电压 */
20     if(KEY1_StateRead()==KEY_DOWN)
21     {
22       if(dac_value<245)
23         dac_value+=10;  
24       else
25         dac_value=255;       
26       HAL_DAC_SetValue(&hdac, DACx_CHANNEL, DAC_ALIGN_8B_R, dac_value);  //设置值
27     }
28     /* KEY2减少输出电压 */
29     if(KEY2_StateRead()==KEY_DOWN)
30     {
31       if(dac_value>10)
32         dac_value-=10;  
33       else
34         dac_value=0;
35       HAL_DAC_SetValue(&hdac, DACx_CHANNEL, DAC_ALIGN_8B_R, dac_value);
36     }
37   }

 

输出正弦波----DMA模式

就是预设一组值,不断改变

 1 const uint16_t CH_value[32] = {
 2     2448,2832,3186,3496,3751,3940,4057,4095,4057,3940,
 3     3751,3496,3186,2832,2448,2048,1648,1264,910,600,345,
 4     156,39,0,39,156,345,600,910,1264,1648,2048
 5 };
 6 
 7 
 8 
 9 
10 int main(void)
11 {  
12   /* 复位所有外设,初始化Flash接口和系统滴答定时器 */
13   HAL_Init();
14   /* 配置系统时钟 */
15   SystemClock_Config();
16  
17  
18   /* 初始化DAC */
19   MX_DAC_Init();
20   /* 启动定时器 */
21   HAL_TIM_Base_Start(&htim6);
22   /* 启动DAC DMA功能 */
23   HAL_DAC_Start_DMA(&hdac,DACx_CHANNEL,(uint32_t *)CH_value,32,DAC_ALIGN_12B_R);
24   /* 无限循环 */
25   while (1)
26   {
27    
28   }
29 }

 

2019-03-26

 

posted @ 2019-03-26 20:57  CodeAllen  阅读(8829)  评论(0编辑  收藏  举报