定时器是一个功能强大的外设。

一般功能:

  1. 定时中断,计时器,给定一个时间,到达时间后产生一个中断
  2. 定时器输出比较的功能,用于PWM波形的产生,驱动电机
  3. 定时器输入捕获,测频率

    核心关键参数:

  4. 16位计数器

  5. 16位预分频器
  6. 16位自动重装载寄存器

比如高级定时器0,最大是108M,108M/65536/65536=39.76823……(最大定时时间)
image.png
如果你觉得时间不够,还可以使用定时器级联功能,三个定时器级联,就可以定时34万亿年。

高级/通用/基本

GD32F103只有三个定时器,一个高级Timer0,两个通用Timer1、2
image.png

计数模式

向上,向下,中央对齐。
其中中央对齐可以用在SVPWM控制算法中,产生三角载波。

影子寄存器/缓冲寄存器

预分频寄存器自动重载寄存器都是有影子寄存器的,只有在下一个周期你更改后的值才会生效。
image.png
image.png

问题1

不知道结构体这里为什么会报错?
image.png
解决办法
image.png

定时器-基本定时功能

  1. #include "gd32f10x.h" // Device header
  2. void Timer_Init(void)
  3. {
  4. /* TIMER2 configuration */
  5. timer_parameter_struct Timer_initpara;
  6. rcu_periph_clock_enable(RCU_TIMER2); //使能RCU_TIMER2时钟
  7. timer_deinit(TIMER1);
  8. /* initialize TIMER init parameter struct */
  9. timer_struct_para_init(&Timer_initpara);
  10. Timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
  11. Timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
  12. Timer_initpara.counterdirection = TIMER_COUNTER_UP;
  13. Timer_initpara.period = 10000 - 1;
  14. Timer_initpara.prescaler = 10800 - 1;
  15. Timer_initpara.repetitioncounter = 0;
  16. timer_init(TIMER2, &Timer_initpara);
  17. //手动把更新中断标志位清除一下,避免刚初始化完成就进入中断
  18. timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP);
  19. /* TIMER2 channel control update interrupt enable */
  20. timer_interrupt_enable(TIMER2, TIMER_INT_UP);
  21. timer_enable(TIMER2);
  22. /* enable and set key EXTI interrupt to the specified priority */
  23. nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
  24. nvic_irq_enable(TIMER2_IRQn, 1U, 1U);
  25. }
  26. //void TIMER2_IRQHandler(void)
  27. //{
  28. // if (timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_UP) == SET)
  29. // {
  30. //
  31. // timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP);
  32. // }
  33. //}
  1. #include "gd32f10x.h"
  2. #include "gd32f10x_libopt.h"
  3. #include "systick.h"
  4. #include "OLED.h"
  5. #include "Timer.h"
  6. uint16_t Num;
  7. int main(void)
  8. {
  9. OLED_Init();
  10. Timer_Init();
  11. OLED_ShowString(1, 1, "Num:");
  12. while (1)
  13. {
  14. OLED_ShowNum(1, 5, Num, 5);
  15. OLED_ShowNum(2, 5, timer_counter_read(TIMER2), 5);
  16. OLED_ShowNum(3, 5, timer_prescaler_read(TIMER2), 5);
  17. }
  18. }
  19. void TIMER2_IRQHandler(void)
  20. {
  21. if (timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_UP) == SET)
  22. {
  23. Num++;
  24. timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP);
  25. }
  26. }

定时器-外部时钟功能

