2019-09-25 09:13 PM
STM32F205 uses the TIM_DMA_Update event loop of timer 8 to trigger DMA2 transport, which moves 5 data from test_data to dest_arr at a time.
Using DMA2_Stream1_Channel7, start these two functions in the main program, configure DMA and TIM8, and then observe that the value of test_data changes to 0x06030444.
When test_data is cleared after a period of delay, the timer can enter the interrupt normally, but DMA no longer works. Test_data is always zero, and I don't know what the problem is.
Please help me to analyze it.
unsigned int dest_arr;
unsigned int test_data[5] = {0x06030440,0x06030441,0x06030442,0x06030443,0x06030444};
/*DMA configuration*/
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){} // wait DMA2_Stream1 disable
DMA_InitStructure.DMA_Channel = DMA_Channel_7; // select DMA_Channel_7
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(test_data); // source address
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)(&dest_arr); // Destination address
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory; // 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;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
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 configuration*/
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); // Enable TIM8 IRQ
TIM8->CR2 |= TIM_CR2_CCDS;
TIM_DMACmd(TIM8,TIM_DMA_Update,ENABLE);
TIM_Cmd(TIM8,ENABLE);
}
/*Main*/
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 irq*/
void TIM8_UP_TIM13_IRQHandler(void)
{
if(TIM_GetITStatus(TIM8,TIM_IT_Update)==SET)
{
TIM_Cmd(TIM8, DISABLE);
TIM_ClearITPendingBit(TIM8,TIM_IT_Update); // ClearITPendingBit
printf("TIMER_8 IRQ IRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQ!\n");
delay_ms(100);
TIM_Cmd(TIM8, ENABLE);
}
}
Output:(Dest_arr is always 0)
dest_arr = 0x0
TIMER_8 IRQ IRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQ!
TIMER_8 IRQ IRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQ!
TIMER_8 IRQ IRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQ!
dest_arr= 0x0
TIMER_8 IRQ IRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQIRQ!
2019-09-26 03:04 AM
> DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory; // Peripheral to memory
If you use MemoryToMemory, transfers are not controlled by the trigger, i.e. the TIM8_update, but will happen automatically (you also are not supposed to use Direct mode in that case).
Read the DMA chapter in RM.
You want to use PeripheralToMemory, even if it is in fact transfer from memory to memory.
JW
PS. Please use English in this forum.
> DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToMemory; //内存的外围
如果使用MemoryToMemory,则传输�?�?�触�?�器(�?�TIM8_update)的控制,但将自动�?�生(在这�?情况下,您也�?应该使用直接模�?)。
阅读RM中的DMA章节。
�?�使实际上是从内存到内存的传输,也�?使用PeripheralToMemory。
JW
PS。 请在此论�?�中使用英语。
2019-09-26 03:18 PM
https://www.on-the-right-track.com/do-you-suffer-from-centre-of-the-universe-syndrome/
If a person does not even care to use Google Translate to make their problem understandable to others, then that person does not deserve any answer at all!
2019-09-26 03:51 PM
Use the DEBUGGER to inspect the DMA registers to determine what the actual state is, and whether it got in some error or fault condition.
So it stops after it sends the LAST word? Why would it restart?
The DMA transfers ONE word at each UPDATE until all 5 are transferred, then it will STOP.
If you want it to cycle, which is good for testing/analyzing, put it in CIRCULAR mode.
If a variable will be changed by an IRQ or DMA, it should be defined as being volatile
2019-09-26 07:31 PM
Thank you for your reply. The post has been rewritten in English.
2019-09-26 07:31 PM
Thank you for your reply. The post has been rewritten in English.
2019-09-26 07:32 PM
Thank you for your reply。Thanks。