STM32完全学习3:标准库
掌握的标准:
1.搞清楚库对STM32硬件的封装和表达方式
2.彻底理解苦衷使用的结构体式访问硬件寄存器的方式
3.初步建立起面向对象式编程的概念
4.以模块为单位去研究模块的库函数,并且用库函数编程,实验结果,分析代码,从而熟悉库函数的使用方法
5.思维能够穿透库函数直达内部对寄存器的操作
标准库——方便,由芯片厂商提供数据手册、示例代码、开发环境
整体框架和层次认识,要会没有外设库时C语言直接操作寄存器的方式(看原理图,查数据手册,位操作等)
规范化编程的意识和能力
C语言基础
外设库的结构介绍:
固件库的架构
CMSIS: ARM核心相关内容,大部分由ARM公司决定
CoreSupport:内核相关的寄存器集合及封装
DeviceSupport:startup起始代码
STM32F10x_StdPeriph_Driver:外设驱动
inc(include,头文件,.h)
src(source,源文件,.c)
预先定义了各种寄存器的基地址,可以直接使用
标准库对硬件信息的封装方式
1. 寄存器地址的封装
2.寄存器位定义的封装
3.外设操作的封装
宏定义和API(帮助手册或者源码 )
使用结构体的方式访问寄存器的原理
寄存器的版本:使用C语言访问内存地址,并且赋值
C语言访问寄存器的本质是C语言访问内存,本质思路是定义一个指针(临时变量)指向这块内存,然后解引用*p = xx这种方式去解引用指针,从而向目标内存中写入内容。
缺陷:当寄存器多了之后,每一个寄存器都需要定义,很麻烦
解决思路:打包成结构体,用结构体批量定义。
why:不用数组?
个人理解:使用数组,每个元素之间的距离都是固定的数据类型大小,不能进行数据填充或者调整。
具体做法:把整个模块的所有寄存器(地址相邻)打包在同一个结构体中,每个寄存器对应结构体中的一个元素,然后结构体的基地址对应寄存器组的基地址。
定义了一个结构体,结构体中的数据类型占据大小和寄存器地址对应。
使用结构体的方式访问寄存器的实践
typedef struct{ volatile unsigned int CRL; volatile unsigned int CRH; volatile unsigned int IDR; volatile unsigned int ODR; volatile unsigned int BSRR; volatile unsigned int BRR; volatile unsigned int LCKR; }LED_Typedef;
结构体对齐问题需要考虑,如果存在为空的部分,需要填充padding。或者直接定义一个比较长的结构,只使用低X位或者高X位。
使用标准库重写LED的程序
void LED_Init(){ RCC->APB2ENR = 0x00000010; GPIOC->ODR = 0x00000000; GPIOC->ODR = 0x000000aa; }
对硬件进行了封装
RCC模块的标准库解析
位带操作:将其中一位对应到一个u32的区域,bitband操作
使用库函数重写系统时钟设定
GPIO库解析
标准库中的面向对象的思想
面向对象的三大特征:封装,继承和多态。
各种数据类型结构体就是一种封装。
标准库就是为了被复用。
GPIO的编程模式是典型的面向对象式编程。
步骤:
1.先构造对象
2.用对象构造实例
3.填充实例
4.使用实例
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)