当前课程知识点:智能车制作:嵌入式系统 >  第四章 MCU外设与开发 >  4.6 嵌入式开发中的C语言(上) >  Video

返回《智能车制作:嵌入式系统》慕课在线视频课程列表

Video在线视频

Video

下一节:Video

返回《智能车制作:嵌入式系统》慕课在线视频列表

Video课程教案、知识点、字幕

各位同学大家好

我是清华大学工程物理系的曾鸣老师

欢迎大家回到我们ARM微控制器

与嵌入式系统的课程

我们的课程呢现在还是在第四章

继续讲解嵌入系统开发当中的一些知识和结构

在前面几节课呢我们讲了一个最典型的外设 IO

以及用怎样简单的几句话

来把这样几个灯给点起来

也就是我们传说中的

对一个嵌入式系统先点个灯

来掌握它的开发 接着我们认识了一下

嵌入式开发里面的一些基本的步骤 方法 概念

比如什么是开发板 什么是开发工具

什么是IDE集成环境 然后我们上节课顺了顺

在看起来很神奇的IDE集成环境的背后

编译器 汇编器 链接器是怎么工作的

怎么把我们写的代码中的简单的main函数

变成一个放在烧写在芯片里可以运行的程序

我们讲了这个比较fantasy的从一个main函数

到你看到点灯的过程

然后呢也讲了一个实际上reality

我们这个CPU怎么读取0或者1

按着一个一个时序来执行 那么今天这节课

我们进入一个 我个人认为也比较好玩的阶段

就是讲一讲嵌入式开发里头的C语言

我们这门课不是一个C语言的课 但是呢

在之前的这个学习里头我们讲过我们这门课

只要求大家有C语言的基础 而这节课

给大家讲一讲c语言的

基本的历史渊源 在嵌入式系统里的特点

或者说它跟我们以前所熟悉的

在计算机平台上的C语言编程 有点什么区别

那么C语言是一种什么样的语言呢

在嵌入式行业里应该说它用的是非常非常广泛

特别是在微控制器这样一种比较simple的

比较简单的这个嵌入式系统里头

绝大多数的时候都是C语言的天下

那么C语言它是一种结构化的语言

它写起来代码非常的小巧 更重要的呢

它非常容易地实现一些底层的

比如说按位的操作 所以很多时候

我们会把C语言称为一个 高阶的汇编语言

或者叫宏汇编语言

那么C语言除了这些特点以外

我们为什么要用C语言呢

我们任何一个程序员经常会分成很多很多派

有C派 有JAVA派 有C++派 甚至C#派

他们都会说出自己这个语言的特点

那么C语言经常会提到的一个特点呢

就是比如说它很可靠 它可剪裁

它非常容易在不同的平台和系统上移植

然后呢它又非常容易的维护

一方面因为它结构化

一方面它的比较对象比如说跟汇编比

在实现同样的底层功能的时候

它要容易维护的多 另外它非常的高效

我本人见过的同样的一个程序

用汇编语言的版本给我的代码

打印出来像一尺那么厚

但是用C语言写的代码都非常整齐 就是这个

很多个函数的集合体

所以这样的代码的维护工作量

如果你有亲身体验 你一定会特别容易感觉到

然后最后我想说 C语言有一个非常重要的精神

或者我们叫philosophy of C language(C语言的哲学)

就是编程人员 这个programmer 在座的诸位

你们应该知道 what you are doing

你们在做什么

换言之这件事情的背后在于

语言它不是智能的 它只是一个工具

作为一个编程语言的开发者

特别是当它非常地底层 非常强大的时候

当我们做一个嵌入式开发的时候

你能够通过它去直接掌控硬件里头的很多东西

所以你必须很清楚我写的每句话

它在时序上是怎么样的

它在电路上是如何工作的

那么我们有些同学

在编程当中会因为软件编程的错误

导致硬件上的损坏

