//以下为键盘使用的全局变量声名 #define KEY_BUFFER_SIZE 30 //键盘缓存大小,如果缓存的按键数量大于缓存容量,则最早按下的按键丢弃 #define KEY_CANCEL 0x11 #define KEY_UP 0x12 #define KEY_CONFIRM 0x10 #define KEY_LEFT 0x14 #define KEY_DOWN 0x13 #define KEY_RIGHT 0x15 //--定义键盘缓存:缓存为循环链表 unsigned char key_buffer[KEY_BUFFER_SIZE]; //键盘缓存 int key_buffer_pointer; //键盘缓存首指针(指向最后一个被按下的按键) int key_buffer_amount; //键盘缓存键值数() //int key_current_key; //--定义结束 //--定义ZLG7289与MCU的硬件连接 sbit ZLG7289_pinCS = P0^3; sbit ZLG7289_pinCLK = P0^2; sbit ZLG7289_pinDIO = P0^1; unsigned char ZLG7289_Delay_t; //--定义结束 //键盘使用的全局变量定义结束 /* 宏定义:ZLG7289_ShortDelay() 功能:短延时 说明:延时(ZLG7289_Delay_t*2+2)个机器周期 */ void ZLG7289_ShortDelay() { unsigned char t = ZLG7289_Delay_t; while ( --t != 0 ); } /* 宏定义:ZLG7289_LongDelay() 功能:长延时 说明:延时(ZLG7289_Delay_t*12+8)个机器周期 */ void ZLG7289_LongDelay() { unsigned char t = ZLG7289_Delay_t * 6; while ( --t != 0 ); } /* 函数:ZLG7289_SPI_Write() 功能:向SPI 总线写入1 个字节的数据 参数: dat:要写入的数据 */ void ZLG7289_SPI_Write(char dat)// reentrant { unsigned char t = 8; do { ZLG7289_pinDIO = (bit)(dat & 0x80); dat <<= 1; ZLG7289_pinCLK = 1; ZLG7289_ShortDelay(); ZLG7289_pinCLK = 0; ZLG7289_ShortDelay(); } while ( --t != 0 ); } /* 函数:ZLG7289_SPI_Read() 功能:从SPI 总线读取1 个字节的数据 返回: 读取到的数据 */ char ZLG7289_SPI_Read()// reentrant { char dat; unsigned char t = 8; ZLG7289_pinDIO = 1; //读取数据之前DIO 引脚要置1 以切换到输入状态 do { ZLG7289_pinCLK = 1; ZLG7289_ShortDelay(); dat <<= 1; if ( ZLG7289_pinDIO ) dat++; ZLG7289_pinCLK = 0; ZLG7289_ShortDelay(); } while ( --t != 0 ); return dat; } /* 功能:执行ZLG7289 键盘命令 返回: 返回读到的按键值:0~63 如果返回0xFF 则表示没有键按下 */ char ZLG7289_Key() //reentrant { char key; ZLG7289_pinCS = 0; ZLG7289_LongDelay(); ZLG7289_SPI_Write(0x15); ZLG7289_LongDelay(); key = ZLG7289_SPI_Read(); ZLG7289_pinCS = 1; ZLG7289_LongDelay(); return key; } void ZLG7289_Reset(){ EX0=0; key_buffer_pointer=-1; key_buffer_amount=0; ZLG7289_pinCS = 0; ZLG7289_LongDelay(); ZLG7289_SPI_Write(0xA4); ZLG7289_pinCS = 1; EX0=1; ZLG7289_LongDelay(); } /* 函数:ZLG7289_Init() 功能:ZLG7289 初始化 参数: t:SPI 总线的延时值设置,取值1-40(超出范围可能导致错误) 说明: t的取值可以参照以下公式:t >= 5 * f1 / f2,其中f1 表示80C51 的 晶振频率,f2 表示ZLG7289 的晶振频率 */ void ZLG7289_Init() { //unsigned char x; //I/O 口初始化 ZLG7289_pinCS = 1; ZLG7289_pinCLK = 0; ZLG7289_pinDIO = 1; //ZLG7289_pinINT = 1; EA=0; IT0 = 1; //负边沿触发中断 EX0 = 1; //允许外部中断 EA=1; //延时初始化 ZLG7289_Delay_t = 30; ZLG7289_Reset(); } void ZLG7289_read() interrupt 0 using 1// 读键盘函数,响应外部中断0 { unsigned char t,t1; unsigned char dat; EX0=0; //此处处理键盘缓存,取回的键值已放在了temp变量中 key_buffer_pointer++; key_buffer_pointer=key_buffer_pointer%KEY_BUFFER_SIZE; ZLG7289_pinCS = 0; t = ZLG7289_Delay_t * 6; while ( --t != 0 ); t=8; dat=0x15; do { ZLG7289_pinDIO = (bit)(dat & 0x80); dat <<= 1; ZLG7289_pinCLK = 1; t1 = ZLG7289_Delay_t; while ( --t1 != 0 ); ZLG7289_pinCLK = 0; t1 = ZLG7289_Delay_t; while ( --t1 != 0 ); }while ( --t != 0 ); t = ZLG7289_Delay_t * 6; while ( --t != 0 ); t=8; dat=0; ZLG7289_pinDIO = 1; //读取数据之前DIO 引脚要置1 以切换到输入状态 do { ZLG7289_pinCLK = 1; t1 = ZLG7289_Delay_t; while ( --t1 != 0 ); dat <<= 1; if ( ZLG7289_pinDIO ) dat++; ZLG7289_pinCLK = 0; t1 = ZLG7289_Delay_t; while ( --t1 != 0 ); } while ( --t != 0 ); key_buffer[key_buffer_pointer] = dat; ZLG7289_pinCS = 1; t = ZLG7289_Delay_t * 6; while ( --t != 0 ); key_buffer_amount++; EX0=1; } unsigned char GetKey() //用户函数,得到最先被按下且尚未被处理的按键。若未有按键则返回 -1 { unsigned char temp; if(key_buffer_amount){ EX0=0; if(key_buffer_amount>KEY_BUFFER_SIZE)key_buffer_amount=KEY_BUFFER_SIZE; temp=key_buffer[(key_buffer_pointer-key_buffer_amount+1)%KEY_BUFFER_SIZE]; key_buffer_amount--; EX0=1; return temp; } return 0xFF; } unsigned char GetLastKey() //用户函数,得到最后被按下的按键,尚未处理的按键全部丢弃;若无键按下,返回-1。 { unsigned char temp; if(key_buffer_amount){ EX0=0; temp=key_buffer[key_buffer_pointer]; key_buffer_pointer=-1; key_buffer_amount=0; EX0=1; return temp; } return -1; } unsigned char GetCurrentKey() //用户函数,等待用户按键,并得到键值,尚未处理的按键全部丢弃 { unsigned char temp; EX0=0; key_buffer_pointer=-1; key_buffer_amount=0; EX0=1; ZLG7289_Reset(); while(!key_buffer_amount); EX0=0; key_buffer_pointer=-1; key_buffer_amount=0; temp=key_buffer[0]; EX0=1; return temp; }