stm32学习之路,方法很重要

2023-05-16

学习stm32已经一个月时间了,可算是入门了。

相信很多人跟我一样,刚开始学的时候会遇到很多问题,以及对stm32里面众多寄存器的恐惧。要利用stm32官方给的固件库开发,少不了的还是要对寄存器有一定的了解。下面我就谈谈我的入门之路吧。

刚开始接触到的时候,还是看原子的视频,但是那个视频就想大型连续剧一样,一看时长就让人没什么欲望学下去了,而且,前面有有两三个小时都是都是些芯片的基本的介绍和选型手册的介绍,其实刚开始学,没必要了解这么多,后面学习有关功能的使用再去了解,就自然能看懂那些手册了,所以原子的视频,我看了几节,是真没什么学习的欲望了。

后面我自己在b站上找到了海创电子的stm32的视频还是学习,海创的教学视频比原子的讲得通俗易懂,而且刚开始学,讲了最最基本的操纵地址去控制IO口,然后是讲了固件库中的宏替换的地址,然后去推算各个外设,GPIO,时钟等等的地址,然后一步一步仿照库函数优化程序,这其中也包含了结构体,枚举,结构体指针的传递等等c语言的知识,然后就是一边看海创的视频,一边复习c语言,慢慢的基本也就能看懂固件库中那些初始化函数的参数是怎么传递到寄存器中的了。

再次强调一下,一定要多去看C语言后面那部分,因为固件库中的参数传递会涉及到。
即使是使用固件库开发,也还是要对寄存器有一定了解。

下面是刚开学的时候,了解到的最底层的操作方式,加上自己的一些理解。

int main(void)
{
	*(unsigned int*)0x4002 1018 |=(1<<4);//打开时钟
	*(unsigned int*)0x40011004 &= ~(0x0F<<(4*5));//配置输出模式
    *(unsigned int*)0x40011004 |= (1<<20);
    *(unsigned int*)0x4001 100C&=~(1<<13)//配置输出低电平
    *(unsigned int*)0x4001 100C|=(1<<13)//配置输出高电平
}

Stm32最最底层、完全暴力的方式点亮LED,可读性比较差。
以PC13引脚输出高低电平
//根据单片机的地址映射,查找到相应总线地址,再去查找相应的GPIO的地址(可直接查表,也可根据相对总线的地址去算偏移地址),在相应的GPIO下面,又有对应的寄存器的地址,最后就可以算出要操作的寄存器的地址。

关于上面这段文字,如果看不懂的话,那么你就要去看一看stm32存储器的映射了。

找到相应的地址后,这个还只是一个数字,跟程序没有关系,通过定义一个(unsigned int*)类型的指针,把这个数字转换成单片机能够识别的相应的地址,再在这个地址前面加上*,如*(unsigned int*)0x4002 1018,就可以对它进行赋值了,*表示取地址的内容。

这些数字就是寄存器所在的地址。
下面的程序和上面的是一个意思,只是把相应的地址操作用#define替换成了相应的寄存器名字。

#define PERIPH_BASE   0x4000 0000
//片上外设基地址
#define  APB1PERIPH_BASE   PERIPH_BASE     // APB1总线地址
#define  APB2PERIPH_BASE   (PERIPH_BASE+0x00010000)  //APB2总线地址
#define  AHBPERIPH_BASE   (PERIPH_BASE+0x00020000)  //AHB总线地址

#define  RCC_BASE  (AHBPERIPH_BASE+0x1000)   //时钟地址
#define  RCC_APB2ENR  *(unsigned int*)(RCC_BASE+0x18)  
//APB2外设时钟使能寄存器地址

#define  GPIOC_BASE    (APB2PERIPH_BASE+0x00010000)   //GPIOC地址
//GPIOC相关寄存器的地址
#define GPIOC_CRL          *(unsigned int *)( GPIOC_BASE+0x00)
#define GPIOC_CRH          *(unsigned int *)( GPIOC_BASE+0x04)
#define GPIOC_IDR          *(unsigned int *)( GPIOC_BASE+0x08)
#define GPIOC_ODR          *(unsigned int *)( GPIOC_BASE+0x0C)
#define GPIOC_BSRR         *(unsigned int *)( GPIOC_BASE+0x10)
#define GPIOC_BRR          *(unsigned int *)( GPIOC_BASE+0x14)
#define GPIOC_LCKR         *(unsigned int *)( GPIOC_BASE+0x18)
这些宏定义可直接定义在头文件中。
以上实现过程都是先找到基地址,再经过偏移取找到相应的地址


