Other Parts Discussed in Thread: TM4C1294NCPDT
大家好、团队、
我正在处理到 TM4C1294NCPDT (定制板)中 UART 外设的 DMA 传输。 从 Pkt2 (大小为312字节的阵列)向另一个控制器发送字节时遇到问题。 但问题是 DMA 传输函数无法按预期正常工作、它发送的随机字节与实际字节相比。
1) 1)我将填充一个数组、以将这些字节传输到另一个控制器。
2)在一个数组(程序中指定的 Pkt2)中填充312个字节后、我将使用 " MAP_uDMAChannelEnable (UDMA_CH17_UART3TX);"来启动 DMA 传输。
3) 3)发生错误的地方、我无法识别。 有人能不能帮助我 DMA 在这种情况下的工作方式、并帮助我 解决这个问题。
我想使用 DMA_Tx 将312个数据字节从内部阵列(Pkt2)发送到另一个微控制器、而不会丢失任何数据。
同时连接 DMA Rx 和 Tx 以及输出 I GOT 的配置。 任何帮助都是非常感谢的。
void Init_UART3()
{
//
// Enable the GPIO Peripheral used by the UART.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
//
// Enable UART3.
//
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART3);
//
// Enable processor interrupts.
//
IntMasterEnable();
//
// Configure GPIO Pins for UART mode.
//
GPIOPinConfigure(GPIO_PA4_U3RX);
GPIOPinConfigure(GPIO_PA5_U3TX);
GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_4 | GPIO_PIN_5);
//
// Initialize the UART for console I/O.
//
MAP_UARTConfigSetExpClk(UART3_BASE, gu32SysClk, 230400,
(UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE));
HWREG(UART3_BASE + UART_O_CTL) |= UART_CTL_RXE;
HWREG(UART3_BASE + UART_O_CTL) |= UART_CTL_TXE;
// HWREG(UART3_BASE + UART_O_CTL) |= UART_CTL_LBE;
// Make sure there is no junk left in the FIFO
while (UARTCharGetNonBlocking(UART3_BASE) != -1);
MAP_UARTFIFOEnable(UART3_BASE);
MAP_UARTFIFOLevelSet(UART3_BASE, UART_FIFO_TX1_8, UART_FIFO_RX1_8);
// Make sure there is no junk left in the FIFO
while (UARTCharGetNonBlocking(UART3_BASE) != -1);
}
void Init_UART3_DMA(void)
{
MAP_uDMAChannelAssign(UDMA_CH16_UART3RX);
MAP_uDMAChannelAssign(UDMA_CH17_UART3TX);
//
// Enable the UART for operation, and enable the uDMA interface for both TX
// and RX channels.
//
MAP_UARTDMAEnable(UART3_BASE, UART_DMA_RX);
MAP_UARTDMAEnable(UART3_BASE, UART_DMA_TX);
//
// Put the attributes in a known state for the uDMA UART1RX channel. These
// should already be disabled by default.
//
MAP_uDMAChannelAttributeDisable(UDMA_CH16_UART3RX,
UDMA_PRI_SELECT | 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.
//
MAP_uDMAChannelControlSet(UDMA_CH16_UART3RX | UDMA_PRI_SELECT,
UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_2);
MAP_uDMAChannelTransferSet(
UDMA_CH16_UART3RX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC,
(void*) (UART3_BASE + UART_O_DR), gu16Array,
sizeof(gu16Array) >> 1u);
MAP_uDMAChannelAttributeEnable(UDMA_CH16_UART3RX,
UDMA_PRI_SELECT | UDMA_ATTR_USEBURST);
/* Tx DMA setting */
/* clear any previous defined attribute */
uDMAChannelAttributeDisable(UDMA_CH17_UART3TX , UDMA_PRI_SELECT
| UDMA_ATTR_USEBURST |
UDMA_ATTR_REQMASK);
MAP_uDMAChannelAttributeEnable(UDMA_CH17_UART3TX, UDMA_ATTR_USEBURST);// UDMA_PRI_SELECT
/* set the control pars */
uDMAChannelControlSet(UDMA_CH17_UART3TX | UDMA_PRI_SELECT , UDMA_SIZE_16 |
UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_2);
uDMAChannelTransferSet(UDMA_CH17_UART3TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC,
Pkt2, (void *)(UART3_BASE + UART_O_DR),
312);
/////////////////////////////////////////////////
MAP_UARTDMAEnable(UART3_BASE, UART_DMA_RX);
MAP_UARTDMAEnable(UART3_BASE, UART_DMA_TX);
MAP_uDMAChannelEnable(UDMA_CH16_UART3RX);
//
// Enable the UART DMA TX/RX interrupts.
//
MAP_UARTIntEnable(UART3_BASE, UART_INT_DMARX | UART_INT_DMATX);
MAP_UARTEnable(UART3_BASE);
//
// Enable the UART interrupt.
//
MAP_UARTIntEnable(UART3_BASE, UART_INT_RX | UART_INT_RT); //UART_INT_RX |
}
uint16_t Pkt2[312];
int main()
{
Init_SysClk();
Init_GPIO();
Init_UART3();
Init_UART3_DMA();
//uint8_t lu8Index;
uint8_t lu8Checksum;
uint8_t inc = 0;
uint16_t lu16PktIndex = 0;
while(1)
{
// Preparing 312 bytes in Pkt2 Array
for (i = 0; i < 52; i++)
{
Pkt2[lu16PktIndex] = gu8Command2;
lu8Checksum ^= Pkt2[lu16PktIndex];
lu16PktIndex++;
lu16PktIndex &= 0x01FF;
Pkt2[lu16PktIndex] = gu8Data2 + inc;
inc++;
lu8Checksum ^= Pkt2[lu16PktIndex];
lu16PktIndex++;
lu16PktIndex &= 0x01FF;
OnTime1 = gu16SineArray[0][i]; //One ON Long Time
OffTime1 = gu16SineArray[1][i];
Pkt2[lu16PktIndex] = (OnTime1 & 0x7F);
lu8Checksum ^= Pkt2[lu16PktIndex];
lu16PktIndex++;
lu16PktIndex &= 0x01FF;
Pkt2[lu16PktIndex] = ((OnTime1 >> 7) & 0x03);
Pkt2[lu16PktIndex] = Pkt2[lu16PktIndex] | ((OffTime1 << 2) & 0x7F);
Pkt2[lu16PktIndex] = (Pkt2[lu16PktIndex] & 0x7F);
lu8Checksum ^= Pkt2[lu16PktIndex];
lu16PktIndex++;
lu16PktIndex &= 0x01FF;
Pkt2[lu16PktIndex] = ((OffTime1 >> 5) & 0x0F);
Pkt2[lu16PktIndex] = (Pkt2[lu16PktIndex] | ((Mode << 5) & 0x60));
Pkt2[lu16PktIndex] = (Pkt2[lu16PktIndex] & 0x7F);
lu8Checksum ^= Pkt2[lu16PktIndex];
lu16PktIndex++;
lu16PktIndex &= 0x01FF;
lu8Checksum = lu8Checksum & 0x7F;
Pkt2[lu16PktIndex++] = lu8Checksum;
lu16PktIndex &= 0x01FF;
}
// After i = 52 initiating DAM transfer
if (i >= 52)
{
MAP_uDMAChannelEnable(UDMA_CH17_UART3TX);
}
}
}
下面是 DMA 传输的数据、它是随机传输的/不是预期传输的数据。