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

目录

一、 实验目的

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

二、 端口初始化

1.时钟配置

以下内容皆是通过查询stm32官方文档获得,可自行至官网下载对应文档

  1. 查看存储器映像,找到时钟使能映射基地址。
    STM32F103寄存器方式点亮LED流水灯
  2. 可知时钟使能寄存器偏移地址为0x18

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

  1. 时钟使能
#define RCC_APB2ENR		*((unsigned volatile int*)0x40021018)
RCC_APB2ENR|=1<<2|1<<3|1<<4;  

说明:0x40021018=基地址+偏移地址=0x40021000+0x18

2.输入输出模式设置

我的3个引脚为A12,B0,C14.

  1. GPIOX基地址
    STM32F103寄存器方式点亮LED流水灯

端口配置低寄存器(GPIOx_CRL) 0-7,端口配置高寄存器(GPIOx_CRH) 8-15

  1. A12,C14STM32F103寄存器方式点亮LED流水灯
  2. B0STM32F103寄存器方式点亮LED流水灯
  3. 配置对应引脚基地址
//GPIOA
#define GPIOA_CRH		*((unsigned volatile int*)0x40010804)
//GPIOB
#define GPIOB_CRL		*((unsigned volatile int*)0x40010C00)
//GPIOC
#define GPIOC_CRH		*((unsigned volatile int*)0x40011004)
  1. 设置输出模式为推挽输出,速率为2Mhz
    STM32F103寄存器方式点亮LED流水灯
GPIOA_CRH &= 0xFFF0FFFF;		//设置位 清零	
GPIOA_CRH |= 0x00020000;		//PA12推挽输出,把第19、18、17、16位变为0010

GPIOB_CRL &=0xFFFFFFF0;		//设置位 清零	
GPIOB_CRL |=0x00000002;		//PB0推挽输出,把第3、2、1、0变为0010

GPIOC_CRH &=0xF0FFFFFF;		//设置位 清零	
GPIOC_CRH |=0x02000000;		//PC14推挽输出,把第27、26、25、24变为0010

三、代码编写

  1. c语言代码
    led.h
#ifndef _LED_H
#define _LED_H

//#define LEDO PCout(13)
//时钟使能
#define RCC_APB2ENR		*((unsigned volatile int*)0x40021018)
//GPIOA
#define GPIOA_CRH		*((unsigned volatile int*)0x40010804)
#define	GPIOA_ODR		*((unsigned volatile int*)0x4001080C)
//GPIOB
#define GPIOB_CRL		*((unsigned volatile int*)0x40010C00)
#define	GPIOB_ODR		*((unsigned volatile int*)0x40010C0C)
//GPIOC
#define GPIOC_CRH		*((unsigned volatile int*)0x40011004)
#define	GPIOC_ODR		*((unsigned volatile int*)0x4001100C)
void My_LED_Init(void);//初始化
void Delay();
#endif

led.c

#include "led.h"
#include "stm32f10x.h"

void My_LED_Init(void)
{
		  	RCC_APB2ENR|=1<<2|1<<3|1<<4; //使能
	
				GPIOA_CRH &= 0xFFF0FFFF;		//设置位 清零	
				GPIOA_CRH |= 0x00020000;		//PA12推挽输出,把第19、18、17、16位变为0010
				GPIOA_ODR &=~(1<<12);			//设置初始灯为灭
	
				GPIOB_CRL &=0xFFFFFFF0;		//设置位 清零	
				GPIOB_CRL |=0x00000002;		//PB0推挽输出,把第3、2、1、0变为0010
				GPIOB_ODR &=~(1<<0);			//设置初始灯为灭
  
				GPIOC_CRH &=0xF0FFFFFF;		//设置位 清零	
				GPIOC_CRH |=0x02000000;		//PC14推挽输出,把第27、26、25、24变为0010
        GPIOC_ODR &=~(1<<14);			//设置初始灯为灭
	
				
	
}
void Delay()
 {
   u32 i=0;
   for(;i<5000000;i++);
 }

main.c