int main(void{
	RCC_APB2 |=(1<<4);//打开时钟
	GPIOC_CRH &= ~(0x0F<<(4*5));//配置输出模式
    GPIOC_CRH |= (1<<20);
    GPIOC_ODR&=~(1<<13);//配置输出低电平
    GPIOC_ODR|=(1<<13);//配置输出高电平
}

这样可读性就要强很多了。
后面又是了解到了固件库中对很多寄存器都是封装了的

由于GPIOA—GPIOG有众多组,每组有7个寄存器,如果每次都去找地址再用宏替换,就会写很多,实际上每个GPIO组,里面的7个寄存器都是一样的,所以可以直接把这七个寄存器定义在一起(采用结构体方式)

typedef unsigned int uint32_t;4字节)
typedef struct 
{
	uint32_t CRL;
	uint32_t CRH;
	uint32_t IDR;
	uint32_t ODR;
	uint32_t BSRR;
	uint32_t BRR;
	uint32_t LCKR;
}GPIO_TypeDef;

这样封装的目的,当然是为了方便开发者使用时更方便调用。

下面的解读,很重要!很重要!很重要!
结构体中定义的变量都是连续排列的,恰好每个寄存器都是32位的,占用4个字节,这个就和每个寄存器在实际的存储器映像中偏移量是一样的了,看上面的结构体,我们只需要,定义一个结构体指针,让他指向需要使用到的GPIO口的地址就可以了。就相当于给了一个入口地址,再用结构体指针,就很容易的引用其中的成员变量了。

#define GPIOC ((GPIO_TypeDef*)GPIOC_BASE)

这条语句中,GPIOC_BASE是之前用宏定义过的GPIOC的地址(只是一个数值),前面加上一个(GPIO_TypeDef*)把他转换为单片机能够识别的地址。这里的GPIOC_BASE就相当于给这个结构体传递了一个GPIO口的地址,然后就可以很方便的引用GPIO口中的寄存器了。

上面这条语句的意思就是用GPIOC替换替换了 (GPIO_TypeDef*)类型的GPIOC的地址
如果要引用GPIOC中的寄存器,用结构体成员指针就ok。
GPIOC->CRH GPIOC->ODR

时钟相关的寄存器定义也和GPIO口差不多。

基本学习了这些,对固件库中的一些东西也有了初步的认识了,别说使用库函数开发就不用看这些,那都是些屁话。

后面就是具体学习了
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
这个函数的参数传递过程,不得不说这些工程师是真的牛逼,基本了解完这个函数的参数传递之后,其他的函数传递都差不多。就对stm32这些函数有个初步的认识了吧。

这些了解完之后,就可以开始学习,stm32的模板学习了,刚开始接触的时候,我想大多数人和我一样,并不想用这个模板,因为我们以前写的51,arduino,基本一个工程就一个文件,很简单,stm32的模板一下子多了这么多东西,肯定是不知道从何下手的。

对于模板的学习呢,首先是要了解这个模板是怎么配置的,哪些文件是必须的,哪些不必要的,以及各个文件都是关于什么模块的,这些了解清楚之后,差不多就有一个初步认识了,然后再去了解一下MDK软件是怎么运行的,差不多你就知道为什么需要启动文件,和为什么不需要SYsInit()这个函数了,因为有些东西是在启动文件中定义过了,启动文件也决定了这个程序的入口。

模板配置好之后,就可以开始学习各个模块了,由于是用的库函数开发,所以并不推荐大家像之前那样去学习,因为你会发现学习效率非常低,很难就不说了,众多的寄存器,一会又要操作这个寄存器,一会那个寄存器,很快就绕晕了。

所以学习这部分,我也是转变了思路
1,学习工作原理,比如中断,怎么实现中断,中断检测的是什么,怎么去管理中断,定时器时间的计算,pwm的频率计算等等
2,配置的相关初始化函数,这部分,所用到函数我都会去固件库查功能,相应的参数,再结合原理去理解每个参数干嘛用的。
3,配置自己的模板,这个是我们自己的模板,比如要用pwm模块,自己配置一个PWM.c文件和PWM.h文件。
4,剩下的就是学习相关驱动模块了,比如电机,舵机,编码器,角度传感器等等。
5,使用库函数开发的时候,不要过多的纠结寄存器怎么配置的,用到了哪些寄存器,心里有个数就好,用自己配置好的模板来开发项目。
7.推荐大家找本实战开发的书,再配合原子的视频或者一些博主写的学习笔记学习学习,这样会比单看视频或者书有用得多。

