这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 企业专区 » GD32 » [GD32130C-START]GD32F130C8真的可以兼容ST的吗?(二)

共2条 1/1 1 跳转至

[GD32130C-START]GD32F130C8真的可以兼容ST的吗?(二)KeyScan实验

院士
2015-03-29 00:15:05     打赏

为了验证GD32F130C8ST的兼容性,版主本次做了按键扫描的实验。

本次实验使用GD32130C-START的开发板,其按键连接PA0引脚,并通过上拉电阻与电容来做硬件消抖与EMI去除。

在软件上面,仍然使用STM32F0xx的固件库。版主以STM32F030为基准型号生成固件库,并放入IAR软件里调用。

软件架构实现方式:

首先,使用库函数的方式初始化了芯片的晶振系统,使用其外置的8MHz晶振。

然后初始化了板载外设,两个LED灯与1个按键;

在板载bsp支持包内添加按键扫描功能函数,其函数具体实现请看版主的源代码;

在应用层上面设计了按键扫描的检测函数,通过状态机的方式来实现按键的各个状态之间的流轮。状态图版主这里因为时间关系没有画,也请大家直接看源代码,毕竟代码量较少,还是相当容易就能看出来的。

实验现象:当有按键按下时,LED0灯将会亮起,按键释放后,LED1灯将会熄灭;

实验结果:实验结果与设计方案完全相符,STM32F0xx的固件库目前完美支持GD32F130C8芯片。

版主源代码如下:

void SysClockInit(void)
{
  
  ErrorStatus HSEStartUpStatus;
  
  /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration -----------------------------*/   
  /* RCC system reset(for debug purpose) */
  RCC_DeInit();

  /* Enable HSE */
  RCC_HSEConfig(RCC_HSE_ON);

  /* Wait till HSE is ready */
  HSEStartUpStatus = RCC_WaitForHSEStartUp();

  if (HSEStartUpStatus == SUCCESS)
  {
    /* Enable Prefetch Buffer */
    FLASH_PrefetchBufferCmd(ENABLE);

    /* Flash 2 wait state */
    FLASH_SetLatency(FLASH_Latency_0);
 
    /* HCLK = SYSCLK */
    RCC_HCLKConfig(RCC_SYSCLK_Div1); 
  
    /* PCLK2 = HCLK */
    RCC_PCLKConfig(RCC_HCLK_Div1); 

    /* PLLCLK = 8MHz * 6 = 48 MHz */
//    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);    /* 此处需要根据外部晶振的改变而改变 */
    RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_12);     /* Max Freq = 48MHz */

    /* Enable PLL */ 
    RCC_PLLCmd(ENABLE);

    /* Wait till PLL is ready */
    while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
    {
    }

    /* Select PLL as system clock source */
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);

    /* Wait till PLL is used as system clock source */
    while(RCC_GetSYSCLKSource() != 0x08)
    {
    }
  }
  else
  { /* If HSE fails to start-up, the application will have wrong clock configuration.
       User can add here some code to deal with this error */    

    /* Go to infinite loop */
    while (1)
    {
    }
  }
}



/**
  * @brief  初始化按键 PA0
  * @param  
  * @retval 
  * @date   2015-03-26
  * @note   外部连接上拉电阻,空闲状态为高电压,按下时为低电压
  */

void KeyInit(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
  
  /* Configure PA0 in input pushpull mode */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
//  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  
  GPIO_Init(GPIOA, &GPIO_InitStructure);
}

/**
  * @brief  scan key 
  * @param  the key number
  * @retval true = press down; false = idle;
  * @date   2015-03-28
  * @note   PA0 =>外部连接上拉电阻,空闲状态为高电压,按下时为低电压
  */

bool KeyScan(uint8_t num)
{
  bool keyStatus = false;
  uint16_t t;
  t = GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0);
  switch(num)
  {
    case 0:
    {
      if(GPIO_Pin_0 == (GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)))
      {
        keyStatus = false;
      }
      else
      {
        keyStatus = true;
      }
      break;
    }
    default: keyStatus = false;
    
  }
  return keyStatus;
}


/**
  * @brief  led initial
  * @param  
  * @retval 
  * @date   2015-03-26
  * @note   LED0 =>PF6 LED1 =>PF7
  */

void LedInit(void)
{
  GPIO_InitTypeDef  GPIO_InitStructure;
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, ENABLE);
  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
  GPIO_Init(GPIOF, &GPIO_InitStructure);
}

