基于STM32F103流水灯的实现(寄存器版)

目录

一、原理介绍

1、 芯片介绍

1.1、STMF103C8T6

1.2、地址说明 

2、寄存器介绍

2.1、APB2 外设时钟使能寄存器(RCC_APB2ENR)

  2.2、GPIO寄存器

2.3、端口输出数据寄存器(GPIOx_ODR) 

二、C语言代码实现 

 1、工程构建

2、代码编写 

 2.1、打开对应管脚

2.2、 配置输出,确定输出模式

2.3、输出低电平

2.4、延时操作 

2.5、完整代码 

三、仿真运行,并利用KEIL软件示波器进行输出口观察

 四、hex文件烧录

 五、结果展示

六、总结

七、参考链接


一、原理介绍

1、 芯片介绍

STM32F系列属于中低端的32位ARM微控制器,该系列芯片是意法半导体(ST)公司出品,其内核是Cortex-M3 [1]


 。

系列芯片按片内Flash的大小可分为三大类:小容量(16K和32K)、中容量(64K和128K)、大容量(256K、384K和512K)。

芯片集成定时器Timer,CAN,ADC,SPII2C,USB,UART等多种外设功能。

1.1、STMF103C8T6

首先介绍本文的主角了——stm32f103c8t6芯片,它是一款基于ARM Cortex-M 内核STM32系列的32位的微控制器程序存储器容量是64KB,需要电压2V~3.6V,工作温度为-40°C ~ 85°C。

32位指的是该芯片每次能同时处理的数据为4个字节共32位(bit),与以前我们学的51单片机一样,每次能够同时处理1个字节共8位数据,这对于我们在接下来寄存器的使用十分重要。

1.2、地址说明 

这里给出 有关寄存器的地址,可以看见这里为寄存器的初始地址,而在后面我们会遇见一个偏移地址,这里给出寄存器的地址说明:

寄存器的具体地址=寄存器初始地址(基地址)+偏移地址

给出例子:例如GPIOA_CRH寄存器的基地址为0x4001 0800,后面的偏移地址为0x04

所以GPIOA_CRH寄存器的最终地址为0x4001 0804。同理,RCC_APB2ENR的地址为:

0x4002 1000 +0x18 =0x4002 1018。

通过系统图,我们可以看出ABP2寄存器与GPIOX输出端口相关联,所以接下来我们进行寄存器调用时便用RCC_ABP2外设时钟使能寄存器。 

2、寄存器介绍

寄存器的功能是存储二进制代码,它是由具有存储功能的触发器组合起来构成的。一个触发器可以存储1位二进制代码,故存放n位二进制代码的寄存器,需用n个触发器来构成。

2.1、APB2 外设时钟使能寄存器(RCC_APB2ENR)

  根据实验需求,这里对后面将要用到的RCC寄存器做出说明;由图可见,为了实现流水灯,我们需要利用芯片的GPIOX引脚,RCC寄存器则具有控制GPIOX引脚的功能。

 

由上图可以清晰的看出,当对应的RCC位输出为1时,相应的GPIOX口开始工作。 

  2.2、GPIO寄存器

接下来便是本文的重头戏,GPIO管脚的选择;GPIO寄存器下面总共又分为7种,分别是:

1、端口配置低寄存器(GPIOx_CRL) (x=A..E)

2、端口配置高寄存器(GPIOx_CRH) (x=A..E)

3、端口输入数据寄存器(GPIOx_IDR) (x=A..E)

4、端口输出数据寄存器(GPIOx_ODR) (x=A..E)

5、端口位设置/清除寄存器(GPIOx_BSRR) (x=A..E)

6、端口位清除寄存器(GPIOx_BRR) (x=A..E)

7、端口配置锁定寄存器(GPIOx_LCKR) (x=A..E) 

首先,我们需要确定的是,在我们所看到的的芯片上PX0~PX15引脚在寄存器中分别对应的是什么位置,接下来给出简要说明:   

 在芯片上我们可以看到总共有PX0~PX15号引脚,就拿PA脚来做说明,首先,上图所示,GPIOX_CRL总共有0~31共32位,而这32位又可以分为8组,每组分别是:CNF 和 MODE,所以我们用一组来对应其中的一个管脚,共8个脚;这里需要注意下,根据我们在单片机所学,地址又有高低之分,所以这里则代表了PA0~PA7八个低位管脚。

所以我们可以推出,GPIOX_CRH则代表了PA8~PA15八个高位管脚。

由图中可见,GPIOX_CLR只能给出输出的模式,而不是输出的值,所以接下来介绍,STM32芯片的输出寄存器。

2.3、端口输出数据寄存器(GPIOx_ODR) 

我们可以清楚地知道,计算机的输出值只有2种:‘0’ 或者 ‘1’;现在来介绍如何实现值的输出:

  由图我们可以看到,GPIOX_ODR寄存器与之前的不同,这里只有0~15位可以用,上图我也标出,这15位分别代表着PX0~PX15共16个引脚,例如:PA1引脚我们就用到ODR1位置;PB5引脚我们就用ODR5位置,这样距离希望你们能够理解。。

好了,配置流水灯所需要的寄存器都已经进行说明,接下来就是如何利用寄存器来实现流水灯的运行。

二、C语言代码实现 

 代码实现思路:打开对应管脚的时钟——>配置输出,确定输出模式——>输出低电平——>实现流水灯

 1、工程构建

在进行单片机以及ARM芯片的仿真以及代码嵌入,我们采用的软件一般为KEIl软件:

