• 沒有找到結果。

基于构件的带DMA的UART编程实例

2.DMA重启序列

4.8 基于构件的带DMA的UART编程实例

在本章的 4.4 节已经详细介绍了基于构件的 UART 编程实例,本节主要在 4.4 节的基 础上介绍带 DMA 的 UART 编程实例。带 DMA 的 UART 具有接收和发送初始化、启动 DMA 接收和发送以及重新启动 DMA 接收这五种基本操作。按照构件化的思想,可将它 们封装成五个独立的功能函数,初始化过程主要完成 DMA 通道供给 UART 模块的发送器 和接收器使用的一些相关设置,启动 DMA 接收和发送功能函数则完成利用 DMA 进行数 据传输需要的一些规则,重新启动 DMA 接收功能函数则完成对 DMA 数据接收规则的重 新设置。

4.8.1 DMA构件的函数原型设计

参照本章 4.8 节对 DMA 初始化、DMA 启动序列和 DMA 重新启动的描述,本章的编 程实例设计了 5 个基本的功能函数,以下是各功能函数的原型设计:

(1)DMA 发送和接收初始化

void DmaUartTxInit(uint8 dmaCh,uint8 reqNo,uint8 enInt) void DmaUartRxInit(uint8 dmaCh,uint8 reqNo,uint8 enInt)

(2)DMA 发送和接收启动序列

void DmaUartTxStrt(uint8 dmaCh,uint8 reqNo,uint8* seBuff,uint16 buffSize) void DmaUartRxStrt(uint8 dmaCh,uint8 reqNo,uint8* reBuff,uint16 buffSize)

(3)DMA 接收重新启动序列

void DmaUartRxNext(uint8 dmaCh,uint8 reqNo,uint8* reBuff,uint16 buffSize)

4.8.2 DMA构件的头文件

与使用 DMA 功能的 UART 通信子函数相关的文件有头文件 DMA.h 和 DMA.c。

头文件 DMA.h 中的内容可分为两个主要的部分,它们分别是 5 个函数原型的声明和 外设模块寄存器相关信息的定义。前者给出了使用 DMA 的 UART 构件对上层构件或软件 所提供的接口函数,而后者则指明了本“元构件”与具体硬件相关的信息。

DMA.h 中含有相关的 DMA 寄存器和标志位定义,以及使用 DMA 功能的 UART 需 要配置的相关函数声明。以初始化接收函数 DmaUartRxInit为例,要设置的 DMA 通道号、

UART 接收器的编号、初始化时是否开启某些中断,都被设计为函数参数。这样的话,应 用程序和上层构件在使用(调用)它时,将具有极大的灵活性。文件还给出了必要的硬件 相关信息,当要把该构件移植到其他芯片时,就必须检查并修改这些信息。

第 4 章 异步串行通信与直接存储器访问 DMA extern uint8 __IPSBAR[]; //引用外部标号 //2.外用通信函数声明 //实 例: DmaUartRxInit(0,0,0)表示将UART0接收器连接到DMA0通道,且初始禁中断 * //说 明: 参数不能越界 * //---*

void DmaUartRxInit(uint8 dmaCh,uint8 reqNo,uint8 enInt);

//---* //实 例: DmaUartRxStrt(0,0,(uint8 *)reRingBuff,10)表示将UART0接收器连接到 * // DMA0通道且把接收到的10个数据传送到目的地址为reRingBuff的内存区域 * //说 明: 参数不能越界 * //---*

void DmaUartRxStrt(uint8 dmaCh,uint8 reqNo,uint8* reBuff,uint16 buffSize);

//---* //实 例: DmaUartRxNext(0,0,(uint8 *)reRingBuff,10)表示将UART0接收器连接到 * // DMA0通道,且把接收到的10个数据传送到目的地址为reRingBuff的内存区域*

// 中 * //说 明: 参数不能越界 * //---*

void DmaUartRxNext(uint8 dmaCh,uint8 reqNo,uint8* reBuff,uint16 buffSize);

//---*

103 //实 例: DmaUartRxInit(0,0,0)表示将UART0接收器连接到DMA0通道且初始时禁中断*

//说 明: 参数不能越界 * //---*

void DmaUartTxInit(uint8 dmaCh,uint8 reqNo,uint8 enInt);

//---* //实 例: DmaUartTxStrt(0,0,(uint8*)reRingBuff,10) 表示将UART0发送器连接到 * // DMA0通道且从首地址为reRingBuff的内存区写10个数据到发送缓冲寄存器 * //说 明: 参数不能越界 * //---*

void DmaUartTxStrt(uint8 dmaCh,uint8 reqNo,uint8* seBuff,uint16 buffSize);

//---*

#define MCF_INTC_MASK(x) (0x0200<<(x)) //DMA中断源(9-12)掩码

#define MCF_INTC_ICR_IL(x) (((x)&0x07)<<3) //中断级别掩码

#define MCF_INTC_ICR_IP(x) (((x)&0x07)<<0) //中断优先级掩码

#define MCF_DMA_DSR_DONE (0x01) //DSR清零掩码

#define MCF_DMA_DCR_BWC(x) (((x)&0x7)<<0x19)//DCR传输块的字节数掩码

#define MCF_DMA_DCR_AA (0x10000000) //DCR自动对齐掩码

