文档RM0091(DocID018940 Rev 6 官方最新的)里面只告诉了我们开启ADC模块的方法。如果按照文档来,里面的示例代码是错误的。如果按照代码来,那文档文档是错误的。 RM0091 page 925 的示例代码 ADC Calibration code example /* (1) Ensure that ADEN = 0 */ /* (2) Clear ADEN */ /* (3) Launch the calibration by setting ADCAL */ /* (4) Wait until ADCAL=0 */ if ((ADC1->CR & ADC_CR_ADEN) != 0) /* (1) */ { ADC1->CR &= ( uint32_t)(~ADC_CR_ADEN); /* (2) */ } ADC1->CR |= ADC_CR_ADCAL; /* (3) */ while ((ADC1->CR & ADC_CR_ADCAL) != 0) /* (4) */ { /* For robust implementation, add here time-out management */ } RM0091 page 214的原话: The calibration is initiated by software by setting bit ADCAL=1. Calibration can only be initiated when the ADC is disabled (when ADEN=0). ADCAL bit stays at 1 during all the calibration sequence. It is then cleared by hardware as soon the calibration completes. After this, the calibration factor can be read from the ADC_DR register (from bits 6 to 0) 这个IF语句我的理解是 if ((ADC1->CR & ADC_CR_ADEN) != 0) /* (1) */ { ADC1->CR &= ( uint32_t)(~ADC_CR_ADEN); /* (2) */ } 如果ADC模块ENABLE了,就DISABLE.我只能这样理解,我看不出来还能有其他的任何意思,好的这样问题就来了。 RM0091 PAGE 238: ADC control register (ADC_CR) 寄存器里的所有的位域都是rs属性,rs是什么意思呢,在文档的page 41 :read/set (rs) Software can read as well as set this bit. Writing ‘0’ has no effect on the bit value. 中文意思是,软件能够读和置位这个BIT,写0是无效的。 文档和里面的代码完全是矛盾的,一开始我还真信了 ADC1->CR &= ( uint32_t)(~ADC_CR_ADEN); /* (2) */这个能够DISABLE ADC module. 各种不正常,最后跟踪调试,发现有时要不在ADC校正的时候的时候卡死,要不就是在DMA方式转换等待结果的时候卡死,但是总之不正常。 一个官方的文档,里面的漏洞百出,你让我们怎么用呀,还让不让人愉快的写代码呀。 求ST的权威人士出来解释一下。 |
【STM32F0开发日志/评测/笔记】+互补PWM波的产生
STM32F030 PB14和PB15无法输出PWM求助
【STM32F030探索套件】序列之五 外部中断
【STM32F0开发日志---二】+ucosii.2.92移植在STM32F030
上传个STM32F0+5110+内部温度传感器的菜鸟实例
【STM32F030探索套件使用问题】STM32F030 SPI方式驱动ST7565LCD失败
求一份STM32F051 I2C驱动LCD 12864的例程
STM32F0 M0 向结构体赋值进入HardFault异常
STM32F0 ADC-DMA方式采集2路数据时出现问题
STM32F030C8T6,TIM16定时慢很多问题?
于是,例程的写法就不对劲了。因为赋“1”没有意义。而且还有可能导致异常的发生。
看来楼主只能自己做测试了。
找找还有没有别的使能位,例如关断时钟之类的。
楼主可有其他不同的见解?
我明白你说的意思,我的ADC在进入stop mode的时候需要关掉的,按照文档里面的代码关不掉(ADC1->CR &= ( uint32_t)(~ADC_CR_ADEN); /* (2) */) ,只能在RCC里面RESET ADC的clock才行。就是由于关不掉,所以每次从stop mode wake up后,ADC校正都会出问题
因为reset操作需要先enbale再disbale;不然寄存器的值不会被更新,一直被锁存在历史的值。
/* 关掉ADC */
while(ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN) == RESET);
ADC_Cmd(ADC1, DISABLE);