/**
  * @brief  LED on
  * @param  
  * @retval 
  * @date   2015-03-27
  * @note   
  */

void LedOn(uint8_t num)
{
  switch(num)
  {
    case 0:
    {
      GPIO_SetBits(GPIOF, GPIO_Pin_6);
      break;
    }
    case 1:
    {
      GPIO_SetBits(GPIOF, GPIO_Pin_7);
      break;
    }
  }
}

/**
  * @brief  LED off
  * @param  
  * @retval 
  * @date   2015-03-27
  * @note   
  */

void LedOff(uint8_t num)
{
  switch(num)
  {
    case 0:
    {
      GPIO_ResetBits(GPIOF, GPIO_Pin_6);
      break;
    }
    case 1:
    {
      GPIO_ResetBits(GPIOF, GPIO_Pin_7);
      break;
    }
  }
}

/**
  * @brief  led toggle
  * @param  
  * @retval 
  * @date   2015-03-28
  * @note   
  */

void LedToggle(uint8_t num)
{
  switch(num)
  {
    case 0:
    {
      GPIOF->ODR ^= GPIO_Pin_6;
      break;
    }
    case 1:
    {
      GPIOF->ODR ^= GPIO_Pin_7;
      break;
    }
  }
}

/**
  * @brief  bsp initial 
  * @param  
  * @retval 
  * @date   2015-03-26
  * @note   1 *key; 1 *LED
  */

void bspInit(void)
{
  SysClockInit();
  LedInit();
  KeyInit();
}

 


/**
  * @brief  key check
  * @param  
  * @retval 
  * @date   2015-03-28
  * @note   
  */

void KeyCheck(void)
{
  bool KeyStatus;
  KeyStatus = KeyScan(0);
  
  switch(gKeyStatus)
  {
    case 0:  /*!< 空闲状态 */
    {
      if(KeyStatus == true)
      {
        gKeyStatus = 1;
      }
      else
      {
        gKeyStatus = 0;
        LedOff(0);
      }
      break;
    }
    case 1:  /*!< 消抖状态 */
    {
      if(KeyStatus == true)
      {
        gKeyCnt = 5;
        gKeyStatus = 2;
      }
      else
      {
        gKeyCnt = 0;
        gKeyStatus = 0;
      }
      break;
    }
    case 2:  /*!< 按下状态 */
    {
      if(KeyStatus == true)
      {
        if(gKeyCnt == 0)
        {
          LedOn(0);
        }
        else
        {
          gKeyStatus = 2;
        }
      }
      else
      {
        gKeyCnt = 0;
        gKeyStatus = 0;
      }
      break;
    }
    case 3:  /*!< 确认按下 */
    {
      LedOn(0);
      break;
    }
    default: gKeyStatus = 0;
  }

}


void main(void)
{
  bool LedStatus[2];
  gKeyStatus = 0;
  bspInit();
  gCntLed[0] = 500;
  gCntLed[1] = 500;
  LedStatus[0] = false;
  LedStatus[1] = false;
  
  
  

  
  if (SysTick_Config(48000)) //参数为系统时钟的向上溢出值,此配置为48000,即1ms中断一次
  {
    /* Capture error */ 
    while (1);

  }
  
  while(1)
  {
    if(gCntLed[0] == 0)
    {
      LedToggle(1);
      gCntLed[0] = 500;
      
    }
    KeyCheck();
    
  }
}

/**
  * @brief  SysTick_Handler的中断入口函数
  * @param  
  * @retval 
  * @date   2014-11-23
  * @note   
  */

void SysTick_Handler(void)
{
  if(gCntLed[0] > 0)
  {
    gCntLed[0]--;
  }
  else
  {
    gCntLed[0] = 0;
  }
  
  if(gCntLed[1] > 0)
  {
    gCntLed[1]--;
  }
  else
  {
    gCntLed[1] = 0;
  }
  
  if(gKeyCnt > 0)
  {
    gKeyCnt--;
  }
  else
  {
    gKeyCnt = 0;
  }
}

 


IAR工程源代码:exp02_key.zip




关键词: GD32130C-START     兆易     GD32F13    

高工
2015-03-29 08:37:46     打赏
2楼

状态机真是个好机制,尤其是在多任务相互耦合的情况下,赞楼主


共2条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]