/************************************************************************************
* Copyright (c), 2006-2007, C8051F网络
* All rights reserved.
*
* Http: www.c8051f.com
* Email: mite@vip.qq.com
*
* File name: keyled.c
* Project : C8051F330ST
* Processor: C8051F330
* Compiler : Keil C51 Compiler
*
* author: glacier
* QQ: 252858144
* date: 2009.02.12
*
* Description: 本文件是键盘读取及LED显示驱动程序文件;
*
* Others: none;
*
* Function List:
* 1. void Keyled_Init(void)
* 2. unsigned char Key_Read(void)
*
*************************************************************************************/
/********************************引用外部头文件*************************************/
#include <INTRINS.H>
#include "..\source\c8051f330.h"
#include "..\source\keyled.h"
/*********************************常量及全局变量声明********************************/
//位操作设置
sbit MISO = P0^3; //模拟SPI方式
sbit MOSI = P0^6;
sbit SCK = P0^2;
sbit nLD = P1^6;
/*0-F数码管显示数组*/
unsigned char code LED_Tab[16]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71};
unsigned char xdata Led_Buf[8]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07};
unsigned char xdata Led_ID = 0;
//按键检测
unsigned char Key0,Key1;
unsigned char Key_Value;
bit bKeyDown;
/*************************************************************************************/
//
// 键盘读取及LED显示硬件驱动程序函数定义
// Note: 需要占用定时器0;
//
/*************************************************************************************/
/***********************************************************************************
* Function: Keyled_Init;
*
* Description: 为Spi方式LED显示及按键检测设置的定时0初使化;
*
* Input: none;
*
* Output: none;
*
* Return: none;
*
* Note: none;
************************************************************************************/
void Keyled_Init(void)
{
#define TIME 2 //2ms
//中断设置
ET0=1; //定时器T0中断允许
PT0=0; //定时器T0中断优先级为低
//时钟设置
CKCON |= 0x02;//系统时钟的48分频为T0时钟
CKCON &= 0xfe;
TMOD &= 0xf0;//设置当TR1=1时开启T0,T0为13位计时器方式
TH0 = 0x00; //清T0初值
TL0 = 0x00;
bKeyDown = 0; //清按键检测
Key_Value = 0xff;
Key0 = 0;
Key1 = 0;
TR0 = 1; //使能T0
}
/***********************************************************************************
* Function: SPI_PutVal;
*
* Description: 通过SPI总线协议发送和接收数据;
*
* Input: val,通过SPI总线协议发送的数据;
*
* Output: none;
*
* Return: 通过SPI总线协议接收的数据;
*
* Note: none;
************************************************************************************/
unsigned char SPI_PutVal(unsigned char val)
{
unsigned char count; // SPI位计数值
for (count = 8; count > 0; count--) // 单字节位移
{
MOSI = val & 0x80; // 将字节最高为送MOSI
val = val << 1; // 字节向左移一位
SCK = 0x00; // SCK拉低
val |= MISO; // 将MISO值付val
SCK = 0x01; // SCK拉高
}
return (val); //将MISO采到的单字节送出
}
/***********************************************************************************
* Function: Key_Read;
*
* Description: 读取按键键值函数;
*
* Input: none;
*
* Output: none;
*
* Return: 返回按键键值, 键值范围是0x01~0x08; 如果返回0xff, 表示无按键按下;
*
* Note: none;
************************************************************************************/
unsigned char Key_Read(void)
{
unsigned char val;
val = Key_Value; //取键值
Key_Value = 0xff; //复位Key_Value
return val; //送出键值
}
/***********************************************************************************
* Function: LED_Display;
*
* Description: 读取按键键值函数;
*
* Input: none;
*
* Output: none;
*
* Return: 返回按键键值, 键值范围是0x01~0x08; 如果返回0xff, 表示无按键按下;
*
* Note: none;
************************************************************************************/
/*
void LED_Display(unsigned char *p,unsigned char len)
{
unsigned char val;
val = Key_Value;
Key_Value = 0xff;
return val;
}
*/
/***********************************************************************************
* Function: Timer0_ISR;
*
* Description: 为Spi方式LED显示及按键检测服务的定时0中断函数;
*
* Input: none;
*
* Return: none;
*
* Note: none;
************************************************************************************/
void Timer0_ISR(void) interrupt 1 using 3 //T0中断函数
{
TR0 = 0; //关闭T0
TH0 = 0xe0; //付T0初值
TL0 = 0x03; //开启T0
TR0 = 1;
nLD = 0; // 锁定并行数据
_nop_();
nLD = 1;
Key0 = SPI_PutVal(Led_Buf[Led_ID]); //取键值并显示字型
SPI_PutVal(0x80>>Led_ID); //送位选信号
Led_ID++; //位计数++
if (Led_ID>7) //如果位计数超限
{
Led_ID = 0; //位计数清零
if (Key0!=0xff) //如果有键按下
{
if ((Key0==Key1)&&(!bKeyDown)) //去抖动,按键读取完成位不为1
{
bKeyDown = 1; //按键读取完成位为1
switch (Key0) //判断按键值
{
case 0xfe: Key_Value = 1;break;
case 0xfd: Key_Value = 2;break;
case 0xfb: Key_Value = 3;break;
case 0xf7: Key_Value = 4;break;
case 0xef: Key_Value = 5;break;
case 0xdf: Key_Value = 6;break;
case 0xbf: Key_Value = 7;break;
case 0x7f: Key_Value = 8;break;
default: Key_Value = 0xff;
bKeyDown = 0;break;
}
}
else
Key1 = Key0;
}
else
{
if (Key0==Key1)
bKeyDown = 0;
else
Key1 = Key0;
}
}
}
/************************************************************************************
* 文件结束
************************************************************************************/