STM32单片机C语言

news2025/5/11 21:05:07

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
去看一下宏定义

#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)

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

/*typedef   现有类型   新名字*/
typedef  unsigned  char uint8_t;
typedef  unsigned  short int uint16_t;
typedef  unsigned  int uint32_t;

类型别名应用
下面是结构体应用typedef

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:

typedef struct Student
{
	int a;
}Stu;

于是在声明变量的时候就可:Stu stu1;
如果没有typedef就必须用struct Student stu1;来声明
这里的Stu实际上就是struct Student的别名。
另外这里也可以不写Student(于是也不能struct Student stu1;了)

typedef struct
{
	int a;
}Stu;

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

struct Student
{
	int a;
};

于是就定义了结构体类型Student,声明变量时直接Student stu2;
2其次:
在c++中如果用typedef的话,又会造成区别:

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

使用时可以直接访问stu1.a
但是stu2则必须先 stu2 s2;
然后 s2.a=10;

3 掌握上面两条就可以了,不过最后我们探讨个没多大关系的问题
如果在c程序中我们写:

typedef struct
{
	int num;
	int age;
}aaa,bbb,ccc;

结构体

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

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

应用举例(定义&使用)

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

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源码,使用类型别名)

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

指针

指针就是内存的地址
指针变量是保存了指针的变量
类型名 * 指针变量名

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变量的地址,取指针的地址

举例
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] = ?

在这里插入图片描述

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,越界使用

//错误用法(未分配内存)
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;

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

规范的关键点:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2338899.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

多模态融合(十一): SwinFusion——武汉大学马佳义团队(二)

目录 一.摘要 二. Introduction 三. Related Work A. 特定任务图像融合方法 B. 通用图像融合方法 C. 视觉 Transformer 四.方法 A. 整体框架 B. 损失函数 C.解析 1. 整体框架 2. 特征提取 3. 注意力引导的跨域融合 五. 实验结果与讨论 A. 实验配置 B. 实现…

IDEA202403常用快捷键【持续更新】

文章目录 一、全局搜索二、美化格式三、替换四、Git提交五、代码移动六、调试运行 在使用IDEA进行程序开发,快捷键会让这个过程更加酸爽,下面记录各种快捷键的功能。 一、全局搜索 快捷键功能说明Shift Shift全局搜索Ctrl N搜索Java类 二、美化格式 …

从 LabelImg 到 Label Studio!AI 数据标注神器升级,Web 版真香

视频讲解: 从 LabelImg 到 Label Studio!AI 数据标注神器升级,Web 版真香 Label Studio 支持图像、文本、音频、视频、时间序列等多类型数据标注,覆盖计算机视觉(目标检测、语义分割)、自然语言处理&#x…

【ESP32】ESP-IDF开发 | 低功耗蓝牙开发 | GAP协议 + 设备扫描例程

