中级会员
- 积分
- 485
- 威望
- 305
- 贡献
- 78
- 兑换币
- 119
- 注册时间
- 2016-9-14
- 在线时间
- 51 小时
- 毕业学校
- bilibili
|
//作者:哈工大智能车创新俱乐部
////主要依赖:MK66F18.h(CMSIS Peripheral Access Layer for MK66F18)
////描述:用DMA发送数据,减缓CPU的运行压力。
#define BAUD_RATE 115200
#define UART_WITH_DMA uart1
#define DMA_UARTn_Tx DMA_UART1_Tx
#define DMA_CHANNEL_in_GROUP1 17 //请用16到31通道
//选group1 配置group1的优先级低于group 0(摄像头驱动使用g0)
#define default_transmittion_size 50
#define default_minor_loop_counter default_transmittion_size
#define default_dma_address_go_back_when_finish default_transmittion_size
uint8 sendbuff[1024]="Empty eDMA-UART send buff,wanna put some thing in here?\n";
extern UART_Type * uart[5];
void uart_init_with_dma()
{
uart_init (UART_WITH_DMA, BAUD_RATE);
uart[UART_WITH_DMA]->C2 |=
(0
| UART_C2_TE_MASK //发送使能
| UART_C2_RE_MASK //接收使能
| UART_C2_TIE_MASK //发送中断或DMA传输请求使能
);
uart[UART_WITH_DMA]->C2 &=~UART_C2_TCIE_MASK;
uart[UART_WITH_DMA]->C5 |=UART_C5_TDMAS_MASK;
SIM->SCGC7 |= SIM_SCGC7_DMA_MASK; //时钟
SIM->SCGC6 |= SIM_SCGC6_DMAMUX_MASK; //时钟
DMAMUX0->CHCFG[DMA_CHANNEL_in_GROUP1] = (0
| DMAMUX_CHCFG_ENBL_MASK // Enable routing of DMA request
| DMAMUX_CHCFG_SOURCE(DMA_UARTn_Tx) // 通道触发传输源:
);
DMA0->CR |= DMA_CR_GRP0PRI_MASK ;//CR_GRP0PRI=1 //设0组有高优先级
DMA0->CR &=~ DMA_CR_GRP1PRI_MASK ;//CR_GRP1PRI=0 //设1组有低优先级
//实际上用DMA1,即16到31通道
//PS:DMA0是0到15通道
DMA0->TCD[DMA_CHANNEL_in_GROUP1].SADDR =(uint32)(void *)(sendbuff) ;
DMA0->TCD[DMA_CHANNEL_in_GROUP1].DADDR =(uint32)(&(uart[UART_WITH_DMA]->D));
DMA0->TCD[DMA_CHANNEL_in_GROUP1].NBYTES_MLNO = DMA_NBYTES_MLNO_NBYTES(1);////需要发送的数据,最好是4的整数倍.
//UART准备好后 触发一次minor loop 每个minor loop 只能把一个字节送入传输用的寄存器
DMA0->TCD[DMA_CHANNEL_in_GROUP1].SLAST= - default_dma_address_go_back_when_finish; ////大循环结束后,源地址改变量。最好是4的整数倍,等于上面
DMA0->TCD[DMA_CHANNEL_in_GROUP1].DLAST_SGA = 0; ////大循环结束后,目标地址改变量。最好是4的整数倍,等于上面
//UART情况 地址不变
DMA0->TCD[DMA_CHANNEL_in_GROUP1].SOFF = 1; //读取一次地址后,偏移量,与DMA_ATTR_SSIZE有关?
DMA0->TCD[DMA_CHANNEL_in_GROUP1].DOFF = 0; //写一次地址后, 偏移量,与DMA_ATTR_DSIZE有关?
DMA0->TCD[DMA_CHANNEL_in_GROUP1].ATTR = (
DMA_ATTR_SSIZE(0)
| DMA_ATTR_DSIZE(0)
| DMA_ATTR_SMOD(0) //Source address modulo feature is disabled
| DMA_ATTR_DMOD(0)
|0
);
DMA0->TCD[DMA_CHANNEL_in_GROUP1].CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(default_minor_loop_counter);//minor loop小循环计数
DMA0->TCD[DMA_CHANNEL_in_GROUP1].BITER_ELINKNO = DMA_BITER_ELINKNO_BITER(default_minor_loop_counter);//需要与上面的值实质相等
DMA0->TCD[DMA_CHANNEL_in_GROUP1].CSR = 0;
DMA0->TCD[DMA_CHANNEL_in_GROUP1].CSR = (0
| DMA_CSR_BWC(3)//带宽控制,每读一次,eDMA 引擎停止 8 个周期
//DMA冷却时间(0不停止;1保留;2停止4周期;3停止8周期)
//取消注释,解除反复发送 // | DMA_CSR_DREQ_MASK //主循环结束后停止硬件请求 /* major_loop递减为0时自动关闭DMA,即只进行一次DMA传输 */
| DMA_CSR_INTMAJOR_MASK //主循环结束后产生中断
);
//DMA0->CR &= ~DMA_CR_EMLM_MASK;//Minor Loop Mapping Disabled.//default disabled already
// DMA0->TCD[DMA_CHANNEL_in_GROUP1].CSR |= DMA_CSR_START(1);
DMA0->ERQ &=~ (DMA_ERQ_ERQ0_MASK<<( DMA_CHANNEL_in_GROUP1 ));
uint8 test = DMA0->DCHPRI16;
}
/*
*说明:开始循环传输,开始之后不用管。。
*传输size个字节
*地址为上面的sendbuff[1024]
*/
void uart_dma_start_Nostop(uint32 size)
{
DMA0->TCD[DMA_CHANNEL_in_GROUP1].CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(size);//minor loop小循环计数
DMA0->TCD[DMA_CHANNEL_in_GROUP1].BITER_ELINKNO = DMA_BITER_ELINKNO_BITER(size);//需要与上面的值实质相等
DMA0->TCD[DMA_CHANNEL_in_GROUP1].SLAST= - size; ////大循环结束后,源地址改变量
DMA0-> ERQ |= (1 << DMA_CHANNEL_in_GROUP1); //开始循环传输
}
/*
*说明:开始循环传输,开始之后不用管。。
*传输size个字节
*传输某地址开始的size个字节
*/
void uart_dma_start_Nostop_plus_BuffAddress(void *t,uint32 size)
{
DMA0->TCD[DMA_CHANNEL_in_GROUP1].SADDR =(uint32)t;
DMA0->TCD[DMA_CHANNEL_in_GROUP1].CITER_ELINKNO = DMA_CITER_ELINKNO_CITER(size);//minor loop小循环计数
DMA0->TCD[DMA_CHANNEL_in_GROUP1].BITER_ELINKNO = DMA_BITER_ELINKNO_BITER(size);//需要与上面的值实质相等
DMA0->TCD[DMA_CHANNEL_in_GROUP1].SLAST= - size; ////大循环结束后,源地址改变量
DMA0-> ERQ |= (1 << DMA_CHANNEL_in_GROUP1); //开始循环传输
}
void uart_dma_stop()
{
DMA0->ERQ &=~ (DMA_ERQ_ERQ0_MASK<<( DMA_CHANNEL_in_GROUP1 ));
}
补充内容 (2018-7-18 23:30):
66 |
|