[经验分享] GD32E231 DIY大赛(8)——完成定时器2的驱动

hujj   2019-5-17 13:58 楼主
    为了可控制报警声音时间的长短,我利用了定时器2的功能。具体做法是先配置定时器2计时为一秒,然后将设定的时间长度给一个变量,在定时器中断处理中对这个变量进行减1操作,当变量等于0时,关闭报警声音。
    下面是定时器配置的代码:
  1. void timer_config(void)
  2. {
  3.     /* -----------------------------------------------------------------------
  4.     TIMER2CLK is 100KHz定时器2 CLK为100kHz

  5.     TIMER2 channel0 duty cycle = (25000/ 50000)* 100  = 50%
  6.     ----------------------------------------------------------------------- */
  7.     timer_oc_parameter_struct timer_ocintpara; //定义数据结构
  8.     timer_parameter_struct timer_initpara;

  9.     rcu_periph_clock_enable(RCU_TIMER2);       //开启时钟

  10.     timer_deinit(TIMER2);                      //指定定时器

  11.     /* TIMER configuration 定时器配置*/
  12.     timer_initpara.prescaler         = 719;
  13.     timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;
  14.     timer_initpara.counterdirection  = TIMER_COUNTER_UP;
  15.     timer_initpara.period            = 99999;            //定时1000毫秒
  16.     timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;
  17.     timer_initpara.repetitioncounter = 0;
  18.     timer_init(TIMER2,&timer_initpara);

  19. timer_interrupt_enable(TIMER2, TIMER_INT_UP); //Enable TIMER2
  20.     nvic_irq_enable(TIMER2_IRQn, 0);              //Set priority to 0(0-2)

  21.     /* auto-reload preload enable 自动重新加载预加载启用*/
  22.     timer_auto_reload_shadow_enable(TIMER2);
  23.     /* auto-reload preload enable */
  24.     timer_enable(TIMER2);
  25. }



    下面是定时器中断处理的代码:
  1. void TIMER2_IRQHandler(void)
  2. {
  3.     if(RESET != timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_UP))
  4.     {

  5.                 if(time>0)
  6.                         time--;
  7.     }
  8.     timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP);
  9. }


    在外部中断处理程序中设置报警模式,在主循环中获取报警标志时开启音乐IC的电源,并在到时后关闭音乐IC的电源:
  1.                 if(mode==110){
  2.                         alar++;           //警情计数
  3.                         LCD_line_clear(3);
  4.                         LCD_line_clear(4);
  5.                         LCD_write_string(0,3,(uint8_t *) "报警记录");
  6.                         LCD_write_value(53,4,3,0,1,alar);
  7.                        
  8.                         date_write();     //添加警情记录
  9.                         LCD_write_value(18,2,3,0,1,recn);
  10.                     LCD_write_value(60,2,3,0,1,addr);

  11.                         mode = 0;
  12.                     if(ala8==4){      //启动音乐
  13.                                 gpio_bit_set(GPIOA, GPIO_PIN_2);//发出启动信号
  14.                             delay_1ms(100);
  15.                                 gpio_bit_reset(GPIOA, GPIO_PIN_2);//撤消启动信号
  16.                         }
  17.                         else{
  18.                             if(ala8>0)    //指定报警声
  19.                                         alarm_type(ala8-1);
  20.                                 time = ala9;  //报警声音时长
  21.                                 gpio_bit_reset(GPIOA, GPIO_PIN_3);//启动报警声
  22.                                 gd_eval_led_off(LED2);
  23.                         }

  24.                 }
  25.                 if(time==0){
  26.                         gpio_bit_set(GPIOA, GPIO_PIN_3);  //关闭报警声
  27.                     gd_eval_led_off(LED2);
  28.                 }
  29.                 else
  30.                         LCD_write_value(53,3,3,0,0,time); //显示剩余时间


    经测试,程序代码基本上达到要求,仅仅是我配置定时器时间为一秒,而实际测试发现低于一秒,大约为0.5秒左右,尚未查出原因。



回复评论 (9)

不错的分享,多分享这些国产MCU大家都来用,都来完善
点赞  2019-5-17 15:43
定时器时钟频率为144hz.
点赞  2019-5-17 17:11
引用: serialworld 发表于 2019-5-17 17:11 定时器时钟频率为144hz.
timer_initpara.period = 99999; //定时1000毫秒 原来范例中定时500毫秒,这个数值是49999,我以为改为99999就可以定时1000毫秒呢。请问该如何计算呢? 本帖最后由 hujj 于 2019-5-17 18:52 编辑
点赞  2019-5-17 18:51
问题是定时器都是16位的最大值位65536,99999太大了
点赞  2019-5-17 20:10
你需要多少频率
intersil Techwell应用工程师
点赞  2019-5-17 21:22
引用: serialworld 发表于 2019-5-17 20:10
问题是定时器都是16位的最大值位65536,99999太大了

谢谢指教!没注意到这个问题,怪不得只有半秒左右的时间,我改回5000毫秒再试试看。
点赞  2019-5-18 06:53
引用: 李百仪 发表于 2019-5-17 21:22
你需要多少频率

原来准备定时1秒的,现在准备仍采用例程原来的500毫秒。
点赞  2019-5-18 06:55
谢谢分享!
点赞  2019-5-18 08:39
将数值改回了49999,这次定时准确了,500毫秒。
点赞  2019-5-18 09:28
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复