比如把电路烧了把一个I/O给损毁了

这个时候呢 就是体现了C语言这种精神

但大家不要怕 我们可以一步一步往下试

那么回顾C语言 我们不是一门C语言的课

但还是应该看看它的历史

所以呢如果大家看一看这样两位这个

叫前人也好 叫这个大牛也好

左边的一位呢叫做肯·汤姆森(Ken Thompson)

右边的一位呢叫做丹尼斯.里奇(D.Ritchie)

这两个人应该来讲在某种意义上

是对计算机行业影响深远的人

丹尼斯.里奇(D.Ritchie)理论上是我们

实际上C语言这样一种语言的开发者

那么他在这个1969年到1973年这个年代里

工作在美国的贝尔实验室

那么开发C语言的故事为什么我要在这讲一讲

跟我这门课给大家讲的这个精神很有关

比如大家再看看这张图片

这张图片是一个非常有意思的小游戏

它的名字叫做space travel

是一个星际旅行的游戏

这个游戏从来没有商业发表过

它是一个爱好者写的游戏

它的作者呢就刚才我们看到这个大胡子

这个肯·汤姆森(Ken Thomsen)

他最早在一些大型机上自己写了一个代码

一个二维的平面的小游戏

用一些小圆弧代表飞船

在一个二维平面模拟的太阳系里

靠近若干个星体

每个行星每个卫星 尝试在它们表面着陆

于是在贝尔实验室里

他的很多同事成了这个游戏的疯狂爱好者

那么在1960年代的某一天

他手上有一台DEC的PDP7的这种计算机

尝试把这个space travel这个游戏

移植到这样一个计算机上

但是发现这个计算机没有操作系统

他们以前使用的操作系统Multics

在这个计算机上无法运行

于是决定自己又动手为了玩这个游戏

写个操作系统 久而久之

这个操作系统开发出来

也是我们今天所使用到的Unix系统的1.0版本

然后他有个很好的朋友叫

就刚才提到的丹尼斯.里奇(D.Ritchie)

也很爱好这个游戏

于是到了1969年前后他们尝试

把这个游戏和这个操作系统

进一步移植到

PDP-11这样一个型号的机器上的时候呢

发现了问题说这个操作系统移植很困难

因为大量代码是用汇编写的

于是他们决定使用一种叫B language B语言

来编写这个新的操作系统

而在写的时候

发现这个时候的计算机已经进化到了

比如说以字节为单位来做操作

所以说原有的B语言不够使用

于是他们从想玩一个简单的space travel游戏

到写了个操作系统

再做操作过程当中对它进行语法的扩充

于是产生一种新的语言 完善了它的语法

那这个语言叫什么呢

这些不负责任的玩家们就决定

既然它的前身叫B语言

那这个新的语言就叫C语言吧

所以C语言只是很Simple地从α β下来

B语言的后一个字母作为它的名字

所以这个故事呢

说我们所从事的 所熟悉的计算机

乃至嵌入式这个行业

并没有想象中那么高大上

很多东西都是在爱好者的疯狂的 玩儿

并且把它玩得很酷 玩的很好

这样一种Geeks(极客)的精神里头来发扬光大的

那么C语言的诞生在了1969到1973年代

早期的C语言是没有标准的Standard的

所以呢在1978年最早由这个

由Kernighan和Ritchie这两个人一起写的这样一本书

叫“The C Programming Language”

这本书在实质上成为了非Standard的

一个Specification 一个C语言的标准

这本书里给出了C语言的基本的语法

然后C语言的所有的语序和关键词

那么也定义了C语言的标准的C语言函数库

也就是我们现在经常会一上来就include的

那几个函数库

那么它成为了C语言实际上的标准

到了某一个年代这本书出第二版的时候

才出现了ANSI的C标准

一直发展到我们今天的C89 C99这些Standard

所以在很长时间内K&R的C就是C语言的

