注解目录

第一章《振南当年入门 C 语言和单片机的那些事儿》

1、注定堕入单片机

1.1 懵懂好奇的我

(小时候好奇的性格经常让我屁股开花。初中开始对计算机产生兴趣,并一发不可收拾。)

1.2 我的 C 语言学习经历

(上大学后自学 C 语言。遇到“能人”加入 ACM 竞赛。感觉 C 语言乐趣多多,程序如人生。)

1.3 C 语言的顶级赛事

(ACM 国际程序设计竞赛在东北被我们发扬光大。ACM 竞赛浙大的一段传奇佳话。振南在关注的 IOCCC 国际混乱 C 代码大赛。网吧包宿学 C 语言惊呆室友。)

1.4 岔路口上选择单片机

(搞纯软件还是搞单片机,这是一个抉择。鬼才杜撰拉我进入单片机快车道。)

1.5 窗户纸破了

(入门阶段的困惑,看破 C 语言与单片机之间的鸿沟。)

2 、看穿单片机

2.1 CPU 模型

(CISC 与 RISC 指令集。CPU 如何执行指令。汇编不是第一代编程语言,打孔纸带才是。)

2.2 存储器模型

(存储器就是一个指令和数据的容器。)

2.3 总线模型

(地址、数据和控制三大总线。贯穿整个单片机芯片的通路。)

2.4 外设模型

3、单片机跑起来

3.1 时钟系统

(时钟是单片机激励和血液。时钟频率不能无限提高。)

3.2 二进制

(为什么单片机采用二进制?振南告诉你如果单片机使用十进制会怎样?)

3.3 中断机制

(中断不是在给 CPU 捣乱。中断对于单片机为什么如何重要?)

注定堕入单片机

1.3 C语言的顶级赛事


在C语言专业课上,老师告诫我们:“C 语言,学得多精都不为过!”

很多人可能当时并没有完全理解这句话,但是我却深深的赞同。后来,我们的 ACM参赛组对编程的高涨热情感染了整个计算机学院,而这位C语言老师,也成为了我们的集训老师。再后来,我们的举动,带动了更多人参加ACM程序设计竞赛,学院、学校、乃至哈尔滨市、黑龙江省、东北三省。最终,国际ACM委员会委任我们学校为国际ACM中国东北赛区承办方(南方赛区承办方是浙大)。当时,全校到处都挂满了条幅:“Program Your World!”关于 ACM程序设计竞赛,当年还有一个关于浙大的传奇故事(浙大是当年的 ACM 世界总冠军)。我们知道写程序要经历编程、编译、查错修改、再编译,如此往复,若干次。这个往复的次数,与程序的难度与程序员的能力有很大关系。但是要做到所有一次成功,不能说不可能,但是极难!当年浙大参加总决赛,只剩十分钟,还有最后一道试题。参赛队员,打开记事本,直接写代码,直接提交,一次通过。这件事情,在圈里流传,也许有夸张的成分。但是,也足以显示我们与顶尖编程高手之间的巨大差距。

