我改成外设到内存模式,产生中断后,所对应的中断标志DMA1->LIFCR所有位都是0。初始化,我采用寄存器方式,简单明了。麻烦城主看一下哪地方出错了?
//DMAx的各通道配置
//这里的传输形式是固定的,这点要根据不同的情况来修改
//从存储器->外设模式/8位数据宽度/存储器增量模式
//DMA_Streamx:DMA数据流,DMA1_Stream0~7/DMA2_Stream0~7
//chx:DMA通道选择,范围:1~115(详见<<STM32H7xx参考手册>>16.3.2节,Table 116)
//par:外设地址
//mar:存储器地址
//ndtr:数据传输量
void MYDMA_Config(DMA_Stream_TypeDef *DMA_Streamx,uint8_t chx,uint32_t par,uint32_t mar,uint16_t ndtr)
{
DMA_TypeDef *DMAx;
DMAMUX_Channel_TypeDef *DMAMUXx;
uint8_t streamx;
if((uint32_t)DMA_Streamx>(uint32_t)DMA2)//得到当前stream是属于DMA2还是DMA1
{
DMAx=DMA2;
RCC->AHB1ENR|=1<<1; //DMA2时钟使能
}else
{
DMAx=DMA1;
RCC->AHB1ENR|=1<<0; //DMA1时钟使能
}
while(DMA_Streamx->CR&0X01);//等待DMA可配置
streamx=(((uint32_t)DMA_Streamx-(uint32_t)DMAx)-0X10)/0X18; //得到stream通道号
if(streamx>=6)DMAx->HIFCR|=0X3D<<(6*(streamx-6)+16); //清空之前该stream上的所有中断标志
else if(streamx>=4)DMAx->HIFCR|=0X3D<<6*(streamx-4); //清空之前该stream上的所有中断标志
else if(streamx>=2)DMAx->LIFCR|=0X3D<<(6*(streamx-2)+16); //清空之前该stream上的所有中断标志
else DMAx->LIFCR|=0X3D<<6*streamx; //清空之前该stream上的所有中断标志
if((uint32_t)DMA_Streamx>(uint32_t)DMA2)streamx+=8; //如果是DMA2,通道编号+8
DMAMUXx=(DMAMUX_Channel_TypeDef *)(DMAMUX1_BASE+streamx*4); //得到对应的DMAMUX通道控制地址
DMAMUXx->CCR=chx&0XFF; //通道选择
DMA_Streamx->PAR=par; //DMA外设地址
DMA_Streamx->M0AR=mar; //DMA 存储器0地址
DMA_Streamx->NDTR=ndtr; //DMA 存储器0地址
DMA_Streamx->CR=0; //先全部复位CR寄存器值
DMA_Streamx->CR|=0<<6;
DMA_Streamx->CR|=0<<7; //外设到存储器模式
DMA_Streamx->CR|=0<<8; //非循环模式(即使用普通模式)
DMA_Streamx->CR|=0<<9; //外设非增量模式
DMA_Streamx->CR|=1<<10; //存储器增量模式
DMA_Streamx->CR|=1<<11; //外设数据长度:16位
DMA_Streamx->CR|=1<<13; //存储器数据长度:16位
DMA_Streamx->CR|=1<<16; //中等优先级
DMA_Streamx->CR|=0<<21; //外设突发单次传输
DMA_Streamx->CR|=0<<23; //存储器突发单次传输
DMA_Streamx->CR|=1<<4; //传输完成产生中断
DMA_Streamx->CR|=1<<3; //传输完成一半产生中断
DMA_Streamx->CR|=1<<2; //传输错误产生中断
DMA_Streamx->CR|=1<<1; //直接模式错误产生中断
//DMA_Streamx->FCR=0X21; //FIFO控制寄存器
// DMA interrupt init
// DMA1_Stream0_IRQn interrupt configuration
HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
}
//开启一次DMA传输
//DMA_Streamx:DMA数据流,DMA1_Stream0~7/DMA2_Stream0~7
//ndtr:数据传输量
void MYDMA_Enable(DMA_Stream_TypeDef *DMA_Streamx,uint16_t ndtr)
{
DMA_Streamx->CR&=~(1<<0); //关闭DMA传输
while(DMA_Streamx->CR&0X1); //确保DMA可以被设置
DMA_Streamx->NDTR=ndtr; //DMA 存储器0地址
DMA_Streamx->CR|=1<<0; //开启DMA传输
}
//初始化调用
MYDMA_Config(DMA1_Stream0,0,(uint32_t)0x64000000,(uint32_t) 0x24001000,16000);//DMA1,STEAM0,CH0,外设为FIFO,存储器为SendBuff,长度为:16000.
//外部中断里启动DMA
MYDMA_Enable(DMA1_Stream0,16000);//开始一次DMA传输!
|