嵌入式——了解stm32

目录

 

1、了解单片机

2、了解简单电子元器件

3、stm32开发的原理

1. 寄存器基础

2. 寄存器访问方式

3. 寄存器编程步骤

4. 示例代码

5. 注意事项

6. 资源推荐

4、标准库开发 

1. STM32标准库概述

2. 环境配置

3. 项目结构

4. 初始化与配置

4.1 包含头文件

4.2 时钟配置

4.3 GPIO配置

5. 点亮LED的示例

6. 注意事项

7. 资源与文档

5、对比

1. 开发方式

2. 可读性和可维护性

3. 性能

4. 调试和测试

5. 适用场景

总结


 

1、了解单片机

(1)单片机特点:高性能、低功耗、低成本

(2)单片机编程:通过编程使MCU驱动片上外设或者片外外设

(3)本质上单片机的工作方式就是编程使引脚或者内部硬件输出一个高电平或者低电平,根据不同的设备所需要的高/低电平的组合以及所需要的高低电平的持续时间来驱动设备

2、了解简单电子元器件

  • 电阻(Resistors):用于限流、分压、偏置等功能,是电路中最基本的元件。

  • 电容(Capacitors):用于滤波、耦合、去耦等,可以稳定电源和信号。

  • 二极管(Diodes):用于整流、保护电路(如防止反向电流)等。

  • 晶体管(Transistors):作为开关或放大器使用,可以控制大电流或高电压。

  • 集成电路(ICs):如运算放大器、计时器、调制解调器等,根据需要选择合适的IC。

  • LED(发光二极管):用于指示和显示状态,广泛应用于各种指示灯和显示屏。

  • 传感器(Sensors):如温度传感器、湿度传感器、加速度传感器等,根据项目需求选择合适的传感器。

  • 继电器(Relays):用于控制大功率设备,可以通过小信号控制大电流。

  • 电源管理IC(Power Management ICs):用于电源转换、稳压、充电等。

  • 连接器(Connectors):用于电路板之间或与外部设备的连接。

  • PCB(印刷电路板):用于承载和连接各种元器件,设计时需要考虑布线和布局。

3、stm32开发的原理

STM32的寄存器开发是嵌入式系统编程的重要部分,理解寄存器的使用能帮助你更有效地控制硬件。

1. 寄存器基础

  • 寄存器定义:寄存器是微控制器内部的存储单元,用于控制和配置外设。每个外设都有一组特定的寄存器。
  • 地址空间:每个寄存器都有一个对应的地址,通过这个地址进行读写操作。

2. 寄存器访问方式

  • 直接访问:通过指针直接访问寄存器。例如,使用C语言的指针来定义寄存器地址。
  • 结构体映射:使用结构体将寄存器映射为变量,这样可以通过变量名称更清晰地访问寄存器。

3. 寄存器编程步骤

  1. 包含头文件:包含STM32的头文件,例如stm32f4xx.h,其中定义了寄存器的地址和结构体。
  2. 使能时钟:在使用外设之前,首先需要使能其时钟。通常通过RCC(时钟控制寄存器)进行配置。
  3. 配置寄存器:根据需要配置相关的控制寄存器,例如设置GPIO模式、外设参数等。
  4. 操作外设:使用配置好的寄存器控制外设的行为,例如读取传感器数据、发送数据等。

4. 示例代码

以GPIO为例,下面是一个简单的代码示例,配置GPIO为输出模式并点亮LED。

