蓝桥杯

[TOC]


蓝桥杯

image-20220903175753217
1
2
3
4
5
#include "reg52.h"

sfr P4 = 0xc0; // reg52.h 中没有定义 P4 寄存器故自己定义
sbit P3_6 = P4^2; // 位定义用 P3_6 在程序中替换 P4^2的功能
sbit P3_7 = P4^4; // 同上
1
2
3
4
#include “stc15f2k60s2.h”	// 该文件已定义 P4 寄存器故无需重复定义

sbit P3_6 = P4^2; // 位定义用 P3_6 在程序中替换 P4^2 的功能
sbit P3_7 = P4^4; // 同上

基础编程——位运算

基本位运算符

取反、按位与、按位或、按位异或

基本位运算

掩码

讲各个位的值初始化为想要的样子,对于74HC138译码器,我们初始化为

1
2
3
//initial value is not sure
P2 &= 0x1f;
//P2 = 0001 1111

通过掩码 0x1f 我们可以让 38 译码器的 ABC 三个引脚初始化为 000 。

设置位

通过或运算符可以设置各个位的值,对于 38 译码器,我们想要使之使能Y4,需要设置 ABC 为 001 ,可以使用

1
2
3
//set P2 = 0001 1111
P2 |= 0x80;
//get P2 = 1000 1111
关闭位

关闭 P2 的

LED

题目要求:

在CT107D单片机综合训练平台上实现LED的基本控制:

首先让8路LED指示灯闪烁3遍然后熄灭;

接着依次点亮LED指

示灯;

最后依次熄灭指示灯;

程序循环实现上述功能。

考点:

74HC138、74HC573和74HC02三个数字IC;C51开发方式——IO口扩展

笔记:

​ C51开发的两种方式:IO口扩展和存储器映射扩展

​ 跳线帽\(J3\):WR引脚,存储器映射扩展;接地,IO扩展

image-20211030180455602

三八译码器:三个输入控制八路互斥的低有效输出——七位高一位低

使用方法:

  • ABC三个输入端控制Y0-Y7八个输出端
  • 输入端输入的三位二进制数的十进制形式对应Y的编号
    • \(CBA=(100)_2=(4)_{10} \Rightarrow Y(4)\)
  • 片选已经完成

image-20211030180601344

锁存器:八路三态输出的非反转透明锁存器

使用方法:

  • 控制引脚:LE,低电平锁存,高电平导通
  • 导通时D和Q的电平一致
  • 片选已经完成

image-20211030180521683

使用方法:

  • 使用IO扩展,跳线帽设置为为GND

  • \((WR->GND)J13\)

    \(74HC138(Y4)->(Y4)74HC02(Y4C)->(LE)M74HC573MIR\)

    \(\sf{使用}:WR=0;\,Y4=0\,\sf{ 时},\, Y4C=1\)

左移运算

1
2
3
4
5
6
7
int P0 = 0;
for(int i=1;i<=8;i++)
{
P0 = (0xff <<i);
cout << P0 << " ";
}
//结果:510 1020 2040 4080 8160 16320 32640 65280
1
2
3
4
5
6
7
8
9
10
11
void Delay100ms()		//@11.0592MHz
{
unsigned char i, j;

i = 180;
j = 73;
do
{
while (--j);
} while (--i);
}

代码:

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
#include "reg52.h"

sbit HC138_A = P2^5;
sbit HC138_B = P2^6;
sbit HC138_C = P2^7;

void Delay(unsigned int time)
{
while(time--);
while(time--);
}

void LEDrunning()
{
unsigned char i;
//通过配置三八译码器使得锁存器导通,此时单片机P0口电压直接对应LED灯的电压
HC138_C = 1;
HC138_B = 0;
HC138_A = 0;

//将P0口全部设为低电平,点亮所有LED灯
for(i=0;i<3;i++)
{
P0 = 0x00;
Delay(60000);
Delay(60000);
P0 = 0xff;
Delay(60000);
Delay(60000);
}

for(i=1;i<=8;i++)
{
P0 = 0xff<<i;
Delay(60000);
Delay(60000);
}

for(i=1;i<=8;i++)
{
P0 = ~(0xff<<i);
Delay(60000);
Delay(60000);
}

}
void mian()
{
while(1)
{
LEDrunning();
}
}

蜂鸣器和继电器

题目要求:

在CT107D单片机综合训练平台上实现蜂鸣器与继电器的基本控制:

首先让8路LED指示灯闪烁3遍后熄灭;

接着依次点亮LED指示灯;

继电器吸合一会后断开;

然后依次熄灭LED指示灯;

蜂鸣器鸣叫会后关闭;

程序循环实现上述功能。

考点:

蜂鸣器和继电器的使用;继续使用上面的三个IC;ULN2003达林顿管——一个驱动管

笔记:

针脚选择BTN

代码:

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
void SelectHC138(unsigned char n)
{//通过三八译码器选择正确的锁存器;输入端口,配置相应锁存器
switch(n)
{
case 4:
HC138_C=1;
HC138_B=0;
HC138_A=0;
break;
case 5:
HC138_C=1;
HC138_B=0;
HC138_A=1;
break;
case 6:
HC138_C=1;
HC138_B=1;
HC138_A=0;
break;
case 7:
HC138_C=1;
HC138_B=1;
HC138_A=1;
break;
}//switch
}//void

