搜索
bottom↓
回复: 10

发一个按键程序,并求指点

[复制链接]

出0入0汤圆

发表于 2012-7-15 20:07:02 | 显示全部楼层 |阅读模式
本帖最后由 wh8010jky 于 2012-7-16 11:26 编辑

    刚学C不久,写了一个键盘程序,在KEIL上编译,运行符合设想,贴出来请各位高手评一评:1、程序思路好不好?(思路:在监测到有键按下立即求得键号,然后等待按键释放执行相关程序,在此之前,可以执行其他程序)。  2、运行效率如何?本人不知如何测试效率,也没有条件测试,因为本人是业余自学的,哪位大侠测试了请告诉一声。
   
    另外:看了本站上的文章:从单片机初学者迈向单片机工程师(一份正真的让你成为工程师的贴子),学着写了模块,但不能编译,KEIL提示了几个错误,具体请看第< 二 >部分,希望有好心的大侠指点指点,先说一声谢谢!!

                 < 一 >

#include <reg52.h>
#define uchar unsigned char

uchar KeyNo=0xff;            //键号
uchar K_No=0xff;             //键号
uchar KeyValue=0;            //键值
uchar TimeCount=0;           //计时器

bit flag_KeyDown=0;          //键“按下”标志
bit flag_KeyUp=0;            //键“抬起”标志

#define Led P0

uchar KeyBoard();
void KeyNo_Deal();
void Time0Init();


void main()
{
    Time0Init();
    Led=0xf0;
    while(1)
    {
        K_No=KeyBoard();
        KeyNo_Deal();        
    }
}


uchar KeyBoard()
{
    uchar temp=0xff;

    P1=0xf0;                      //监测按键

  //---如果检测为低电平,"有键按下"---//

    if(P1!=0xf0)               
    {
        if(flag_KeyDown==0)      //如果首次检测到有键按下
        {
            flag_KeyDown=1;      //标志:“按下”
            TR0=0;               //开中断计时
            TimeCount=0;

            temp=P1&0xf0;         //求键值
            P1=0x0f;
            KeyValue=P1&0x0f|temp;

            switch(KeyValue)     //定键号
            {
                case 0xbe:KeyNo=0x00; break;
                case 0x77:KeyNo=0x01; break;
                .
                .
                .
                default:KeyNo=0xff; break;
            }
        }
    }

  //---如果检测为高电平,且“按下”状态去抖时间到,进入“抬起”状态监测---//

    else if((TimeCount==20)&&(flag_KeyUp==0))   
    {
        TR0=1;                    //重开中断重新计时
        TimeCount=0;
        flag_KeyUp=1;             //标志 :“抬起”
    }

       //---输出---//

  //---如果“抬起”状态去抖时间到,输出“键号”---//

    if((TimeCount==20)&&(flag_KeyUp==1))        
    {
        TimeCount=0;
        flag_KeyDown=0;
        flag_KeyUp=0;
        return KeyNo;           
    }

  //---非按键”抬起“状态,输出非键号信息--- //

    else                            
    {
        return 0xff;         
    }   
}

void KeyNo_Deal()
{
    if(K_No!=0xff)
    {
        K_No=0xff;
        Led=~Led;
    }
}

void Time0Init()
{
    TMOD &=0xf0;
    TMOD |=0x01;
    TH0=0xfc;                            
    TL0=0x66;
    ET0=1;            
    EA=1;            
}

void Time0Isr() interrupt 1
{
    TH0=0xfc;
    TL0=0x66;
    TimeCount++;
    if(TimeCount==20)
    {
        TR0=0;             //关中断停止计时
    }
}



=============================================================
=============================================================

                 < 二 >

    ////---main.c---////

#include <reg52.h>
#include "KeyBoard.h"
#include "Timer.h"
#include "KeyNoDeal.h"

void main()
{
    Timer0Init();

    while(1)
    {
         KeyMonitor();
         KeyNoDeal();      
    }
}


    ////---KeyBoard.c---////