#define RCC_BASE      0x40023800UL  // RCC寄存器的基地址
#define GPIOA_BASE    0x40020000UL  // GPIOA寄存器的基地址#define RCC_AHB1ENR  (*(volatile unsigned int *)(RCC_BASE + 0x30))  // RCC AHB1时钟使能寄存器
#define GPIOA_MODER   (*(volatile unsigned int *)(GPIOA_BASE + 0x00))  // GPIOA模式寄存器
#define GPIOA_ODR     (*(volatile unsigned int *)(GPIOA_BASE + 0x14))  // GPIOA输出数据寄存器void GPIO_Config(void) {// 使能GPIOA时钟RCC_AHB1ENR |= (1 << 0);  // 使能GPIOA的时钟// 设置PA1为输出模式GPIOA_MODER &= ~(0x3 << (1 * 2));  // 清除PA1的模式位GPIOA_MODER |= (0x1 << (1 * 2));   // 设置PA1为输出模式
}void LED_On(void) {GPIOA_ODR |= (1 << 1);   // 设置PA1为高电平,点亮LED
}void LED_Off(void) {GPIOA_ODR &= ~(1 << 1);  // 设置PA1为低电平,熄灭LED
}int main(void) {GPIO_Config();  // 配置GPIOwhile (1) {LED_On();   // 点亮LEDfor (volatile int i = 0; i < 100000; i++); // 简单延时LED_Off();  // 熄灭LEDfor (volatile int i = 0; i < 100000; i++); // 简单延时}
}

在这个示例中,我们可以在不使用库文件的情况下,只依靠芯片手册来对stm32进行开发; 

5. 注意事项

  • 访问顺序:某些寄存器的访问顺序和时序可能会影响外设的正常工作。
  • 并发访问:当多个外设需要同时访问相同的寄存器时,要注意并发问题。
  • 手册参考:参考STM32的参考手册和数据手册,了解每个寄存器的具体功能和配置方式。

6. 资源推荐

  • STM32官方文档:阅读STM32的参考手册和编程手册。
  • 开发社区:参与STM32相关的开发者社区,获取更多示例和经验。

4、标准库开发 

STM32的标准库开发是一个便捷的方法来进行嵌入式系统编程,尤其适合于初学者和快速原型开发。以下是标准库开发的详解,包括基础知识、配置和一些示例。

1. STM32标准库概述

STM32标准库是STMicroelectronics提供的,用于简化与硬件的交互。它封装了对寄存器的直接操作,使开发更加高效和可读。

2. 环境配置

  • 开发工具:使用STM32CubeIDE、Keil或其他支持STM32的IDE。
  • 库文件:下载并安装STM32标准外设库,通常为STM32F4xx_StdPeriph_Lib等。

3. 项目结构

标准库的项目一般包括以下文件结构:

  • main.c:主程序文件。
  • stm32f4xx_conf.h:配置文件,包含所有需要的外设头文件。
  • stm32f4xx_syscfg.hstm32f4xx_gpio.h等:各外设的头文件。

4. 初始化与配置

在使用标准库进行开发时,常见的初始化步骤如下:

4.1 包含头文件

#include "stm32f4xx.h"          // 选择合适的头文件
#include "stm32f4xx_gpio.h"     // GPIO相关函数
#include "stm32f4xx_rcc.h"      // RCC相关函数
#include "stm32f4xx_system.h"   // 系统时钟相关函数

4.2 时钟配置

通过RCC库函数配置系统时钟,确保外设时钟被使能。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); // 使能系统配置时钟
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);  // 使能GPIOA时钟

4.3 GPIO配置

配置GPIO模式、速度等属性。

GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;         // PA1
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;      // 输出模式
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; // 速度
GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;     // 推挽输出
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;   // 无上下拉
GPIO_Init(GPIOA, &GPIO_InitStruct);             // 初始化GPIO

5. 点亮LED的示例

以下是完整的代码示例,点亮连接在GPIOA的第1个引脚上的LED。

