C语言基础(初级嵌入式)
清秋碧落
2026年02月19日 10:54

C语言的基本内容,可以查看:https://www.runoob.com/cprogramming/c-tutorial.html

但是,为了更精简化,只需要提取10~20%的内容就可以满足普通MCU类产品的开发,故做精简整理如下:

 

根据总结,C语言的基本规则,有:

4种变量用法

1种常量用法

3种函数声明

20个运算符

2种判断语句

2种循环语句

1种头文件写法

 

学以致用,因用而学。学习基本的C语言语法前,不得不考虑清楚,是用在什么上面

之所以定义初级嵌入式,删掉 指针、结构体、位与、异或、左移、右移 等内容,是因为考虑到在大部分的初级嵌入式开发中,这些内容可有可无的

什么叫初级嵌入式呢?比如开发剃须刀、电推剪、保温杯、加湿器、香薰机、茶吧机、充电宝 等非常普通的、且不带物联网功能的电子产品,功能不过 GPIO、ADC、TIM、PWM、UART、I2C、SPI,连DMA都不需要考虑。这种产品只要思维逻辑清晰,是不需要复杂的语法逻辑的,用简单的语句实现产品的功能才是更有价值的

 

二进制、十进制、十六进制

1. 计算机只识别二进制,其存储只有0/1两个状态。因为其Flash位置只有高低两种电平

所以才引出了进制的概念,二进制、八进制、十六进制,都是面向于MCU的

2. 8位单片机,之所以叫8位单片机,是因为其具有同一时间处理8个二进制的长度的寄存器的能力

8个二进制,就是2个十六进制。所以我们在MCU中,经常见到0x00~0xFF的字段,

0x就是标明后面的数字是16进制,而十进制则不需要特殊标识

注:硬件的GPIO是三种输出状态:输出高、输出低、不输出。请不要搞混了

变量、常量

变量

1. 在C语言中,变量有 int、float、char、short、double …… 等等乱七八糟的

在MCU中,我们只有 bit、u8、u16、u32 这么几种 (还有vu8、vu16、vu32)

bit:是指声明长度只有1个二进制的无符号变量,变量的取值范围只能是0~1 (32位MCU可能不支持bit)

u8:是指声明长度只有8个二进制的无符号变量,变量的取值范围只能是0~255

u16:是指声明长度只有16个二进制的无符号变量,变量的取值范围只能是0~65535

u32:是指声明长度只有32个二进制的无符号变量,变量的取值范围只能是0~4294967295

2. u8、u16、u32,前面的u,代表的是unsigned,即没有 正负符号

3. vu8、vu16、vu32,前面的v,代表的是volatile,即禁止编译器进行优化,在全局变量中,需要加v。也可以理解为,这是vip变量,要一直为它保留座位,不允许把他的座位给别人用

4. 普通MCU,是不支持浮点运算的(即小数运算),所以不需要了解float是什么,没有float变量,硬件不支持。那么小数怎么处理?换数量级啊,4.2V,是不是等于4200mV?4.2就永远当4200处理啊。35.8℃,就晋级当成358来进行处理,在需要显示的时候,再将数据除以10,不就可以了么?

π是3.1416,用u16定义成31416不也一样计算么?

5. 负数怎么处理?我们也不支持负数,按最大量程处理,假如最低支持-10℃,那么在程序中-10就是0

在需要显示的时候,再将数据减去10,不就可以了么?

所以,无符号的整数,可以通用全场,只需要掌握bit、u8、u16、u32就够了

别的变量并不能提高程序的运行效率,反而会提高出错的概率,予以忽略之即可

 

常量

1. 只掌握一种定义方式:#define

这个方式是预处理,在编译器编译的时候,就把值进行替换掉了,不占用MCU的RAM资源的

函数声明

1. 函数,会在变量上,增加一个void类型,void是指 空 的意思

比如这个,第一个void,代表该函数没有返回值。第二个void代表该函数没有输入值

2. 再来一个函数,这个函数是没有返回值,但是有输入值。输入值就是u8 Byte_TM1652_Display

得到了Byte_TM1652_Display的值之后,从硬件上就调度GPIO发送出去了,所以不需要软件上的返回值

输入值可以不止一个的

3. 再来一个函数,这个就是既有输入值又有返回值的函数。其实现的功能是,把ADC数值给它,它返回温度值

4. 针对于 没有输入值、没有返回值 的函数,使用的时候:Deal_SW();

针对于 有输入值、没有返回值 的函数,使用的时候:USART_Printf_Init(2000000);

针对于 有输入值、有返回值 的函数,使用的时候:num_Tem_Display = NTC_Refresh(adc_NTC); (即需要一个变量,来保存函数的返回值)

运算符

1. 我们不考虑指针,不考虑指针。普通的MCU开发,根本用不上指针

就像不用浮点数、不用负数一样,没有指针运算,一样能够完成产品的开发

2. 常用的运算符,按优先级排序如下:(1是最高优先级,中文是对符号的描述)

优先级1:()括号  []括号

优先级2:++加加  --减减  !取反

优先级3:*乘号  /除号  %求余

优先级4:+加号  -减号

优先级5:非相等的关系运算符: >大于  <小于  >=大于等于  <=小于等于

优先级6:相等性关系运算符: ==等于  !=不等于

 

优先级10:|按位或 (目前只存在于GPIO的操作中)

 

优先级11:&&逻辑与 (两个条件必须同时满足)

优先级12:||逻辑或 (两个条件满足任一即可)

优先级13:=赋值运算,将 =后面 的值赋给 =前面 的变量

 

3. 通常情况下,如果记不清运算的优先级,可以大量使用()括号,括号内的肯定是优先处理的

4. 在按键的处理判断函数中,往往是大量使用运算符,可以在了解完每个运算符的作用后,

能够在不借助AI工具的情况下,读懂这些逻辑,这样才能说明你具备开发软件的逻辑思维

判断

if + else if + else

注意,if()中的判断,是非0即1,就是说只有if(0)是不执行的,if(1)、if(2)、if(888)都是执行的

switch + case + break

case 0 代表的含义是:Byte_TM1652_Display == 0

case 1 代表的含义是:Byte_TM1652_Display == 1

每个case执行后,必须加break退出。假如需要执行多条语句,就用{}扩起来

if + else if + else能干所有的事情,相比较switch而言,执行速度回慢一些,if是顺序执行

switch只能做等于的比较判断,但是执行速度快、代码更清晰,可以直接根据变量的值,找到对应的执行语句

 

循环

while循环

for循环

新建头文件