OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 5276|回复: 8

待机唤醒+定时器中断=长按开关机以及实现开机过久自动关机的功能

[复制链接]

8

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
120
金钱
120
注册时间
2016-9-20
在线时间
26 小时
发表于 2016-10-24 19:20:03 | 显示全部楼层 |阅读模式
10金钱
这几天看了论坛上的好多帖子,基本搞懂了原子的待机唤醒程序,我想在待机唤醒程序的基础上增加一个功能,比如说开机之后10分钟内没有操作,就自动再次进入待机状态。我考虑的是再加一个定时器中断,不知道思路对不对。下面开始贴程序:
void WKUP_Init()
{
        GPIO_InitTypeDef GPIO_InitStruct;
        EXTI_InitTypeDef EXTI0_InitStruct;
        NVIC_InitTypeDef NVIC_InitStruct;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
       
        GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IPD;//下拉输入=上升沿触发;
        GPIO_InitStruct.GPIO_Pin=GPIO_Pin_0;
        GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(GPIOA,&GPIO_InitStruct);
       
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource0);//十分重要的一句!!
       
        EXTI0_InitStruct.EXTI_Line=EXTI_Line0;
        EXTI0_InitStruct.EXTI_LineCmd=ENABLE;
        EXTI0_InitStruct.EXTI_Mode=EXTI_Mode_Interrupt;
        EXTI0_InitStruct.EXTI_Trigger=EXTI_Trigger_Rising;//上升沿触发中断
        EXTI_Init(&EXTI0_InitStruct);
        //设置中断优先级
        NVIC_InitStruct.NVIC_IRQChannel=EXTI0_IRQn;
        NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
        NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=0;
        NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;
        NVIC_Init(&NVIC_InitStruct);
       
        if(WKUP_Scan()==0)
        {
                RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);
          PWR_WakeUpPinCmd(ENABLE);
          PWR_EnterSTANDBYMode();//一开始是待机模式
        }
}
u8 WKUP_Scan()
{
        u8 t;
        LED0=0;
        while(1)
        {
                if(WKUP_Status==1)
                {
                        t++;
                        delay_ms(30);
                  if(t>=100)
                        {
                          LED0=0;//开机灯亮起
                          return 1;
                        }
                }
                else
                {
                LED0=1;
                return 0;//没有按键按下,进入待机模式调到wkup_Init这个函数里面去了       
                }
        }
}

//进入待机模式
void Enter_Standby()
{
        RCC_APB2PeriphResetCmd(0x01fc,DISABLE);//在进入待机模式前先对所有的IO口进行复位操作(RCC_APB2RST寄存器)
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR,ENABLE);//使能PWR的时钟(关机开机都涉及到pwr)
        PWR_WakeUpPinCmd(ENABLE);//使能PWR的引脚唤醒功能
        PWR_EnterSTANDBYMode();
}

//EXTI0中断函数
void EXTI0_IRQHandler()
{
        EXTI_ClearITPendingBit(EXTI_Line0);//清除中断标志位
        if(WKUP_Scan()==1)
                Enter_Standby();//(第二次按下按键之后的中断使得进入待机模式)
}

void WKUP_TIM_Init(u16 arr, u16 psc)
{
        TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;//定时器初始化设置
        NVIC_InitTypeDef NVIC_InitStruct;//定时器中断优先级设置
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE);
       
        TIM_TimeBaseStruct.TIM_ClockDivision=TIM_CKD_DIV1;//不分频
        TIM_TimeBaseStruct.TIM_CounterMode=TIM_CounterMode_Up;
        TIM_TimeBaseStruct.TIM_Period=arr;
        TIM_TimeBaseStruct.TIM_Prescaler=psc;
        TIM_TimeBaseInit(TIM2,&TIM_TimeBaseStruct);
       
        TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);
       
        NVIC_InitStruct.NVIC_IRQChannel=TIM2_IRQn;
        NVIC_InitStruct.NVIC_IRQChannelCmd=ENABLE;
        NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority=1;
        NVIC_InitStruct.NVIC_IRQChannelSubPriority=0;
        NVIC_Init(&NVIC_InitStruct);                                                                  
}

