[STM32F1] 中断方式实现ADC的多通道

[复制链接]
2275|13
 楼主| zhuhuis 发表于 2018-11-27 19:19 | 显示全部楼层 |阅读模式
最近在学习stm32f103rbt6。发现网上都是用DMA实现ADC的多通道、连续转换。 我想用中断实现ADC的多通道、单次转换。在中断函数里读取每次转换的结果,但是,用我下面的代码,只能实现读出一个通道的转换结果。
 楼主| zhuhuis 发表于 2018-11-27 19:19 | 显示全部楼层

void ADC_init(void)
{
           ADC_InitTypeDef ADC_InitStructure;
           ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;         
           ADC_InitStructure.ADC_ScanConvMode = ENABLE;
           ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;   // 单次转换
           ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
           ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
           ADC_InitStructure.ADC_NbrOfChannel = 2;
           ADC_Init(ADC1, &ADC_InitStructure);
           ADC_RegularChannelConfig(ADC1, ADC_Channel_16, 2, ADC_SampleTime_239Cycles5);
           ADC_RegularChannelConfig(ADC1, ADC_Channel_17, 1, ADC_SampleTime_239Cycles5);           

           ADC_TempSensorVrefintCmd(ENABLE);
           ADC_Cmd(ADC1, ENABLE);
           ADC_ResetCalibration(ADC1);
           while(ADC_GetResetCalibrationStatus(ADC1));
           ADC_StartCalibration(ADC1);//开始校准  
           while(ADC_GetCalibrationStatus(ADC1));//等待校准完成
           ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);
}

u16 Get_ADC(void)
{
        unsigned int i;
        u16 temper=0,temp=0;
        temp=ADC_GetConversionValue(ADC1);
        temper +=temp;
        Delay(0xfff);
        return temper;
}

void ADC1_2_IRQHandler(void)
{
ADC_Temp=Get_ADC();  //ADC_Temp 和 Vsense 是全局变量
  printf("  %d",ADC_Temp);
        Vsense=(ADC_Temp*3.3)/4096;

        printf("the temperature now is : %.2f\n",Vsense);
ADC_ClearITPendingBit(ADC1, ADC_IT_EOC);

}
pangb 发表于 2018-11-27 19:20 | 显示全部楼层
u16 Get_ADC(void)
{
        unsigned int i;
        u16 temper=0,temp=0;
        temp=ADC_GetConversionValue(ADC1);
        temper +=temp;
        Delay(0xfff);
        return temper;
}
      Delay(0xfff)去掉, printf("the temperature now is : %.2f\n",Vsense);也去掉 ,

ADC_Temp=Get_ADC();  //ADC_Temp 和 Vsense 是全局变量  改成 ADC_Temp[i++]=Get_ADC();  这样再看看
morrisk 发表于 2018-11-27 19:23 | 显示全部楼层

用注入模式
        ADC_InjectedChannelConfig(ADC1, ADC_INJECTED_GROUP1_CHANNEL1, 1, ADC_CHANNEL_SAMPLETIME);
        ADC_InjectedChannelConfig(ADC1, ADC_INJECTED_GROUP1_CHANNEL2, 2, ADC_CHANNEL_SAMPLETIME);

一次四个,结果在寄存器JDR1~4中
kangzj 发表于 2018-11-27 19:25 | 显示全部楼层
关于STM32的AD,如果说我们用的是N个通道的规则采样,并且使能了扫描模式,那么就只能使用DMA。不然读数就存在问题了,(对比单次转换的情况,仅一个通道,那我们可以在AD转换中断EOC里面取读取AD的值)因为AD的EOC中断是在一次转换完成之后才触发的,N个通道转换完。。AD寄存器里面保存的是最后一次转换的结果,这导致了在中断当中没**常读取全部的转换值了
huanghuac 发表于 2018-11-27 19:27 | 显示全部楼层
注入组,4个通道各有一个寄存器,可以将转换的结果保存
tian111 发表于 2018-11-27 19:28 | 显示全部楼层
dma的触发条件和通道的转换是两个问题,自动切换通道的方式有两种,规则和注入。
chuxh 发表于 2018-11-27 19:30 | 显示全部楼层
dma的触发只能是一种就是ad转换完成,特别的你可以用扫描模式注入和规则模式里整个序列转换完才算是完成,dma的源地址是可以设置的。注入方式的数据保存地址是连续的。
 楼主| zhuhuis 发表于 2018-11-27 19:32 | 显示全部楼层

其实还是不大明白,我再琢磨琢磨吧,多谢了哈,结贴了先
晓伍 发表于 2018-12-4 10:06 | 显示全部楼层
用规则连续转换
观海 发表于 2018-12-4 12:09 | 显示全部楼层
您想实现多通道单词转换吗
guanjiaer 发表于 2018-12-4 12:36 | 显示全部楼层
那你读取过别的通道的寄存器了吗
tpgf 发表于 2018-12-4 12:43 | 显示全部楼层
例程里边有你这种  可以找找看
heimaojingzhang 发表于 2018-12-4 12:47 | 显示全部楼层
用cube生成吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则

728

主题

8464

帖子

6

粉丝
快速回复 在线客服 返回列表 返回顶部