外部时钟,配置输入捕获功能IC

  1. 输入捕获结构体
  2. 输入捕获引脚时钟、复用时钟、初始化引脚 输入上拉模式
  3. 输入捕获结构体配置
  4. 输入捕获从模式 ```c

    include “gd32f10x.h” // Device header

void Timer_Init(void) { / TIMER1 configuration / timer_parameter_struct Timer_initpara; timer_ic_parameter_struct timer_icinitpara;

  1. rcu_periph_clock_enable(RCU_TIMER1); //使能RCU_TIMER1时钟
  2. rcu_periph_clock_enable(RCU_GPIOA);
  3. rcu_periph_clock_enable(RCU_AF);
  4. gpio_init(GPIOA, GPIO_MODE_IPU, GPIO_OSPEED_50MHZ, GPIO_PIN_0);
  5. timer_deinit(TIMER1);
  6. /* initialize TIMER init parameter struct */
  7. timer_struct_para_init(&Timer_initpara);
  8. Timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
  9. Timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
  10. Timer_initpara.counterdirection = TIMER_COUNTER_UP;
  11. Timer_initpara.period = 10 - 1;
  12. Timer_initpara.prescaler = 1 - 1;
  13. Timer_initpara.repetitioncounter = 0;
  14. timer_init(TIMER1, &Timer_initpara);
  15. /* TIMER1 CH0 input capture configuration */
  16. timer_icinitpara.icpolarity = TIMER_IC_POLARITY_FALLING;
  17. timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI;
  18. timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1;
  19. timer_icinitpara.icfilter = 0x00;
  20. timer_input_capture_config(TIMER1, TIMER_CH_0, &timer_icinitpara);
  21. /* slave mode selection : TIMER1 */
  22. /* TIMER1 input trigger : external trigger connected to CI0 */
  23. timer_input_trigger_source_select(TIMER1,TIMER_SMCFG_TRGSEL_CI0FE0);
  24. timer_slave_mode_select(TIMER1,TIMER_SLAVE_MODE_EXTERNAL0);
  25. //手动把更新中断标志位清除一下,避免刚初始化完成就进入中断
  26. timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_UP);
  27. /* TIMER2 channel control update interrupt enable */
  28. timer_interrupt_enable(TIMER1, TIMER_INT_UP);
  29. timer_enable(TIMER1);
  30. /* enable and set key EXTI interrupt to the specified priority */
  31. nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);
  32. nvic_irq_enable(TIMER1_IRQn, 1U, 1U);

}

//void TIMER2_IRQHandler(void) //{

// if (timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_UP) == SET) // { //
// timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_UP); // } //}

  1. <a name="MNfPo"></a>
  2. # 输出比较功能-PWM
  3. 输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形。<br />每个高级定时器和通用定时器都拥有4个输出比较通道。<br />高级定时器的前3个通道额外拥有死区生成和互补输出的功能。<br />死区时间的插入,确保了通道互补的两路信号不会同时有效。<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/29409159/1666853764785-dc39752b-fda6-4d2f-aab3-5bae49fdad65.png#clientId=uc25cbe92-31ee-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=524&id=u09561e74&margin=%5Bobject%20Object%5D&name=image.png&originHeight=524&originWidth=1172&originalType=binary&ratio=1&rotation=0&showTitle=false&size=39721&status=done&style=none&taskId=u7443f5fa-7a69-4485-8e32-ad3b8e082d6&title=&width=1172)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/29409159/1666853818753-771a6119-b683-4133-b664-38fb1b28eedf.png#clientId=uc25cbe92-31ee-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=326&id=uf82c0407&margin=%5Bobject%20Object%5D&name=image.png&originHeight=326&originWidth=576&originalType=binary&ratio=1&rotation=0&showTitle=false&size=6066&status=done&style=none&taskId=u93f9b0aa-bc12-4b94-9b98-deb13396ff4&title=&width=576)<br />![image.png](https://cdn.nlark.com/yuque/0/2022/png/29409159/1666853829179-efd9dd71-38da-4307-8b8a-f46bd9f9a223.png#clientId=uc25cbe92-31ee-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=146&id=uacaf90ed&margin=%5Bobject%20Object%5D&name=image.png&originHeight=146&originWidth=1161&originalType=binary&ratio=1&rotation=0&showTitle=false&size=19464&status=done&style=none&taskId=u85fbd9d2-5706-419b-a15d-499aea0f88b&title=&width=1161)
  4. <a name="nbIIe"></a>
  5. ## 呼吸灯
  6. ```c
  7. #include "gd32f10x.h" // Device header
  8. void PWM_Init(void)
  9. {
  10. //输出比较与定时器初始化结构体
  11. timer_oc_parameter_struct timer_ocintpara;
  12. timer_parameter_struct timer_initpara;
  13. //时钟 TIMER1 GPIOA
  14. rcu_periph_clock_enable(RCU_TIMER1);
  15. rcu_periph_clock_enable(RCU_GPIOA);
  16. rcu_periph_clock_enable(RCU_AF);
  17. //PA1初始化 复用推挽输出
  18. gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_1);
  19. timer_deinit(TIMER1);
  20. /* TIMER1 参数配置 */
  21. timer_initpara.prescaler = 10800 - 1; //PSC
  22. timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
  23. timer_initpara.counterdirection = TIMER_COUNTER_UP;
  24. timer_initpara.period = 100 - 1; //ARR
  25. timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
  26. timer_initpara.repetitioncounter = 0;
  27. timer_init(TIMER1,&timer_initpara);
  28. //输出比较参数配置
  29. timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;//高极性,不反转,REF直接输出
  30. timer_ocintpara.outputstate = TIMER_CCX_ENABLE;//输出使能
  31. timer_channel_output_config(TIMER1,TIMER_CH_1,&timer_ocintpara);
  32. /* CH1 configuration in PWM mode1,duty cycle 0% */
  33. timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_1,0);//CCR 占空比
  34. timer_channel_output_mode_config(TIMER1,TIMER_CH_1,TIMER_OC_MODE_PWM0);//PWM模式0 模式1
  35. timer_channel_output_shadow_config(TIMER1,TIMER_CH_1,TIMER_OC_SHADOW_DISABLE);
  36. /* auto-reload preload enable */
  37. timer_auto_reload_shadow_enable(TIMER1);
  38. /* auto-reload preload enable */
  39. timer_enable(TIMER1);
  40. }
  41. void PWM_SetCompare1(uint16_t Compare)
  42. {
  43. timer_channel_output_pulse_value_config(TIMER1,TIMER_CH_1,Compare);
  44. }
  1. #include "gd32f10x.h"
  2. #include "gd32f10x_libopt.h"
  3. #include "systick.h"
  4. #include "OLED.h"
  5. #include "Timer.h"
  6. #include "PWM.h"
  7. uint8_t i;
  8. int main(void)
  9. {
  10. OLED_Init();
  11. PWM_Init();
  12. OLED_ShowString(1, 1, "Duty: %");
  13. while (1)
  14. {
  15. for (i = 0; i <= 100; i++)
  16. {
  17. PWM_SetCompare1(i);
  18. Delay_ms(10);
  19. OLED_ShowNum(1, 6, i, 3);
  20. }
  21. for (i = 0; i <= 100; i++)
  22. {
  23. PWM_SetCompare1(100 - i);
  24. Delay_ms(10);
  25. OLED_ShowNum(1, 6, i, 3);
  26. }
  27. }
  28. }

