搜索
bottom↓
回复: 23

关于PIC单片机的“休眠”和“唤醒”

[复制链接]

出0入0汤圆

发表于 2010-10-11 15:20:01 | 显示全部楼层 |阅读模式
关于PIC单片机的“休眠”和“唤醒”自己还是不太会用。希望各位大虾能给点指导。
现在主要是用PIC12F635单片机。用其中一个引脚GP0做为按键输入,其中一个引脚GP4作为输出。要达到的效果就是:平时都是“休眠”状态,当有按键按下时,单片机立即“唤醒”,GP4开始发出某段波形。就是想问一问这“休眠”与“唤醒”,具体怎么设置,希望有朋友写一小段用C的休眠和唤醒程序。让我能入个门。

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

发表于 2010-10-11 15:26:51 | 显示全部楼层
选择有唤醒功能的I/O接按键就好啦

出0入0汤圆

发表于 2010-10-11 15:46:46 | 显示全部楼层
休眠的概念源自低功耗,如果系统没有低功耗需求,应该不要考虑这个问题。

出0入0汤圆

发表于 2010-10-11 21:58:58 | 显示全部楼层
void goSleep()
{
        asm("MOVLW 9");
        asm("TRIS 6");
        GP0=1;
        GP1=1;
        asm("MOVLW 79");//电平唤醒使能,弱上拉禁用,分频器分配给WDT
        asm("OPTION");
        asm("SLEEP");       
}

手头有个程序,我是这样处理进入休眠的
唤醒的话就是引脚电平变化,程序就从头开始运行

出0入0汤圆

发表于 2010-10-12 00:48:04 | 显示全部楼层
如果有电平变化中断,开启就可以了,我现在用没中断的单片机,唤醒出了点问题,顺便也向大家求教!

出0入0汤圆

发表于 2010-10-12 01:18:41 | 显示全部楼层

12f629关于休眠唤醒的描述 (原文件名:629.jpg)


mcv08关于休眠唤醒的描述 (原文件名:mcv08.jpg)


对比了12F629和MCV08两个中文手册,关于唤醒,发现如下问题:
12F629唤醒后是先进中断(如果中断开),然后从程序休眠处继续往下跑。
MCV08这类没有中断的单片机,是单片机重新复位,程序从头开始跑。
不知道我的理解是否正确!?
现在问题来了,如果MCV08是复位,那我中间运行的一些变量是不是都要重新赋初值,那就实现不了我的预想的目的了,怎么办?

出0入0汤圆

发表于 2010-10-12 02:05:24 | 显示全部楼层
"不知道我的理解是否正确!? "

yes.

"现在问题来了,如果MCV08是复位,那我中间运行的一些变量是不是都要重新赋初值,那就实现不了我的预想的目的了,怎么办?"

1) you ask the start-up not to initialize global variable;
2) or you use static variables (in C).

出0入0汤圆

发表于 2010-10-12 06:43:31 | 显示全部楼层
1.变量初始化不要在定义时做
2.初始化里作上电检测,非上电重启时跳过初始化
3.程序流程复杂时使用状态机实现,以便立即回到唤醒前状态.

出0入0汤圆

发表于 2010-10-12 09:12:22 | 显示全部楼层
非常感谢楼上两位,我照你们的办法试试!

出0入0汤圆

发表于 2010-10-12 15:17:11 | 显示全部楼层
今天做了实验,发现休眠后RAM数据无法保存,也就是说所有变量都被清零了,静态全局变量也一样被清零!
“millwood0”和 “rainyss ”请看一下我的程序,看是不是程序问题!?

/////////////////////////////////////////////////////////////////////////////////////////////////
#include <pic.h>
#define uchar unsigned char

#define Weak_up  GP3  //I
#define LED   GP0        //o

//__CONFIG(0x06);//内部4M晶振,代码保护开,WDT开
__CONFIG(0x02);//内部4M晶振,代码保护开,WDT 0ff

//////////////////////////////////////////////////////////////////////////////////////////////////////////
static bit POWER_flag;//开关机标记
static uchar        Sleep_count;//休眠延时
//////////////////////////////////////////////////////////////////////////
////////////////////初始化程序//////////////////////////////////////////////
void Init(void)//初始化程序
{
       
        OPTION = 0x00;//T0分频:2;上拉开,唤醒开
    TRIS = 0x3E;//设置IO口方向3E:111110
        CM1CON0 = 0xF7;//电压比较器关
        ADCON0=0x00;  //AD关

        if(PD)//如果是上电复位
        {
               
                GPIO = 0x00;//输出口清零
                POWER_flag=1;//开机
                //LED=POWER_flag;//上电led亮
                LED=1;//上电led亮
        }
        else//如果不是上电复位
        {       
                if(GPWUF)//如果是电平变化唤醒
                {
                        GPWUF = 0;    //清除唤醒标志
                        Sleep_count=255;//休眠延时计数赋值
                        POWER_flag=!POWER_flag;//开关机标记取反
                        //LED=POWER_flag;//LED无法取反,一直亮,所以我认为无论什么复位,POWER_flag每次都被清零了
                        LED=!LED;//LED状态正常取反
                }
        }

}


