一、实验目的
1、了解矩阵键盘扫描方法。
2、了解数码管动态显示方法。
二、实验内容
1、完成读取矩阵键盘并静态显示。
2、完成完成读取矩阵键盘并动态显示。
三、实验原理
四、实验电路与程序
1、软件实验一:完成读取矩阵键盘并静态显示。
1)实验要求:单片机完成读取矩阵键盘并通过八段数码管静态显示按下的键盘编号。
2)实验目的:了解单片机读取矩阵键盘的方法;了解八段数码管静态显示的方法。
3)实验说明:通过本实验,可以了解单片机读取矩阵键盘的方法;了解八段数码管静态显示的方法。
4)、程序框图
5)、代码main.c
1. #include <reg52.h>
2. #include <tube.h>
3. #include <keyboard.h>
4. void main()
5. {
6. unsigned char tube_num;
7. while(1)
8. {
9. tube_num=keyboard_scan();
10. if(tube_num!=0xff)
11. {
12. tube_all(tube_num);
13. }
14. }
15. }
tube.h
1. #ifndef _TUBE_H
2. #define _TUBE_H
3. #include <reg52.h>
4. sbit WE = P2^7; //位定义数码管位选锁存器接口
5. sbit DU = P2^6; //位定义数码管段选锁存器接口
6. void delay1(unsigned int z);
7. void tube_all(unsigned char tube_num);
8. extern int timer_flag;
keyboard.h9. #ifndef _KEYBOARD_H
10. #define _KEYBOARD_H
11. #include <reg52.h>
12. void delay_kb(unsigned int z);
13. unsigned char keyboard_scan(void);
14. #endif
keyboard.c
1. #include <keyboard.h>
2. void delay_kb(unsigned int z)
3. {
4. unsigned int x,y;
5. for(x = z; x > 0; x–)
6. for(y = 114; y > 0 ; y–);
7. }
8.
9. unsigned char keyboard_scan(void)
10. {
11. unsigned char kb_val;
12. unsigned char return_val;
13. P3=0x0f;
14.
15. if((P3 & 0x0f)!=0x0f)//若有按键按下
16. {
17. delay_kb(5);//延时消抖
18. if((P3 & 0x0f)!=0x0f)
19. {
20. kb_val=P3 & 0x0f;//存行
21. P3= kb_val | 0xf0;//准备读取列
22. kb_val+=P3 & 0xf0;//读列
23. while( (P3 & 0xf0) != 0xf0 );//松手检测
24. switch(kb_val)
25. {
case 0xee: return_val = 0; break;
case 0xde: return_val = 1; break;
case 0xbe: return_val = 2; break;
case 0x7e: return_val = 3; break;
//第二行键值码
case 0xed: return_val = 4; break;
case 0xdd: return_val = 5; break;
case 0xbd: return_val = 6; break;
case 0x7d: return_val = 7; break;
//第三行键值码
case 0xeb: return_val = 8; break;
case 0xdb: return_val = 9; break;
case 0xbb: return_val = 10; break;
case 0x7b: return_val = 11; break;
//第四行键值码
case 0xe7: return_val = 12; break;
case 0xd7: return_val = 13; break;
case 0xb7: return_val = 14; break;
case 0x77: return_val = 15; break;
- }
- return return_val;
- }
- }
- else
- {
- return 0xff;
- }
- }
1、软件实验二:完成读取矩阵键盘并动态显示。
1)实验要求:单片机完成读取矩阵键盘并通过八段数码管动态显示按下的键盘编号,一共显示最近按下的八次键盘的编号。
2)实验目的:了解单片机读取矩阵键盘的方法;了解八段数码管动态显示的方法。
3)实验说明:通过本实验,可以了解单片机读取矩阵键盘的方法;了解八段数码管动态显示的方法。
4)、程序框图
5)、代码
main.c
- #include <reg52.h>
- #include <tube.h>
- #include <keyboard.h>
- void main()
- {
- unsigned char key_num[8]={0};
- unsigned char tube_num;
- unsigned char i=0;
- while(1)
- {
- tube_num=keyboard_scan();
- if(tube_num!=0xff)
- {
- if(i>=8)
- {
i=0;
- }
- key_num[i]=tube_num;
- i++;
- }
- tube_light(key_num);
- }
- }
tube.h
- #ifndef _TUBE_H
- #define _TUBE_H
- #include <reg52.h>
- sbit WE = P2^7; //位定义数码管位选锁存器接口
- sbit DU = P2^6; //位定义数码管段选锁存器接口
- void delay1(unsigned int z);
- void tube_light(unsigned char tube_num);
- extern int timer_flag;
- #endif
tube.c
- #include <tube.h>
- //共阴极数码管码表
- unsigned char code leddata[]={
0x3F, //"0"
0x06, //"1"
0x5B, //"2"
0x4F, //"3"
0x66, //"4"
0x6D, //"5"
0x7D, //"6"
0x07, //"7"
0x7F, //"8"
0x6F, //"9"
0x77, //"A"
0x7C, //"B"
0x39, //"C"
0x5E, //"D"
0x79, //"E"
0x71, //"F"
};
- unsigned char code weidata[]={
- 0xFE,
- 0xFD,
- 0xFB,
- 0xF7,
- 0xEF,
- 0xDF,
- 0xBF,
- 0x7F
- };
- void delay1(unsigned int z)
- {
- unsigned int x,y;
- for(x = z; x > 0; x–)
- for(y = 114; y > 0 ; y–);
- }
- void tube_light(unsigned char *number)
- {
- int i=0;
- for(i=0;i<8;i++)
- {
- P0=0;
- DU=1;
- //delay1(1);
- DU=0;
- //delay1(1);
- //位选
- P0=weidata[i];
- WE=1;
- //delay1(1);
- WE=0;
- //delay1(1);
- //段选
- P0=leddata[number[i]];
- DU=1;
- //delay1(1);
- DU=0;
- //delay1(5);
- }
- //防止最后一个过亮
- P0=0;
- DU=1;
- //delay1(1);
- DU=0;
- //delay1(1);
- //位选
- P0=weidata[7];
- WE=1;
- //delay1(1);
- WE=0;
- //delay1(1);
- //段选
- P0=0x00;
- DU=1;
- //delay1(1);
- DU=0;
- //delay1(5);
- }
keyboard.h
- #ifndef _KEYBOARD_H
- #define _KEYBOARD_H
- #include <reg52.h>
- void delay_kb(unsigned int z);
- unsigned char keyboard_scan(void);
- #endif
keyboard.c
- #include <keyboard.h>
- void delay_kb(unsigned int z)
- {
- unsigned int x,y;
- for(x = z; x > 0; x–)
- for(y = 114; y > 0 ; y–);
- }
- unsigned char keyboard_scan(void)
- {
- unsigned char kb_val;
- unsigned char return_val;
- P3=0x0f;
- if((P3 & 0x0f)!=0x0f)//若有按键按下
- {
- delay_kb(5);//延时消抖
- if((P3 & 0x0f)!=0x0f)
- {
- kb_val=P3 & 0x0f;//存行
- P3= kb_val | 0xf0;//准备读取列
- kb_val+=P3 & 0xf0;//读列
- while( (P3 & 0xf0) != 0xf0 );//松手检测
- switch(kb_val)
- {
case 0xee: return_val = 0; break;
case 0xde: return_val = 1; break;
case 0xbe: return_val = 2; break;
case 0x7e: return_val = 3; break;
//第二行键值码
case 0xed: return_val = 4; break;
case 0xdd: return_val = 5; break;
case 0xbd: return_val = 6; break;
case 0x7d: return_val = 7; break;
//第三行键值码
case 0xeb: return_val = 8; break;
case 0xdb: return_val = 9; break;
case 0xbb: return_val = 10; break;
case 0x7b: return_val = 11; break;
//第四行键值码
case 0xe7: return_val = 12; break;
case 0xd7: return_val = 13; break;
case 0xb7: return_val = 14; break;
case 0x77: return_val = 15; break;
1. }
2. return return_val;
3. }
4. }
5. else
6. {
7. return 0xff;
8. }
9.
10. }
五、实
验总结
- 动态数码管在位选之前,应该将段选清零,否则会有鬼影。
2.点亮第八个数码管之后应该熄灭它,否则在读取键盘时它还是亮的,会导致它的亮度和前七个数码管不一样。