📄 main.c
字号:
//****************************************************************************************
//** 文件名:main.c
//** Copyright (c) 2003
//** 创建人:Himai (WYJ)
//** 日期:2003.10.26
//** 描述:此程序用于演示键盘输入和处理,程序将输入的键值存在数组ksystore中,可以在程序中断或结束的时候查看
//**
//** 版本:1.0
//**************************************************************************************
//**此处包含的头文件主要是用于定义数据类型和常用地址
#include "def.h"
#include "44b.h"
//**keyoutput 定义的是键盘扫描时的输出地址,keyinput定义的是键盘读入的地址
#define BOARD_TYPE (*(volatile INT8U *)0xa040038)
#define KEYOUTPUT (*(volatile INT8U *)0xa0c0018)
#define KEYINPUT (*(volatile INT8U *)0xa040018)
#define RUNLEDLIGHT (*(volatile INT8U *)0x6480000)=0x00
#define RUNLEDCLEAR (*(volatile INT8U *)0x6480000)=0xff
//#define KEYOUTPUT (*(volatile INT8U *)0xa0c0010)
//#define KEYINPUT (*(volatile INT8U *)0xa040010)
#define beepon() {rPDATE =rPDATE |0xff;}
#define beepoff() {rPDATE =rPDATE &0x00;}
//**定义7289的片选信号使能为数据d0为1
#define cs_disable {(*(volatile unsigned char *)0x0a0c0020)=0xff;}
#define cs_enable {(*(volatile unsigned char *)0x0a0c0020)=0xf7;}
//#define cs_disable {(*(volatile unsigned char *)0x0b8c0018)=0xff;}
//#define cs_enable {(*(volatile unsigned char *)0x0b8c0018)=0xf7;}
//**定义7289的串行数据线用F口bit5仿真,操作时注意保存F口其它位的设置和数值
#define setdata_1 {rPDATF=(0x020|DATASHADOW);DATASHADOW=rPDATF;} //output logic true on data line
#define setdata_0 {rPDATF=(0x1df&DATASHADOW);DATASHADOW=rPDATF;} //output logic false on data line
//**定义7289的通信时钟信号用F口的bit8仿真,操作时注意保存其它位的设置和数值
#define setclock_1 {rPDATF=(0x100|DATASHADOW);DATASHADOW=rPDATF;} //clock turn high
#define setclock_0 {rPDATF=(0x0ff&DATASHADOW);DATASHADOW=rPDATF;} //clock turn low
//**定义一个变量保护F口的数据
int DATASHADOW;
//**此映射表用来映射LED模块不译码时,显示的字符和必须输入的数据的关系
//**每段和对应比特位的关系见示意图
// g
// --- ---
// b | a |f | | <---显示0时点亮的段为gfedcb
// ---
// c | |e | | 那么写入数据为0x7e
// --- ---
// d
// bit: 7 6 5 4 3 2 1 0
// 段位: g f e d c b a
int mapda[10]={0x7e,0x30,0x6d,0x79,0x33,0x5b,0x5f,0x70,0x7f,0x7b};
//int keymap[10]={0xfbfd,0xfefe,0xfefd,0xfefb,0xfdfe,0xfdfd,0xfdfb,0xf7fe,0xf7fd,0xf7fb};
//for the 4*4 keyvalue
//**此数组存放读取的键值
INT16U keystore[100];
//****************************************************************************************
//**函数名:mydelay()
//**参 数:i,j
//**返回值:无
//**功 能:实现延迟等待
//**备 注:
//**************************************************************************************
void mydelay(unsigned int i,unsigned int j)
{
int m,n;
for (m=0;m<=i;m++)
{
for (n=0;n<j;n++);
}
}
//****************************************************************************************
//**函数名:scankey()
//**参 数:无
//**返回值:扫描值(高8位是输出的值,低8位是读入的值,扫描值是两者和)
//**功 能:调用一次此函数,可以实现对键盘一次全扫描
//**备 注:
//**************************************************************************************
INT16U ScanKey()
{
INT16U key=0xffff;
INT16U i;
INT8U temp=0xff,output;
//**扫描时,循环往键盘(4×5)输入线送低电平,**//
//**其中输出为5根所以循环5次就可以了,输入为4根,同时读进输入值,将两者合并返回**//
for (i=1;(( i<=16)&&(i>0)); i<<=1)
{
//**将第i根数据线置低,其余为高**//
output |= 0xff;
output &= (~i);
KEYOUTPUT=output;
//**读入此时的键盘输入值**//
temp = KEYINPUT;
//**如果输入的4根数据线有低电平出现,说明有键输入,否则无**//
if ((temp&0x0f)!=0x0f)
{
//**将此时的输出值左移8位并和将读入的值合并为16位数值,返回待处理**//
key = (~i);
key <<= 8;
key |= ((temp&0x0f)|0xf0);
RUNLEDLIGHT;
return (key);
}
}
//**如果没有键值输入返回0xffff**//
RUNLEDCLEAR;
return 0xffff;
}
//****************************************************************************************
//**函数名:getkey()
//**参 数:无
//**返回值:读取的确定的键值
//**功 能:通过函数scankey()读取键盘输入的变化值,然后经过去抖动和一些处理,获得一个可靠的键值,存入数组内
//**备 注:
//**************************************************************************************
INT16U getkey(void)
{
INT16U key,tempkey=1;
INT16U oldkey=0xffff;
INT8U keystatus=0;
INT8U keycnt=0;
//**等到有合法的、可靠的键值输入,才返回,否则无穷等待**//
while(1)
{
//**key设置为0xffff,初始状态为无键值输入**//
key = 0xffff;
//**等待键盘输入,若有输入则退出此循环进行处理,否则等待**//
while(1)
{
//**扫描一次键盘,将读到的键值送入key**//
key = ScanKey() ;
//**判断是否有键输入,如果有键输入(也就是(key&0xff)!=0xff),则退到外循环进行去伪处理**//
tempkey = (key|0xff00);
if ((tempkey&0xffff) != 0xffff) break;
//**如果没有键值输入,则延迟一段时间后,继续扫描键盘,同时设oldkey=0xffff**//
mydelay(20,50);
oldkey=0xffff;
}
//**在判断到有键输入的情况下延迟一段时间(几十毫秒),再读一次键盘,如果两者不等,退到大循环,继续等待**//
mydelay(50,5000);
if (key != ScanKey())
continue;
//**如果连续两次读的键值一样,并且不等于oldkey,那么可以判断确实有新的键值输入了**//
if (oldkey != key) keystatus=0;
//**如果是新键按下,那么初始化计数器Keycnt,并置状态标志为1**//
if (keystatus==0)
{
keycnt = 0;
keystatus = 1;
}
//**设定Oldkey为新的键值,并退出循环,返回键值**//
oldkey = key;
break;
}
return key;
}
void ledinit(void)
{
//**将F口的bit5和bit8设置为输出工作方式,同时设定无需上拉电阻
rPCONF=0x92555;
rPUPF =0x1ff;
DATASHADOW=0x01ff;
//**使片选失效,设定数据和时钟线均为高,初始化led
cs_disable;
setdata_1;
setclock_1;
//**等待
mydelay(10,1000);
}
void sendleddata(int i,int context)
{
int a[2],count,k;
setclock_0; //clock low
mydelay(3,100);
setdata_0; //data low
a[0]=0x90+i; //set the display location
a[1]=context;//set the digit mapdata as the byte follow the command byte
mydelay(3,10);
cs_enable;
mydelay(3,10);
for (k=0;k<2;k++){
for (count=0x80;count>0;count>>=1)
{ //send a byte
if(a[k] &count)
{
setdata_1;
}
else
{
setdata_0;
}
mydelay(3,10);
setclock_1; //set clock high
mydelay(3,10); //it is time for 7289 to receive command or data.
setclock_0; //set clock low
mydelay(3,10);
}
mydelay(3,10);
}
//disable the chip select
cs_disable ;
mydelay(3,10);
}
void sendledcmd(int context)
{
int count;
//**将时钟和数据线均设为低,
setclock_0;
mydelay(20,10);
setdata_0;
//**使能片选
mydelay(20,10);
cs_enable;
mydelay(35,10);
//**传送8比特,由高位到低位
for (count=0x80;count>0;count>>=1)
{
//**如果此位为1,则数据线送1否则送0
if(context &count)
{
setdata_1;
}
else
{
setdata_0;
}
mydelay(3,10);
//**时钟翻转为高,等待7289取数据
setclock_1;
mydelay(3,10);
//**时钟翻转为低,7289取数据结束
setclock_0;
mydelay(5,10);
}
//**一个字节传送完毕,片选失效
cs_disable;
mydelay(3,10);
}
//****************************************************************************************
//**函数名:main()
//**参 数:无
//**返回值:无
//**功 能:读键值并存储
//**备 注:
//**************************************************************************************
void Main(void)
{
int i=0,data=0;
INT16U key=0,boardtype,lednum=8;
boardtype=BOARD_TYPE;//读入板类型号,d7位为1时,识别键盘为4×4,led4位,否则键盘为4×5,led8位
if((boardtype&0x80)!=0)
{
boardtype=1;
lednum=4;
}
else boardtype=0;
ledinit();
sendledcmd(0xbf);
mydelay(10,1000);
sendledcmd(0xa4);
while(1)
{
mydelay(10,1000);
//**读取键值后取反作为存储值,存入数组内**//
key = getkey();
key = (~key);
keystore[i]=key;
i++;
//**如果输入的键值取反等于0x801(就是f1键),则退出主函数**//
beepon();
if (i==100) i=0;
switch(key)
{
//case 0x801:return ;
case 0x208:if(!boardtype) data=0 ;
break ;
case 0x101:data=1 ;
break ;
case 0x201:if (boardtype) data=4;
else data=2 ;
break ;
case 0x401:if (!boardtype) data=3;
break ;
case 0x102:if (boardtype) data=2;
else data=4 ;
break ;
case 0x202:data=5 ;
break ;
case 0x402:if (boardtype) data=0;
else data=6 ;
break ;
case 0x104:if (boardtype) data=3;
else data=7 ;
break ;
case 0x204:if (boardtype) data=6;
else data=8 ;
break ;
case 0x404:if(!boardtype) data=9 ;
break ;
case 0x801:if (boardtype) data=7;
break;
case 0x802:if (boardtype) data=8;
break;
case 0x804:if (boardtype) data=9;
break;
break;
}
sendledcmd(0xa4);
mydelay(100,500);
sendleddata(i%lednum,mapda[data]) ;
beepoff();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -