?? keyled.c
字號:
#include <stdio.h>
#include <reg51all.h>
#include <intrins.h>
#define SEGCODE P1 // 數碼管字型碼由P1輸出,A~H對應D7~D0,0點亮,1熄滅
#define POSCTRL0 P34
#define POSCTRL1 P35
#define LS0 P30 // 位置碼同時作為鍵盤列掃描碼,共8列,2行
#define LS1 P31 // 行掃描由P36,P37完成,D0~D7對應1~8列,為0表示有鍵按下
#define JCON0 P32 //繼電器選通
#define JCON1 P33 //繼電器選通
#define BRAY P37
unsigned char Row,Col; // 按鍵的行列值
unsigned char ucTH,ucTL; // 定時器初值
unsigned char start,set,position,ii; //按鍵設置標記和選路標記
unsigned char hnum,lnum; //定時數的高位和低位
unsigned char count[2]; //定時數
int jj; //中斷計數
unsigned char logo; //倒計時時間到標記
/*******************************************************************************
鍵盤連接方式:
C0 C1
R0 -|---|- P30
R1 -|---|- P31
P34 P35
*******************************************************************************/
// 根據A~H對應D7~D0的關系設定0~F的字形碼
unsigned char code SEGTABLE[] = {
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x5f,0x7c,0x58,0x5e,0x79,0x71};
unsigned char CurrRow[2],CurrCol[2],LastRow[2],LastCol[2]; // 存放當前和前次兩行和兩列掃描碼
//******************************************************************************
// 函數名:T0ISR
// 功 能:2.5ms中斷服務程序
// 作 者:mudfish 2005-10-31 10:12
// 注 釋:
//******************************************************************************
void T0ISR(void) interrupt 1
{
unsigned char i,j,k;
// 重新設置定時常數
TH0 = ucTH;
TL0 = ucTL;
TR0 = 1;
if(logo==1) //倒計時時間到標記
BRAY=1; //鳴叫1秒
else BRAY=0; //關閉鳴叫
// 先進行鍵盤掃描
SEGCODE = 0xff; // 關閉所有段顯示
CurrRow[0] = 0;
CurrRow[1] = 0;
CurrCol[0] = 0;
CurrCol[1] = 0;
POSCTRL0 = 0; // 當前掃描列送0
POSCTRL1 = 1;
LS0 = 1;
_nop_();_nop_();_nop_();_nop_();
if(LS0 == 0)
{
CurrRow[0] =1;
CurrCol[0]=1; // 該位置0
}
LS1 = 1;
_nop_();_nop_();_nop_();_nop_();
if(LS1 == 0)
{
CurrRow[1] =1;
CurrCol[0]=1; // 該位置1
}
POSCTRL0 = 1;
POSCTRL1 = 0; // 當前掃描列送0
LS0 = 1;
_nop_();_nop_();_nop_();_nop_();
if(LS0 == 0)
{
CurrRow[0] =1;
CurrCol[1]=1; // 該位置1
}
LS1 = 1;
_nop_();_nop_();_nop_();_nop_();
if(LS1 == 0)
{
CurrRow[1] =1;
CurrCol[1]=1; // 該位置1
}
// 掃描完成
// 開始按鍵處理
Row = 0xff; // 缺省無按鍵狀態
Col = 0xff;
for(j=0;j<2;j++)
{
if( (CurrRow[j]^LastRow[j]) != 0) // 按鍵狀態有變化
{
for(i=0;i<2;i++)
{
if( LastCol[i]== 1 )
{
Row = j; // 本次掃描按鍵狀態有變化且上次為按下
Col = i; // 說明本次為按鍵松開,有效
break; // 每次只處理一個按鍵
}
}
}
if( (Row!=0xff) && (Col!=0xff) ) break; // 每次只處理一個按鍵
}
for(j=0;j<2;j++)
{
LastRow[j] = CurrRow[j];
LastCol[j]=CurrCol[j]; // 將本次掃描碼保存到上次掃描碼
}
//加法按鍵
if(Row==0 && Col==0)
{
count[position]=count[position]+1; //加1
if(count>99)
count[position]=0; //值0~99
BRAY=1; //鳴叫
}
//減法按鍵
if(Row==0 && Col==1)
{
count[position]=count[position]-1; //減1
if(count<0) //值0~99
count[position]=99;
BRAY=1; //鳴叫
}
//選路按鍵
if(Row==1 && Col==0)
{
set=1; //設置標志
start=0;
position=(position+1)%2; //選路
BRAY=1; //鳴叫
}
//開始倒計時按鍵
if(Row==1 && Col==1)
{
set=0;
start=1; //開始標記
JCON0=1; //繼電器0選通
JCON1=1; //繼電器1選通
BRAY=1; //鳴叫
}
//設置倒計時間時數碼管的顯示處理
if(set==1)
{
hnum=count[position]/10; //高位
lnum=count[position]%10; //低位
POSCTRL0=1; //顯示高位
POSCTRL1=0;
SEGCODE=SEGTABLE[hnum];
_nop_();_nop_();_nop_();_nop_();
POSCTRL0=0;
POSCTRL1=1; //顯示低位
SEGCODE=SEGTABLE[lnum];
}
//開始倒計后的顯示處理和計時到處理
if(start==1)
{
hnum=count[ii]/10; //高位
lnum=count[ii]%10; //低位
POSCTRL0=1; //顯示高位
POSCTRL1=0;
SEGCODE=SEGTABLE[hnum];
_nop_();_nop_();_nop_();_nop_();
POSCTRL0=0;
POSCTRL1=1; //顯示低位
SEGCODE=SEGTABLE[lnum];
jj++;
if(jj>200) ii=(ii+1)%2; //0.5秒 顯示另外一路
if(jj>400) //1秒
{
jj=1;
logo=0; //1秒重設標記
for(k=0;k<2;k++)
{
count[k]=count[k]-1; //1秒 減1
if(count[k]==0) //計時到
{
logo=1; //倒計時間到標記
if(k==0)
JCON0=0; //繼電器0該路關閉
if(k==1)
JCON1=0; //繼電器1該路關閉
}
}
}
}
}
void main(void)
{
position=0; //選第一路
count[0]=0; //第一路初值為0
count[1]=0; //第二路初值為0
JCON0=0; //關閉繼電器0
JCON1=0; //關閉繼電器1
ii=1;
jj=1;
EA = 0; // 停止所有中斷
ucTH = (65536-22118400/12/400)/256; // 計算2.5ms定時的時間常數(22.1184M OSC)
ucTL = (65536-22118400/12/400)%256;
TMOD = 0x01; // T0:模式1,16位定時器
TH0 = ucTH; //定時器賦初值
TL0 = ucTL;
ET0 = 1; // T0允許中斷
TR0 = 1; //開始計數
EA = 1; //開所有的中斷
while(1);
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -