电机控制-stm32f4 AD配置(二)

STM32_F4_ADC_lxtqyh的博客-CSDN博客_stm32f4adc通道

一、cubemx设置

 

 

 二、keil编写

这里ad不用中断,打开dma,adc1 adc2 双重模式,触发方式为软件触发。

使用软件触发,不开DMA:
HAL_ADC_Start(&ADC1_Handler); //开启 ADC
HAL_StatusTypeDef HAL_ADC_PollForConversion(ADC_HandleTypeDef* hadc,uint32_t Timeout); //查询方式等待上一次转换结束。
uint32_t HAL_ADC_GetValue(ADC_HandleTypeDef* hadc); //读取adc的值。

HAL_ADC_Stop();

软件触发,开DMA:
HAL_ADC_Start_DMA();//就这个就行
 

注意,当前hal库版本中没有校准这一步了。

例子:https://blog.csdn.net/qiyu040526/article/details/120993467

uint16_t ADC_res[3];//定义数组存储数据
HAL_ADC_Start_DMA (&hadc1,(uint32_t*)ADC_res,3);//以DMA方式打开ADC1,最后一个参数为数据数量
while (1)
  {
        printf ("1:%d  2:%d  3:%d \r\n",ADC_res[0],ADC_res[1],ADC_res[2]);
  }

三、电机中adc dma的使用方式:

1.使用定时器中断每隔一定时间进行ADC转换,这样每次都必须读ADC的数据寄存器,非常浪费时间;

2.把ADC设置成连续转换模式,同事对应的DMA通道开启循环模式,这样ADC就一直在进行数据采集然后通过DMA把数据搬运至内存。再加一个定时中断,用来定时读取内存中的数据。
//这样相当于ad一直在工作。但无法保证读取的值是采样点的值。
3.使用ADC的定时器触发ADC转换的功能,然后使用DMA进行数据的搬运,这样只要设置好定时器的触发间隔,就能实现ADC定时采样转换的功能,然后可以在程序的死循环中一直检
测DMA转换完成标志,然后进行数据的读取,或者使能DMA转换完成中断,这样每次转换完成就会产生中断。
//历程中时采用的类似这种方式。TIM1给TGRO2到ADC1,adc1开启外部触发方式,选择TIM1的TRGO2。这样每次TIM1发生更新事件(三角波下溢),就会触发adc采样。
 

四、双adc dma:https://blog.csdn.net/m0_46637061/article/details/121003074         尝试失败。目前的hal好像无法实现了。

https://blog.csdn.net/qq_37281984/article/details/122354897 看(四)

我的理解:

双adc规则同步模式,adc1设置一个触发方式(我设置的是软件触发),adc2自动没有触发方式的选项了。

ADC1打开dma,字长选择32位,adc2不打开dma。这样调用

HAL_ADC_Start_DMA (&hadc1,(uint32_t*)ADC_res,1);//以DMA方式打开ADC1,最后一个参数为数据数量

后,adc1的数值放在高16位,adc2的数值放在低16位。数据处理:

 float ADC_ConverValuelocal[2];//存放转换的数值
 int main(void)
 {    
 //    int i;
     u16 temp0,temp1;
     delay_init();             //延时函数初始化      
     NVIC_Configuration();      //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
     uart_init(9600);     //串口初始化为9600
      LED_Init();                 //LED端口初始化
     KEY_Init();          //初始化与按键连接的硬件接口
     ADC_DMA_config();
     ADCx_Init();
     
         while(1)
         {
             //取出寄存器的高16位--ADC2值
             temp0=(ADC_ConValue[0]&0xffff0000)>>16;
             //取出ADC的低16位---adc1值
             temp1=ADC_ConValue[0]&0xffff;
             
           ADC_ConverValuelocal[0]=(float)temp0/4096*3.3;//adc2的值
             
             ADC_ConverValuelocal[1]=(float)temp1/4096*3.3;//adc1的值
 
 
             
             printf("The current ADC1_Value=%f V\r\n",ADC_ConverValuelocal[1]);//adc1的转换值
             printf("The current ADC2_Value=%f V\r\n",ADC_ConverValuelocal[0]);//adc2的转换值
     
 
             printf("\r\n");
             delay_ms(1500);
         }
             
 
 }

 

 

 

 

 

 

 

 

posted @ 2022-04-27 20:40  jamaal555  阅读(304)  评论(0)    收藏  举报