实质上的标准

所以这样一种C语言的历史发展到今天

也就是我们大家在之前的别的课堂上所学习的

C语言 那么C语言拉起来大家会发现

它有很多很多的关键字

有很多keywords 同时呢比如include

比如说define 同时呢它还有很多的运算符

那么如果大家的C语言基础不扎实

在学这门课的时候 一方面大家应该补一补

C语言的基础语法 首先熟悉各种运算符

尤其熟悉指针的概念 其次呢

跟着我们课程在我后面要讲的内容里

也会进一步加深

C语言的一些基本概念在嵌入式系统里头的应用

那么这些运算符 这些关键字当中

有一些我要提示大家注意的

比如说我们在C语言的编程里

很多同学都会学习if else语句

都会用感叹号来表示取非

对吧 一个逻辑条件

那么在计算机在嵌入式应用里头

我们会经常会做位的操作

比如这么会用一个小的波浪号

进行按位取反的操作

我们会用两个向右的这个尖括号

代表左移或者右移的运算

这是可能大家在学习计算机平台的C语言

编程当中学习到但使用得比较少的运算符

希望大家加以巩固 那么从C语言的历史

到C语言的这些大家耳熟能详的Standard

究竟在嵌入式的 在微控制器里头C语言

有哪些特别要注意的地方

或者说跟计算机系统不一样的东西呢

我们分成几个小的topic来给大家讲

第一个呢 是C语言当中的数据类型

C语言当中的数据类型大家都很熟

我们有char 有int 有long然后还有float

还有single double这样整数的

和浮点数的运算类型

然后整数运算类型这些我们当中

还可以是signed unsigned有符号无符号

那么大家对这些都很熟

那我想问作为一个本科同学

如果让你写个C程序

上来你知道有个main 要声明一个变量

你会给变量用什么类型呢

我们很多本科的同学或者初学者

很喜欢就是int 一个整型

然后编到尾巴里头从整个程序编下来

那么在这个过程当中

其实大家还有一个非常糟糕的习惯

在这里我只提 不给大家讨论了

就是这个变量的名字信手拈来

用到谁是谁 int abc ijk不够了再往后面lmn

编程序的时候经常信手拈来的用

回头就忘了这个变量是什么功能

那么这件事情先放在一边 我们单讨论类型

在嵌入式应用的行业里头

我们实际上对于C语言的一个基本概念

扣一扣就会知道每一种变量类型

它是有它自己所占的这个字节数

或者叫字位数的

那么它们就会有一个range的概念

也就是动态范围

比如说一个unsigned的char

它是8个比特一个字节 那么它的值就从00

一直到ff 或者是二进制的0000八个0

1111八个1 从0到255

如果它是signed的char

就是有符号类型的char变量八个比特

那么根据负数的这个定义

我们从负的128到正的127是它的取值范围

以此类推包括int 包括long

大家都会知道它是有它的这个range

有概念的有它的范围的

那么如这样一个代码

比如说一个delay函数

大家觉得有点熟悉 为什么

我们在本章的第一小节讲点灯

说我让一个灯变亮 中间delay一段时间

这个delay我可以是五百个毫秒

也可以是一秒

那么在C语言编程里怎么实现它呢

最简单的方法就是

我给大家提示过做一个大大的for循环

我们的计算机指令是大约以每条指令

几十个纳秒的速度在运行

那么我们如果编一个大大的for循环

让它在这执行上千条上百万条指令

差不多一秒钟的时间就过去了

所以我们会做一个大大的delay

比如像现在这个函数叫void delay(void)

我没有参数 我就delay一个固定的时间

那进去以后我unsigned char两个变量

大家注意这两个变量什么类型

底下有个嵌套的for循环 那么第一层for循环

是从i等于0到10循环

第二层是从j等于0到j到6万循环

那我想问这个函数正确吗

它执行的时候能够正确的延时或者能够退出吗

