梳理嵌入式单片机C语言基础
梳理一下嵌入式单片机C语言基础,数据类型、关键字、指针这些。
文章目录
- 一、数据类型
- 二、C语言关键字
- 1.static
- 2.const
- 3.extern
- 4.volatile
- 5.typedef
- 6.enum
- 7.struct
- 三、指针
- 四、条件编译
- 总结
一、数据类型
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++; //每进入一次中断就加1if(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.cextern u8 action_fig;
为了代码的美观可读性,我们通常把extern修饰的语句放在ui.h或者eye.h文件里,这样只要其他.c或者.h包含了这个ui.h文件就可以直接使用了。
//ui.hextern 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语言基础,顺便记录一下所学,希望能对你有帮助。
梳理嵌入式单片机C语言基础相关推荐
- c语言中void delay0.5(),第5章补充 单片机C语言基础.ppt
第5章补充 单片机C语言基础.ppt 2.中断函数举例 例4-16 本例程序电路图可参考图4-1.下面的程序的功能是:对外部中断1中断次数计数,并送P0口显示. #include unsigned c ...
- MSP430初学:MSP430单片机C语言基础(一)
前言 1.<MSP430单片机应用基础与实践>(华中科技大学出版社)-第1章-MSP430单片机C语言基础 2.B站视频视频总结 3.自己 (本文章作备忘录使用) 内容(概要) 1.1标识 ...
- 单片机c语言0x 1x,科目1单片机C语言基础.doc
科目1单片机C语言基础 二进制:数字电路中的两种电平特性决定了它 0 0 6 110 1 17111 2 1081000 3 1191001 4 100101010 5 10111 1011 十六进制 ...
- 单片机c语言基础知识,c语言必背100代码有哪些?
我记得刚开始接触编程的时候,觉得太难了. 也很好奇,写代码的那些人也太厉害了吧?全是英文的,他们的英文水平一定很好吧? 他们是怎么记住这么多代码格式的?而且错了一个标点符号,整个程序都会有影响. 一个 ...
- MSP430初学:MSP430单片机C语言基础(二)
目录 前言 1.进制转换 2.数值数据的表示 3.计算机的码制 前言 1.<MSP430单片机应用基础与实践>(华中科技大学出版社)-第0章-计算机的基础知识 2.B站视频视频总结 3.自 ...
- 手把手教你学51单片机-C语言基础
二进制.十进制和十六进制 对于二进制来说,8 位二进制我们称之为一个字节. 我们在进行 C 语言编程的时候,我们只写十进制和十六进制,那么不带 0x 的就 是十进制,带了 0x 符号的就是十六进制. ...
- 单片机c语言cy,单片机c语言基础教程
例 1-1: 让接正在 P1.0 引脚上的LED 照射. 图1-1 接有LED 的单片机根本通路 P1.0 EA/VPP VCC XTAL2 XTAL1 GND RST +5V +5V + R1 E1 ...
- c语言入门自学书籍推荐6,菜鸟自学嵌入式之C语言基础No6 算法分析
一.冒泡法(起泡法) 算法要求:用起泡法对10个整数按升序排序. 算法分析:如果有n个数,则要进行n-1趟比较.在第1趟比较中要进行n-1次相邻元素的两两比较,在第j趟比较中要进行n-j次两两比较.比 ...
- 初学者怎么学单片机,嵌入式单片机培训机构有用吗?
我从业10余年,一直从事单片机开发,目前也算是行业内的老油条了. 之前很多的同事,做硬件开发的,测试的,或者想学单片机的小伙伴们都会问这个问题"初学者怎么学单片机" 我也是从一个小 ...
最新文章
- linux下配置tomcat、resin
- 双代号网络图节点编号原则_『干货』二级建造师考试高频考点 双代号网络图的详细解析...
- 【实习之T100开发】T100 单档程序开发(2)添加功能
- html input 的value变颜色,vue里input根据value改变背景色的实例
- [转]Stream 和 byte[] 之间的转换
- [HTML] Prettify 代码高亮使用总结
- 产品经理面试题(面试经历)
- 除了Stripe,Paypal国内还能使用哪些海外支付接口
- excel快捷键设置
- Autovue Client/Server 性能优化
- UNITY 2015 大会 观展记录
- 使用css中的white-space:pre-wrap;让html浏览器显示空白空格符
- 大数据征信|芝麻信用、腾讯信用和51信用卡等信用评分模型解析
- 宽带常见的有20 30 50 100兆指的是什么意思???
- html怎么搞滚动字幕,抖音滚动字幕怎么弄 滚动字幕怎么做
- html视频滑动抖音代码,抖音 - 分享代码,大鱼海棠,片段滚动效果代码!
- 面向对象编程练习(一)
- 您有一份来自COSCon'21的志愿者感谢信,请查收!
- 【Linux运维-集群技术进阶】集群/分布式环境下5种session处理策略
- 如何在Android上设置默认短信应用
热门文章
- 生鲜价目表制作 水果价目表 蔬菜价目表
- freee Programming Contest 2022(AtCoder Beginner Contest 264)A~D题详细讲解
- python实现对简单的运算型验证码的识别【不使用OpenCV】
- Android 录屏时的帧率控制
- 程序员的奋斗史(二十一)——我们的大学观
- [Arduino] 基于Xbee Pro和网络技术的智能公交系统设计
- 2021年全国矢量数据,ENVI,ArcGIS,SuperMap制图数据。
- 泄露八股文最新面试题,“死记”这些你也可以斩获阿里offer
- java插件不存在,java – Maven shade插件找不到’mainClass’异常?
- MATLAB中Full-BNT库的使用以及部分问题解决