单片机学习小组
直播中

建立建利12

8年用户 1371经验值
擅长:可编程逻辑 嵌入式技术
私信 关注

STM32F407的DAM输出配置有哪些步骤呢

STM32F407的DAM输出配置有哪些步骤呢?怎样去实现其代码呢?

回帖(1)

史娟

2022-1-25 11:05:06
1 DMA通道

STM32F407有两个DAM,每个DMA有8个数据流,每个数据流有8个通道。
数据流之间可以配置优先级。


2 DMA输出配置

使用DMA输出波形,基本思路为,使用定时器循环间隔触发DMA请求,由DMA将波表数据输出到外设上(IO口,DA的输入等)。定时器的中断周期决定了波表的读取频率,进而决定了最后波形的频率,而波表决定了波形的形状。
大体配置步骤:
1)DMA方向:存储器对外设的传输;
2)模式:循环模式;
3)数据项数寄存器NDTR设置为波表的长度。
4)内存地址设置为波表头,地址设置为增量模式;
5)外设地址设置为对应的外设(IO的ODR寄存器,DA的DHRx寄存器),地址为非增量模式;
5)触发改为定时中断触发,定时中断的周期要根据输出波形的频率和波表来确定,ftime = fsin * 波表size;
3 示例代码

3.1DMA 配置

以定时器1更新事件触发DMA发送,根据DMA通道可知TIM1_UP为DMA2 Steam5 Channel6。

/**********配置DMA**********/
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);//DMA2时钟使能
DMA_DeInit(DMA2_Stream5);


while (DMA_GetCmdStatus(DMA2_Stream5) != DISABLE){}//等待DMA可配置


/* 配置 DMA Stream */
DMA_InitStructure.DMA_Channel = DMA_Channel_6;  //通道选择
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(GPIOE->ODR));//DMA外设地址
DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)tab;//DMA 存储器0地址
DMA_InitStructure.DMA_DIR = DMA_DIR_MemoryToPeripheral;//存储器到外设模式
DMA_InitStructure.DMA_BufferSize = TAB_SIZE;//数据传输量
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设非增量模式
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//存储器增量模式
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//外设数据长度:8位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//存储器数据长度:8位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;// 使用循环模式
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;//非常高优先级
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_Stream5, &DMA_InitStructure);//初始化DMA Stream


3.2触发源配置-定时器更新事件TIM1_UP触发


TIM_TimeBaseStructure.TIM_Prescaler=psc;          //预分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up;
TIM_TimeBaseStructure.TIM_Period=arr;                  //重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_RepetitionCounter=0; //重复计数值 会影响更新频率
TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
TIM_ARRPreloadConfig(TIM1,ENABLE);


TIM_DMACmd(TIM1,TIM_DMA_Update,ENABLE);//使能DMA请求源
3.3开启传输

开启传输有两点,一是通道本身要使能,二是触发请求源要能工作。
另外,实验发现每次传输前要把传输完成标志清掉,不然DMA不会工作。

DMA_ClearFlag(DMA2_Stream5,DMA_FLAG_TCIF5|DMA_FLAG_HTIF5|DMA_FLAG_TEIF5|DMA_FLAG_DMEIF5|DMA_FLAG_FEIF5);//清除传输完成标志
DMA_Cmd(DMA2_Stream5, ENABLE);                      //开通DMA数据流,此时触发源产生就会传输一次数据
TIM_Cmd(TIM1, ENABLE);                  //使能定时器,更新事件会不断触发DMA
举报

更多回帖

发帖
×
20
完善资料,
赚取积分