STM32-寄存器编程-使用寄存器点亮LED

2023-05-16

一、工程文件的建立

1、我们建立一个”工程模板“文件夹,在它下面在新建4个文件夹

Listing存放编译器编译适合产生的C/汇编/链接的列表信息
Project存放工程
Output存放编译产生的调用信息、hex文件、预览信息、封装库等
User存放用户编写的驱动文件

2、打开keil5点击Project新建一个工程放到我们刚建的”工程模板“文件夹中的Project中命名按喜好来就行,这里建议使用英文。

3、 在弹出的界面中我们选中F1系列中103中的任意一款芯片,这里我选的STM31F103R6,因为我们用的Proteus仿真中有这款芯片,等下可以仿真。

4、我们在Project视图栏里对Source Group 1 右击我们的鼠标Add New一个c文件名字随意就好这里建议英文。

 5、我们到keil5的根目录下找到此路径下的启动文件夹这里看你安装在哪里了

 我这里就不详细介绍这些启动文件了这里给张表想要更深的了解这些东西关注我后面我会更新STM32启动文件详解。

启动文件区别
startup_stm32f10x_ld.sld:low-density 小容量,Flash容量为16 ~ 32K
startup_stm32f10x_md.smd:medium-density中容量,Flash容量为64 ~ 128K
startup_stm32f10x_hd.shd:high-density大容量,Flash容量为256 ~ 512K
startup_stm32f10x_xl.sxl:超大容量,Flash容量为512K ~ 1024K
以上4种都属于基本型
startup_stm32f10x_cl.scl:connectivity line devices 互联型
startup_stm32f10x_ld_vl.svl:value line devices 超值型系列
startup_stm32f10x_md_vl.s
startup_stm32f10x_hd_vl.s

6、这里我用的是startup_stm32f10x_ld.s,把他复制到我们建立的工程文件夹中的User文件夹并在我们的工程里添加它。

7、我们可以看看这个启动文件,详细的我会在后面更新的STM32启动文件详解中介绍这里我们只看我们等下需要的部分,找到这个函数Reset_Handler

 129行定义了一个子程序:Reset_Handler。 PROC是子程序定义伪指令。这里就相当于C语言中定义了一个函数,函数名是Reset_Handler。

130行EXPORT表示Reset_Handler这个子程序可以被其他模块调用。相当于C语言中对函数进行声明。[WEAK]表示弱定义,如果编译器发现在别的地方定义了同名的函数,则在链接时用别处的地址进行链接。

131、132行的TMPORT表示定义的标号在其他文件中,在链接的时候需要到其他文件中去寻找。用C语言来解释从其他文件引入函数声明。以便下面对外部函数调用。

SystemInit是需要我们自己实现,需要编写一个同名称的函数,用来初始化STM32的时钟,用来时STM32达到稳定运行。这个函数固件库里有但我们寄存器编程的化还是要写的(但这个函数只要写个空的同名函数就行了,只要骗过编译器我们已经写了,里面可以不用写东西。STM32在我们没有配置时钟的时候会自己使用内部的系统时钟)关注我在后面更新的时钟章节会详细介绍

_main不用我们定义(不要与C语言中的主函数main混淆了)这是一个C库函数,该函数主要功能是:初始化栈、堆,配置系统环境,并在函数最后调用用户编写的主函数,从此进入C的环境。

133行把SystemInit的地址写入到寄存器R0。

134行程序跳转到R0中执行程序,就是执行SystemInit函数。

135行吧_main的地址写入到寄存器R0。

136行程序跳转到R0中执行程序,就是执行_main函数。

137程序结束。

8、看完启动文件我们就可以开始写我们的代码了,哪我们该怎么动手呢,看过我前篇文章STM32-存储器和寄存器中知道,寄存器就是就是给一个已经分配好地址的特殊内存空间的一个别名,既然是地址那么我们就可以用C语言中的指针来操作它。那么我们来实现寄存器映射(不知到什么意思可以翻看我前面STM32-存储器和寄存器文章)。

stm32f10x.h头文件

#ifndef _STM32F103_H_
#define _STM32F103_H_

/*片上外设基地址*/
#define PERIPH_BASE         ((unsigned int) 0x40000000)

/*总线基地址,GPIO挂再在APB2上,详情可以看STM的手册*/
#define APB2PERIPH_BASE     (PERIPH_BASE+0x10000)

/*AHB总线基地址*/
#define AHBPERIPH_BASE      ((unsigned int)0x40020000)

/*GPIOB外设的基地址*/
#define GPIOB_PERIPH_BASE   (APB2PERIPH_BASE+0x0c00)

/*RCC外设基地址*/
#define RCC_BASE     (AHBPERIPH_BASE+0x1000)

