自学内容网 自学内容网

1-12 GD32基于定时器输入捕获

前言:


基于本人对相关知识回顾与思考,仅供学习参考


目录

前言:

1.0 输入捕获

 2.0 信号周期

3.0 定时器配置

4.0 定时器配置

5.0 定时器中断

后记:


1.0 输入捕获



 2.0 信号周期


获取信号周期的方法,在第一次捕获与第二次不会之间做差值运算,最后乘以计数周期得到信号周期。

还有月中方式是,在第一次获取计数寄存器数值时,将计数寄存器里面的数组设置为0,这样等到下一次计数时就能从0重新开始计数,通过这个方法就不用做差值运算了。


3.0 定时器配置


4.0 定时器配置


初始化GPIO 

static void GpioInit(void)
{
rcu_periph_clock_enable(RCU_GPIOA);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_10MHZ, GPIO_PIN_0);
}

开启GPIOA时钟,初始化GPIOA管脚,使用浮空输入,输入频率为10MHz,输入引脚为第0号引脚


使能定时器时钟

// 使能定时器1时钟
rcu_periph_clock_enable(RCU_TIMER1);
// 复位定时器
timer_deinit(TIMER1);

定时器初始化

timer_parameter_struct timerInitPara;
// 初始化定时器值
timer_struct_para_init(&timerInitPara);
// 设置预分频器的值
timerInitPara.prescaler = 120 - 1;
// 设置CRA重装计数器的值
timerInitPara.period = 65536 - 1;
// 定时器初始化
timer_init(TIMER1, &timerInitPara);

定时器通道配置

// 定时器输入捕获
timer_ic_parameter_struct icInitPara;
// 输入捕获通道赋初始值
timer_channel_input_struct_para_init(&icInitPara);
// 设置上升沿捕获/下降沿捕获
icInitPara.icpolarity  = TIMER_IC_POLARITY_RISING;
// 设置输入通道
icInitPara.icselection = TIMER_IC_SELECTION_DIRECTTI;
timer_input_capture_config(TIMER1, TIMER_CH_0, &icInitPara);

使能定时器

// 清除定时器中断标志位
timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_CH0);
// 使能定时器中断
timer_interrupt_enable(TIMER1, TIMER_INT_CH0);

// 使能定时器中断优先级
nvic_irq_enable(TIMER1_IRQn, 0, 0);

// 使能定时器
timer_enable(TIMER1);

5.0 定时器中断

static uint32_t g_icValue;

void TIMER1_IRQHandler(void)
{
if (timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_CH0) == SET)
{
timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_CH0);
// 读取输入捕获寄存器里面的数值
g_icValue = timer_channel_capture_value_register_read(TIMER1, TIMER_CH_0) + 1;
// 将计数寄存器的数值清除为 0 
timer_counter_value_config(TIMER1, 0);
}
}

void CaptureDrvInit(void)
{
GpioInit();
TimerInit();
}

void CaptureDrvTest(void)
{
printf("period is %d us.\n", g_icValue);
DelayNms(500);
}

6.0 全部程序

|---------------------capture_drv.h---------------------|-------------------------
#ifndef _CAPTURE_DRV_H_
#define _CAPTURE_DRV_H_

void CaptureDrvInit(void);
void CaptureDrvTest(void);
#endif

|---------------------capture_drv.c---------------------|-------------------------
#include <stdint.h>
#include <stdio.h>
#include "gd32f30x.h"
#include "delay.h"

static void GpioInit(void)
{
rcu_periph_clock_enable(RCU_GPIOA);
gpio_init(GPIOA, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_10MHZ, GPIO_PIN_0);
}

static void TimerInit(void)
{
// 使能定时器1时钟
rcu_periph_clock_enable(RCU_TIMER1);
// 复位定时器
timer_deinit(TIMER1);

timer_parameter_struct timerInitPara;
// 初始化定时器值
timer_struct_para_init(&timerInitPara);
// 设置预分频器的值
timerInitPara.prescaler = 120 - 1;
// 设置CRA重装计数器的值
timerInitPara.period = 65536 - 1;
// 定时器初始化
timer_init(TIMER1, &timerInitPara);

// 定时器输入捕获
timer_ic_parameter_struct icInitPara;
// 输入捕获通道赋初始值
timer_channel_input_struct_para_init(&icInitPara);
// 设置上升沿捕获/下降沿捕获
icInitPara.icpolarity  = TIMER_IC_POLARITY_RISING;
// 设置输入通道
icInitPara.icselection = TIMER_IC_SELECTION_DIRECTTI;
timer_input_capture_config(TIMER1, TIMER_CH_0, &icInitPara);

// 清除定时器中断标志位
timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_CH0);
// 使能定时器中断
timer_interrupt_enable(TIMER1, TIMER_INT_CH0);

// 使能定时器中断优先级
nvic_irq_enable(TIMER1_IRQn, 0, 0);

// 使能定时器
timer_enable(TIMER1);
}

static uint32_t g_icValue;

void TIMER1_IRQHandler(void)
{
if (timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_CH0) == SET)
{
timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_CH0);
// 读取输入捕获寄存器里面的数值
g_icValue = timer_channel_capture_value_register_read(TIMER1, TIMER_CH_0) + 1;
// 将计数寄存器的数值清除为 0 
timer_counter_value_config(TIMER1, 0);
}
}

void CaptureDrvInit(void)
{
GpioInit();
TimerInit();
}

void CaptureDrvTest(void)
{
printf("period is %d us.\n", g_icValue);
DelayNms(500);
}



编译结果:

后记:

......


原文地址:https://blog.csdn.net/qq_45973003/article/details/144242822

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!