配置STM32寄存器控制GPIO点亮LED

STM32点亮LED 寄存器方式 

IO简介

1、每个IO可以自由编程,但是IO口寄存器必须按照32位字被访问。

2、每个IO端口都有7个寄存器来控制。

CRL 【0-7】端口配置寄存器  32位

CRH 【8-15】端口配置寄存器  32位

IDR 数据寄存器 32位  输入

ODR 数据寄存器 32位 输出

BSRR 置位/复位寄存器  32位

BRR 复位寄存器  16位

LCKR 锁存寄存器  32位

3、常用的IO端口寄存器 CRL CRH IDR ODR

4、CRL CRH控制每个IO口的模式及输出速率

(1)STM32的IO口可以由软件配置为8种模式:

输入浮空

输入上拉

输入下拉

模拟输入

开漏输出

推挽输出

推挽式复用功能

开漏复用功能

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

偏移地址:0x00

复位值:0x4444 4444

 

(3)端口位配置

配置模式

 

CNF1

CNF0

MODE1

MODE0

PxODR寄存器

通用输出

 

 

推挽输出

0

0

01

10

11

 

0或1

开漏输出

0

1

 

 

0或1

复用功能输出

 

推挽

1

0

 

 

不使用

开漏

1

1

 

 

不使用

输入

 

 

 

模拟输入

0

0

00

 

不使用

浮空输入

0

1

 

 

不使用

下拉输入

1

0

 

 

0

上拉输入

1

0

 

 

1

(4)输出模式

MODE[1:0]

意义

00

保留

01

最大输出速率10MHz

10

最大输出速率2MHz

11

最大输出速率50MHz

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

偏移地址:0x04

复位值:0x4444 4444

CRH的作用和使用方法与CRL基本一致。

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

偏移地址:0x08

复位值:0x0000 XXXX

IDR是一个端口输入数据寄存器,只用了低16位。

IDR寄存器是一个只读寄存器,并且只能以16位的形式读出。

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

偏移地址:0xCH

复位值:0x0000 0000、

ODR是一个端口输出数据寄存器,只用了低16位。

ODR寄存器是一个可读写的寄存器。

从该寄存器读出来的数据可以判断当前IO口的输出状态。

向该寄存器写数据,可以控制某个IO口的输出电平。

注意:

在配置STM32外设的时候,任何时候都需要先使能该外设时钟。例如APB2ENR是APB2总线上的外设时钟使能寄存器。

Keil

1、工程创建(寄存器)

模板文件结构

└─OBJ

    └─project_template

        ├─CMSIS

        │  └─CM3

        │      ├─CoreSupport

        │      │      core_cm3.c

        │      │      core_cm3.h

        │      │     

        │      └─DeviceSupport

        │          └─ST

        │              └─STM32F10x

        │                  │  stm32f10x.h

        │                  │  system_stm32f10x.c

        │                  │  system_stm32f10x.h

        │                  │ 

        │                  └─startup

        │                      └─arm

        │                              startup_stm32f10x_cl.s

        │                              startup_stm32f10x_hd.s

        │                              startup_stm32f10x_hd_vl.s

        │                              startup_stm32f10x_ld.s

        │                              startup_stm32f10x_ld_vl.s

        │                              startup_stm32f10x_md.s

        │                              startup_stm32f10x_md_vl.s

        │                              startup_stm32f10x_xl.s

        │                             

        ├─HARDWARE

        │  ├─inc

        │  └─src

        ├─lst

        ├─out

        ├─project

        └─user

                main.c

                stm32f10x_conf.h

                stm32f10x_it.c

                stm32f10x_it.h

2、模板工程结构(寄存器)

 

 

3、寄存器编程技巧

                寄存器编程的一般步骤:

                (1)宏定义寄存器基地址         通过查看芯片数据手册获得

                (2)宏定义寄存器地址           基地址+偏移量

                (3)宏定义寄存器的指针类型     (*(unsigned int*)address)

                (4)对寄存器指针进行赋值

 

点亮LED

1 原理图

 

 

 

LED连接特点:

8个LED灯共阳极,IO提供低电平时,LED灯亮

LED灯在CPU上的接口是PC端口,PC0-PC7

2 端口定义

第一步:宏定义PC端口的寄存器地址

端口PC的其实地址是 0x4001 1000

定义GPIO端口C的基地址:   #define GPIOC_BASE_ADD  0x40011000

第二步:配置端口

