本帖最后由 济颠进京 于 2018-9-28 16:45 编辑
如题,小弟现在用STM32F4的定时器2作为片内内置ADC1的外部触发,采集两路电压(PA5和PA6作为模拟输入),采用1uS定时触发ADC1通道5、通道6, 不连续采样模式。(网上的例程里大都是定时器某个通道配置成 输出PWM 作为触发信号,但我选择的是定时器 更新事件 输出OPM 作为触发)按我的理解,应该是单次采集通道5的电压,双次采集通道6的电压,可是我用调试助手查看结果的时候貌似只是光采集通道5(PA5)的电压,通道6不采集,求助大神帮我看看ADC配置的哪里不对,谢谢。个人觉得可能是哪个寄存器相应的功能设置位没设置或者设置的不对,但是读了好多遍的数据手册和参考了库函数版本的程序,就是找不出来。
PS:如果单独使能PA6通道6,是能采集到电压的。
[mw_shl_code=c,true]//初始化ADC
//以 规则通道 的 不连续 采样模式设置 ADC1_CH5 ADC1_CH6
//以 外部触发->定时器2_TRGO事件 触发ADC采样
void Adc1_Init(void)
{
//先初始化IO口
RCC->APB2ENR|=1<<8; //使能ADC1时钟
RCC->AHB1ENR|=1<<0; //使能PORTA时钟
GPIO_Set(GPIOA,PIN5|PIN6,GPIO_MODE_AIN,0,0,GPIO_PUPD_NONE); // PA5, PA6 模拟输入,不带上下拉电阻
RCC->APB2RSTR|=1<<8; //ADCs复位
RCC->APB2RSTR&=~(1<<8); //复位结束
ADC->CCR|=1<<16; //ADCPRE: ADC时钟 ADCCLK=PCLK2/4=84/4=21Mhz
//ADC挂载到APB2总线上,ADC时钟最好不要超过36Mhz
ADC1->CR1=0; //CR1设置清零
ADC1->CR2=0; //CR2设置清零
ADC1->CR1&=~(3<<24); //RES:12位分辨率模式,(15个时钟周期总转换时间)
ADC1->CR1&=~(7<<13); //DISCNUM:设置不连续采样模式下 每次触发 转换的通道数为1
ADC1->CR1|=1<<11; //DISCEN: 规则通道的不连续采样使能
ADC1->CR2&=~(1<<11); //ALIGN:右对齐
ADC1->CR2|=1<<28; //EXTEN:上升沿触发
ADC1->CR2|=6<<24; //EXTSEL:选择外部触发为定时器2 TRGO事件
ADC1->CR2|=1<<10; //EOCS:设置规则通道 每单次转换完成EoC标志 置位;
ADC1->SQR1|=1<<20; //L:设置规则通道序列总数为2
ADC1->SQR3|=5<<0; //SQ1:设置规则序列第一次转换为通道5
ADC1->SQR3|=6<<5; //SQ2:设置规则序列第二次转换为通道6
//设置通道5 6的采样时间
ADC1->SMPR2=0; //所有通道采样时间清空
ADC1->SMPR2|=7<<(3*5); //SMP5:通道5采样时间:480个周期
ADC1->SMPR2|=7<<(3*6); //SMP6:通道6采样时间:480个周期
ADC1->CR2|=1<<0; //ADON: 开启AD转换器
}
//获得ADC值
//返回值:转换结果
u16 Get_Adc1(void)
{
while(!(ADC1->SR&(1<<1))); //等待转换结束
return ADC1->DR; //返回adc值同时硬件自动清除EoC标志位
}[/mw_shl_code]
PPS:下面是我写的定时器外设的配置函数:
[mw_shl_code=c,true]void TIM2_Init(u16 arr,u16 psc)
{
RCC->APB1ENR|=1<<0; //TIM2时钟使能
TIM2->ARR=arr; //设定计数器自动重装值
TIM2->PSC=psc; //预分频器
TIM2->CR1&=~(1<<7); //ARPE:设置TIM2_ARR寄存器为非缓冲模式
TIM2->CR1&=~(3<<5); //CMS:选择计数模式为边沿模式(center-aligned mode selection)
TIM2->CR1&=~(1<<4); //DIR:选择计数方向为增加方向
TIM2->CR1|=1<<3; //OPM: 选择单脉冲输出模式
TIM2->CR1|=1<<2; //URS: 设置只有计数器溢出才能产生更新
TIM2->CR1&=~(1<<1); //UDIS:使能 更新事件
TIM2->CR2|=(u32)(2<<4); //MMS:定时器2配置为主模式,将 更新事件 作为触发输出
}[/mw_shl_code]
[mw_shl_code=c,true]
这是我的主函数,只是不断的使能定时器
while(1)
{
TIM2->CR1|=1<<0; //CEN:使能定时器2:
//在单脉冲模式中,如果发生更新事件,
//CEN位被硬件自动清零,故需要每次使能。
adcx=Get_Adc1();
voltage_show=(float)adcx*(3.3/4096);
printf("the voltage is %f
",voltage_show);
}[/mw_shl_code]
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
一周热门 更多>