[转载]STM32学习笔记——控制GPIO输出点亮LED灯(直接操作存储器)

控制GPIO输出点亮LED灯——直接操作存储器

.预备知识

使用51单片机控制IO口相对来说要简单得多,最小系统搭建完毕后直接通过软件往各IO口写“1”或者写“0”即可。但使用STM32控制IO口输入输出却远没有这么容易,经过一个下午的查阅文献及探索后,略微有了头绪。

个人所使用的STM32F103VBT6100个引脚,其中有五组GPIOGPIOA…GPIOE),每组有16GPIO端口GPIOx_Pin0…GPIOx_Pin1580个,每个GPIO端口都有:

两个32位配置寄存器(GPIOx_CRLGPIOx_CRH)

两个32位数据寄存器(GPIOx_IDRGPIOx_ODR)

一个32位置位/复位寄存器(GPIOx_BSRR)

一个16位复位寄存器(GPIOx_BRR);

和一个32位锁定寄存器(GPIOx_LCKR)

其中各个寄存器的作用:

名称

寄存器

意义

端口配置寄存器

GPIOx_CRL

GPIOx_CRH

配置GPIO工作模式

端口输入数据寄存器

GPIOx_IDR

读取GPIO输入状态

端口输出数据寄存器

GPIOx_ODR

控制GPIO输出状态

端口位设置/复位寄存器

GPIOx_BSRR

用于位操作GPIO的输出状态的:设置端口为01

端口位复位寄存器

GPIOx_BRR

用于位操作GPIO的输出状态的:设置端口为0

端口配置锁定寄存器

GPIOx_LCKR

端口锁定后下次系统复位之前将不能再更改端口位的配置


每个I/O端口位可以自由编程,然而I/0端口寄存器必须按32位字被访问(不允许半字或字节访问)GPIOx_BSRRGPIOx_BRR寄存器允许对任何GPIO寄存器的读/更改的独立访问;这样,在读和更改访问之间产生IRQ时不会发生危险。

输入数据寄存器(GPIOx_IDR)在每个APB2时钟周期捕捉I/O引脚上的数据。因此,要控制GPIOC端口,必须先使能APB2时钟。此外,STM32初始化外设第一步就是开启APB时钟。(时钟部分知识暂时知道该如此,往后再学习。)

关于GPIO各寄存器的描述:

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

[转载]STM32学习笔记——控制GPIO输出点亮LED灯(直接操作存储器) [转载]STM32学习笔记——控制GPIO输出点亮LED灯(直接操作存储器)


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

[转载]STM32学习笔记——控制GPIO输出点亮LED灯(直接操作存储器) [转载]STM32学习笔记——控制GPIO输出点亮LED灯(直接操作存储器)


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

[转载]STM32学习笔记——控制GPIO输出点亮LED灯(直接操作存储器)


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

[转载]STM32学习笔记——控制GPIO输出点亮LED灯(直接操作存储器)


端口位设置/复位寄存器(GPIOx_BSRR) (x=A..E):

[转载]STM32学习笔记——控制GPIO输出点亮LED灯(直接操作存储器)


端口位复位寄存器(GPIOx_BRR) (x=A..E):

[转载]STM32学习笔记——控制GPIO输出点亮LED灯(直接操作存储器)


端口配置锁定寄存器(GPIOx_LCKR) (x=A..E):

当执行正确的写序列设置了位16(LCKK)时,该寄存器用来锁定端口位的配置。位[15:0]用于锁定GPIO端口的配置。在规定的写入操作期间,不能改变LCKP[15:0]。当对相应的端口位执行了LOCK序列后,在下次系统复位之前将不能再更改端口位的配置。

每个锁定位锁定控制寄存器(CRL, CRH)中相应的4个位。

[转载]STM32学习笔记——控制GPIO输出点亮LED灯(直接操作存储器) [转载]STM32学习笔记——控制GPIO输出点亮LED灯(直接操作存储器)
 
 
各寄存器地址:
GPIOC_CRL0x40011000
GPIOC_CRH0x40011004
GPIOC_ODR0x4001100C
GPIOC_BSRR0x40011010
GPIOC_BRR0x40011014

RCC_APB2ENR0x40021018

.点亮LED

外部LED灯原理图:

[转载]STM32学习笔记——控制GPIO输出点亮LED灯(直接操作存储器)

编程思路:

1.     定义各寄存器地址

2.     使能APB2时钟

3.     配置GPIOC各端口输出模式

4.     利用BRRBSRRODR寄存器点亮LED灯并循环流水灯

具体编程:

新建工程并设置好环境,添加c文件,键入如下程序:

//**********************************************

//* 通过直接操作存储器控制GPIO输出点亮LED    *

//* LED1=GPIOC_Pin6;                           *

//* LED2=GPIOC_Pin7;                           *

