引言
C语言是面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发,并且C语言能以简易的方式编译、处理低级存储器,也是仅产生少量的机器语言以及不需要任何运行环境支持便能运行的高效率程序设计语言。所以51单片机的程序也大多使用C语言来编写,在正式开始学习单片机之前,一些基础性的程序编写知识学习就比较必要了。正文更多使用的是我的理解,用语可能不准确,一些术语大家可以自行上网查询。
一、进制转换基础
平时我们经常使用的就是十进制(即”逢十进一“),至于为什么使用十进制我觉得主要原因这源于它具有公认性(大家都能理解并方便使用),但是在程序里面,机器却没有这种观念,对它来说更容易理解的是二进制(即”开和关“)以及四/八/十六(二的倍数次)……进制,所以就需要我们在程序编译当中进行进制转换。
N进制,简言之,就是逢”N“进一,每一位的单位是N的对应次幂,例如:
十进制 | 15(1*10+5*1) | 16(1*10+6*1) | 17(1*10+7*1) |
十六进制 | 0F(0*16+15*1) | 10(1*16+0*1) | 11(1*16+1*1) |
所以,针对程序经常会使用到的十进制与十六进制的转换,给出下面的进制对应表:
备注:1——255之间没有展示的数值可以自己推一下,主要在于理解如何实现进制转换
1 | 0x01 | 16 | 0x10 | 31 | 0x1f |
2 | 0x02 | 17 | 0x11 | 32 | 0x20 |
3 | 0x03 | 18 | 0x12 | 33 | 0x21 |
4 | 0x04 | 19 | 0x13 | 34 | 0x22 |
5 | 0x05 | 20 | 0x14 | 35 | 0x23 |
6 | 0x06 | 21 | 0x15 | 36 | 0x24 |
7 | 0x07 | 22 | 0x16 | 37 | 0x25 |
8 | 0x08 | 23 | 0x17 | 38 | 0x26 |
9 | 0x09 | 24 | 0x18 | ...... | ...... |
10 | 0x0a | 25 | 0x19 | 250 | 0xfa |
11 | 0x0b | 26 | 0x1a | 251 | 0xfb |
12 | 0x0c | 27 | 0x1b | 252 | 0xfc |
13 | 0x0d | 28 | 0x1c | 253 | 0xfd |
14 | 0x0e | 29 | 0x1d | 254 | 0xfe |
15 | 0x0f | 30 | 0x1e | 255 | 0xff |
二、变量类型基础
在单片机学习过程中,不仅需要常量的数据,更多的时候需要添加一些变量来完成数据处理。对应不同的位置,使用到的变量类型和范围都不会一样,所以要根据实际需要来定义不同变量的类型。
基本类型 | 类型表示 | 数值范围 |
字符型 | unsigned char | 0~255 |
字符型 | signed char | -128~127 |
整型 | unsigned int | 0~65535 |
整型 | signed int | -32768~32767 |
长整型 | unsigned long | 0~4294967295 |
长整型 | signed long | -2147483648~2147483647 |
浮点型 | float | -3.4*10^38~3.4*10^38 |
浮点型 | double | -3.4*10^38~3.4*10^38 |
三、基本运算基础
1.四则运算符
加、减、乘、除、取余分别为:+、-、*、/、%,与日常运算格式相同。
2.补充运算符
自加一:++
自减一:--
备注:上面两个放在一个变量前后表示的含义是不一样的,简单地讲,放在前面就是我先拿这个变量原来的值参与某个语句的处理或判断,然后在程序执行下一条语句前才会加减一,相反的是放在后面就表示要先将这个变量在原来数值的基础上加减一,然后才拿这个变量去参与到语句的处理或判断当中。(当然这个主要用于理解,具体还是要看代码是如何写的)
与或非:&、|、~
运算理解:与对应“and”,即左右两个都要符合要求才是符合条件;或对应“or”,即左右两边有一个符合条件就是符合条件;非对应“not”,即取反的意思。
举例:
与运算( 1 & 1 = 1;1 & 0 = 0;0 & 0 = 0;):
10110000 & 11010010 = 10010000
1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 |
1 | 1 | 0 | 1 | 0 | 0 | 1 | 0 |
1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
或运算( 1 & 1 = 1;1 & 0 = 1;0 & 0 = 0;):
10110000 & 11010010 = 11110010
1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 |
1 | 1 | 0 | 1 | 0 | 0 | 1 | 0 |
1 | 1 | 1 | 1 | 0 | 0 | 1 | 0 |
或运算( ~ 1 = 0;~ 0 = 1;):
~ 10110000 = 01001111
1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 |
四、循环语句基础
在编写程序中,大多功能都需要进行重复多次相同操作,这个时候就需要使用循环来简化整个代码的长度,提高代码运行效率
1.for循环
代码结构:
for(表达式1;表达式2;表达式3)
{
(表达式4);
}
代码解析:
表达式1:只执行一次(在循环最开始的时候),相当于进行循环变量赋值的初始化
表达式2:判断语句(每循环一遍就执行一次),相当于对循环变量是否满足循环条件的审核
表达式3:执行语句(每循环一遍就执行一次),相当于对审核通过的循环变量进行特定处理
表达式4:操作语句(每循环一遍就执行一次),相当于循环过程想要展现出的现象
代码举例:
unsigned char i;
for(i = 10;i > 0;i--) //循环10次
{
P2 = 0x00; //亮
Delay(50000); //延时函数
Delay(50000);
P2 = 0xff; //灭
Delay(50000);
Delay(50000);
}
2.while循环
代码结构:
while(表达式1)
{
(表达式2);
}
代码解析:
表达式1:判断语句(每循环一遍就执行一次),相当于门卫,如果表达式1符合条件(即为真)时,通过开始运行下面代码;反之,不符合(即为假),退出循环不再运行下面代码。
备注:在C语言里,对于非零的常数都认为是真的,只有零认为是假的,如果表达式1里面是一个非零常数循环将一直循环下出。
表达式2:操作语句(每循环一遍就执行一次),相当于循环过程想要展现出的现象
代码举例:
unsigned char i = 10;
while(i) //循环十次
{
P2 = 0x00; //亮
Delay(50000); //延时函数
Delay(50000);
P2 = 0xff; //灭
Delay(50000);
Delay(50000);i--;
}
五、函数定义基础
代码结构:
函数值类型 函数名(形式参数列表)
{
函数体;
}
代码解析:
函数值类型:
函数返回值的类型,即为主函数里面调用一次子函数,子函数运行完返回给主函数的一个特定值,这个值可以是多种类型的。特殊地,子函数也可以只执行操作,不返回任何值。示例:
int hanshu() //返回一个整型的值
{
return M; //返回一个M值
}
void hanshu() //无返回值
{}
函数名:
由字母、数字和下划线组成,但数字不能作为开头,即为一段子函数的名字,主函数可以根据名字找到对应的代码运行。需要注意的是,函数名不能和其他函数名或者变量重名,也不能使用关键字作为函数名(关键词是程序中具备特殊功能的标志符,例如:char/int/void......)
形式参数列表(形参列表):
函数调用时,主函数传特定数据给子函数时使用的形式变量,即为子函数很多是用于对主函数中一些数据进行处理,所以主函数调用时需要把要处理的数据传到子函数里面,子函数需要定义一个形参来存储这个数据,方便之后的处理。特殊地,有时候子函数不是用于数据处理时,主函数不需要传数据给它,这时使用void(也可以省略不填)来代替。
函数体:
包含声明语句部分和执行语句部分,即在开始运行代码前先把一些需要使用到的变量定义一下,之后是想要实现功能的对应代码,这个顺序不能改变,改变会报错。
主函数:
程序开始执行的起始位置,即为一篇文章正文的开端,其他部分只作为页眉和页脚,是对正文内容的补充说明。必须知道的是,一个工程文件必须有且仅有一个mian主函数。
代码示例
void Delay(unsigned int t) //延时函数
{
while(t--);
}void led(unsigned char n) //子函数,led闪烁一定次数
{
unsigned char i;
for(i = n;i > 0;i--)
{
P2 = 0x00; //亮
Delay(50000);
Delay(50000);
P2 = 0xff; //灭
Delay(50000);
Delay(50000);
}}
void main() //主函数
{
led(6);
while(1);
}