前提准备

  • 硬件设备

    • 51单片机开发板

    • Windows电脑(mac系统装个虚拟机)

  • 软件设备

    • Keil5(编写程序,必装)

    • STC-ISP(下载程序,必装)

    • 有道词典(选择安装)

    • 福昕阅读器(选择安装)

软件的安装

Keil5的安装

  • 途径一,在百度搜索Keil,进入官网keil官网

计数法

1
104 = 10 0000 (10)

单片机介绍

  • 单片机,英文MicroController Unit,简称MCU

  • 内部集成了CPU、RAM、ROM、定时器、中断系统、通讯接口等一系列电脑的常用硬件功能

  • 单片机的任务是信息采集(依靠传感器)、处理(依靠CPU)和硬件设备(例如电机,LED等)的控制

  • 单片机跟计算机相比,单片机算是一个袖珍版计算机,一个芯片就能构成完整的计算机系统。但在性能上,与计算机相差甚远,但单片机成本低、体积小、结构简单,在生活和工业控制领域大有所用

  • 同时,学习使用单片机是了解计算机原理与结构的最佳选择

单片机的应用领域

  • 单片机的使用领域已十分广泛,如智能仪表、实时工控、通讯设备、导航系统、家用电器等。各种产品一旦用上了单片机,就能起到使产品升级换代的功效,常在产品名称前冠以形容词——“智能型”,如智能型洗衣机等

STC89C52单片机

命名规则

单片机内部结构图

IO口的工作方式

准双向口

推挽输出

开漏输出

高阻输入

数码管

LED数码管

  • 数码管是一种简单、廉价的显示器,由多个发光二极管封装在一起组成“8”字型的器件

数码管引脚定义

  • 共阴极连接:二极管的阴极都连接到一个端口上

  • 共阳极连接:二极管的阳极都连接到一个端口上

  • 数码管段名称:从上开始顺时针分别为A、B、C、D、E、F,中间G段,再加上一个点DP段

  • 数码管引脚定义:左下角开始到右下角1-5,右上角到左上角6-10。

    • 上图的共阴极连接和共阳极连接对应的序号7、6、4、2、1、9、10、5都是与引脚号对应连接(就近引出)

    • LED段码:显示相应数字所对应的高低电平(二进制表示),共阴极要给阳码,共阳极要给阴码

    例如:共阴极,要显示6,阴极端接地,阳极端除了B、DP不亮其他都亮则段码为10111110

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    0x3F,
    0x06,
    0x5B,
    0x4F,
    0x66,
    0x7D,
    0x07,
    0x7F,
    0x6F,
    0x77,
    0x7C,
    0x39,
    0x5E,
    0x79,
    0x71,
    0x00

  • 四位一体数码管

  • 共阴极连接、共阳极连接

LS138译码器

  • 电子电工技术有学

74HC245(双向数据缓冲器)

静态数码管显示

  • 单个位置显示单个数字
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
#include <REGX52.H>
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00};
void Nixie(unsigned char location, unsigned int number);
void main()
{
Nixie(7,2);
//LED6 110
/*
P2_2=0;
P2_3=1;
P2_4=0;
P0=0x7D;
*/
/* P0_0=1;
P0_1=0;
P0_2=1;
P0_3=1;
P0_4=1;
P0_5=1;
P0_6=1;
P0_7=0;
*/
}

void Nixie(unsigned char location, unsigned int number)
{
switch(location)
{
case 1:P2_4=1;P2_3=1;P2_2=1;break;
case 2:P2_4=1;P2_3=1;P2_2=0;break;
case 3:P2_4=1;P2_3=0;P2_2=1;break;
case 4:P2_4=1;P2_3=0;P2_2=0;break;
case 5:P2_4=0;P2_3=1;P2_2=1;break;
case 6:P2_4=0;P2_3=1;P2_2=0;break;
case 7:P2_4=0;P2_3=0;P2_2=1;break;
case 8:P2_4=0;P2_3=0;P2_2=0;break;
}
P0=0x7D;

}

动态数码管显示

  • 多个位置显示不同数字

  • 当动态数码管显示无延时的时候,会出现显示错误

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
#include <REGX52.H>
unsigned char NixieTable[]={0x3F,0x06,0x5B,0x4F,0x66,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71,0x00};
void Nixie(unsigned char location, unsigned int number);

void Delay(unsigned int xms) //@12.000MHz
{
unsigned char i, j;
while(xms--)
{
i = 2;
j = 239;
do
{
while (--j);
} while (--i);
}

}