首先,新建工程:

选择工程放置的文件,并给出工程名称:

 芯片选择:

相关环境的配置:

添加项目到工程中: 

 选择.c文件,并命名:

2、代码编写 

根据上面我们所给出的实验思路,这里依据思路进行代码编写。

 2.1、打开对应管脚

由于我采用的PA0、PB0、PC14三个管脚,所以这里对三个GPIO口进行激活,即使用位操作,将对应的为数变为1。

RCC_APB2ENR |=(1<<2);
RCC_APB2ENR |=(1<<3);
RCC_APB2ENR |=(1<<4);

2.2、 配置输出,确定输出模式

 这里的&运算以及|运算,是对相应的PX管脚进行输出模式操作;由于CRL寄存器共有32位,所以这里采用8位的16进制来直接赋值(每一位16进制对应着4位2进制)。

GPIOA_CRL &=0xFFFFFFF0;
GPIOA_CRL |=0xFFFFFFF3;
	
GPIOB_CRL &=0xFFFFFFF0;
GPIOB_CRL |=0xFFFFFFF3;

GPIOC_CRH &=0xF0FFFFFF;
GPIOC_CRH |=0xF3FFFFFF;

2.3、输出低电平

我采用的是低电平点亮LED,高电平点灭LED

GPIOA_ODR =0x0<<0;
Delay_ms(10000000);
GPIOA_ODR =0x1<<0;
Delay_ms(10000000);

GPIOB_ODR =0;
Delay_ms(10000000);	
GPIOB_ODR =1;
Delay_ms(10000000);

GPIOC_ODR =0<<14;
Delay_ms(10000000);
GPIOC_ODR =1<<14;
Delay_ms(10000000);

2.4、延时操作 

注意:这里采用延时函数是为了实现LED循环点亮点灭的操作

int  Delay_ms(volatile unsigned int time)
{    
	int i;
   while(time--)
   {
      i=20000;  
      while(i--) ;    
   }
	 return 0;
}

2.5、完整代码 

#define RCC_APB2ENR *(unsigned int*)0x40021018
#define GPIOA_CRL	*(unsigned int*)0x40010800
#define GPIOB_CRL *(unsigned int*)0x40010C00
#define GPIOC_CRH *(unsigned int*)0x40011004
#define GPIOA_ODR *(unsigned int*)0x4001080C
#define GPIOB_ODR *(unsigned int*)0x40010C0C
#define GPIOC_ODR *(unsigned int*)0x4001100C
	
int  Delay_ms(volatile unsigned int time)
{    
	int i;
   while(time--)
   {
      i=20000;  
      while(i--) ;    
   }
	 return 0;
}

int main()
{
	RCC_APB2ENR |=(1<<2);
	RCC_APB2ENR |=(1<<3);
	RCC_APB2ENR |=(1<<4);
	
	while(1)
	{		
	GPIOA_CRL &=0xFFFFFFF0;
	GPIOA_CRL	|=0xFFFFFFF3;
	GPIOA_ODR =0x0<<0;
	Delay_ms(10000000);
	GPIOA_ODR =0x1<<0;
	Delay_ms(10000000);
	
	GPIOB_CRL &=0xFFFFFFF0;
	GPIOB_CRL |=0xFFFFFFF3;
	GPIOB_ODR =0;
	Delay_ms(10000000);
	GPIOB_ODR =1;
	Delay_ms(10000000);
	
	GPIOC_CRH &=0xF0FFFFFF;
	GPIOC_CRH |=0xF3FFFFFF;
  GPIOC_ODR =0<<14;
	Delay_ms(10000000);
	GPIOC_ODR =1<<14;
	Delay_ms(10000000);
}
}

三、仿真运行,并利用KEIL软件示波器进行输出口观察

首先,进行虚拟仿真环境配置:

 文件编译,并开始运行:

打开keil软件示波器:

 

 

 波形显示:

 四、hex文件烧录

首先我们需要在keil下生成hex文件:

常用的烧录软件一般为:mcusip软件:

关于该软件的使用方法我就不做过多说明: 这里我给出可以参考的链接,有需要的可以直接去查看,步骤写的很清楚,有很大的借鉴价值。

STM32串口下载程序_lengyuefeng212的博客-CSDN博客_stm32串口下载程序

这里需要补充说明一下,在进行芯片烧录时,需要注意将芯片上的boot置1,在烧录完毕后,再讲其改为0。    十分重要!!!! 

烧录时的boot状态:

 完成后的状态:

 五、结果展示

六、总结

 本次实验,主要是考验我们对于STM32芯片寄存器地址的了解,以及其各寄存器功能的了解。想要顺利的完成本次实验就需要去查阅大量的书籍资料,这里我推荐去STM32官网寻找,上面有着stm各系列的编程资料以及芯片手册。虽然,stm32有着更为简单的操作方式即库函数,但对于初学者来说,还是一步一步,脚踏实地的通过了解寄存器来完成才对于提高自己有着帮助。其次,KEIL自带的示波器还是挺好用的,这对于我们观察输出的结果很有帮助。另外推荐一位B站UP主——海创电子,讲解的STM32芯片对于小白来说很有帮助。

七、参考链接

STM32串口下载程序_lengyuefeng212的博客-CSDN博客_stm32串口下载程序

STM32延时函数的三种方法——最好掌握第三种_luodonghuan1的专栏-CSDN博客_stm32延时函数写法 4、stm32F103入门学习--点亮LED(寄存器操作)_daniaoxp的博客-CSDN博客

  • 5
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值