LED跑马灯-寄存器

一,GPIO知识回顾

1,四种输入模式:

    输入浮空
    输入上拉
    输入下拉
    模拟输入

2,四种输出模式:

    开漏输出
    开漏复用输出
    推挽输出
    推挽复用输出

3,三种最大输出速度

    2MHz 
    10MHz 
    50MHz

每组GPIO共16个IO口,含下7个寄存器

GPIOx_CRL  : 端口配置低寄存器
GPIOx_CRH  : 端口配置高寄存器
GPIOx_IDR  : 端口输入寄存器
GPIOx_ODR  : 端口输出寄存器
GPIOx_BSRR : 端口位设置/清除寄存器
GPIOx_BRR  : 端口位清除寄存器
GPIOx_LCKR : 端口配置锁存寄存器

二,LED硬件连接:

  LED跑马灯-寄存器_第1张图片

连接方式:
    LED0连接PB5引脚
    LED1连接PE5引脚

三,LED跑马灯实现流程-寄存器

 1,使能GPIO时钟

 2,初始化IO口工作模式
      配置寄存器:GPIOx_CRH/CRL

 3,操作IO口输出高低电平
      配置寄存器GPIO_ODR或GPIO_BRR

四,寄存器介绍

4.1,RCC_APB2ENR寄存器

4.1.1,RCC_APB2ENR相关文档

  LED跑马灯-寄存器_第2张图片
  
  使能GPIOB时钟:
  
  这里写图片描述
  
  使能GPIOE时钟:
  
  这里写图片描述


4.1.2,RCC_APB2ENR相关源码:

stm32f10x.h找到RCC_TypeDef结构体声明:

typedef struct
{
  __IO uint32_t CR;
  __IO uint32_t CFGR;
  __IO uint32_t CIR;
  __IO uint32_t APB2RSTR;
  __IO uint32_t APB1RSTR;
  __IO uint32_t AHBENR;
  __IO uint32_t APB2ENR;
  __IO uint32_t APB1ENR;
  __IO uint32_t BDCR;
  __IO uint32_t CSR;

#ifdef STM32F10X_CL
  __IO uint32_t AHBRSTR;
  __IO uint32_t CFGR2;
#endif /* STM32F10X_CL */

#if defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || defined (STM32F10X_HD_VL)
  uint32_t RESERVED0;
  __IO uint32_t CFGR2;
#endif /* STM32F10X_LD_VL || STM32F10X_MD_VL || STM32F10X_HD_VL */
} RCC_TypeDef;

再找到结构体指针RCC:

#define RCC                 ((RCC_TypeDef *) RCC_BASE)

4.1.3,使能GPIOB,GPIOE时钟

接下来我们需要操作RCC_TypeDef结构体下APB2ENR寄存器的第3位(GPIOB)和第6位(GPIOE)使能

这里为了修改APB2ENR第3位和第6位而不影响其他位的值,我们采用”|”(或)运算(有一个是1结果就为1)

使能GPIOB和GPIOE我们需要将APB2ENR寄存器第3位和第6位赋值为1
使能GPIOB: RCC->APB2ENR|=1<<3;
使能GPIOE: RCC->APB2ENR|=1<<6;

4.2,配置IO口工作模式(以GPIOB.5为例)

4.2.1,GPIOx_CRL , GPIOx_CRH文档

  LED跑马灯-寄存器_第3张图片

  LED跑马灯-寄存器_第4张图片

  每组GPIO有16个IO口,GPIOx_CRL配置0-7位,GPIOx_CRH配置8-15位

  所以配置PB5和PE5需要操作GPIO_CRL寄存器

  这里写图片描述
  
  每个IO口由4个位控制,GPIOx_CRL的32个位控制8个IO口

4.2.2GPIOx_CRL配置

  LED跑马灯需要设置IO为推挽输出
  
  LED跑马灯-寄存器_第5张图片
  
  所以我们需要将GPIOx.5的CNF5设置为00,MODE5设置为11 , 0011的16进制值为3

    // 配置GPIOx.5配置为输出速度50MHz的推挽输出

    GPIOB->CRL&=0xFF0FFFFF;    // 一个F代表4位,我们将20-23位(GPIOx.5)清空为0
    GPIOB->CRL|=0x00300000;    // 不影响其他位,将20-24位值设置为0011(16进制为3)

4.3,控制IO口输出高低电平

  我们的LED为低电平点亮,高电平熄灭,所以初始化应设置为熄灭状态,设置IO口输入为高电平
需要操作ORD或BRR寄存器,我们以ODR寄存器为例:

  LED跑马灯-寄存器_第6张图片
  
  我们要将PB5或PE5的输出电平设置为1,需要设置第五位ODR5值为1:
  

    GPIOB->ODR|=1<<5; // 在不影响其他位的情况下,将ODR5赋值为1

五,完整代码:

新建LED头文件:HAERWARE->LED->led.h 定义LED初始化函数

#ifndef __LED_H
#define __LED_H

void LED_Init(void);

#endif

新建:HAERWARE->LED->led.c 实现LED初始化函数

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

void LED_Init(void){

    RCC->APB2ENR|=1<<3;
    RCC->APB2ENR|=1<<6;

    //GPIOB.5
    GPIOB->CRL&=0xFF0FFFFF;    // 一个F代表4位,我们将20-23位(GPIOx.5)清空为0
    GPIOB->CRL|=0x00300000; // 不影响其他位,将20-24位值设置为0011(16进制为3)
    GPIOB->ODR|=1<<5;        // 在不影响其他位的情况下,将ODR5赋值为1

    //GPIOE.5
    GPIOE->CRL&=0xFF0FFFFF;
    GPIOE->CRL|=0x00300000;
    GPIOE->ODR|=1<<5;

}

USER->main.c 主函数编写LED跑马灯代码


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

int main(void)
{

    delay_init();      // 初始化延时函数
    LED_Init();        // 初始化LED

    while(1){

        // LED熄灭
        GPIOB->ODR|=1<<5;     // PB5=1,小灯熄灭
        GPIOE->ODR|=1<<5;     // PE5=1,小灯熄灭
        delay_ms(500);        // 延时500ms

        // LED点亮
        GPIOB->ODR&=~(1<<5);  // ~(1<<5):除第五位都为1  和之前的取&  第5位置0小灯点亮
        GPIOE->ODR&=~(1<<5);  // 位5置0,小灯点亮
        delay_ms(500);        // 延时500ms
    }
}

以上代码实现了LED0,LED1每间隔500毫秒闪烁

你可能感兴趣的:(STM32,STM32学习笔记)