1-12 GD32基于定时器输入捕获
前言:
基于本人对相关知识回顾与思考,仅供学习参考
目录
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)!