【笔记】STM32F4xx 通用 I/O (GPIO)

第三部分 通用 I/O (GPIO)

一、GPIO寄存器

0.问题的引入

LED灯原理:LED0给它一个低电平,灯就可以亮;LED0给它一个高电平,灯就会灭

这些引脚最终是接入到MCU的某个引脚(GPIO)上去,控制LED灯或其他,可以在MCU上面写程序去控制这些引脚。

四个灯如下:
在这里插入图片描述
找到对应CPU的引脚:D1-PF9,D2-PF10,D3-PE13,D4-PE14

在这里插入图片描述
在这里插入图片描述

2.GPIO简介

General Purpose Input/Output 通用功能的输入输出

GPIO 引脚(GPIO pin)从芯片内部引出一根功能复用的口线(电线),可以配置成不同的功能,如:输入功能,输出功能,其他复用功能等。

MCU控制"一切",通过它的引脚(Pins)来实现的。

在这里插入图片描述

STM32F4xx共用144个GPIO引脚,分为9组,记为GPIOA,GPIOB, GPIOC,GPIOD,GPIOE,GPIOF,GPIOG,GPIOH,GPIOI.每组管理16个引脚,编号从0~15,如:

GPIOF 这一组的16个引脚,分别记为:GPIOF0,GPIOF1,GPIOF2,…,GPIOF15(其他组类似)

简写方式:GPIOF9 -> PF9 GPIOE10 -> PE10

这些GPIO都是功能复用的,有不同的寄存器组来配置它们。

每组GPIO地址分配如下:(0x3FF~1024KB)

边界地址外设
0x4002 0000 - 0x4002 03FFGPIOA
0x4002 0400 - 0x4002 07FFGPIOB
0x4002 0800 - 0x4002 0BFFGPIOC
0x4002 0C00 - 0x4002 0FFFGPIOD
0x4002 1000 - 0x4002 13FFGPIOE
0x4002 1400 - 0x4002 17FFGPIOF
0x4002 1800 - 0x4002 1BFFGPIOG
0x4002 1C00 - 0x4002 1FFFGPIOH
0x4002 2000 - 0x4002 23FFGPIOI

2. STM32F4xx GPIO内部结构原理

每个GPIO引脚在芯片内部都可以配置成如下功能:

  • 输入功能 Input
    在这里插入图片描述

    CPU可以获取该GPIO引脚的外部输入的一个电平状态。输入功能也有几种模式:

    1. 模拟输入 Input Analog(GPIO_MODE_AIN)

      接收外部模拟信号(如变化的电压值),然后交给片上外设模块(如ADC)模数转换。

    2. 悬空输入 Input Floating(GPIO_MODE_IN_FLOATING)

      内部不接上拉/下拉电阻,输入引脚状态完全由外部电路所决定的。CPU能够通过读取GPIO的状态知道I/O的电平状态。

    3. 下拉输入 Input Pull-Down(GPIO_MODE_IPD)

      内部接一个下拉电阻。

      作用:引脚在悬空的状态或外部电路没有输出电平时,CPU读取到的为低电平。

    4. 上拉输入 Input Pull-Up(GPIO_MODE_IPU)

      内部接一个上拉电阻。

      作用:引脚在悬空的状态或外部电路没有输出电平时,CPU读取到的为高电平。

  • 输出功能 Output
    在这里插入图片描述

    CPU往GPIO引脚输出一个电平状态。输出功能也有几种模式:

    1. 输出开漏 Open-Drain (GPIO_MODE_Out_OD)

      不输出电压。输出寄存器中的“0”可激活 N-MOS,而输出寄存器中的“1”会使端 口保持高组态 (Hi-Z)(P-MOS 始终不激活)

      CPU write 0,接地引脚,输出就是低电平

      CPU write 1,输出电平受上拉下拉电阻决定(悬空的状态)

    2. 输出推挽 Push-Pull (GPIO_MODE_Out_PP)

      输出寄存器中的“0”可激活 N-MOS,而输出寄存器中的“1”可激活 P-MOS

      作用:增强驱动力可以输出一个高、低电平,其原理见图

      CPU write 0 -> 引脚输出低电平

      CPU write 1 -> 引脚输出高电平

  • 复用功能 Alternate Function GPIO_MODE_AF

    复用功能是指GPIO引脚用作其它的功能使用,如: I2C,UART,SPI,CAN等。

    每个GPIO口都可以配置成多达16种复用功能,记为AF0,AF1,AF2,…,AF15。

    具体哪个GPIO可以配置成哪种复用功能,需要看原理图和datasheet.

