GD32实战3__点亮LED灯

知识点

1. GPIO控制

2. LED灯驱动原理

3. 按键检查原理

硬件部分

在这里插入图片描述

如上图,LED灯负极接地,正极通过470欧电阻后,接到了MCU的引脚上。可以看出,当MCU的GPIO口输出

高电平时LED亮,

低电平时LED灭。

在这里插入图片描述

如上图,

​ 当按键弹起时,GPIO接在3.3V上,为高电平

​ 当按键按下时,GPIO接到地上,为低电平

在这里插入图片描述

注意:

  1. 原理图中的K1,K2,K3分别对应板子上的K2,K3,K4,本文都是按原理图描述
  2. 0.1uF电容作用去抖动

功能设计

​ 设计一个小功能,KEY3按下 4个LED灯亮,弹起时4个LED灭。子功能设计包括,

1. 功能状态设计

在这里插入图片描述

​ 如上图,该功能一共要经历上面几个状态,从而也就明白我们需要提供哪些功能函数,细节读下面的代码。

static VOID LED_Init(VOID)
{
    DRV_LED_Init();
    DRV_KEY_Init();
}

static VOID LED_SetLedStatus(IN U8 status)
{
    if (DRV_KEY_DOWN == status)
    {
        DRV_LED_On(DRV_LED1);
        DRV_LED_On(DRV_LED2);
        DRV_LED_On(DRV_LED3);
        DRV_LED_On(DRV_LED4);
    }
    else if (DRV_KEY_UP == status)
    {
        DRV_LED_Off(DRV_LED1);
        DRV_LED_Off(DRV_LED2);
        DRV_LED_Off(DRV_LED3);
        DRV_LED_Off(DRV_LED4);
    }
    else
    {
        ;
    }
}

static VOID LED_CheckKeyStatus(VOID)
{
    U8 keyStatus = 0;
    
    keyStatus = DRV_KEY_GetStatus(DRV_KEY3);
    if (DRV_KEY_DOWN == keyStatus)
    {
        APP_Delay(50); /* 50ms去抖动 */
        keyStatus = DRV_KEY_GetStatus(DRV_KEY3);
        if (DRV_KEY_DOWN == keyStatus)
        {
            LED_SetLedStatus(DRV_KEY_DOWN);
        }
    }
    else
    {
        LED_SetLedStatus(DRV_KEY_UP);
    }
}

VOID APP_LED_Test(VOID)
{
    LED_Init();
    LED_SetLedStatus(DRV_KEY_UP);
    
    while (1)
    {
        LED_CheckKeyStatus();
    }
}

2. 定时器设计

1. 采用systick作为功能定时器,初始配置成1ms一次中断
2. 提供delay延时函数
static U32 gDrvSystickDelayCount = 0;

S32 DRV_SYSTICK_Init(VOID)
{
    /* 1000Hz,1ms中断一次 */
    if (SysTick_Config(SystemCoreClock / 1000))
    {
        return OS_ERROR;
    }
    
    NVIC_SetPriority(SysTick_IRQn, 0x00);

    return OS_OK;
}

/* 1ms中断一次 */
VOID SysTick_Handler(VOID)
{
    if (gDrvSystickDelayCount > 0)
    {
        gDrvSystickDelayCount--;
    }
}

VOID DRV_SYSTICK_Delay(IN U32 ms)
{
    gDrvSystickDelayCount = ms;
    while (1)
    {
        if (gDrvSystickDelayCount <= 0)
        {
            break;
        }
    }

    return;
}

3. LED驱动

  1. 提供初始化函数接口
  2. 提供LED on/off接口
#define DRV_LED1 GPIOC,GPIO_PIN_0
#define DRV_LED2 GPIOC,GPIO_PIN_2
#define DRV_LED3 GPIOE,GPIO_PIN_0
#define DRV_LED4 GPIOE,GPIO_PIN_1
#define DRV_LED_On(led) GPIO_SetBits(led);
#define DRV_LED_Off(led) GPIO_ResetBits(led);

extern void DRV_LED_Init(void);

4. 按键驱动

  1. 提供初始化接口
  2. 提供获取按键状态接口
#define DRV_KEY3 GPIOB, GPIO_PIN_14
#define DRV_KEY_GetStatus(key) GPIO_ReadInputBit(key)
#define DRV_KEY_DOWN 0
#define DRV_KEY_UP 1

extern VOID DRV_KEY_Init(VOID);

总结

IO配置总结(配置时钟(必配)–>选择复用(选配)–>选择模式(必配)–>配置速率(必配)):

  1. 判断是GPIO(通用IO)和AFIO(复用IO),可以从datasheet的PIN definition章节查到,如图在这里插入图片描述default是作为普通GPIO口配置,remap(复用)可以作为TM1_BKIN

  2. IO作为普通GPIO口使用,配置流程如下:

    1. 配置GPIO时钟,由下图可以看出,GPIO挂在APB2上,所以,配置代码如下RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_GPIOC |RCC_APB2PERIPH_GPIOE,ENABLE);在这里插入图片描述

    2. 配置GPIO方向、模式和速率在这里插入图片描述在这里插入图片描述如上图几种方式,配置代码如下,注意,输入时速率硬件已经配置好了,软件不需要配置

      GPIO_InitPara GPIO_InitStructure;
      
      /* 上拉输出,50MHz */
      GPIO_InitStructure.GPIO_Pin = GPIO_PIN_0 | GPIO_PIN_2;
      GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUT_PP;
      GPIO_InitStructure.GPIO_Speed = GPIO_SPEED_50MHZ;
      GPIO_Init(GPIOC,&GPIO_InitStructure);
      
      /* 浮空输入 */
      GPIO_InitStructure.GPIO_Pin = GPIO_PIN_14;
      GPIO_InitStructure.GPIO_Mode = GPIO_MODE_IN_FLOATING;
      GPIO_Init(GPIOB,&GPIO_InitStructure);
      
    3. 配置GPIO口中断,参考中断章节

  3. AFIO remap流程,先使能AF时钟,再调用pinRemap函数重新映射即可

    RCC_APB2PeriphClock_Enable(RCC_APB2PERIPH_AF, ENABLE);
    GPIO_PinRemapConfig(GPIO_REMAP_SWJ_DISABLE, ENABLE);
    

参考资料

《GD32F10xCH_V1.1.pdf》

《GD32103C-EVAL-V1.1.pdf》

《GD32F103xxDatasheetRev2.2.pdf》

代码路径

https://github.com/YaFood/GD32F103/tree/master/TestLED

猜你喜欢

转载自blog.csdn.net/qq_17854661/article/details/91876312