本帖最后由 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; 两句,其用意何在?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
1.上边有函数或语法错!你的uchar定义的重复了。一个程序中智能定义一次。
3.直接用就等于1了,用或高几位不变,只最低位不一样。
先谢谢!!关于第一个错误能帮助改过来吗?我自己找不出来、
又学到了新知识, 谢谢3楼!!
一周热门 更多>