本帖最后由 c67890 于 2019-9-27 10:07 编辑
STM32F205使用定时器8的TIM_DMA_Update 事件循环触发DMA2搬运,从 test_data 每次搬运五个数据到 dest_arr 中。
使用DMA2_Stream1_Channel7 ,在主程序中启动这两个函数,配置DMA和TIM8,然后观察test_data的值变为了0x06030444,
延时一段时间后清零 test_data,定时器可以正常进入中断,但DMA不再起作用, test_data始终是零,不知道问题出在哪,
请各位协助分析一下。
unsigned int dest_arr;
unsigned int test_data[5] = {0x06030440,0x06030441,0x06030442,0x06030443,0x06030444};
/*DMA配置函数*/
void DMA_Auto_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);
DMA_DeInit(DMA2_Stream1);
while (DMA_GetCmdStatus(DMA2_Stream1) != DISABLE){} // 等待DMA可配置
DMA_InitStructure.DMA_Channel = DMA_Channel_7; // 通道选择
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(test_data); // DMA外设地址(SOURCE ADDR)
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)(&dest_arr); // DMA 存储器0地址
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory; // 内存到内存
DMA_InitStructure.DMA_BufferSize = 5; // 数据传输量
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Enable; // 外设增量模式
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable; // 存储器非增量模式
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word; // 外设数据长度:32位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word; // 存储器数据长度:32位
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal; // 不使用循环模式
DMA_InitStructure.DMA_Priority = DMA_Priority_High; // 优先级
DMA_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable;
DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_Full;
DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; // 存储器突发单次传输
DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; // 外设突发单次传输
DMA_Init(DMA2_Stream1, &DMA_InitStructure);
DMA_Cmd(DMA2_Stream1, ENABLE);
}
/*timer8配置函数*/
void timer8_init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM8, ENABLE);
TIM_TimeBaseStructure.TIM_Period = 100-1;
TIM_TimeBaseStructure.TIM_Prescaler = 60000-1;
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM8, &TIM_TimeBaseStructure);
NVIC_InitStructure.NVIC_IRQChannel = TIM8_UP_TIM13_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
TIM_ClearFlag(TIM8,TIM_FLAG_Update);
TIM_ITConfig(TIM8, TIM_IT_Update, ENABLE); // 开中断
TIM8->CR2 |= TIM_CR2_CCDS;
TIM_DMACmd(TIM8,TIM_DMA_Update,ENABLE);
TIM_Cmd(TIM8,ENABLE);
}
/*主函数*/
int main(void)
{
uart5_init();
timer8_init();
DMA_Auto_Config();
delay_ms(100);
test_arr = 0;
while(1)
{
delay_ms(100);
printf("dest_arr = 0x%x\n",dest_arr);
}
return 0;
}
/*TIM8中断函数*/
void TIM8_UP_TIM13_IRQHandler(void)
{
if(TIM_GetITStatus(TIM8,TIM_IT_Update)==SET) // 溢出中断
{
TIM_Cmd(TIM8, DISABLE);
TIM_ClearITPendingBit(TIM8,TIM_IT_Update); // 清除中断标志位
printf("TIMER_8 IRQ IRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQ!\n");
delay_ms(100);
TIM_Cmd(TIM8, ENABLE);
}
}
打印输出结果:(循环输出如下,dest_arr始终为0)
dest_arr = 0x0
TIMER_8 IRQ IRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQ!
TIMER_8 IRQ IRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQ!
TIMER_8 IRQ IRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQ!
dest_arr= 0x0
TIMER_8 IRQ IRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQ!
TIMER_8 IRQ IRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQ!
TIMER_8 IRQ IRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQ!
dest_arr= 0x0
|