大家可以想一想

然后如果C语言基础比较扎实

又跟着我刚才那些概念

顺下来的同学会很快的反应过来这有问题

有什么问题呢

因为我们的变量类型是unsigned char

所以在我们的嵌套循环的第二层循环里

我们判断条件是j小于6万

而对一个8比特的无符号整型变量

每当他的值到255的时候

它累加就会溢出回到零

所以它的值永远在0到255的这个range

它的范围内循环 这个条件永远不会满足

所以我们的函数我们的程序 走到这一步

如果你单步执行或者你跟踪执行的话

它就死在这儿了 永远出不了这个循环体

那么这就是函数类型(字幕菌注:应为变量类型)引起了一个错误

那么在计算机的行业里头

我们实际上会发现很多很多这样的问题

现在大家可能接触不到

我只举了这个简单的例子 我提一下

比如有兴趣的同学

你希望去做一个USB的设备 做USB通讯

希望自己开发一个以太网的接口程序

这个时候你会非常明显的感觉到一个概念

叫protocol 也就通讯协议

我们所使用的网络 我们所使用的USB

每一个数据都以数据帧

数据包的形式来发

包头包尾校验帧每一个单元是几个字节

都是非常清晰定义了的

所以按照协议

关心的不仅仅是这个数 值是多少

更关注的是在按照通信协议

在每个step我们应该发送一个字节

或者两个字节 这个位宽是一定不能出错的

所以在这个时候 这个变量一定要准确

我们刚才讲了 那就是说这个数据的类型

关系到程序运行结果的正确与否

而实际上在嵌入式开发的领域里头呢

数据类型不仅仅涉及到正确与否

还涉及到我们应该尽可能地节约

我们的代码空间 我举个非常简单的例子

我们绝大多数的C语言初学者

都非常喜欢int型变量因为这是第一个学的

又很顺手甚至是默认的类型

那么这样的情况下我们在32位

我们这门课

所学习的ARM Cortex M系列的CPU上 MCU上

它是个32位宽架构的MCU 所以大多数时候

它的编译器int类型

对应的是32位的四字节存储空间

而我们很多时候使用的变量

只是用来给if else做一个简单的判断

那么大家可以知道if else判断

实际上是一个布尔型的变量

我们所需要用到它的值只是1或者0

这样一个1比特的信息

于是我们这样子进行一个

习惯性的编程开发的时候

你往往会为了一个比特的信息

用掉32比特四个字节的空间

嵌入式MCU嵌入式系统的存储空间

往往都是非常有限的

所以我们需要量入为出地来使用它

这是我在之前讲基本开发时给大家强调过的概念

所以实际上在C语言编程的时候

我们应该尽量使用满足我们程序功能要求的

最小的变量类型来做

那么另外一个需要注意的点呢

就是关于浮点数 很多同学会说我想算个周长

乘以3.14 测个温度 几点几除以几点几

我们在不带有浮点运算单元的MCU

或者CPU架构下

比如说我们现在讲的ARM Cortex M0 M0+

乃至ARM Cortex M3

这样的MCU上使用浮点运算的时候一定要小心

在这样的不带有浮点运算功能的CPU上面

与带有浮点运算功能

比如像M4这样的MCU上是不一样的

它的浮点运算功能需要一个庞大的

C语言的标准函数库来加以支撑

这样也许在你的代码里

你只出现了一次浮点运算

就是每次运算结果比如说几点几乘以几点几

算一步就一句话 但是它会导致你的程序

需要include进来一个非常大的浮点运算的

支持函数库

使你整个代码编译出来的量比原来要大的多

占掉更多的存储空间

那么在一些存储空间非常受限的应用里头

我们可能会发现这是一个瓶颈

那么处理的方法当然很多了

大家如果有兴趣去学习嵌入式的书可以做更多的阅读

比如说我们将浮点数在有限精度下

