STM32F103系列芯片的地址和寄存器映射原理、LED轮流闪烁实现

文章目录

    • STM32F103系列芯片的地址和寄存器映射原理、LED轮流闪烁实现
  • 1 51单片机和STM32的不同点
  • 2 寄存器
    • 2.1 寄存器介绍
    • 2.2 51单片机和STM32对寄存器的操作
  • 3 地址映射和寄存器映射原理
  • 4 GPIO端口
    • 4.1 GPIO的工作模式主要有八种
    • 4.2 GPIO端口初始化
  • 5 LED轮流闪烁实现
    • 5.1 题目
    • 5.2 建立工程
    • 5.3 编写代码
    • 5.4 编译构建
    • 5.5 烧录以及电路连接
      • 5.5.1 USB转接口以及核心板烧录
      • 5.5.2 面包板电路连接
    • 5.6 结果
  • 6 总结
  • 7 参考文献

1 51单片机和STM32的不同点

1.开发方式不同:51单片机一般是直接操作寄存器,STM32主要操作库函数编程。

2.系统资源不同:一般而言STM32资源要比51单片机更多。

3.开发环境可能不同:51和STM32一般来讲都可以在Keil下开发,但STM32有更多中选择,可以在Linux下面开发,windows Esplise下开发,甚至直接用VSCode + 插件方式开发。

4.操作系统区别:一般而言,51单片机不支持操作系统,STM32支持各种主流操作系统,STM32开发起来更容易,可以很方便的利用系统实现各种场景下的应用,51单片机由于没有操作系统,开发起来有一定阻碍,甚至有时候必须要做出部分功能的牺牲才能达到整体功能的和谐运行。

5.后期维护方式可能不同:STM32资源足够多,可以写一个bootloader程序来完成之后的系统升级工作,不需要拆机就可以完成固件的升级,而51单片机则不可以。

2 寄存器

2.1 寄存器介绍

寄存器是中央处理器内的组成部分。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令数据地址

  1. 存放数据的寄存器:如果你需要读取一个数据,直接到这个寄存器所在的地方来问问他,数据是多少就行了。问寄存器这个动作,叫做访问寄存器。不同的数据会存放在不同的寄存器,例如:引脚PA2与PB8的高低电平数据(1或0)肯定放在不同的寄存器里,那么怎么区分不同的寄存器呢?通过地址,不同的寄存器有不同的地址,就像老张行李寄存处在101号店铺,老王行李寄存处在258号店铺。
  2. 指令、地址寄存器与数据寄存器类似,里边存放的都是0和1,只是特别的规定下,数据寄存器里面存放的0和1表示数据,指令寄存器里存放的表示指令。

2.2 51单片机和STM32对寄存器的操作

1)51单片机:

 sfr P0=0x80;      //关键字sfr 声明地址和名称的映射P0=0x00;          //将0x00赋值给P0口的8位(51单片机一组IO为8位)

2)STM32:

 GPIOA->ODR=0x00000000     //为GPIOA的ODR寄存器地址赋值0x00000000

3 地址映射和寄存器映射原理

根据每个单元功能的不同,以功能为名给这个内存单元取一个别名,这个别名就是我们经常说的寄存器,这个给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射

GPIOA下的某个寄存器,挂载在GPIOA下,地址为GPIOA基地址+偏移量;
GPIOA挂载在APB2总线,地址为APB2总线基地址+GPIOA偏移量;
ABP2挂载加外设基地址,地址为外设基地址+ABP2偏移量

在STM32手册中:GPIO寄存器地址映像如下:

4 GPIO端口

4.1 GPIO的工作模式主要有八种

4种输入方式,4种输出方式,分别为输入浮空,输入上拉,输入下拉,模拟输入;输出方式为开漏输出,开漏复用输出,推挽输出,推挽复用输出。

