定义变量
定义时的糟糕习惯,
定义变量或函数的名字信手拈来用到谁是谁
int abc
int ijk
不够了在往后面lmn
回头就忘了变量名是什么功能
正确示范
uint16_t GPIO_ReadOutputData() //读取io口输出的值
{
}
uint16_t GPIO_ReadInputData()//读取io口输入的值
{
}
定义的类型
每一种变量的类型有自己所占的字节数
Date Type | Size in Bits | Data Range |
unsigned char | 8-bit | 0~255 |
signed char | 8-bit | -128 ~ +127 |
unsigned int | 16-bit | 65535 |
signed int | 16-bit | -32768 ~ +32767 |
延时函数
void delay(void) { unsigned char i , j; for(i = 0 ; i < 10 ; i++ ) for(j = 0 ; j < 60000 ; j++); }
这个程序能延时吗 ?会,会一直延时
这个程序最终会干嘛? 死循环,走不出去
为什么?
unsigned char 的最大值是255,j 最大到255,再大就会溢出,j会返回到0,继续加
总结1
- 选择合适的数据类型可以节省代码空间,提高运行速度-----我们习惯使用int 类型,但这个类型并不是最适合微控制编程的
- 嵌入式系统的MCU往往是非常有限的
- 尽量使用满足要求的最小变量类型
- 避免使用浮点数和双精度
注意
每个数据类型的宽度在不同的编译器环境下是一个可以设定的值
具体的值,可以查编译器的手册
总结 2
避免直接使用基本数据类型(char , short ,int ,long )
比如int 在8bit, 32bit 系统上不同
使用typedef 定义更清晰的数据类型
根据编译器和环境的设定成对应的基本类型
代码将不受编译器和环境的影响
- 显式的申明变量的宽度/有无符号
typedef unsigned char uint8_t; typedef int int16_t; typedef usigned long uint32_t;
4.方便代码移植和修改
嵌入式 C语言位操作
具体应用举例
- 控制引脚输出的值 改变寄存器中某一个比特的值
- 读取某一个引脚输入的值 在对应的寄存器中读取某一比特的值是0 还是 1
- 在他的配置里头根据功能打开时钟,设置使用的复用功能,我们要给某一位置1或者置0
- 在嵌入式中,把某一比特某几个比特置0或者清零,把某几个比特值移位,判断某几个比特是零,还是1,或者把某几个比特的值和另外几个比特的值进行比较
与 或 非 按位取反 左移 右移
一个实列
把一个数的第八位从0 变为 1
uchar_var = 0x34;
uchar_var |= 0b1000000; //0与任何数或不改变他的值,1与与任何数或变为1
//于是这个数在其他位都不变的情况下,对应的第八位变为1
//0b 二进制C语言的写法
ob100000 // mask 掩码
把掩码定义为相应的宏更方便 代码更
//代码更加可读
#define BIT3_MASK 0b00001000 //第三位
#define BIT4_MASK 0b00010000 //第四位
#define BIT1_MASK 0b00000010 // 第一位
uchar_var = 0x34;
uchar_var |= BIT4_MASK; //把第四位改为1
某一位置 0 操作
- 先按位取反
- 与变量自身与
左移和右移
uchar_var = 0x34;
//shift right
uchar_var >>= 4;
//shift left
uchar_var <<= 4;