TI中文支持网
TI专业的中文技术问题搜集分享网站

EK-TM4C123GXL uDMA pingpong模式

请教个问题》》。 

      我用tiva板的uDMA的pingpong模式从串口接收数据 ,当用USB转串口通过电脑模拟发送数据是可以一直接收(每次发送18个字节数据  发送间隔时间较长)。但是接收机跟tiva板发送数据时只能接收两次 ,就不进中断了(接收机会每隔 7ms 通过 串口 发送一帧数据(18 字节) )。

      再后来我用串口助手的自动发送功能模拟,7ms发送一帧数据。接收成功的次数比接收机多很多,但还是会卡死(进不了中断)。

代码如下:

      中断:

void
UART1IntHandler(void)
{
uint32_t ui32Status;
uint32_t ui32Mode;
ui32Status = ROM_UARTIntStatus(UART1_BASE, 1);
ROM_UARTIntClear(UART1_BASE, ui32Status);
ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT); //主结构体
if(ui32Mode == UDMA_MODE_STOP)
{
g_ui32RxBufACount++;
ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT,
UDMA_MODE_PINGPONG,
(void *)(UART1_BASE + UART_O_DR),
g_ui8RxBufA, sizeof(g_ui8RxBufA));
RC_Ctl.rc.ch0 = (g_ui8RxBufA[0]| (g_ui8RxBufA[1] << 8)) & 0x07ff; //!< Channel 0
RC_Ctl.rc.ch1 = ((g_ui8RxBufA[1] >> 3) | (g_ui8RxBufA[2] << 5)) & 0x07ff; //!< Channel 1
RC_Ctl.rc.ch2 = ((g_ui8RxBufA[2] >> 6) | (g_ui8RxBufA[3] << 2) | (g_ui8RxBufA[4] << 10)) & 0x07ff; //!< Channel 2
RC_Ctl.rc.ch3 = ((g_ui8RxBufA[4] >> 1) | (g_ui8RxBufA[5] << 7)) & 0x07ff; //!< Channel 3
RC_Ctl.rc.s1 = ((g_ui8RxBufA[5] >> 4)& 0x000C) >> 2; //!< Switch left
RC_Ctl.rc.s2 = ((g_ui8RxBufA[5] >> 4)& 0x0003); //!< Switch right
RC_Ctl.mouse.x = g_ui8RxBufA[6] | (g_ui8RxBufA[7] << 8); //!< Mouse X axis
RC_Ctl.mouse.y = g_ui8RxBufA[8] | (g_ui8RxBufA[9] << 8); //!< Mouse Y axis
RC_Ctl.mouse.z = g_ui8RxBufA[10] | (g_ui8RxBufA[11] << 8); //!< Mouse Z axis
RC_Ctl.mouse.press_l = g_ui8RxBufA[12]; //!< Mouse Left Is Press ?
RC_Ctl.mouse.press_r = g_ui8RxBufA[13]; //!< Mouse Right Is Press ?
RC_Ctl.key.v = g_ui8RxBufA[14] | (g_ui8RxBufA[15] << 8); //!< KeyBoard value
}
ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT);
if(ui32Mode == UDMA_MODE_STOP)
{
g_ui32RxBufBCount++;
ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT,
UDMA_MODE_PINGPONG,
(void *)(UART1_BASE + UART_O_DR),
g_ui8RxBufB, sizeof(g_ui8RxBufB));
RC_Ctl.rc.ch0 = (g_ui8RxBufB[0]| (g_ui8RxBufB[1] << 8)) & 0x07ff; //!< Channel 0
RC_Ctl.rc.ch1 = ((g_ui8RxBufB[1] >> 3) | (g_ui8RxBufB[2] << 5)) & 0x07ff; //!< Channel 1
RC_Ctl.rc.ch2 = ((g_ui8RxBufB[2] >> 6) | (g_ui8RxBufB[3] << 2) | (g_ui8RxBufB[4] << 10)) & 0x07ff; //!< Channel 2
RC_Ctl.rc.ch3 = ((g_ui8RxBufB[4] >> 1) | (g_ui8RxBufB[5] << 7)) & 0x07ff; //!< Channel 3
RC_Ctl.rc.s1 = ((g_ui8RxBufB[5] >> 4)& 0x000C) >> 2; //!< Switch left
RC_Ctl.rc.s2 = ((g_ui8RxBufB[5] >> 4)& 0x0003); //!< Switch right
RC_Ctl.mouse.x = g_ui8RxBufB[6] | (g_ui8RxBufB[7] << 8); //!< Mouse X axis
RC_Ctl.mouse.y = g_ui8RxBufB[8] | (g_ui8RxBufB[9] << 8); //!< Mouse Y axis
RC_Ctl.mouse.z = g_ui8RxBufB[10] | (g_ui8RxBufB[11] << 8); //!< Mouse Z axis
RC_Ctl.mouse.press_l = g_ui8RxBufB[12]; //!< Mouse Left Is Press ?
RC_Ctl.mouse.press_r = g_ui8RxBufB[13]; //!< Mouse Right Is Press ?
RC_Ctl.key.v = g_ui8RxBufB[14] | (g_ui8RxBufB[15] << 8); //!< KeyBoard value
}
UARTprintf("RC_Ctl.rc.ch0 = %6d\n", RC_Ctl.rc.ch0);
UARTprintf("RC_Ctl.rc.ch1 = %6d\n", RC_Ctl.rc.ch1);
UARTprintf("RC_Ctl.rc.ch2 = %6d\n", RC_Ctl.rc.ch2);
UARTprintf("RC_Ctl.rc.ch3 = %6d\n", RC_Ctl.rc.ch3);
UARTprintf("RC_Ctl.rc.s1 = %6d\n", RC_Ctl.rc.s1);
UARTprintf("RC_Ctl.rc.s2 = %6d\n", RC_Ctl.rc.s2);
UARTprintf("RC_Ctl.mouse.x = %6d\n", RC_Ctl.mouse.x);
UARTprintf("RC_Ctl.mouse.y = %6d\n", RC_Ctl.mouse.y);
UARTprintf("RC_Ctl.mouse.z = %6d\n", RC_Ctl.mouse.z);
UARTprintf("RC_Ctl.mouse.press_l = %6d\n", RC_Ctl.mouse.press_l);
UARTprintf("RC_Ctl.mouse.press_r = %6d\n", RC_Ctl.mouse.press_r);
UARTprintf("RC_Ctl.key.v = %6d\n", RC_Ctl.key.v);
}

