This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DMA发送,出现异常情况



//我用的是Cortex-M4 的Tiva.c launchpad 开发板,我想做的是,用UART0 DMA方式发送字符串,但是接收不用DMA方式,直接用UART0的RX。现在遇到的异常情况是,我在调用DMA的发送函数的时候,有部分字符串会出现乱码,而且同一个字符串,在不同的地方调用DMA发送函数,出现的结果也不相同。

//这是UAR0初始化函数
void InitUART(void)
{
//
// Enable the peripherals.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);

//
// Enable processor interruputs.
//
IntMasterEnable();

//
// Set GPIO A0 and A1 as UART pins.
//
GPIOPinConfigure(GPIO_PA0_U0RX);
GPIOPinConfigure(GPIO_PA1_U0TX);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);

//
// Configure the UART for 9,600
//
//UARTConfigSetExpClk(UART0_BASE,SysCtlClockGet(),

UARTConfigSetExpClk(UART0_BASE,16000000,
115200,(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE));

//
// Enable the UART interrupt.
//
IntEnable(INT_UART0);

//UARTIntEnable(UART0_BASE,UART_INT_RX | UART_INT_RT);

// UARTFIFODisable(UART0_BASE);
// UARTFIFOLevelSet(UART0_BASE,UART_FIFO_TX1_8,UART_FIFO_RX7_8);
//UARTIntEnable(UART0_BASE, UART_INT_RX);
//UARTIntRegister(UART0_BASE, UART0IntHandler);
//UARTDMAEnable(UART0_BASE,UART_DMA_RX );


GPIODirModeSet(GPIO_PORTA_BASE, GPIO_PIN_0|GPIO_PIN_1, GPIO_DIR_MODE_HW);

//UARTIntRegister(UART0_BASE, UARTRXIntHandler);
//UARTIntRegister(UART0_BASE, uDMAUART0IntHandler);
UARTDMAEnable(UART0_BASE,UART_DMA_TX );
}

//这是DMA初始化函数

void InitDMAUART0(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
uDMAEnable();
uDMAControlBaseSet(ucDMAControlTable);

uDMAChannelAttributeDisable(UDMA_CHANNEL_UART0TX,UDMA_ATTR_ALL);//DMA UART TX
uDMAChannelControlSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 |UDMA_DST_INC_NONE | UDMA_ARB_8);
/*
uDMAChannelAttributeDisable(UDMA_CHANNEL_UART0RX,UDMA_ATTR_ALL);//DMA UART Rx
uDMAChannelControlSet(UDMA_CHANNEL_UART0RX | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE |UDMA_DST_INC_8 | UDMA_ARB_8);
*/
uDMAChannelTransferSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, (void*)DMATxBuff,
(void*)DMARxBuff,
DMAUARTRevCn);
uDMAChannelEnable(UDMA_CHANNEL_UART0TX);
/*
uDMAChannelAttributeDisable(UDMA_CHANNEL_SW,UDMA_ATTR_ALL);//DMA UART SW
uDMAChannelControlSet(UDMA_CHANNEL_SW | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 |UDMA_DST_INC_8 | UDMA_ARB_8);
*/
}

//这是DMA的发送函数


void DMAUART0SendDat(void *dat,uint32_t Lenth)
{

uDMAChannelDisable(UDMA_CHANNEL_UART0TX);
uDMAChannelTransferSet(UDMA_CHANNEL_UART0TX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC,(void *)dat ,
(void *)(UART0_BASE + UART_O_DR),
Lenth);
uDMAChannelEnable(UDMA_CHANNEL_UART0TX);
}

  • Hi xian,

       能具体描述一下,发送的数据是什么样的,出现错误是什么样的字符,能截个图吗?另外你说放在不同的地方,出现的错误不一样,能在详细一点吗?

    谢谢

    ken

  • Hi,ken

    下面是我发送的3个字符串数组

    static uint8_t MODULE_SET[5]={'A','T','E','0','\r'};

    static uint8_t SEND_TCP_SHUT[11]={'A','T','+','C','I','P','S','H','U','T','\r'};

    static uint8_t SEND_TCP_CLOSE[12]={'A','T','+','C','I','P','C','L','O','S','E','\r'};

    DMAUART0SendDat(MODULE_SET, 5);

    DMAUART0SendDat(SEND_TCP_SHUT,11);

    DMAUART0SendDat(SEND_TCP_CLOSE,12);

    接收到的字符分别为

    ATEO

    AT+CIPSH

    (第三个字符串 就全是乱码)

    十六进制显示为:

    41 54 45 30 0D

    41 54 2B 43 49 50 53 48 92 00 00

    00 C0 00 40 B1 C0 40 C0 4F 53 45 0D

    我在main()函数中调用DMAUART0SendDat()函数进行DMA方式发送这三个字符串的时候,就是显示的正确的结果。但是我在我建立的另外一个.c文件里的一个函数void CellModule_ATE0_SET(void)中发送这三个字符串的时候,就会出现上面我说的错误情况。

    谢谢!

    xiang

  • Hi ken,

        下面是我main函数中的while loop,DMA的发送函数就是在这个里面的CellModule_ATE0_SET();中调用(在上面的程序中有详细的内容)。如果我将switch、case语句加上之后,用DMA发送字符串就会产生异常,如果将switch,case语句去掉,紧紧单独调用CellModule_ATE0_SET();这个函数,就会是正常。ken,你知道这是为什么吗??

    谢谢!

    xiang

    while(!(CellModule_GetStates()==CELL_MODULE_NEXTSEND))
    {

    uint8_t cell_task_state;
    cell_task_state = CellModule_GetStates();
    switch (cell_task_state)
    {
    case (CELL_MODULE_PWROFF):
    {
    CellModule_Open();
    break;
    }
    case (CELL_MODULE_ATstart):
    {
    CellModule_ATE0_SET();
    break;
    }