#define MCF_DMA_DCR_CS (0x20000000) //DCR允许周期挪用掩码

第 4 章 异步串行通信与直接存储器访问 DMA

#define MCF_SCM_MPR (*(vuint8 *)(&__IPSBAR[0x20])) //DMA请求控制寄存器

#define MCF_SCM_DMAREQC (*(vuint32*)(&__IPSBAR[0x14])) //UART中断状态/掩码寄存器

#define MCF_UART_UIMR(x) (*(vuint8 *)(&__IPSBAR[0x000214+((x)*0x040)])) //中断控制寄存器

#define MCF_INTC0_ICR(x) (*(vuint8 *)(&__IPSBAR[0x000C49+(x)])) //中断屏蔽寄存器

#define MCF_INTC0_IMRL (*(vuint32*)(&__IPSBAR[0x000C0C])) //UART接收数据寄存器

#define MCF_DMA_URB(x) (*(vuint8 *)(&__IPSBAR[0x20C+((x)*0x040)])) //UART发送接收数据寄存器

#define MCF_DMA_UTB(x) (*(vuint8 *)(&__IPSBAR[0x20C+((x)*0x040)])) //DMA源地址寄存器

#define MCF_DMA_SAR(x) (*(vuint32*)(&__IPSBAR[0x100 + ((x)*0x10)])) //DMA目的地址寄存器

#define MCF_DMA_DAR(x) (*(vuint32*)(&__IPSBAR[0x104 + ((x)*0x10)])) //DMA状态寄存器

#define MCF_DMA_DSR(x) (*(vuint8 *)(&__IPSBAR[0x108 + ((x)*0x10)])) //DMA字节计数寄存器

#define MCF_DMA_BCR(x) (*(vuint32*)(&__IPSBAR[0x108 + ((x)*0x10)])) //DMA控制寄存器

#define MCF_DMA_DCR(x) (*(vuint32*)(&__IPSBAR[0x10C + ((x)*0x10)]))

#endif //实 例: DmaUartRxInit(0,0,0)表示将UART0接收器连接到DMA0通道且初始时禁中断*

//说 明: 参数不能越界 * //---*

void DmaUartTxInit(uint8 dmaCh,uint8 reqNo,uint8 enInt) {

//1.使能DMA控制器

105 MCF_SCM_MPR |= 0x04;

//2.在DMA请求控制寄存器中使用DMA(dmaCh)通道的UART(reqNo)发送器请求 MCF_SCM_DMAREQC |= MCF_SCM_DMAC(reqNo+0x0C)<<(dmaCh*4);

//3.设置UART中断屏蔽寄存器中的中断使能位 MCF_UART_UIMR(reqNo) = 0x02;

//4.设置DMA中断的级别和优先级(DMA通道(0-3)中断源是9-12) MCF_INTC0_ICR(dmaCh) = (MCF_INTC_ICR_IL(0x04) |

MCF_INTC_ICR_IP(0x03)); //实 例: DmaUartRxInit(0,0,0)表示将UART0接收器连接到DMA0通道,且初始禁中断 * //说 明: 参数不能越界 * //---*

void DmaUartRxInit(uint8 dmaCh,uint8 reqNo,uint8 enInt) {

//1.使能DMA控制器 MCF_SCM_MPR |= 0x04;

//2.在DMA请求控制寄存器中使用DMA(dmaCh)通道的UART(reqNo)接收器请求 MCF_SCM_DMAREQC |= MCF_SCM_DMAC(reqNo+0x08)<<(dmaCh*4);

//3.设置UART中断屏蔽寄存器中的中断使能位 MCF_UART_UIMR(reqNo) = 0x02;

//4.设置DMA中断的级别和优先级(DMA通道(0-3)中断源是9-12) MCF_INTC0_ICR(dmaCh) = (MCF_INTC_ICR_IL(0x04) |

MCF_INTC_ICR_IP(0x03));

第 4 章 异步串行通信与直接存储器访问 DMA //实 例: DmaUartTxStrt(0,0,(uint8*)reRingBuff,10) 表示将UART0发送器连接到 * // DMA0通道且从首地址为reRingBuff的内存区写10个数据到发送缓冲寄存器 * //说 明: 参数不能越界 * //---*

void DmaUartTxStrt(uint8 dmaCh,uint8 reqNo,uint8* seBuff,uint16 buffSize) {

//1.对DMA状态寄存器DSR清零

MCF_DMA_DSR(dmaCh) = MCF_DMA_DSR_DONE;

//2.设置源地址为seBuff

MCF_DMA_SAR(dmaCh) = (unsigned long) seBuff;

//3.设置目的地址为发送缓冲区的地址

MCF_DMA_DAR(dmaCh) = (unsigned long) & MCF_DMA_UTB(reqNo);

//4.设置DMA的字节计数寄存器为buffSize MCF_DMA_BCR(dmaCh) = buffSize;

//5.设置DMA的控制寄存器: 允许外部请求、使能周期窃取、 //实 例: DmaUartRxStrt(0,0,(uint8 *)reRingBuff,10)表示将UART0接收器连接到 * // DMA0通道且把接收到的10个数据传送到目的地址为reRingBuff的内存区域 * //说 明: 参数不能越界 * //---*

void DmaUartRxStrt(uint8 dmaCh,uint8 reqNo,uint8* reBuff,uint16 buffSize)