LM3S9b96 uart DMA 在uCosii下 问题



根据官方给的例程,代码全都没变,仅仅是吧,启动数据发送从中断中移到线程中,但发送的数据总是错误,各种办法试了都没有解决,把代码简略贴出来,那位大神帮忙看看。

首先是:dma初始化,uart初始化,串口中断,启动数据发送四个函数

unsigned char g_ch232SendReady=0;  判断DMA是否发送成功的标志

//---------------------------------------------------------------------------------------------
//功 能:DMA初始化
//输入参数:无
//输出参数:无
//---------------------------------------------------------------------------------------------
void DMA_Init(void)
{

//
// Enable the uDMA controller at the system level. Enable it to continue
// to run while the processor is in sleep.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);
//
// Enable the uDMA controller error interrupt. This interrupt will occur
// if there is a bus error during a transfer.
//
IntEnable(INT_UDMAERR);

//
// Enable the uDMA controller.
//
uDMAEnable();
//
// Point at the control table to use for channel control structures.
//
uDMAControlBaseSet(ucControlTable);

}

//---------------------------------------------------------------------------------------------
//功 能:RS232通信初始化
//输入参数:无
//输出参数:无
//---------------------------------------------------------------------------------------------
void Uart1_Init(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1); // 使能UART模块
SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART1); //休眠时启用uart1


GPIOPinTypeUART(GPIO_PORTD_BASE, // 配置RX/TX所在管脚为
GPIO_PIN_0 | GPIO_PIN_1); // UART收发功能

GPIOPinConfigure(GPIO_PD0_U1RX);
GPIOPinConfigure(GPIO_PD1_U1TX);

UARTConfigSet(UART1_BASE, // 配置UART端口
19200, // 波特率:9600
UART_CONFIG_WLEN_8 | // 数据位:8
UART_CONFIG_STOP_ONE | // 停止位:1
UART_CONFIG_PAR_NONE); // 校验位:无
UARTFIFOLevelSet(UART1_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);

IntEnable(INT_UART1);
UARTEnable(UART1_BASE);
UARTDMAEnable(UART1_BASE, UART_DMA_TX);
UARTIntEnable(UART1_BASE, UART_INT_RX|UART_INT_RT); // 接收中断和接收超时中断

uDMAChannelAttributeDisable(UDMA_CHANNEL_UART1TX,
UDMA_ATTR_ALTSELECT |
UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);


uDMAChannelAttributeEnable(UDMA_CHANNEL_UART1TX, UDMA_ATTR_USEBURST);


uDMAChannelControlSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE |
UDMA_ARB_4);
}

//---------------------------------------------------------------------------------------------
//功 能:串口1 DMA方式发送
//输入参数:无
//输出参数:是否成功启动发送, 1 成功 0 失败
//---------------------------------------------------------------------------------------------
int Uart1DMASendStr(char *pBuf,unsigned int nNum)
{

 if(!uDMAChannelIsEnabled(UDMA_CHANNEL_UART1TX))
{
g_ch232SendReady=0;

uDMAChannelTransferSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, pBuf,
(void *)(UART1_BASE + UART_O_DR),
nNum);

uDMAChannelEnable(UDMA_CHANNEL_UART1TX);
return 1;
}
else
return 0;
}

//---------------------------------------------------------------------------------------------
// 功 能:串口1中断
// 入口参数:无
// 出口参数:无
//---------------------------------------------------------------------------------------------
void UART1_ISR(void)
{
unsigned long ulStatus;

ulStatus = UARTIntStatus(UART1_BASE, true); // 读取中断状态
UARTIntClear(UART1_BASE, ulStatus); // 清除中断状态

if ((ulStatus & UART_INT_RX) || (ulStatus & UART_INT_RT))
{
while (UARTCharsAvail(UART1_BASE))
{
if (BTRec.chWriteIndex == UARTBUFFSIZE)
BTRec.chWriteIndex = 0;
BTRec.chBuff[BTRec.chWriteIndex] = UARTCharGetNonBlocking(UART1_BASE);
BTRec.chWriteIndex++;
if (++BTRec.chCount == UARTBUFFSIZE)
{
BTRec.chReadIndex=BTRec.chWriteIndex;
BTRec.chOverFlag = 1;
BTRec.chCount = UARTBUFFSIZE;
}
}
}

if(!uDMAChannelIsEnabled(UDMA_CHANNEL_UART1TX))
{
g_ch232SendReady=1;

}
}