/*GPIOB寄存器地址*/
#define GPIO_CRL            *(unsigned int*)(GPIOB_PERIPH_BASE+0x00)
#define GPIO_ODR            *(unsigned int*)(GPIOB_PERIPH_BASE+0x0c)
#define GPIO_BSRR           *(unsigned int*)(GPIOB_PERIPH_BASE+0x10)
#define GPIO_BRR            *(unsigned int*)(GPIOB_PERIPH_BASE+0x14)

/*RCC的使能寄存器地址*/
#define RCC_APB2ENR        *(unsigned int*)(RCC_BASE+0x18)

#endif

这里我吧手册中的存储器印象地址放这里详情可以查看手册STM32FXX手册  https://pan.baidu.com/s/1sk1_DSbL5ZV33I7zqzJEsg 
提取码:pyj1

 寄存器的地址就是在外设GPIOB的地址上加上地址偏移,可以在手册中查看比如CRL(端口配置低寄存器)就是GPIOB_PERIPH_BASE(GPIOB外设基地址)+0x00(偏移地址)后面几个寄存器以此类推。

 main主函数

#include "stm32f103.h"
int main()
{
    /*开启GPIOB端口的时钟,详情可看下文1*/
	RCC_APB2ENR|=((1)<<3);

    /*清空控制PB0的端口位*/
	GPIO_CRL&=~((0x0f)<<(4*0));

    /*配置PB0为通用推挽输出,速度为10MHz,详情可看下文2*/
	GPIO_CRL|=((1)<<(4*0));

    /*PB0输出低电平,详情可看下文3*/
	GPIO_ODR |= (0<<0);

}
void SystemInit()  /*骗过编译器我们已经编写了,详情可以看上面关于启动文件的介绍*/
{

}

1、开启GPIO端口时钟

2、 配置PB0为通用推挽输出,速度为10MHz

3、 PB0输出低电平

9、编译后我们来看看仿真结果可以看出来LED已经被点亮了

其实寄存器编程和固件库编程本质上都一样都是配置各种寄存器,可以看我前面的文章STM32-固件库编程点亮LED对照的看一下,关注我后面我会更新STM32所有特色外设的介绍,STM32时钟篇章

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