我目前就是这样学习stm32的,我想等我把32的外设资源都学得差不多了,差不多就可以去了解stm32内核哪些事了。

这些学习经历分享给初学的朋友们,希望你们戒骄戒躁,一步一步一个脚印。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

stm32学习之路,方法很重要 的相关文章

  • k8s监控prometheus+Grafana

    Kubernetes集群资源监控 概述 监控指标 一个好的系统 xff0c 主要监控以下内容 集群监控 节点资源利用率节点数运行PodsPod监控 容器指标应用程序 程序占用多少CPU 内存 监控平台 使用普罗米修斯 prometheus
  • python学习(猜数字游戏)

    import random x 61 int random randint 0 10 i 61 1 print 39 39 39 欢迎进入猜数字小游戏 xff01 本次游戏机会只有三次 xff01 小伙伴拼手气的机会到了哟 xff01 39
  • python脚本批量创建job并自动添加视图

    由于我们项目jenkinsfile和deployment yaml都是单独分开放在git仓库上管理的 xff0c 脚本实现的是通过批量创建对应的文件和job任务自动提交git仓库 xff0c 并把job加入到视图里 xff01 话不多说贴脚
  • 远程登陆Ubuntu服务器anaconda的使用问题(多用户)

    远程登录Ubuntu的新用户在使用 conda 命令时 xff0c 可能会遇到找不到 conda 命令的情况 xff0c 因此在多用户使用 anaconda 的情况下 xff0c 需要提前在 Ubuntu 服务器上做一下 anaconda
  • telnet批量检查端口是否正常

    一 本机测试目标端口是否正常 xff1a python调用的socket模块来实现 xff1a usr bin python3 import socket ip 43 port 描述 ip prot 61 39 39 39 0 0 0 0
  • mongo副本集一主两从读写分离部署

    mongodb 副本集部署 mongodb 0 gt 3717 mongodb 1 gt 3718 mongodb 2 gt 3719 wget https fastdl mongodb org linux mongodb linux x8
  • 二进制部署mongodb_exporter

    一 先安装部署好prometheus和grafana 二 部署exporter客户端 1 下载软件mongodb下载地址 xff08 grafana模板选择2583 xff09 版本选择0 11 2的 xff0c 不然和模板的语句prome
  • rocketmq二进制2m-2s异步集群部署

    一 机器规划 第一台机器 192 168 20 101 端口规划 xff1a 9876 NameServer1 10910 BrokerA master 10921 BrokerB slave 第二台机器 192 168 20 102 端口
  • Linux(Ubuntu系统)安装unzip

    最近在阿里云服务器上下载了zip形式的数据集压缩包 xff0c 解压时却发现并没有unzip解压命令 xff0c 于是习惯性地pip install unzip xff0c 并不能成功 xff0c 网上很多方法都说运行 sudo apt g
  • Python问题&解决

    python pycharm小技巧 1 要学会使用Debug pycharm Debug使用 Debug记得打断点 xff01 Pycharm debug技巧 在debug的时候python console可以直接敲变量显示 在安装Pych
  • Linux系统安装ClamAV的详细步骤

    ClamAV是一款开源免费的杀毒软件 xff0c 它可以在Linux系统上运行 以下是在Linux系统上安装ClamAV的步骤 xff1a 打开终端并更新软件包列表 xff1a sudo apt update 安装ClamAV xff1a
  • 为什么 0.1 + 0.2 不等于0.3?如何解决这个问题?

    一 开头 我们都知道0 1 43 0 2 61 61 0 3 xff0c 而是0 30000000000000004 xff0c 那么是为什么 xff1f 我们都知道计算机在内部实现中使用的是二进制 xff0c 0 1也是不例外的 xff0
  • 前端手写(十八)——Promise并行限制

    一 写在前面 一般我们做多个异步请求 xff0c 此时我们常常采用的是Promise all来进行处理 xff0c Promise all会全部的一起执行 xff0c 但是如果存在一些并行的限制 xff0c 也就是说一次最多只能执行固定的数
  • 深度学习环境安装(VMware)-Miniconda-pytorch

    提示 xff1a 最近要要跑一些算法 xff0c 用的linux系统一直是在服务器上进行开发 xff08 无GUI界面 xff09 xff0c 双系统又懒得开关机 xff0c 虚拟机还不能调用gpu xff0c 真无了个大语 对于文章中出现
  • novnc安装

    ubuntu22 04 span class token comment 安装软件 span span class token function sudo span span class token function apt span sp
  • python扫描端口

    什么是端口扫描 定义 xff1a 对一段端口或指定的端口进行扫描 目的 xff1a 通过扫描结果可以知道一台计算机上都提供了哪些服务 xff0c 然后就可以通过所提供的这些服务的己知漏洞就可进行攻击 原理 xff1a 当一个主机向远端一个服
  • HTML_移动端界面

    homework8 移动端界面 注 点击图标放大 点击图片旋转180度 ydd html span class token doctype lt DOCTYPE html gt span span class token tag span
  • Windows11安装与使用初体验

    Windows11安装 因为下载的是美国镜像 xff0c 所以系统语言是英文的 xff0c 但是这么多年的使用 xff0c 还是能够看懂一二的 xff0c 一步步操作就好了呗 xff0c 随缘点击 xff0c 无脑下一步 不知是我没有选择对
  • 基于51单片机的智能窗帘仿真方案原理图设计

    系统总体方案 xff08 附文件 xff09 通过上述对各个模块介绍 xff0c 我们最终选择了采用STC89C52作为的主控芯片 xff0c 采用光敏电阻采集环境光强通过ADC0832转换成数字信息然后由单片机处理得出环境光强的情况 xf
  • 基于RNN-LSTM模型的诗词生成/TensorFlow

    1 研究任务一介绍 1 1 研究任务 给定诗词数据集poems xff0c 采用基于循环神经网络 xff08 RNN xff09 的LSTM模型实现古诗词自动生成 xff0c 调整参数实现五言诗 七言诗 五言藏头诗 七言藏头诗和词的自动生成

