|
DMA
- Direct Memory
Access(存储器直接访问)。是指一种高速的数据传输操作,允许在外部设备直接读写存储器,不需要CPU干预
CPU除了在数据传输开始和结束时做一点处理外,在传输过程中CPU可以进行其他的工作。
因此,使整个计算机系统的效率大大提高。
AT91SAM7S64中的外设数据控制器(PDC)其实就是这样的一个控制器,它提供了片内外设直接存取存储器的一种方法,使处理器的工作更加
有效率。
目前我有这样一个需求,从USART0口发送一组(frame)准备好的数据,而在发送期间CPU又要处理其它检测任务。传统的做法是使用中断
即发送一个字节产生一次中断,在中断处理程序中检测是否发送完成,如果没有发送完成则继续发后面的字节,直到全部发送完成。而在有PDC
的处理器AT91SAM7S64来讲,这是完全没有必要的,只要确定了要发送的数据那将它们交给PDC便万事OK。
理解PDC时应先有通道的概念,每一个有此功能的外设对应了PDC的两个通道,分别是发送和接收,而每一个通道都对应四个寄存器:
存储器指针寄存器
传输计数寄存器
下一个存储器指针寄存器
下一个传输计数寄存器
PDC根据存储器指针寄存器和传输计数寄存器控制外设的传输操作,每发送一字节存储器指针寄存器增一而传输计数寄存器减一,当
传输计数寄存器变0时如果下一个传输计数寄存器内容为0则停止传输,否则将下一个存储器指针寄存器和下一个传输计数寄存器的值载入
到存储指针寄存器和传输计数寄存器,并开始新的一次传输,同时将下一个存储器指针寄存器和下一个传输计数寄存器清0.
这些寄存器并没有在一个专门为PDC分配的空间内集中安排,而是分散在对应外设寄存器后偏移0x100地址处,以下代码实现了上面
所提到的需求:
#define BR 115200
/// Baud Rate
#define BRD (MCK/16/BR)
// Baud Rate Divisor
#define EXT_OC
18432000 // Exetrnal ocilator MAINCK
#define MCK
48054857 // MCK (PLLRC div by 2)
AT91S_USART *
pUSART = AT91C_BASE_US0;
void UartInit(void)
{
*AT91C_PMC_PCER =
(1 << AT91C_ID_US0); // Enable Clock for USART0
*AT91C_PIOA_PDR =
AT91C_PA5_RXD0 | //Enable RxD0 Pin
AT91C_PA6_TXD0; //Enalbe
TxD0 Pin
pUSART->US_CR =
AT91C_US_RSTRX | //Reset Receiver
AT91C_US_RSTTX |
//Reset Transmitter
AT91C_US_RXDIS |
//Receiver Disable
AT91C_US_TXDIS;
//Transmitter Disable
pUSART->US_MR =
AT91C_US_USMODE_NORMAL | // Normal Mode
AT91C_US_CLKS_CLOCK
| // Clock = MCK
AT91C_US_CHRL_8_BITS | // 8-bit Data
AT91C_US_PAR_NONE |
// No Parity
AT91C_US_NBSTOP_1_BIT; // 1 Stop Bit
pUSART->US_BRGR =
BRD; // Baud Rate Divisor
//设置PDC
pUSART->US_PTCR
= AT91C_PDC_TXTEN; //PDC 发送允许
pUSART->US_CR =
AT91C_US_RXEN | // Receiver Enable
AT91C_US_TXEN; //
Transmitter Enable
}
void
UartSendFrame(unsigned char *buf,unsigned int size)
{
pUSART->US_TPR=(unsigned
int )buf;
pUSART->US_TCR=size;
//设置传输计数寄存器触发传输
}
芯艺设计室(http://www.chipart.cn) 2010.09.02 转载请注明出处!
|