⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 此工程项目用于测试键盘 下载并运行该工程项目后
💻 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 + -