【请教】关于AVR中某C语句
爱非神话2009/06/28软件综合 IP:广东
书读少了,也没学过编程,抱着书啃程序太费力了。
照着书上做矩阵键盘扫描实验时,没做成书上的2*3键盘矩阵而是做成了3*3,将代码也做了相应修改,这个程序是带3秒无操作自动休眠的,任意键唤醒,可我写入程序调试时却遇到个很奇怪的问题,就是我自己加的那列键盘死活就是唤不醒休眠后的单片机,但第一次休眠后可以,反正就是不按那排按钮就正常,一按就不正常。后来将程序又从头检查了N遍,还是没发现有明显问题。最后尝试着去掉一句没看明白但觉得可能影响唤醒的语句,嘿!结果就好了!特来请教各位该语句是什么意思?在下面用红字标出来了……希望能尽量解释通俗点,没学过C的,呵呵,路还很长啊……
PICT0941.jpg PICT0942.jpg   

#include "iom48v.h"
#include "macros.h"
#include "delay.h"
#include "led_dis.h"

#define Key_X_1 PORTC = 0b11011111            //扫描第1行键
#define Key_X_2 PORTC = 0b11101111            //扫描第2行键
#define Key_X_3 PORTC = 0b11110111          //扫描第3行键

#define Key_Scan_Port PINC                    //定义用于扫描键盘的端口
#define Key_Y_1 0b11111011                    //第1列上有键按下
#define Key_Y_2 0b11111101                    //第2列上有键按下
#define Key_Y_3 0b11111110                    //第3列上有键按下

#define Key_1 0x01
#define Key_2 0x02
#define Key_3 0x03
#define Key_4 0x04
#define Key_5 0x05
#define Key_6 0x06
#define Key_7 0x07
#define Key_8 0x08
#define Key_9 0x09
#define NoKey 0x00

#define LedDisPort PORTD

unsigned char Key_Scan (void)
{
/*-----------------------扫描第1行-----------------------*/
    Key_X_1;

    Delay_ms(1);

    if ((Key_Scan_Port|Key_Y_1)==Key_Y_1)
        return Key_1;
    else if ((Key_Scan_Port|Key_Y_2)==Key_Y_2)
        return Key_2;
    else if ((Key_Scan_Port|Key_Y_3)==Key_Y_3)
        return Key_3;
/*-----------------------扫描第2行-----------------------*/
    Key_X_2;

    Delay_ms(1);

    if ((Key_Scan_Port|Key_Y_1)==Key_Y_1)
        return Key_4;
    else if ((Key_Scan_Port|Key_Y_2)==Key_Y_2)
        return Key_5;
    else if ((Key_Scan_Port|Key_Y_3)==Key_Y_3)
        return Key_6;

/*-----------------------扫描第3行-----------------------*/
    Key_X_3;

    Delay_ms(1);

    if ((Key_Scan_Port|Key_Y_1)==Key_Y_1)
        return Key_7;
    else if ((Key_Scan_Port|Key_Y_2)==Key_Y_2)
        return Key_8;
    else if ((Key_Scan_Port|Key_Y_3)==Key_Y_3)
        return Key_9;

    return NoKey;
}

unsigned char Key_Scan_Ant_Dither(void)                   //抗抖动的键盘扫描函数,扫描键盘并返回键值
{
    unsigned char TmpKeyValue=NoKey;

    TmpKeyValue=Key_Scan();

    if (TmpKeyValue==NoKey)
        return NoKey;

    Delay_ms(20);

    if (TmpKeyValue!=Key_Scan())
        return NoKey;

    return TmpKeyValue;
}

#pragma interrupt_handler pcint1_isr: iv_PCINT1
void pcint1_isr(void)                                    //引脚电平变化中断PCINT1中断服务函数
{
    SMCR&=0xFE;                                          //禁止休眠功能,以免误触发
    PCMSK1&=(~((1<<[s:9]CINT11)|(1<<[s:9]CINT10)|(1<<[s:9]CINT9)));  //禁止引脚电平变化中断,以免影响键盘扫描程序的运行
    PCICR&=(~(1<<[s:9]CIE1));                //就是这句了,书上也没说,网上也没查到资料[s:245]
}


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

    DDRC=0xF8;                  //将键盘的"行"设置为输出,键盘的"列"设置为输入并开启了输入端的内部上拉电阻
    DDRB=0xFF;
    DDRD=0xFF;
    PORTC=0xFF;
    PORTB=0x00;
    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=0b11000111;                                   //将键盘的行(PC5,PC4)设置为输出"0"状态
                    PORTD=0x00;                                         //关闭数码管显示驱动以节省电能
                    PCMSK1|=((1<<[s:9]CINT10)|(1<<[s:9]CINT9)|(1<<[s:9]CINT8));    //使能PCINT9..11
                    PCICR|=(1<<[s:9]CIE1);                                  //使能第一组引脚电平变化中断
                    SMCR=0x05;                                          //设置掉电状态并使能休眠功能
                    asm("SLEEP");                                       //休眠单片机,进入掉电状态
                    PORTC=0xFF;                                            //休眠唤醒后将PC端口重置回初始化状态
                }
            }                    //End Of Else
    }                            //End Of While
}
来自:计算机科学 / 软件综合
4
已屏蔽 原因:{{ notice.reason }}已屏蔽
{{notice.noticeContent}}
~~空空如也
爱非神话 作者
15年8个月前 IP:未同步
115961
大家都挤在这里,就先发到这里了,解决后我再转去计算机版呃……吃饭去……
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
小俊
15年8个月前 IP:未同步
115982
把PCICR的第PCIE1位清零。
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论
kangyuhelf2
15年8个月前 IP:未同步
115983
自己做得开发板? 强大
引用
评论
加载评论中,请稍候...
200字以内,仅用于支线交流,主线讨论请采用回复功能。
折叠评论

想参与大家的讨论?现在就 登录 或者 注册

所属专业
上级专业
同级专业
爱非神话
学者 笔友
文章
71
回复
981
学术分
11
2008/03/23注册,7年0个月前活动
暂无简介
主体类型:个人
所属领域:无
认证方式:邮箱
IP归属地:未同步
插入公式
评论控制
加载中...
文号:{{pid}}
投诉或举报
加载中...
{{tip}}
请选择违规类型:
{{reason.type}}

空空如也

加载中...
详情
详情
推送到专栏从专栏移除
设为匿名取消匿名
查看作者
回复
只看作者
加入收藏取消收藏
收藏
取消收藏
折叠回复
置顶取消置顶
评学术分
鼓励
设为精选取消精选
管理提醒
编辑
通过审核
评论控制
退修或删除
历史版本
违规记录
投诉或举报
加入黑名单移除黑名单
查看IP
{{format('YYYY/MM/DD HH:mm:ss', toc)}}