
使用STM32F401RET6芯片,sysem tick产生5ms中断,主程序查询5ms是否有到,到了就做启动一次ad转换(查询方式),下一个5ms去判断转换是否结束(实际转换不需要这么长时间),如果转换结束就读取转换值。再下一个5ms来又启动转换,如此循环。但是现在现象是,进入调试后,可以正常转换几次,转换值也是正确的,紧接着就是不能查询到转换结束标志EOC,但STRT一直为1. 如果改变写法,启动adc后,立即等待adc做完,这样写就正常。 u16 Get_Adc(void) { ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_480Cycles ); ADC_SoftwareStartConv(ADC1); while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC )); return ADC_GetConversionValue(ADC1); } void adc_scan(void) //@5ms { #if 1 // 这样写就正常 res = Get_Adc(); cnt++; return; #else // 这样写就开始正常转换,几次后EOC标志就不会被置位。 if(index == 0) { ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 1, ADC_SampleTime_480Cycles ); ADC_SoftwareStartConv(ADC1); index = 1; } else { if(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ) == SET) { ADC1->SR = ~(uint32_t)ADC_SR_EOC; cnt++; res = (uint16_t)ADC1->DR; index = 0; } } #endif } 哪位有遇到过这种情况吗?为什么不立即去等ADC做完就有问题,还是adc就有这种限制? 附件是整个项目文件。 |
stm32f401ret6_adc_issue.zip
下载475.19 KB, 下载次数: 4, 下载积分: ST金币 -1
STM32多通道FFT运算异常
在其他电脑上编译成功没有错误并且能够烧录,换了电脑之后编译出现一堆错误,并且不能烧录程序
SD卡初始化第一次初始化后再次初始化时会失败。
串口重定向接收不同
关于三轴陀螺仪 I3G4250D
经过光耦之后,脉冲计数功能为啥不能实现?
STM32F407 ADC Dual regular simultaneous only 模式下最高采样率仅 96 kHz,960 kHz 无法工作,求助!
STM32 F407骄阳电机版用DMA双缓存接收串口数据时,上电第一次接收区是memory1而不是memory0?
STM32F407骄阳版用DMA双缓存区接收串口数据,上电第一次接收到的数据在memory1而不是memory0
stm32f407无法配置定时器2为全部dma
版主,你好。adc采集是在主程序里做的,system tick 中断只产生一个5ms标志。帮看看这个时钟配置是否有问题(HCLK=84M, PCLK1=42M, PCLK2=84M),似乎有问题也说不通,因为换一种写法,它确是正常的,不知道真实的问题在哪里。
void adc_initialize(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_CommonInitTypeDef ADC_CommonInitStructure;
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, ENABLE); /* ADC1复位 */
RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1, DISABLE);/* 复位结束 *
ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;/* 独立模式 */
ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;/* 两个采样阶段之间的延迟5个时钟 */
ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; /* DMA失能 */
ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div8;/* 预分频4分频。ADCCLK=84/4=21Mhz,ADC时钟最好不要超过36Mhz */
ADC_CommonInit(&ADC_CommonInitStructure);
ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;/* 12位模式 */
ADC_InitStructure.ADC_ScanConvMode = DISABLE;/* 非扫描模式 */
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;/* 关闭连续转换 */
ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;/* 禁止触发检测,使用软件触发 */
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;/* 右对齐 */
ADC_InitStructure.ADC_NbrOfConversion = 1;/* 1个转换在规则序列中 也就是只转换规则序列1 */
ADC_Init(ADC1, &ADC_InitStructure);/* ADC初始化 */
ADC_Cmd(ADC1, ENABLE);
}
main里的循环:
while(1)
{
if(system_tick != 0)
{
system_tick = 0;
adc_scan();
}
}
wenyangzeng,你好;ad是在主程序里的做的,我的做法是启动ad后,没有立即等它做完,而是下个5ms去判断EOC是否有置位,但几次正常采集后就不正常了,EOC标志不能被置位?!但换一种写法(启动ad后,紧接着就判断EOC标志),这样却正常。
2使用DMA去处理你的ADC转换结果
目前一直等肯定可以,你不等待,就把ADC设置成单次触发,不要设置成连续转换,我觉得这个才是问题所在
两次定时器中断里不见得ADC刚好转换结束,所以还是不要在定时器中断里判断ADC转换是否结束,而是启动ADC转换后就等待结束比较合理。
非常感谢你的建议,单次转换改为中断的方式,可以;
这里还是有疑问,用查询方式,并没设置成连续转换,5ms轮询一次怎么就检测不到EOC标志呢,用其它芯片的adc都可以这样操作。是不是ST哪里有特殊要求。