//* LED3=GPIOC_Pin8;                           *

//* LED4=GPIOC_Pin9;                           *

//* ------------------Sah_Pah----------------- *

//**********************************************

#include<stdio.h>

 

//定义各寄存器地址

#define GPIOC_CRL  (* (volatile unsigned long *)(0x40011000))

#define GPIOC_CRH  (* (volatile unsigned long *)(0x40011004))

#define GPIOC_ODR  (* (volatile unsigned long *)(0x4001100C))

#define GPIOC_BSRR (* (volatile unsigned long *)(0x40011010))

#define GPIOC_BRR  (* (volatile unsigned long *)(0x40011014))

#define RCC_APB2ENR (*(volatile unsigned long *)(0x40021018))

 

//设置GPIOC_Pin6,Pin7,Pin8,Pin9为推挽输出模式,最大速度50MHz

#define _GPIOC_CRL 0x33000000

#define _GPIOC_CRH 0x00000033

void delay(void);

 

void main(void)

{

  volatile int i;

  //使能APB2PORTC时钟

  RCC_APB2ENR |=(1<<4);

//设置GPIOC_Pin6,Pin7,Pin8,Pin9为推挽输出模式,最大速度50MHz

  GPIOC_CRL = _GPIOC_CRL;

  GPIOC_CRH = _GPIOC_CRH;

 

  while(1)

  {

    delay();

    //利用端口位复位寄存器BRR清除GPIOC各端口的ODR位为0

    GPIOC_BRR=0xFFFF;

    delay();

    //利用端口位设置/复位寄存器BSRRP6P7P8P9口置1,点亮LED

    GPIOC_BSRR=0x000003C0;

    delay();

    //重复三次,偷懒就不写循环了

    GPIOC_BRR=0xFFFF;

    delay();

    GPIOC_BSRR=0x000003C0;

    delay();

    GPIOC_BRR=0xFFFF;

    delay();

    GPIOC_BSRR=0x000003C0;

    delay();

    GPIOC_BRR=0xFFFF;

    //利用端口输出数据寄存器ODR进行流水灯循环

    for(i=0;i<3;i++)

    {

      //P6脚置1

      GPIOC_ODR=0x0040;

      delay();

      //0

      GPIOC_ODR=0x0000;

      //P7脚置1

      GPIOC_ODR=0x0080;

      delay();

      GPIOC_ODR=0x0000;

      //P8脚置1

      GPIOC_ODR=0x0100;

      delay();

      GPIOC_ODR=0x0000;

      //P9脚置1

      GPIOC_ODR=0x0200;

      delay();

    }

  }

}

 

//定义延迟函数

void delay(void)

{

 unsigned long j,n=100000;

 while(n--)

 {

  j=12;

  while(j--);

 }

}

最终结果:

保存编译后,将程序烧写到开发板上,板上四个LED等闪烁三次后以流水灯形式循环三次。

.参考文献

[1]半壶水,《STM32 菜鸟学习手册-罗嗦》,  http://wenku.baidu.com/view/fc7c7d20ccbff121dd3683da.html, 2012-08-19.

[2]电脑圈圈.自己动手创建一个基于万利STM32板的IAR工程[EB/OL].http://blog.21ic.com/user1/2198/archives/2008/48929.html ,2008-07-02/2012-08-19.

[3]Changing.stm32点个灯[操作寄存器+库函数][EB/OL]. http://www.ichanging.org/stm32_gpio_led.html, 2012-06-29/2012-08-19.

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您好!对于STM32GPIO输出实验,点亮三色LED,您可以按照以下步骤进行操作: 1. 首先,您需要在STM32开发环境中创建一个新的工程。 2. 在工程中,您需要包含相应的头文件,如"stm32f10x.h"。 3. 接下来,配置相应的引脚为输出模式。假设红色LED连接到GPIOA的Pin0引脚,绿色LED连接到GPIOA的Pin1引脚,蓝色LED连接到GPIOA的Pin2引脚,您可以使用以下代码进行配置: ``` GPIO_InitTypeDef GPIO_InitStructure; // 使能GPIOA的时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); // 配置红色LED引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; // 推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置绿色LED引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); // 配置蓝色LED引脚 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); ``` 4. 现在,您可以使用相应的寄存器控制LED点亮和熄灭。例如,要点亮红色LED,可以使用以下代码: ``` GPIO_SetBits(GPIOA, GPIO_Pin_0); // 将Pin0引脚置高,点亮红色LED ``` 要熄灭红色LED,可以使用以下代码: ``` GPIO_ResetBits(GPIOA, GPIO_Pin_0); // 将Pin0引脚置低,熄灭红色LED ``` 同样的方法,您可以控制绿色和蓝色LED点亮和熄灭。 这就是点亮三色LED的基本步骤。希望对您有所帮助!如果您有任何其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值