读书笔记:十天学会51单片机

3,620 阅读13分钟

"好记性不如烂笔头",读书笔记系列是为了记录自己的读书心得,文章内容一部分是摘抄原文,一部分是自己的理解和总结

本篇文章记录的是,来自郭天祥老师的《十天学会51单片机》视频课

一、写在前面

前段时间我在网上买了块 51 单片机开发板

接下来的两周,我每天下班回到家的第一件事就是,跟着郭天祥老师的《十天学会51单片机》视频鼓捣一会儿,那阵子在我们家天天都能听到蜂鸣器滴滴滴~滴滴滴的声音

我当时买开发版的初衷是想了解:单片机是如何执行代码的?

了解单片机的执行过程,对下一阶段(操作系统)的学习有很大的帮助。因为操作系统最重要的任务之一,就是管理 CPU 执行多任务

但是,直到我能控制8位数码管显示数字以后,我才意识到,哦~ 原来这是偏实践类的课程,理论知识讲的比较少,这和我原定的目标相差甚远。

于是,后续课程的串口液晶屏啥的我就没有继续学了,在网上查了单片机原理作为本节课的补充。

本篇文章共包含两部分内容:

  • 一是课程简介,介绍郭天祥老师的《十天学会51单片机》每小讲的课程内容
  • 二是课程总结,主要是想聊聊我个人非常疑惑的一个问题,单片机是如何执行代码的?

接下来,我们先跟随郭天祥老师的脚步,一起来学习怎么控制单片机上的硬件

二、十天学会51单片机

郭天祥老师的《十天学会51单片机》课程一共有13讲,每一讲的内容都是基于配套的 TX-1C 开发板展开

因此,在介绍课程内容之前,我们有必要先来了解 TX-1C 开发板的构成

tx_1c.jpg

图片来源:拼夕夕卖家详情页

如图,从左到右分别是发光二极管1602液晶屏接口六位数码管,整块开发版的学习要点如下:

  • 了解最小系统必要条件:电源、晶振、复位电路
  • 控制任意I/O口:输出控制电平高低、输入检测电平高低
  • 掌握定时器的用法
  • 掌握外部中断、定时器中断、串口中断
  • 串口通信:单片机与单片机、单片机与计算机通信

课程内容大致是这些,从目录来看还是比较简单的。当我们具备控制这些简单设备的能力以后,其他复杂的功能原理上也都差不多

好,接下来我们开始上课

点亮一个发光管

课程第一讲,老师先进行个人介绍,然后讲了单片机的发展史,以及介绍单片机能做什么?

在课程结尾,老师带领我们点亮了一个发光二极管

点亮代码过于简单,我当时顺手把剩下的7个发光二极管一起点亮了,还做了一个流水灯的效果出来,代码如下:

#include <reg52.h>

sbit led1 = P1^0;
...// 中间还有 6 个灯,忽略重复代码
sbit led8 = P1^7;

unsigned int index = 0; //轮到第几个 LED 灯
unsigned int toggle = 1; // 1 表示开灯 0 表示关灯 

void main(){
    while(1){
	perform_once();// 控制发光二极管亮灭
	delay();// 休眠一段时间,代码实现省略
    }
}

void perform_once(){
    if(index>=8){ // 让每个发光二极管,一轮亮,一轮灭
	index = 0;
	toggle = toggle == 1 ? 0 : 1;
    }

    switch(index){
	case 0:led1 = toggle;
	...
	case 8:led8 = toggle;
    }
    index++; // 控制下一个发光二极管
}

编写完上述代码以后,我们在 Kiel 中将 c 文件编译打包成 .hex 文件

再通过 STC_ISP 软件烧录到开发板中,将板子重新上电就可以看到代码运行效果了

led.GIF

图片来源:自己拍的

控制蜂鸣器发声

第二讲老师教了我们怎么控制蜂鸣器发声

不过,在学习蜂鸣器之前,老师先接着上节课的内容,带我们一起实现了发光二极管的流水灯效果

唉嘿,流水灯效果我在上节课就搞定了,我可真是个懂得未雨绸缪挖地道的好孩子,骄傲

讲完流水灯的实现,老师才教了我们怎么去控制蜂鸣器,再往后就是蜂鸣器发声实战了,代码也很简单

