1.单片机引脚、晶振、复位的作用

在这里插入图片描述

  • 复位电路:,复位是单片机的初始化操作。单片机启动时都需要先付薇,其作用是“清零”,也就是CPU和其他部件处于一个确定的初始状态,并从这个初始状态开始。
  • 复位实质上是单片机的复位脚保持很短时间的高电平,按键复位就是通过按键接高电平(按一下的时间已经足够)
  • 时钟电路(晶振):产生时间信号,使单片机按照一定的时间规律进行指令,晶振频率越高,时钟信号的周期就小,单片机运行也就越快。

在这里插入图片描述

  • 32个I/O口

  • P1.0 ~ P1.7 对应1 ~ 8 号引脚

  • P2.0 ~ P2.7 对应21 ~ 28 号引脚

  • P3.0 ~ P3.7 对应10 ~ 17 号引脚

  • P0.0 ~ P0.7 对应39 ~ 32 号引脚
    其中,P3口除作标准I/O口外,还可以将每一位用于第二功能:
    在这里插入图片描述
    其他引脚功能:
    在这里插入图片描述

2.流水灯原理图

在这里插入图片描述

  • D1~D8为发光二极管(LED),由于LED工作时能承受的电流很小,所以后面接在PR1上,PR1是一个排阻,电阻的大小一般为100Ω左右,以防止电流过大击穿二极管,P20-P27是接单片机的P2.0-P2.7的引脚,Vcc接高电平,所以电流从右向左流,要想LED导通,仅需引脚处为低电平,两端形成电位差,LED被点亮
  • 所以通过编程控制P2口的8个引脚,使他们周期性的输出高电平、低电平并延时,即可使LED闪烁,构成流水灯。

3.单片机的周期

  • 时钟周期:

也称振荡周期,是时钟频率的倒数,就看晶振是多少HZ的,若是12MHZ的,时钟周期就是1/12微秒,他是单片机中最小的时间单位,在一个时钟周期内单片机仅能完成一个最基本的动作。

  • 机器周期:

是单片机的基本操作周期,为时钟周期的12倍,在一个机器周期内可以完成一个取指令的动作。

  • 指令周期:

指单片机完成一条指令所需的时间,一般为4个机器周期。

4.延时函数的编写

1
2
3
4
5
6
7
void delay()
{
unsigned int x,y; //定义无符号的int型x,y
for(x = 1000;x>0;x--)
for(y=110;y>0;y--);

}
  • 每执行一次x-1,y就要从110逐步-1,直到减小到0,x共要自减1000次,总耗时约为1秒(这个时间会有误差,如果要精确延时,后面讲到中断再说明)
  • 如果一个程序里需要不同的延时时间,就需要用带参数的延时函数
1
2
3
4
5
6
7
void delay(unsigned int z)
{
unsigned int x,y; //定义无符号的int型x,y
for(x = z;x>0;x--)
for(y=110;y>0;y--);

}

5.使用“位操作”控制流水灯

  • 编程思路:“位操作”就是控制单独的一个I/O口,使该引脚输出高电平或低电平,来驱动与该引脚相连的元器件发生相应的动作。
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
#include<reg52.h>
sbit led0 = P2^0; // sbit是定义位的关键字,一个引脚就是一位,P2^0代表P2.0引脚,以此类推
sbit led1 = P2^1;
sbit led1 = P2^2;
sbit led1 = P2^3;
sbit led1 = P2^4;
sbit led1 = P2^5;
sbit led1 = P2^6;
sbit led1 = P2^7;
void delay(unsigend z);
void main()
{
led0 = 0; //此时P2.0引脚为低电平,LED点亮
delay(500); //延时500毫秒
led0 = 1; //将P2.0引脚为低电平,LED熄灭

led1 = 0;
delay(500);
led1 = 1;
led2 = 0;delay(500);led2=1;led3=0;delay(500);led3=1;
led4 = 0;delay(500);led4=1;led5=0;delay(500);led5=1;
led6 = 0;delay(500);led6=1;led7=0;delay(500);led7=1;
}
void delay(unsigned z)
{
unsigned x,y;
for(x = z;x>0;x--)
for(y = 110;y>0;y--);
}
  • 按照上一篇的烧写方法就可以烧入单片机,观察到流水灯闪烁。

6.使用字节控制(并行I/O口控制)流水灯

  • 编程思路:51系列单片机是8位单片机,每一组端口共有8个引脚,每个引脚可输出一个电平(0/1),一组端口可同时输出8个电平,正好构成一个字节。用字节操作来控制同时点亮几个流水灯的流动,要比位操作简单的多,即要点亮D2,D4,D6,D8,只需要P2端口从高位P2.7-P2.0 输出 0101 0101,将这8位二进制数转化为十六进制位0X55,只需要P2 = 0X55就行了。
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
#include<reg52.h>
#defined LED P2; //宏定义 LED表示端口P2
void delay(unsigned int z)//延时函数的另一种写法
{
while(z--);
}
void main()
{
LED = 0xlf; //0xlf = 0001 1111
delay(30000);
LED = 0x8f; //0x8f = 1000 1111
delay(30000);
LED = 0xc7; //0xc7 = 1100 0111
delay(30000);
LED = 0xe3; //0xe3 = 1110 0011
delay(30000);
LED = 0xf1; //0xf1 = 1111 0001
delay(30000);
LED = 0xf8; //0xf8 = 1111 1000
delay(30000);
LED = 0x7c; //0x7c = 0111 1100
delay(30000);
LED = 0x3e; //0x3e = 0011 1110
delay(30000);
}

7.使用数组控制流水灯

  • 定义一个char类型(一个字节)的数组存放每个十六进制数,这样用一个for循环就可以循环赋值并延时
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<reg52.h>
unsigned char table[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//点亮第1、2、3、4···个灯的十六进制代码传入
void delay(unsigned int z)
{
unsigned int x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
void main()
{
for(i=0;i<8;i++)
{
P2 = table[i];
delay(500);
}
}