单片机分类
分类
- 单片机由 内核、内存、IO 接口 组成。
- 单片机可根据 内核、位数、品牌 进行分类。
- 主流位数:8位、16位、32位
- 内核
- Intel —— 51 内核
- Ateml —— AVR 内核
- ARM —— ARM 内核
- 开发方式分类:库开发、底层开发
- 什么是微型计算机:以微处理器为核心的计算机称为微型计算机。
工作条件
- 单片机工作条件
- 供电(4.5V ~ 5.5V 直流电)
- 时钟(晶振)
- 复位:手动复位、上电复位
- 程序
- 计算机工作条件:供电、时钟、复位、reday
电路图
- 电路原理图
- 电源
- 负载:耗电的元件(元件三要素:标识、符号、参数)
- 控制:单片机、开关
- PCB 图
电流与电路
- 串联:电流相等,电压不同。
- 并联:电压相等,电流不同。
- 串联分压,并联分流。
- 交流变直流的过程称为:整流
- 直流遍交流的过程称为:逆变
- 欧姆定律及演变公式
51单片机内部结构
组成部分
- 中央处理单元:51 内核、CPU
- 内存:见下文
- IO口:见下文
- 中断控制器:5 种中断源(见下文)
- 定时/计数器:2 个 16 位的定时/计数器(见下文)
- 振荡器:内部振荡器(时钟 IC) + 外部时钟电路(晶振、电容)
- 总线控制器(略)
内存
- ROM:只读存储器,用于存储程序,断电数据不丢失。
- RAM:随机存储器,用于存储数据,断电数据清空。
- 标准 51 单片机 ROM(4KB)RAM(128B)
- 60S2 的 ROM(60KB)RAM(1280B)
- 存储器结构:哈佛结构、冯诺依曼结构
- 51单片机所有存储器均是 8位 的。
IO口
- 并行口:P0、P1、P2、P3
- 串行口:RxD、TxD
可编程芯片的开发框架
- 内部编程结构
- 外部引脚定义
- 系统组成
- 编程方法
外部引脚
灌电流:从外部流入单片机。
拉电流:从单片机流入外设。
每个 IO 引脚最大可接受灌电流为 20mA。
整个单片机最大可接受灌电流为 120mA。
单片机直驱:仅有单片机提供电流,不需要其他的驱动电路。
驱动电路:有些外设 > 120mA,可以使用驱动电路辅助单片机供电。
一个引脚实现多个功能:引脚复用
最小系统电路
- 供电电路
- 时钟电路
- 复位电路
- 最小系统电路的作用:为单片机提供基本工作条件的电路
- 如何判断单片机正常工作了?单片机执行了内部程序
工作模式
模式
- 标准双向口
- 强推挽输出(强推):提高了单片机的 IO 扣的拉电流
- 开漏模式(略)
- 高阻模式(略)
模式参数(第一个值:M1,第二个值:M0)
00:标准双向口,灌电流
01:强推模式,拉电流
10:开漏模式
11:高阻模式
例:给 P1.0 设置成强推模式
1
2P1M1 = 0x00; // 0b 0000 0000
P1M0 = 0x01; // 0b 0000 0001
LED
外形
长正短负,箭头方向即为电流方向。
欧姆定律
- R = U/I
- I = U/R
- U = IR
逻辑运算
- 指定位清零,其他位不变:与运算,指定位和 0 相与,其他位和 1 相与。
- 指定位置 1,其他位不变:或运算,指定位和 1 相或,其他位和 0 相或。
- 指定位取反,其他位不变:异或,指定位和 1 异或,其他位和 0 异或。
按键
动态扫描步骤
1 | unsigned char key_scan() { |
时间碎片
1 | // 拆碎前 |
数码管与点阵屏
极
- 共阴:公共的负极
- 共阳:公共的正极
动态扫描
- 选位|选列
- 送段|送行
- 延时|延时
- 灭段|灭行
选位送段
- 数码管:高选位,低送段
- 点阵屏:高选列,低送行
sizeof
计算数组所占内存的大小。
计算数组元素个数:n = sizeof(arr) / sizeof(type for arr)
1
2int arr[] = {1,2,3,4,5};
int n = sizeof(arr) / sizeof(int);
蜂鸣器
发声原理:不断切换高低电平。
有源/无源:是否有震荡源。
给定频率输出声音:
- 给定频率求周期:5Hz,200ms
- 给定周期求频率:20ms,50Hz
- GMK:1GHz = 1000MHz,1MHz = 1000KHz,1KHz = 1000Hz
- smu:1s = 1000ms,1ms = 1000 us(1m = 1kms = 1mus)
人耳可听见的声音频率范围:5 Hz ~ 20 KHz(200ms ~ 50us)
例题:用蜂鸣器发出一个 440Hz 的声音,写出 TH0 和 TL0 的值。
1
2TH0 = (65536 - 1000000 / 440 / 2) / 256;
TL0 = (65536 - 500000 / 440) % 256;
中断
定义
- 中断定义:打断 CPU 当前工作的一个事件。事件的集合称为中断源。
- 5 个中断源
- 外部中断类
- 外部中断 0
- 外部中断 1
- 定时计数器类
- 定时计数器 0 中断
- 定时计数器 1 中断
- 串行类:串行中断
- 外部中断类
- 数字信号
- 高电平
- 低电平
- 上升沿
- 下降沿
- 51 单片机里只支持低电平、下降沿的外部中断。
外部中断
步骤
- 开中断
- 设置中断请求模式
- 中断处理子函数
开外部中断
IE 寄存器:可以位寻址
表
位 8 7 6 5 4 3 2 1 名称 EA ES ET1 EX1 ET0 EX0 0-关,1-开
设置外部中断请求类型
TCON:可以位寻址
表
位 8 7 6 5 4 3 2 1 名称 IE1 IT1 IE0 IT0 IT0/IT1:设置请求信号类型。0-低电平 1-下降沿。
IE0/IE1:使能信号。
中断处理子函数
- 特点
- 无带入值、无返回值。
- 中断处理子函数不可被其他函数调用,由 CPU 自动调用。
- 无需声明,直接使用。
- 必须要有中断向量号。
- 中断向量号
- 中断向量和中断向量号不是同一个东西,中断向量是地址,中断向量号是地址别名。
- 中断向量用于标识中断源类型。
- 关键字:interrupt
- 中断向量号
- 0 - 外部中断 0
- 1 - 定时计数器 0 中断
- 2 - 外部中断 1
- 3 - 定时计数器 1 中断
- 4 - 串行口
- 特点
例题:设计一个是用外部中断 0 下降沿触发的程序。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
bit flag = 0;
void init() {
EA = EX1 = IT0 = 1;
}
void main() {
init();
while(1) {
if (flag) {
flag = 0;
// 1000 行代码
}
}
}
void inter() interrupt 0 {
EX0 = 0;
flag = 1;
EX0 = 1;
}
定时计数器
知识点
- 51 单片机里有两个 16 位的定时计数器。
- 16 位定时计数器最大计算能力:65536(0~65535)
- 分类
- 加法计数器(51):计数初值 = 最大计数值 - 计数值。
- 减法计数器:计数初值 = 计数值
- 工作模式
- 定时模式
- 计数模式
- 工作方式:方式0 ~ 方式3(方式1最常用)
- 方式 0:13 位。
- 方式 1:16 位。
- 方式 2:8 位,有 8 位自动装载。
- 方式 3(略)
步骤
模式方式设置
TMOD 寄存器:不可进行位寻址
表
8 7 6 5 4 3 2 1 GATE C/~T M1 M0 GATE C/~T M1 M0 GATE:门控信。0-软件开启,1-硬件开启。
C/~T:工作模式。0-定时模式,1-计数模式。
M1M0:工作方式
- 00-方式0
- 01-方式1(常用)
- 10-方式2
- 11-方式3
写入计数初值
寄存器:TH0、TH1、TL0、TL1
表
T1高 8 位 T1低 8 位 T0高 8 位 T0低 8 位 TH1 TL1 TH0 TL0 计算高 8 位:计数初值 / 256
计算低 8 位:计数初值 % 256
开启定时计数器
寄存器:TCON
表
8 7 6 5 4 3 2 1 TF1 TR1 TF0 TR0 IE1 IT1 IE0 IT0 TF1/TF0:溢出标志位
TR1/TR0:定时计数器开关 0-关 1-开
查询法:设置一个计数器 T0,计数 3 次为一个周期,每个周期切换一次 LED(P1.0) 的亮灭状态。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
sbit LED = P1 ^ 0;
void init() {
LED = 1;
TMOD = 0x05;
TH0 = (65536 - 3) / 256;
TL0 = (65536 - 3) % 256;
TR0 = 1;
}
void main() {
init();
while(1) {
if (TF0) {
TR0 = TF0 = 0;
TH0 = (65536 - 3) / 256;
TL0 = (65536 - 3) % 256;
LED = ~LED;
TR0 = 1;
}
}
}定时计数器中断
开中断:IE
中断处理子函数
程序1:设置一个定时器 T0,每隔 3 秒切换一次 LED(P1.0) 的亮灭状态。
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
sbit LED = P1 ^ 0;
void init() {
LED = 1;
TMOD = 0x01;
TH0 = (65536 - 50000) / 256;
TL0 = (65536 - 50000) % 256;
EA = ET0 = TR0 = 1;
}
void main() {
init();
while(1);
}
// 马
void timer() interrupt 1 {
static unsigned char c = 0;
c = ++c % 60;
if (!c) LED = ~LED;
else {
TR0 = 0;
TH0 = (65536 - 50000) / 256;
TL0 = (65536 - 50000) % 256;
TR0 = 1;
}
}
// 刘
void timer() interrupt 1 {
static unsigned char c = 0;
TR0 = 0;
TH0 = (65536 - 50000) / 256;
TL0 = (65536 - 50000) % 256;
if (++c == 60) {
c = 0;
LED = ~LED;
}
TR0 = 1;
}程序2:设置一个定时器 T0,每隔 2 秒切换一次 LED_BLUE(P1.0) 的亮灭状态。每隔 3 秒切换一次 LED_RED(P1.1) 的亮灭状态。
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
sbit LED_BLUE = P1 ^ 0;
sbit LED_RED = P1 ^ 1;
bit F2 = F3 = 0;
void init() {
LED_BLUE = LED_RED = 1;
TMOD = 0x01;
TH0 = (65536 - 50000) / 256;
TL0 = (65536 - 50000) % 256;
EA = ET0 = TR0 = 1;
}
void main() {
init();
while(1);
}
void timer() interrupt 1 {
static unsigned char c = 0;
c = ++c % 120;
if (!(c % 40)) LED_BLUE = ~LED_BLUE;
else if (!(c % 60)) LED_RED = ~LED_RED;
else {
TR0 = 0;
TH0 = (65536 - 50000) / 256;
TL0 = (65536 - 50000) % 256;
TR0 = 1;
}
}
void timer() interrupt 1 {
static unsigned char c = 0,k = 0;
TR0 = 0;
TH0 = (65536 - 50000) / 256;
TL0 = (65536 - 50000) % 256;
if (++k == 40) {
k = 0;
LED_BLUE = ~LED_BLUE;
}
if (++c == 60) {
c = 0;
LED_RED = ~LED_RED;
}
TR0 = 1;
}
频率与周期
考点
- 给定频率求周期:5Hz,200ms
- 给定周期求频率:20ms,50Hz
时钟周期
- 时钟电路中晶振的周期即为时钟周期。
- 晶振频率 12MHz,时钟周期是:1s/12MHz = 1ms/12KHz = 1us/12Hz = 1/12us
机器周期
- 一个机器周期 = 12个时钟周期
- 晶振频率 12MHz,机器周期是:1us