文章目录
一、数据类型
C语言里有很多数据类型,有整型、浮点型、字符型、结构体、枚举类型等等。
在那么多数据类型中,整型和字符型用的更频繁一些,其中一个字符型占一个字节(8位),而一个整型占4个字节(32位)。根据数据范围,他们又分成好几种数据类型,下面列举51、stm32等单片机开发常用的几个字符型数据类型。
C语言的数据类型 | stm32对应的数据类型 | 数值范围 |
---|---|---|
signed char | int8_t | -128~+127 |
unsigned char | uint8_t (u8) | 0-255 |
signed char | int16_t | -32768~+32767 |
unsigned char | uint16_t (u16) | 0-65535 |
signed char | int32_t | -231~231-1 |
unsigned char | uint32_t (u32) | 0~232-1 |
很多情况下,字符型数据也够用了。
二、C语言关键字
1.static
static用来修饰变量或者函数,可以修饰全局变量或者局部变量。
static用来修饰函数的时候,只能在这个.c文件里调用。
static用来修饰变量的时候,只能在这个.c文件或者这个函数里调用。
比如下面比较典型的,在定时器中断服务函数里使用static 修饰变量Count,每次进入这个函数时Count 不会被重新赋值,是上一次累加的值,这样每进入一次中断就加1。因此static 可以做数据统计使用。
void TIM2_IRQHandler(void) //TIM2中断服务函数
{
static u32 Count = 0; //Count初始值是0,往后都是上一次累加的值。
if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
{
TIM_ClearITPendingBit(TIM2, TIM_IT_Update );
Count++; //每进入一次中断就加1
if(Count>=30)
{
Beep_on();
}
}
}
2.const
const修饰的变量的值不可以被修改,只能读,不可写。
比如我们要读取某个传感器输出的数值或者gpio的电平时,也可以用
const u8 Re_val =GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2); //读取PA2引脚的电平
const修饰一般常量及数组
int const a = 100;
const int a = 100; //与上面等价
int const arr [3] = {1,2,3};
const int arr [3] = {1,2,3};//与上面等价
对于这些基本的数据类型,修饰符const可以用在类型说明符前,也可以用在类型说明符后,其结果是一样的。
const修饰指针(*),主要有以下几种类型:
char *p = "hello"; // 非const指针,
// 非const数据
const char *p = "hello"; // 非const指针,
// const数据
char * const p = "hello"; // const指针,
// 非const数据
const char * const p = "hello"; // const指针,
// const数据
当为常量指针时,不可以通过修改所指向的变量的值,但是指针可以指向别的变量。
int a = 5;
const int *p =&a;
*p = 20; //error 不可以通过修改所指向的变量的值
int b =20;
p = &b; //right 指针可以指向别的变量
当为指针常量时,指针常量的值不可以修改,就是不能指向别的变量,但是可以通过指针修改它所指向的变量的值。
int a = 5;
int *const p = &a;
*p = 20; //right 可以修改所指向变量的值
int b = 10;
p = &b; //error 不可以指向别的变量
3.extern
extern的作用:它通常的作用是用来修饰全局变量或者函数。被修饰的变量和函数在别的地方已经声明定义过,在另一个文件.c文件引用可以它的对应.h头文件引入,就用extern来实现。
例如在ui.c中定义了这个action_fig变量:
//ui.c
u8 action_fig =0;
我们要在另一个eye.c使用到action_fig变量,就可以在eye.h文件下添加:
//eye.c
extern u8 action_fig;
为了代码的美观可读性,我们通常把extern修饰的语句放在ui.h或者eye.h文件里,这样只要其他.c或者.h包含了这个ui.h文件就可以直接使用了。
//ui.h
extern u8 action_fig;
还有另一个作用就是在C++文件中,对嵌入C语言的部分指定使用C编译器解析程序时,用使用:extern “C” 来指明。
4.volatile
Volatile关键字的主要有两个作用:
1.线程的可见性:当一个线程修改一个共享变量时,另外一个线程能读到这个修改的值。
2. 顺序一致性:禁止指令重排序。
5.typedef
作用是为一种数据类型定义一个新名字,这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)。
比如前面stm32对应的数据类型里的uint8_t 其实就是unsigned char。
typedef unsigned char uint8_t
6.enum
枚举类型,例如stm32的引脚速度配置:
typedef enum
{
GPIO_Speed_10MHz = 1,
GPIO_Speed_2MHz,
GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;
列举了三个变量,GPIO_Speed_10MHz 的值为1,GPIO_Speed_2MHz默认赋值为2,GPIO_Speed_50MHz默认赋值为3.
7.struct
结构体,就类似于一个数组,与数组不同的是,结构体中的元素可以是我们自定义的不同类型的变量,结构体元素可以是int,float,char等不同类型,更确切地来说,结构体就像是个大集合,这个集合中能够包含我们想要的任何元素。
typedef struct
{
uint16_t GPIO_Pin;
GPIOSpeed_TypeDef GPIO_Speed;
GPIOMode_TypeDef GPIO_Mode;
}GPIO_InitTypeDef;
这段代码包含了两步操作:首先是定义了一个结构体,其中包含了GPIO_Pin、GPIO_Speed、GPIO_Mode等不同类型成员,然后将本结构体取一个新的变量名为GPIO_InitTypeDef。
在使用的时候,先定义一个结构体变量,然后用成员运算符变量名.成员名
GPIO_InitTypeDef GPIO_InitStructure; //定义一个引脚初始化的结构体
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
这里提一下成员运算符 . 与指向运算符 -> 的区别
1、当使用成员运算符的时候,定义普通的变量,同样在C++中就是定义类的普通对象,然后就可以用成员运算符访问变量或者
对象的数据成员和成员函数。
struct Student
{
int a;
}stu1;//stu1是一个变量
stu1.a;
使用时候可以直接进行访问 stu1.a;使用的就是成员运算符。
2、当使用指向运算符的时候,需要定义一个指针。->是一个整体,它是用于指向结构体、C++中的class等含有子数据的指针用来取子数据。换种说法,如果我们在C语言中定义了一个结构体,然后申明一个指针指向这个结构体,那么我们要用指针取出结构体中的数据,就要用到“->”.
struct Student
{
int a;
};/*定义结构体*/
struct Student * p; /*定义结构体指针*/
stu2->a;
三、指针
指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。玩单片机底层的肯定要对它有一定了解,关于指针可以参考一下B站的一个视频,讲的通俗易懂:Bilibili_从计算机底层认识指针!深入理解C语言指针
他用了一个译码器(4输入16输出)做比喻,如下图:
&a 的运算结果是一个指针,指针的类型是a 的类型加个*, 指针所指向的类型是a 的类型,指针所指向的地址,也就是a 的地址。
p=0xf;对应上面的111B
*p;对应上面的变量a,就是第16个字节
也可以参考一下这篇文章:让你不再害怕指针——C指针详解(经典,非常详细)
四、条件编译
条件编译,直接看下面代码
#define out_fig 1
#if out_fig
语句1();
#elseif
语句2();
#endif
这段代码的意思就是,如果out_fig 为真则编译执行语句1(),如果out_fig 为假则编译执行语句2()。现在我们用#define 宏定义out_fig的值为1,所以编译器会编译语句1()的内容,语句2()的内容就相当于被注释掉了。
总结
以上就是简单梳理一下嵌入式单片机C语言基础,包括了常用的数据类型、几个常见的关键字,指针,还有列举一个条件编译的例子。关于C语言的知识还有很多,这里主要是梳理嵌入式单片机C语言基础,顺便记录一下所学,希望能对你有帮助。
评论(0)
您还未登录,请登录后发表或查看评论