STM32F103寄存器方式点亮LED流水灯

本文详细介绍了如何使用STM32F103通过寄存器方式点亮LED流水灯。内容涵盖STM32寄存器基础知识,GPIO端口初始化的三个步骤,工程模板建立,程序编写与Keil仿真,以及烧录程序的完整流程。通过实例讲解,帮助读者掌握STM32嵌入式开发。

一、STM32寄存器简介及GPIO端口的初始化设置三步骤

1、STM32寄存器简介及找寻寄存器地址 

    寄存器是中央处理器内的组成部分。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令数据地址。 存放数据的寄存器是最好理解的,如果你需要读取一个数据,直接到这个寄存器所在的地方来问问他,数据是多少就行了。问寄存器这个动作,叫做访问寄存器。不同的数据会存放在不同的寄存器,例如引脚PA2与PB8的高低电平数据(1或0)肯定放在不同的寄存器里,那么怎么区分不同的寄存器呢?通过地址,不同的寄存器有不同的地址,就像老张行李寄存处在101号店铺,老王行李寄存处在258号店铺。
  指令、地址寄存器与数据寄存器类似,里边存放的都是0和1,毕竟单片机也只认识机器码,机器码都是0或1,只是特别的规定下,数据寄存器里面存放的0和1表示数据,指令寄存器里存放的表示指令。

     找寻寄存器地址需要查看数据手册,但是手册中没有直接给出所有的寄存器的地址,需要读者稍加计算。STM32给不同的寄存器分配了不同的地址,有点像划分了片区。在《STM32中文参考手册_V10》的第28页,有不同寄存器的地址范围。

    例如,我们想要读取PB3引脚的电平,分为以下几步:

  •      找到GPIOB的基地址 

     也就是找到GPIOB的小区。结论是,所有GPIOB相关的寄存器,都住在0x4001 0C00到0x4001 0FFF范围内。

  •    找到端口输入寄存器的地址偏移

     找到存储数据的那个屋子,结论是0x4001 0C00+8 = 0x4001 0C08 

  •     找到知道数据的那个人  

      PB3的数据位于从右往左数第4个。 

   而这个寄存器的位数是32位(虽然高16位没有用到),这就是32位的单片机的意思。每个寄存器都占据4字节,32位。而CPU的总线一次可以操作32位,所以比8位单片机厉害一点。
   经过这三步查找,我们可以做出以下结论:
   PB3的输入数据位于0x4001 0C08这个地址上,这个地址上存放数据的右起第4个位就是PB3引脚对应的高低电平。

参考文献:https://blog.csdn.net/geek_monkey/article/details/86291377
 

2、GPIO端口初始化 

   GPIO端口的初始化设置可以大致分三步骤:时钟配置、输入输出模式设置、最大速率设置。本次实验中的STM32的点灯则需要通过使能外设GPIO时钟,发出指令给外设GPIO,外设GPIO收到指令后,着手配置自己的寄存器,然后给IO口模式,让其实现各种功能。
其过程可表示为:CPU给指令—>GPIO收到指令—>配置内部寄存器—>配置IO口模式—>控制LED亮灭。

二、用STM32F103点亮流水灯

1、工程模板的建立

 工程模板的建立对我们编写程序来说非常重要,但是我们自己来建立可能对入门者比较困难。我们可以在网上选择现成的工程模板文件,这些程序都是编写组织好的,将不同的功能文件做了区分,放在了不同的文件夹中,逻辑非常清晰。这里整理了许多压缩包有不同的功能,在此次实验中我们只需要下载1-2-1-STM32F103这个压缩包就好了。

http://www.doyoung.net/YT/xx3.html

2、程序编写

 2.1 分析工程模板内的函数

打开压缩包里的工程,我们可以看到有许多已经编写好的功能程序。我们以后都在这里调用我们要用的功能。

                                         

