8538|0

6495

帖子

10

TA的资源

版主

楼主
 

03 LED操作和普通定时功能 [复制链接]

一、前言

        首先了解一下板卡上自带的4个LED,

        分别对应PA7、PA8、PC6、PC7控制,对于LED的控制涉及单片机最基础的IO控制,上图我们看到4个LED是共地的,故IO输出为高则点亮LED,本开发板单片机系统的供电电压为3.3V,点亮LED4后,测量的R5的电压为1.27V,故该路电流为1.27V/470R=2.7mA。

 

二、目标

        开发板初始demo程序一般搭载的都是走马灯程序,直观简单,使用延时方法阻塞式进行LED控制,我们换一种方法通过定时器实现LED的控制,藉此可以了解熟悉单片机的IO控制和普通定时器的定时功能,由于LED资源比较充足,这里我们较多的展示LED例如最常见的走马灯,同亮同灭闪烁,间隔闪烁等。

 

三、代码介绍

        对于IO的控制流程:

            第一步:打开对应IO的时钟,例如PA引脚rcu_periph_clock_enable(RCU_GPIOA);

            第二步:进行具体IO口的初始化,例如PA7引脚gpio_mode_set(GPIOA,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLDOWN,GPIO_PIN_7),gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7),对于引脚是否上拉下拉问题,个人喜欢与引脚的初始状态保持一致,对于这些LED的控制引脚的希望初始状态都为低,需要输出能力的引脚需配置为推挽输出。这里有一个问题,可能不是同一个团队的原因或者有特殊考量,GD32F303系列只用了一个函数即可进行IO口初始化,这里需要两部才能配置完成;

            第三步:就是IO的高低输出配置了。

IO口初始化代码:

#define GD_RCU_GPIOA_INIT       rcu_periph_clock_enable(RCU_GPIOA)
#define GD_RCU_GPIOC_INIT       rcu_periph_clock_enable(RCU_GPIOC)

#define GD_LED1_On      gpio_bit_set(GPIOA,GPIO_PIN_7)
#define GD_LED1_Off     gpio_bit_reset(GPIOA,GPIO_PIN_7)
#define GD_LED2_On      gpio_bit_set(GPIOA,GPIO_PIN_8)
#define GD_LED2_Off     gpio_bit_reset(GPIOA,GPIO_PIN_8)

#define GD_LED3_On      gpio_bit_set(GPIOC,GPIO_PIN_6)
#define GD_LED3_Off     gpio_bit_reset(GPIOC,GPIO_PIN_6)
#define GD_LED4_On      gpio_bit_set(GPIOC,GPIO_PIN_7)
#define GD_LED4_Off     gpio_bit_reset(GPIOC,GPIO_PIN_7)

//******************************************************************************
//* 函数名称  : GPIO_Config                                              
//* 函数描述  : IO引脚的初始化                                               
//* 输入参数  :                                                               
//* 参数描述  : 对应    IO口初始化及初始状态                                  
//* 输出参数  : 无                                                          
//* 返回值    : 无                                                           
//******************************************************************************
void gd_GPIO_init(void)
{
  
  GD_RCU_GPIOA_INIT;                                                            
  GD_RCU_GPIOC_INIT;

  //*************************LED IO初始化************************************************
  gpio_mode_set(GPIOA,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLDOWN,GPIO_PIN_7|GPIO_PIN_8);
  gpio_output_options_set(GPIOA, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_7 | GPIO_PIN_8);
  gpio_mode_set(GPIOC,GPIO_MODE_OUTPUT,GPIO_PUPD_PULLDOWN,GPIO_PIN_6|GPIO_PIN_7);
  gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7);
  
  GD_LED1_Off;
  GD_LED2_Off;
  GD_LED3_Off;
  GD_LED4_Off;

}

 

        对于定时的配置:

            第一步,选取合适的定时器,查看数据手册有定时器1/2, 定时器8/11, 定时器5/6,其中定时器5/6只能使用内部时钟源,故本次能使用的定时器只有剩余的4个,只是简单的定时功能,选择定时器8作为本次功能实现的定时器;

            第二步,定时器的初始化,见代码;

            第三步,编写中断处理函数。

定时器初始化代码:

//******************************************************************************
//* 函数名称  : gd_TIMER_init                                              
//* 函数描述  : 定时器配置                                               
//* 输入参数  :                                                               
//* 参数描述  : 定时器初始化配置                                  
//* 输出参数  : 无                                                          
//* 返回值    : 无                                                           
//******************************************************************************
void gd_TIMER_init(void)
{
  gd_TIMER8_init(6400,100); //定时10ms
}

