GD32F450定时器输入捕获上升沿触发DMA
时间: 2023-07-07 07:07:53 浏览: 274
GD32的定时器输入输出捕获
3星 · 编辑精心推荐
GD32F450的定时器可以配置为输入捕获模式,可以使用DMA进行数据传输。以下是一个示例代码,可以实现当定时器的通道1检测到上升沿时,将定时器的CNT值传输到DMA缓存中。
```
#include "gd32f4xx.h"
#define TIMER_PRESCALER 1000
#define TIMER_PERIOD 100
#define DMA_CHANNEL DMA_CH4
#define DMA_STREAM DMA0_STREAM0
#define DMA_CHANNEL_SOURCE DMA_CHXCTL_CHSEL(TIMER1_OVF)
#define BUFFER_SIZE 10
uint32_t buffer[BUFFER_SIZE];
void dma_config(void)
{
dma_parameter_struct dma_init_struct;
rcu_periph_clock_enable(RCU_DMA0);
dma_deinit(DMA0, DMA_STREAM);
dma_init_struct.direction = DMA_PERIPHERAL_TO_MEMORY;
dma_init_struct.memory_addr = (uint32_t)buffer;
dma_init_struct.memory_width = DMA_MEMORY_WIDTH_32BIT;
dma_init_struct.number = BUFFER_SIZE;
dma_init_struct.periph_addr = (uint32_t)&TIMER1_CNT;
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_init_struct.periph_width = DMA_PERIPHERAL_WIDTH_32BIT;
dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
dma_init_struct.transfer_direction = DMA_MEM_INC;
dma_init(DMA0, DMA_STREAM, &dma_init_struct);
dma_circulation_disable(DMA0, DMA_STREAM);
dma_channel_subperipheral_select(DMA0, DMA_STREAM, DMA_SUBPERI0);
dma_memory_to_memory_disable(DMA0, DMA_STREAM);
dma_memory_increment_enable(DMA0, DMA_STREAM);
dma_peripheral_increment_disable(DMA0, DMA_STREAM);
dma_transfer_data_size(DMA0, DMA_STREAM, DMA_TRANSFERSIZE_32BIT);
dma_transfer_enable(DMA0, DMA_STREAM);
}
void timer_config(void)
{
timer_oc_parameter_struct timer_ocinitpara;
timer_parameter_struct timer_initpara;
rcu_periph_clock_enable(RCU_TIMER1);
rcu_timer_clock_prescaler_config(TIMER_PRESCALER);
timer_deinit(TIMER1);
timer_struct_para_init(&timer_initpara);
timer_initpara.prescaler = TIMER_PRESCALER - 1;
timer_initpara.period = TIMER_PERIOD - 1;
timer_initpara.clock_division = TIMER_CKDIV_DIV1;
timer_initpara.counter_mode = TIMER_COUNTER_UP;
timer_initpara.repetition_counter = 0;
timer_init(TIMER1, &timer_initpara);
timer_channel_input_capture_parameter_struct timer_inputcapturepara;
timer_channel_struct_para_init(&timer_inputcapturepara);
timer_inputcapturepara.icpolarity = TIMER_IC_POLARITY_RISING;
timer_inputcapturepara.icselection = TIMER_IC_SELECTION_DIRECTTI;
timer_inputcapturepara.icprescaler = TIMER_IC_PSC_DIV1;
timer_inputcapturepara.icfilter = 0x0;
timer_input_capture_config(TIMER1, TIMER_CH_1, &timer_inputcapturepara);
timer_oc_struct_para_init(&timer_ocinitpara);
timer_channel_output_config(TIMER1, TIMER_CH_1, &timer_ocinitpara);
timer_interrupt_enable(TIMER1, TIMER_INT_CH1);
timer_interrupt_flag_clear(TIMER1, TIMER_INT_CH1);
nvic_irq_enable(TIMER1_IRQn, 0, 0);
timer_enable(TIMER1);
}
void TIMER1_IRQHandler(void)
{
if (timer_interrupt_flag_get(TIMER1, TIMER_INT_CH1) == SET) {
timer_interrupt_flag_clear(TIMER1, TIMER_INT_CH1);
dma_transfer_disable(DMA0, DMA_STREAM);
dma_transfer_number_config(DMA0, DMA_STREAM, BUFFER_SIZE);
dma_channel_select(DMA0, DMA_STREAM, DMA_CHANNEL_SOURCE);
dma_transfer_enable(DMA0, DMA_STREAM);
}
}
int main(void)
{
dma_config();
timer_config();
while (1);
}
```
在上述代码中,首先需要配置定时器的输入捕获模式和DMA传输模式。然后,在定时器中断处理程序中,检测到定时器通道1检测到上升沿时,禁用DMA传输,配置DMA传输缓冲区大小,并启动DMA传输。在主函数中,不断循环等待中断触发。
阅读全文