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

这篇博客介绍了如何通过STM32F103的寄存器操作来点亮LED流水灯,涵盖了寄存器基础知识、GPIO工作模式,以及使用汇编和C语言的具体实现步骤,包括延时函数和主函数的编写,并提到了程序的编译、烧录和实物构建的过程。
摘要由CSDN通过智能技术生成

一、寄存器简介

寄存器,根据百度百科介绍,寄存器是中央处理器内的组成部分。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和地址。
通俗的讲,寄存器就是存放东西的。存放的东西不过是由我们客观上的东西变为了指令、数据或地址。

GPIO

简介
GPIO(General-Purpose IO ports),也就是通用输入输出口。一个GPIO端口至少需要两个寄存器,一个做控制用的“通用IO端口控制寄存器”,还有一个是存放数据的“通用I/O端口数据寄存器”。数据寄存器的每一位是和GPIO的硬件引脚对应的,而数据的传递方向是通过控制寄存器设置的,通过控制寄存器可以设置每一位引脚的数据流向。
在这里插入图片描述
GPIO的工作模式
1、浮空输入GPIO_IN_FLOATING ——浮空输入,可以做KEY识别,RX1 2、带上拉输入GPIO_IPU——IO内部上拉电阻输入
3、带下拉输入GPIO_IPD—— IO内部下拉电阻输入
4、模拟输入GPIO_AIN ——应用ADC模拟输入,或者低功耗下省电
5、开漏输出GPIO_OUT_OD ——IO输出0接GND,IO输出1,悬空,需要外接上拉电阻,才能实现输出高电平。当输出为1时,IO口的状态由上拉电阻拉高电平,但由于是开漏输出模式,这样IO口也就可以由外部电路改变为低电平或不变。可以读IO输入电平变化,实现C51的IO双向功能
6、推挽输出GPIO_OUT_PP ——IO输出0-接GND, IO输出1 -接VCC,读输入值是未知的
7、复用功能的推挽输出GPIO_AF_PP ——片内外设功能(I2C的SCL,SDA)
8、复用功能的开漏输出GPIO_AF_OD——片内外设功能(TX1,MOSI,MISO.SCK.SS)

二、汇编语言点亮LED灯

LED0 EQU 0x42218194
RCC_APB2ENR EQU 0x40021018
;GPIOA_CRH EQU 0x40010804
GPIOB_CRL EQU 0x40010C00
 
Stack_Size      EQU     0x00000400
 
                AREA    STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem       SPACE   Stack_Size
__initial_sp
 
                AREA    RESET, DATA, READONLY
 
__Vectors       DCD     __initial_sp               
                DCD     Reset_Handler              
                    
                    
                AREA    |.text|, CODE, READONLY
                    
                THUMB
                REQUIRE8
                PRESERVE8
                    
                ENTRY
Reset_Handler 
                BL LED_Init
MainLoop        BL LED_ON
                BL Delay
                BL LED_OFF
                BL Delay
                
                B MainLoop
             
LED_Init
                PUSH {R0,R1, LR}
                
                LDR R0,=RCC_APB2ENR
                ORR R0,R0,#0x08		
                LDR R1,=RCC_APB2ENR
                STR R0,[R1]
                
                LDR R0,=GPIOB_CRL
                BIC R0,R0,#0XFF0FFFFF	
                LDR R1,=GPIOB_CRL
                STR R0,[R1]
                
                LDR R0,=GPIOB_CRL
                ORR R0,R0,#0X00300000
                LDR R1,=GPIOB_CRL
                STR R0,[R1]
                
                MOV R0,#1 
                LDR R1,=LED0
                STR R0,[R1]
             
                POP {R0,R1,PC}
 
             
LED_ON
                PUSH {R0,R1, LR}    
                
                MOV R0,#0 
                LDR R1,=LED0
                STR R0,[R1]
             
                POP {R0,R1,PC}
             
LED_OFF
                PUSH {R0,R1, LR}    
                
                MOV R0,#1 
                LDR R1,=LED0
                STR R0,[R1]
             
                POP {R0,R1,PC}             
             
Delay
                PUSH {R0,R1, LR}
                
                MOVS R0,#0
                MOVS R1,#0
                MOVS R2,#0
                