void main()
{
while(1)
{
Nixie(1,1);
// Delay(20);
Nixie(2,2);
// Delay(20);
Nixie(3,3);
// Delay(20);
}

//LED6 110
/*
P2_2=0;
P2_3=1;
P2_4=0;
P0=0x7D;
*/
/* P0_0=1;
P0_1=0;
P0_2=1;
P0_3=1;
P0_4=1;
P0_5=1;
P0_6=1;
P0_7=0;
*/
}

void Nixie(unsigned char location, unsigned int number)
{
switch(location)
{
case 1:P2_4=1;P2_3=1;P2_2=1;break;
case 2:P2_4=1;P2_3=1;P2_2=0;break;
case 3:P2_4=1;P2_3=0;P2_2=1;break;
case 4:P2_4=1;P2_3=0;P2_2=0;break;
case 5:P2_4=0;P2_3=1;P2_2=1;break;
case 6:P2_4=0;P2_3=1;P2_2=0;break;
case 7:P2_4=0;P2_3=0;P2_2=1;break;
case 8:P2_4=0;P2_3=0;P2_2=0;break;
}
P0=NixieTable[number];

}

  • 这时需要消影

位选 段选 位选 段选 位选 段选

两个位选之间夹着一个段选,会导致段选与位选匹配不一致

这时需要

位选 段选 清零 位选 段选 清零 位选 段选 清零

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void Nixie(unsigned char location, unsigned int number)
{
switch(location)
{
case 1:P2_4=1;P2_3=1;P2_2=1;break;
case 2:P2_4=1;P2_3=1;P2_2=0;break;
case 3:P2_4=1;P2_3=0;P2_2=1;break;
case 4:P2_4=1;P2_3=0;P2_2=0;break;
case 5:P2_4=0;P2_3=1;P2_2=1;break;
case 6:P2_4=0;P2_3=1;P2_2=0;break;
case 7:P2_4=0;P2_3=0;P2_2=1;break;
case 8:P2_4=0;P2_3=0;P2_2=0;break;
}
P0=NixieTable[number];
Delay(1); #延迟清零,为了让灯光更亮
P0=0x00; #清零,消影
}

数码管驱动方式

  • 单片机直接扫描:硬件设备简单,但会耗费大量的单片机CPU时间

  • 专用驱动芯片:内部自带显存、扫描电路,单片机只需要告诉它显示什么即可

模块化编程

介绍

  • 传统方式编程:所有的函数均放在main.c里,若使用的模块比较多,则一个文件内会有很多的代码,不利于代码的组织和管理,而且很影响编程者的思路

  • 模块化编程:把各个模块的代码放在不同的.c文件里,在.h文件里提供外部可调用函数的声明,其它.c文件想使用其中的代码时,只需要#include "XXX.h"文件即可。使用模块化编程可极大的提高代码的可阅读性、可维护性、可移植性等

  • 模块化编程的注意事项

    • c文件:函数、变量的定义

    • h文件:可被外部调用的函数、变量的声明

    • 任何自定义的变量、函数在调用前必须有定义或声明(同一个.c)

    • 使用到的自定义函数的.c文件必须添加到工程参与编译

      文件必须要添加到该位置上

    • 使用到的.h文件必须要放在编译器可寻找到的地方(工程文件夹根目录、安装目录、自定义)

      .h的路径要在该图中指明

C语言的预编译

  • C语言的预编译以#开头,作用是在真正的编译开始之前,对代码做一些处理(预编译)

  • 此外还有#ifdef,#if,#else,#elif,#undef等

任务

  • 将动态数码管显示的main.c文件转换为模块化编程

LCD1602调试工具

  • 使用LCD1602液晶屏作为调试窗口,提供类似printf函数的功能,可实时观察单片机内部数据的变换情况,便于调试和演示。

  • 本视频提供的LCD1602代码属于模块化的代码,使用者只需要知道所提供函数的作用和使用方法就可以很容易的使用LCD1602

矩阵键盘

介绍

  • 在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式

  • 采用逐行或逐列的“扫描”,就可以读出任何位置按键的状态

扫描

  • 数码管扫描(输出扫描)

    • 原理:显示第1位→显示第2位→显示第3位→……,然后快速循环这个过程,最终实现所有数码管同时显示的效果
  • 矩阵键盘扫描(输入扫描)

    • 原理:读取第1行(列)→读取第2行(列) →读取第3行(列) → ……,然后快速循环这个过程,最终实现所有按键同时检测的效果

    • 注意:按行扫描会影响到蜂鸣器

  • 以上两种扫描方式的共性:节省I/O口

