51单片机学习之路 —— 1.7 独立键盘
1 作业回顾
1 #include<reg52.h> 2 #define uchar unsigned char 3 #define uint unsigned int 4 sbit LED1 = P1^0; 5 sbit du = P2^6; 6 sbit we = P2^7; 7 uchar num,num1,num2,shi,ge; 8 uchar code leddata[]={ 9 10 0x3F, //"0" 11 0x06, //"1" 12 0x5B, //"2" 13 0x4F, //"3" 14 0x66, //"4" 15 0x6D, //"5" 16 0x7D, //"6" 17 0x07, //"7" 18 0x7F, //"8" 19 0x6F, //"9" 20 0x77, //"A" 21 0x7C, //"B" 22 0x39, //"C" 23 0x5E, //"D" 24 0x79, //"E" 25 0x71, //"F" 26 0x76, //"H" 27 0x38, //"L" 28 0x37, //"n" 29 0x3E, //"u" 30 0x73, //"P" 31 0x5C, //"o" 32 0x40, //"-" 33 0x00, //熄灭 34 0x00 //自定义 35 36 }; 37 38 void delay(uint xms) 39 { 40 uint i, j; 41 for(i=xms;i>0;i--) 42 for(j=114;j>0;j--); 43 } 44 void display(uchar shi, uchar ge) 45 { 46 we = 1; 47 P0 = 0xfe; //1111 1110 第一位为十位 48 we = 0; 49 P0 = 0xff; 50 du = 1; 51 P0 = leddata[shi]; 52 delay(5); 53 54 we = 1; 55 P0 = 0xfd; //1111 1101 第二位为个位 56 we = 0; 57 P0 = 0xff; 58 du = 1; 59 P0 = leddata[ge]; 60 delay(5); 61 62 } 63 64 void main() 65 { 66 TMOD = 0x11; //开两个定时器0和1 工作方式1 (0001 0001) 67 TH0 = (65536-45872)/256; 68 TL0 = (65536-45872)%256; 69 TH1 = (65536-45872)/256; 70 TL1 = (65536-45872)%256; 71 EA = 1; 72 ET0 = 1; 73 ET1 = 1; 74 TR0 = 1; 75 TR1 = 1; 76 while(1) 77 { 78 display(shi,ge); 79 } 80 81 } 82 83 84 void T0_time() interrupt 1 85 { 86 TH0 = (65536-45872)/256; 87 TL0 = (65536-45872)%256; 88 num1++; 89 if(num1==4) 90 { 91 num1 = 0; 92 LED1 = ~LED1; 93 } 94 } 95 96 void T1_time() interrupt 3 97 { 98 TH1 = (65536-45872)/256; 99 TL1 = (65536-45872)%256; 100 num2++; 101 if(num2==20) 102 { 103 num2 = 0; 104 num++; 105 if(num==60) 106 num=0; 107 shi = num/10; 108 ge = num%10; 109 } 110 } 111 112 113


2 独立键盘概念


s2 s3 s4 s5 为独立键盘与P3^0 P3^1 P3^2 P3^3 相连接
s2 = 0 就是s2被按下的意思


3 程序编写
1 先写个简单的
要求 按下s2按键 led点亮,再次按下熄灭
代码
1 #include <reg52.h> 2 #include <intrins.h> 3 #define uchar unsigned char 4 #define uint unsigned int 5 sbit LED1 = P1^0; 6 sbit S2 = P3^4; 7 void delay(uint z) 8 { 9 uint x,y; 10 for(x = z; x > 0; x--) 11 for(y = 114; y > 0 ; y--); 12 } 13 void main() 14 { 15 while(1) 16 { 17 if(S2==0) 18 { 19 delay(10); 20 if(S2==0) 21 LED1=~LED1; 22 while(!S2); 23 } 24 } 25 } 26 27 #include <reg52.h> 28 #include <intrins.h> 29 #define uchar unsigned char 30 #define uint unsigned int 31 sbit LED1 = P1^0; 32 sbit S2 = P3^4; 33 void delay(uint z) 34 { 35 uint x,y; 36 for(x = z; x > 0; x--) 37 for(y = 114; y > 0 ; y--); 38 } 39 void main() 40 { 41 while(1) 42 { 43 if(S2==0) 44 { 45 delay(10); 46 if(S2==0) 47 LED1=~LED1; 48 while(!S2); 49 } 50 } 51 }
分析:
1 ![]()
sbit S2 =P3^4;


在板子的原理图中,S2 接的是P3.4口不要写错了
2

