嵌入式C学习笔记

嵌入式基本认知:

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。

  1. tatic声明的函数和变量不能在另一个文件中引用,也就是说,如果加了 static,就会对其它源文件隐藏,无法进行调用。
  2. 默认初始化初值为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看不太懂。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值