【嵌入式学习笔记】嵌入式基础5——C语言基础

文章介绍了C语言中的stdint.h头文件,用于定义固定宽度的整型类型如uint8_t。还讨论了位操作,包括置位、清零和翻转,以及宏定义的使用和条件编译的作用。此外,提到了extern声明、类型别名typedef、结构体定义和指针操作,最后强调了编写代码时的规范和注意事项。
摘要由CSDN通过智能技术生成

1.stdint.h简介

stdint.h 是从 C99 中引进的一个标准 C 库的文件,路径:D:\MDK5.34\ARM\ARMCC\include
推荐使用符合C99标准的uint8_t、uint16_t、uint32_t等类型别名
注意:配置MDK需要配置支持C99模式
在这里插入图片描述

2.位操作*

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

  • 给变量某个位,置位(例如位6)
temp &= 0xFFFFFFBF;	//位清零               
temp |= 0x00000040; //置位
temp &= ~(1<<6);    //位清零   
temp |= 1<<6; 		//置位
  • 给变量某个位,翻转(例如位6)
temp ^= 0x00000040;
temp ^= 1<<6;

3.宏定义

宏定义可以提高效率、可读性、易改性,核心是替换

#define 标识符 字符串
标识符:宏定义的名字
字符串:常数、表达式、格式串等

  • 一般的宏定义
#define     PI           3.14159
#define     HSE_VALUE    8000000U 
  • 带参数的宏定义
#define LED1(x)  do{  x ? \
                      HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_SET) : \
                      HAL_GPIO_WritePin(LED1_GPIO_PORT, LED1_GPIO_PIN, GPIO_PIN_RESET); \
                 	}while(0)

建议使用 do{ … }while(0)来构造宏定义,这样不会受到大括号、分号、运算符优先级等的影响,总是会按你期望的方式调用运行。具体可以参考https://blog.csdn.net/xiaoyilong2007101095/article/details/77067686

4.条件编译

让编译器只对满足条件的代码进行编译,不满足条件的不参与编译
在这里插入图片描述
头文件的条件编译

#ifndef 	_LED_H
#define 	_LED_H
#include "./SYSTEM/sys/sys.h"
	//code...
#endif

代码条件编译

#if   SYS_SUPPORT_OS
       //code...
#endif

5.extern声明

放在函数/变量前,表示此函数/变量在其他作用域定义,以便本文件引用

extern uint16_t g_usart_rx_sta;
extern void delay_us(uint32_t nus); 

6.类型别名(typedef)

为现有数据类型创建一个新的名字,或称为类型别名,用来简化变量的定义

typedef 现有类型 新名字

typedef   unsigned  char 			uint8_t;
typedef   unsigned  short  int 		uint16_t;
typedef   unsigned  int 			uint32_t;

在类型别名时的应用

struct GPIO_TypeDef
{
     __IO uint32_t   CRL;
     __IO uint32_t   CRH;};
struct GPIO_TypeDef gpiox;	//必须加struct
//等同于,上面的更繁琐
typedef struct
{
     __IO uint32_t   CRL;
     __IO uint32_t   CRH;} GPIO_TypeDef;
GPIO_TypeDef gpiox

更多参考:
https://www.runoob.com/cprogramming/c-structures.html
https://www.runoob.com/cprogramming/c-typedef.html

7.结构体

由若干基本数据类型集合组成的一种自定义数据类型,也叫聚合类型

struct tag {
    member-list
    member-list
    member-list  
    ...
} variable-list ;

在一般情况下,tag、member-list、variable-list 这 3 部分至少要出现 2 个。

typedef struct
{
  uint32_t 	Pin ;		/* 引脚号 */
  uint32_t 	Mode ;		/* 工作模式 */
  uint32_t 	Pull ;      /* 上下拉 */
  uint32_t 	Speed ;		/* IO速度 */
} GPIO_InitTypeDef;

8.指针

指针就是内存的地址,指针就是内存的地址

类型名 * 指针变量名
char * p_str = “This is a test!”;
*p_str:取p_str 变量的值
&p_str:取p_str变量的地址

指针练习

uint8_t  buf[5] = {1, 3, 5, 7, 9}; 
uint8_t  * p_buf = buf;
*p_buf = 1
p_buf[0] = 1
p_buf[1] = 3
p_buf++;
*p_buf = 3
p_buf[0] = 3

指针使用的2大最常见问题:

  • 未分配(申请)内存就用
char * p_buf;
p_buf[0] = 100;
p_buf[1] = 120;
p_buf[2] = 150;
  • 越界使用**
uint8_t  buf[5] = {1, 3, 5, 7, 9}; 
uint8_t  * p_buf = buf;
p_buf[5] = 200;
p_buf[6] = 250;

9.代码规范

规范的关键点:

  1. 所有函数/变量名字非特殊情况,一般使用小写字母;
  2. 注释风格使用 doxgen 风格,除屏蔽外,一律使用 /* */ 方式进行注释;
  3. TAB 键统一使用 4 个空格对齐,不使用默认的方式进行对齐;
  4. 每两个函数之间,一般有且只有一个空行;
  5. 相对独立的程序块之间,使用一个空行隔开;
  6. 全局变量命名一般用 g_开头,全局指针命名一般用 p_开头;
  7. if、 for、 while、 do、 case、 switch、 default 等语句单独占一行, 一般无论有多少行执行语句,都要用加括号: {}。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值