假如S2 被按下,如果10ms后还是按下的
其中的语句delay(10) 学名叫去抖延时
还有while(!S2)分析以下
假如S2被按下,则!S2 = 1 就一直执行空语句;假如S2松开则可以往下执行。
2 来个复杂点的
1 要求:用数码管的前两位显示一个十进制数,变化范围为00到59
按键功能: S2 按下数值加一
S3 按下数值减一
S4 按下数值清零
S5 按下后启动自加每秒加一,再次按下后暂停并显示数值
2 代码:
1 #include <reg52.h> 2 #include <intrins.h> 3 #define uchar unsigned char 4 #define uint unsigned int 5 sbit LED1 = P1^0; 6 sbit S2 = P3^4; 7 sbit S3 = P3^5; 8 sbit S4 = P3^6; 9 sbit S5 = P3^7; 10 sbit du = P2^6; 11 sbit we = P2^7; 12 uchar numt0, num; 13 uchar code leddata[]={ 14 15 16 0x3F, //"0" 17 0x06, //"1" 18 0x5B, //"2" 19 0x4F, //"3" 20 0x66, //"4" 21 0x6D, //"5" 22 0x7D, //"6" 23 0x07, //"7" 24 0x7F, //"8" 25 0x6F, //"9" 26 0x77, //"A" 27 0x7C, //"B" 28 0x39, //"C" 29 0x5E, //"D" 30 0x79, //"E" 31 0x71, //"F" 32 0x76, //"H" 33 0x38, //"L" 34 0x37, //"n" 35 0x3E, //"u" 36 0x73, //"P" 37 0x5C, //"o" 38 0x40, //"-" 39 0x00, //熄灭 40 0x00 //自定义 41 42 }; 43 void delay(uint xms) 44 { 45 uint i,j; 46 for(i=xms;i>0;i--) 47 for(j=114;j>0;j--); 48 } 49 void init() 50 { 51 TMOD = 0x01; 52 TH0 = (65536-45872)/256; 53 TL0 = (65536-45872)%256; 54 EA = 1; 55 ET0 = 1; 56 } 57 void display(uchar i) 58 { 59 uchar shi, ge; 60 shi= i/10; 61 ge = i%10; 62 63 we = 1; 64 P0=0xfe; 65 we = 0; 66 P0 = 0xff; 67 du = 1; 68 P0=leddata[shi]; 69 du = 0; 70 delay(5); 71 72 we = 1; 73 P0 = 0xfd; 74 we = 0; 75 P0 = 0xff; 76 du = 1; 77 P0=leddata[ge]; 78 du = 0; 79 delay(5); 80 } 81 void keyscan() 82 { 83 if(S2==0) 84 { 85 delay(10); 86 if(S2==0) 87 { 88 num++; 89 if(num==60) 90 num=0; 91 while(!S2); 92 } 93 } 94 95 if(S3==0) 96 { 97 delay(10); 98 { 99 if(S3==0) 100 { 101 if(num==0) 102 num=60; 103 num--; 104 while(!S3); 105 } 106 } 107 } 108 109 if(S4==0) 110 { 111 delay(10); 112 if(S4==0) 113 { 114 num=0; 115 while(!S4); 116 } 117 } 118 119 if(S5==0) 120 { 121 delay(10); 122 if(S5==0) 123 { 124 while(!S5); 125 TR0=~TR0; 126 } 127 } 128 } 129 void main() 130 { 131 init(); 132 while(1) 133 { 134 keyscan(); 135 display(num); 136 } 137 } 138 void T0_time() interrupt 1 139 { 140 TH0=(65536-45872)/256; 141 TL0=(65536-45872)%256; 142 numt0++; 143 if(numt0==20) 144 { 145 numt0=0; 146 num++; 147 if(num==60) 148 num=0; 149 } 150 }
3 分析下:
要完成自加,需要定时器,我们需要写一个中断程序;
我建议写代码时用notepad,可以写的很清晰明白

这里我将代码主要写了7大块;看上去就清晰明白了许多吧。下面我们主要看几块代码
1

初始化函数的作用是选定定时器0工作模式1 并打开开关总断和定时器0中断
2
显示函数
P0 = 0xfe; // 1111 1110 第一位数码管 对应十位
P0 = 0xfd // 1111 1101 第二位数码管 对应个位
3 键盘块代码




对S2 功能是加一 但假如加满到60时将其置零
S3 功能是减一 ,先判断是否位0;为零置60
S4 功能清零
S5 S5是按下一次开始,在按下一次暂停,所以先while(!S5)
先判断S5是否按完毕了,一但手从S5按键拿开,就开始自加或暂停。
4 主函数

套个大循环,让他一直扫描键盘并显示即可。
5 中断

每一次中断时,先填值,保证每次定时都是50ms
每20个50ms 即1s,将numt0置零,num+1;num会用于显示函数中
假如大于59 将其置0;
4 作业
这一次程序写得挺多的,作业就算了,大家好好看看,多看看书,思考下。可以预习矩阵键盘
5 还是老样子,假如在博客中发现有什么错误和不足,请联系我,我尽量及时根正避免误导他人。
浙公网安备 33010602011771号