定时器

  • 定时器介绍:51单片机的定时器属于单片机的内部资源,其电路的连接和运转均在单片机内部完成

  • 定时器作用:

    (1)用于计时系统,可实现软件计时,或者使程序每隔一固定时间完成一项操作

    (2)替代长时间的Delay,提高CPU的运行效率和处理速度

    (…)

  • 定时器框图

STC89C52定时器资源

  • 定时器个数:3个(T(Timer)0、T1、T2),T0和T1与传统的51单片机兼容,T2是此型号单片机增加的资源

  • 注意:定时器的资源和单片机的型号是关联在一起的,不同的型号可能会有不同的定时器个数和操作方式,但一般来说,T0和T1的操作方式是所有51单片机所共有的

定时器工作模式

  • STC89C52的T0和T1均有四种工作模式:

    模式0:13位定时器/计数器

    模式1:16位定时器/计数器(常用)

    模式2:8位自动重装模式

    模式3:两个8位计数器

    • 工作模式0框图:

    • 工作模式1框图:

      • 时钟部分:SYSclk:系统时钟,即晶振周期,本开发板上的晶振为12MH。T0Pin是外部引脚,时钟脉冲的另一提供方式

      • 计数单元:TL0(Timer low)、TH0(Timer High),16位的计数器,高字节TH0,低字节TL0,最高可以计数65535

      • 中断部分:在计数65535后,计数器产生溢出回到0,会置TF0标志,该标志会向中断系统申请中断

    • 工作模式2框图:

    • 工作模式3框图:

中断系统

  • 概念

  • 目的

  • 中断源和中断优先级

  • 中断嵌套

  • 中断流程

  • STC89C52中断源

    • 中断源个数:8个(外部中断0、定时器0中断、外部中断1、定时器1中断、串口中断、定时器2中断、外部中断2、外部中断3)

    • 中断优先级个数:4个

    • 中断号:

    • 注意:中断的资源和单片机的型号是关联在一起的,不同的型号可能会有不同的中断资源,例如中断源个数不同、中断优先级个数不同等等
  • 中断系统结构(以传统8051单片机介绍)

串口

串口介绍

  • 串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信。

  • 单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信,极大的扩展了单片机的应用范围,增强了单片机系统的硬件实力。

  • 51单片机内部自带UART(Universal Asynchronous Receiver
    Transmitter,通用异步收发器),可实现单片机的串口通信。

  • USB转串口

  • 陀螺仪:有加速度、传感器,可以检测当前模块所在的姿态角、加速度等信息

  • 蓝牙串口

    • 下面四根线是串口模块

    • 上面是狼牙模块

串口的接口及引脚定义

  • 串口的标准接口DB9总接口

  • 笔记本电脑已经没有该接口了,一般为HDMI接口

  • 台式机上一般会有DB8接口

DB9接口

  • 传输数据

  • DB9接口有分公母头,顾名思义,下图中上方的是DB9母头接口,下方是DB9公头接口

HDMI接口

  • 高清多媒体接口

VGA接口

  • 传输视频

USB接口

  • 左边是USB接口

  • 右边是串口接口,直接连接单片机

串口助手

  • 在电脑端需要串口助手才能收发串口数据

电平协议

  • 由于电平协议的存在,有的转换头与串口的电压不一样,如果直接连接就会造成其中一个硬件电压过大而烧掉。例如:如果将DB9接口直接与串口连接就会导致单片机烧掉

  • 电平标准是数据1和数据0的表达方式,是传输线缆中人为规定的电压与数据的对应关系,串口常用的电平标准有如下三种:

  • 常用电平协议

    1
    2
    3
    4
    5
    6
    (transistor-transistor logic(circuit) 晶体管晶体管逻辑电路)
    TTL电平:+5V表示1,0V表示0

    RS232电平:-3~-15V表示1,+3~+15V表示0

    RS485电平:两线压差+2~+6V表示1,-2~-6V表示0(差分信号)

硬件电路

  • 简单双向串口通信有两根通信线(发送端TXD和接收端RXD)

    • TXD(transmit exchange data)

    • RXD(resave exchange data)

  • TXD与RXD要交叉连接,如果是串口的延长线,那么就不需要交叉连接。

  • 当只需单向的数据传输时,可以直接一根通信线

  • 当电平标准不一致时,需要加电平转换芯片

常见通信串口比较