#include "stm32f10x.h"
#include "led.h"

int main(void)
{
	  My_LED_Init();
	 while(1)
	 {
//		  GPIO_SetBits(GPIOC,GPIO_Pin_13) ;
//		 
//		  delay_ms (1000);
//			GPIO_ResetBits(GPIOC,GPIO_Pin_13);
//		  delay_ms(1000);
		 //GPIOA
			GPIOA_ODR|=1<<12;		//PA2高电平
			Delay();
			GPIOA_ODR&=~(1<<12);		//PA2低电平,因为是置0,所以用按位与
			
			//GPIOB
			GPIOB_ODR|=1<<0;		//PB0高电平
			Delay();
			GPIOB_ODR&=~(1<<0);		//PB0低电平,因为是置0,所以用按位与
	
			//GPIOC
			GPIOC_ODR|=1<<14;		//PC14高电平
			Delay();
			GPIOC_ODR&=~(1<<14);		//PC14低电平,因为是置0,所以用按位与
		
		}
}
  1. 汇编代码
 AREA MYDATA, DATA
	
 AREA MYCODE, CODE
	ENTRY
	EXPORT led

led
	;使能A,B,C
    ldr r0, =0x40021018
    ldr r1, =0x0000001c
    str r1, [r0]                


	;配置端口A12
	ldr r0, =0x40010804
    ldr r1, [r0]
    bic r1, r1, #0x000f0000
    orr r1, r1, #0x00010000
    str r1, [r0]

	;配置端口B0
    ldr r0, =0x40010c00
    ldr r1, [r0]
    bic r1, r1, #0x0000000f
    orr r1, r1, #0x00000001
    str r1, [r0]
	
	;配置端口C14
	ldr r0, =0x40011004
    ldr r1, [r0]
    bic r1, r1, #0x0f000000
    orr r1, r1, #0x01000000
    str r1, [r0]

	;初始为A12亮灯
	ldr r0, =0x4001080c
    ldr r1, =0x00000010
    str r1, [r0]

	ldr r0, =5000000;频率
    ldr r1, =0
	
  ;循环亮灯	
blink
    add r1, r1, #1
    cmp r1, r0
    blt blink
	
	;A12灭
	ldr r1, =0x4001080c
    ldr r2, [r1]
    eor r2, r2, #0x00001000
    str r2, [r1]
	
	;B0亮
	ldr r1, =0x40010c0c
    ldr r2, [r1]
    eor r2, r2, #0x00000001
    str r2, [r1]
	
	ldr r1, =0

blink1	
	add r1, r1, #1
    cmp r1, r0
    blt blink1
	
	;B0灭
	ldr r1, =0x40010c0c
    ldr r2, [r1]
    eor r2, r2, #0x00000010
    str r2, [r1]
	
	;C14亮
	ldr r1, =0x4001100c
    ldr r2, [r1]
    eor r2, r2, #0x00004000
    str r2, [r1]
	

	ldr r1, =0

blink2
	add r1, r1, #1
    cmp r1, r0
    blt blink2
	
	;C14灭
	ldr r1, =0x4001100c
    ldr r2, [r1]
    eor r2, r2, #0x00004000
    str r2, [r1]
	
	;A12亮
	ldr r1, =0x4001080c
    ldr r2, [r1]
    eor r2, r2, #0x00001000
    str r2, [r1]
	
	ldr r1, =0
    b blink

	END

四、效果显示

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

3个LED对应的GPIO端口电平状态为 111 (高电平,灯不亮),
S1(011)、S2(101)和S3(110)这3个状态,按周期时间进行状态转换:
011 (S1)—> 101(S2) —> 110(S3) —>011 (S1)…

五、总结

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

六、参考

https://blog.csdn.net/gelad_w/article/details/115555631
https://blog.csdn.net/qq_47281915/article/details/120812867

上一篇:[物联网] - [STM32/51|JavaWeb|微信小程序] - 3.系统的进行模块开发


下一篇:粤嵌gec6818开发板LED屏幕上画图(数组与内存映射的采用)