(1)GPIO_Mode_AIN 模拟输入 (应用ADC模拟输入,或者低功耗下省电)
(2)GPIO_Mode_IN_FLOATING 浮空输入 (浮空就是浮在半空,可以被其他物体拉上或者拉下,可以用于按键输入)
(3)GPIO_Mode_IPD 下拉输入 (IO内部下拉电阻输入)
(4)GPIO_Mode_IPU 上拉输入 (IO内部上拉电阻输入)
(5)GPIO_Mode_Out_OD 开漏输出(开漏输出:输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行)
(6)GPIO_Mode_Out_PP 推挽输出 (推挽就是有推有拉电平都是确定的,不需要上拉和下拉,IO输出0-接GND, IO输出1 -接VCC,读输入值是未知的 )
(7)GPIO_Mode_AF_OD 复用开漏输出(片内外设功能(I2C的SCL,SDA))
(8)GPIO_Mode_AF_PP 复用推挽输出 (片内外设功能(TX1,MOSI,MISO.SCK.SS))

4.2 GPIO端口初始化

GPIO端口的初始化设置三步骤
时钟配置、输入输出模式设置、最大速率设置

对于多个GPIO口的初始化如下:
GPIO_InitTypeDef GPIO_InitStructure;

  1. 第一步:使能GPIOA,GPIOE的时钟: RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
  2. 第二步:设置GPIOA,GPIOE参数:输出OR输入,工作模式,端口翻转速率
  3. 第三步:调用GPIOA口初始化函数,进行初始化。
  4. 第四步:调用GPIO-SetBits函数,进行相应为的置位。

▶把第二、三、四步合并分别设置GPIOA和GPIOE
先设置GPIOA
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4; // 第四个口,PA4
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置为推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度为50MHz
GPIO_Init(GPIOA,&GPIO-InitST); //根据设定参数初始化GPIOA
GPIO_SetBits(GPIOA,GPIO_Pin_4); //输出高

再设置GPIOE
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; // 第三个口,PE3
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置为推挽输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // IO口速度为50MHz
GPIO_Init(GPIOE,&GPIO-InitST); //根据设定参数初始化GPIOE
GPIO_SetBits(GPIOE,GPIO_Pin_3); //输出高

5 LED轮流闪烁实现

5.1 题目

以 STM32最小系统核心板(STM32F103C8T6)+面板板+3只红绿蓝LED 搭建电路,使用GPIOB、GPIOC、GPIOD这3个端口控制LED灯(本文用GPIOB和GPIOA端口),轮流闪烁,间隔时长1秒。

1)写出程序设计思路,包括GPIOx端口的各寄存器地址和详细参数;

2)分别用汇编语言,C语言编程实现。(本文只采用C语言实现)

5.2 建立工程

打开 Keil uVision5 软件选择 STM32F03C8 芯片,然后单击OK,弹出的 Manage Run-Time Environment 直接点取消。【注意:如果这里像之前一样进行配置(CMSIS、Device)会导致与启动文件即 .md 文件冲突,识别不出来,导致构建不成功。最后才发现这个问题,所有的步骤重新来过,十分麻烦。所以这里一定不要配置,直接点取消即可。】
双击 Source Group1

添加启动文件步骤如图:
启动文件判断方法如下:

小容量:FLASH≤32K               ld.s
中容量:64K≤FLASH≤128K          md.s
大容量:256K≤FLASH              hd

因此,本文的C8T6芯片采用md.s文件即可。

这里将keil的工程文件存放在USER文件夹,芯片公司给的文件存放在SYSTEM文件夹下,硬件电路的编程代码存放在HARDWARELED文件夹下,其他文件存放在OBJ文件夹,整理如图:



右击Target1 ,选择 Manage Project Items...
按照图示顺序添加Group,即USER ,SYSTEM ,HARDWARE , 然后在USER,添加test.c ,在 SYSTEM添加文件夹中的三个 .c 文件,如图,HAREWARE 文件夹中添加 led.hled.c 文件。

添加完成,如图所示:

接下来点击魔法棒,进行环境配置,操作顺序如下:
总共需要配置 OutputListingC/C++ 三个菜单。


注意: 一定要将LED文件夹配置进去,一个也不能落下。

5.3 编写代码

