单片机与C语言编程基础
当前文章介绍C语言的: 位运算运算符、基本运算符、数据类型、变量、for语句、while语句、goto语句、switch语句、运算符优先级强制转换等。一、变量的命名
变量的命名: (13个字符)
1. A~Za~z
2. 0-9
3. _
4. 说明:只能字母和数字开头。不能使用关键字。
//左值和右值
unsigned int a=123;//4个字节
const int b=456;
char c='A';
float d=123.456; //123.456 浮点数常量
char *p="123456"; //"123456"字符串常量
复制
二、常量数据格式
#include "stdio.h"
//常量声明: U和L 表示无符号长整型
#define ABC 123UL
#define ABC 123ul
int main(void)
{
//0b101010; //二进制表示形式
//0x123; //表示十六进制
//123 //表示十进制
int a=0x123;
return 0;
}
复制
三、运算符
3.1 逻辑非
#include "stdio.h"
//常量声明: U和L 表示无符号长整型
#define ABC 123UL
int main(void)
{
int a=0;
if(!a)
{
printf("为真!\n");
}
int data=1234;
printf("%d\n",!!data);//1
return 0;
}
复制
3.2 位运算
&:全1为1,有0为0
| :全0为0,有1为1
^:相同为0,不同为1
~:1为0,0位1
>> :右移运算,低位溢出高位补0
<< :左移运算符,高位溢出,低位补0
复制
位运算符使用较多的地方: (1) 单片机里寄存器操作
(2) 协议加密解密、压缩算法、各种算法。
(3) 当做标志位使用
#include "stdio.h"
//系统里需要有8个状态位,需要存放8个状态位--------当做寄存器使用
int main(void)
{
unsigned char a=0; //8个位范围:0~7
//如何将a第7位,置1呢?
a|=1<<7;
//如何将a第2位,置1呢?
a|=1<<2;
//将2的第3位和第4位置1
a|=0x3<<3;
//如何判断第7位是0还是1呢?
if((a>>7)&0x1)
{
printf("第7位的值为真!\n");
}
else
{
printf("第7位的值为假!\n");
}
//bool sbit位定义 。
//bool a; sbit LED1=P1^1;
return 0;
}
复制
3.3 sizeof运算符
Sizeof运算符
#include "stdio.h"
int main(void)
{
int a=1234;
printf("%d\n",sizeof(a)); //4
int b=1;
printf("%d\n",sizeof(b));//4
return 0;
}
复制
3.4 三目运算符
#include "stdio.h"
int main(void)
{
/*
int a;
scanf("%d",&a);//取地址
int a,b;
a=a&b; //与
int a,b;
a=a*b;//乘号
int *a; //指针类型
*/
int a;
a=8>5?123:456;//if(8>5){a=123;}else{a=456;}
printf("%d\n",a); //123
return 0;
}
复制
3.5 运算符的优先级和强制转换
#include "stdio.h"
int main(void)
{
int a=123+456-12*5/78; //高优先级先结合,再依次....
//如果优先级同级,执行顺序是从左边到右边。
//优先级最高:()小括号
int b=123456789;
char a=(char)b; //强制转换,只是取低8位
//欺骗编译器,告诉它,b是char类型。
char a='8';
int b=(int)a; //强制转换
printf("b=%d\n",b); //还是字符8
return 0;
}
复制
四、语句
4.1 for循环语句
#include "stdio.h"
//系统里需要有8个状态位,需要存放8个状态位--------当做寄存器使用
int main(void)
{
int a=123,b=456;
int cnt=0;
for(a=0;a<5;a++)
{
for(b=0;b<5;b++)
{
if(a==2)
{
break; //跳出最近的一层循环
}
cnt++;
}
}
/*
for(;;)
{
//死循环
}
while(1)
{
//死循环
}
do
{
//死循环
}while(1);
*/
printf("cnt=%d\n",cnt);//20
return 0;
}
复制
4.2 while循环语句
while循环语句
#include "stdio.h"
//系统里需要有8个状态位,需要存放8个状态位--------当做寄存器使用
int main(void)
{
int a=0,b=0;
int cnt=0;
while(a<5)
{
while(b<5)
{
if(a==2)break;
b++;
cnt++;
}
b=0;
a++;
}
printf("cnt=%d\n",cnt);//20
return 0;
}
复制
4.3 goto语句
在平常的逻辑代码里面,不推荐使用goto语句。 常用的地方: 错误处理,某某程序初始化失败,就释放资源等操作。
#include "stdio.h"
//系统里需要有8个状态位,需要存放8个状态位--------当做寄存器使用
int main(void)
{
int cnt=0;
AA: //标签的定义,可以放在函数范围内的任意位置。(不能超出函数范围)
printf("123\n");
if(cnt==5)goto DATA;
cnt++;
goto AA;
DATA:
return 0;
}
Goto语句常用在错误处理:
#include "stdio.h"
//goto语句在错误处理里使用
int main(void)
{
if(LED_Init()<0) //表示该函数返回值错误
{
goto ERROR;
}
if(KEY_Init()<0) //表示该函数返回值错误
{
goto ERROR;
}
/*....*/
/*....*/
ERROR:
//释放资源,结束程序
return 0;
}
复制
4.4 Switch语句
Switch语句主要用在多分支选择结构----有很多种条件/情况。 实际代码里,常用于菜单选择:
#include "stdio.h"
int main(void)
{
switch(cmd) //cmd的值传入之后,与case后面的比较,成功之后再执行语句
{
case 1: //case 后面值只能是常量,而且不能重复
break; //跳出最近的一层switch语句
case 2:
{
/*......*/
break;
}
case 3:
break;
/*......*/
default: //类似于else
printf("所有的条件都不成立!\n");
}
return 0;
}
复制
示例:
#include "stdio.h"
//投票系统,有3个待选举的人,A,B,C ,有10张票
int main(void)
{
int i;
int A=0,B=0,C=0;
int data;
for(i=0;i<10;i++)
{
printf("请投票(范围1~3):");
scanf("%d",&data);
switch(data) //data的值传入之后,与case后面的比较,成功之后再执行语句
{
case 1: //case 后面值只能是常量,而且不能重复
A++;
break; //跳出最近的一层switch语句
case 2:
B++;
break;
case 3:
C++;
break;
// default: //类似于else
}
}
printf("A=%d\n",A);
printf("B=%d\n",B);
printf("C=%d\n",C);
return 0;
}
最经典、最基础的入门单片机,如AT89C51。结构简单,资源有限,但学习曲线平缓。 C语言代码可以在不同的硬件平台上编译运行。 可以通过指针、位操作等方式直接访问和控制硬件寄存器。 支持函数、模块化编程,代码更清晰、易维护。 注意函数的调用开销(栈的使用),在资源受限的单片机上要合理设计。 使用C语言等编程语言编写程序代码。 现代编译器能生成效率很高的机器码,接近汇编语言的效率。 ISR需要简短高效,尽快完成处理并返回。 通过C语言直接操作单片机的寄存器,控制硬件功能。 相比汇编语言,C语言代码在不同架构的单片机上更容易移植。 尽量减少全局变量使用,优先使用局部变量 数据类型:如int、char、float、double等。
变量与常量:变量用于存储数据,常量用于表示固定值。
运算符:如算术运算符、逻辑运算符、位运算符等。
控制结构:如if语句、for循环、while循环等。
函数:用于封装代码,实现模块化编程。 检查数组边界,优先使用静态内存。 关注寄存器操作、GPIO 控制、中断机制、低功耗设计 不要滥用动态内存分配(如malloc),因为嵌入式环境不支持或资源有限。 单片机与C语言编程基础是嵌入式系统开发的重要组成部分。
页:
[1]