#include <reg52.h>

sbit beep = P2^3; //蜂鸣器

void main(){
    while(1){
	perform_once();// 让蜂鸣器配合发光二极管,滴滴滴~
	delay();// 休眠一段时间
    }
}

void perform_once(){
    if(index>=8){ 
	index = 0;
	toggle = toggle == 1 ? 0 : 1;
    }
	
    beep = toggle;

}

我这儿偷了个懒,直接在原先控制发光二极管的基础上,增加了控制蜂鸣器的逻辑。让蜂鸣器当背景音乐,配合发光二极管流水灯一起发声

编写完上述代码以后,我们在 Kiel 中将 c 文件编译打包成 .hex 文件

再通过 STC_ISP 软件烧录到开发板中,将板子重新上电就可以看到代码运行效果了

蜂鸣器.GIF

图片来源:自己拍的

数码管、中断原理和定时器

第三讲的内容比较多,有中断、定时器的原理,还有数码管的控制显示,其中数码管的 ‘段选’ 和 ‘位选’ 让我反应了好一会才理解

接下来又是动手实践环节

我在之前的代码基础上加了数码管的显示逻辑,另外还单独写了一个检测外部中断的程序,这两段代码都比较长我就不放出来了,直接来看效果

数码管.GIF

图片来源:自己拍的

在后面的4 ~ 13讲的课程中,老师还教了:独立键盘矩阵键盘的控制,串口通信,1602液晶屏显示,I2C总线等内容

不过这几节课的视频我全部开2倍速看完的,视频中的代码我也没有动手实践

开倍速和没有写代码是因为,在上完 1~3 讲以后,我已经学会了:

  1. 如何控制输出电平进而控制发光二极管蜂鸣器
  2. 如何检测输入电平
  3. 如何使用中断、定时器

虽然东西不多,但学习目的已经达到了,再学会控制后面的几个元器件,对我来说意义不是很大

对剩下课程感兴趣的朋友,可以查看参考资料一栏中 “十天学会51单片机教程”

好了,课程简介部分到这里就先结束了

接下来的时间,我们来聊聊本篇文章中,我最感兴趣的话题:单片机是如何执行代码的?

三、单片机是如何执行代码的?

在之前几节课的实践过程中,不知道大家有没有注意到一个规律

我们每次写完代码,都需要先用 Kiel 软件,将 c 文件编译成 .hex 文件

再通过 STC_ISP 软件烧录到开发板中,然后板子重新上电,我们就能看到新代码运行的效果了

为什么简单操作几步就可以让单片机运行我们的新代码呢?

我们把前后流程捋一下,可以发现上述的操作流程,大致可以分为:编码编译烧录运行这四个阶段

想要了解单片机是怎么运行的,我们就需要知道,这几个阶段各自都做了哪些事情?

我们先来看第一步,编码阶段

编码阶段

编码阶段指的是把我们人类的想法,转换为编程语言来实现

比如我想让板子上的第一个发光二极管亮起来,用代码实现的话可以这样写:

#include <reg52.h>

sbit led1 = P1^0;

void main(){
    led1 = 0;
}

核心代码就一句话:'led1 = 0' ,非常的简单

编译阶段

当我们的需求(点亮第一个二极管)用编程语言实现了以后,接下来就是要把这段逻辑代码,翻译给单片机去执行

怎么翻译呢?

这就是编译器做的事情,大致流程是,先把源代码进行语法解析,然后再转化为各个平台的机器代码

具体到 51 单片机,Kiel 集成了编译器的功能,我们写完代码后,将工程的目标指令集设置为 MCS-51,然后就可以一键打包成 .hex 可执行文件,等待下一阶段烧录到单片机

这里有两个比较关键的点,什么是指令集,以及什么是 hex 文件?

我们先来看第一点,什么是指令集?

1、什么是指令集

我们都知道,芯片是由无数个功能不同的电路组合而来,而电路又只能通过开关来控制

那么,芯片厂商就需要告诉其他人,应该通过什么样的开关组合规则,才来控制这个芯片上不同的电路

控制芯片的规则,就被称为指令集。

比如,51单片机使用的是 MCS-51 指令集,这套指令集包含了:数据传送位操作逻辑运算及转移算术运算控制转移5个大类,共计111条指令