3.STM32F4xx GPIO寄存器说明

每个通用 I/O 端口包括 4 个 32 位配置寄存器

(GPIOx_MODER、GPIOx_OTYPER、GPIOx_OSPEEDR 和 GPIOx_PUPDR)

2 个 32 位数据寄存器(GPIOx_IDR 和 GPIOx_ODR)

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

1 个 32 位锁定寄存器 (GPIOx_LCKR)

2 个 32 位复用功能选择寄存器(GPIOx_AFRH 和 GPIOx_AFRL)

  • 端口模式寄存器 GPIOx_MODER

    偏移地址:0x00

    复位值:

    • 0xA800 0000(端口 A)
    • 0x0000 0280(端口 B)
    • 0x0000 0000(其它端口)

    例:GPIOA_MODER = 0x40020000 + 0x00 GPIOF_MODER = 0x40021400 + 0x00

    该寄存器用来控制x(x=A,B,C,…I)组GPIO的16个引脚的模式,每个pin都有4种模式,每个pin需要2bits来配置。编号为y(y=0,1,2,…,15)的GPIO引脚在该寄存器的bit位置为:GPIOx_MODER[2y+1:2y]

    在这里插入图片描述

    具体配置如下:

    • 00 通用输入模式 input
    • 01 通用输出模式 output
    • 10 复用功能模式 Alternate Function
    • 11 模拟输入模式 input analog
  • 端口输出类型寄存器 GPIOx_OTYPER

    偏移地址:0x04

    复位值:0x0000 0000

    该寄存器用来控制x(x=A,B,C,…I)组的16个GPIO口的输出类型(PP/OD),每个GPIO引脚,占1bit,编号为y(y=0,1,2,…,15)的引脚在该寄存器的bit位置为:GPIOx_OTYPER[y]

    在这里插入图片描述

    具体配置如下:

    • 0 输出推挽(PP) PP: 1 -> 输出高电平 0 -> 输出低电平
    • 1 输出开漏(OD) OD: 0 -> 引脚内部接地 1 ->输出电平受上拉下拉电阻决定
  • 端口输出速度寄存器 GPIOx_OSPEEDR

    偏移地址:0x08

    复位值:

    • 0x0000 00C0(端口 B)
    • 0x0000 0000(其它端口)

    该寄存器用来控制x(x=A,B,C,…,I)组的16个GPIO的输出速率,每个GPIO口占2bits。编号为y(y=0,1,2,…,15)的GPIO口在该寄存器的bit位为:GPIOx_OSPEEDR[2y+1:2y]

    在这里插入图片描述

    具体输出速率为:

    • 00 2 MHz(低速)
    • 01 25 MHz(中速)
    • 10 50 MHz(快速)
    • 11 30 pF 时为 100 MHz(高速)(15 pF 时为 80 MHz 输出(最大速度))
  • 端口上拉/下拉寄存器 GPIOx_PUPDR

    偏移地址:0x0C

    复位值:

    • 0x6400 0000(端口 A)
    • 0x0000 0100(端口 B)
    • 0x0000 0000(其它端口)

    该寄存器用来控制x(x=A,B,C,…,I)组的16个GPIO引脚的上下拉电阻选择。每个GPIO引脚占2bits.编号为y(y=0,1,2,…,15)的GPIO口在该寄存器的bit位为:GPIOx_PUPDR[2y+1:2y]

    在这里插入图片描述

    具体上下拉情况为:

    • 00 无上拉,无下拉
    • 01 上拉
    • 10 下拉
    • 11 无上拉,无下拉保留
  • 端口输入数据寄存器 GPIOx_IDR

    偏移地址:0x10

    复位值:0x0000 XXXX(其中 X 表示未定义)

    当GPIO引脚配置成输入模式时,CPU可以读取这个寄存器的值(来自外部电路的值)

    该寄存器用来表示x(x=A,B,C,…,I)组的16个GPIO口的输入值,其中位31:16保留。位IDR[15:0]表示相应的GPIO引脚的输入状态,只读。

    在这里插入图片描述

    0 低电平 1 高电平

  • 端口输出数据寄存器 GPIOx_ODR

    偏移地址:0x14

    复位值:0x0000 0000

    当GPIO引脚配置成输出模式时,CPU可以往该寄存器写0引脚输出低电平。写1在推挽方式下是引脚输出是高电平,开漏状态下外部电路决定。

    该寄存器用来表示x(x=A,B,C,…,I)组的16个GPIO口的输出值,其中位31:16保留。位ODR[15:0]表示相应的GPIO引脚的输出状态,只写。

    在这里插入图片描述

    0 低电平

    1 PP :高电平

    ​ OD : 悬空(外部电路决定)

  • 端口置位/复位寄存器 GPIOx_BSRR

    偏移地址:0x18

    复位值:0x0000 0000
    在这里插入图片描述

    BSRR[31:16] 端口复位寄存器 对BSRR[31:16]写1,相应的GPIO引脚输出0

    BSRR[15:0] 端口置位寄存器 对BSRR[15:0]写1,相应的GPIO引脚输出1

    这个寄存器只写1,写0无效