DelayLoop0        
                ADDS R0,R0,#1
 
                CMP R0,#330
                BCC DelayLoop0
                
                MOVS R0,#0
                ADDS R1,R1,#1
                CMP R1,#330
                BCC DelayLoop0
 
                MOVS R0,#0
                MOVS R1,#0
                ADDS R2,R2,#1
                CMP R2,#15
                BCC DelayLoop0
                
                POP {R0,R1,PC}    
 
                END

三、C语言点亮LED灯

延时函数Delay.h

void  Delay()
{
     unsigned  int  i;
     while(t--)
         for (i=0;i<10000000;i++);
}

点灯函数Light.h

//A灯
void A_LED(){
	GPIOA_ORD=0x0<<5;		//PA5低电平
	GPIOB_ORD=0x1<<6;		//PB6高电平
	GPIOC_ORD=0x1<<7;		//PC7高电平
}
//B灯
void B_LED(){
	GPIOA_ORD=0x1<<5;		//PA5高电平
	GPIOB_ORD=0x0<<6;		//PB6低电平
	GPIOC_ORD=0x1<<7;		//PC7高电平
}
//C灯
void C_LED(){
	GPIOA_ORD=0x1<<5;		//PA5高电平
	GPIOB_ORD=0x1<<6;		//PB6高电平
	GPIOC_ORD=0x0<<7;		//PC7低电平	
}

主函数

#include"Delay.h"
#include"Light.h"
#define RCC_AP2ENR	*((unsigned volatile int*)0x40021018)//APB2使能时钟寄存器
#define GPIOA_CRL	*((unsigned volatile int*)0x40010800)//配置GPIOA寄存器
#define	GPIOA_ORD	*((unsigned volatile int*)0x4001080C)
#define GPIOB_CRH	*((unsigned volatile int*)0x40010C04)//配置GPIOB寄存器
#define	GPIOB_ORD	*((unsigned volatile int*)0x40010C0C)
#define GPIOC_CRH	*((unsigned volatile int*)0x40011004)//GPIOC配置寄存器
#define	GPIOC_ORD	*((unsigned volatile int*)0x4001100C)

//主函数
int main()
{
	int j=100;
	RCC_AP2ENR|=1<<2;			//APB2-GPIOA外设时钟使能
	RCC_AP2ENR|=1<<3;			//APB2-GPIOB外设时钟使能	
	RCC_AP2ENR|=1<<4;			//APB2-GPIOC外设时钟使能
	//这两行代码可以合为 RCC_APB2ENR|=1<<3|1<<4;
	GPIOA_CRL&=0x0FFFFFFF;		//设置位 清零	
	GPIOA_CRL|=0x20000000;		//PA7推挽输出
	GPIOA_ORD|=1<<5;			//设置PA5初始灯为灭
	
	GPIOB_CRH&=0xFFFFFF0F;		//设置位 清零	
	GPIOB_CRH|=0x00000020;		//PB6推挽输出
	GPIOB_ORD|=1<<6;			//设置初始灯为灭
	
	GPIOC_CRH&=0x0FFFFFFF;		//设置位 清零
	GPIOC_CRH|=0x30000000;   	//PC7推挽输出
	GPIOC_ORD|=0x1<<7;			//设置初始灯为灭	
	while(j)
	{	
		A_LED();	
		Delay();
		B_LED();
		Delay();
		C_LED();
		Delay();
	}
}

编译构建后生成.HEX文件,创建工程及后续操作可参考笔者以前的博客
Keil5 MDK版的STM32工程创建

烧录程序
可以用Keil5直接烧录,也可用FlyMcu烧录。

  1. 打开程序,点击三个小圆点,导入生成的.HEX文件

在这里插入图片描述

  1. 读取器件信息
    在这里插入图片描述
  2. 开始编程
    在这里插入图片描述

四、构建实物

连线过程自行操作,由于编者搭线时未拍照,具体过程可上网查阅。

连线实物图
在这里插入图片描述

  • 运行结果
    在这里插入图片描述

五、小结

对于用STM32来开发一些简单功能的东西总体来说还是不难的,但是由于笔者是第一次用硬件左开发,对很多东西都不太理解,可以说是边做边学吧。我现在更加相信 “世上无难事,只要肯攀登” 了。

六、参考文章

STM32F103C8T6实现流水灯
STM32寄存器的简介、地址查找,与直接操作寄存器
STM32从地址到寄存器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值