#include <stdint.h>
#include <stdio.h>
#include "stdio_dma.h"
#ifdef configDMA_STDIO_UART_TX
static int8_t dmaUartTxBuffer[configDMA_STDIO_UART_TX_SIZE];
__data static volatile uint8_t dmaUartTxHead = 0x00;
__data static volatile uint8_t dmaUartTxTail = 0x00;
static volatile __bit dmaUartTxBusy = 0;
void vInitalizeUart(void)
{
#if (configCPU_CLOCK_1T == 1)
AUXR |= 0x02; // 定时器时钟1T模式
const uint16_t uiTick = MCU_MAJOR_FOC / configUART_BAUDRATE / 4;
#else
AUXR &= 0xFB; // 定时器时钟12T模式
const uint16_t uiTick = MCU_MAJOR_FOC / configUART_BAUDRATE / 4 / 12;
#endif
const uint16_t uiInit = 0x10000 - uiTick;
TMR2 = uiInit;
S2CON = 0x10;
AUXR |= 0x10;
}
void prvDmaUartTxStart(void)
{
dmaUartTxBusy = 1;
uint16_t ptr = (uint16_t)&dmaUartTxBuffer[dmaUartTxHead];
DMA_UART_TX_TXAH = (uint8_t)(ptr >> 8);
DMA_UART_TX_TXAL = (uint8_t)(ptr & 0xff);
uint8_t len = 0;
if (dmaUartTxHead < dmaUartTxTail) {
len = dmaUartTxTail - dmaUartTxHead;
} else {
len = configDMA_STDIO_UART_TX_SIZE - dmaUartTxHead;
}
DMA_UART_TX_AMNT = len;
DMA_UART_TX_STAT = 0;
DMA_UART_TX_CONF = 0x8f;
DMA_UART_TX_CTRL = 0xC0;
EA = 1;
}
void vDmaUartTxISR(void) __interrupt(VECTOR_DMA_UART_TX)
{
P6 = 0xf0;
// 清除DMA_UART_TX中断标志
DMA_UART_TX_STAT = 0;
// 更新发送缓冲区头指针
dmaUartTxHead = dmaUartTxHead + DMA_UART_TX_DONE + 1;
dmaUartTxHead = dmaUartTxHead % configDMA_STDIO_UART_TX_SIZE;
// 清除自定义DMA繁忙标志
dmaUartTxBusy = 0;
// 如果还有数据待发送,则重新启动DMA传输
if (dmaUartTxHead != dmaUartTxTail) {
prvDmaUartTxStart();
}
}
int putchar(int ch)
{
// 等待DMA发送缓冲区有空间
uint8_t next;
do {
next = dmaUartTxTail + 1;
next = next % configDMA_STDIO_UART_TX_SIZE;
} while (next == dmaUartTxHead);
dmaUartTxBuffer[dmaUartTxTail] = ch;
dmaUartTxTail = next;
// 如果DMA传输未在进行中,则启动DMA传输
if (!dmaUartTxBusy) {
prvDmaUartTxStart();
}
return ch;
}
#endif // configSTDIO_UART_TX_DMA
如以上代码所示,我尝试在AI8H8K64U上使用DMA传输串口数据,但是串口助手中收到的数据如图所示:

经反复调试发现,是DMA发送中断中,DMA_UR2T_DONE
始终为0导致。换了其它几个串口也是一样的效果……
现在求教大家,所有示例中似乎都没找到 DMA_UR2T_DONE
用法,是我 DMA_UR2T_DONE
使用姿势不太对吗?
(为了切换串口方便,我重新定义了XSFR)
附件:stdio_dma.h
附件:stdio_dma.c