1. 简介 1.1 GAP协议 GAP(General Access Protocol),全称通用访问协议,它定义了低功耗蓝牙设备的发现流程,设备管理和设备连接的建立。 低功耗蓝牙设备定义了4种角色: 广播者(Broadcaster&…

网络开发基础(游戏)之 Socket API

Socket简介 Socket (套接字)是网络编程的基础,在 C# 中通过 System.Net.Sockets 命名空间提供了一套完整的 API 来实现网络通信。 网络上的两个程序通过一个双向的通信连接实现数据交换, 这个连接的一端称为一个Socket。 一个Socket包含了进行网络通信必…

行为审计软件:企业合规与内部监控的数字守门人

在当今高度数字化的商业环境中,企业运营产生的电子数据呈指数级增长,员工行为也日益复杂多样。行为审计软件应运而生,成为现代企业管理不可或缺的工具。这类软件通过系统化记录、分析和报告组织内部用户活动,帮助企业管理风险、确…

bat脚本转换为EXE应用程序文件

很多时候,我们使用电脑时会编辑bat脚本文件 很多时候,我们制作的玩笑,病毒也会使用这个格式. 但这个格式也有很多缺点 1,如果是需要管理员运行的程序,需要费劲的自己使用管理员身份运行 2,文件并不为大家所熟知,认同度不高 3,可以非常轻松的看到原代…

细说STM32单片机FreeRTOS任务管理API函数vTaskList()的使用方法

目录 一、函数vTaskList() 1、 函数说明 2、返回的字符串表格说明 3、函数的使用方法 二、 vTaskList()的应用示例 1、示例功能、项目设置 2、软件设计 (1)main.c (2)freertos.c (3)FreeRTOSConf…

DNS主从同步

安装软件 主配置中完成DNS解析:192.168.131.134 [rootlocalhost ~]# mount /dev/sr0 /mnt [rootlocalhost ~]# vim /etc/yum.repos.d/myrepo.repo [base] namebase baseurl/mnt/BaseOS gpgchcek0 enable1 [base2] namebase2 baseurl/mnt/AppStream gpgchcek0 enab…

双指针算法(部分例题解析)

快慢指针左右指针 前言 双指针,它通过设置两个指针来遍历数据,从而实现高效的查找、排序、去重等操作。双指针算法的核心在于通过合理地移动这两个指针,减少不必要的遍历,提高算法的效率。 283. 移动零 - 力扣(LeetCo…

解决Windows打印问题的集成软件

家里或公司电脑经常为连不上打印机而烦恼,今天给大家推荐一款修复打印工具,该工具是采用易语言开发的集成化打印机故障修复软件,专为解决 Windows 系统(含 32/64 位 Windows 7/10/11)中因权限配置、服务异常、补丁缺失…

警惕阿里云中的yum update操作不当导致:/sbin/init被清空导致Linux无法正常启动

由于使用阿里云进行部署测试,因而会对yum update进行操作,这两天更新了systemd-239-82.0.3.4.al8.2.x86_64,但存在报错,然后进行yum history undo和清空yum cache,但出现操作Linux命令行无效。具体来说,几个…

关系型数据库MYSQL(续)

目录 三.MySQL事务原理分析 1.事务是什么? 2.执行事务的目的是什么? 3.事务是由什么组成的? 4.事务的特征是什么? 5.事务控制语句 6.ACID特性 6.1原子性(A) 6.2隔离性(I) …

WInform当今技术特性分析

Windows Forms (WinForms) 技术特性分析 引言 Windows Forms (WinForms) 作为微软最早推出的基于.NET的图形用户界面开发框架,已经存在了20多年。在如今充满了各种现代UI框架的软件开发生态系统中,WinForms仍然保持着其独特的地位。本文将深入分析WinF…

运筹学之模拟退火

目录 一、历史二、精髓思想三、案例与代码实现 一、历史 问:谁在什么时候提出模拟退火?答:模拟退火算法(Simulated Annealing,SA)是由斯图尔特柯尔斯基(Scott Kirkpatrick) 等人在 …

树莓派5-开发应用笔记

0.树莓派系统目录 /home:用户目录。 除了root用户外,其他所有的使用者的数据都存放在这个目录下,在树莓派的系统中,/home目录中有一个pi的子目录,这个就是pi用户的默认目录。 /bin: 主要放置系统的必备执行文件目录。 …

8.5/Q1,Charls最新文章解读

文章题目:Atherogenic index of plasma, high sensitivity C-reactive protein and incident diabetes among middle-aged and elderly adults in China: a national cohort study DOI:10.1186/s12933-025-02653-4 中文标题:中国中老年人群血…

k8s 调整Node节点 Max_Pods

默认情况下,Kubernetes集群中一个Node最多能起110个Pod。 这是基于性能和资源管理的考虑,以确保Kubernetes集群的稳定性和可靠性。 查看kht125节点上支持的最大pod数量: kubectl describe node kht125 | grep -i “Capacity|Allocatable” -A 6 调整…

使用Service发布前后端应用程序

使用Service发布前后端应用程序 文章目录 使用Service发布前后端应用程序[toc]一、创建并发布后端应用程序二、创建并发布前端应用程序三、通过前端发送流量进行测试 部署前端(Frontend)微服务和后端(Backend)微服务是比较常见的应…

Ubuntu20.04下Docker方案实现多平台SDK编译

0 前言 熟悉嵌入式平台Linux SDK编译流程的小伙伴都知道,假如平台a要求必须在Ubuntu18.04下编译,平台b要求要Ubuntu22.04的环境,那我只有Ubuntu20.04,或者说我的电脑硬件配置最高只能支持Ubuntu20.04怎么办?强行在Ubuntu20.04下编译,编又编不过,换到旧版本我又不愿意,…