通过TIM8的事件触发DMA,从内存中的地址搬运数据到外设的寄存器,例子中的中断部分可以关闭,与功能无关,仅为测试时观察方便。 定时器每产生一次事件(本文以UPDATE为例,CC等其他事件也可实现),DMA被启动一次,搬运预设的若干个数据到指定位置。
先看下下面两个DMA通道表,TIM8的UPDATE对应的DMA通道为DMA2-->stream1-->channel7,通道一定选择对,否则神仙也没辙!!!,实际使用中要注意!
/* | ||
程序实现内容:通过定时器触发DMA,实现DMA传输的可控性 | ||
程序通过 定时器8 触发 DMA2_Stream1开启,DMA2_Stream1从内存到外设传递数据,每次传递数据的个数为5 | ||
TIM8 每触发一次, DMA2_Stream1 开启一次传输,TIM8 触发100次后,关闭TIM8,清空 外设寄存器。 | ||
主函数中循环打印外设寄存器的值,100次触发之内,外设寄存器的数据一直在更新, | ||
关闭定时器后,外设寄存器中的数据为0,表示TI8关闭后,DMA不再被触发。 | ||
注:本测试总TIM8开启的了中断,用来观察和测试使用,实际应用中可以不开中断,TIM8同样会触发启动DMA. | ||
*/ | ||
unsigned int timer8_times_count = 0; // 计数用变量 | ||
unsigned int config_CR[5] = {0x06030440,0x06030446,0x06030442,0x06030448,0x06030444}; // 外部数据 | ||
/* | ||
通过 DMA2_Stream1_DMA_Channel_7 向 DMA2_Stream3的 CR 寄存器中搬运数据 | ||
注:数据为测试数据,无实际意义,仅用于测试功能 | ||
*/ | ||
void DMA_Auto_Config_CR(void) | ||
{ | ||
DMA_InitTypeDef DMA_InitStructure; |
||
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA1|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)(&DMA2_Stream3->CR); // D |