方法一(推荐)
#include
#include
//段选segment 0 1 2 3 4 5 6 7 8 9 A b C d E F
unsigned char code seg[]={
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xA1,0x86,0x8e};
unsigned char temp,i; //临时变量temp,循环变量i
sbit k1=P1^0;//控制列
sbit k2=P1^1;
sbit k3=P1^2;
sbit k4=P1^3;
void delay(int a)//延时函数,增大从一个状态到另一个状态之间的时间,避免因变化过快而超出人眼视觉停留的最佳时间
{
while(a--);
}
void main()
{
while(1)
{
P1=0xef;// 选择第一行P1.7~P1.4 e(1110) P1.3~P1.0 f(1111)
for(i=0;i<=3;i++)
{
if(k1==0)//k1=P1^0,k1=0,P1^0=0检查第一行第一列按钮是否有按钮被按下
//第一次循环检查第一行第一列按钮
//第二次循环检查第一行第二列按钮……
P0=seg[i*4+0]; //i=0 seg[0]为数字0 //i=1 seg[4]为数字4 //i=2 seg[8]为数字8 //i=3 seg[12]为字母C
if(k2==0)//检查第二行是否有按钮被按下
//第一次循环检查第二行第一列按钮
//第二次循环检查第二行第二列按钮……
P0=seg[i*4+1]; //i=0 seg[1]为数字1 //i=1 seg[5]为数字5 //i=2 seg[9]为数字9 //i=3 seg[13]为字母d
if(k3==0)//检查第三行是否有按钮被按下
//第一次循环检查第三行第一列按钮
//第二次循环检查第三行第二列按钮……
P0=seg[i*4+2]; //i=0 seg[2]为数字2 //i=1 seg[6]为数字6 //i=2 seg[10]为字母A //i=3 seg[14]为字母E
if(k4==0)//检查第四行是否有按钮被按下
//第一次循环检查第四行第一列按钮
//第二次循环检查第四行第二列按钮……
P0=seg[i*4+3]; //i=0 seg[3]为数字3 //i=1 seg[7]为数字7 //i=2 seg[11]为字母b //i=3 seg[15]为字母F
delay(300);//消抖
temp=P1;//第一次循环为temp=0xef,第二次循环为temp=0xbf,……
temp=temp<<1;//此左移并非函数_crol_()
//第一次循环0xef左移1位 1101 1110 //第二次循环0xef再次左移1位 1011 1100 /……
temp=temp | 0x0f;
//第一次循环 1110 1111 0xef 第二次循环0xef左移一位后:1101 1110
// | |
// 0000 1111 0x0f 0000 1111 0x0f
// 1110 1111 0xef(选择第一行) 1101 1111 0xbf(选择第二行)
P1=temp; //将临时量temp赋值给P1,以便下次循环,进入扫描下一行
}
}
}
方法二
#include
#include
//段选segment 0 1 2 3 4 5 6 7 8 9 A b C d E F
unsigned char code led[]={
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xA1,0x86,0x8e};
// unsigned char code led[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
unsigned char temp,i; //临时变量temp,循环变量i
sbit k4=P1^4;//控制行
sbit k5=P1^5;
sbit k6=P1^6;
sbit k7=P1^7;
void delay(int a)//延时函数,增大从一个状态到另一个状态之间的时间,避免因变化过快而超出人眼视觉停留的最佳时间
{
while(a--);
}
void main()
{
while(1)
{
P1=0xfe;//P1.7~P1.4 (1111) P1.3~P1.0 (1110)选择第一列 1111 1101 1111 1011 1111 0111
for(i=0;i<=3;i++)
{
if(k4==0)//1110 1110 第一列第一行 数字1
P0=led[0+i];//i=0 数字0 i=1 数字1 i=2 数字2 i=3 数字3
if(k5==0)//1101 1110 第一列第二行 数字4
P0=led[4+i];//i=0 数字4 i=1 数字5 i=2 数字6 i=3 数字7
if(k6==0)//1011 1110 第一列第三行 数字8
P0=led[8+i];//i=0 数字8 i=1 数字9 i=2 字母A(10) i=3 字母B(11)
if(k7==0)//0111 1110 第一列第四行 字母C
P0=led[12+i];//i=0 字母C(12) i=1 字母D(13) i=2 字母E(14) i=3 字母F(16)
delay(25000);
if(i!=3)//选列只需要移动三次(0,1,2)防止第4次左移
{
temp=P1;
temp=temp<<1; //1111 1100 P1 1111 1010 P1 1111 0110
temp=temp | 0x01; //0000 0001 <<1 0000 0001 <<1 0000 0001
P1=temp; //1111 1101 1111 1011 1111 0111
}
}
}
}
方法三
#include
//段选segment 0 1 2 3 4 5 6 7 8 9 A b C d E F
unsigned char code seg[]={
0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xc6,0xA1,0x86,0x8e};
unsigned char temp,key; //临时变量temp,seg[key]下标
sbit k1=P1^0;
sbit k2=P1^1;
sbit k3=P1^2;
sbit k4=P1^3;
void delay(int a)//延时函数,增大从一个状态到另一个状态之间的时间,避免因变化过快而超出人眼视觉停留的最佳时间
{
while(a--);
}
void display()
{
delay(30000);
P0=seg[key];
}
void main()
{
P0=0xff;//清屏
while(1)
{
//选择第一行
P1=0xef;//行P1.7~P1.4 1110 列P1.3~P1.0 1111
temp=P1;
if( (temp&0xef)!=0xef ) //扫描第一行
{
delay(15);//消抖
if((temp&0xef)!=0xef) //消抖后再次扫描第一行
{
switch(temp)
{
case 0xee:key=0;break;//第一行第一列 P1.7~P1.4行1110 P1.3~P1.0列1110
case 0xed:key=1;break;//第一行第二列 P1.7~P1.4行1110 P1.3~P1.0列1101
case 0xeb:key=2;break;//第一行第三列 P1.7~P1.4行1110 P1.3~P1.0列1011
case 0xe7:key=3;break;//第一行第四列 P1.7~P1.4行1110 P1.3~P1.0列0111
}
}
display();
}
//选择第二行
P1=0xbf;//行P1.7~P1.4 1101 列P1.3~P1.0 1111
temp=P1;
if((temp&0xbf)!=0xbf) //扫描第二行
{
delay(15); //消抖
if((temp&0xbf)!=0xbf)
{
switch(temp)
{
case 0xbe:key=4;break;//第二行第一列 P1.7~P1.4行1101 P1.3~P1.0列1110
case 0xbd:key=5;break;//第二行第二列 P1.7~P1.4行1101 P1.3~P1.0列1101
case 0xbb:key=6;break;//第二行第三列 P1.7~P1.4行1101 P1.3~P1.0列1011
case 0xb7:key=7;break;//第二行第四列 P1.7~P1.4行1101 P1.3~P1.0列0111
}
}
display();
}
//选择第三行
P1=0x9f;//行P1.7~P1.4 1011 列P1.3~P1.0 1111
temp=P1;
if((temp&0x9f)!=0x9f) //扫描第三行
{
delay(15); //消抖
if((temp&0x9f)!=0x9f)
{
switch(temp)
{
case 0x9e:key=8;break;//第三行第一列 P1.7~P1.4行1011 P1.3~P1.0列1110
case 0x9d:key=9;break;//第三行第二列 P1.7~P1.4行1011 P1.3~P1.0列1101
case 0x9b:key=10;break;//第三行第三列 P1.7~P1.4行1011 P1.3~P1.0列1011
case 0x97:key=11;break;//第三行第四列 P1.7~P1.4行1011 P1.3~P1.0列0111
}
}
display();
}
//选择第四行
P1=0x7f;//行P1.7~P1.4 0111 列P1.3~P1.0 1111
temp=P1;
if((temp&0x7f)!=0x7f) //扫描第四行
{
delay(15); //消抖
if((temp&0x7f)!=0x7f)
{
switch(temp)
{
case 0x7e:key=12;break;//第四行第一列 P1.7~P1.4行0111 P1.3~P1.0列1110
case 0x7d:key=13;break;//第四行第二列 P1.7~P1.4行0111 P1.3~P1.0列1101
case 0x7b:key=14;break;//第四行第三列 P1.7~P1.4行0111 P1.3~P1.0列1011
case 0x77:key=15;break;//第四行第四列 P1.7~P1.4行0111 P1.3~P1.0列0111
}
}
display();
}
}
}