// test.c
#include "sys.h"
#include "delay.h"
#include "led.h"
int main(void)
{ Stm32_Clock_Init(9); //系统时钟设置delay_init(72); //延时初始化LED_Init(); //初始化与 LED 连接的硬件接口while(1){LED0=0;LED1=1;LED2=1;delay_ms(1000);LED0=1;LED1=0;LED2=1;delay_ms(1000);LED0=1;LED1=1;LED2=0;delay_ms(1000);}
}
// led.c
#include "led.h"
//初始化 PB1 PC4 PD8为输出口.并使能这三个口的时钟
//LED IO 初始化
void LED_Init(void)
{RCC->APB2ENR|=1<<2; //使能 PORTA 时钟 RCC->APB2ENR|=1<<3; //使能 PORTB 时钟
//  RCC->APB2ENR|=1<<4; //使能 PORTC 时钟
//  RCC->APB2ENR|=1<<5; //使能 PORTD 时钟 GPIOB->CRL&=0XFF0FFFFF; GPIOB->CRL|=0X00300000;//PB.5 推挽输出 GPIOB->ODR|=1<<5; //PB.5 输出高 GPIOB->CRL&=0XFFFFFFF0; GPIOB->CRL|=0X00000003;//PB.0 推挽输出 GPIOB->ODR|=1<<0; //PB.0 输出高GPIOA->CRL&=0XFFFFFF0F; GPIOA->CRL|=0X00000030;//PA.1 推挽输出 GPIOA->ODR|=1<<1; //PA.1 输出高
}
//led.h
#ifndef __LED_H
#define __LED_H
#include "sys.h"
//LED 端口定义
#define LED0 PBout(5) // DS0
#define LED1 PBout(0) // DS1
#define LED2 PAout(1) // DS2
void LED_Init(void); //初始化
#endif

5.4 编译构建

编译构建,生成HEX文件:

5.5 烧录以及电路连接

5.5.1 USB转接口以及核心板烧录

转接口和核心板对应连接:

USB转接口 C8T6核心板
3v3 3.3
GND G
TXD A10
RXD A9

注意: 下载时,将boot0置为1boot1置为0,利用跳线帽实现。如图。
而插上面包板运行时,则要将两个都置为0.

先下载CH340驱动,只需要下载一次,没有的话无法识别串口。
把USB转接口插进电脑,打开驱动下载:

再使用FlyMcu软件进行烧录。

5.5.2 面包板电路连接

给核心板上电,以及接地。三个LED灯,长管脚分别接核心板(A1,B5,B0),短管脚接地。最后电路连接如结果中图所示,杜邦线连接核心板和LED灯。

5.6 结果

流水灯点亮如图所示(红、绿、黄依次亮,持续时间1s)。

6 总结

本次实验由于最开始配置keil时出错,导致后面耗费了许多时间都无法生成HEX文件,最后在同学的帮助下完成了烧录。再连接电路时由于面包板的功能没了解清楚,中间的地线和电源是断开的,以为是LED灯的问题,又耗费了很多时间,终于在不断尝试下找出问题所在。

7 参考文献

[1]STM32直接用寄存器点亮GPIO口
[2]寄存器名称和地址的映射分析
[3]STM32 GPIO初始化步骤