#include "stm32f4xx.h"          // 包含STM32F4库的主头文件
#include "stm32f4xx_gpio.h"     // GPIO库
#include "stm32f4xx_rcc.h"      // RCC库
#include "stm32f4xx_system.h"   // 系统时钟void GPIO_Config(void) {// 使能GPIOA时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);// 配置PA1为输出模式GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1;         // PA1GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;      // 输出模式GPIO_InitStruct.GPIO_Speed = GPIO_Speed_100MHz; // 速度GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;     // 推挽输出GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;   // 无上下拉GPIO_Init(GPIOA, &GPIO_InitStruct);             // 初始化GPIO
}int main(void) {GPIO_Config();  // 配置GPIOwhile (1) {GPIO_SetBits(GPIOA, GPIO_Pin_1);   // 点亮LEDfor (volatile int i = 0; i < 100000; i++); // 延时GPIO_ResetBits(GPIOA, GPIO_Pin_1); // 熄灭LEDfor (volatile int i = 0; i < 100000; i++); // 延时}
}

 在标准库的开发中,我们可以发现,对寄存器的具体功能的每一位的操作,都被封装好了,我们只需要调用对应的函数以及使用对应的宏便可以进行开发,不需要自己对寄存器的每一位都去进行操作

6. 注意事项

  • 延时实现:示例中的延时采用简单循环,实际开发中可使用定时器或其他更精确的延时方法。
  • 硬件连接:确保LED的正极连接到PA1,负极通过电阻接地。
  • 标准库文档:参考标准库的文档,了解更多函数和使用方式。

7. 资源与文档

  • STMicroelectronics官网:提供标准库和文档下载。
  • 参考手册:每个STM32系列的参考手册中有关于各个寄存器和外设的详细说明。

5、对比

可能有些同学想问,那这样看起来,寄存器开发的代码,可比标准库看起来简单呀??为什么更多使用标准库开发呢??

1. 开发方式

  • 寄存器开发

    • 直接操作:直接对硬件寄存器进行读写,控制硬件行为。
    • 灵活性:可以精确控制每一个寄存器位,适合对硬件底层有深入了解的开发者。
  • 标准库开发

    • 封装性:通过标准库提供的API函数来操作硬件,减少了对底层寄存器的直接接触。
    • 易用性:开发更简单,函数接口更容易理解,适合初学者和快速开发。

2. 可读性和可维护性

  • 寄存器开发

    • 复杂性:代码通常较复杂,难以阅读和维护,尤其在需要频繁访问多个寄存器时。
    • 错误风险:手动设置寄存器可能导致错误,特别是对位域的操作。
  • 标准库开发

    • 高可读性:代码更加结构化和清晰,使用函数名可以直观了解其功能。
    • 降低错误风险:库函数通常处理了边界情况,减少了出错的可能性。

3. 性能

  • 寄存器开发

    • 高效性:可以实现更高效的代码,尤其是在需要高度优化的应用中。
    • 无额外开销:没有库函数调用的开销,直接操作寄存器。
  • 标准库开发

    • 一定开销:库函数可能引入额外的函数调用开销,但在大多数应用中影响不大。

4. 调试和测试

  • 寄存器开发

    • 调试难度:调试可能更复杂,因为需要对硬件和寄存器的状态有深刻理解。
    • 设备特定:寄存器直接操作可能导致代码不具有可移植性,特定于某一系列的微控制器。
  • 标准库开发

    • 易于调试:高层API通常提供更好的抽象,便于调试和测试。
    • 可移植性:使用标准库的代码通常更易于在不同平台上移植。

5. 适用场景

  • 寄存器开发

    • 底层驱动:适合开发底层驱动或对性能要求极高的应用。
    • 特定需求:当需要特定硬件的详细控制时,例如定制外设操作。
  • 标准库开发

    • 快速原型:适合快速开发和原型设计,特别是对于初学者。
    • 通用应用:对于大多数常规应用,标准库提供了足够的功能和灵活性。

总结

选择寄存器开发还是标准库开发取决于项目需求、开发者的经验和对硬件的熟悉程度。在实际开发中,常常会结合使用这两种方式,以获得最佳的开发效率和控制能力。

标准库对于初学者来说,远远比寄存器开发上手来的快,当然,随着开发的深入以及了解,学习寄存器开发是不可避免的;但是,标准库开发相较于寄存器开发来说,虽然丢失了那么一丢丢的效率,但是换来了不可替换的可读性与易于移植的优点,总得来说,寄存器开发,你的板子读起来比你容易,但是标准库开发,可以让你也读起来比较容易;

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

go 聊天系统项目-1