名称 引脚定义 通信方式 特点
UART TXD、RXD 全双工、异步 点对点通信
I²C SCL、SDA 半双工、同步 可挂载多个设备
SPI SCLK、MOSI、MISO、CS 全双工、同步 可挂载多个设备
1-Wire DQ 半双工、异步 可挂载多个设备
  • 此外还有:CAN、USB等

相关术语

  • 全双工:通信双方可以在同一时刻互相传输数据

  • 半双工:通信双方可以互相传输数据,但必须分时复用一根数据线

  • 单工:通信只能有一方发送到另一方,不能反向传输

  • 异步:通信双方各自约定通信速率

  • 同步:通信双方靠一根时钟线来约定通信速率

  • 总线:连接各个设备的数据传输线路(类似于一条马路,把路边各住户连接起来,使住户可以相互交流)

51单片机的UART

  • STC89C52有1个UART

  • STC89C52的UART有四种工作模式:

模式0:同步移位寄存器

模式1:8位UART,波特率可变(常用)

模式2:9位UART,波特率固定

模式3:9位UART,波特率可变

串口参数即时序图

  • 波特率:串口通信的速率(发送和接收各数据位的间隔时间)

  • 检验位:用于数据验证

  • 停止位:用于数据帧间隔

  • 8位数据格式

  • 9位数据格式

串口模式图

  • SBUF:串口数据缓存寄存器,物理上是两个独立的寄存器,但占用相同的地址。写操作时,写入的是发送寄存器,读操作时,读出的是接收寄存器

  • 虚线左边都是MCU内部里面的东西

串口和中断系统

串行口相关寄存器

LED点阵屏

LED点阵屏介绍

  • LED点阵屏由若干个独立的LED组成,LED以矩阵的形式排列,以灯珠亮灭来显示文字、图片、视频等。LED点阵屏广泛应用于各种公共场合,如汽车报站器、广告屏以及公告牌等

  • LED点阵屏分类

    • 按颜色:单色、双色、全彩

    • 按像素:88、1616等(大规模的LED点阵通常由很多个小点阵拼接而成)

    image-20240312171445704

    image-20240312171508904

显示原理

原理介绍

image-20240312171636233

  • LED点阵屏的结构类似于数码管,只不过是数码管把每一列的像素以“8”字型排列而已
image-20240312171641771 image-20240312171742116
  • LED点阵屏与数码管一样,有共阴和共阳两种接法,不同的接法对应的电路结构不同
  • LED点阵屏需要进行逐行或逐列扫描,才能使所有LED同时显示
  • 点阵屏的排列也是就近引出,距离哪个引脚近就接哪个引脚,在设计点阵屏的时候需要查询引脚标号

原理举例

image-20240312171641771
  • 想让第一行的灯亮,就要将⑨置1

    • 如果要想第一行第一列亮灯,那么就要将13置零;
    • 如果想第一行全亮,那就13、3、4…全置0
  • 逐行扫描

    • ⑨给1,其他行给0,然后看列将13给0,其他给1,这样第一行第一列就亮了

    • 接下来14给1,其他给0,将3给0,这样第二行第二列就亮了

    • 由于扫描很快,在点阵屏上就会看到斜着的一排灯都被点亮了

  • 逐列扫描

    • 13给0,其他给1,然后⑨给1其他给0

原理图

image-20240312174023597 image-20240312174251154 image-20240312175006810
  • 74HC595上有两个跳线帽,在使用LED点阵屏的时候要把JP595的跳线帽接上(也可以不接),然后JOE接GND才能使用

image-20240312174108767

  • 在keil5上写的程序仅仅只是对mcu的控制,通过对mcu的控制,间接控制点阵屏
  • LED的P0~P7是直接与mcu相连
  • LED的D0~D7是连接着74HC595

74HC595

image-20240312175006810
  • OE(output enabl)是输出使能端,低电平有效,所以JOE的OE端要接地
  • RCLK(register clock)寄存器时钟
  • SRCLR(serial)串行清零端
  • SRCLK()串行时钟
  • SER串行数据
  • QH’用来多片级联
image-20240312175322443
  • 具体操作

    1. SER保持0或1
    2. SERCLK时钟上升沿的时候
    3. SER保持的0或1就会被送入到图中的格子里面
    4. 当RCLK给个高电平时,左边格子的数据会一同被送入右边的格子中,然后就会QA、QB等就会出现高低电平
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    演示:
    SER = 0;
    SERCLK上升后
    0输入到格子里面

    SER = 1;
    SERCLK上升后
    1输入到格子里面

    现在从上到下依次为10,按照先进的在底下,后进的在上面

DS1302实时时钟