之后我们只需要编写相应的程序加入到对应功能的文件夹中就好了。打开文件夹前面的加号可以看到文件夹里面的文件。

                              

可以观察到Startup文件夹中有启动文件,User文件夹里面有主函数,Basic文件夹里面有延时函数等功能函数。Hardware里面没有文件,我们需要编写我们需要的执行的程序加入里面。

2.2 程序的编写与添加 

我们本次实验的目的是为了让三个LED灯间隔一秒钟一次亮起来,我们的思路是将灯一端全部接地,再在另外一端依次给入高电平,小灯就可以依次亮起来了,主要电路图可以如下所示:

 

此处我们小灯另一端接入的管脚分别为PA.0,PB.0,PC.0,流水灯的制作可以理解为三个管脚来回输出高低电平。

因为STM32点灯需要端口初始化,所以我们首先应该要将管脚初始化成我们所需要的样子。创建一个led.c文件来存放我们的初始化代码。

led.c: 

#include "led.h"
 
void LED_Init(void){ //LED灯的接口初始化
 
 GPIO_InitTypeDef  GPIO_InitStructure;
 	
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	 //开启时钟
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;				 //初始化管脚
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //设置输出模式,推挽输出模式
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		//设置输出速率
 GPIO_Init(GPIOA, &GPIO_InitStructure);					 
 GPIO_ResetBits(GPIOA,GPIO_Pin_0);					//将该管脚初始值定义为低电平
	
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	 
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;				 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		
 GPIO_Init(GPIOB, &GPIO_InitStructure);					 
 GPIO_ResetBits(GPIOB,GPIO_Pin_0);
	
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);	 
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;				 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		
 GPIO_Init(GPIOC, &GPIO_InitStructure);					 
 GPIO_ResetBits(GPIOC,GPIO_Pin_15);
}

这里的设置输出模式为推挽输出模式,其实还有几种其他的输出方式,但是我们流水灯用到的大电流输出需要用到的就是推挽输出,另外的输出如下: 

 GPIO_Mode_AIN:模拟输入模式
GPIO_Mode_IN_FLOATING:浮空输入模式
GPIO_Mode_IPD:下拉输入模式
GPIO_Mode_IPU:上拉输入模式
GPIO_Mode_Out_OD:通用开漏输出模式
GPIO_Mode_Out_PP:通用推挽输出模式
GPIO_Mode_AF_OD:复用开漏输出模式
GPIO_Mode_AF_PP:复用推挽输出模式