输出比较-互补、死区时间、刹车

1.高级定时器只有 TIMER0 四通道定时器
image.png
通过配置互补通道PB13 PA8
image.png
配置刹车PB12
image.png

  1. #include "gd32f10x.h" // Device header
  2. void PWM_Init(void)
  3. {
  4. //输出比较与定时器初始化结构体 刹车结构体
  5. timer_oc_parameter_struct timer_ocintpara;
  6. timer_parameter_struct timer_initpara;
  7. timer_break_parameter_struct timer_breakpara;
  8. //时钟 TIMER0 GPIOA GPIOB
  9. rcu_periph_clock_enable(RCU_TIMER0);
  10. rcu_periph_clock_enable(RCU_GPIOA);
  11. rcu_periph_clock_enable(RCU_GPIOB);
  12. rcu_periph_clock_enable(RCU_AF);
  13. //PA1初始化 复用推挽输出
  14. gpio_init(GPIOA, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_8);
  15. //PB13 互补通道初始化 复用推挽输出
  16. gpio_init(GPIOB, GPIO_MODE_AF_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_13);
  17. /* configure PB12(TIMER0 BKIN) as alternate function */
  18. gpio_init(GPIOB, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, GPIO_PIN_12);
  19. timer_deinit(TIMER0);
  20. /* TIMER0 参数配置 */
  21. timer_initpara.prescaler = 108 - 1; //PSC
  22. timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
  23. timer_initpara.counterdirection = TIMER_COUNTER_UP;
  24. timer_initpara.period = 600 - 1; //ARR
  25. timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
  26. timer_initpara.repetitioncounter = 0;
  27. timer_init(TIMER0,&timer_initpara);
  28. //输出比较参数配置
  29. timer_ocintpara.outputstate = TIMER_CCX_ENABLE;//输出使能
  30. timer_ocintpara.outputnstate = TIMER_CCXN_ENABLE;//互补输出使能
  31. timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;//高极性,不反转,REF直接输出
  32. timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
  33. timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_HIGH;
  34. timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_HIGH;
  35. //通道选择
  36. timer_channel_output_config(TIMER0,TIMER_CH_0,&timer_ocintpara);
  37. /* CH0 configuration in PWM mode1,duty cycle 0% */
  38. timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_0,0);//CCR 占空比
  39. timer_channel_output_mode_config(TIMER0,TIMER_CH_0,TIMER_OC_MODE_PWM0);//PWM模式0 模式1
  40. timer_channel_output_shadow_config(TIMER0,TIMER_CH_0,TIMER_OC_SHADOW_ENABLE);
  41. /* automatic output enable, break, dead time and lock configuration*/
  42. timer_breakpara.runoffstate = TIMER_ROS_STATE_ENABLE;
  43. timer_breakpara.ideloffstate = TIMER_IOS_STATE_ENABLE ;
  44. timer_breakpara.deadtime = 164;
  45. timer_breakpara.breakpolarity = TIMER_BREAK_POLARITY_LOW;
  46. timer_breakpara.outputautostate = TIMER_OUTAUTO_ENABLE;
  47. timer_breakpara.protectmode = TIMER_CCHP_PROT_OFF;
  48. timer_breakpara.breakstate = TIMER_BREAK_ENABLE;
  49. timer_break_config(TIMER0,&timer_breakpara);
  50. /* auto-reload preload enable */
  51. // timer_auto_reload_shadow_enable(TIMER0);
  52. /* TIMER0 primary output function enable */
  53. timer_primary_output_config(TIMER0,ENABLE);
  54. /* TIMER0 channel control update interrupt enable */
  55. timer_interrupt_enable(TIMER0,TIMER_INT_CMT);
  56. /* TIMER0 break interrupt disable */
  57. timer_interrupt_disable(TIMER0,TIMER_INT_BRK);
  58. nvic_priority_group_set(NVIC_PRIGROUP_PRE1_SUB3);
  59. nvic_irq_enable(TIMER0_TRG_CMT_IRQn, 0, 1);
  60. /* TIMER0 counter enable */
  61. timer_enable(TIMER0);
  62. }
  63. void PWM_SetCompare1(uint16_t Compare)
  64. {
  65. timer_channel_output_pulse_value_config(TIMER0,TIMER_CH_0,Compare);
  66. }

互补输出:
image.png
死区时间:
image.png
刹车功能
image.png