抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

矩阵键盘

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*
time:2023-05-08
array buttons
*/
# include "reg51.h"

unsigned int num = 9;
unsigned char s[] = {0X3F, 0X06, 0X5B, 0X4F, 0X66, 0X6D, 0X7D, 0X07, 0X7F, 0X6F,0X76, 0X79, 0X38, 0X38, 0X3F,0XFF}; // 0-9
sbit P10=P1^0;
sbit P11=P1^1;
sbit P12=P1^2;
sbit P13=P1^3;
sbit P14=P1^4;
sbit P15=P1^5;
sbit P16=P1^6;
sbit P17=P1^7;
void Delay(unsigned int n)
{
unsigned int i, j;
for (i=0; i<n; i++)
{
for (j=0; j<120; j++);
}
}

void key_scan()
{
P1 = 0xff;
/*---------------cycle scan-----------------*/
P1=0xFF;
P13=0;
if(P17==0){Delay(20);while(P17==0);Delay(20);num=1;}
if(P16==0){Delay(20);while(P16==0);Delay(20);num=5;}
if(P15==0){Delay(20);while(P15==0);Delay(20);num=9;}
if(P14==0){Delay(20);while(P14==0);Delay(20);num=13;}

P1=0xFF;
P12=0;
if(P17==0){Delay(20);while(P17==0);Delay(20);num=2;}
if(P16==0){Delay(20);while(P16==0);Delay(20);num=6;}
if(P15==0){Delay(20);while(P15==0);Delay(20);num=10;}
if(P14==0){Delay(20);while(P14==0);Delay(20);num=14;}

P1=0xFF;
P11=0;
if(P17==0){Delay(20);while(P17==0);Delay(20);num=3;}
if(P16==0){Delay(20);while(P16==0);Delay(20);num=7;}
if(P15==0){Delay(20);while(P15==0);Delay(20);num=11;}
if(P14==0){Delay(20);while(P14==0);Delay(20);num=15;}

P1=0xFF;
P10=0;
if(P17==0){Delay(20);while(P17==0);Delay(20);num=4;}
if(P16==0){Delay(20);while(P16==0);Delay(20);num=8;}
if(P15==0){Delay(20);while(P15==0);Delay(20);num=12;}
if(P14==0){Delay(20);while(P14==0);Delay(20);num=16;}

}

void display()
{
P2 = s[num];
}

void main()
{
while(1)
{
key_scan();
display();
}

}

定时器

工作方式

  1. interrupt0,13位,当 INT0 引脚由高电平变为低电平时触发中断。

    • $X=8192-N\frac{12}{fosc}$​
    • 上次计数为0,要重复计数需要置零
  2. interrupt1,16位,当定时器 0 计数器溢出时触发中断。

    • $X=65536-N\frac{12}{fosc}$​
    • 上次计数值为0,要重复计数需要重置初值
  3. interrupt2,8位自动重置定时/计数器,当 INT1引脚由高电平变为低电平时触发中断。

  4. interrupt3,8位,只有T0才能使用,当定时器 1 计数器溢出时触发中断。

    • $X=256-N\frac{12}{fosc}$​
    • 计数器自动配置初值,不需要用户重置
  5. interrupt4,串口中断,当串口接收完成(RI)或发送完成(TI)时触发中断。

TMOD 寄存器

TMOD 的低 4 位控制定时器 0,高 4 位控制定时器 1,每个定时器都有两个工作模式可以选择

M0表示定时器0,M1表示定时器1

TMOD=0x20表示定时器1设置为2模式

TMOD=0x02表示定时器0设置为2模式

TMOD GATE C/T M1 M0 工作模式
0x00 0 0 0 0 模式 0:13 位计数器
0x01 0 0 0 1 模式 1:16 位计数器
0x02 0 0 1 0 模式 2:8 位自动重装载计数器
0x03 0 0 1 1 模式 3:16 位自动重装载计数器
0x04 0 1 0 0 模式 4:外部事件计数
0x05 0 1 0 1 模式 5:保留
0x06 0 1 1 0 模式 6:8 位 PWM 波形发生器
0x07 0 1 1 1 模式 7:16 位 PWM 波形发生器

TH和TL寄存器

  1. TH0/TL0​表示定时器0的高低八位
  2. TH1/TL1​表示定时器1的高低八位

IT寄存器

  1. IT0​,外部中断寄存器

  2. IT1​,外部中断寄存器

  3. IT0/IT1=0​​,低电平触发

  4. IT0/IT1=1​​,下降沿触发

中断寄存器

  1. ET0/ET1​,定时器中断使能寄存器,为1中断允许,为0不允许
  2. EA​,总中断使能寄存器,为1中断允许,为0不允许
  3. TR0/TR1​,定时器启动控制寄存器,为1时开始计数,为0时停止计数。

12MHz晶振对应的一个机器周期为1us,需要延时50ms,则从65536-50000开始计数,分为高低八位分别存储计数,当定时器0计数到65536溢出位时,触发timer_isr中断,执行函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
/*
time: 2023-05-08
timer
*/

# include "reg51.h"
unsigned char s[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
unsigned char count = 0, num = 0;

void inittimer()
{
TMOD = 0x01; // 0000 0001
TH0 = (65536 - 50000) / 256; // 50ms = 50000us initial value >> 8
TL0 = (65536 - 50000) % 256;
ET0 = 1; /* timer0 interrupt on*/
EA = 1; // interrupt on
TR0 = 1; //timer0 on
}
void display()
{
P2 = s[num];
if (num == 10)
{
num = 0;
}
}

/*
0 out interrupt0;
1 timer interrupt0;
2 out interrupt1;
3 timer interrupt1;
4 COM interrupt
*/
void timer_isr() interrupt 1
{
TH0 = (65536 - 50000) / 256; // 50ms = 50000us initial value >> 8
TL0 = (65536 - 50000) % 256;
count++;
if (count == 20) // setTime 1s
{
num++;
count = 0;
}

}
void main()
{
inittimer();
while(1)
{
display();
}
}

计数器

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/*
time:2023-05-08
8bit auto reset count
*/

# include "reg51.h"
unsigned char s[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f};
unsigned char num = 0;

void initcounter()
{
TMOD = 0X06; // 0000 0110 auto reset
TH0 = 255;
TL0 = 255;
ET0 = 1;
EA = 1;
TR0 = 1;
}

void display()
{
P2 = s[num];
if (num == 10)
{
num = 0;
}
}

void counter_isr() interrupt 1
{
num++;
}

void main()
{
initcounter();
while(1)
{
display();
}
}