STM32F103系列芯片的地址和寄存器映射原理、LED轮流闪烁实现相关推荐

  1. 学习和理解STM32F103系列芯片的地址映射和寄存器映射原理;了解GPIO端口的初始化设置三步骤(时钟配置、输入输出模式设置、最大速率设置)。

    ​​ 目录 一:什么是寄存器 1. 2. 二.程序设计思路 1.GPIO模式 2.存储器空间 3.存储器映射 4.寄存器操作 三.GPIO寄存器 STM32 GPIO口的工作模式: 四.总结: ​​​ ...

  2. STM32F103系列芯片原理学习以及LED灯的点亮

    一.STM32F103系列芯片的地址映射和寄存器映射原理 1.寄存器 寄存器是中央处理器内的组成部分.寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令.数据和地址. 其实,寄存器就是存放东西的东 ...

  3. 【嵌入式07】寄存器映射原理详解,GPIO端口的初始化设置步骤

    本文主要介绍STM32F103系列芯片的地址映射和寄存器映射原理,GPIO端口的初始化设置步骤. 一.STM32F103系列芯片的地址映射和寄存器映射原理 1.什么是寄存器? 2.地址映射和寄存器映射 ...

  4. DSP CCS 12.00 芯片:TMS320F28335 建立工程 ,使LED 灯闪烁

    1.建立工程 2.连接芯片,测试是否连接 3.需要用到的文件展示 ! 4. 在工程里面新建一个文件夹,来存储数据,(.c  文件    .asm 文件) 5.添加文件到 文件夹里面去 6.在新建的文件 ...

  5. STM32F103系列_OLED屏幕(SSD1306、SSD1315驱动)SPI驱动【DMA】(高刷)

    STM32F103系列_OLED屏幕(SSD1306.SSD1315驱动)SPI驱动[DMA](高刷) 一.SSD1306和SSD1315 二.电路原理图(SPI接法) 三.STM32_SPI 四.S ...

  6. [笔记].浅析在Nios II中的两种寄存器映射方法的异同

    此处以我所写的MAX7219为范例,从HDL接口描述到C语言软件编程,分析两种表面不一样.但实质是一样的寄存器映射方法,找出其中联系与区别. 方法1 使用Altera提供的API 1. 使用HDL描述 ...

  7. 西门子PLC源码原创最新 CPU:STM32F103RCT6(或其他STM32F103系列大容量芯片)

    西门子PLC源码原创最新 CPU:STM32F103RCT6(或其他STM32F103系列大容量芯片) 开发平台:keilMDK5 针对PLC型号:224XP或226 经众网友反馈,发现并解决某些BU ...

  8. STM32F103系列GPIO重映射一览表

    以下是STM32F103系列GPIO重映射一览表,参考一位博友的文章,大家学习!

  9. S32K系列芯片--简介

    1.1        概述 S32K1xx系列产品在汽车行业中进一步扩展了Arm®Cortex®-M0+/M4F MCU的高度可扩展产品组合.它建立在KEA系列的遗产之上,同时引入更高的内存选项和更丰 ...

最新文章

  1. java代码中fastjson生成字符串和解析字符串的方法和javascript文件中字符串和json数组之间的转换方法...
  2. Linux_《Linux命令行与shell脚本编程大全》第十八章学习总结
  3. mapredue输入路径
  4. Mysql 死锁过程及案例详解之记录锁与间隔锁Record Lock Gap Lock
  5. Android闹钟 AlarmManager的使用
  6. Android之解决toolbar里面显示返回按钮图片太大和没有水平居中的问题
  7. webapi找到了与该请求匹配的多个操作
  8. JavaScript学习(五十三)—借用构造方法继承
  9. 潜移默化学会WPF(样式)-- DataGrid(转载)
  10. tt c mysql t4 bll_通过T4模板实现代码自动生成
  11. javaeye API
  12. tomcat是干什么的? 什么叫web容器以及作用?
  13. 跨越opengl和d3d的鸿沟(四):完结篇,平台和未来
  14. E11000 duplicate key error collection
  15. python之钉钉机器人自动发消息——傻瓜式教程
  16. Xubuntu之lightdm开机无密码进入界面
  17. Keil4工程转keil5工程方法
  18. 六度人脉 全球最高效的人脉法则(图)
  19. 第二章 ObjectARX类库简介
  20. js事件-阻止默认操作

热门文章

  1. 重磅!项目经理指导手册和全套管理秘籍下载
  2. 寒假每日一题题解(1.20)十三号星期五
  3. freemarker模板注入
  4. python循环展示大写字母_python调用大写函数python中字典的循环遍历的两种方式
  5. 中文关键词提取tfidf算法改进bsaeline
  6. matlab之向数据点添加文本说明函数text
  7. caffe中的各种loss函数
  8. Blog UPUP——域名、图床与其他
  9. React 音乐播放器
  10. 《人工智能的未来》摘录