二、流水灯(直接写寄存器)

1. start.s

stack_size  EQU 0x200       ;宏指令,定义了两个宏
vector_size EQU 0x400
;define stack            ;名字为mystack,数据,可读可写
AREA mystack,DATA,READWRITE
stack_S              ;顶格
   SPACE stack_size       ;设置空间大小
stack_end         ;stack top--SP

;define vector table        ;定义向量表,只读
   AREA RESET,DATA,READONLY
vector_s
   DCD stack_end      ;the first must be stack top 
   DCD code_start      ;this must be start code
   SPACE vector_size
vector_end 
      IMPORT main
;define code
   AREA mycode,CODE,READONLY,ALIGN=3
   PRESERVE8         ;8字节对齐
code_start PROC
     BL main
   B .  ;while(1)
ENDP
   END

2. led_reg.h

#ifndef __LED_H__       //avoid duplicate head
#define __LED_H__
//include
//define
#define rRCCAHB1CLKEN           *((volatile unsigned long *)0x40023830)

#define GPIOE_BASE_ADDR         0X40021000      //引脚GPIOE的地址
#define GPIOF_BASE_ADDR         0x40021400      //引脚GPIOF的的地址

#define MODER_OFFSET_ADDR       0x00            //对应寄存器的偏移地址
#define OTYPER_OFFSET_ADDR      0x04
#define OSPEEDR_OFFSET_ADDR     0x08
#define PUPDR_OFFSET_ADDR       0x0c
#define BSRR_OFFSET_ADDR        0x18

//各寄存器的地址 = 引脚地址+偏移地址
//volatile:(每次存取都往该的实地址存取最新数据)
#define rGPIOF_MODER            (*(volatile unsigned long*)(GPIOF_BASE_ADDR+MODER_OFFSET_ADDR))
#define rGPIOF_OTYPER           (*(volatile unsigned long*)(GPIOF_BASE_ADDR+OTYPER_OFFSET_ADDR))
#define rGPIOF_OSPEEDR          (*(volatile unsigned long*)(GPIOF_BASE_ADDR+OSPEEDR_OFFSET_ADDR))
#define rGPIOF_PUPDR            (*(volatile unsigned long*)(GPIOF_BASE_ADDR+PUPDR_OFFSET_ADDR))
#define rGPIOF_BSRR             (*(volatile unsigned long*)(GPIOF_BASE_ADDR+BSRR_OFFSET_ADDR))
    