STM32-寄存器编程-使用寄存器点亮LED 的相关文章

  • ROS的ros_canopen调试(1)

    Ros canopen是ros支持can通信的package 链接 xff1a http wiki ros org ros canopen distro 61 indigo Ros canopen包结构如下 SocketCAN 是一组开源的
  • linux gcc编译错误:undefined reference to `aio_error‘解决方法

    include lt aio h gt void aiow completion handler sigval t sigval int ret struct aiocb req req 61 struct aiocb sigval siv
  • wait_event_interruptible_locked的使用方法

    wait event interruptible locked interface New wait event interruptible exclusive locked irq macros added They work just
  • printk在应用层的设置方式及读取内核打印信息的方法

    如果 printk 中没有加调试级别 xff0c 则使用默认的调试级别 注意 xff0c 调试级别和格式化字符串之间没有逗号 当前控制台的各打印级别可以通过下面的命令来查看 cat proc sys kernel printk 4 4 1
  • qt编译Qxlsx模块及安装

    主要参考如下地址 xff1a https www icode9 com content 4 715555 html 注意的点 xff1a 1 把下载的代码复制到根目录下 xff0c 路径不要有什么空格啥的 xff0c 否则你会发现perl老
  • GitLab 使用Tortoisegit询问“git@192.168.1.18‘s password“问题解决

    现象如下 xff1a 使用TortoiseGit去拉本地GitLab上建立的项目时 xff0c 一直提示输入密码 xff08 如下图 xff09 xff0c 这个密码又没有指定用户名 xff0c 就算你输入你用户名的密码也是失败 但是很诡异
  • 二代身份证读写器原理及开发

    身份证读写器的作用就是从身份证中读取身份信息 xff08 例如姓名 民族 身份证号等 xff09 xff0c 然后显示或者传输给其他模块使用 功能框架如下 xff1a 功能框图说明 xff1a 1 业务模块 负责向安全模块发送命令 xff0
  • JLINK V10 V11固件修复

    先去我的资源里面下载bootloader和app固件文件 步骤 xff1a 1 PC上安装JLINK V4 9工具 xff08 貌似不能使用太高版本的工具 xff0c 否则有问题 xff09 2 打开j flash v4 9 xff0c 新
  • ROS | 话题通信的编程实现

    ROS 话题通信的编程实现 1 创建功能包2 节点编程与消息定义2 1 案例说明2 2 话题消息的定义2 3 创建 cpp文件2 4 话题发布者编程2 5 话题订阅者编程 3 配置与编译3 1 在CMaKeLists txt中添加编译选项3
  • Cocos2dx 3.0配置环境

    3 15 cocos2dx 3 0rc0 终于放出来了 在这里不得不吐槽一件事 xff0c 3 0版本从Alpha xff0c 到beta xff0c 再到rc xff0c 三个版本竟然都有各自创建项目的方式 xff0c 这样真的不会被人打
  • linux 开机运行应用程序

    把运行应用程序的脚本放在 etc rc local里面 xff0c 如果没有 etc rc local xff0c 需要执行前面的3条指令新建这个文件 注意执行应用最好要在后台执行 xff08 后面加个 amp xff09 xff0c 否则
  • arm linux游戏手柄(joystick)驱动移植

    在arm linux中移植usb joystick驱动 xff0c 参考了如下经验 xff1a Linux系统中使用Xbox360手柄 知 行 博客园 cnblogs com 使用BlueZ连接蓝牙手柄 Dokin丶的博客 CSDN博客 蓝
  • linux ubuntu下网络调试助手(GUI)工具

    mNetAssist这个工具在ubuntu下可以运行 xff0c 是个带界面的tcp调试工具 1 UDP通讯 xff1b 2 可做 TCP客户端 xff1b 3 可做 TCP服务器 xff1b 4 可以 十六进制 传送接收数据 5 可以传送
  • fft的通俗解释

    FFT是离散傅立叶变换的快速算法 xff0c 可以将一个信号变换 到频域 有些信号在时域上是很难看出什么特征的 xff0c 但是如 果变换到频域之后 xff0c 就很容易看出特征了 这就是很多信号 分析采用FFT变换的原因 另外 xff0c
  • linux 字符驱动完整框架(poll,async,waitqueue,nonblock等)

    一个linux内核驱动的完整框架 xff0c 包含了能遇到的大部分内容 xff0c 例如timer poll async waitqueue nonblock等等 xff0c 不过基本上没啥大用 xff0c 就是用来熟悉基础的 xff0c
  • vscode远程调试Linux CUDA程序

    参考了 xff1a CUDA 01 第一个程序 知乎 zhihu com 1 本地安装插件 xff1a remote ssh xff0c Microsoft C C 43 43 与NVIDIA Nsight Visual Studio Co
  • 移植MQTT-C库(附源码)

    Software mqtt org 中mqtt客户端的c库里面有一个叫MQTT C的库 xff0c 就2个实现文件 xff0c 算比较简单的了 xff0c 实现了基本的mqtt客户端功能 xff0c 移植一下试试 我的移植代码放在我的资源里
  • TCP协议的滑动窗口和流量控制算法(转)

    目录 滑动窗口 流量控制 操作系统缓冲区与滑动窗口的关系 窗口关闭 糊涂窗口综合症 拥塞控制 慢启动 拥塞避免算法 拥塞发生 快速恢复 拥塞算法示意图 引入 窗口概念的原因 我们都知道 TCP 是每发送一个数据 xff0c 都要进行一次确认
  • linux应用中的时间处理

    参考下 xff1a Linux下有关时间的函数 xff1a time times clock gettimeofday等 linux time函数 见牛羊的博客 CSDN博客 下面的代码基本涵盖了获取时间和操作计时的一些函数使用 xff1a
  • 从旋转向量到欧拉角的六种计算方法

    利用SolvePNP解出旋转向量 xff0c 旋转向量通过罗德里格斯公式解出旋转矩阵 xff0c 然后通过下面六种公式计算即可 xff0c 欧拉角有十二种 xff0c 六种是相对于自身参考系 xff0c 六种是相对于惯性参考系 xff0c

随机推荐

  • ROS | 服务通信的编程实现

    ROS 服务通信的编程实现 1 创建功能包2 节点编程与服务数据定义2 1 案例说明2 2 服务数据的定义2 3 创建 cpp文件2 4 客户端编程2 5 服务器编程 3 配置与编译3 1 在CMaKeLists txt中添加编译选项3 2
  • HTTP基础验证

    HTTP 内置基础验证 浏览器收到401状态码响应后 xff0c 弹出要求输入信息的对话框 通过验证则显示内容 xff0c 不通过不显示需要验证身份的内容 1 xff1b 手动HTTP基础验证 xff1a header 39 http 1
  • 位域,段域,联合体,结构体操作寄存器

    include lt stdio h gt typedef int Uint16 struct SCICCR BITS bit description Uint16 SCICHAR 3 2 0 Character length contro
  • C++ 网络编程之使用socket + epoll 模拟http 的请求与响应

    为了更好的理解http协议 xff0c 笔者使用了C 43 43 socket模拟了一个http服务器 xff0c 其中的服务器使用了epoll的方式 xff0c 并针对每一个新的连接开启新线程处理 大致分为三个部分 xff0c 具体代码可
  • 【Nova】nova-scheduler过滤称重

    在上一篇 nova scheduler调度过程分析 中 xff0c 对过滤称重的过程一笔带过了 xff0c 这篇着重介绍一下 首先 xff0c 我们声明一下host为主机 xff0c node为节点 xff0c 在OpenStack中一个h
  • 1.通过tcp从daytime服务器获取时间

    最近愈发觉得在学习源代码或者看书的时候 xff0c 做下读书笔记 xff0c 不仅能加深印象和理解 xff0c 同时也方便日后进行回顾 xff0c 所以就写下UNP UNIX网络编程 卷1的读书笔记 xff0c 涉及到的代码基本都是原作者提
  • 4.IPv4和IPv6地址长度

    IPv4地址的二进制形式长度为32 xff0c 使用我们常用的点分十进制形式进行表示那么最长长度为15 xff0c 例如 255 255 255 255 所以在posix的 lt netinet in h gt 中定义的IPv4地址字符串形
  • 29.Nginx HTTP之请求行解析函数ngx_http_parse_request_line

    Nginx的HTTP模块中使用ngx http parse request line函数来对读取的请求行进行解析 xff0c HTTP请求行的格式不是很复杂 xff0c 但是要注意HTTP 0 9与1 0 1 1之间的区别 xff1b 另外
  • 4. 事务隔离级别之Read Uncommitted

    前面我们说过 xff0c 要获得最高的事务隔离性 xff0c 可以采取序列化 串行的方式 xff0c 代价是严重影响系统处理事务的吞吐量 就好像数据库是个多核CPU xff0c 事务串行后 xff0c 那么意味着我们总是在使用单核 xff0
  • Vision Transformer学习笔记

    Vison Transformer学习笔记 1 前言2 网络结构 amp 设计原理2 1 Linear Projection of Flattened Patches2 2 Transformer Encoder2 2 1 Layer No
  • 5. 事务隔离级别之Read Committed

    这篇我们学习事务隔离级别Read Committed xff0c 顾名思义 xff0c 就是读已提交 xff0c 一个事务只能看到其他并发的已提交事务所作的修改 很显然 xff0c 该级别可以解决Read Uncommitted中出现的 脏
  • 6. 事务隔离级别之Repeatable Read

    接下来我们学习Mysql默认的事务隔离级别Repeatable Read xff0c 顾名思义 xff0c 可重复读 xff0c 也即在一个事务范围内相同的查询会返回相同的数据 延续上面的栗子 xff1a 1 小明很开心自己考了69分 xf
  • 7.事务隔离级别之Serializable

    最后我们学习一下最高的事务隔离级别Serializable xff0c 顾名思义 xff0c 可串行化的 xff0c 也即并发事务串行执行 很显然 xff0c 该级别可以避免前面讲到的所有问题 xff1a 脏读 不可重复读 和 幻读 代价是
  • 6. 消息发送重试

    当连接失败 xff0c Celery会自动重试发送消息 xff0c 我们可以对重试行为进行设置 xff0c 譬如说多久重试一次 最大重试次数或者干脆不重试 xff01 当然这只是官方文档说的 xff0c 我在Windows上进行测试 xff
  • 1. RabbitMQ安装

    RabbitMQ作为消息队列 xff0c 在分布式系统中具有举足轻重的作用 xff0c 能够方便地解耦各个组件 xff1b OpenStack之所以具有高扩展性 xff0c RabbitMQ功不可没 虽然一直都在用 xff0c 但没有进行过
  • 1. Tornado实现聊天室

    Tornado的异步I O机制使其很适合处理长连接的场景 xff0c 在官方提供的Demo中就有一个简单的聊天室实现 xff0c 大致做法如下 xff1a 1 提供一个全局的消息缓存 2 每次获取新消息时 xff0c 如果缓存中没有新消息出
  • D435i运行VINS-mono以及Kalib标定

    D435i运行VINS mono以及Kalib标定 系统说明 xff1a Ubuntu 18 04 内核版本 xff1a 5 4 0 1 运行VINS mono 参考博客VINS xff08 D435i xff09 测试 问题 xff1a
  • ESP8266/ESP01 Server模式中TCP Client无法接收到数据

    硬件环境 xff1a ESP01 ESP8266 Windows7 xff0c 网络调试助手 xff0c 串口调试助手 先设置ESP8266的服务器模式 AT 43 CIPMUX 61 1 AT 43 CIPSERVER 61 1 8080
  • ROS报错:TF_OLD_DATA ignoring data from the past for frame leftwheel_link

    现象 xff1a rviz 中提示no transform from XX to odom 原因 xff1a lt param name 61 34 use sim time 34 value 61 34 true 34 gt 中use s
  • STM32-寄存器编程-使用寄存器点亮LED

    一 工程文件的建立 1 我们建立一个 工程模板 文件夹 xff0c 在它下面在新建4个文件夹 Listing存放编译器编译适合产生的C 汇编 链接的列表信息Project存放工程Output存放编译产生的调用信息 hex文件 预览信息 封装