通过移动小数点的位数全部转换成整数运算

或者类似于三角函数这样一些浮点的运算

我们可以做一张在一定精度下的查表

用一张查表运算来替代我们的浮点运算

这都是技巧 接下来我们要讲的一件事情呢

就是数据类型不仅仅取决于我们所使用的CPU

它还取决于我们所使用的编译器换言之

char类型的变量 int型的变量

乃至long型的变量 它对应一个字节两个字节

还是四个字节 这件事儿既取决我们所用的CPU

也取决于我们当前开发所使用的编译器

根据我们所使用的 比如是code warrior里头的C编译器

Freescale公司提供的或者是开源的

ARM下的这个GCC的编译器

它是有不同的界定的

具体的值应该去查这个编译器的手册

它会有一些默认的规范同时它是可以设置的

比如说我们通过编译器的一些参数

可以指定int型对应一个字节或者两个字节

那么有同学会说 既然它是可以设置是灵活的

我是不是就可以随意使用了

等到我发现这个字节不对的时候

我改一改编译器设置不就行了吗

我要放在这也是一个不好的习惯

如果大家养成良好的编程习惯

熟悉嵌入式C语言

大家可以阅读一些开放源代码的作品

它里头的代码的写法 那么最常用的一种做法

就是我们在嵌入式开发里头

避免直接使用基本类型来声明变量

就是说我们尽量避免使用 char int short

那怎么办呢

我们在我们程序的最开头或者它们头文件里

使用typedef这样一个关键字 将一种变量类型

声明为一种替代类型

比如我这里要举的这两个例子

int型的变量在8比特的MCU或者CPU上

一般编译器会把它处理成16比特占两个字节

而在32比特的系统上默认它就是32个比特

反过来short变量在32位系统上

才是两个字节16个比特

那么这样一种不一样的对应关系

我们怎么在代码上做到统一呢

大家如果去看一看μC/OS linux

以及包括lwIP这样的

开放源代码的project你就会发现

它们往往都会像这两段代码所写的

先把char 把int和long这样的变量

typedef成u32_t或者是int32_t

这样的变量类型

用一种替代变量类型直接说明这个变量应该是

8比特还是16比特

日后声明变量的时候

只用使用后面这样一个替代类型

来声明变量比如说uint32_t声明一个变量

那么在任何代码上

就知道这个变量是32位4个字节的

那么当我们把这样一个程序代码

移植到一个新的计算机构架的时候

我只用改最前面这些typedef

根据我当前所使用的CPU和所使用的编译器

把它定位到正确的类型上

那么这个代码就不会出现任何

因为字节的长短而出现的bug

那么在日后会节约我们大量的时间

讲完了这件事呢

再来讲一个第二个topic 比较简单的一件事儿

就是C语言里头的位操作 C语言里头的位操作

在计算机层面的开发用得比较少

但如果根据我们这个课的第一小节

给大家讲的这个IO的编程

就会感觉到我们要大量的使用位的操作

为什么呢 因为我们直接涉及到这寄存器里头

一个比特两个比特的操作

比如说在嵌入式开发里头

位操作有很多具体的应用

像我们已经有的例子里头

我们要控制一个引脚输出的值

需要改变寄存器里某一个比特的值

我要读取一个引脚输入的电压值

我应该在对应的寄存器里

读取寄存器某一个比特的值是0还是1

那么我们在它的配置里头也根据功能打开时钟

设置使用的复用功能

我们要给某一位置1或者置0

所以可以发现在嵌入式C语言开发里头

我们会非常频繁使用的一类操作

就包括了对一个变量对一个寄存器

把某一个比特某几个比特置位或者清零

把某几个比特的值进行移位

然后判断某几个比特是零或者一

或者把某几个比特里某一个寄存器里头

某几个比特值拿出来进行进一步的判断

那么这样会涉及到很多按位的操作

这块儿我会讲得稍微快点