#define rGPIOE_MODER            (*(volatile unsigned long*)(GPIOE_BASE_ADDR+MODER_OFFSET_ADDR))
#define rGPIOE_OTYPER           (*(volatile unsigned long*)(GPIOE_BASE_ADDR+OTYPER_OFFSET_ADDR))
#define rGPIOE_OSPEEDR          (*(volatile unsigned long*)(GPIOE_BASE_ADDR+OSPEEDR_OFFSET_ADDR))
#define rGPIOE_PUPDR            (*(volatile unsigned long*)(GPIOE_BASE_ADDR+PUPDR_OFFSET_ADDR))
#define rGPIOE_BSRR             (*(volatile unsigned long*)(GPIOE_BASE_ADDR+BSRR_OFFSET_ADDR))

enum LED_NUM{LED1,LED2,LED3,LED4};
//func
void led_init(void);            //初始化函数申明
void led_ctrl( int led_num);    //流水灯控制函数申明
void delay(int num);            //延迟时间函数申明

#endif

3. led_reg.c

#include "led_reg.h"
void led_init(void)
{
    unsigned long r_value;
//GPIOE GPIOF
//rRCCAHB1CLKEN[4]--GPIOE rRCCAHB1CLKEN[5]--GPIOF
    rRCCAHB1CLKEN   |= (1<<4)|(1<<5);   //时钟
    
//PF9,PF10-->out    设置为输出模式
//[21:18] 0101
    r_value=rGPIOF_MODER;
    r_value &=~(0xf<<18);
    r_value |=(1<<18)|(1<<20);  
    rGPIOF_MODER=r_value;

//PE13,PE14-->out   
//[29:26] 0101
    r_value=rGPIOE_MODER;
    r_value &=~(0xf<<26);
    r_value |=(1<<26)|(1<<28);
    rGPIOE_MODER=r_value;
    
//PF9,PF10-->pp 0   设置为输出类型为推挽
//[10:9] 00
    r_value=rGPIOF_OTYPER;
    r_value &=~((1<<9)|(1<<10));
    rGPIOF_OTYPER=r_value;
    
//PE13,PE14-->pp 0
    //[14:13] 00
    r_value=rGPIOE_OTYPER;
    r_value &=~((1<<13)|(1<<14));
    rGPIOE_OTYPER=r_value;
    
//PF9,PF10-->50MHZ 10   设置输出速度为50MHZ
//[21:18] 1010
    r_value=rGPIOF_OSPEEDR;
    r_value &=~(0xf<<18);//****0000******
    r_value |=(1<<19)|(1<<21);
    rGPIOF_OSPEEDR=r_value;

//PE13,PE14-->50MHZ 10
//[29:26] 1010
    r_value=rGPIOE_OSPEEDR;
    r_value &=~(0xf<<26);
    r_value |=(1<<29)|(1<<27);
    rGPIOE_OSPEEDR=r_value;
    
//PF9,PF10-->no 00  设置无上拉、无下拉
//[21:18] 0000
    r_value=rGPIOF_PUPDR;
    r_value &=~(0xf<<18);
    rGPIOF_PUPDR=r_value;
    
//PE13,PE14-->no 00
//[29:26] 0000
    r_value=rGPIOE_PUPDR;
    r_value &=~(0xf<<26);
    rGPIOE_PUPDR=r_value;
    
//LED1 LED2-->PF9,PF10-->BSRR(1)    //设置灯初始状态全灭
//[10:9] 11
    r_value=rGPIOF_BSRR;
    r_value |=(1<<9)|(1<<10);
    rGPIOF_BSRR=r_value;
    
//LED3 LED4-->PE13,PE14-->BSRR(1)
//[14:13] 11
    r_value=rGPIOE_BSRR;
    r_value |=(1<<13)|(1<<14);
    rGPIOE_BSRR=r_value;    
}

