最近项目用到了F4单片机的片内AD,在网上搜索到的中断采集方式介绍都不详细,现分享一下自己调试通过的代码,希望对大家有所帮助,如有不足望指导,谢谢!!!
一、目的:使用多通道中断方式进行采集
二、实施步骤: 1、配置ADC ->开启扫描模式 ->开启EOC中断 ->开启连续转换 ->设置通道总数量,即你要用几个通道进行转换(勿忘) 2、ADC回调函数内配置各模拟输入引脚,选为模拟不带上下拉. 3、配置ADC通道: -> 配置第几个通道,第几次转换,转换时间,以上图为例,因为在初始化中配置通道总数为3个,所以通道5为第一次转换,通道6第二次转换,通道9第三次转换,采样周期 480个时钟周期 ->以中断方式开启ADC(勿忘此处必须以中断方式开启) ->配置中断优先级并开启AD中断 4、重写ADC中断回调函数以及服务函数: -> 在服务函数内需要进行计数判断当前中断的转换值属于哪一个通道,因为在通道配置内设置的顺序为通道5,通道6,通道9,切为扫描模式转换,所以进入中断的顺序即转换的顺序也为5,6,9,因此此处直接判断计数值将转换数值放入相应位置即可。(此处直接操作寄存器提取转换数值速度会快很多) 5、程序源码: void MY_ADC_Init(void) { //ADC初始化程序 ADC1_Handler.Instance=ADC1; ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV4; ADC1_Handler.Init.Resolution=ADC_RESOLUTION_12B; ADC1_Handler.Init.DataAlign=ADC_DATAALIGN_RIGHT; ADC1_Handler.Init.ScanConvMode=ENABLE; //开启扫描模式 ADC1_Handler.Init.EOCSelection=ENABLE; //开启EOC中断 ADC1_Handler.Init.ContinuousConvMode=ENABLE;//开启连续按转换 ADC1_Handler.Init.NbrOfConversion=3; //通道总数为3 ADC1_Handler.Init.DiscontinuousConvMode=DISABLE; ADC1_Handler.Init.NbrOfDiscConversion=0; ADC1_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START; ADC1_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_NONE; ADC1_Handler.Init.DMAContinuousRequests=DISABLE; HAL_ADC_Init(&ADC1_Handler); } void ch_config (void) { //通道配置 ADC_ChannelConfTypeDef ADC1_ChanConf; ADC1_ChanConf.Channel=ADC_CHANNEL_5; //通道5 ADC1_ChanConf.Rank=1; //第一次转换 ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES;//转换周期 ADC1_ChanConf.Offset=0; HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); ADC1_ChanConf.Channel=ADC_CHANNEL_6; //通道6 ADC1_ChanConf.Rank=2; //第二次转换 ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES; ADC1_ChanConf.Offset=0; HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); ADC1_ChanConf.Channel=ADC_CHANNEL_9; //通道9 ADC1_ChanConf.Rank=3; //第三次转换 ADC1_ChanConf.SamplingTime=ADC_SAMPLETIME_480CYCLES; ADC1_ChanConf.Offset=0; HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); HAL_ADC_Start_IT(&ADC1_Handler); //必须以中断方式开启 HAL_NVIC_SetPriority(ADC_IRQn,1,0); //中断优先级 HAL_NVIC_EnableIRQ(ADC_IRQn); //开启中断 } void ADC_IRQHandler(void) { //回调函数 HAL_ADC_ConvCpltCallback(&ADC1_Handler); } void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc) { //服务函数,真正要干的事 nn++; HAL_NVIC_ClearPendingIRQ(ADC_IRQn); //清除中断 switch(nn) //判断相应通道值,存入相应位置 { case 1: aa=ADC1_Handler.Instance->DR; break; case 2: bb=ADC1_Handler.Instance->DR; //nn=0; break; case 3: cc=ADC1_Handler.Instance->DR; nn=0; break; } }
|