ACM竞赛,就是一群疯狂热爱计算机和编程的人们,一起正在作的事情。他们技术夯实,以不断猎奇、不断学习、不断完成新的目标为最大乐趣。除了 ACM,我私下还在关注另一个国际编程竞赛,IOCCC(国际混乱 C 代码大赛,官方网站 http://www.ioccc.org/,如图L2所女"供重免其实很多人都不知道这个比赛,我也是偶然间发现的。

振南技术干货集:振南当年入门C语言和单片机的那些事儿(2)-LMLPHP
图1.2 IOCCC官网历届比赛的消息公布

为什么会关注这样一个似乎不太正经的比赛?它不比算法,也不比代码的质量和风格,而是比谁的代码最乱,但是乱得要艺术,要能编译,要能实现正确的功能,如图 1.3 所示代码。

振南技术干货集:振南当年入门C语言和单片机的那些事儿(2)-LMLPHP
图1.3 第24届IOCCC(2015年)参赛代码

C语言代码还能写得如此任性?它体现了C语言在形式上的灵活性。当然,也不是单纯用代码来画画,就能被称为“乱”的,它有更多更深层的编程技巧。在这里,你可以看到C语言世界的无奇不有,各种挥挥洒洒的编程风格,以及映射出来的代码背后的那个“高手”我对C语言的学习热情是自始至终的,现在也还是在学习。记得大学时候我们宿舍有一个习惯,就是大考之后的晚上要倾巢出动去网吧包宿。当时流行玩CS,他们联网打得热闹。但是我对游戏毫无兴趣,就窝在一个靠边的位置上,上网看C语言代码。当时特别热衷逛编程网站,比如CSDN、PUDN 等,还喜欢把代码包全下载下来,看看别人的代码是怎么写的。看了代码,就想编译试试,于是就在网吧的电脑上安装VC6.0。室友过来看我在于啥,然后就惊呆了:“都考完了,你还在看C语言?”

1.4 岔路口上选择单片机


接下来,我继续学了C++,还有后来的 MATLABVHDL和Verlog(其实当时对硬件数字信号处理和仿真没什么概念,所以对于后者没有多少热情)。在学C++之前,我使用VC6.0已经有一定经验了,尤其是 MFC(当时有人建议我学。NET,比如C#,或者JAVA,说MFC已经过时,说MFC的意思就是Maybe Finally Canceled,即最终会被微软取消)。在系统学了C++之后,我对MFC(微软基础类库)有了深入的理解,开始阅读这方面的一些专业书籍,已经可以编写一些功能复杂的多层级的应用软件了。

到这里,我对编程的学习开始出现瓶颈,感觉到迷茫。C语言,很优雅,很强大,它的父集C++,面向对象的编程模式,可以开发专业的桌面软件。然后呢?似乎其他人用C#或者JAVA,开发软件的速度更快,作得更好。优雅不能当饭吃,在这种驱使下,我开始转入C#、JAVA、PHP、JSP、ASP这些上层应用级语言的学习,准备努力成为一个出色的软件工程师。在这个岔路口上,我遇到了我的启蒙老师,让我再一次打开好奇之门,从而走上了单片机和嵌人式技术的道路。他就是杜撰(化名):他以年龄最小,学历最低的身份,代表黑龙江省参加全国“挑战杯”科技创新大赛,凭自己设计的“仿生蛇”获得二等奖。获奖后,他把相关技术全部无偿给了国防科大。曾作为“小崔说事”栏目的特邀嘉宾接受专访。

关于“杜撰”和我当初进人单片机圈的经历,振南在本书“我与郭天祥的那些事儿”这一章有详细的描写。

他给我讲了很多关于单片机的事情,当时我对单片机完全不了解,只知道在他的“仿生蛇”里使用了单片机,而且单片机可以用C语言进行编程开发。单片机可以作出如此强大的东西,它远比在电脑上写桌面软件要有趣的多。正是这一点,深深吸引了我。

“你从51开始学吧,先焊个最小系统,然后点个灯!”

他给了我一个最小系统板和一些配件,还有一个叫《平凡的 C51 教》的电子文档。

“你就在我这学吧,有问题问我就行。”

我照着图 1.4 依葫芦画瓢的焊完了我人生中第一个电路版。虽然惨不忍睹,但是经杜撰过目之后,评价是“还不错,能用。”然后,就让我去C51。其实我对这个被称为“最小系统”的

振南技术干货集:振南当年入门C语言和单片机的那些事儿(2)-LMLPHP
图1.5 我的第一个单片机实验原理图(摘自《平凡的C51教程》)

电路为什么要用到这些元件,为什么要焊成这样,完全没有概念。带着诸多的迷惑不解开始了我的单片机 C 语言学习之旅,让我开始慢慢明白了 C 语言课上老师说的“C 语言是最贴近硬件的高级语言”这句话。

1.5 窗户纸破了


C语言,不论是变量、函数,还是分支循环,,乃至于算法,哪怕是最复杂的算法,这一切的体质都是CPU内核的指令执行和访存操作(RAM 和 ROM)。这是起初我对C语言的理解。那如何让C语言去操控硬件产生物理效果呢? 当时让我百思不得其解的是C语言是软件,发光二极管是物理上的硬件,软件是如何能够影响到物理世界的呢?小到点灯;大到“仿生蛇”产生一系列的动作;更大的比如控制火箭发动机点火。这曾经是我入门阶段无法逾越的一条思维鸿沟。

sfr P1 = 0x80;

void main(void)

{

   P1=0x55;

   While(1);

}

这是我亲手写过的第一个嵌人式C语言代码。它为我第一次揭示了 C 语言与硬件之间的交互方式一特殊功能寄存器(Special Function Register)。

register在标准C语言中是一个修饰符。一个变量在定义的时候如何加入这个修饰符,编译器便不会把它分配在内存里,而是放在CPU内部寄存器里。它的目的是为了加快变量的访问速度,尤其是那些需要被频繁访问的变量。

registerint i;

registerint sum = 0;

for(i= 1;i<= 100;i++ )

{

sum+=i;

}

上面这段代码(计算1到100 的和)的执行效率就比没有register 要高。51 单片机中的 SFR本质上也是一些随机存储单元,它们的访问速度很快(与CPU之间采用直接寻址)。但其又有特殊之处,它们都是一些电路(片内外设)的门户出入口。向这些寄存器写入数值,会直接影响相关电路的运行和输出。

51单片机的C语言中,为这些有特殊功能的寄存器,专门增加了一个修饰符一SFR。由它定义的标识(类似变量名),是可以访问到相应的特殊功能寄存器的,即片内外设电路的出入口,从而达到控制电路的目的。诸多的电路,具有各自的功能,它们纷纷留出寄存器接口,形成一系列的 SFR。通过CPU统一调配、有机控制,最终就可以完成复杂而有序的各种功能。这就是单片机,乃至于更高端的嵌入式 CPU,如ARM、DSP 等均采用的运作机理。而这些电路库同CPU内核,还有存储器,当然还有连接它们之间的总线,被塑封在一起(即封装),再把电路(片内外设)的相关外部信号通过引脚引出,这就是我们所看到的单片机芯片了。其实它就是一个完整的计算机。这大大拓宽了我起初对计算机认识的范畴:凡是拥有独立计算能力,具备输入输出和存储功能的设备都可以称为计算机。从某种范范的意义来说,算盘就是最原始的计算机,虽然它很大程度上依赖人的操作和辅助。

一直困惑我的谜雾终于变得清晰了。捅破了这层C语言软件与硬件之间的窗户纸,让我看清了硬件和嵌入式系统的本质。我觉得在硬件上,我将可以发挥更大的创造力。兴趣的泛滥再一次一发不可收拾。基于我在C语言方面的扎实基础和深入的理解,我对单片机的学习也较为顺利。理解了51 单片机的SFR,很多东西便变得简单了。对“C 语言,学得再精也不为过!”这句话有了更深的认识:C语言不光是一门语言,它影射出了整个计算机体系的运作机制,每当硬件出现进步,甚至是革命的时候,C语言必定会随之进化。(大家可以看一下GCC 编译器的选代历程,基本上就是主流编程语言行化的写照)

我们不应再为C语言如何操控硬件而产生疑惑,因为从我们使用C语言写下第一行代码的那一刻起,其实我们就已经在操控硬件了(内存访问、数据传送、CPU 执行就是硬件行为)。振南技术干货集:振南当年入门C语言和单片机的那些事儿(2)-LMLPHP

11-11 01:02