STM32F103的流水灯点亮版本1(寄存器地址操作)

本文详细介绍了STM32F103C8T6微控制器的GPIO端口操作,包括地址映射、寄存器设置以及如何通过示例代码实现GPIO驱动流水灯的点亮与熄灭。作者分享了从新建keil工程到烧录过程的步骤,强调了基础配置和问题解决的重要性。
摘要由CSDN通过智能技术生成

STM32F103的流水灯点亮版本1(寄存器地址操作)

一.实验原理

1.STM32F103C8T6

STM32F103C8T6是一种微控制器,属于意法半导体(STMicroelectronics)的STM32系列。它是一款基于ARM Cortex-M3内核的32位单片机,具有高性能、低功耗、丰富的外设接口和强大的计算能力。STM32F103C8T6还具有丰富的存储容量和扩展性,适合于各种应用领域,如工业自动化、消费类电子、通信和控制等。

2.地址映射

STM32F103C8T6是一款32位ARM Cortex-M3微控制器,其地址映射如下:

Flash存储器:用于存储程序代码的非易失性存储器,大小为64KB,起始地址为0x0800 0000。

SRAM存储器:用于存储数据和程序的易失性存储器,大小为20KB,起始地址为0x2000 0000。

外设地址映射:

GPIO端口:每个GPIO端口有4个寄存器,包括输入数据寄存器、输出数据寄存器、数据方向寄存器和上拉下拉寄存器,其地址为0x4001 0800 - 0x4001 0C00。

ADC:内置12位ADC转换器,其地址为0x4001 2400 - 0x4001 27FF。

TIM定时器:STM32F103C8T6支持多个TIM定时器,每个定时器有数个寄存器,包括控制寄存器、计数器寄存器、比较寄存器等,其地址为0x4000 0000 - 0x4000 1000。

USART串口通信:STM32F103C8T6支持多个USART串口通信口,每个口有数个寄存器,包括控制寄存器、状态寄存器和数据寄存器等,其地址为0x4001 3800 - 0x4001 3C00。

I2C总线:STM32F103C8T6支持多个I2C总线,每个总线有数个寄存器,包括控制寄存器、状态寄存器和数据寄存器等,其地址为0x4000 5400 - 0x4000 5800。

NVIC中断向量表:用于存储中断向量表和NVIC寄存器的非易失性存储器,其地址为0xE000 E000 - 0xE000 FFFF。

3.寄存器映射

STM32F103C8T6是一款基于ARM Cortex-M3内核的微控制器,其内部集成了大量的外设模块,比如GPIO、USART、SPI、I2C等等。这些外设模块都需要通过寄存器进行配置和控制。

以下是STM32F103C8T6主要的寄存器映射:

RCC寄存器映射:RCC(Reset and Clock Control)寄存器用于控制系统时钟和外设时钟的配置和控制。该寄存器映射如下:
RCC_CR:时钟控制寄存器,用于控制系统时钟和外设时钟的开关。
RCC_CFGR:时钟配置寄存器,用于配置系统时钟和外设时钟的分频和时钟源选择等参数。
RCC_APB2ENR:APB2总线外设时钟使能寄存器,用于控制APB2总线上的外设时钟使能。
RCC_APB1ENR:APB1总线外设时钟使能寄存器,用于控制APB1总线上的外设时钟使能。
GPIO寄存器映射:GPIO(General Purpose Input/Output)寄存器用于控制GPIO口的输入/输出状态。该寄存器映射如下:
GPIOx_CRL:GPIO口配置寄存器0,用于控制GPIO口的输入/输出模式、上下拉电阻等参数。
GPIOx_CRH:GPIO口配置寄存器1,用于控制GPIO口的输入/输出模式、上下拉电阻等参数。
GPIOx_ODR:GPIO口数据输出寄存器,用于控制GPIO口的输出状态。
GPIOx_IDR:GPIO口数据输入寄存器,用于读取GPIO口的输入状态。
外设寄存器映射:除了上述的寄存器映射之外,STM32F103C8T6还有大量的外设寄存器需要配置和控制,比如USART、SPI、I2C等等。这些外设的寄存器映射可以在官方的数据手册中查找到。

4.GPIO端口设置

本次实验采用GPIO的ABC端口进行电平输出

请添加图片描述时钟地址
请添加图片描述

请添加图片描述
首先打开ABC三个输出端口的时钟,将三个位置1

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

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

请添加图片描述

以GPIOA和0号引脚(A0)为例,将其设置为推挽输出,并设置最大速度为10MHz,则将控制A0的四个位设置为0001

#define GPIOA_CRL (*(unsigned int *)0x40010800)

// 最后四位变为0001
GPIOA_CRL |= (1<<0);  // 最后一位变1
GPIOA_CRL &= ~(0xE<<0);  // 倒数2、3、4位变0

三个端口设置如下

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

// 配置 GPIO 口为推免输出
// 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
// GPIOA----最后四位为0001
GPIOA_CRL |= (1<<0);  // 最后一位变1
GPIOA_CRL &= ~(0xE<<0);  // 倒数2、3、4位变0

设置低电平
请添加图片描述

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

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

二.创建项目

1.新建keil工程

请添加图片描述

2.编写代码并生成hex文件

在上一节点亮led的基础上加上时延函数

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

总代码如下


#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<1000;i++);
}


int main(){
	// 开启时钟
	RCC_APB2ENR |= (1<<2); // 开启 GPIOA 时钟
	RCC_APB2ENR |= (1<<3); // 开启 GPIOB 时钟
	RCC_APB2ENR |= (1<<4); // 开启 GPIOC 时钟
	
	
	// 设置 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
		Delay_ms(1000000);
		
		GPIOC_ODR &= ~(1<<15); // 点灯2
		Delay_ms(1000000);
		GPIOC_ODR |= (1<<15);  // 灭灯2
		Delay_ms(1000000);
		
		GPIOA_ODR &= ~(1<<0); // 点灯3
		Delay_ms(1000000);
		GPIOA_ODR |= (1<<0);  // 灭灯3
		Delay_ms(1000000);
		
	}
	
}


void SystemInit(){
	
}  //防报错


生成hex文件
请添加图片描述

3.烧录实现

请添加图片描述

c39672e091b9b22fa

四.实验总结

此次实验让我认识到如何用GPIO端口的八种工作方式并进行输入输出,在实现烧录时虽然出现了不少问题,但是依然实现了,总的来说在stm32的学习中我刚入门,还需多多学习。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值