
在使用ADC的时候发现一些疑问,和调试分析分享 1.手册上介绍ADC有个低功耗模式,配置寄存器将AUTOFF=1和WAIT=1,可以让ADC在转换完成后自动关闭,再次触发时会自动开启,可以有效降低功耗。我将这两位功能使能后,发现每次想开启采样,若采用LL库函数LL_ADC_Enable()将ADEN位置1后,是无法等到ADRDY位被置1的,也就是ADRDY始终是0,但是如果不给ADEN置1,直接用LL_ADC_REG_StartConversion()函数给ADSTART位置1,让ADC开始转换,也是可以正常开始的,读到的ADC结果也正常。想问一下这是不是就是AUTOFF和WAIT产生的效果,那么在使用中,只要使能这两位,每次开启ADC采样的时候,直接使能开始ADSTART=1就可以了,不用再让ADEN=1,这样对吗? 2.结合第1个问题,我使用的cubeMX的LL库生成的ADC初始化函数,其中将AUTOFF=1,WAIT=1,上电后,运行完该初始化函数后,使用了校准功能,调用了LL_ADC_StartCalibration(ADC1)进行校准,调试发现,执行完该校准,再延时几个时钟周期后,ADC好像就已经可以正常工作,也是没有ADEN=1的情况下,直接让ADSTART=1,ADC就可以采集到正确数据了。我看到手册中有这样一个描述:启动校准(将ADCAL置1)时,或者使能ADC时(将ADEN置1),ADVREGEN位通过硬件被置1。也就是说执行了校准操作后ADC的调压器被使能了,且又被配置成了AUTOFF=1和WAIT=1的模式,那么在调压器使能的状态下,只要执行ADSTART=1就可以正常开始转换了。再结合其他讨论中有人说到如果要在系统进入低功耗模式前将ADC的调压器失能ADVREGEN=0才可以,据此推断,如果系统唤醒后想让ADC恢复正常工作,必须再执行一次校准操作或者执行一次ADEN=1的操作才可以。我在调试中在进入芯片的STOP模式前执行了CLEAR_BIT(ADC1->CR, ADC_CR_ADVREGEN)禁止调压器,在退出STOP模式后,再执行了一次LL_ADC_StartCalibration(ADC1)的校准操作,ADC都可以恢复正常采集数据。请教一下我的上述操作是否正确可靠? 3.虽然手册中介绍说AUTOFF和WAIT使能后ADC可以在采集后自动关闭,但我想尽快降低功耗,所以每次读取到序列最后一个数据后,都再执行一次ADSTP=1和ADDIS=1的操作。我的设计采用的是定时器中断里进行一次ADC采样的方式,每次中断里采样完毕还必执行一次LL_ADC_REG_StopConversion(ADC1)让ADSTP=1使ADC停止,然后再必执行一次LL_ADC_Disable(ADC1)让ADDIS=1使ADC关闭,而下次中断进入时,也是不执行ADEN=1,直接让ADSTART=1,等待ADC获得正确的采样值。。当前调试使用这种方式都是可以获得正确的采样数据的。但拿不准是否会有隐患。请问我这样使用是否规范可靠? |
STM32F373 SDAC1+DMA,数据只能更新一次?
关于stm32g030f6p6 adc3个值问题 temp vrefint vbat
STM32 双ADC同步注入转换模式,模块ADC2没有数据。
STM32G0B1adc+dma采样数据错位
STM32H743+USB3300传输采集的数据前几次会丢包问题
H750/743 VREFBUF配置问题
stmL5系列,HAL库如何设置Lpuart APB clock domain
为什么STM32L496RG第一次烧写程序后需要重新上下电才能正常执行程序?
关于STM32F4的ADC测量不准确
与HAL_ADC_Start_DMA相关的一个十分怪异的问题
1、手册上介绍ADC有个低功耗模式,配置寄存器将AUTOFF=1和WAIT=1,可以让ADC在转换完成后自动关闭,再次触发时会自动开启,可以有效降低功耗。我将这两位功能使能后,发现每次想开启采样,若采用LL库函数LL_ADC_Enable()将ADEN位置1后,是无法等到ADRDY位被置1的,也就是ADRDY始终是0,但是如果不给ADEN置1,直接用LL_ADC_REG_StartConversion()函数给ADSTART位置1,让ADC开始转换,也是可以正常开始的,读到的ADC结果也正常。想问一下这是不是就是AUTOFF和WAIT产生的效果,那么在使用中,只要使能这两位,每次开启ADC采样的时候,直接使能开始ADSTART=1就可以了,不用再让ADEN=1,这样对吗?
===》这样没有什么问题,你的ADSART指令即可开启ADC转换,当然硬件会自动插入启动稳定时间,达到ADEN=1,ADRDY=1的效果。在AUTOFF=1和WAIT=1的情况下,软件启动或硬件触发或对ADC_DR的访问都可以启动ADC转换。
2、结合第1个问题,我使用的cubeMX的LL库生成的ADC初始化函数,其中将AUTOFF=1,WAIT=1,上电后,运行完该初始化函数后,使用了校准功能,调用了LL_ADC_StartCalibration(ADC1)进行校准,调试发现,执行完该校准,再延时几个时钟周期后,ADC好像就已经可以正常工作,也是没有ADEN=1的情况下,直接让ADSTART=1,ADC就可以采集到正确数据了。
===》这个其实跟第一个问题是一样的。尽管校准后理应进入ADC的power off状态,但ADSTART=1还是可以开启ADC转换。这里顺便说下,当我们将ADC配置在AUTOFF状态时,硬件会无视ADRDY标志的,而且会始终保持0状态,也就是上面你提到过的它始终为0的情形.
3、我看到手册中有这样一个描述:启动校准(将ADCAL置1)时,或者使能ADC时(将ADEN置1),ADVREGEN位通过硬件被置1。也就是说执行了校准操作后ADC的调压器被使能了,且又被配置成了AUTOFF=1和WAIT=1的模式,那么在调压器使能的状态下,只要执行ADSTART=1就可以正常开始转换了。再结合其他讨论中有人说到如果要在系统进入低功耗模式前将ADC的调压器失能ADVREGEN=0才可以,据此推断,如果系统唤醒后想让ADC恢复正常工作,必须再执行一次校准操作或者执行一次ADEN=1的操作才可以。我在调试中在进入芯片的STOP模式前执行了CLEAR_BIT(ADC1->CR, ADC_CR_ADVREGEN)禁止调压器,在退出STOP模式后,再执行了一次LL_ADC_StartCalibration(ADC1)的校准操作,ADC都可以恢复正常采集数据。请教一下我的上述操作是否正确可靠?
===》没有什么不可靠。首先,即使你关闭了ADC voltage regulator,当我们进行ADC校准时硬件会自动开启之。校准后即可直接使用ADSTART=1来开启ADC转换,当然此时还是基于你说到的AUTOFF=1模式。
4、虽然手册中介绍说AUTOFF和WAIT使能后ADC可以在采集后自动关闭,但我想尽快降低功耗,所以每次读取到序列最后一个数据后,都再执行一次ADSTP=1和ADDIS=1的操作。我的设计采用的是定时器中断里进行一次ADC采样的方式,每次中断里采样完毕还必执行一次LL_ADC_REG_StopConversion(ADC1)让ADSTP=1使ADC停止,然后再必执行一次LL_ADC_Disable(ADC1)让ADDIS=1使ADC关闭,而下次中断进入时,也是不执行ADEN=1,直接让ADSTART=1,等待ADC获得正确的采样值。
===》你的这些操作没有啥问题,也没看出有啥隐患。你没必要自己手动执行ADSTP=1和ADDIS=1操作了,硬件会自动完成。
楼主需要进一步进入低功耗模式,由于主电源调节器进入了低功耗模式,所以ADC的电压调节器也就不能工作了。
对于进出低功耗的操作手册上有一个顺序介绍,楼主按照这个顺序操作就可以了,附图就是这个顺序截图。
感谢您的回复。这篇文章中提到的退出STOP模式时,如果采用的是快速唤醒不考虑vrefint的时间有可能影响到ADC。我在使用时确实也是用的快速唤醒,我有两种进入STOP的情况,一种是准备长时间停留在STOP中,只有外部按键产生的中断才能唤醒,在这种模式下,进入STOP前使用CLEAR_BIT(ADC1->CR, ADC_CR_ADVREGEN)禁止的是ADC的调压器,退出STOP后一定使用校准操作再次启用ADC的调压器,并且也会等待几个时钟周期后再开启ADC功能,所以应该有足够的时间让ADC恢复正常。第二种情况是,设备正常工作期间,用定时器LPTIM定时去ADC采样,依靠每次定时器的中断唤醒STOP,这种情况下进入STOP前也是设置成快速唤醒,HSI保持工作,但不会将ADC的调压器禁止,LPTIM中断唤醒STOP后,在该中断回调函数中使能ADCSTART=1等待获得转换结果再退出中断回调函数。这第二种情况我这样使用是否有什么隐患吗?
很感谢您的回复,很有帮助。又去看了手册确实如您所说。但又增加了新的疑问:
1.在我的第一种应用场景中,需要长时间停留在STOP里时,进入STOP前确实按照手册介绍的那个顺序执行的,但是在退出STOP时,并没有作循环等待REGLPF=0的操作,因为在看HAL库和LL库的例程里并没有看到等待这个标志位的操作所以忽略了,请问REGLPF位恢复为0大概需要多少时间?我用外部中断退出STOP时,中断回调函数入口的大概有4-5条语句执行后(系统时钟16MHz),这个时长是否足够保证REGLPF位恢复为0呢?也就是利用执行语句的延时是否可以保证后面的程序运行可靠呢?
2.在我的第二种低功耗应用场景中,需要用LPTIM定时唤醒STOP,LPTIM的定时中断周期大约为4ms,在该中断中执行ADC采样操作,读取采样数据后就执行停止转换ADSTP=1,并将ADEN清0使ADC关闭(虽然我配置AUTOFF=1,但也执行了这个关闭动作),但不执行关闭ADC的调压器的操作,退出中断后回到主循环,然后进入STOP等待下一个定时中断的到来。主要是不想在反复开关ADC调压器上占用过多的等待时间,所以始终没执行ADVREGEN清0的操作。请问我这种不关闭ADC调压器就进入STOP的操作方式可靠吗?
很感谢您的回复,很有帮助。又去看了手册确实如您所说。但又增加了新的疑问: 1.在我的第一种应用场景中,需要长时间停留在STOP里时,进入STOP前确实按照手册介绍的那个顺序执行的,但是在退出STOP时,并没有作循环等待REGLPF=0的操作,因为在看HAL库和LL库的例程里并没有看到等待这个标志位的操作所以忽略了,请问REGLPF位恢复为0大概需要多少时间?我用外部中断退出STOP时,中断回调函数入口的大概有4-5条语句执行后(系统时钟16MHz),这个时长是否足够保证REGLPF位恢复为0呢?也就是利用执行语句的延时是否可以保证后面的程序运行可靠呢? 2.在我的第二种低功耗应用场景中,需要用LPTIM定时唤醒STOP,LPTIM的定时中断周期大约为4ms,在该中断中执行ADC采样操作,读取采样数据后就执行停止转换ADSTP=1,并将ADEN清0使ADC关闭(虽然我配置AUTOFF=1,但也执行了这个关闭动作),但不执行关闭ADC的调压器的操作,退出中断后回到主循环,然后进入STOP等待下一个定时中断的到来。主要是不想在反复开关ADC调压器上占用过多的等待时间,所以始终没执行ADVREGEN清0的操作。请问我这种不关闭ADC调压器就进入STOP的操作方式可靠吗?
很感谢您的回复,很有帮助。又去看了手册确实如您所说。但又增加了新的疑问: 1.在我的第一种应用场景中,需要长时间停留在STOP里时,进入STOP前确实按照手册介绍的那个顺序执行的,但是在退出STOP时,并没有作循环等待REGLPF=0的操作,因为在看HAL库和LL库的例程里并没有看到等待这个标志位的操作所以忽略了,请问REGLPF位恢复为0大概需要多少时间?我用外部中断退出STOP时,中断回调函数入口的大概有4-5条语句执行后(系统时钟16MHz),这个时长是否足够保证REGLPF位恢复为0呢?也就是利用执行语句的延时是否可以保证后面的程序运行可靠呢? 2.在我的第二种低功耗应用场景中,需要用LPTIM定时唤醒STOP,LPTIM的定时中断周期大约为4ms,在该中断中执行ADC采样操作,读取采样数据后就执行停止转换ADSTP=1,并将ADEN清0使ADC关闭(虽然我配置AUTOFF=1,但也执行了这个关闭动作),但不执行关闭ADC的调压器的操作,退出中断后回到主循环,然后进入STOP等待下一个定时中断的到来。主要是不想在反复开关ADC调压器上占用过多的等待时间,所以始终没执行ADVREGEN清0的操作。请问我这种不关闭ADC调压器就进入STOP的操作方式可靠吗?
很感谢您的回复,很有帮助。又去看了手册确实如您所说。但又增加了新的疑问: 1.在我的第一种应用场景中,需要长时间停留在STOP里时,进入STOP前确实按照手册介绍的那个顺序执行的,但是在退出STOP时,并没有作循环等待REGLPF=0的操作,因为在看HAL库和LL库的例程里并没有看到等待这个标志位的操作所以忽略了,请问REGLPF位恢复为0大概需要多少时间?我用外部中断退出STOP时,中断回调函数入口的大概有4-5条语句执行后(系统时钟16MHz),这个时长是否足够保证REGLPF位恢复为0呢?也就是利用执行语句的延时是否可以保证后面的程序运行可靠呢? 2.在我的第二种低功耗应用场景中,需要用LPTIM定时唤醒STOP,LPTIM的定时中断周期大约为4ms,在该中断中执行ADC采样操作,读取采样数据后就执行停止转换ADSTP=1,并将ADEN清0使ADC关闭(虽然我配置AUTOFF=1,但也执行了这个关闭动作),但不执行关闭ADC调压器的操作,退出中断后回到主循环,然后进入STOP等待下一个定时中断的到来。主要是不想在反复开关ADC调压器上占用过多的等待时间,所以始终没执行ADVREGEN清0的操作。请问我这种不关闭ADC调压器就进入STOP的操作方式可靠吗?
很感谢您的回复,很有帮助。又去看了手册确实如您所说。但又增加了新的疑问:
1.在我的第一种应用场景中,需要长时间停留在STOP里时,进入STOP前确实按照手册介绍的那个顺序执行的,但是在退出STOP时,并没有作循环等待REGLPF=0的操作,因为在看HAL库和LL库的例程里并没有看到等待这个标志位的操作所以忽略了,请问REGLPF位恢复为0大概需要多少时间?我用外部中断退出STOP时,中断回调函数入口的大概有4-5条语句执行后(系统时钟16MHz),这个时长是否足够保证REGLPF位恢复为0呢?也就是利用执行语句的延时是否可以保证后面的程序运行可靠呢?
2.在我的第二种低功耗应用场景中,需要用LPTIM定时唤醒STOP,LPTIM的定时中断周期大约为4ms,在该中断中执行ADC采样操作,读取采样数据后就执行停止转换ADSTP=1,并将ADEN清0使ADC关闭(虽然我配置AUTOFF=1,但也执行了这个关闭动作),但不执行关闭ADC调压器的操作,退出中断后回到主循环,然后进入STOP等待下一个定时中断的到来。外部中断唤醒STOP后,也不执行开启ADC的调压器操作。主要是不想在反复开关ADC调压器上占用过多的等待时间,所以始终没执行ADVREGEN清0的操作。请问我这种不关闭ADC调压器就进入STOP的操作方式可靠吗?
很感谢您的回复
很有帮助。又去看了手册确实如您所说。但又增加了新的疑问
1.在我的第一种应用场景中,需要长时间停留在STOP里时,进入STOP前确实按照手册介绍的那个顺序执行的,但是在退出STOP时,并没有作循环等待REGLPF=0的操作,因为在看HAL库和LL库的例程里并没有看到等待这个标志位的操作所以忽略了,请问REGLPF位恢复为0大概需要多少时间?我用外部中断退出STOP时,中断回调函数入口的大概有4-5条语句执行后(系统时钟16MHz),这个时长是否足够保证REGLPF位恢复为0呢?也就是利用执行语句的延时是否可以保证后面的程序运行可靠呢? 2.在我的第二种低功耗应用场景中,需要用LPTIM定时唤醒STOP,LPTIM的定时中断周期大约为4ms,在该中断中执行ADC采样操作,读取采样数据后就执行停止转换ADSTP=1,并将ADEN清0使ADC关闭(虽然我配置AUTOFF=1,但也执行了这个关闭动作),但不执行关闭ADC调压器的操作,退出中断后回到主循环,然后进入STOP等待下一个定时中断的到来。外部中断唤醒STOP后,也不执行开启ADC的调压器操作。主要是不想在反复开关ADC调压器上占用过多的等待时间,所以始终没执行ADVREGEN清0的操作。请问我这种不关闭ADC调压器就进入STOP的操作方式可靠吗?
1.在我的第一种应用场景中,需要长时间停留在STOP里时,进入STOP前确实按照手册介绍的那个顺序执行的,但是在退出STOP时,并没有作循环等待REGLPF=0的操作,因为在看HAL库和LL库的例程里并没有看到等待这个标志位的操作所以忽略了,请问REGLPF位恢复为0大概需要多少时间?我用外部中断退出STOP时,中断回调函数入口的大概有4-5条语句执行后(系统时钟16MHz),这个时长是否足够保证REGLPF位恢复为0呢?也就是利用执行语句的延时是否可以保证后面的程序运行可靠呢?
1.在我的第一种应用场景中,需要长时间停留在STOP里时,进入STOP前确实按照手册介绍的那个顺序执行的,但是在退出STOP时,并没有作循环等待REGLPF=0的操作,因为在看HAL库和LL库的例程里并没有看到等待这个标志位的操作所以忽略了,请问REGLPF位恢复为0大概需要多少时间?我用外部中断退出STOP时,中断回调函数入口的大概有4-5条语句执行后(系统时钟16MHz),这个时长是否足够保证REGLPF位恢复为0呢?也就是利用执行语句的延时是否可以保证后面的程序运行可靠呢? 2.在我的第二种低功耗应用场景中,需要用LPTIM定时唤醒STOP,LPTIM的定时中断周期大约为4ms,在该中断中执行ADC采样操作,读取采样数据后就执行停止转换ADSTP=1,并将ADEN清0使ADC关闭(虽然我配置AUTOFF=1,但也执行了这个关闭动作),但不执行关闭ADC调压器的操作,退出中断后回到主循环,然后进入STOP等待下一个定时中断的到来。外部中断唤醒STOP后,也不执行开启ADC的调压器操作。主要是不想在反复开关ADC调压器上占用过多的等待时间,所以始终没执行ADVREGEN清0的操作。请问我这种不关闭ADC调压器就进入STOP的操作方式可靠吗?
1.在我的第一种应用场景中,需要长时间停留在STOP里时,进入STOP前确实按照手册介绍的那个顺序执行的,但是在退出STOP时,并没有作循环等待REGLPF=0的操作,因为在看HAL库和LL库的例程里并没有看到等待这个标志位的操作所以忽略了,请问REGLPF位恢复为0大概需要多少时间?我用外部中断退出STOP时,中断回调函数入口的大概有4-5条语句执行后(系统时钟16MHz),这个时长是否足够保证REGLPF位恢复为0呢?也就是利用执行语句的延时是否可以保证后面的程序运行可靠呢?