void led_ctrl( int led_num)     //设置对应灯亮
{
    unsigned long r_value;
    switch(led_num)
    {
        case LED1:      
        {
            r_value=rGPIOF_BSRR;
            //PF9--0,PF10--1
            r_value |=(1<<25)|(1<<10);
            rGPIOF_BSRR=r_value;
            
            r_value=rGPIOE_BSRR;
            //PE13--1,PE14--1
            r_value |=(1<<13)|(1<<14);
            rGPIOE_BSRR=r_value;    
            break;
        }
        
        case LED2:
        {
            r_value=rGPIOF_BSRR;
            //PF9--1,PF10--0
            r_value |=(1<<9)|(1<<26);
            rGPIOF_BSRR=r_value;
            
            r_value=rGPIOE_BSRR;
            //PE13--1,PE14--1
            r_value |=(1<<13)|(1<<14);
            rGPIOE_BSRR=r_value;    
            break;
        }
        
        case LED3:
        {
            r_value=rGPIOF_BSRR;
            //PF9--1,PF10--1
            r_value |=(1<<9)|(1<<10);           
            rGPIOF_BSRR=r_value;
            
            r_value=rGPIOE_BSRR;
            //PE13--0,PE14--1
            r_value |=(1<<29)|(1<<14);
            rGPIOE_BSRR=r_value;    
            break;
        }
        
        case LED4:
        {
            r_value=rGPIOF_BSRR;
            //PF9--1,PF10--1
            r_value |=(1<<9)|(1<<10);           
            rGPIOF_BSRR=r_value;
            
            r_value=rGPIOE_BSRR;
            //PE13--1,PE14--0
            r_value |=(1<<13)|(1<<30);
            rGPIOE_BSRR=r_value;    
            break;
        }
        
        default:
            break;              
    }
}

void delay(int num)
{
        while(num--);
}

int main()
{
    
    led_init(); 
    while(1)
    {
        for(int led_n=LED1;led_n<=LED4;led_n++)     //循环点亮各个灯
        {
                led_ctrl(led_n);
                delay(0x100000);
        }
    }
}

三、STM32官方固件库

总线APB/AHB 不同外设连接不同总线(AHB1,AHB2,AHB3,APB1,APB2),GPIO—>AHB1

1. 使能GPIO分组的时钟

RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState)

  • uint32_t RCC_AHB1Periph: 连接到AHB1上的外设编号

  • FunctionalState NewState: ENABLE or DISABLE

    例:RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF|RCC_AHB1Periph_GPIOE,ENABLE);

注意:RCC_总线名一定要和外设编号要对应

2. GPIO初始化