#include <reg52.h>
#include "KeyBoard.h"
#include "Timer.h"

#define uchar unsigned char

uchar temp=0xff;
uchar K_No=0xff;               //键号
uchar KeyValue=0xff;
uchar KeyNo=0xff;              //输出键号

bit flag_KeyDown=0;
bit flag_KeyUp=0;


    //=========监测按键========//

void KeyMonitor()            
{
    P1=0xf0;
    if(P1!=0xf0)
    {
        LowVoltageDeal();
    }
    else
    {
        HighVoltageDeal();
    }
    KeyNoOutput();
}



    //=========低电平状态:确定键号=========//

void LowVoltageDeal()            
{
    if(flag_KeyDown==0)            //首次检测到有键按下
    {
        flag_KeyDown=1;            //标志:“按下”

        TR0=0;                     //开中断计时,去抖
        TimeCount=0;

        temp=P1&0xf0;
        P1=0x0f;
        KeyValue=P1&0x0f|temp;     //---键值---

        switch(KeyValue)           //---求键号---
        {
            case 0xbe:K_No=0x00; break;
            case 0x77:K_No=0x01; break;
            .
            .
            .
            default  :K_No=0xff;
        }
    }            
}


        //=========高电平状态:去抖==========//

void HighVoltageDeal()
{
        //---按键“按下”状态去抖时间到,进入“抬起”状态监测---//

    if((TimeCount==20)&&(flag_KeyUp==0))         
    {
        TR0=1;                               //重开中断计时,“抬起”状态去抖
        TimeCount=0;
        flag_KeyUp=1;                        //标志 :“抬起”
    }   


        //---按键“抬起”状态去抖时间到---//

    if((TimeCount==20)&&(flag_KeyUp==1))        
    {
        TimeCount=0;
        flag_KeyDown=0;
        flag_KeyUp=0;
    }
}


        //=========键号输出============//

void  KeyNoOutput()
{
        //---按键“抬起”状态去抖时间到,输出“键号”---//

    if((TimeCount==20)&&(flag_KeyUp==1))        
    {
        KeyNo=K_No;                           
    }

        //---按键非"抬起"状态,输出非键号信息---//

    else                                       
    {
        KeyNo=0xff;                           
    }
}



   ////---KeyBoard.h---////

#ifndef _KEYBOARD_H_
#define _KEYBOARD_H_

extern void KeyMonitor();
void LowVoltageDeal();
void HighVoltageDeal();
void KeyNoOutput();

extern uchar KeyNo;-----------------?????

#endif


    ////---KeyNoDeal.c---////


#include <reg52.h>
#include "KeyNoDeal.h"
#define uchar unsigned char
#define Led P0

LED=0xf0;

void KeyNoDeal()
{
    if(KeyNo!=0xff)
    {
        KeyNo=0xff;------------------?????
        Led=~Led;
    }
}


    ////---KeyNoDeal.h---////

#ifndef _KEYNODEAL_H_
#define _KEYNODEAL_H_

extern void KeyNoDeal();

#endif



   ////---Timer.c---////

#include <reg52.h>
#include "Timer.h"
#define uchar unsigend char

uchar TimeCount=0;-------------?????

void Timer0Init()
{
    TMOD &=0xf0;
    TMOD |=0x01;
    TH0=0xfc;
    TL0=0x66;
    EA=1;
    ET0=1;
}


void Time0Isr() interrupt 1
{
    TH0=0xfc;
    TL0=0x66;
    TimeCount++;
    if(TimeCount==20)
    {
        TR0=0;
    }
}



    ////---Timer.h---////


#ifndef _TIMER_H_
#define _TIMER_H_

extern void Timer0Init();
extern TimeCount;

#endif


================================================================================
KEIL 提示:(错误处已在相关文件中以 ?????标注)

bUILD Output

compiling main.c...

    KEYBOARD.H(12): error C129: missing ';' before 'KeyNo'

compiling Timer.c...

    TIMER.C(8): error C129: missing ';' before 'char'