image-20211030203349176

独立按键

题目要求:

考点:

  • 独立按键;矩阵键盘
  • 读取IO口电平
  • 按键消抖

笔记:

根据原理图可知:

image-20211030204322671

\(J5\)接2、3引脚,此时\(P30-P33\)四个单片机IO口分别接\(S7-S4\)四个独立按键再接\(GND\)

代码:

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
void DelayKey(unsigned char t)
{
while(t--);
}
void ScanKeys_Alone()
{
if(s7 == 0)
{
DelayKey(100);
if(s7 == 0)
{
L1 = 0;
while(s7 == 0);//我不理解?????
L1 = 1;
}
}//if外层
if(s6 == 0)
{
DelayKey(100);
if(s6 == 0)
{
L2 = 0;
while(s6 == 0);//我不理解?????
L2 = 1;
}
}//if外层
if(s5 == 0)
{
DelayKey(100);
if(s5 == 0)
{
L3 = 0;
while(s5 == 0);//我不理解?????
L3 = 1;
}
}//if外层
if(s4 == 0)
{
DelayKey(100);
if(s4 == 0)
{
L4 = 0;
while(s4 == 0);//我不理解?????
L4 = 1;
}
}//if外层

}
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include "reg52.h"

sbit s7 = P3^0;
sbit s6 = P3^1;
sbit s5 = P3^2;
sbit s4 = P3^3;

sbit L1 = P0^0;
sbit L2 = P0^1;
sbit L3 = P0^2;
sbit L4 = P0^3;
sbit L5 = P0^4;
sbit L6 = P0^5;


void SelectHC138(unsigned char n)
{//通过三八译码器选择正确的锁存器;输入端口,配置相应锁存器
switch(n)
{
case 4:
HC138_C=1;
HC138_B=0;
HC138_A=0;
break;
case 5:
HC138_C=1;
HC138_B=0;
HC138_A=1;
break;
case 6:
HC138_C=1;
HC138_B=1;
HC138_A=0;
break;
case 7:
HC138_C=1;
HC138_B=1;
HC138_A=1;
break;
}//switch
}//void

void DelayKey(unsigned char t)
{
while(t--);
}
void ScanKeys_Alone()
{
if(s7 == 0)
{
DelayKey(100);
if(s7 == 0)
{
L1 = 0;
while(s7 == 0);//我不理解?????
L1 = 1;
}
}//if外层
if(s6 == 0)
{
DelayKey(100);
if(s6 == 0)
{
L2 = 0;
while(s6 == 0);//我不理解?????
L2 = 1;
}
}//if外层
if(s5 == 0)
{
DelayKey(100);
if(s5 == 0)
{
L3 = 0;
while(s5 == 0);//我不理解?????
L3 = 1;
}
}//if外层
if(s4 == 0)
{
DelayKey(100);
if(s4 == 0)
{
L4 = 0;
while(s4 == 0);//我不理解?????
L4 = 1;
}
}//if外层

}

void main()
{
SelecHC138(4);//控制锁存器打开LED灯

while(1)
{
ScanKeys_Alone();
}

}

数码管

1
2
3
unsigned char code SegTab[]={0xc0,0xf9,0xa4,0xb0,0x99,
0x92,0x82,0xf8,0x80,0x90};
unsigned char code SegBuf[]={0xff,0xff,0xff,0xff,0xff,0xff};

数码管延时

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
void delay_dtms(uchar t)
{
int i;
for(i=0;i<t;i++){
unsigned char i, j;

i = 10;
j = 73;
do
{
while (--j);
} while (--i);
}//t=1时刷新频率可以到100Hz,即0.01ms

void delay_tms(uchar t)
{
int i;
for(i=0;i<t;i++){
unsigned char i, j;

i = 180;
j = 73;
do
{
while (--j);
} while (--i);
}//t=1时延时大约1ms

中断

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
/*===============初始化定时器0==================*/
void Init_Timer0()
{
TMOD = 0x01; //16位定时模式
TH0 = (65536 - 50000) / 256; //定时50ms
TL0 = (65536 - 50000) % 256;
ET0 = 1; //使能定时器T0中断
EA = 1; //使能总中断
TR0 = 1; //启动定时器T0
}
/*============定时器0中断服务函数===============*/
unsigned char count = 0;
void SeviceTimer0() interrupt 1
{
unsigned char i=1;
TH0 = (65536 - 50000) / 256;
TL0 = (65536 - 50000) % 256;
P0=0xff;
count++;
if(count == 40)
{
EGplay(i);
i++;
}
}

定时器计算

\[ 10ms=0.01s\\ \sf{计算机器周期数目:}\\x\frac{12}{11059200}=0.01\\ get\:x=9216=0x2400\\ so\:TH0=0x24,TL0=0x00; \]

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
void timer_0_ini()
{
TMOD = 0x01;
TH0 = 0xfc;
TL0 = 0x67;
TR0=1;
TF0=0;
}
unsigned char timer_0(unsigned int t)//@ t (ms)
{
unsigned char timer_0_tag = 0;
unsigned int cnt=0;
if(TF0==1)
{
TF0=0;
TH0 = 0xfc;
TL0 = 0x67;
cnt++;
if(cnt>=t)
{
cnt=0;
timer_0_tag=1;
return timer_0_tag=1;
}
}
else
return timer_0_tag;

}

通信

image-20211116001027941