搜索
bottom↓
回复: 3

关于傻孩子书中 “中断唤醒的键盘扫描” (P109)只能唤...

[复制链接]

出0入76汤圆

发表于 2012-10-31 21:41:30 | 显示全部楼层 |阅读模式
傻孩子大侠书中【实例七】中断唤醒的键盘扫描,P109页,说到  “这个实例还有一个遗留的问题需要大家注意:如果去掉中断服务函数中“PCMSK1&=(~((1<<PCINT11)|(1<<PCINT10)|(1<<PCINT9)));”一句,键盘将只能被唤醒1次。据说DA895在这个问题上找了半天,在这里我们不打算详细分析,把这个问题留给读者思考。”

pragma interrupt_handler pcint1_isr: iv_PCINT1
void pcint1_isr(void)                                    //引脚电平变化中断PCINT1中断服务函数
{
    SMCR&=0xFE;                                          //禁止休眠功能,以免误触发
    //PCMSK1&=(~((1<<PCINT11)|(1<<PCINT10)|(1<<PCINT9)));  //禁止引脚电平变化中断,以免影响键盘扫描程序的运行 (把这一行注释掉)
    PCICR&=(~(1<<PCIE1));
}

void main (void)
{
    unsigned char KeyValue=NoKey;
    unsigned int SleepTimer=0;

    DDRC=0xF1;                  //将键盘的"行"设置为输出,键盘的"列"设置为输入并开启了输入端的内部上拉电阻
    DDRB=0xFF;
    DDRD=0xFF;
    PORTC=0xFF;
    PORTB=0xFF;
    PORTD=0xFF;

    SEI();                     //允许全局中断

    LedDisPort=DisTab[0];      //上电后初始化显示"0"

    while(1)
    {
        KeyValue=Key_Scan_Ant_Dither();
        if (KeyValue!=NoKey)                                            //当有按键按下时,显示该键的键值
            {
                LedDisPort=DisTab[KeyValue];
                SleepTimer=0;                                           //并清0休眠计时器
            }
        else                                                            //当没有按键按下时,计算连续未操作的时间
            {
                SleepTimer++;                                           //休眠计时器自加以实现计时
                if (SleepTimer >= 1500)                                  //当连续3秒钟(近似值)没有按任何按键时,将进入休眠状态
                {
                    SleepTimer=0;                                       //清0休眠计时器,以便唤醒后继续计时
                    PORTC=0b11001111;                                   //将键盘的行(PC5,PC4)设置为输出"0"状态
                    PORTD=0x00;                                         //关闭数码管显示驱动以节省电能
                    PCMSK1|=((1<<PCINT11)|(1<<PCINT10)|(1<<PCINT9));    //使能PCINT9..11
                    PCICR|=(1<<PCIE1);                                  //使能第一组引脚电平变化中断
                    SMCR=0x05;                                          //设置掉电状态并使能休眠功能
                    asm("SLEEP");                                       //休眠单片机,进入掉电状态
                    PORTC=0xFF;                                                                                        //休眠唤醒后将PC端口重置回初始化状态
                }
            }                                        //End Of Else
    }                                                        //End Of While
}

键盘只能唤醒一次?我感觉有点疑问:
1. 在第一次中断唤醒后,虽然PCMSK1中的电平变化中断没有被屏蔽掉,但是在 PCICR&=(~(1<<PCIE1)) 后, PCIE1(PCINT8-14端口的总开关)是掉的,故即使唤醒后的,键盘操作(PC1,PC2,PC3输入)或端口(PORT PC4,PC5输出变化)引起的电平也不会使得再次进入电平变化中断服务程序。

除非把 PCICR&=(~(1<<PCIE1));也去掉,每次按键或PORTC的电平变化都将引起中断,从而影响程序的正常运行而已。

2.我在Protues中仿真试过,后续唤醒仍然是有效的。(并不是只能唤醒一次)

出0入76汤圆

 楼主| 发表于 2012-10-31 22:07:24 | 显示全部楼层
现在都没有人讨论AVR啦 ?

出0入296汤圆

发表于 2012-11-1 10:27:12 | 显示全部楼层
不要相信protues

出0入76汤圆

 楼主| 发表于 2012-11-1 10:30:32 | 显示全部楼层
本帖最后由 foxpro2005 于 2012-11-1 10:36 编辑

谢谢傻孩子大侠 即时回复。
但我想后续应该也还是可以唤醒的啊。因为PCICR&=(~(1<<PCIE1)),PCIE1是屏蔽掉的。
我还是没有想通,只能唤醒一次,后续无法再唤醒。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-5-2 11:02

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

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