大家好,我最近写了一个GPIO数据通过DMA传输到内存的程序,但是在周期调用dma_transfer_number_get获取DMA缓存区剩余数据数量时,出现调用几次后程序就进入HardFault_Handler硬错误,请问大家有没有遇到相似问题的。下面是我DMA相关配置。void dma_config(void)
{
dma_single_data_parameter_struct dma_init_struct;
/* enable DMA clock */
rcu_periph_clock_enable(RCU_DMA1);
/* initialize DMA channel5 */
dma_deinit(DMA1,DMA_CH1);
/* DMA channel5 initialize */
dma_init_struct.periph_addr = (GPIO_BASE + 0x00000400U+0x10U);//(uint32_t)TIMER0_CH0CV;
dma_init_struct.periph_inc = DMA_PERIPH_INCREASE_DISABLE;
dma_init_struct.memory0_addr = (uint32_t)buffer;
dma_init_struct.memory_inc = DMA_MEMORY_INCREASE_ENABLE;
dma_init_struct.periph_memory_width = DMA_PERIPH_WIDTH_16BIT;
dma_init_struct.circular_mode = DMA_CIRCULAR_MODE_ENABLE;
dma_init_struct.direction = DMA_PERIPH_TO_MEMORY;
dma_init_struct.number = DMA_BUFF_SIZE;
dma_init_struct.priority = DMA_PRIORITY_ULTRA_HIGH;
dma_single_data_mode_init(DMA1,DMA_CH1,dma_init_struct);
dma_channel_subperipheral_select(DMA1,DMA_CH1,DMA_SUBPERI7);
// /* enable dma switch buffer mode */
// dma_switch_buffer_mode_config(DMA1, DMA_CH1, (uint32_t)(&buffer2), DMA_MEMORY_0);
// dma_switch_buffer_mode_enable(DMA1, DMA_CH1, ENABLE);
/* enable DMA channel5 */
dma_channel_enable(DMA1,DMA_CH1);
}
void timer7_config(void)
{
/* TIMER0 DMA Transfer example -------------------------------------------------
TIMER0CLK = 120MHz, Prescaler = 120
TIMER0 counter clock = systemcoreclock/120 = 1MHz.
the objective is to configure TIMER0 channel 1 to generate PWM
signal with a frequency equal to 1KHz and a variable duty cycle(25%,50%,75%) that is
changed by the DMA after a specific number of update DMA request.
the number of this repetitive requests is defined by the TIMER0 repetition counter,
each 2 update requests, the TIMER0 Channel 0 duty cycle changes to the next new
value defined by the buffer .
-----------------------------------------------------------------------------*/
timer_oc_parameter_struct timer_ocintpara;
timer_parameter_struct timer_initpara;
rcu_periph_clock_enable(RCU_TIMER7);
rcu_timer_clock_prescaler_config(RCU_TIMER_PSC_MUL4);
timer_deinit(TIMER7);
/* TIMER0 configuration */
timer_initpara.prescaler = TIME_PRE-1;
timer_initpara.alignedmode = TIMER_COUNTER_EDGE;
timer_initpara.counterdirection = TIMER_COUNTER_UP;
timer_initpara.period = TIME_PERIOD-1;
timer_initpara.clockdivision = TIMER_CKDIV_DIV1;
timer_initpara.repetitioncounter = 0;
timer_init(TIMER7,&timer_initpara);
/* CH0 configuration in PWM1 mode */
timer_ocintpara.outputstate = TIMER_CCX_ENABLE;
timer_ocintpara.outputnstate = TIMER_CCXN_DISABLE;
timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH;
timer_ocintpara.ocnpolarity = TIMER_OCN_POLARITY_HIGH;
timer_ocintpara.ocidlestate = TIMER_OC_IDLE_STATE_HIGH;
timer_ocintpara.ocnidlestate = TIMER_OCN_IDLE_STATE_LOW;
timer_channel_output_config(TIMER7,TIMER_CH_0,&timer_ocintpara);
timer_channel_output_config(TIMER7,TIMER_CH_2,&timer_ocintpara);
timer_channel_output_pulse_value_config(TIMER7,TIMER_CH_0,TIME_PERIOD/2);
timer_channel_output_mode_config(TIMER7,TIMER_CH_0,TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER7,TIMER_CH_0,TIMER_OC_SHADOW_DISABLE);
timer_channel_output_pulse_value_config(TIMER7,TIMER_CH_2,TIME_PERIOD/2);
timer_channel_output_mode_config(TIMER7,TIMER_CH_2,TIMER_OC_MODE_PWM0);
timer_channel_output_shadow_config(TIMER7,TIMER_CH_2,TIMER_OC_SHADOW_DISABLE);
/* TIMER0 primary output enable */
timer_primary_output_config(TIMER7,ENABLE);
/* TIMER0 update DMA request enable */
timer_dma_enable(TIMER7,TIMER_DMA_UPD);
/* auto-reload preload enable */
timer_auto_reload_shadow_enable(TIMER7);
/* TIMER0 counter enable */
timer_enable(TIMER7);
}
|