IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32F103寄存器方式点亮LED流水灯(软硬结合初尝试) -> 正文阅读

[嵌入式]STM32F103寄存器方式点亮LED流水灯(软硬结合初尝试)

一、关于STM32芯片寄存器

1.什么是寄存器

提到单片机,就不得不提到寄存器。根据百度百科介绍,寄存器是中央处理器内的组成部分。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和地址。

简单来说,寄存器就是存放东西的东西。从名字来看,跟火车站寄存行李的地方好像是有关系的。只不过火车站行李寄存处,存放的行李;寄存器可能存放的是指令、数据或地址。
  存放数据的寄存器是最好理解的,如果你需要读取一个数据,直接到这个寄存器所在的地方来问问他,数据是多少就行了。问寄存器这个动作,叫做访问寄存器。不同的数据会存放在不同的寄存器,例如引脚PA2与PB8的高低电平数据(1或0)肯定放在不同的寄存器里,那么怎么区分不同的寄存器呢?通过地址,不同的寄存器有不同的地址,就像老张行李寄存处在101号店铺,老王行李寄存处在258号店铺。
  指令、地址寄存器与数据寄存器类似,里边存放的都是0和1,毕竟单片机也只认识机器码,机器码都是0或1,只是特别的规定下,数据寄存器里面存放的0和1表示数据,指令寄存器里存放的表示指令。

2.怎么找到某个寄存器的地址

想要找到某个寄存器的地址,可以查看《STM32中文参考手册_V10》,手册可以在这里下载,但是手册中没有直接给出所有的寄存器的地址,需要读者稍加计算,具体可查看这里

3.寄存器映射

我们知道,存储器本身没有地址,给存储器分配地址的过程叫存储器映射,那什么叫
寄存器映射?寄存器到底是什么?
在存储器 Block2 这块区域,设计的是片上外设,它们以四个字节为一个单元,共 32bit,
每一个单元对应不同的功能,当我们控制这些单元时就可以驱动外设工作。我们可以找到
每个单元的起始地址,然后通过 C 语言指针的操作方式来访问这些单元,如果每次都是通
过这种地址的方式来访问,不仅不好记忆还容易出错,这时我们可以根据每个单元功能的
不同,以功能为名给这个内存单元取一个别名,这个别名就是我们经常说的寄存器,这个
给已经分配好地址的有特定功能的内存单元取别名的过程就叫寄存器映射。

二、GPIO端口设置

1.GPIO简介

GPIO 是通用输入输出端口的简称,简单来说就是 STM32 可控制的引脚,STM32 芯片的 GPIO 引脚与外部设备连接起来,从而实现与外部通讯、控制以及数据采集的功能。STM32 芯片的 GPIO 被分成很多组,每组有 16 个引脚,如型号为 STM32F103VET6 型号的芯片有 GPIOA、GPIOB、GPIOC至 GPIOE共 5组 GPIO,芯片一共 100个引脚,其中 GPIO就占了一大部分,所有的 GPIO 引脚都有基本的输入输出功能。
最基本的输出功能是由 STM32 控制引脚输出高、低电平,实现开关控制,如把 GPIO引脚接入到 LED灯,那就可以控制 LED灯的亮灭,引脚接入到继电器或三极管,那就可以通过继电器或三极管控制外部大功率电路的通断。
最基本的输入功能是检测外部输入电平,如把 GPIO 引脚连接到按键,通过电平高低
区分按键是否被按下。

2.GPIO框图剖析

在这里插入图片描述

3.初始化设置概述

1:打开GPIO口的时钟
2:初始化GPIO口(选择推挽输出)
3:设置低电平

三、点亮LED流水灯

1.打开GPIO口的时钟信号

查阅手册查到时钟信号的地址:
在这里插入图片描述
GPIO的地址:
在这里插入图片描述
在这里插入图片描述
则可以计算出时钟寄存器地址为0x40021018,则打开三个IO口的时钟(本例拟打开A、B、C三个IO口)需要将三个位都置1。

#define RCC_APB2ENR (*(unsigned int *)0x40021018)