这个是的所有外设的初始化函数,不知道对初始化顺序会不会对dma有影响,先贴出来。

void BSP_PreInit (void)
{

Port_Init();
GPRS_LED_OFF;
BD_LED_OFF;
ETH_LED_OFF;
DMA_Init();
I2c0_Init(); //EEPROM接口(基于AT24C256(32KBYTE),A1,A0接地)
Uart0_Init(); //UART0初始化,串口转以太网
Uart1_Init(); //UART1初始化,RS232--参数配置功能
Uart2_Init(); //UART2初始化,RS485--室外板,北斗模块

RS485SendDisable();
InitQueue(&OutDataQue); //初始化室外板缓存队列
InitQueue(&ETHDataQue); //初始化FTU数据缓存队列
InitQueue(&ConfDataQue);//初始化232接口缓存队列
EEPROM_Write(EEPROM_ADDR_WRITE,(const unsigned char*)&EepromDefaultData,sizeof(EepromDefaultData));
EEPROM_Read(EEPROM_ADDR_READ,(unsigned char*)&EepromSaveData,sizeof(EepromSaveData));

//Timer1_Init();

}

下面这个是串口数据处理的进程函数。首先判定发送队列里是否有数据需要发送,如果有就取出来然后发送出去,如果没有就等待10ms。

这个任务优先级排第三,前面还有2个进程进程在运行,一个代码很少运行很快,也是延时10ms,另一个大概1s运行一次,每次运行时间不到10ms的样子。

//---------------------------------------------------------------------------------------------
//功 能:串口数据发送任务
//输入参数:无
//输出参数:无
//---------------------------------------------------------------------------------------------

void App_UartDataSend(void *p_arg)
{

static SBEvent_T EventTemp;
while (1)
{
CPU_SR_ALLOC();
CPU_CRITICAL_ENTER();
if(g_ch232SendReady==1)
{

if (!IsQueueEmpty(ConfDataQue))
{

OutQueue(&ConfDataQue, &EventTemp);
Uart1DMASendStr( EventTemp.pPayload, ,EventTemp.pPayloadlen);
}
}
CPU_CRITICAL_EXIT();

OSTimeDlyHMSM(0,0,0,10);

}
}

大神们看看,到底是哪里错了呢为什么发送的数据总是错的。

  • void Uart1_Init(void)

    {

    SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1); // 使能UART模块

    SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART1); //休眠时启用uart1

    GPIOPinTypeUART(GPIO_PORTD_BASE, // 配置RX/TX所在管脚为

    GPIO_PIN_0 | GPIO_PIN_1); // UART收发功能

    GPIOPinConfigure(GPIO_PD0_U1RX);

    GPIOPinConfigure(GPIO_PD1_U1TX);

    UARTConfigSet(UART1_BASE, // 配置UART端口

    19200, // 波特率:9600

    UART_CONFIG_WLEN_8 | // 数据位:8

    UART_CONFIG_STOP_ONE | // 停止位:1

    UART_CONFIG_PAR_NONE); // 校验位:无

    UARTFIFOLevelSet(UART1_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);

    IntEnable(INT_UART1);

    UARTEnable(UART1_BASE);

    UARTDMAEnable(UART1_BASE, UART_DMA_TX);

    UARTIntEnable(UART1_BASE, UART_INT_RX|UART_INT_RT); // 接收中断和接收超时中断

    uDMAChannelAttributeDisable(UDMA_CHANNEL_UART1TX,

    UDMA_ATTR_ALTSELECT |

    UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);

    uDMAChannelControlSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT,

    UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE |

    UDMA_ARB_4);

    uDMAChannelAttributeEnable(UDMA_CHANNEL_UART1TX, UDMA_ATTR_USEBURST);