因为它涉及到C语言的基础

比如说与 或 亦或 按位取反 左移 右移这些运算

那么比如说我这里给两句话

在我们之前做点灯的例子

大家都看到过GDIOD_PDOR输出数据寄存器

等于它自身的值按位取反 所有的0变1

所有的1变0 说if GPIOD_PDOR这个寄存器的值

与上0x80等于0 这是判断什么

这是判断输出的这些引脚当中

第八个引脚也就是最高的那个引脚

是否为一 对不对

那么通过这些语句我们可以

控制寄存器的某一个比特为0为1

或者把它值给拎出来 那么归总起来

它的操作应该这样几类 我们顺着捋一下

按照C语言来讲它并不困难

比如说我有一个变量

我希望把当中的BIT7也就是第8个比特

从0开始数置1 变成1 我应该怎么做呢

我们应该写这么一句简单的话

就是这个变量或等于0b1000

后面7个0 0b是二进制的C语言写法

与这样一个二进制数来或

0与任何数或 不改变它的值

1与任何数或 变成1

于是这个变量在其他位不变的情况下

对应的这个比特变成了1

那同时我要把这个变量里头BIT5和BIT4

两个比特同时变成1怎么办呢

我应该把它与一个0b00110000

这样的一个变量来或

对吧这是这非常简单的

那么我们会把后面的称为0b1000

或者0b0011000这样的二进制

0和1组成的这样一个码串

在很多时候称为mask mask是什么 面具

面膜对吧

实际上在计算机行业我们把它称为掩码

它来标识哪些位要被改变哪些位不被改变

很像一个纸板上若干个被抠出的洞

让你来涂改的意思 那么 一个小quiz

大家看一看

说这两个变量经过这个程序以后

它有什么区别

一个是这个变量或一个值

一个是变量等于一个值

我想这件事情是非常清楚的

我们在第一小节做IO操作的时就说过

或的时候只改变一个比特 等于的时候

是把不想改变别的比特也都强行置0了

这就是位操作的好处

那么我们如果把类似于0001

0010这样的值全部拎出来

把它做一个define成一个宏呢

大家会发现这件事情变得很简单

比如说define BIT1的mask

这个宏是0b00000010 相应的BIT2

BIT3我们的代码就会变得更加可读

比如说刚才的程序

就变成了一个变量或等于BIT3的mask

日后我们再来读这段代码的时候

不用去看它的运算什么

我很清楚 我把它的BIT3置位了

那么下面代码也是变量或等于BIT2的mask

或上BIT1的mask

我们很清楚我们把哪两个比特给置位了

那么反过来说

如果我们要把一个变量

一个寄存器里头的某一个位清0怎么做

大家会说置位用或清0呢用与

但是这个时候我们不用为了清零

重新再做一组掩码 非常简单把0001000

这样的一个掩码按位取反

是不是就它的反变成1110111

我们要的那一位是0其他位都是1

这个时候再与变量自身与

写成变量与等于我们要的掩码去反

就是别的位不变

掩码对应的这一位被清零了

那么我们也可以用同样的方法

来实现对多个比特的清零 那么除了置位清零

我们还会很常见做到的一个操作

大家在学习计算机的C语言

可能基础不扎实的时候不太熟的左移和右移

我们把运算符写在等号前面

等于是这个变量来移

往右移四位往左移四位 0x34往右移四位

四没有了 只剩下0x03

往左移四位3被移出去了如果它是char

类型变量的话

那么4被移到了高四位 下面替补0变成0x40

左移和右移

大家可以在C语言里头去回忆一下

那么它有什么用呢

在我们计算机操作的时候

比如说有一个变量 有个寄存器

我想把它当中某几个比特的值取出来

赋给一个新的变量

看一看我们应该怎么做

比如现在最简单取高四位和低四位

我们就定义了两个掩码

h4的high 4的mask

是0b11110000

