发一个按键程序,并求指点
本帖最后由 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;
}
}
//=========键号输出============//
voidKeyNoOutput()
{
//---按键“抬起”状态去抖时间到,输出“键号”---//
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; 两句,其用意何在?
本帖最后由 gallle 于 2012-7-15 20:46 编辑
1.上边有函数或语法错!你的uchar定义的重复了。一个程序中智能定义一次。
3.直接用就等于1了,用或高几位不变,只最低位不一样。 第三点,这样用法可以不影响其它模块设置,以文章中为例,只修改定时器0而不影响定时器1 gallle 发表于 2012-7-15 20:42 static/image/common/back.gif
1.上边有函数或语法错!你的uchar定义的重复了。一个程序中智能定义一次。
3.直接用就等于1了,用或高几位 ...
先谢谢!!关于第一个错误能帮助改过来吗?我自己找不出来、 mcu_lover 发表于 2012-7-15 21:58 static/image/common/back.gif
第三点,这样用法可以不影响其它模块设置,以文章中为例,只修改定时器0而不影响定时器1 ...
又学到了新知识, 谢谢3楼!! wh8010jky 发表于 2012-7-16 09:09
先谢谢!!关于第一个错误能帮助改过来吗?我自己找不出来、
uchar 定义错误,unsigned char仔细检查拼写是否正确。 第一个错误我觉得有可能是重复定义导致的。试着把 uchar KeyNo=0xff;更改为 KeyNo=0xff; 看看。 openepo 发表于 2012-7-16 09:57 static/image/common/back.gif
第一个错误我觉得有可能是重复定义导致的。试着把 uchar KeyNo=0xff;更改为 KeyNo=0xff; 看看。 ...
只在 KeyBoard.c 中定义了一次,没有重复的。 本帖最后由 wh8010jky 于 2012-7-16 11:47 编辑
mcu_lover 发表于 2012-7-16 09:22 static/image/common/back.gif
uchar 定义错误,unsigned char仔细检查拼写是否正确。
拼写没有错误,我同时定义了几个变量,并且这段代码是从“非模块化程序(即<一>)”中复制过来的。
我发现两个 C129: missing ';' 错误是乎均与 extern 有关,具体不明白。 围观 学习一下 uchar keyno定义把它放在C文件里。uchar 有个定义拼写错误,仔细检查。 有问题能上传文件,回头可以改完。
页:
[1]