void main()              //主程序
{
    Init();                                //初始化
       
    while (1)           //主循环
    {        
               
                if(Sleep_count)//进入休眠延时
                        Sleep_count--;
                else//进入休眠
                {       
                        if(Weak_up)        //进入休眠前读端口,这点很重要,否则不正常               
                        asm("sleep"); //休眠                                       
                }
        }

}

出0入0汤圆

发表于 2010-10-13 23:02:14 | 显示全部楼层
每次重新执行main()就初始化?楼上不是有人说过从休眠退出时就相当于重启,会执行main()不.

出0入0汤圆

发表于 2010-10-14 01:33:44 | 显示全部楼层
MCV08唤醒会执行main(),但我在Init()里面可以通过PD位判断是上电复位还是唤醒,从而决定对不对变量赋初值,现在感觉无论是唤醒还是复位都对变量清零了!

出0入0汤圆

发表于 2010-10-14 07:58:15 | 显示全部楼层
I am not going to write the code for you but here is an example where the pic wakes up from a wdt reset and retains its value.

============code====================

#include <htc.h>
#include "gpio.h"

__CONFIG(MCLRDIS & WDTEN & BORDIS & PWRTEN & INTIO);

#define LED_PORT                GPIO
#define LED_DDR                        TRISIO
#define LED_PINs                0xff

void mcu_init(void) {
        ANSEL=0x00;                        //all pins digital
        CMCON=0x07;                        //analog comparators off
        PSA=1;                                                                                //prescaller to wdt
//        PS2=1, PS1=1, PS0=1;                                                //prescaler to 1<<0b111. time-out period=18ms*128=2s
        PS2=0, PS1=1, PS0=1;                                                //prescaler to 1<<0b011. time-out period=18ms*8=160ms
        IO_CLR(LED_PORT, LED_PINs);        //led_pins low
        IO_OUT(LED_DDR, LED_PINs);
}

void
main(void)
{
        static unsigned char wdt_counter=0;
       
        mcu_init();
        while (1){
                //TODO Auto-generated main function
                if (!TO) {
                        //CLRWDT();                        //clear wdt status
                        wdt_counter++;                //if wdt reset
                        LED_PORT = wdt_counter;
                        while (1);                        //wait for the next wdt
                }
                //do something here
        }
}
==============end code==========================

出0入0汤圆

发表于 2010-10-14 08:03:59 | 显示全部楼层
the code sets up the wdt to wake the mcu up ever 160ms.

Once the mcu wakes up, it sets up the port / wdt, and then goes into the main while() loop.

in the main while loop, it checks to see if it is waking up. if it is, it increments a counter (wdt_counter). and then it outputs the wdt_counter on LED_PORT (GPIO here). after that, it goes into an infinite loop.

what you will see is that GPIO's pins will increment with each reset (every 160ms), with the exception that GPIO3 will not change as it is an input only pin on this mcu.

the code is compiler so that it does NOT clear data segments (bss Psects in Hi-Tech PICC talk).

here is the sim.

hope it helps.



(原文件名:12f675 wdt.PNG)

出0入0汤圆

发表于 2010-10-14 13:49:20 | 显示全部楼层
找到原因了,如 millwood0 所说:the code is compiler so that it does NOT clear data segments (bss Psects in Hi-Tech PICC talk).

原来是编译器的问题,编译的时候clear bss不要打开,否则编译系统编译的时候会在初始化之前自动加上一些对RAM清零的代码,这样每次复位都会把RAM数据都清零,我也是仔细检测了汇编代码才发现的,我用的是PICC 9.8.
非常感谢 millwood0!!

出0入0汤圆

发表于 2010-11-12 09:02:08 | 显示全部楼层
各位大侠,有个简单但很急的问题,PIC24fj64G怎么进入休眠模式,最好有程序

出0入0汤圆

发表于 2011-3-29 20:52:25 | 显示全部楼层
终于见识到了真正的高手对话,学习!!!!

出0入0汤圆

发表于 2011-4-2 13:06:20 | 显示全部楼层
晕,这个问题又被困扰了一次,唉,记性真不好,原来去年十月份已经解决了!!

出0入0汤圆

发表于 2011-4-17 21:54:13 | 显示全部楼层
SLEEP();

出0入0汤圆

发表于 2013-7-3 14:32:50 | 显示全部楼层
mark;;

出0入0汤圆

发表于 2013-7-22 22:04:14 | 显示全部楼层
mark!!!!

出0入0汤圆

发表于 2013-7-25 10:58:29 | 显示全部楼层
millwood0,niu ren

出0入0汤圆

发表于 2015-6-22 22:42:15 | 显示全部楼层
millwood0 哪个国家的?

出0入0汤圆

发表于 2015-7-28 14:00:28 | 显示全部楼层
受教了,面临同样的问题。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-6-1 15:36

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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