至于为什么一定要将管脚初始值设置为低电平,可以将管脚输出想象成一个变量,如果没有一个定值的话,它的输出我们是不知道的,所以我们必须将它设置为一个我们知道的定值。(如果电路示意图跟我上面接法正好相反的话,就需要把初始值设置为高电平。

上面我们编写好了led.c文件,并在其中创建了一个LED_Init(void)初始化函数,我们在main文件中需要调用这个函数的时候就需要事先声明,所以我们创建一个头文件led.h用于声明我们这个函数名,再在main文件的头文件上加上#include "led.h"用于调用该头文件下的函数。
led.h:

#include "stm32f10x.h"
void LED_Init(void);//初始化

接下来我们需要将led.c和led.h文件导入到我们的工程中。

双击左边工程栏里的Hardware文件夹,然后找到我们刚保存的led.c文件的路径,再点击add即可。 

 然后我们需要在工程里的main.c函数下面和led.c函数导入led.h头文件对所需要的函数进行初始化。

首先打开User底下的main.c函数,右击选择魔法棒。

进入后先点击C/C++,然后点击Include Paths后面的三个小点:

 接着在弹出来的窗口里面选择添加,然后再选择led.h函数保存的文件夹路径就ok了。

具体详细操作可以参考这个博客:https://blog.csdn.net/bankexinan/article/details/109640994 

到此,我们的硬件(LED)算是编写完成,但是我们的main函数还是空空如也。所以接下来我们就要对我们的main函数进行编写了。要实现流水灯,我们就要让我们定义的输出管脚的输出在高低电平之间反复横跳,所以我们要对其进行赋值,具体操作代码如下: 

#include "stm32f10x.h"
#include "delay.h"
#include "led.h"
 
 
int main (void){//主程序
	RCC_Configuration(); //时钟设置
	LED_Init();
	while(1){		
	  GPIO_SetBits(GPIOA,GPIO_Pin_0);	//这个就是将IO口设置为高电平就是3.3V
	  delay_ms(500);
    GPIO_ResetBits(GPIOA,GPIO_Pin_0);//这个就是将IO口设置为低电平就是0V
    delay_ms(500);   						 
    GPIO_SetBits(GPIOB,GPIO_Pin_0);	//这个就是将IO口设置为高电平就是3.3V
    delay_ms(500); 
		GPIO_ResetBits(GPIOB,GPIO_Pin_0);//这个就是将IO口设置为低电平就是0V
    delay_ms(500);   
    GPIO_SetBits(GPIOC,GPIO_Pin_15);	//这个就是将IO口设置为高电平就是3.3V
    delay_ms(500); 
		GPIO_ResetBits(GPIOC,GPIO_Pin_15);//这个就是将IO口设置为低电平就是0V
    delay_ms(500);  
	}
}

GPIO_SetBits(GPIOX,GPIO_Pin_x),这个函数的意思是将该管脚置为高电平,也就是我之前提到过的赋值为1,Reset则表示赋值为0。 

在将程序烧录进板子之前,我们可以在keil上仿真看看波形,以便于我们及时纠错。

2.3 Keil仿真 

在开始仿真之前我们需要对keil进行一系列的配置,点击“仙女棒”,然后在Debug选项中选择软件仿真(use simulator),并且将下面的设置改成你对应的芯片即可。 

 

然后我们编译运行程序,并进入调试页面。在调试界面点击下图按钮选择逻辑分析仪。

然后点击setup,我们就可以设置我们想看的管脚号了。

 

 点击运行仿真,然后就可以看到仿真波形了。

3、烧录程序 

我们在keil中仿真好的程序最终要烧录到STM32F103C8T6(STM32最小系统核心板)中去执行,这时我们就需要用到专门的烧录硬件和软件了,硬件是USB转TTL,用于我们的PC和板子连接,软件是Fly MCU和CH340驱动直接在CSDN上搜索就可以下载到,安装好就可以了。 

3.1 关于USB-TTL与板子之间的连线方法 

现在我们仔细观察我们的USB-TTL和板子,可以看到我们USB-TTL身上有五个管脚,分别是5V电源管脚、3.3V电源管脚、TXD(数据传送)管脚、RXD(数据接收)管脚、GND管脚。我们要实现PC与板子相连接就要让对应管脚连接起来,即板子的TXD接USB-TTL的RX,RXD接TX。
总结来说:

PA9---RXD                               GND---GND

PA10---TXD                              3V3---3V3

 其次LED灯正极就如我们上面所说的连接A0、B0、C15管脚,负极共地,连接完后如下图所示:

 3.2 开发板BOOT设置

我们此时注意到板子上有两个跳线帽,分别在BOOT0和BOOT1上,我们要烧录程序之前必须改变模式BOOT0和BOOT1模式为系统存储器模式。务必将boot0设为1,boot1设为0,利用跳线帽实现。

3.3 驱动及烧录程序

在安装好CH340驱动以后,我们可以在我们的设备管理器中找到对应连接的设备。

现在只需要我们打开FlyMCU进行一定的配置后,就可以进行烧录了。配置如下图: 

 点击开始编程进行烧录,烧录完成后提示命令执行完毕,一切正常。

 4、运行成果

 

三、参考资料 

https://blog.csdn.net/txmnQAQ/article/details/120903713?utm_source=app&app_version=4.16.0&code=app_1562916241&uLinkId=usr1mkqgl919blen 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值