首页 > 其他分享 >STM32深入学习4:标准库

STM32深入学习4:标准库

时间:2023-09-05 23:00:40浏览次数:64  
标签:学习 封装 int unsigned STM32 深入 寄存器 volatile RCC

掌握的标准:

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操作

 bit mask:位掩码,事先把设定的数提前封装好。  RCC_Define()和RCC_HSEConfig()  枚举可以限制参数范围,或者使用assert_param()进行判断——assert机制是c语言中判断对错的工具,使用最多的场景就是判断库函数中传参对不对。 bypass:直接提供了一个外部时钟。 RCC_WaitForHSEStartUp(),返回值为errorstatus,一个枚举量
这是ST库里面的宏定义,定义如下:  
#define __I volatile const  /*!< defines 'read only' permissions*/
#define  __O  volatile      /*  !< defines 'write only' permissions  */
#define __IO  volatile      /* !< defines 'read / write' permissions */

RCC_AdjustHSICalibrationValue()校准

RCC_HSICmd()

 

使用库函数重写系统时钟设定

   
void SysClick_Init(){
    ErrorStatus hse_status;
    //1.开启外部时钟HSE
    RCC_HSEConfig(RCC_HSE_ON);
    //等待HSEON稳定
    hse_status = RCC_WaitForHSEStartUp();
    if(hse_status==SUCCESS){
        FLASH->ACR |= 0x10;
        FLASH->ACR &= (~0x03);
        FLASH->ACR |= 0x02;
        
        //2.设置PLL,HB和APB2未分频,APB1被2分频,
        //配置HCLK为SYSCLK/1;
        RCC_HCLKConfig(RCC_SYSCLK_Div1);
        //APB1被2分频,APB2为HCLK/1
        RCC_PCLK1Config(RCC_HCLK_Div2);
        RCC_PCLK2Config(RCC_HCLK_Div1);
        //选择HSE/1为时钟源,同时设置频率为9倍
        RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);
        //打开PLL开关
        RCC_PLLCmd(ENABLE);
        //等待PLL稳定
        while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET);
        //切换系统时钟为PLLCLK
        RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
        while(RCC_GetSYSCLKSource()!=0x08);
    }else while(1);
        
}

 

 GPIO库解析

标准库中的面向对象的思想

面向对象的三大特征:封装,继承和多态。

各种数据类型结构体就是一种封装。

标准库就是为了被复用。

GPIO的编程模式是典型的面向对象式编程。

步骤:

1.先构造对象

2.用对象构造实例

3.填充实例

4.使用实例

  TRANSLATE with x English
Arabic Hebrew Polish
Bulgarian Hindi Portuguese
Catalan Hmong Daw Romanian
Chinese Simplified Hungarian Russian
Chinese Traditional Indonesian Slovak
Czech Italian Slovenian
Danish Japanese Spanish
Dutch Klingon Swedish
English Korean Thai
Estonian Latvian Turkish
Finnish Lithuanian Ukrainian
French Malay Urdu
German Maltese Vietnamese
Greek Norwegian Welsh
Haitian Creole Persian  
  TRANSLATE with COPY THE URL BELOW Back EMBED THE SNIPPET BELOW IN YOUR SITE Enable collaborative features and customize widget: Bing Webmaster Portal Back     此页面的语言为中文(简体)   翻译为        
  • 中文(简体)
  • 中文(繁体)
  • 丹麦语
  • 乌克兰语
  • 乌尔都语
  • 亚美尼亚语
  • 俄语
  • 保加利亚语
  • 克罗地亚语
  • 冰岛语
  • 加泰罗尼亚语
  • 匈牙利语
  • 卡纳达语
  • 印地语
  • 印尼语
  • 古吉拉特语
  • 哈萨克语
  • 土耳其语
  • 威尔士语
  • 孟加拉语
  • 尼泊尔语
  • 布尔语(南非荷兰语)
  • 希伯来语
  • 希腊语
  • 库尔德语
  • 德语
  • 意大利语
  • 拉脱维亚语
  • 挪威语
  • 捷克语
  • 斯洛伐克语
  • 斯洛文尼亚语
  • 旁遮普语
  • 日语
  • 普什图语
  • 毛利语
  • 法语
  • 波兰语
  • 波斯语
  • 泰卢固语
  • 泰米尔语
  • 泰语
  • 海地克里奥尔语
  • 爱沙尼亚语
  • 瑞典语
  • 立陶宛语
  • 缅甸语
  • 罗马尼亚语
  • 老挝语
  • 芬兰语
  • 英语
  • 荷兰语
  • 萨摩亚语
  • 葡萄牙语
  • 西班牙语
  • 越南语
  • 阿塞拜疆语
  • 阿姆哈拉语
  • 阿尔巴尼亚语
  • 阿拉伯语
  • 韩语
  • 马尔加什语
  • 马拉地语
  • 马拉雅拉姆语
  • 马来语
  • 马耳他语
  • 高棉语
 

