使用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
目前新项目,MCU采用STM32F407VGT6,文件存在TF卡(SDIO),请问能否通过F4的USB把TF卡里面的txt和excel文件拷贝到U盘?哪个USB可以实现?
STM32F407ZGT6假死现象,看门狗不起作用
STM32F407VGT6使用PLL倍频后芯片会反复重启
CAN接收丢包
使用Cubeprogrammer无法连接、连接G431和一块H750的板子可以连上但是连另外一块H750的板子和F407的板子就直接报错,这个应该如何解决。
SPI 通信,既有单字节数据传输,又有多字节数据传输,该如正确使用 DMA?
SD卡log存储
STM32F413ZGT6的NRST需要接上拉电阻吗
STM32F4的串口在配置DMA之后,不能使用高波特率吗?
劳烦大佬们看一下,为什么我的USART1 这样配置接收不了数据啊
版主,你好。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哪里有特殊要求。