嵌入式基本认知:
1.IEEE定义:用于控制、监视或辅助操作机器和设备的装置,一种专门的计算机系统
2.国内普遍认同定义:一种以应用为中心,以计算机技术为基础,软硬件可裁剪,适应应用系统对功能、可靠性、成本、体积、功耗等严格要求的专用计算机系统;
3.是一个控制程序,储存在ROM中的嵌入式处理器控制板。
与C语言的关系
是c语言的扩展,在嵌入式系统中应用于编写嵌入式软件。
1.主要区别
嵌入式C语言和C语言是完全一样的,区别在于嵌入式C是跑在开发板上的。
2.启动过程
普通c语言的编译器会自启动处理器
嵌入式c语言用户必须做特定的启动程序,一般情况下,在支持微处理器的编译器中会捆绑相应的启动程序,如下图:
3.存储空间分配
对于普通c程序,操作系统将程序和数据从外部存储设备载入RAM中运行。代码、数据、堆栈都在RAM中。
对于嵌入式c程序,因没有通用的操作系统,嵌入式系统必须先将代码设置到ROM中,将数据、堆栈设置到RAM中才可以运行。
ROM:只读存储器——只能读出,断电后数据不改变
RAM:随机存储器(random access memory),主存(内存),可读可写,速度快,关闭电源后数据消失。
4.硬件访问
普通c语言:操作系统对计算机硬件设备进行操作,如控制声卡发出声音,控制显卡绘制图形等。
嵌入式系统在访问硬件时,必须编写直接操作硬件的应用程序。
5.资源限制
由于在嵌入式系统中使用小而耗电的组件,嵌入式系统具有有限的ROM和RAM以及较少的处理能力,因此在嵌入式C中编写程序时应该注意有限的资源。
在C语言中,台式计算机可以访问系统操作系统,存储器等,可以利用所有计算机资源。
6.
C主要用于简单但逻辑的程序,基于操作系统的软件等。
嵌入式C用于电视,洗衣机等微控制器。
嵌入式基本知识
主要知识如下:
1.逻辑运算位操作
2.条件编译
3.指针
4.typedef声明类型
5.extern变量声明
6.static关键字
7.文件包含问题
8.四大储存类
1.逻辑运算与位运算
逻辑运算
“|”: 或的符号,1|1=1、1|0=1、0|0=0,只要有1则为1;
“&”: 与的符号,1|1=1、1|0=0、0|0=0,只要有0则为0;
“~”: 非的符号, ~1=0、 ~0=1,等于取反;
“^”: 异或的符号,两个位相同为0,相异为1;
位运算
PS:按位操作只能用于整数类型的数据,不能用于浮点型和double型
(1)<<左移:用来将一个数的各二进制位全部左移N位,右补0。// 00001100 << 2 = 00110000
(2)>> 右移:将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0。// 00001100 >> 2 = 00000011
条件编译
单片机程序开发过程中,经常会遇到一种情况, 当满足某条件时对一组语句进行编译,而当条件不满足时则编译另一组语句。 条件编译命令最常见的形式为:
#ifdef 标识符
程序段 1
#else
程序段 2
#endif
它的作用是:当标识符已经被定义过(一般是用#define 命令定义),则对程序段 1 进行编译,否则编译程序段 2。 其中#else 部分也可以没有,即:
#ifdef
程序段 1
#endif
typedef声明类型
用typedef的一个好处就是使代码的可读性更高,写代码也更方便。typedef 在代码中用得最多的就是定义结构体的类型别名和枚举类型。
typedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
…
} GPIO_TypeDef;
在定义好后,可以接着通过GPIO_TypeDef来定义结构体变量:
GPIO_TypeDef GPIOA,GPIOB;
用在结构体上,typedef类型别名也大量用在int、short等这种变量上, 所以写STM32代码的时候几乎就不会出现类似于定义int型变量这样的语句,全部用 u8、u16这样的量代替
extern关键字
C 语言中 extern 可以置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。这里面要注意,对于 extern 申明变量可以多次,但定义只有一次。
extern u16 USART_RX_STA;
这个语句是申明 USART_RX_STA 变量在其他文件中已经定义了,在这里要使用到。所以,你肯定可以找到在某个地方有变量定义的语句:
extern int a; // 声明一个全局变量 a
int a; // 定义一个全局变量 a
extern int a =0 ; // 定义一个全局变量 a 并给初值。
int a =0; // 定义一个全局变量 a, 并给初值
指针
*和&实质是运算符
说明:
int a=6;//定义一个变量a,类型是int 赋值6
int p = &a //定义一个指针p,类型int,&是运算符,取得后面变量a的地址,
说明:*p=a=6, p赋值是a数据所在地址的数值,是运算符,取得后面跟着变量值作为地址上的值,所以p=a=6;
即p(看做一个整体)可以看做是a的一个别名,对于p的所有运算操作,相当于对a进行操作;
静态变量和静态函数
总结:static 的最主要功能是隐藏,其次因为 static 变量存放在静态存储区,所以它具备持久性和默认值0。
- tatic声明的函数和变量不能在另一个文件中引用,也就是说,如果加了 static,就会对其它源文件隐藏,无法进行调用。
- 默认初始化初值为0。在静态存储区共有两种变量存储:全局变量和 static 变量,而且在静态数据区,内存中所有的字节默认值都是0x00
文件包含问题
#include操作是,若后面带的是<>,则文件在安装路径中找;
若后面带的是“”,则文件在源目录中找
存储类
一共有四种类型,分别有:extern、static、register、auto
auto 存储类是所有局部变量默认的存储类,auto 只能用在函数内,即 auto 只能修饰局部变量;
register 存储类用于定义存储在寄存器中而不是 RAM 中的局部变量。
extern存储类:C 语言中 extern 可以置于变量或者函数前,以表示变量或者函数的定义在别的文件中,提示编译器遇到此变量和函数时在其他模块中寻找其定义。这里面要注意,对于 extern 申明变量可以多次,但定义只有一次。
static存储类:
所有未加 static 前缀的全局变量(这里的全局变量指在源文件的开头处,不包含在源文件的任何函数内)和函数都具有全局可见性,其它的源文件也能访问。static声明的函数和变量不能在另一个文件中引用,也就是说,如果加了 static,就会对其它源文件隐藏,无法进行调用。
利用这一特性可以在不同的文件中定义同名函数和同名变量,而不必担心命名冲突。static 可以用作函数和变量的前缀,对于函数来讲,static 的作用仅限于隐藏,而对于变量,static 还有下面两个作用。
①存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。在下次使用静态变量时,则不会在去初始化。
②默认初始化初值为0。在静态存储区共有两种变量存储:全局变量和 static 变量,而且在静态数据区,内存中所有的字节默认值都是0x00
③总结:首先 static 的最主要功能是隐藏,其次因为 static 变量存放在静态存储区,所以它具备持久性和默认值0。
问题:
1.volatile看不太懂。