标签:学习,封装,int,unsigned,STM32,深入,寄存器,volatile,RCC
From: https://www.cnblogs.com/ustc2122zy/p/17675373.html

相关文章

  • openGauss学习笔记-61 openGauss 数据库管理-常见主备部署方案
    openGauss学习笔记-61openGauss数据库管理-常见主备部署方案61.1单中心图1单中心部署图组网特点:单AZ部署,可以配置一个同步备一个异步备优势:三个node完全等价,故障任意一个node都可以提供服务;成本低。劣势:高可用能力较低,发生AZ级故障只能依赖节点恢复;适用性:适用于......
  • 深入了解Mosquitto:MQTT消息的用法和介绍
    MQTT(MessageQueuingTelemetryTransport)是一种轻量级的消息传输协议,在物联网领域得到广泛应用。Mosquitto是一个流行的MQTT消息代理实现,它允许设备和应用之间进行高效的消息通信。本文将介绍Mosquitto的基本用法和特点,并提供代码演示。什么是Mosquitto?Mosquitto是一个开源的MQTT......
  • 文件上传基础学习
    文件上传基础学习一、基础知识1、上传功能存在漏洞通常,Web应用程序允许用户上传文件,例如图像、文档或其他类型的文件,以便后续处理或共享。漏洞出现在服务器未正确验证或限制上传文件的类型、大小和位置时。2、不正确的输入验证:文件上传漏洞通常是由于不正确的输入验证引起的......
  • 三、(续)vector学习
    1、容器特性1)顺序序列顺序容器中的元素按照严格的线性顺序排序。可以通过元素在序列中的位置访问对应的元素。2)动态数组支持对序列中的任意元素进行快速直接访问,甚至可以通过指针算述进行该操作。操供了在序列末尾相对快速地添加/删除元素的操作。3)能够感知内存分配器的容器使用一......
  • 深入研究消息队列03 各消息队列架构对比
    10RabbitMQ的架构设计与实现系统架构RabbitMQ由Producer、Broker、Consumer三个大模块组成。生产者将数据发送到Broker,Broker接收到数据后,将数据存储到对应的Queue里面,消费者从不同的Queue消费数据。协议和网络模块主要包含tcp_listener、tcp_acceptor、rabbit_reader......
  • C++学习笔记
    C++:C的编译器叫gcc,C++的编译器叫g++c++最容易发生的问题是内存泄漏问题,例如释放p所指的空间时,应该是free(p);p=NULL;很多人忘记将p归零,这样下次不小心调用了p就会出现内存泄漏问题,如果要把释放内存写成函数,示例如下(两层指针)voidfree_mem(int**pp){if(pp==NULL......
  • STL学习笔记
    迭代器迭代器(iterator)是一种抽象的设计概念,现实程序语言中并没有直接对应于这个概念的实物。在<>一书中提供了23中设计模式的完整描述,其中iterator模式定义如下:提供一种方法,使之能够依序寻访某个容器所含的各个元素,而又无需暴露该容器的内部表示方式。迭代器案例#include<ios......
  • 深入理解零拷贝技术
    注意事项:除了DirectI/O,与磁盘相关的文件读写操作都有使用到pagecache技术。数据的四次拷贝与四次上下文切换很多应用程序在面临客户端请求时,可以等价为进行如下的系统调用:File.read(file,buf,len);Socket.send(socket,buf,len);例如消息中间件Kafka就是这个应用场......
  • C++语言学习09
    STL标准模版库STL是StandardTemplateLibrary的缩写,中文名标准模版库,由惠普实验室提供(使用C++模板语言封装的常用的数据结构与算法)STL中有六大组件:算法:以函数模板形式实现的常用算法,例如:swap\max\min\find\sort容器:以类模板的形式实现的常用的数据结构,例如:vector\list\arra......
  • Markdown学习
    Markdown学习标题三级标题四级标题HelloWorld!HelloWorld!HelloWorld!HelloWorld! 引用选择狂神说JAVA,走向人生巅峰 分割线 图片 超链接点击跳转到狂神博客  列表13 ABC 表格名字性别生日张三男1997.1.1......