low 4是00001111 那么同样一个变量

我想把三和四分别取出来 怎么取

这在我们以后做通讯的时候

会用到这个这段代码

这个变量或等于它自己与上低四位的掩码

这样就拿到了最低的四个比特

那么高四位呢比它多一个步骤

让这个变量与高四位的掩码11110000来或

这样它的四就没了

只剩下三但这个时候是0x30啊 我们再右移四位

把三作为一个独立的部分

取到一个新的变量里头

所以根据移位 加 与或

我们就可以非常容易地取出

任意一个寄存器任一个变量里的某几位的值

来进行下一步的编程操作

那么这是左移和右移

最后呢还有一个就是我们的

叫做condition判断条件

比如说我们会说我们回到点灯

我们点了八个灯

它输出的值是零的时候都是亮的

输出的值是一的时候都是灭的 那我想看一看

这个我上一步的程序运行结果

这个灯当前状态是亮是灭

我怎么判断呢

我要把这个寄存器的值读出来

检查某一位是零还是一

我们往往会在语句里出现这样的句子

if一个变量与上一个掩码不等于0

if一个变量与上一个掩码等于0

因为任何数跟零与都是零

所以整个这个与的逻辑表达是否为1是否为0

只取决于掩码对应的那一位是否为1

大家想想这件事儿

所以我们

就很容易把一个变量里头的某几个比特的值

拿出来做个条件判断 所以呢

我们在这样短短的一节课里

已经回顾了C语言的基本历史渊源

讲了C语言的数据类型的概念

讲了C语言按位取的概念

这都是非常基础的

那么这节课的内容差不多到这就结束

下一节课我们会再往前走一点

去给大家讲讲C语言在嵌入式开发里头

指针的灵活运用

和volatile这样的关键字的使用

我们究竟在Code Warrior里头 在我们第一节课里头

去编一个点灯的那几句简单的代码

它背后的故事是什么

请大家下一节课再继续学习

智能车制作:嵌入式系统课程列表:

第一章 概览

-1.1 课程概览

--Video

-1.2 进入嵌入式系统的世界

--Video

-1.3 如何学好嵌入式系统

--Video

第二章 绪论

-2.1 计算机的基本概念、发展历史

--Video

-2.2 从晶体管到CPU

--Video

-2.3 概念CPU、微控制器MCU和嵌入式系统

--Video

-2.4 八卦计算机史

--Video

-2.5 不同领域、不同系列的嵌入式系统

--Video

-2.6 ARM历史与MKL25Z128 MCU

--Video

第三章 MCU基础

-3.1 CPU的基本结构和运行机制

--Video

-3.2.1 堆栈的概念

--Video

-3.2.2 堆栈的概念-头脑体操

--Video

-3.3.1 ARM的体系结构

--Video

-3.3.2 ARM的体系结构-头脑体操

--Video

-3.4 中断的概念和机制

--Video

-3.5 中断子程的概念和编程

--Video

-3.6 复位、时钟、存储器和总线

--Video

-3.7 小结:MCU的总体结构和程序运行机制

--Video

第四章 MCU外设与开发

-4.1 第一种外设:IO

--Video

-4.2 IO外设的编程实操-点亮LED

--Video

-4.3 IO外设的进阶知识

--Video

-4.4 嵌入式开发的基本概念与工具链

--Video

-4.5 嵌入式开发的进阶知识

--Video

-4.6 嵌入式开发中的C语言(上)

--Video

-4.7 嵌入式开发中的C语言(下)

--Video

-E0.1 实验零 开发板的初步认识与工具链的安装

--Video

-E0.2 实验零 体验一个例程的编译与下载

--Video

-E0.3 实验零 编写第一个程序:点亮核心板LED

--Video

-E1 实验一 点灯秘籍

--Video

第五章 MCU与嵌入式系统设计

-5 智能车视角的嵌入式设计

--Video

Video笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。