这里以瑞萨单片机为例,吸收和发送均通过DMA实现,上实例代码,包括DMA和UART的配置以及详细的注释,用到同款单片机的朋友可以参考。
//DMA+USART的配置 250字节的定长发送和250字节的定长吸收

INT8U sciTxBuf[256];//定长发送缓冲数组,DMA吸收的目标地址
INT8U sciRxBuf[256];//定长吸收缓冲数组,DMA发送的源地址
void dmac0_init(void)//吸收DMA通道0
{
IEN(DMAC,DMAC0I) = 0; / 禁用DMAC0I中断要求 /
DMAC0.DMCNT.BIT.DTE = 0; / 禁用DMA0传送数据/
ICU.DMRSR0 = 219; / DMAC0的要求源: RXI1 ,(RXI中断向量号为219) /
DMAC0.DMAMD.BIT.DM = 2; / 目标地址更新办法:递增,值为10b /
DMAC0.DMAMD.BIT.SM = 0; / 源地址更新办法:固定,值为00b /
DMAC0.DMAMD.BIT.DARA = 0; / 目标地址扩展重复区域:不指定 /
DMAC0.DMAMD.BIT.SARA = 0; / 源地址扩展重复区域 :不指定/
DMAC0.DMTMD.BIT.DCTG = 1; / DMA 要求源: 外设中断 /
DMAC0.DMTMD.BIT.SZ = 0; / 数据传送长度: 8 bits /
DMAC0.DMTMD.BIT.MD = 0; / 传送模式: 正常传送 /
DMAC0.DMCSL.BIT.DISEL = 0; / 传送结束后,将启动源的中断标志清0 /
DMAC0.DMSAR = (void )&SCI1.RDR; / 源地址: SCI1.RDR register /
DMAC0.DMDAR = (void )sciRxBuf; / 目标地址: 吸收缓存 /
DMAC0.DMCRA = 250; / DMCRA.DMCRAL = 0, 指定传送个数 1024/
/ DMCRA.DMCRAH = 0, 指定备份传送个数1024 /
IPR(DMAC,DMAC0I) = 10; / DMAC0I中断优先级: Level 12 /
DMAC0.DMINT.BIT.DTIE = 1; / 许可传送结束中断要求 /
IEN(DMAC,DMAC0I) = 1; / 许可DMAC0I的中断要求 /
DMAC0.DMCNT.BIT.DTE = 1; / 许可DMA传送数据 /
}
void dmac1_init(void)//发送DMA通道1
{
IEN(DMAC,DMAC1I) = 0; / 禁用DMAC1I的中断要求 /
DMAC1.DMCNT.BIT.DTE = 0; / 禁用DMA传送 /
ICU.DMRSR1 = 220; / DMAC1的要求源:TXI ,(TXI中断向量号为220)/
DMAC1.DMAMD.BIT.DM = 0; / 目标地址更新办法:固定 ,值为00b /
DMAC1.DMAMD.BIT.SM = 2; / 源地址更新办法:递增 , 值为10b /
DMAC1.DMAMD.BIT.DARA = 0; / 目标地址扩展重复区域:不指定 /
DMAC1.DMAMD.BIT.SARA = 0; / 源地址扩展重复区域 :不指定/
DMAC1.DMTMD.BIT.DCTG = 1; / DMA 要求源: 外设中断 /
DMAC1.DMTMD.BIT.SZ = 0; / 数据传送长度: 8 bits /
DMAC1.DMTMD.BIT.MD = 0; / 传送模式: 正常传送 /
DMAC1.DMCSL.BIT.DISEL = 0; / 传送结束后,将启动源的中断标志清0 /
DMAC1.DMSAR = (void )sciTxBuf; / 源地址: 传送缓存 /
DMAC1.DMDAR = (void )&SCI1.TDR; / 目标地址: SCI1.TDR 发送寄存器 /
DMAC1.DMCRA = 250; / 指定传送个数 /
IPR(DMAC,DMAC1I) = 10; / DMAC1I 中断优先级: Level 12 /
DMAC1.DMINT.BIT.DTIE = 1; / 许可传送结束中断要求 /
IEN(DMAC,DMAC1I) = 1; / 许可DMAC1I的中断要求 /
DMAC1.DMCNT.BIT.DTE = 0; / 许可DMA数据传送 /
}
void init_uart(void)
{
dmac0_init(); / 初始化DMAC0,用于串口SCI1吸收 /
dmac1_init(); / 初始化DMAC1,用于串口SCI1发送 /
SYSTEM.PRCR.WORD = 0xA502;
MSTP(SCI1) = 0;
SYSTEM.PRCR.WORD = 0xA500;
IEN(SCI1,ERI1) = 0; / 禁用SCI1.ERI1中断 /
IEN(SCI1,RXI1) = 0; / 禁用SCI1.RXI1中断 /
IEN(SCI1,TXI1) = 0; / 禁用SCI1.TXI1中断 /
IEN(SCI1,TEI1) = 0; / 禁用SCI1.TEI1中断 /
/SCI1 module stop state cancel/
SCI1.SCR.BYTE = 0x00; / 禁用发送和吸收 /
while (0x00 != (SCI1.SCR.BYTE & 0xF0)){}/ Confirm that bit is actually 0 /
/only RE/TE/RIE/TIE==0 can write register/
MPC.PWPR.BIT.B0WI = 0;
MPC.PWPR.BIT.PFSWE = 1;
MPC.P30PFS.BYTE = 0x0A;//RXD1
MPC.P26PFS.BYTE = 0x0A;//TXD1
MPC.PWPR.BIT.PFSWE = 0;
MPC.PWPR.BIT.B0WI = 1;
/MPC=RXD and TXD/
PORT3.PMR.BYTE |= 0x01U;//PORT3.PMR.BIT.B0 = 1;//串口管脚配置
/PMR=peripheral/
SCI1.SCR.BIT.CKE = 0; / 利用内部波特率发生器/
SCI1.SMR.BYTE = 0x20; / 时钟源:PCLK /
/ 1个停滞位,偶校验,数据位:8,异步通信 /
SCI1.SCMR.BYTE = 0xF2; / SCI1通信模式:串行通信 /
SCI1.SEMR.BIT.ABCS = 1; / ABCS值为0: 16个基本时钟为1bit的传送韶光 /
/ ABCS值为1: 8个基本时钟为1bit的传送韶光 /
SCI1.BRR = 0; / 波特率: 0->781250bps ,以是末了波特率是1.5M/
/interrupt priority/
IPR(SCI1, ) = 10;
IR(SCI1,RXI1) = 0;
IR(SCI1,TXI1) = 0;
IR(SCI1,ERI1) = 0;//
SCI1.SCR.BIT.RIE = 1;
SCI1.SCR.BIT.RE = 1;
IEN(SCI1,RXI1)=1;
IEN(SCI1,ERI1)=1;
DMAC.DMAST.BYTE = 0x01; / DMAC启动 /
}
void uart_send(INT8Updata,INT8U len)//DMA定长模式发送250字节
{
int i = 0;
if(len>=250)
{
return;//发送长度不对
}
for(i = 0; i < 250; i++)
{
if(i < len)
{
sciTxBuf[i] = pdata[i];
}
else
{
sciTxBuf[i] = 0x00;
}
}
DMAC1.DMCNT.BYTE = 0x00;
DMAC1.DMSAR = (void )sciTxBuf; / 源地址: 传送缓存 /
DMAC1.DMCRA = 250; / 指定传送个数,250字节 /
DMAC1.DMCNT.BYTE = 0x01;
PORT2.PMR.BIT.B6 = 1;
SCI1.SCR.BIT.TIE = 1;
SCI1.SCR.BIT.TE = 1;
IEN(SCI1,TXI1)=1;
}
void Excep_SCI1_ERI1(void)//串口吸收缺点中断
{
INT8U dummy;
dummy = SCI1.RDR;
dummy+=0;
init_uart_terminal();//重新配置串口
}
void Excep_DMAC_DMAC0I(void)// DMAC DMAC0I RCV
{
INT16U i;
for(i=0;i<250;i++)
{
message_buff[i]=sciRxBuf[i];// 吸收内容缓存到message_buff
}
dmac0_init();
}
void Excep_DMAC_DMAC1I(void)// DMAC1 SEND
{
IEN(SCI1,TXI1) = 0;
SCI1.SCR.BIT.TIE = 0;
while(0 != SCI1.SCR.BIT.TIE){}
IR(SCI1,TXI1) = 0;
while(0 == SCI1.SSR.BIT.TEND){}
SCI1.SCR.BIT.TE = 0;
}
这里有一个问题须要大家在利用的时候思考并办理,在通讯过程中因串口丢失数据会导致DMA吸收对不齐,也便是上一次的吸收和下一次的吸收内容会拼在仪器产生一个DMA吸收中断,且该次中断的数据无效,并且只要一涌现对不齐,如果不采纳方法的话,那么往后永久都对不齐了。这个问题大家自行办理,也可以在评论区分享自己的见地。