1、登录界面 说明&#xff1a;这一节的内容采用 go mod 管理【GO111MODULE‘’】模块&#xff0c;从第二节开始使用【GO111MODULE‘off’】GOPATH 管理模块。具体参见 go 包相关知识 1.1登录界面代码目录结构 代码所在目录/Users/zld/Go-project/day8/chatroom/ 1.2登录界…

Balluff EDI 项目需求分析

电子数据交换&#xff08;EDI&#xff0c;Electronic Data Interchange&#xff09;是一种通过电子方式在不同组织之间交换商业文档的技术和标准。它涉及使用标准格式的电子文档&#xff0c;如订单、发票、运输单据等&#xff0c;以实现自动化的数据传输。这种技术通常依赖于专…

如何在 Ubuntu 上安装和配置 GitLab

简介 GitLab是一个开源应用程序&#xff0c;主要用于托管 Git 仓库&#xff0c;并提供与开发相关的附加功能&#xff08;如问题跟踪&#xff09;。GitLab 可由用户自己的基础架构托管&#xff0c;可灵活部署为开发团队的内部存储库、与用户对接的公共方式或供稿者托管自己项目…

c语言-常量和变量

文章目录 一、常量是什么&#xff1f;&#xff08;1&#xff09;整型常量&#xff1a;&#xff08;2&#xff09;实型常量&#xff1a;&#xff08;3&#xff09;字符常量&#xff1a;&#xff08;4&#xff09;字符串常量&#xff08;5&#xff09;地址常量 二、define 和 con…

【Linux】进程间通信(匿/命名管道、共享内存、消息队列、信号量)

文章目录 1. 进程通信的目的2. 管道2.1 原理2.2 匿名管道2.3 管道通信场景&#xff1a;进程池2.4 命名管道 3. System V共享内存3.1 操作共享内存3.2 使用共享内存通信 4. System V 消息队列&#xff08;了解&#xff09;5. System V 信号量&#xff08;了解&#xff09;5.1 信…

VirtualBox 解决虚拟机Cable Unplugged 无法上网问题

问题描述 VirtualBox 中的虚拟机无法上网&#xff0c;在虚拟机中查看网络设置显示 Cable Unplugged。 解决方案 选择VirtualBox 上方任务栏的控制->设置->网络&#xff0c;勾选接入网线即可解决。

大学适合学C语言还是Python?

在大学学习编程时&#xff0c;选择C语言还是Python&#xff0c;这主要取决于你的学习目标、专业需求以及个人兴趣。以下是对两种语言的详细比较&#xff0c;帮助你做出更明智的选择&#xff1a; C语言 优点&#xff1a; 底层编程&#xff1a;C语言是一种底层编程语言&#x…

【深入浅出】深入浅出Bert(附面试题)

本文的目的是为了帮助大家面试Bert&#xff0c;会结合我的面试经历以及看法去讲解Bert&#xff0c;并非完整的技术细致讲解&#xff0c;介意请移步。 深入浅出】深入浅出Bert&#xff08;附面试题&#xff09; 网络结构Pre-TrainingFine-Tuning 输入编码词向量编码句子编码位置…

thrift rpc 四种类型的服务端的实现详细介绍

thrift rpc 四种类型的服务端的实现详细介绍 这里主要是使用 thrift 开发的时候服务器端的实现&#xff0c;以及 thrift 提供给我们多钟的服务的实现&#xff0c;以及每个实现的服务器的特点和 API 介绍&#xff0c;TServer 主要包含以下几种实现 TSimpleServer 阻塞的但线程…

Python | Leetcode Python题解之第530题二叉搜索树的最小绝对差

题目&#xff1a; 题解&#xff1a; # Definition for a binary tree node. # class TreeNode(object): # def __init__(self, x): # self.val x # self.left None # self.right Noneclass Solution(object):def isValidBST(self, root):"…

[Prometheus学习笔记]从架构到案例,一站式教程

