STM32单片机C语言

1、stdint.h简介

stdint.h 是从 C99 中引进的一个标准 C 库的文件

路径:D:\MDK5.34\ARM\ARMCC\include

大家都统一使用一样的标准,这样方便移植

配置MDK支持C99

位操作

如何给寄存器某个值赋值

举个例子:uint32_t temp = 0;

宏定义

带参数的宏定义

https://blog.csdn.net/xiaoyilong2007101095/article/details/77067686

去看一下宏定义

c 复制代码
#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) 来 构造宏定义,这样不会受到大括号、分号、运算符优先级等的影响,总是会按你期望的方式调用运行!

假设LED1(1)参数为真 ,那么就执行第一句,如果是LED1(0),那么就执行第二句

条件编译

让编译器只对满足条件的代码进行编译,不满足条件的不参与编译!

extern声明

类型别名(typedef)

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

c 复制代码
/*typedef   现有类型   新名字*/
typedef  unsigned  char uint8_t;
typedef  unsigned  short int uint16_t;
typedef  unsigned  int uint32_t;

类型别名应用

下面是结构体应用typedef

c 复制代码
struct GPIO_TypeDef
{
     __IO uint32_t   CRL;
     __IO uint32_t   CRH;
     //...
};
struct GPIO_TypeDef gpiox;   //声明

typedef struct
{
     __IO uint32_t   CRL;
     __IO uint32_t   CRH;
     //...
} GPIO_TypeDef;
GPIO_TypeDef gpiox;  //声明

在C中定义一个结构体类型要用typedef:

c 复制代码
typedef struct Student
{
	int a;
}Stu;

于是在声明变量的时候就可:Stu stu1;

如果没有typedef就必须用struct Student stu1;来声明

这里的Stu实际上就是struct Student的别名。

另外这里也可以不写Student(于是也不能struct Student stu1;了)

c 复制代码
typedef struct
{
	int a;
}Stu;

但在c++里很简单,直接

c 复制代码
struct Student
{
	int a;
};

于是就定义了结构体类型Student,声明变量时直接Student stu2;

2其次:

在c++中如果用typedef的话,又会造成区别:

c 复制代码
struct Student
{
	int a;
}stu1;//stu1是一个变量
typedef struct Student2
{
	int a;
}stu2;//stu2是一个结构体类型

使用时可以直接访问stu1.a

但是stu2则必须先 stu2 s2;

然后 s2.a=10;

3 掌握上面两条就可以了,不过最后我们探讨个没多大关系的问题

如果在c程序中我们写:

c 复制代码
typedef struct
{
	int num;
	int age;
}aaa,bbb,ccc;

结构体

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

c 复制代码
struct   结构体名
{
          成员列表;
} 变量名列表(可选);
c 复制代码
struct student
{
    char  	*name;		/* 姓名 */
    int     	num;  		/* 学号 */
    int     	age; 			/* 年龄 */
    char	group;  		/* 所在学习小组 */
    float  	score;  		/* 成绩 */
}stu1, stu2;

应用举例(定义&使用)

c 复制代码
struct student
{
    char  	*name;		/* 姓名 */
    int     	num;  		/* 学号 */
    int     	age; 			/* 年龄 */
    char	group;  		/* 所在学习小组 */
    float  	score;  		/* 成绩 */
};

struct student stu3,stu4;
stu3.name = "张三";
stu3.num = 1; 
stu3.age = 18; 
stu3.group = 'A';
stu3.score = 80.9;

用上typedef

c 复制代码
typedef struct
{
    char  	*name;		/* 姓名 */
    int     	num;  		/* 学号 */
    int     	age; 			/* 年龄 */
    char	group;  		/* 所在学习小组 */
    float  	score;  		/* 成绩 */
}student;

student stu3,stu4;
stu3.name = "张三";
stu3.num = 1; 
stu3.age = 18; 
stu3.group = 'A';
stu3.score = 80.9;

应用举例(ST源码,使用类型别名)

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

指针

指针就是内存的地址

指针变量是保存了指针的变量

类型名 * 指针变量名

c 复制代码
char * p_str = "This is a test!"; 
//*p_str:*是间接寻址运算符,取p_str变量的值,p_str是指针,*p_str就是取指针p_str指向的地址的值,实际就是'T'
//p_str是地址,p_str[0] 和 *p_str 一样都是 'T'
//&p_str:取p_str变量的地址,取指针的地址
举例
c 复制代码
uint8_t  buf[5] = {1, 3, 5, 7, 9}; 
uint8_t  * p_buf = buf;
*p_buf = ? 
p_buf[0] = ?
p_buf[1] = ?
p_buf++;
*p_buf = ?
p_buf[0] = ?
c 复制代码
uint8_t  buf[5] = {1, 3, 5, 7, 9};  //假设此时buf的首地址为0x0002
uint8_t  * p_buf = buf;   //此时指针指向地址0x0002
//下面就是答案
*p_buf = 1   //此时 p_buf和buf一样指向地址为0x0002的空间
p_buf[0] = 1
p_buf[1] = 3
p_buf++;    //此时指针指向地址0x0003
*p_buf = 3  //此时指针指向地址0x0003
p_buf[0] = 3  //此时指针指向地址0x0003
指针使用的2大最常见问题

1,未分配(申请)内存就用

2,越界使用

c 复制代码
//错误用法(未分配内存)
char * p_buf;
p_buf[0] = 100;
p_buf[1] = 120;
p_buf[2] = 150;
c 复制代码
//错误用法(越界使用)
uint8_t  buf[5] = {1, 3, 5, 7, 9}; 
uint8_t  * p_buf = buf;
p_buf[5] = 200;
p_buf[6] = 250;

嵌入式单片机 C代码规范与风格

规范的关键点:

  1. 所有函数/变量名字非特殊情况,一般使用小写字母;
  2. 注释风格使用 doxgen 风格,除屏蔽外,一律使用 /* */ 方式进行注释;
  3. TAB 键统一使用 4 个空格对齐,不使用默认的方式进行对齐;
  4. 每两个函数之间,一般有且只有一个空行;
  5. 相对独立的程序块之间,使用一个空行隔开;
  6. 全局变量命名一般用 g_开头,全局指针命名一般用 p_开头;
  7. if、 for、 while、 do、 case、 switch、 default 等语句单独占一行,
    一般无论有多少行执行语句,都要用加括号: {}。
相关推荐
the sun342 小时前
STM32---串口通信USART
stm32·单片机·嵌入式硬件
jacklood3 小时前
基于cubeMX的hal库STM32实现MQ2烟雾浓度检测
stm32·单片机·嵌入式硬件
阿让啊4 小时前
单片机获取真实时间的实现方法
c语言·开发语言·arm开发·stm32·单片机·嵌入式硬件
FightingLod4 小时前
STM32版I²C相亲指南(软件硬件双修版)
c语言·stm32·单片机
狄加山6755 小时前
STM32 SysTick定时器
stm32·单片机·嵌入式硬件
杰尼龟3686 小时前
51单片机的原理图和PCB绘制
单片机·嵌入式硬件·51单片机
Tlog嵌入式6 小时前
STM32提高篇: 蓝牙通讯
stm32·单片机·嵌入式硬件·mcu·iot
猫猫的小茶馆7 小时前
【PCB工艺】运放电路中的负反馈机制
stm32·单片机·嵌入式硬件·51单片机·pcb工艺
小禾苗_7 小时前
32单片机——GPIO的工作模式
单片机·嵌入式硬件