随机推荐

  • PX4飞控学习与开发(三)-PX4+ROS开发环境搭建

    PX4开发环境搭建 主要步骤如下 xff1a 第一步 xff0c 设置用户组 在终端输入命令 xff1a sudo usermod a G dialout USER xff0c 然后登出 xff0c 重启 xff1b 第二步 xff0c P
  • PX4飞控学习与开发(五)-Pixhawk固件Firmware源码结构分析

    Pixhawk固件Firmware源码结构分析 Pixhawk源码Firmware是一个内容庞大的文件夹 xff0c 里面有许多的子文夹 xff0c 代表着不同的功能模块 文件夹结构如下图所示 xff1a 图1 Firmware源码结构 图
  • Latex的一些排版技巧

    Latex是科研论文写作的必备工具之一 xff0c 学会一些常用的排版指令有助于快速提高论文的排版质量 本篇博客的主要内容就是总结一些排版技巧 xff0c 方便后续查找使用 当然 xff0c 随着latex排版相关知识的进一步学习和使用 x
  • PX4飞控学习与开发(六)-利用 VScode 修改源码

    努力学习 xff0c 珍惜时间 xff1b 全力以赴 xff0c 创造未来 克制欲望 xff0c 摒除心魔 xff1b 心向何处 xff0c 往来圣贤 功崇惟志 xff0c 业广惟勤 xff1b 惟克果断 xff0c 乃罔后艰 面临困难 x
  • 基于VSCode软件的markdown笔记环境配置

    前期在CSDN上用markdown写了一些博客 xff0c 使用时还是觉得不太方便 xff0c 尤其是在编写公式时 xff0c 效率十分低下 但Markdown本身还是一款非常不错的笔记撰写工具 xff0c 所以一直琢磨着怎么改善其使用体验
  • Ubuntu 主机单系统 安装

    首先是安装系统 xff0c 启动盘是USB HDD模式 xff0c 其他基本和下面这篇文章一样 xff0c 除了安装时候没有Install 然后按e什么的 xff0c 应该是因为我的是20 04吧 史上最全Ubuntu18 04单系统安装教
  • 竞拍算法(Auction Algorithm)原理及工作过程分析

    这几天因一些项目工作 xff0c 需要对竞拍算法进行学习 但百度了大部分资料都未找到一篇文章对此算法有着较为深入的介绍 在一番努力之下 xff0c 终于找到了最初提出该算法的论文 xff0c 本文内容主要结合该论文对竞拍算法进行分析 竞拍算
  • PX4飞控学习与开发(七)-Pixhawk源码中的功能模块分析

    本篇博客主要介绍Firmware固件中各功能模块的基本结构 功能模块的编译 从上篇博客内容中的demo我们可以发现 xff0c 如果我们需要给Pixhawk模块新增一个功能模块 xff0c 一般的做法是新建一个文件夹 xff0c 所有这个功
  • XBee模块实现QGC与PX4飞控的组网通信连接

    本篇博客介绍如何利用XBee模块实现QGC地面站与飞控的通信 一 问题的提出 正如 上一篇博客 指出 xff0c PX4飞控原装数传模块 xff08 3DR Radio xff09 只能一对一通信 xff0c 并不能实现多机组网通信 xff
  • 基于PX4飞控的双机领航-跟踪的理论分析与实验验证

    双机领航 跟踪是最简单的无人机分布式控制 xff0c 是实现大规模集群分布式控制的基础 xff0c 本文主要记录对如何实现双机跟踪护航控制的思考以及验证实验 文章目录 一 理论基础二 仿真实验三 实飞实验 一 理论基础 无人机的位置控制模型
  • MATLAB常用命令及操作

    目录 0 MATLAB注释转到Ubuntu下乱码问题1 矩阵的相关操作2 取整函数3 MATLAB排序4 矩阵构造5 各种线条颜色及形状标记 0 MATLAB注释转到Ubuntu下乱码问题 将文件夹下所有m文件转为UTF 8 xff1a e
  • ubuntu里的QGC编译生成的文件到第二台电脑里运行

    QGC编译生成的文件如下 xff1a 将整个debug文件夹复制过去 xff0c 然后执行以下步骤 xff1a sudo chmod 43 x qgroundcontrol start sh 赋予权限 qgroundcontrol star
  • 2021 SLAM会议论文汇总

    目录 1 ICRA2021语义定位与建图视觉SLAM视觉里程计视觉三维重建视觉惯性里程计跟踪深度估计视觉定位激光雷达定位多传感器数据融合多传感器融合建图激光雷达SLAM激光雷达定位激光雷达建图激光里成计 amp 激光惯性里程计标题点云注册特
  • JavaScript 表单操作以及验证

    大家好 xff0c 我们今天分享一下JavaScript 操作验证表单 首先我们要知道 用JavaScript操作表单和操作DOM是类似的 xff0c 因为表单本身也是DOM树 HTML表单的输入控件 xff08 标签 xff09 主要有以
  • 使用OpenCV查找图像中矩形的位置

    import cv2 image 61 cv2 imread 39 1 jpg 39 blur 61 cv2 pyrMeanShiftFiltering image 11 21 gray 61 cv2 cvtColor blur cv2 C
  • 【GD32F310开发板试用】【001】FreeRTOS移植+“正点原子OLED任务线程”

    首发极术社区 如对兆易创新GD32F310 MCU感兴趣 xff0c 欢迎添加微信 aijishu2020 加入GD32技术讨论群 感谢极术社区提供的SG32F310G测试板 xff0c 尝试移植了一下FreeRTOS顺便点个OLED玩一下
  • apt-get的源

    使用 sudo vim etc apt sources list 修改镜像源 然后执行 sudo apt get update 更新 镜像源如下 xff0c 推荐使用国内源 xff0c 速度更快 镜像源内容转载自 https blog cs
  • Nginx+Keepalived实现站点高可用

    Nginx 43 Keepalived实现站点高可用 发表于 2015 05 18 更新于 2015 05 18 分类于 Linux xff0c Nginx 阅读次数 12301 公司内部 OA 系统要做线上高可用 xff0c 避免单点故障
  • 计算模型的FLOPs

    为了探究影响模型运行时间的变量 xff0c 之前运用了参数量做标准 参数量在TF框架下还是很容易计算的 TF框架下运用 tf span class token punctuation span keras span class token
  • stm32学习之路,方法很重要

    学习stm32已经一个月时间了 xff0c 可算是入门了 相信很多人跟我一样 xff0c 刚开始学的时候会遇到很多问题 xff0c 以及对stm32里面众多寄存器的恐惧 要利用stm32官方给的固件库开发 xff0c 少不了的还是要对寄存器