GPIO_Init(GPIO_TypeDef * GPIOx, GPIO_InitTypeDef * GPIO_InitStruct)

  • GPIO_TypeDef * GPIOx: 分组的寄存器地址 如:GPIOF

  • GPIO_InitTypeDef * GPIO_InitStruct: 结构体指针

    /** 
      * @brief   GPIO Init structure definition  
      */ 
    typedef struct
    {
      uint32_t GPIO_Pin;              /*!< Specifies the GPIO pins to be configured.
                                           This parameter can be any value of @ref GPIO_pins_define */
    
      GPIOMode_TypeDef GPIO_Mode;     /*!< Specifies the operating mode for the selected pins.
                                           This parameter can be a value of @ref GPIOMode_TypeDef */
    
      GPIOSpeed_TypeDef GPIO_Speed;   /*!< Specifies the speed for the selected pins.
                                           This parameter can be a value of @ref GPIOSpeed_TypeDef */
    
      GPIOOType_TypeDef GPIO_OType;   /*!< Specifies the operating output type for the selected pins.
                                           This parameter can be a value of @ref GPIOOType_TypeDef */
    
      GPIOPuPd_TypeDef GPIO_PuPd;     /*!< Specifies the operating Pull-up/Pull down for the selected pins.
                                           This parameter can be a value of @ref GPIOPuPd_TypeDef */
    }GPIO_InitTypeDef;
    
    /** 
      * @brief  GPIO Configuration Mode enumeration 
      */   
    typedef enum
    { 
      GPIO_Mode_IN   = 0x00, /*!< GPIO Input Mode */
      GPIO_Mode_OUT  = 0x01, /*!< GPIO Output Mode */
      GPIO_Mode_AF   = 0x02, /*!< GPIO Alternate function Mode */
      GPIO_Mode_AN   = 0x03  /*!< GPIO Analog Mode */
    }GPIOMode_TypeDef;
    
    /** 
      * @brief  GPIO Output type enumeration 
      */  
    typedef enum
    { 
      GPIO_OType_PP = 0x00,
      GPIO_OType_OD = 0x01
    }GPIOOType_TypeDef;
    
    /** 
      * @brief  GPIO Output Maximum frequency enumeration 
      */  
    typedef enum
    { 
      GPIO_Low_Speed     = 0x00, /*!< Low speed    */
      GPIO_Medium_Speed  = 0x01, /*!< Medium speed */
      GPIO_Fast_Speed    = 0x02, /*!< Fast speed   */
      GPIO_High_Speed    = 0x03  /*!< High speed   */
    }GPIOSpeed_TypeDef;
    /* Add legacy definition */
    #define  GPIO_Speed_2MHz    GPIO_Low_Speed    
    #define  GPIO_Speed_25MHz   GPIO_Medium_Speed 
    #define  GPIO_Speed_50MHz   GPIO_Fast_Speed 
    #define  GPIO_Speed_100MHz  GPIO_High_Speed  
    
    /** 
      * @brief  GPIO Configuration PullUp PullDown enumeration 
      */ 
    typedef enum
    { 
      GPIO_PuPd_NOPULL = 0x00,
      GPIO_PuPd_UP     = 0x01,
      GPIO_PuPd_DOWN   = 0x02
    }GPIOPuPd_TypeDef;
    

3. 置位/复位/取反函数

置位:

void GPIO_SetBits(GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin)

  • GPIO_TypeDef * GPIOx: 指定GPIO分组 如:GPIOF

  • uint16_t GPIO_Pin: 引脚号

    例:GPIO_SetBits(GPIOF, GPIO_Pin_9|GPIO_Pin_10)

函数内部执行:GPIOx->BSRRL = GPIO_Pin;

复位:

void GPIO_ResetBits(GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin)

取反:

void GPIO_ToggleBits(GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin)

函数内部执行:GPIOx->ODR ^= GPIO_Pin;

例:GPIO_ToggleBits(GPIOF, GPIO_Pin_9)

4. GPIO引脚的读写

READ:

  • 读一个分组的所有引脚的电平状态:

    uint16_t GPIO_ReadInputData(GPIO_TypeDef * GPIOx)

​ 返回值:所有引脚的电平状态

  • 读一个分组的指定引脚的电平状态:

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin)

WRITE:

  • MCU给指定GPIO分组(GPIOx)的所有引脚(16个)输出一个电平状态

    void GPIO_Write(GPIO_TypeDef * GPIOx, uint16_t PortVal)

    例子:led0点灯 PF9

    uint16_t value=GPIO_ReadInputData(GPIOF);
    value &= ~(1<<9);
    GPIO_Write(GPIOF,value);
    
  • MCU给指定GPIO分组(GPIOx)的指定引脚(16个)输出一个电平状态

    void GPIO_WriteBit(GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin, BitAction BitVal)

    BitAction BitVal: Bit_Reset 0 Bit_Set 1

    例子:

    case 1GPIO_ResetBits(GPIOF, GPIO_Pin_9);
        GPIO_SetBits(GPIOF, GPIO_Pin_10);
        GPIO_SetBits(GPIOE, GPIO_Pin_13|GPIO_Pin_14);
    

四、流水灯(基于固件库)

1. rj_reg.h

#ifndef _LED_H_
#define _LED_H_

#include "stm32f4xx.h"

enum LED_NUM{LED1,LED2,LED3,LED4};
//函数申明
void led_init(void);
void led_ctrl(int led_n);
void delay(int cnt);
void led_loop(void);
#endif

2.rj_reg.c