文章目录 Prometheus 优势Prometheus 的组件、架构Prometheus Server 直接从监控目标中或者间接通过推送网关来拉取监控指标&#xff0c;它在本地存储所有抓取到的样本数据&#xff0c;并对此数据执行一系列规则&#xff0c;以汇总和记录现有数据的新时间序列或生成告警。可以通…

抓住亚马逊、shein新品扶持期,利用测评提升搜索排名与销量

亚马逊的卖家们应该意识到&#xff0c;新发布的产品在上线后的2到4周内&#xff0c;通常会获得平台的流量支持。这一阶段被称为“新品流量黄金期”&#xff0c;在此期间&#xff0c;产品的搜索排名和曝光率通常会比平时更高。因此&#xff0c;如何有效利用这一阶段&#xff0c;…

轻松入门WordPress:在Ubuntu上搭建本地网站并配置公网访问地址

文章目录 前言1. 安装WordPress2. 创建WordPress数据库3. 安装相对URL插件4. 安装内网穿透发布网站4.1 命令行方式&#xff1a;4.2. 配置wordpress公网地址 5. 配置WordPress固定公网地址 前言 本文主要介绍如何在Linux Ubuntu系统上使用WordPress搭建一个本地网站&#xff0c…

华为云计算知识总结——及案例分享

目录 一、华为云计算基础知识二、华为云计算相关案例实战案例一&#xff1a;搭建弹性云服务器&#xff08;ECS&#xff09;并部署Web应用案例二&#xff1a;构建基于OBS的图片存储和分发系统案例三&#xff1a;基于RDS的高可用数据库应用案例四&#xff1a;使用华为云DDoS防护保…

银行金融知识竞赛活动策划方案

根据《中国人民银行**市中心支行“创新金融服务&#xff0c;支持经济发展”业务竟赛活动实施方案》安排&#xff0c;中支决定于9月28日举办**市人民银行系统“创新金融服务&#xff0c;支持经济发展”现场业务竞赛&#xff0c;为确保业务竞赛组织工作顺利开展&#xff0c;特制定…

动态规划 01背包(算法)

现有四个物品&#xff0c;小偷的背包容量为8&#xff0c;怎么可以偷得价值较多的物品 如: 物品编号&#xff1a; 1 2 3 4 物品容量&#xff1a; 2 3 4 5 物品价值&#xff1a; 3 4 5 8 记f(k,w) ,当背包容量为w,可以偷k件物品…

引领数字时代:万码优才如何变革IT人才招聘新体验(这里有更精准的推荐)

目录 引领数字时代&#xff1a;万码优才如何变革IT人才招聘新体验引领未来科技&#xff0c;精准链接IT精英精准匹配&#xff0c;高效对接海量资源&#xff0c;覆盖广泛优化体验&#xff0c;简化流程 全面升级&#xff1a;AI赋能数字人才职业成长AI模拟面试职场千问智能简历评估…

Rocky Linux 9安装后无法远程ssh密码登录解决

在Rocky Linux 9版本中&#xff0c;为了增加安全性&#xff0c;默认情况下禁用SSH root密码登录。这是系统默认设定的规则&#xff0c;我们同样也可以更改它。   允许Rocky Linux 9 root用户通过ssh登录方法&#xff1a; 1.编辑SSH配置文件 2.找到以下内容 PermitRootLogin …

1.2 图像处理基本操作

在本实战中&#xff0c;我们将学习如何使用OpenCV进行基本的图像处理操作。首先&#xff0c;我们将通过cv2.imread()函数读取图像&#xff0c;并使用cv2.imshow()在窗口中显示它。接着&#xff0c;我们将探索如何通过cv2.imwrite()保存图像&#xff0c;并设置不同的参数以控制图…

【C++】哈希表模拟:开散列技术与哈希冲突处理

C语法相关知识点可以通过点击以下链接进行学习一起加油&#xff01;命名空间缺省参数与函数重载C相关特性类和对象-上篇类和对象-中篇类和对象-下篇日期类C/C内存管理模板初阶String使用String模拟实现Vector使用及其模拟实现List使用及其模拟实现容器适配器Stack与QueuePriori…