每条指令都是 0101010 这样的 01 组合,一条指令有多少位01,要看具体用什么指令

在51单片机的111条指令中,1字节指令共有49条,2字节指令共有45条,3字节指令共有17

详细的指令集可以查看参考资料

2、什么是 hex 文件

至于 Kiel 打包生成的 .hex 文件,我们可以用文本编辑器打开看看

hex.jpg

图片来源:课程视频截图

其实 hex 文件已经是编译过后得到的二进制组合了,里面的内容就是我们用 C51 写的业务代码,不过是被转换为一行行01,我们看不懂罢了

至于为什么显示的是十六进制,这是因为文本编辑器是以四个二进制当作一个单位读的,烧录到单片机还是以二进制来执行的

烧录阶段

在上一步的编译阶段,所有需要执行的指令都已经准备好,保存在 .hex 文件中

接下来,我们只需要使用 STC-ISP 软件,把这些二进制数据,传输给单片机的存储单元(EEPROM)就完事了

烧录的过程和原理我也不是很清楚,我个人是这样理解的,单片机存储单元是由许多电池组成的。烧录电路在碰到 0 时,就对电池放电;碰到 1 时,就对电池充电

对烧录原理感兴趣的朋友可以查看参考资料列出的,STC 51单片机烧录协议分析单片机为什么能直接烧录程序?这两篇文章

运行阶段

好,经过上一步的烧录后,现在单片机的 ROM 存储了是无数个高低电平,等待被执行

接着,我们按下开发板的电源键,板子上电, PC 寄存器电路默认指向 0000H 地址,通过传输电路,寻址寄存器得到第一条指令地址

然后,寻址寄存器ROM 取出第一条指令,传输给指令编码器解析

51的指令类型前面提过了,一共分为5大类:

  1. 数据传送:内部 RAM 或寄存器之间的数据传送、累加器A与外部 RAM 间的数据传送等等
  2. 位操作:位状态控制、位条件转移等等
  3. 逻辑预算及转移:与、或、亦或、循环移位、累加器清零等等
  4. 算术运算:带/不带进位的加法、带借位的加法、加1剪1、乘除等等
  5. 控制转移:子程序调用与返回、空操作、条件转移等等

指令编码器根据指令类型,调用不同的电路来执行任务。一条指令执行结束后,再次重复上述流程,根据 PC 寄存器指向的下一条指令地址,继续取指执行,永不停歇..

至此,编码编译烧录运行这四个阶段我们都已经分析完成,单片机的运行流程到这里就讲完了。

四、结语

在文章的结尾,我们来对本文的两部分内容做个总结

先说《十天学会51单片机》视频课程

对于我不熟悉的领域,我的期望通常是讲的越简单,越入门越好

这一点我觉得《十天学会51单片机》这节课做到了,老师讲的非常好,简单易懂,并且只需要有一点点语言基础就可以直接上手

但是,课程内容对单片机内部电路介绍的比较少,如果没有模电、数电、计组的基础,全部跟下来可能会觉得有点吃力

总的来说,郭天祥老师的《十天学会51单片机》课程,更适合已经有理论基础的科班学生上手实践

如果像我一样,妄想通过这门课来学习《微机原理及接口技术》的同学,可以放弃了,老老实实看书吧

再来看第二个部分,单片机是怎么执行代码的?

我们把单片机的运行流程分为编码编译烧录运行四个阶段,每个阶段做的事情在正文里都已经分析过了,我们这里再简单总结一下:

  • 编码阶段,将业务逻辑解释成代码实现
  • 编译阶段,将代码解释成目标平台的机器语言,也就是 01 组合
  • 烧录阶段,把编译结果的 01 组合,传输到机器的存储单元,每个 01 都被存储为高低电平。此阶段是'虚拟世界'转向'物理世界'的转折点
  • 运行阶段,接下来的事情全部发生在物理电路层面上。在振荡器电路的驱动下,芯片开始取指、译指、执行,根据执行结果,或修改寄存器改变时序电路逻辑,或刷新主存等其他操作,然后继续取指、译指、执行,无限循环,直到断电

好了,本篇文章到这里就全部结束了。各位大佬如果发现本文有写的不对的地方,还望及时指出,我会第一时间改正,感谢

全文完

五、参考资料