compiling KeyBoard.c...

    KEYBOARD.H(12): error C129: missing ';' before 'KeyNo'

compiling KeyNoDeal.c...

    KEYNODEAL.C(14): error C202: 'KeyNo':undefinedidentifier

    KEYNODEAL.C(16): error C202: 'KeyNo': undefined identifier

Target not created


我的问题是:
    1、missing ';' 是什么错误?绝不是“遗漏”了什么,我已检查多遍。
    2、c202错误也不理解,已在KeyNoDeal.h中声明是extern, 其他函数
       为何不能直接使用?
    3、定时器函数是直接套用“从单片机初学者迈向单片机工程(一份正真
       的让你成为工程师的贴子)” 中的,初始化TMOD为什么不直接用                     TMOD=0X01; 而用 TMOD &=0xf0;TMOD |=0x01; 两句,其用意何在?




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

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

出0入96汤圆

发表于 2012-7-15 20:42:49 | 显示全部楼层
本帖最后由 gallle 于 2012-7-15 20:46 编辑

1.上边有函数或语法错!你的uchar定义的重复了。一个程序中智能定义一次。
3.直接用就等于1了,用或高几位不变,只最低位不一样。

出0入264汤圆

发表于 2012-7-15 21:58:15 来自手机 | 显示全部楼层
第三点,这样用法可以不影响其它模块设置,以文章中为例,只修改定时器0而不影响定时器1

出0入0汤圆

 楼主| 发表于 2012-7-16 09:09:29 | 显示全部楼层
gallle 发表于 2012-7-15 20:42
1.上边有函数或语法错!你的uchar定义的重复了。一个程序中智能定义一次。
3.直接用就等于1了,用或高几位 ...

先谢谢!!关于第一个错误能帮助改过来吗?我自己找不出来、

出0入0汤圆

 楼主| 发表于 2012-7-16 09:10:36 | 显示全部楼层
mcu_lover 发表于 2012-7-15 21:58
第三点,这样用法可以不影响其它模块设置,以文章中为例,只修改定时器0而不影响定时器1 ...

又学到了新知识, 谢谢3楼!!

出0入264汤圆

发表于 2012-7-16 09:22:20 来自手机 | 显示全部楼层
wh8010jky 发表于 2012-7-16 09:09
先谢谢!!关于第一个错误能帮助改过来吗?我自己找不出来、

uchar 定义错误,unsigned char仔细检查拼写是否正确。

出0入0汤圆

发表于 2012-7-16 09:57:57 | 显示全部楼层
第一个错误我觉得有可能是重复定义导致的。试着把 uchar KeyNo=0xff;  更改为 KeyNo=0xff; 看看。

出0入0汤圆

 楼主| 发表于 2012-7-16 11:11:41 | 显示全部楼层
openepo 发表于 2012-7-16 09:57
第一个错误我觉得有可能是重复定义导致的。试着把 uchar KeyNo=0xff;  更改为 KeyNo=0xff; 看看。 ...

只在 KeyBoard.c 中定义了一次,没有重复的。

出0入0汤圆

 楼主| 发表于 2012-7-16 11:17:45 | 显示全部楼层
本帖最后由 wh8010jky 于 2012-7-16 11:47 编辑
mcu_lover 发表于 2012-7-16 09:22
uchar 定义错误,unsigned char仔细检查拼写是否正确。


拼写没有错误,我同时定义了几个变量,并且这段代码是从“非模块化程序(即<一>)”中复制过来的。
我发现两个 C129: missing ';' 错误是乎均与 extern 有关,具体不明白。

出0入54汤圆

发表于 2012-7-16 16:59:30 | 显示全部楼层
围观 学习一下

出0入0汤圆

发表于 2012-7-20 00:38:48 来自手机 | 显示全部楼层
uchar keyno定义  把它放在C文件里。uchar 有个定义拼写错误,仔细检查。 有问题能上传文件,回头可以改完。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-8-26 17:28

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

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