LED灯只用到了GPIOC端口的0-7位,所以端口配置寄存器只需要查看地位的寄存器即可。

寄存器地址偏移量是:0x00

寄存器的地址可以定义为: 

#define GPIOC_CRL_ADD  (GPIOC_BASE_ADD + 0x00)
#define GPIOC_CRL  (*(*unsigned int)GPIOC_CRL_ADD)

复位值是:0x4444 4444

GPIOC端口的CRL寄存器的初始化值可以为:

GPIOC_CRL = 0x44444444;

GPIOC端口的每个IO口都是有该寄存器的四位控制的。

    CNF(2位):端口配置位

    在这里我们需要将这两位配置为推挽输出即可:00

    MODE(2位):端口模式位

    在这里我们设置IO口的模式位输出模式,最大速度50MHz : 11

    即每一个IO口的配置位值应该是:0x03

如果需要将GPIOC的0-7个IO口全配置好,而需要以下语句:

GPIOC_CRL = 0x33333333;

第三步:设置IO口的输出值

经过第二步,GPIOC端口的0-7位就配置好了。但是现在还不能是LED灯发光。需要LED灯发光,还要向ODR寄存器中设置好每个端口的数据。

LED灯只用到了GPIOC端口的0-7位,所以我们也就只需要将ODR寄存器的0-7位配置好就可以了。

ODR寄存的地址偏移是:0Ch

则定义ODR寄存器的地址为:

#define GPIOC_ODR_ADD (GPIOC_BASE_ADD + 0x0C);
#define GPIO_ODR (*(*unsigned int)GPIOC_ODR_ADD);

ODR的复位值是:0x0000 0000

则ODR寄存器的初始化值可以设置为:GPIO_ODR = 0x00;

如果我们需要不同的LED灯亮,则只需要就ODR寄存器中的相关位配置为0输出即可。

第四步:设置外设时钟

注意,进过上面的三步,我们将通用GPIO相关的设置都弄清楚了,但是现在还不能使得LED灯亮。因为,STM32的端口管理还需要涉及到相关的时钟设置的内容。

我们查询手册中的系统结构图可以看出,GPIOC是APB2总线上的外设。那么我们还需要将APB2总线时钟相关的参数设置好。

首先确认RCC时钟模块的寄存器基地址:

#define RCC_BASE_ADD 0x40021000

APB2外设使能时钟的寄存器地址偏移量为0x18

#define RCC_APB2ENR_ADD (RCC_BASE_ADD + 0x18)
#define RCC_APB2ENR (*(*unsigned int)RCC_APB2ENR_ADD)

需要外设的时钟打开,只需要将外设时钟使能寄存器的相关位设置为1即可。例如我们需要GPIOC的外设时钟使能,那我们只需要将RCC_APB2ENR的第4位设置为1;

RCC_APB2ENR = 0x00000010

3 源代码

//寄存器基地址
#define GPIOC_BASE_ADD 0x40011000
#define RCC_BASE_ADD0x40021000
//寄存器地址定义
#define GPIOC_CRL_ADD (GPIOC_BASE_ADD + 0x00)
#define GPIOC_ODR_ADD (GPIOC_BASE_ADD + 0x0C)
#define RCC_APB2ENR_ADD (RCC_BASE_ADD + 0x18)
//寄存器定义
#define GPIOC_CRL (*(unsigned int *)GPIOC_CRL_ADD)
#define GPIOC_ODR (*(unsigned int *)GPIOC_ODR_ADD)
#define RCC_APB2ENR (*(unsigned int *)RCC_APB2ENR_ADD)
//函数声明
void led_init(void);
void led_run(void);
void delay(void); //粗略延时
int main(void)
{
    led_init();
    //led初始化之后,LED应该是全亮状态
    while(1)
    {
        led_run();
    }
    return 0;
}
void led_init()
{
    RCC_APB2ENR = 0x00000010;
    GPIOC_CRL &= 0x00;
    PIOC_CRL |= 0x33333333;
    GPIOC_ODR |= 0x00;               //LED全亮
}
void led_run()
{
    unsigned int i = 0;
    GPIOC_ODR |= ~(0x00000001);
    delay();
    for(i = 0; i < 8; i++)
    {
        GPIOC_ODR <<= 1;
        delay();
    }
}
void delay()
{
    unsigned int i,j;
    for(i = 0;i<1000;i++)
    {
        for(j = 0;j<1000;j++);
    }
}

 

  • 3
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

星顶照

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值