• 【STM32】GPIO控制LED(HAL库版)


    STM32最新固件库v3.5/Libraries/CMSIS/CM3/DeviceSupport/ST/STM32F10x/system_stm32f10x.c · 林何/STM32F103C8 - 码云 - 开源中国 (gitee.com)

    STM32最新固件库v3.5/Libraries/STM32F10x_StdPeriph_Driver/src/stm32f10x_gpio.c · 林何/STM32F103C8 - 码云 - 开源中国 (gitee.com)

    1.宏定义

    1. /* ------------ GPIO registers bit address in the alias region ----------------*/
    2. //AFIO:复用寄存器
    3. #define AFIO_OFFSET (AFIO_BASE - PERIPH_BASE)
    4. /* --- EVENTCR Register -----*/
    5. /* Alias word address of EVOE bit */
    6. #define EVCR_OFFSET (AFIO_OFFSET + 0x00)
    7. #define EVOE_BitNumber ((uint8_t)0x07)
    8. #define EVCR_EVOE_BB (PERIPH_BB_BASE + (EVCR_OFFSET * 32) + (EVOE_BitNumber * 4))
    9. /* --- MAPR Register ---*/
    10. /* Alias word address of MII_RMII_SEL bit */
    11. #define MAPR_OFFSET (AFIO_OFFSET + 0x04)
    12. #define MII_RMII_SEL_BitNumber ((u8)0x17)
    13. #define MAPR_MII_RMII_SEL_BB (PERIPH_BB_BASE + (MAPR_OFFSET * 32) + (MII_RMII_SEL_BitNumber * 4))
    14. //位掩码
    15. #define EVCR_PORTPINCONFIG_MASK ((uint16_t)0xFF80)
    16. #define LSB_MASK ((uint16_t)0xFFFF)
    17. #define DBGAFR_POSITION_MASK ((uint32_t)0x000F0000)
    18. #define DBGAFR_SWJCFG_MASK ((uint32_t)0xF0FFFFFF)
    19. #define DBGAFR_LOCATION_MASK ((uint32_t)0x00200000)
    20. #define DBGAFR_NUMBITS_MASK ((uint32_t)0x00100000)

    2..GPIO模块标准库

    1.GPIO_DeInit

    1. /**
    2. * @brief Deinitializes the GPIOx peripheral registers to their default reset values.
    3. * @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
    4. * @retval None
    5. */
    6. void GPIO_DeInit(GPIO_TypeDef* GPIOx)
    7. {
    8. /* Check the parameters */
    9. assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
    10. if (GPIOx == GPIOA)
    11. {
    12. RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, ENABLE);
    13. RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOA, DISABLE);
    14. }
    15. else if (GPIOx == GPIOB)
    16. {
    17. RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, ENABLE);
    18. RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOB, DISABLE);
    19. }
    20. else if (GPIOx == GPIOC)
    21. {
    22. RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC, ENABLE);
    23. RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOC, DISABLE);
    24. }
    25. else if (GPIOx == GPIOD)
    26. {
    27. RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOD, ENABLE);
    28. RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOD, DISABLE);
    29. }
    30. else if (GPIOx == GPIOE)
    31. {
    32. RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOE, ENABLE);
    33. RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOE, DISABLE);
    34. }
    35. else if (GPIOx == GPIOF)
    36. {
    37. RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOF, ENABLE);
    38. RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOF, DISABLE);
    39. }
    40. else
    41. {
    42. if (GPIOx == GPIOG)
    43. {
    44. RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOG, ENABLE);
    45. RCC_APB2PeriphResetCmd(RCC_APB2Periph_GPIOG, DISABLE);
    46. }
    47. }
    48. }

    2.GPIO_Init

    1.参数1:GPIO_TypeDef*

    表示哪一个端口是(CRL还是CRH还是IDR)

    记录的是寄存器地址

    定义在system.stm32f10x.h中【因为外部可能要使用到】

    2.参数2:GPIO_InitTypeDef*

    描述对GPIO的初始化(形容词)

    定义在gpio.h

    1. /**
    2. * @brief GPIO Init structure definition
    3. */
    4. typedef struct
    5. {
    6. uint16_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
    7. This parameter can be any value of @ref GPIO_pins_define */
    8. GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
    9. This parameter can be a value of @ref GPIOSpeed_TypeDef */
    10. GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.
    11. This parameter can be a value of @ref GPIOMode_TypeDef */
    12. }GPIO_InitTypeDef;

    3.步骤1:GPIO Mode Configuration

    输入模式全是0,输出模式全是1

    速度初始化

    1. /*---------------------------- GPIO Mode Configuration -----------------------*/
    2. //取出bit0-bit3
    3. currentmode = ((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x0F);
    4. if ((((uint32_t)GPIO_InitStruct->GPIO_Mode) & ((uint32_t)0x10)) != 0x00)
    5. //判断出等于1(输出模式)的进入
    6. {
    7. /* Check the parameters */
    8. assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));
    9. /* Output mode */
    10. currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;
    11. }

    4.步骤2:GPIO CRL Configuration

    1. /*---------------------------- GPIO CRL Configuration ------------------------*/
    2. /* Configure the eight low port pins */
    3. //判断此时的控制器在CRL(bit0-bit7)还是CRH(bit7-bit15)
    4. if (((uint32_t)GPIO_InitStruct->GPIO_Pin & ((uint32_t)0x00FF)) != 0x00)
    5. //如果进入表示bit0-bit7有为1的,则表示要使用CRL
    6. {
    7. tmpreg = GPIOx->CRL;
    8. //pinpos < 0x08:表示从bit0-bit7开始找
    9. for (pinpos = 0x00; pinpos < 0x08; pinpos++)
    10. {
    11. pos = ((uint32_t)0x01) << pinpos;
    12. /* Get the port pins position */
    13. //判断当前的Pin是哪一个
    14. currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;
    15. if (currentpin == pos)//表示这位Pin是1,找到了
    16. {
    17. pos = pinpos << 2;
    18. /* Clear the corresponding low control register bits */
    19. pinmask = ((uint32_t)0x0F) << pos;
    20. tmpreg &= ~pinmask;//清零
    21. /* Write the mode configuration in the corresponding bits */
    22. tmpreg |= (currentmode << pos);
    23. /* Reset the corresponding ODR bit */
    24. if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
    25. {
    26. GPIOx->BRR = (((uint32_t)0x01) << pinpos);
    27. }
    28. else
    29. {
    30. /* Set the corresponding ODR bit */
    31. if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
    32. {
    33. GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
    34. }
    35. }
    36. }
    37. }
    38. GPIOx->CRL = tmpreg;
    39. }

    5.步骤3:GPIO CRH Configuration

    1. /*---------------------------- GPIO CRH Configuration ------------------------*/
    2. /* Configure the eight high port pins */
    3. if (GPIO_InitStruct->GPIO_Pin > 0x00FF)
    4. {
    5. tmpreg = GPIOx->CRH;
    6. for (pinpos = 0x00; pinpos < 0x08; pinpos++)
    7. {
    8. pos = (((uint32_t)0x01) << (pinpos + 0x08));
    9. /* Get the port pins position */
    10. currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos);
    11. if (currentpin == pos)
    12. {
    13. pos = pinpos << 2;
    14. /* Clear the corresponding high control register bits */
    15. pinmask = ((uint32_t)0x0F) << pos;
    16. tmpreg &= ~pinmask;
    17. /* Write the mode configuration in the corresponding bits */
    18. tmpreg |= (currentmode << pos);
    19. /* Reset the corresponding ODR bit */
    20. if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD)
    21. {
    22. GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08));
    23. }
    24. /* Set the corresponding ODR bit */
    25. if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU)
    26. {
    27. GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08));
    28. }
    29. }
    30. }
    31. GPIOx->CRH = tmpreg;
    32. }

    3.GPIO_StructInit

    对GPIO初始化类型

    GPIO_Pin_All:是用于判断此时这个GPIO是否初始化

    1. /**
    2. * @brief Fills each GPIO_InitStruct member with its default value.
    3. * @param GPIO_InitStruct : pointer to a GPIO_InitTypeDef structure which will
    4. * be initialized.
    5. * @retval None
    6. */
    7. void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct)
    8. {
    9. /* Reset GPIO init structure parameters values */
    10. //GPIO_Pin_All:表示此时初始化到的这个pin是不存在的,表示此时还未指向
    11. GPIO_InitStruct->GPIO_Pin = GPIO_Pin_All;
    12. GPIO_InitStruct->GPIO_Speed = GPIO_Speed_2MHz;
    13. GPIO_InitStruct->GPIO_Mode = GPIO_Mode_IN_FLOATING;
    14. }

    4.GPIO_ReadInputDataBit

    读取哪一个引脚的值

    1. /**
    2. * @brief Reads the specified input port pin.
    3. * @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
    4. * @param GPIO_Pin: specifies the port bit to read.
    5. * This parameter can be GPIO_Pin_x where x can be (0..15).
    6. * @retval The input port pin value.
    7. */
    8. uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
    9. {
    10. uint8_t bitstatus = 0x00;
    11. /* Check the parameters */
    12. assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
    13. assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
    14. if ((GPIOx->IDR & GPIO_Pin) != (uint32_t)Bit_RESET)
    15. {
    16. bitstatus = (uint8_t)Bit_SET;
    17. }
    18. else
    19. {
    20. bitstatus = (uint8_t)Bit_RESET;
    21. }
    22. return bitstatus;
    23. }

    5.GPIO_ReadInputData

    读取整个端口

    1. /**
    2. * @brief Reads the specified GPIO input data port.
    3. * @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
    4. * @retval GPIO input data port value.
    5. */
    6. uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx)
    7. {
    8. /* Check the parameters */
    9. assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
    10. return ((uint16_t)GPIOx->IDR);
    11. }

    6.GPIO_ReadOutputDataBit/GPIO_ReadOutputData

    1. /**
    2. * @brief Reads the specified output data port bit.
    3. * @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
    4. * @param GPIO_Pin: specifies the port bit to read.
    5. * This parameter can be GPIO_Pin_x where x can be (0..15).
    6. * @retval The output port pin value.
    7. */
    8. uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
    9. {
    10. uint8_t bitstatus = 0x00;
    11. /* Check the parameters */
    12. assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
    13. assert_param(IS_GET_GPIO_PIN(GPIO_Pin));
    14. if ((GPIOx->ODR & GPIO_Pin) != (uint32_t)Bit_RESET)
    15. {
    16. bitstatus = (uint8_t)Bit_SET;
    17. }
    18. else
    19. {
    20. bitstatus = (uint8_t)Bit_RESET;
    21. }
    22. return bitstatus;
    23. }
    24. /**
    25. * @brief Reads the specified GPIO output data port.
    26. * @param GPIOx: where x can be (A..G) to select the GPIO peripheral.
    27. * @retval GPIO output data port value.
    28. */
    29. uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx)
    30. {
    31. /* Check the parameters */
    32. assert_param(IS_GPIO_ALL_PERIPH(GPIOx));
    33. return ((uint16_t)GPIOx->ODR);
    34. }

    7. GPIO_EventOutputConfig

    1. /**
    2. * @brief Selects the GPIO pin used as Event output.
    3. * @param GPIO_PortSource: selects the GPIO port to be used as source
    4. * for Event output.
    5. * This parameter can be GPIO_PortSourceGPIOx where x can be (A..E).
    6. * @param GPIO_PinSource: specifies the pin for the Event output.
    7. * This parameter can be GPIO_PinSourcex where x can be (0..15).
    8. * @retval None
    9. */
    10. void GPIO_EventOutputConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
    11. {
    12. uint32_t tmpreg = 0x00;
    13. /* Check the parameters */
    14. assert_param(IS_GPIO_EVENTOUT_PORT_SOURCE(GPIO_PortSource));
    15. assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
    16. tmpreg = AFIO->EVCR;
    17. /* Clear the PORT[6:4] and PIN[3:0] bits */
    18. tmpreg &= EVCR_PORTPINCONFIG_MASK;
    19. tmpreg |= (uint32_t)GPIO_PortSource << 0x04;
    20. tmpreg |= GPIO_PinSource;
    21. AFIO->EVCR = tmpreg;
    22. }

    8.GPIO_PinRemapConfig

    当我们要使用的引脚不够时,就要将其他不需要使用到的引脚进行复用

    1. void GPIO_PinRemapConfig(uint32_t GPIO_Remap, FunctionalState NewState)
    2. {
    3. uint32_t tmp = 0x00, tmp1 = 0x00, tmpreg = 0x00, tmpmask = 0x00;
    4. /* Check the parameters */
    5. assert_param(IS_GPIO_REMAP(GPIO_Remap));
    6. assert_param(IS_FUNCTIONAL_STATE(NewState));
    7. if((GPIO_Remap & 0x80000000) == 0x80000000)
    8. {
    9. tmpreg = AFIO->MAPR2;
    10. }
    11. else
    12. {
    13. tmpreg = AFIO->MAPR;
    14. }
    15. tmpmask = (GPIO_Remap & DBGAFR_POSITION_MASK) >> 0x10;
    16. tmp = GPIO_Remap & LSB_MASK;
    17. if ((GPIO_Remap & (DBGAFR_LOCATION_MASK | DBGAFR_NUMBITS_MASK)) == (DBGAFR_LOCATION_MASK | DBGAFR_NUMBITS_MASK))
    18. {
    19. tmpreg &= DBGAFR_SWJCFG_MASK;
    20. AFIO->MAPR &= DBGAFR_SWJCFG_MASK;
    21. }
    22. else if ((GPIO_Remap & DBGAFR_NUMBITS_MASK) == DBGAFR_NUMBITS_MASK)
    23. {
    24. tmp1 = ((uint32_t)0x03) << tmpmask;
    25. tmpreg &= ~tmp1;
    26. tmpreg |= ~DBGAFR_SWJCFG_MASK;
    27. }
    28. else
    29. {
    30. tmpreg &= ~(tmp << ((GPIO_Remap >> 0x15)*0x10));
    31. tmpreg |= ~DBGAFR_SWJCFG_MASK;
    32. }
    33. if (NewState != DISABLE)
    34. {
    35. tmpreg |= (tmp << ((GPIO_Remap >> 0x15)*0x10));
    36. }
    37. if((GPIO_Remap & 0x80000000) == 0x80000000)
    38. {
    39. AFIO->MAPR2 = tmpreg;
    40. }
    41. else
    42. {
    43. AFIO->MAPR = tmpreg;
    44. }
    45. }

    9.GPIO_EXTILineConfig

    与外部中断有关

    1. /**
    2. * @brief Selects the GPIO pin used as EXTI Line.
    3. * @param GPIO_PortSource: selects the GPIO port to be used as source for EXTI lines.
    4. * This parameter can be GPIO_PortSourceGPIOx where x can be (A..G).
    5. * @param GPIO_PinSource: specifies the EXTI line to be configured.
    6. * This parameter can be GPIO_PinSourcex where x can be (0..15).
    7. * @retval None
    8. */
    9. void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
    10. {
    11. uint32_t tmp = 0x00;
    12. /* Check the parameters */
    13. assert_param(IS_GPIO_EXTI_PORT_SOURCE(GPIO_PortSource));
    14. assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));
    15. tmp = ((uint32_t)0x0F) << (0x04 * (GPIO_PinSource & (uint8_t)0x03));
    16. AFIO->EXTICR[GPIO_PinSource >> 0x02] &= ~tmp;
    17. AFIO->EXTICR[GPIO_PinSource >> 0x02] |= (((uint32_t)GPIO_PortSource) << (0x04 * (GPIO_PinSource & (uint8_t)0x03)));
    18. }

    3.使用GPIO库函数点亮LED

    1.接线

    我们连接的是GPIOB8-GPIOB15

    注意点:我们这里是反着接的【要将引脚一一对应】

    2.代码实现

    1. #include "led.h"
    2. #include "stm32f10x.h" // Device header
    3. static void delay(){
    4. unsigned int i=0,j=0;
    5. for(i=0;i<1000;i++){
    6. for(j=0;j<2000;j++){
    7. }
    8. }
    9. }
    10. /*
    11. void led_init(){
    12. //因为RCC部分还没有定义结构体,所以还是按照原来的方式去操作
    13. RCC->APB2ENR = 0x00000008;
    14. GPIOB->CRH=0x33333333;
    15. GPIOB->ODR=0x00000000;
    16. }
    17. void delay(){
    18. unsigned int i=0,j=0;
    19. for(i=0;i<1000;i++){
    20. for(j=0;j<2000;j++){
    21. }
    22. }
    23. }
    24. void led_flash(void){
    25. unsigned int i=0;
    26. for(i=0;i<3;i++){
    27. GPIOB->ODR = 0x00000000;//全亮
    28. delay();
    29. GPIOB->ODR = 0x0000ff00;//全灭
    30. delay();
    31. }
    32. }
    33. */
    34. //硬件实际用到的是GPIOB8-GPIOB15
    35. //使用标准库中的GPIO进行封装API来进行GPIO设置,以点亮LED
    36. //定义一个结构体:描述GPIO的速度,频率等
    37. GPIO_InitTypeDef gpio_InitStructure;
    38. /**
    39. 注意点:如果我们没有去操纵某一个引脚的时候
    40. 默认上电后,灯全部亮
    41. */
    42. void led_init(){
    43. //一、通过GPIO初始化来实现
    44. //记得一定要加上时钟
    45. RCC->APB2ENR=0x00000008;
    46. //单独设置
    47. //实际操纵寄存器去将GPB8设置为推挽输出模式,并且速率50MHZ
    48. gpio_InitStructure.GPIO_Pin=GPIO_Pin_9;
    49. gpio_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;
    50. gpio_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    51. //void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
    52. GPIO_Init(GPIOB,&gpio_InitStructure);
    53. //二、设置LED亮,则需要输出模式
    54. //此时操纵一个引脚
    55. //操纵BSRR寄存器设置GPB8输出1,让LED点亮
    56. //void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
    57. GPIO_SetBits(GPIOB,GPIO_Pin_9);
    58. }
    59. void led_flash(){
    60. unsigned int i=0;
    61. for(i=0;i<3;i++){
    62. GPIO_SetBits(GPIOB,GPIO_Pin_9);//GPB9亮
    63. delay();
    64. GPIO_SetBits(GPIOB,GPIO_Pin_9);//GPB9灭
    65. delay();
    66. }
    67. }
  • 相关阅读:
    [自制操作系统] 第19回 实现用户进程(下)
    three.js/webgl实现室内模型行走
    Polygon zkEVM中的Merkle tree
    mysql UUID 作为主键的问题
    图文详解Linux基础经典教程(10)——阿里云安装开发工具
    面向开放词汇的目标检测ECCV2022
    想当测试Leader,这6项技能你会吗?
    网络编程套接字(3)——协议定制 | 序列化与反序列化
    潘多拉 IOT 开发板学习(HAL 库)—— 实验1 跑马灯(RGB)实验(学习笔记)
    Android Studio中的模拟器一直在加载(Connecting to the emulator···)
  • 原文地址:https://blog.csdn.net/m0_63077733/article/details/134017810