#include "st_sys.h" #include "st_dma.h" static DMA_Stream_TypeDef * st_dma_steam_map[] = { DMA1_Channel1, DMA1_Channel2, DMA1_Channel3, DMA1_Channel4, DMA1_Channel5, DMA1_Channel6, DMA1_Channel7, DMA2_Channel1, DMA2_Channel2, DMA2_Channel3, DMA2_Channel4, DMA2_Channel5 }; /** * 初始化DMA * * @author lxz */ void st_dma_init(void) { //使能DMA2 DMA1的时钟 int index = 0; do { RCC->AHBENR|=3<<0; }while ((RCC->AHBENR & (0x03 << 0)) == 0); while(index <= ST_DMA2_STREAM5) { DMA_Stream_TypeDef *DMA_Streamx = st_dma_steam_map[index]; DMA_Streamx->CCR = 0; DMA_Streamx->CNDTR = 0; DMA_Streamx->CPAR = 0; DMA_Streamx->CMAR = 0; index++; } } //DMAx的各通道配置 //这里的传输形式是固定的,这点要根据不同的情况来修改 //从存储器->外设模式/8位数据宽度/存储器增量模式 //DMA_Streamx:DMA数据流,DMA1_Stream0~7/DMA2_Stream0~7 //chx:DMA通道选择,范围:1~115(详见<>16.3.2节,Table 116) //par:外设地址 //mar:存储器地址 //ndtr:数据传输量 void st_dma_config(uint8_t streamx,uint8_t chx,uint32_t par,uint32_t mar,uint16_t ndtr) { DMA_Stream_TypeDef *DMA_Streamx; DMA_Streamx = st_dma_steam_map[streamx]; DMA_Streamx->CPAR=par; //DMA外设地址 DMA_Streamx->CMAR=mar; //DMA 存储器0地址 DMA_Streamx->CNDTR=ndtr; //DMA 存储器0地址 DMA_Streamx->CCR=0; //先全部复位CR寄存器值 DMA_Streamx->CCR|=1<<6; //存储器到外设模式 DMA_Streamx->CCR|=0<<8; //非循环模式(即使用普通模式) DMA_Streamx->CCR|=0<<9; //外设非增量模式 DMA_Streamx->CCR|=1<<10; //存储器增量模式 DMA_Streamx->CCR|=0<<11; //外设数据长度:8位 DMA_Streamx->CCR|=0<<13; //存储器数据长度:8位 DMA_Streamx->CCR|=1<<16; //中等优先级 DMA_Streamx->CCR|=0<<21; //外设突发单次传输 DMA_Streamx->CCR|=0<<23; //存储器突发单次传输 DMA_Streamx->CCR |= chx << 25; //DMA_Streamx->FCR=0X21; //FIFO控制寄存器 } //开启一次DMA传输 //DMA_Streamx:DMA数据流,DMA1_Stream0~7/DMA2_Stream0~7 //ndtr:数据传输量 void st_dma_enable(uint8_t streamx,uint16_t ndtr) { DMA_Stream_TypeDef *DMA_Streamx = st_dma_steam_map[streamx]; DMA_Streamx->CCR&=~(1<<0); //关闭DMA传输 while(DMA_Streamx->CCR&0X1); //确保DMA可以被设置 DMA_Streamx->CNDTR=ndtr; //DMA 存储器0地址 DMA_Streamx->CCR|=1<<0; //开启DMA传输 } /** * 停止DMA * * @author lxz * * @param streamx */ void st_dma_disable(uint8_t streamx) { st_dma_steam_map[streamx]->CCR &= ~(1 << 0); } /** * 获取DMA的实体指针 * * @author lxz * * @param streamx * * @return void* */ void * st_dma_get_stream(uint8_t streamx) { SW_WAIT_FINISH(streamx > ST_DMA2_STREAM5); return st_dma_steam_map[streamx]; } /** * 获取DMA通道所在的DMA * * @author lxz * * @param streamx * * @return void* */ void * st_dma_get_dmax(uint8_t streamx) { SW_WAIT_FINISH(streamx > ST_DMA2_STREAM5); if(streamx > ST_DMA1_STREAM7) { return DMA2; } return DMA1; } /** * 判断通道是否使能了 * * @author lxz * * @param streamx * * @return void* */ int st_dma_is_enable(uint8_t streamx) { return (((DMA_Stream_TypeDef *)st_dma_get_stream(streamx))->CCR & 0x0001); }