void TIM2_IRQHandler()
{
        if(TIM_GetITStatus(TIM2,TIM_IT_Update)!=RESET)//检查中断是否发生
        {
                TIM_ClearITPendingBit(TIM2,TIM_IT_Update);//发生了中断,先将中断标志位清零
                LED0=1;
                Enter_Standby();//进入待机模式
        }
}


正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

8

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
120
金钱
120
注册时间
2016-9-20
在线时间
26 小时
 楼主| 发表于 2016-10-24 19:20:32 | 显示全部楼层
下面是主程序部分:
int main()
{
        SystemInit();
        delay_init();
        LED_Init();
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
        WKUP_TIM_Init(19999,35999);
        WKUP_Init();
        TIM_Cmd(TIM2,ENABLE);
        //uart_init(115200);
        while(1)
        {                       
                        LED0=!LED0;
                        delay_ms(200);//延时等待中断的到来
        }
}
回复

使用道具 举报

8

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
120
金钱
120
注册时间
2016-9-20
在线时间
26 小时
 楼主| 发表于 2016-10-24 19:22:27 | 显示全部楼层
外部中断和定时器中断一起用的我还没碰到过,不知道这样写程序对不对。我烧到开发板里面之后发现是没有现象的,连最初的长按开机都无法实现了,不知道是为什么。
回复

使用道具 举报

72

主题

2711

帖子

2

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3505
金钱
3505
注册时间
2014-8-4
在线时间
696 小时
发表于 2016-10-24 20:29:10 | 显示全部楼层
1.思路没错
2.不要轻易就贴程序,没时间看
以我资质之鲁钝,当尽平心静气、循序渐进、稳扎稳打之力。
回复

使用道具 举报

8

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
120
金钱
120
注册时间
2016-9-20
在线时间
26 小时
 楼主| 发表于 2016-10-24 22:06:02 | 显示全部楼层
龙之谷 发表于 2016-10-24 20:29
1.思路没错
2.不要轻易就贴程序,没时间看

嗯嗯,我后来调了一下,能实现功能了,但是有一点搞不懂,TIMER这样设置之后,第一次中断没有经过10s延时就直接进入了,我烧了一下原子的定时器中断实验,把延时设长了,发现第一次直接灯就亮了,说明第一次没有延时就进入了中断,不知道问题出在哪里
回复

使用道具 举报

8

主题

30

帖子

0

精华

初级会员

Rank: 2

积分
120
金钱
120
注册时间
2016-9-20
在线时间
26 小时
 楼主| 发表于 2016-10-25 19:45:02 | 显示全部楼层
求大神给指条明路
回复

使用道具 举报

2

主题

6

帖子

0

精华

新手上路

积分
34
金钱
34
注册时间
2017-4-17
在线时间
8 小时
发表于 2017-8-6 14:27:26 | 显示全部楼层
LLK 发表于 2016-10-25 19:45
求大神给指条明路

请问一下 你之前程序是哪里出现了问题 我现在想写的代码跟你的差不多 也是想实现开机一段时间之后自动进入待机模式 拷入之后没反应了 想参考一下你之前的问题
回复

使用道具 举报

18

主题

66

帖子

0

精华

初级会员

Rank: 2

积分
161
金钱
161
注册时间
2017-9-20
在线时间
49 小时
发表于 2018-2-28 10:22:41 | 显示全部楼层
小弟最近也要写个5min无操作,则自动进入休眠模式。楼主的调试程序可否发我一份,参考下
回复

使用道具 举报

1

主题

2

帖子

0

精华

初级会员

Rank: 2

积分
51
金钱
51
注册时间
2019-9-10
在线时间
17 小时
发表于 2020-3-21 14:42:19 | 显示全部楼层
能提供程序参考一下吗,谢谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-5-23 07:23

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表