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

关于stm32f302的进入睡眠和唤醒模

[复制链接]
alisa123 提问时间:2015-8-10 17:58 /
我想通过检测AD采样的电压低于U1的时候进入睡眠,当高于U2的时候唤醒,求高手指点,谢谢!
收藏 评论18 发布时间:2015-8-10 17:58

举报

18个回答
你好我好大家好! 回答时间:2015-8-10 18:38:06
帮顶            
茅坑的石头 回答时间:2015-8-11 10:07:17
以下是功能实现其中的DMA中断服务函数,你先自己参考参考吧,我最近忙
void DMA1_Channel1_IRQHandler(void)
{
    float Voltage    = 0;                        //电压变量
    float Thermistor = 0;                        //热敏电阻阻值变量
    int   Temp       = 0;                        //热敏电阻测出的温度变量
        
    if(DMA_GetITStatus(DMA1_IT_TC1))
    {   
        //电压采样处理
        Voltage  = g_ADCConvertedValue[2]*3.3/4096;         
        
        #if DEBUG
        /*if(++g_Printf_Count > 300)
        {
            g_Printf_Count = 0;
            printf("Voltage = %f\n", Voltage);
        }*/
        #endif   
        
        Voltage *= VOLTAGE_FACTOR;
        Voltage += 0.35;
        if(Voltage < voltage_sill)                //电压值低于阀值
        {
            if(++g_VoltageLow_Count > 10 )         
            {
                g_VoltageLow_Count = 0;
                g_VoltageLow_Flag  = 1;          //设置电压过低的标志
                g_VoltageLow_Flag_backup = 1;    //设置电压过低标志的备份            
            }
            g_VoltRecovery_Count = 0;
        }
        else if(Voltage > voltage_sill + 0.5)
        {                     
            if(g_VoltageLow_Flag_backup)         //电压过低标志的备份置1表示电压曾经过低,现在表示电压恢复
            {
                if(++g_VoltRecovery_Count > 10 )
                {
                    g_VoltRecovery_Count = 0;
                    g_VoltageLow_Flag_backup = 0;
                    g_VoltageLow_Flag = 2;
                }                    
            }
            else
            {
                g_VoltRecovery_Count = 0;
            }
            
            g_VoltageLow_Count = 0;
        }
        else
        {
            g_VoltRecovery_Count = 0;
            g_VoltageLow_Count   = 0;
        }

        //热敏电阻采样处理,根据计算公式可得Rt = R1*U0/(2*U1-U0),
        //或者Rt = R1*U0/(Vcc-U0)     
        if(2*g_ADCConvertedValue[1] > g_ADCConvertedValue[0])
        {            
            Thermistor = (float)(10.0*g_ADCConvertedValue[0]/(2*g_ADCConvertedValue[1]-g_ADCConvertedValue[0]));
            Temp = ThermalLookUp(Thermistor);        //从热敏电阻阻值查表得到相应温度

            if(Temp < HEAT_TEMPERATURE2)             //低于二级温度阀值
            {
                if(++g_ThermalCount > 200)           //当时间超过2秒时,应该设置加热标志
                {
                    g_ThermalCount = 0;
                    g_ThermalHeat_Flag = 2;
                }            
            }
            else if(Temp < HEAT_TEMPERATURE1)
            {
                if(++g_ThermalCount > 200)
                {
                    g_ThermalCount = 0;
                    g_ThermalHeat_Flag = 1;
                }
            }
            else
            {
                g_ThermalCount = 0;
                g_ThermalHeat_Flag = 0;
            }
               
            #if DEBUG
            //if(++g_Printf_Count > 200)
            //{        
            //    g_Printf_Count = 0;            
            //    printf("Vol0 = %f,Vol1 = %f\n",g_ADCConvertedValue[0]*3.3/4096,g_ADCConvertedValue[1]*3.3/4096);
            //    printf("Thermistor  = %f\n", Thermistor);
            //    printf("Temperature = %d\n", Temp);
            //}
            #endif   
        }
        else
        {
            g_ThermalCount = 0;
            g_ThermalHeat_Flag = 0;
        }
        
        DMA_ClearITPendingBit(DMA1_IT_GL1);
    }
}
alisa123 回答时间:2015-8-12 08:53:34
茅坑的石头 发表于 2015-8-11 10:07
以下是功能实现其中的DMA中断服务函数,你先自己参考参考吧,我最近忙
void DMA1_Channel1_IRQHandler(void ...

我先看看,又不明白的再请教你,谢谢你了!
alisa123 回答时间:2015-8-12 09:01:20
茅坑的石头 发表于 2015-8-11 10:07
以下是功能实现其中的DMA中断服务函数,你先自己参考参考吧,我最近忙
void DMA1_Channel1_IRQHandler(void ...

你的这个里面没有写怎么进入睡眠,还有进入之后怎么唤醒?在DMA中断中检测电压低于阈值多长时间置标志位,高于设定阈值请标志位,但始终没有写怎么进入睡眠。
茅坑的石头 回答时间:2015-8-24 08:59:56
这里只是中断服务函数,中断服务函数里面,仅仅读取电压(DMA会循环把ADC寄存器的数据扫到内存变量里),处理几个全局的标志而已,主程序里面会对这些标志进行判断,然后才进行相应的处理(比如休眠等等);至于多长时间置标志位,这个你可以自行设定,计时我是用的定时器累加实现计时的。差不多低于阀值300ms就会置标志位,然后主程序在循环中发现该标志位,就会进入休眠。至于怎么唤醒,这个也是主程序里实现的。在休眠之前会配置好几个外部中断,只要触发,就会唤醒。
alisa123 回答时间:2015-8-24 11:20:49
茅坑的石头 发表于 2015-8-24 08:59
这里只是中断服务函数,中断服务函数里面,仅仅读取电压(DMA会循环把ADC寄存器的数据扫到内存变量里),处 ...

谢谢你的回复,我明白你的意思,但是我现在的问题是调用进入睡眠的库函数就是进不到睡眠,请问你的主程序中进入睡眠是怎么进去的吗?我的进入睡眠的代码如下:
                RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
                PWR_DeInit();
                PWR_BackupAccessCmd(DISABLE);
                SCB->SCR &= 0xFFFFFFF0;
        //        SCB->SCR &= ~((uint32_t)SCB_SCR_SLEEPDEEP_Msk);
                NVIC_SystemLPConfig(NVIC_LP_SLEEPDEEP,DISABLE);
                NVIC_SystemLPConfig(NVIC_LP_SLEEPONEXIT,DISABLE);
                PWR_EnterSleepMode(PWR_SLEEPEntry_WFE);
        //        __WFE;
不知道那里出问题了,就是进不了睡眠。求帮忙指点,谢谢!
茅坑的石头 回答时间:2015-8-24 13:42:06
stop_mode:
#if DEBUG
                                                printf("S M\n");
#endif

                                                        RTC_Configuration();
                                                        //PWR_BackupAccessCmd(ENABLE);        //使能RTC和后备寄存器访问                                       
                                                        //RTC_ITConfig(RTC_IT_ALR, ENABLE);
                                                        //RTC_WaitForLastTask();                                       
                                                        //RTC_ClearFlag(RTC_FLAG_SEC);
                                                        //while (RTC_GetFlagStatus(RTC_FLAG_SEC) == RESET);
                                                        //RCC_ClearFlag();










                                                //set the all GPIO as general GPIO 、remap IRDA in EXIT0 and disable TIM4 interrupt
                                                lowLevelGPIOCfg();

                                                ADC_Cmd(ADC1, DISABLE);
                                                DMA_Cmd(DMA1_Channel1, DISABLE);
                                                WireControl_EXTI_Enable();

                                                GPIO_ResetBits(Led_Power, Led_Power_Pin);
                                                //GPIO_SetBits(Led_Power, Led_Power_Pin);

                                                BKP_WriteBackupRegister(BKP_DR3, 0xFFFF);  //设置为睡眠状态
                                                #if DEBUG
                                                GPIO_SetBits(GPS_ON,GPS_ON_Pin);
                                                #endif

                                                //Enter a stop mode
                                                //Request to enter STOP mode with regulator in low power mode, wake by any exit interrupt
                                                IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);
                                                IWDG_SetReload(0xffe);
                                                IWDG_ReloadCounter();

                                                GPIO_SetBits(LED_SD1_G, LED_SD1_G_Pin);
                                                GPIO_SetBits(LED_SD2_G, LED_SD2_G_Pin);
                                                GPIO_SetBits(LED_CAM1, LED_CAM1_Pin);
                                                GPIO_SetBits(LED_CAM2, LED_CAM2_Pin);
                                               
                                                mcu_iwdg_flag = 1;
                                                delay_ms(RESET_INTERVAL);

                                            EXTI_ClearITPendingBit(ACC_EXTI_Line |  EXTI_Line0 | EXTI_Line17 | EXTI_Line11);
                                                PWR_EnterSTOPMode(PWR_Regulator_LowPower,
                                                                PWR_STOPEntry_WFI);

                                                GPIO_ResetBits(LED_SD1_G, LED_SD1_G_Pin);
                                                GPIO_ResetBits(LED_SD2_G, LED_SD2_G_Pin);
                                                GPIO_ResetBits(LED_CAM1, LED_CAM1_Pin);
这个是我进入睡眠的代码,
PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI);
这里是进入睡眠的地方,睡眠需要注意的是,睡眠前清理一下中断悬挂
EXTI_ClearITPendingBit(ACC_EXTI_Line |  EXTI_Li.....
,配置好外部中断。
如果睡眠之前有独立看门狗的话,需要另外的处理。
茅坑的石头 回答时间:2015-8-24 13:43:21
睡眠之前有一些其他的操作,主要是关闭一些外设,这个是出于睡眠功耗的考虑。你根据你的外设情况自己定。
茅坑的石头 回答时间:2015-8-24 13:48:14
其实建议你单独,做一个小程序,仅仅做一个进入休眠的小程序,自己测试一下。排除其他因素的干扰,你看能不能行。
12下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版