通道配置:

void
InitUART1Transfer(void)
{
//
// Enable the UART peripheral, and configure it to operate even if the CPU
// is in sleep.
//
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART1);

//
// Configure the UART communication parameters.
//
ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
GPIOPinConfigure(GPIO_PB0_U1RX);
GPIOPinConfigure(GPIO_PB1_U1TX);
ROM_GPIOPinTypeUART(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
/*ROM_UARTConfigSetExpClk(UART1_BASE, ROM_SysCtlClockGet(), 100000,
UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_EVEN);*/
ROM_UARTConfigSetExpClk(UART1_BASE, ROM_SysCtlClockGet(), 115200,
UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE);

//
// Set both the TX and RX trigger thresholds to 4. This will be used by
// the uDMA controller to signal when more data should be transferred. The
// uDMA TX and RX channels will be configured so that it can transfer 4
// bytes in a burst when the UART is ready to transfer more data.
//
ROM_UARTFIFOLevelSet(UART1_BASE, UART_FIFO_TX2_8, UART_FIFO_RX2_8);

//
// Enable the UART for operation, and enable the uDMA interface for both TX
// and RX channels.
//
ROM_UARTEnable(UART1_BASE);
ROM_UARTDMAEnable(UART1_BASE, UART_DMA_RX);

//
// Enable the UART peripheral interrupts. Note that no UART interrupts
// were enabled, but the uDMA controller will cause an interrupt on the
// UART interrupt signal when a uDMA transfer is complete.
//
ROM_IntEnable(INT_UART1);

//
// Put the attributes in a known state for the uDMA UART1RX channel. These
// should already be disabled by default.
//
ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_UART1RX,
UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
UDMA_ATTR_HIGH_PRIORITY |
UDMA_ATTR_REQMASK);

//
// Configure the control parameters for the primary control structure for
// the UART RX channel. The primary contol structure is used for the "A"
// part of the ping-pong receive. The transfer data size is 8 bits, the
// source address does not increment since it will be reading from a
// register. The destination address increment is byte 8-bit bytes. The
// arbitration size is set to 4 to match the RX FIFO trigger threshold.
// The uDMA controller will use a 4 byte burst transfer if possible. This
// will be somewhat more effecient that single byte transfers.
//
ROM_uDMAChannelControlSet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
UDMA_ARB_2);

//
// Configure the control parameters for the alternate control structure for
// the UART RX channel. The alternate contol structure is used for the "B"
// part of the ping-pong receive. The configuration is identical to the
// primary/A control structure.
//
ROM_uDMAChannelControlSet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
UDMA_ARB_2);

//
// Set up the transfer parameters for the UART RX primary control
// structure. The mode is set to ping-pong, the transfer source is the
// UART data register, and the destination is the receive "A" buffer. The
// transfer size is set to match the size of the buffer.
//
ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT,
UDMA_MODE_PINGPONG,
(void *)(UART1_BASE + UART_O_DR),
g_ui8RxBufA, sizeof(g_ui8RxBufA));

//
// Set up the transfer parameters for the UART RX alternate control
// structure. The mode is set to ping-pong, the transfer source is the
// UART data register, and the destination is the receive "B" buffer. The
// transfer size is set to match the size of the buffer.
//
ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT,
UDMA_MODE_PINGPONG,
(void *)(UART1_BASE + UART_O_DR),
g_ui8RxBufB, sizeof(g_ui8RxBufB));

//
// Now the uDMA UART RX channels are primed to start a
// transfer. As soon as the channels are enabled, the peripheral will
// issue a transfer request and the data transfers will begin.
//
ROM_uDMAChannelEnable(UDMA_CHANNEL_UART1RX);
}

求大神指导一下。。。。。。

xyz549040622:

这个需要你进行单步调试的。跟踪你接收到的数据,看看为什么不满足触发中断的条件。一般不外乎就是数据没清空,中断标志没清除之类的。

赞(0)
未经允许不得转载:TI中文支持网 » EK-TM4C123GXL uDMA pingpong模式
分享到: 更多 (0)