// 打开时钟
RCC_APB2ENR |= (1<<2);  // 打开 GPIOA 时钟
RCC_APB2ENR |= (1<<3);  // 打开 GPIOB 时钟
RCC_APB2ENR |= (1<<4);  // 打开 GPIOC 时钟

2.GPIO初始化

由 GPIO 的结构决定了 GPIO 可以配置成以下8种模式:
在这里插入图片描述
本例采用推免输出模式,因为在输出模式中,推挽模式时双 MOS 管以轮流方式工作,输出数据寄存器 GPIOx_ODR可控制 I/O 输出高低电平。输出速度可配置,有 2MHz\10MHz\50MHz的选项。此处的输出速度即 I/O 支持的高低电平状态最高切换频率,支持的频率越高,功耗越大,如果功耗要求不严格,把速度设置成最大即可。在输出模式时施密特触发器是打开的,即输入可用,通过输入数据寄存器 GPIOx_IDR可读取 I/O 的实际状态。
具体操作如下:
端口1-7为低,端口8-15为高。每个引脚由四个位控制。
在这里插入图片描述
在这里插入图片描述
对A、B、C端口,代码如下:

#define GPIOA_CRL (*(unsigned int *)0x40010800)
#define GPIOB_CRL (*(unsigned int *)0x40010C00)
#define GPIOC_CRH (*(unsigned int *)0x40011004)

// 配置 GPIO 口为推免输出
// GPIOA----最后四位为0001
GPIOA_CRL |= (1<<0);  // 最后一位变1
GPIOA_CRL &= ~(0xE<<0);  // 倒数2、3、4位变0
// GPIOB----最后四位为0001
GPIOB_CRL |= (1<<0);  // 最后一位变1
GPIOB_CRL &= ~(0xE<<0);  // 倒数2、3、4位变0
// GPIOC----前四位为0001
GPIOC_CRH |= (1<<28);  //  第四位变1
GPIOC_CRH &= ~(0xE0000000);  // 前三位变0

3.设置低电平

在这里插入图片描述
输出高电平则为1,低电平则为0。
对A、B、C端口,代码如下:

#define GPIOA_ODR (*(unsigned int *)0x4001080C)
#define GPIOB_ODR (*(unsigned int *)0x40010C0C)
#define GPIOC_ODR (*(unsigned int *)0x4001100C)

GPIOA_ODR &= ~(1<<0);  //最后一位变为0
GPIOB_ODR &= ~(1<<0);  //最后一位变为0
GPIOC_ODR &= ~(1<<15); //倒数16位变为0

四、C语言全代码及软硬结合操作

1.创建项目

本例采用Keil5编写程序代码,具体操作见用Keil uVision5创建纯汇编语言的STM32工程
不同之处是:
1)芯片选择STM32F103C8
2)当出现下图时,直接叉掉,不做选择
在这里插入图片描述
在这里插入图片描述
将野火资料中的下图中的文件复制到新建的项目下:
在这里插入图片描述

在这里插入图片描述
右击文件夹,选择Add Existing Files to Group Source Group 1(或双击文件夹),选择All FIles,选择刚刚添加的启动文件,Add,Add之后Close:
在这里插入图片描述
在这里插入图片描述
可以看到Add成功了
在这里插入图片描述
打开魔术棒,如下图所示勾选Create HEX File:
在这里插入图片描述
在这里插入图片描述
在main.c中写入如下代码:

#define GPIOB_BASE 0x40010C00
#define GPIOC_BASE 0x40011000
#define GPIOA_BASE 0x40010800

#define RCC_APB2ENR (*(unsigned int *)0x40021018)

#define GPIOB_CRL (*(unsigned int *)0x40010C00)
#define GPIOC_CRH (*(unsigned int *)0x40011004)
#define GPIOA_CRL (*(unsigned int *)0x40010800)

#define GPIOB_ODR (*(unsigned int *)0x40010C0C)
#define GPIOC_ODR (*(unsigned int *)0x4001100C)
#define GPIOA_ODR (*(unsigned int *)0x4001080C)
	


void SystemInit(void);
void Delay_ms(volatile  unsigned  int);

void Delay_ms( volatile  unsigned  int  t)
{
     unsigned  int  i;
     while(t--)
         for (i=0;i<800;i++);
}