#include "rj_led.h"
void led_init()
{
    //clk enable GPIOE GPIOF    --AHB1 
    //设置连接到AHB1上GPIOE和GPIOF的外设可用
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE|RCC_AHB1Periph_GPIOF, ENABLE);

    //MODE-OUT,OTYPE-PP,OSPEED-50M,NO UPDN
    GPIO_InitTypeDef P;
    P.GPIO_Mode     =GPIO_Mode_OUT;             //设置为输出模式
    P.GPIO_OType    =GPIO_OType_PP;             //设置输出类型为推挽
    P.GPIO_Pin      =GPIO_Pin_9|GPIO_Pin_10;    //设置引脚为9和10
    P.GPIO_PuPd     =GPIO_PuPd_NOPULL;          //设置无上拉、无下拉
    P.GPIO_Speed    =GPIO_Speed_50MHz;          //设置输出速率为50MHz
    GPIO_Init(GPIOF, &P);                       //调用初始化函数
    P.GPIO_Pin      =GPIO_Pin_13|GPIO_Pin_14;
    GPIO_Init(GPIOE, &P);

}
void led_loop()                                //流水灯循环实现
{
    for(int led_n=LED1;led_n<=LED4;led_n++)
    {
            led_ctrl(led_n);
            delay(0x100000);
    }
}

void led_ctrl( int led_num)     //利用置位和复位设置对应的灯的明灭
{
    unsigned long r_value;
    
    switch(led_num)
    {
        case LED1:
        {
            GPIO_ResetBits(GPIOF, GPIO_Pin_9);
            GPIO_SetBits(GPIOF, GPIO_Pin_10);
            GPIO_SetBits(GPIOE, GPIO_Pin_13);
            GPIO_SetBits(GPIOE, GPIO_Pin_14);
            break;
        }
        
        case LED2:
        {
            GPIO_ResetBits(GPIOF, GPIO_Pin_10);
            GPIO_SetBits(GPIOF, GPIO_Pin_9);
            GPIO_SetBits(GPIOE, GPIO_Pin_13);
            GPIO_SetBits(GPIOE, GPIO_Pin_14);
            break;
        }
        
        case LED3:
        {
            GPIO_ResetBits(GPIOE, GPIO_Pin_13);
            GPIO_SetBits(GPIOE, GPIO_Pin_14);
            GPIO_SetBits(GPIOF, GPIO_Pin_9);
            GPIO_SetBits(GPIOF, GPIO_Pin_10);
            break;
        }
        
        case LED4:
        {
            GPIO_ResetBits(GPIOE, GPIO_Pin_14);
            GPIO_SetBits(GPIOE, GPIO_Pin_13);
            GPIO_SetBits(GPIOF, GPIO_Pin_9);
            GPIO_SetBits(GPIOF, GPIO_Pin_10);
            break;
        }
        
        default:
            break;              
    }
}

void delay(int num)
{
        while(num--);
}

