搜索
您的当前位置:首页正文

使用寄存器点亮第LED灯——基于野火STM32F103Mini开发板

来源:吉趣旅游网

先给程序:

main.c

#include "stm32f10x.h" 

/* 主函数 */
int main(void)
{	
	// 开启GPIOC 端口时钟
	RCC_APB2ENR |= (1<<4);

	//清空控制PC2的端口位
	GPIOC_CRL &= ~( 0x0F<< (4*2));	
	// 配置PC2为通用推挽输出,速度为10M
	GPIOC_CRL |= (1<<4*2);

	// PC2 输出 低电平
	GPIOC_ODR &= ~(1<<2);
	
	while(1);
}

// 函数为空,目的是为了骗过编译器不报错
void SystemInit(void)
{	
	
}

stm32f10x.h

/*本文件用于添加寄存器地址及结构体定义*/

/*片上外设基地址  */
#define PERIPH_BASE           ((unsigned int)0x40000000)

/*APB2 总线基地址 */
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
/* AHB总线基地址 */
#define AHBPERIPH_BASE        (PERIPH_BASE + 0x20000)

/*GPIOC外设基地址*/
#define GPIOC_BASE            (APB2PERIPH_BASE + 0x1000)

/* GPIOC寄存器地址,强制转换成指针 */
#define GPIOC_CRL		    *(unsigned int*)(GPIOC_BASE+0x00)
#define GPIOC_CRH			*(unsigned int*)(GPIOC_BASE+0x04)
#define GPIOC_IDR			*(unsigned int*)(GPIOC_BASE+0x08)
#define GPIOC_ODR			*(unsigned int*)(GPIOC_BASE+0x0C)
#define GPIOC_BSRR	        *(unsigned int*)(GPIOC_BASE+0x10)
#define GPIOC_BRR			*(unsigned int*)(GPIOC_BASE+0x14)
#define GPIOC_LCKR		    *(unsigned int*)(GPIOC_BASE+0x18)

/*RCC外设基地址*/
#define RCC_BASE      (AHBPERIPH_BASE + 0x1000)
/*RCC的AHB1时钟使能寄存器地址,强制转换成指针*/
#define RCC_APB2ENR		 *(unsigned int*)(RCC_BASE+0x18)

代码分析:

(初学小白,理解颇浅,如有不对,敬请谅解【抱歉脸】)

首先参考STM32F103Mini原理图,得到LED1和LED2灯为PC2和PC3,对应连接着R45和R46电阻,管脚号分别为10和11,这里主要先点亮PC2端口的LED1灯,LED2同理,如下图所示:

 LED灯原理图

开发板上LED灯所对应的R45和R46电阻

 STM32F103RCT6芯片原理图

两个LED灯的阳极引出连接到3.3V电源,阴极各经过1个限流电阻引入至STM32的2个GPIO引脚中,所以我们只要控制这两个引脚输出高低电平,即可控制其所连接LED灯的亮灭。将GPIO的引脚设置成推挽输出模式并且默认下拉,输出低电平,这样就能让LED灯亮起来了。

stm32f10x.h 文件

/*片上外设基地址  */
#define PERIPH_BASE           ((unsigned int)0x40000000)

/* APB2 总线基地址 */
#define APB2PERIPH_BASE       (PERIPH_BASE + 0x10000)
/* AHB总线基地址 */
#define AHBPERIPH_BASE        (PERIPH_BASE + 0x20000)

/*GPIOC外设基地址*/
#define GPIOC_BASE            (APB2PERIPH_BASE + 0x1000)

/* GPIOC寄存器地址,强制转换成指针 */
#define GPIOC_CRL			*(unsigned int*)(GPIOC_BASE+0x00)
#define GPIOC_CRH			*(unsigned int*)(GPIOC_BASE+0x04)
#define GPIOC_IDR			*(unsigned int*)(GPIOC_BASE+0x08)
#define GPIOC_ODR			*(unsigned int*)(GPIOC_BASE+0x0C)
#define GPIOC_BSRR	        *(unsigned int*)(GPIOC_BASE+0x10)
#define GPIOC_BRR			*(unsigned int*)(GPIOC_BASE+0x14)
#define GPIOC_LCKR		    *(unsigned int*)(GPIOC_BASE+0x18)
/*RCC外设基地址*/
#define RCC_BASE      (AHBPERIPH_BASE + 0x1000)
/*RCC的AHB1时钟使能寄存器地址,强制转换成指针*/
#define RCC_APB2ENR		 *(unsigned int*)(RCC_BASE+0x18)

main.c文件

// 开启GPIOC 端口时钟
RCC_APB2ENR |= (1<<4);

首先,开启外部时钟,RCC_APB2ENR置1,代码释义参考下图:

|= (1 << 4)详解

所有的GPIO都挂载到APB2总线上,具体的时钟由APB2外设时钟使能寄存器 (RCC_ APB2ENR)来控制。

//清空控制PC2的端口位
GPIOC_CRL &= ~( 0x0F<< (4*2));	
// 配置PC2为通用推挽输出,速度为10M
GPIOC_CRL |= (1<<4*2);

接着,在代码中,我们先把控制PC2的端口位清0,然后再向它赋值“0001b”,从而使GPIOC2引脚设置成输出模式,速度为10M,设置参考《STM32库开发实战指南》99页,如下图所示:

// PC2 输出 低电平
GPIOC_ODR &= ~(1<<2);

 最后,给PC2输出低电平,点亮LED1。

(在输出模式时,对端口位设置/清除寄存器BSRR寄存器、端口位清除寄存器BRR和ODR寄存器写入参数即可控制引脚的电平状态,其中操作BSRR和BRR最终影响的都是ODR寄存器,然后再通过ODR寄存器的输出来控制GPIO。为了一步到位,我们在这里直接操作ODR寄存器来控制GPIO的电平)

因篇幅问题不能全部显示,请点此查看更多更全内容

Top