//******************************************************************************
//* 函数名称  : gd_TIMER8_init                                              
//* 函数描述  : 定时器8配置                                               
//* 输入参数  :  psr,arr                                                             
//* 参数描述  : 定时器8初始化配置                                  
//* 输出参数  : 无                                                          
//* 返回值    : 无                                                           
//******************************************************************************
void gd_TIMER8_init(uint32_t psr,uint32_t arr)
{
  timer_parameter_struct timer_initpara;

  /* enable the peripherals clock */
  rcu_periph_clock_enable(RCU_TIMER8);

  /* deinit a TIMER */
  timer_deinit(TIMER8);
  /* initialize TIMER init parameter struct */
  timer_struct_para_init(&timer_initpara);
  /* TIMER1 configuration */
  timer_initpara.prescaler        = psr-1;
  timer_initpara.alignedmode      = TIMER_COUNTER_EDGE;
  timer_initpara.counterdirection = TIMER_COUNTER_UP;
  timer_initpara.period           = arr-1;
  timer_initpara.clockdivision    = TIMER_CKDIV_DIV1;
  timer_init(TIMER8, &timer_initpara);
  
  /* Timer8中断设置,优先级0*/
  nvic_irq_enable(TIMER8_IRQn, 0);
  
  /* 清除定时器中断标志位 */
  timer_interrupt_flag_clear(TIMER8, TIMER_INT_FLAG_UP);
  
  /*使能定时器中断*/
  timer_interrupt_enable(TIMER8, TIMER_INT_UP);
  
//  /* enable a TIMER */
//  timer_enable(TIMER8);//这里暂时没有开启定时器,在最后的应用初始化开启

}

中断代码:

uint16_t LED_cnt=0;

typedef struct 
{
 uint8_t updata_flag; //LED更新标志位
 uint8_t Mode; //LED模式
 uint8_t state; //LED状态
 
}states;
states LED;

void TIMER8_IRQHandler(void)
{
  if(SET == timer_interrupt_flag_get(TIMER8, TIMER_INT_UP))
  {
    timer_interrupt_flag_clear(TIMER8, TIMER_INT_UP);
			
    LED_cnt++;

    if(LED_cnt%50 == 0)
    {
      LED.state ++;
      LED.state %= 4;
      LED.updata_flag = 1;
    }
    if(LED_cnt%400 == 0)
    {
      LED.state = 0;
      LED.Mode ++;
      LED.Mode %= 4;
      LED_cnt = 0;
    }
  }
}

应用代码:

//******************************************************************************
// 函数名称  : gd_App_Init                                                     
// 函数描述  : 应用级初始化操作                                                
// 输入参数  :                                                                 
// 参数描述  : 无                                                              
// 输出参数  : 无                                                              
// 返回值    : 无                                                              
//******************************************************************************
void gd_App_Init(void)
{
  LED.updata_flag = 1;
  timer_enable(TIMER8);
}

//******************************************************************************
// 函数名称  : App_LED
// 函数描述  : LED操作                                              
// 输入参数  :                                                                 
// 参数描述  : 无                                                              
// 输出参数  : 无                                                              
// 返回值    : 无                                                              
//******************************************************************************
void App_LED(uint8_t updata_flag,uint8_t Mode,uint8_t state)
{
  if(updata_flag == 1)
  {
    GD_LED1_Off;
    GD_LED2_Off;
    GD_LED3_Off;
    GD_LED4_Off;
    
    switch(Mode)
    {
      case 0:
        if(state == 0)
          GD_LED1_On;
        else if(state == 1)
          GD_LED2_On;
        else if(state == 2)
          GD_LED3_On;
        else if(state == 3)
          GD_LED4_On;
        break;
        
      case 1:
        if(state%2 == 0)
        {
          GD_LED1_On;
          GD_LED2_On;
          GD_LED3_On;
          GD_LED4_On;
        }
        else 
        {
          GD_LED1_Off;
          GD_LED2_Off;
          GD_LED3_Off;
          GD_LED4_Off;
        }

        break;
        
      case 2:
        if(state%2 == 0)
        {
          
          GD_LED1_Off;
          GD_LED2_On;
          GD_LED3_Off;
          GD_LED4_On;
        }
        else 
        {
          GD_LED1_On;;
          GD_LED2_Off;
          GD_LED3_On;
          GD_LED4_Off;
        }

        break;
        
      case 3:
        if(state == 0)
        {
          GD_LED1_On;
        }
        else if(state == 1)
        {
          GD_LED1_On;
          GD_LED2_On;
        }
        else if(state == 2)
        {
          GD_LED1_On;
          GD_LED2_On;
          GD_LED3_On;
        }
        else if(state == 3)
        {
          GD_LED1_On;
          GD_LED2_On;
          GD_LED3_On;
          GD_LED4_On;
        }
        break;
        
      default:
        break;
    
    }
    updata_flag = 0;
    
  }
}

int main(void)
{
  CK_SYS_int1 = rcu_clock_freq_get(CK_SYS);
  CK_SYS_int2 = rcu_clock_freq_get(CK_AHB);
  CK_SYS_int3 = rcu_clock_freq_get(CK_APB1);
  CK_SYS_int4 = rcu_clock_freq_get(CK_APB2);
  
//  /* configure systick */
//  systick_config();
  
  gd_GPIO_init();
  gd_TIMER_init();

  gd_App_Init();
  while(1) 
  {
    App_LED(LED.updata_flag,LED.Mode,LED.state);
  }
}

现象如下:

 

此帖出自GD32 MCU论坛
点赞 关注
个人签名

在爱好的道路上不断前进,在生活的迷雾中播撒光引

 

回复
举报
您需要登录后才可以回帖 登录 | 注册

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表