int main(){
	// 开启时钟
	RCC_APB2ENR |= (1<<3); // 开启 GPIOB 时钟
	RCC_APB2ENR |= (1<<4); // 开启 GPIOC 时钟
	RCC_APB2ENR |= (1<<2); // 开启 GPIOA 时钟
	
	
	// 设置 GPIO 为推挽输出
	// 设置 GPIOB 最后四位为 0001 (B0)
	GPIOB_CRL |= (1<<0);  // 最后一位设置为1
	GPIOB_CRL &= ~(0xE);  // 倒数二、三、四位设置为0
	// 设置 GPIOC 前四位为 0001  (C15)
	GPIOC_CRH |= (1<<28); // 第四位设置为1
	GPIOC_CRH &= ~(0xE0000000);  // 前三位设置为0
	// 设置 GPIOA 最后四位为 0001 (A0)
	GPIOA_CRL |= (1<<0);  // 最后一位设置为1
	GPIOA_CRL &= ~(0xE);  // 倒数二、三、四位设置为0

	
	// 3个LED初始化为不亮(即高点位)
	GPIOB_ODR |= (1<<0);  // 最后一位设置为1
	GPIOC_ODR |= (1<<15); // 倒数第15位设置为1
	GPIOA_ODR |= (1<<0);  // 最后一位设置为1
	
	
	while(1){
		GPIOB_ODR &= ~(1<<0); // 点灯1
		Delay_ms(1000000);
		GPIOB_ODR |= (1<<0);  // 灭灯1
		
		GPIOC_ODR &= ~(1<<15); // 点灯2
		Delay_ms(1000000);
		GPIOC_ODR |= (1<<15);  // 灭灯2
		
		GPIOA_ODR &= ~(1<<0); // 点灯3
		Delay_ms(1000000);
		GPIOA_ODR |= (1<<0);  // 灭灯3
		
	}
	
}

//函数为空,目的是为了骗过编译器不报错
void SystemInit(){
	
}

2.连接电路

根据设计的程序连接电路:
对于USB转TTL模块和stm32f103c8t6连接:
GND — GND
3v3 — 3v3
TXD — A10
RXD — A9
总电路如图所示:
在这里插入图片描述

3.编译程序

点击如图按钮,编译程序,生成hex文件
在这里插入图片描述
将电路板连接到电脑,打开mcuisp,上传HEX文件到stm32f103c8t6上:
在这里插入图片描述
如上图之后,程序就开始跑了,如下图gif所示,依次亮灯:
在这里插入图片描述
值得注意的点是,LED灯的连法是根据程序连的,正极连面包板正极,负极分别接STM芯片的A0、B0、C15。

五、用示波器仿真查看代码是否正确

1.设置魔法棒信息

点开魔法棒,如图设置
在这里插入图片描述
在这里插入图片描述

2.设置示波器

点击如图所示按键
在这里插入图片描述
设置输出口(灯接的芯片位置)
在这里插入图片描述
在这里插入图片描述
因为我的灯连的芯片管脚分别是A0、B0、C15,并且是GPIO口,所以输入(以A0为例):GPIOA_IDR.0
,之后回车,然后依照上图设置bit,颜色。具体输入形式可以参考如何使用Keil5中的虚拟示波器进行软件仿真
:

3.调试运行

点击如图所示按钮
在这里插入图片描述
一段时间后,可以看到Logic Analyzer里面三个波形的显示,观察图像可以看到与代码一致,说明正确执行了。
在这里插入图片描述

六、总结

总结下来,这个对初学者真的有很大的难度,尤其是代码的编写,我就参考了很多大佬写的代码,另外就是参考了代码,还要读懂代码,不然接线就会遇到问题,正负极和哪个接口的确认都是很困扰的,但能够做下来,确实受益匪浅。

七、参考资料

STM32 F103之点亮LED流水灯 (STM32入门学习)
STM32最小系统下载程序方法
STM32串口下载程序
如何使用Keil5中的虚拟示波器进行软件仿真

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-10-22 11:06:03  更:2021-10-22 11:07:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 6:29:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码