第一部分 嵌入式系统概述
第二部分 ARM指令系统
第三部分 通用 I/O (GPIO)
第四部分 中断机制
第五部分 时钟定时器

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F4XX中文参考手册 嵌入式 Flash 接口 3.1 前言 Flash 接口可管理 CPU 通过 AHB I-Code 和 D-Code 对 Flash 进行的访问。该接口可针对 Flash 执行擦除和编程操作,并实施读写保护机制。 Flash 接口通过指令预取和缓存机制加速代码执行。 3.2 主要特性 ● Flash 读操作 ● Flash 编程/擦除操作 ● 读/写保护 ● I-Code 上的预取操作 ● I-Code 上的 64 个缓存(128 位宽) ● D-Code 上的 8 个缓存(128 位宽) 通用 I/O (GPIO) 除非特别说明,否则本部分适用于整个 STM32F4xx 系列。 7.1 GPIO 简介 每个通用 I/O 端口包括 4 个 32 位配置寄存器(GPIOx_MODER、GPIOx_OTYPER、 GPIOx_OSPEEDR 和 GPIOx_PUPDR)、2 个 32 位数据寄存器(GPIOx_IDR 和 GPIOx_ODR)、1 个 32 位置位/复位寄存器 (GPIOx_BSRR)、1 个 32 位锁定寄存器 (GPIOx_LCKR) 和 2 个 32 位复用功能选择寄存器(GPIOx_AFRH 和 GPIOx_AFRL)。 7.2 GPIO 主要特性 ● 受控 I/O 多达 16 个 ● 输出状态:推挽或开漏 + 上拉/下拉 ● 从输出数据寄存器 (GPIOx_ODR) 或外设(复用功能输出)输出数据 ● 可为每个 I/O 选择不同的速度 ● 输入状态:浮空、上拉/下拉、模拟 ● 将数据输入到输入数据寄存器 (GPIOx_IDR) 或外设(复用功能输入) ● 置位和复位寄存器 (GPIOx_BSRR),对 GPIOx_ODR 具有按位写权限 ● 锁定机制 (GPIOx_LCKR),可冻结 I/O 配置 ● 模拟功能 ● 复用功能输入/输出选择寄存器(一个 I/O 最多可具有 16 个复用功能) ● 快速翻转,每次翻转最快只需要两个时钟周期 ● 引脚复用非常灵活,允许将 I/O 引脚用作 GPIO 或多种外设功能中的一种 7.3 GPIO 功能描述 根据数据手册中列出的每个 I/O 端口的特性,可通过软件将通用 I/O (GPIO) 端口的各个端口 位分别配置为多种模式: ● 输入浮空 ● 输入上拉 ● 输入下拉 ● 模拟功能 ● 具有上拉或下拉功能的开漏输出 ● 具有上拉或下拉功能的推挽输出 ● 具有上拉或下拉功能的复用功能推挽 ● 具有上拉或下拉功能的复用功能开漏 每个 I/O 端口位均可自由编程,但 I/O 端口寄存器必须按 32 位字、半字或字节进行访问。 GPIOx_BSRR 寄存器旨在实现对 GPIO ODR 寄存器进行原子读取/修改访问。这样便可确保 在读取和修改访问之间发生中断请求也不会有问题
针对于stm32f4xx芯片开发使用的hal版本库 /** ****************************************************************************** * @file stm32f4xx_hal.h * @author MCD Application Team * @version V1.4.2 * @date 10-November-2015 * @brief This file contains all the functions prototypes for the HAL * module driver. ****************************************************************************** * @attention * * © COPYRIGHT(c) 2015 STMicroelectronics * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */
stm32f4xx中文参考手册.zip是一份关于STM32F4系列微控制器的中文参考手册的压缩文件。在该手册中,包含了丰富的内容,方便用户了解和使用STM32F4系列微控制器。 首先,手册提供了STM32F4系列微控制器的概述和基本信息,包括芯片架构、特性和主要功能等。这些信息有助于用户对该系列微控制器的整体了解,为项目的开发和设计提供参考。 其次,手册详细介绍了STM32F4系列微控制器的各个外设模块,如GPIO、UART、SPI、I2C、ADC、定时器等。对于每个外设模块,手册提供了对应的功能描述、寄存器配置和使用方法,用户可以根据实际需求选择合适的外设进行配置和使用。 此外,手册还包含了丰富的示例代码和应用案例,帮助用户快速上手和理解STM32F4系列微控制器的编程和应用。这些示例代码包括了常见的功能实现,如定时器中断、串口通信、ADC采集等,非常有助于用户了解和掌握STM32F4系列微控制器的编程方法和技巧。 最后,手册还提供了STM32F4系列微控制器相关的参考资料和文档,如芯片数据手册、参考设计、应用笔记等。这些参考资料可以帮助用户深入了解和应用STM32F4系列微控制器,解决实际问题和提升项目开发的效率。 总之,stm32f4xx中文参考手册.zip对于学习和使用STM32F4系列微控制器的用户来说是一份非常有价值的文档,可以提供系统的指导和帮助,使用户能够充分发挥STM32F4系列微控制器的优势,从而更好地完成项目开发和设计。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值