你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

stm32 ADC定时唤醒采集数据,工作一段时间adc值不变了

[复制链接]
baosong123 提问时间:2018-8-18 16:13 /
阅读主题, 点击返回1楼
收藏 评论18 发布时间:2018-8-18 16:13
18个回答
jiekechoo 回答时间:2018-8-29 17:32:08
butterflyspring 发表于 2018-8-29 11:47
STOP mode唤醒之后就是MSI作为系统时钟,如果你之前不是用MSI,你不需要重新配置?

官方的例程里早就写明了需要重新配置时钟的,而且,必须要跟你启动时的时钟一样才有意义。

现在问题好像不是时钟问题,是ADC读取的问题了。唤醒后,读取ADC是失败的。

baosong123 回答时间:2018-9-1 11:24:31
butterflyspring 发表于 2018-8-29 11:47
STOP mode唤醒之后就是MSI作为系统时钟,如果你之前不是用MSI,你不需要重新配置?

我现在可以确定,确实是因为添加了stop模式之后出的问题,如果屏蔽掉stop模式 就没问题,每次需要复位adc才恢复正常,然后又运行一段时间又出问题
void work_200ms(void)
{
         RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);   //打开复用功能和adc时钟       

                                        if(Press_set==0)//如果处于暂停状态进入停机
                                                {
                                                        TIM_SetAutoreload(TIM1,100);//改频率
                                                        TIM_SetCompare4(TIM1,0);//改占空比
                                       
                                                        Ledless_L;       
                                                        warn_voice(off,100,500);//关闭漏气报警
                                                        warn_time=0;       
                                                  stop_mode();     
                                                }       
       
               
                               
        if(Press_set==125&&time2_flag==1&&press_end==1)//如果处于工作状态并且 达到200ms定时,并且 压力达到设定值进入停机
        {                                TIM_Cmd(TIM2, DISABLE); //关闭计时                                       
                                        time2_flag=0;
                                        work_time=0;
                                        debug_string("Press_adc:");                       
                                        debug_16bit_assic(Press_adc);
                                        debug_string("Vbat_adc:");                       
                                        debug_16bit_assic(Vbat_adc);
                //debug_string("Vref_adc:");                       
                        //                debug_16bit_assic(Vref_adc);                       
               
//200ms工作完成,清除ad数据,下次唤醒重新采集
                                        ready_num=0;
                                //adc_num=0;
                                //Adc_ready=0;
                                //清场完毕,打开rtc时钟,进入睡眠
                if(Stop_flag==0)
                {
                                        RTC_init();                //配置rtc
                                        RTC_EXTI_INITIAL(ENABLE);//打开闹钟中断
                                        Stop_flag=1;
                           stop_mode();
                }
        }

                Ledrun_L;


}
baosong123 回答时间:2018-9-3 13:52:04
我有在唤醒后重新配置了时钟,唤醒后第一时间配置的时钟,和开机复位刚运行是同一个时钟函数
void clk_init(void)
{   ErrorStatus HSEStartUpStatus;
    RCC_DeInit();                 //RCC寄存器设置为默认值
    RCC_HSEConfig(RCC_HSE_ON);        //打开高速外部时钟

    HSEStartUpStatus=RCC_WaitForHSEStartUp ();         //等待时钟起振
    if(HSEStartUpStatus == SUCCESS)
    {
        RCC_HCLKConfig(RCC_SYSCLK_Div1);                 //AHB 时钟为系统时钟
        RCC_PCLK2Config(RCC_HCLK_Div1);           //高速AHB总线时钟为系统时钟
        RCC_PCLK1Config(RCC_HCLK_Div2);                        //低速AHB总线为1/2系统时钟
        FLASH_SetLatency(FLASH_Latency_2);
        FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//预取指缓存使能

        RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_9);        //设置PLL输入时钟分频和PLL 倍频系数
        RCC_PLLCmd(ENABLE);
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);


        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);   //设置pll输出时钟为系统时钟
        while(RCC_GetSYSCLKSource()!=0x08);
    }

                 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);   //打开复用功能和adc时钟                                  
   
}
baosong123 回答时间:2018-9-3 13:53:51
void out_stop(void)
{
        clk_init();
        USART_Cmd(USART1, ENABLE);
        work_time=0;
        time2_flag=0;
        debug_string("wake\n");        

}

void stop_mode(void)
{
        

debug_string("in stop\n");        

USART_Cmd(USART1, DISABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
//PWR_EnterSTOPMode(PWR_Regulator_LowPower,PWR_STOPEntry_WFI);


}
这是进入和退出停机模式的函数,请高手指教,停机模式里我屏蔽掉pwr那条指令,程序运行就不会出问题,加上这个过段时间就adc数据就保持不变了
baosong123 回答时间:2018-9-8 09:31:52
程序重新规划,只写了一个最简单定时一秒进入闹钟,唤醒 后立即停机
                RTC_init();//闹钟初始化
       
                while(1)
                                {
                                       
                                stop_mode();       
                                        if(Stop_flag==0)       
                                        {
                                        debug_16bit_assic(sleep_num);       
                                  debug_16bit_assic(ADC_ConvertedValue[0]);       
                                        }
                                       
       
                               


                                }

adc的死机问题也是存在
baosong123 回答时间:2018-9-8 09:32:46
有兴趣的朋友希望自己试验一下,谢谢大家
wsofter 回答时间:2020-7-15 20:25:13
请问这个问题怎么解决的,我也是低功耗唤醒后ADC出错
baosong123 回答时间:2020-9-18 21:08:35
自己回复下解决方案吧,就是每次唤醒之后要对adc重新初始化,否则adc死机问题还是存在,但是又会带来一个新的问题,刚初始化后数值稳定性会差些
butterflyspring 回答时间:2020-9-28 16:57:35
在进入低功耗前,也需要对ADC模块进行相应的关闭,好像没找到相关部分。建议增加相关部分。
12

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版