Part Number:F28M35H52C
原来uart收发采用中断的方式实现,嫌中断太频繁,现在想改dma,使用的串口1,用的是udma_demo,只开了uart发送的dma,接收部分以及ram to ram部分注释掉了,我理解udma配置好了,通道使能就可以发送了,需要其他操作吧,使能部分我尝试读了,都是faulse
代码flash运行,管脚配置正确,时钟都正确*(单测试串口发送可以用测试代码发送数据到上位机显示。)
大致过程参考了demo,同时对着spru22i手册查看了16.4.3部分寄存器的设置,
代码 如下:
void UART1IntHandler(void)
{
unsigned long ulStatus;
ulStatus = UARTIntStatus(UART1_BASE, 1);
UARTIntClear(UART1_BASE, ulStatus);
if(!uDMAChannelIsEnabled(UDMA_CHANNEL_UART1TX))
{
uDMAChannelTransferSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, g_ucTxBuf,
(void *)(UART1_BASE + UART_O_DR),
sizeof(g_ucTxBuf));
// The uDMA TX channel must be re-enabled.
uDMAChannelEnable(UDMA_CHANNEL_UART1TX);
/////// 怎么读都是没有使能
// uDMAChannelIsEnabled(UDMA_CHANNEL_UART1TX);
}
}
//*****************************************************************************
void
InitUART1Transfer(void)
{
unsigned int uIdx;
for(uIdx = 0; uIdx < UART_TXBUF_SIZE; uIdx++)
{
g_ucTxBuf[uIdx] = uIdx;
}
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1);
SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART1);
UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(SYSTEM_CLOCK_SPEED), 115200,
UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |
UART_CONFIG_PAR_NONE);
UARTFIFOLevelSet(UART1_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);
UARTEnable(UART1_BASE);
UARTDMAEnable(UART1_BASE, UART_DMA_TX);
IntEnable(INT_UART1);
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);
uDMAChannelTransferSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, g_ucTxBuf,
(void *)(UART1_BASE + UART_O_DR),
sizeof(g_ucTxBuf));
////测试串口配置,管脚是否正确,能接到计算机上正常收到数据
// UARTCharPutNonBlocking(UART1_BASE,0xaa);
// UARTCharPutNonBlocking(UART1_BASE,0xaa);
// UARTCharPutNonBlocking(UART1_BASE,0xaa);
// UARTCharPutNonBlocking(UART1_BASE,0xaa);
// UARTCharPutNonBlocking(UART1_BASE,0xaa);
uDMAChannelEnable(UDMA_CHANNEL_UART1TX);
}
int main(void)
{
HWREG(SYSCTL_MWRALLOW) = 0xA5A5A5A5;
// Sets up PLL, M3 running at 75MHz and C28 running at 150MHz
SysCtlClockConfigSet(SYSCTL_USE_PLL | (SYSCTL_SPLLIMULT_M & 0xF) |
SYSCTL_SYSDIV_1 | SYSCTL_M3SSDIV_2 |
SYSCTL_XCLKDIV_4);
#ifdef _FLASH
memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
FlashInit();
#endif
////配置管脚
PinoutSet();
// Disable clock supply for the watchdog modules
SysCtlPeripheralDisable(SYSCTL_PERIPH_WDOG1);
SysCtlPeripheralDisable(SYSCTL_PERIPH_WDOG0);
// Unlock the register to change the commit register value for Port B Pin 7
// This disables the NMI functionality on the pin and allows other muxing
// options to be used
HWREG(GPIO_PORTB_BASE+GPIO_O_LOCK) = GPIO_LOCK_KEY_DD;
// Write to commit register
HWREG(GPIO_PORTB_BASE+GPIO_O_CR) |= 0x000000FF;
// Delay
for (i=0;i<20;i++){};
// Enable peripherals to operate when CPU is in sleep.
SysCtlPeripheralClockGating(true);
// Register interrupt handlers in the RAM vector table
IntRegister(INT_UART1, UART1IntHandler);
// 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);
// Initialize the uDMA UART transfers.
InitUART1Transfer();
// Loop until the button is pressed. The processor is put to sleep
// in this loop so that CPU utilization can be measured.
while(1)
{
;
}
yunfei ma:
调整了以下代码,loopback模式的,还是不行,收不到数据
#pragma DATA_ALIGN(ucControlTable, 1024)unsigned char ucControlTable[1024];void uDMAErrorHandler(void);void setup_uart1_dma(void);void UART1_Link_IntDmaHandler(void);void DownLinkSendDma(void);void udma_demo(void);static unsigned char g_ucTxBuf[256];static unsigned char g_ucRxBufA[256];static unsigned char g_ucRxBufB[256];static unsigned long g_ulRxBufACount = 0;static unsigned long g_ulRxBufBCount = 0;
void setup_uart1_dma(void){ ////dma unsigned int uIdx;
// Fill the TX buffer with a simple data pattern. for(uIdx = 0; uIdx < 256; uIdx++) { g_ucTxBuf[uIdx] = uIdx; } //dma // Enable the peripherals used by this example. SysCtlPeripheralEnable(SYSCTL_PERIPH_UART1); SysCtlPeripheralEnable(GPIO_PORTC_BASE); //UART1 Setup GPIOPinTypeUART(GPIO_PORTC_BASE, GPIO_PIN_6 | GPIO_PIN_7); GPIOPinConfigure(GPIO_PC7_U1TX); GPIOPinConfigure(GPIO_PC6_U1RX);
SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART1);///dma
// // Configure the UART1 for 115,200, 8-N-1 operation.// High-Speed Enable// Note: System clock used is also dependent on the baud-rate divisor configuration (see// Section 22.3.2).// 0 The UART is clocked using the system clock divided by 16.// 1 The UART is clocked using the system clock divided by 8. UARTConfigSetExpClk(UART1_BASE, SysCtlClockGet(SYSTEM_CLOCK_SPEED), 115200, (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));//////////////////////////////////////////////////////////// ////////////////////////////////////// UARTConfigSetExpClk(UART1_BASE, (unsigned long)10000000, 9600,// (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |// UART_CONFIG_PAR_NONE)); UARTFIFOLevelSet(UART1_BASE,UART_FIFO_TX4_8,UART_FIFO_RX4_8);//UART_FIFO_RX7_8);//UART_FIFO_RX4_8);// UARTTxIntModeSet(UART1_BASE,UART_TXINT_MODE_EOT);
UARTEnable(UART1_BASE);
// UARTDMAEnable(UART1_BASE,UART_DMA_TX);
UARTDMAEnable(UART1_BASE,UART_DMA_RX | UART_DMA_TX);
// This register write will set the UART to operate in loopback mode. Any // data sent on the TX output will be received on the RX input. HWREG(UART1_BASE + UART_O_CTL) |= UART_CTL_LBE;
// Enable the UART interrupt. IntEnable(INT_UART1);
uDMAChannel16_23SelectDefault(UDMA_CHAN22_DEF_UART1RX_M | UDMA_CHAN23_DEF_UART1TX_M);
// Put the attributes in a known state for the uDMA UART0RX channel. These // should already be disabled by default. uDMAChannelAttributeDisable(UDMA_CHANNEL_UART1RX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);
uDMAChannelControlSet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_4);
uDMAChannelControlSet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 | UDMA_ARB_4);
uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(UART1_BASE + UART_O_DR), g_ucRxBufA, sizeof(g_ucRxBufA));
uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(UART1_BASE + UART_O_DR), g_ucRxBufB, sizeof(g_ucRxBufB));
// Put the attributes in a known state for the uDMA UART1TX channel. These // should already be disabled by default. uDMAChannelAttributeDisable(UDMA_CHANNEL_UART1TX, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);
uDMAChannelAttributeEnable(UDMA_CHANNEL_UART1TX, UDMA_ATTR_USEBURST | UDMA_ATTR_HIGH_PRIORITY);//);
uDMAChannelControlSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT, UDMA_SIZE_8 | UDMA_SRC_INC_8 | UDMA_DST_INC_NONE | UDMA_ARB_4);
uDMAChannelTransferSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, g_ucTxBuf, (void *)(UART1_BASE + UART_O_DR), sizeof(g_ucTxBuf));
UARTCharPutNonBlocking(UART1_BASE,0xaa); UARTCharPutNonBlocking(UART1_BASE,0xaa); UARTCharPutNonBlocking(UART1_BASE,0xaa); UARTCharPutNonBlocking(UART1_BASE,0xaa); UARTCharPutNonBlocking(UART1_BASE,0xaa); UARTCharPutNonBlocking(UART1_BASE,0xaa); UARTCharPutNonBlocking(UART1_BASE,0xaa); UARTCharPutNonBlocking(UART1_BASE,0xaa);
uDMAChannelEnable(UDMA_CHANNEL_UART1TX); uDMAChannelEnable(UDMA_CHANNEL_UART1RX);}voidUART1_Link_IntDmaHandler(void){ unsigned long ulStatus; unsigned long ulMode; tBoolean ch_en;
// Read the interrupt status of the UART. ulStatus = UARTIntStatus(UART1_BASE, 1);
UARTIntClear(UART1_BASE, ulStatus);
ulMode = uDMAChannelModeGet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT);
if(ulMode == UDMA_MODE_STOP) { g_ulRxBufACount++;
uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(UART1_BASE + UART_O_DR), g_ucRxBufA, sizeof(g_ucRxBufA)); }
ulMode = uDMAChannelModeGet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT);
if(ulMode == UDMA_MODE_STOP) { g_ulRxBufBCount++;
uDMAChannelTransferSet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(UART1_BASE + UART_O_DR), g_ucRxBufB, sizeof(g_ucRxBufB)); }
if(!uDMAChannelIsEnabled(UDMA_CHANNEL_UART1TX)) { // Start another DMA transfer to UART0 TX. uDMAChannelTransferSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT, UDMA_MODE_BASIC, g_ucTxBuf, (void *)(UART1_BASE + UART_O_DR), sizeof(g_ucTxBuf));
// The uDMA TX channel must be re-enabled. uDMAChannelEnable(UDMA_CHANNEL_UART1TX); ch_en = uDMAChannelIsEnabled(UDMA_CHANNEL_UART1TX);
}}
void udma_demo(void){ // Setup main clock tree for 75MHz – M3 and 150MHz – C28x//该设置复位 SysCtlClockConfigSet(SYSCTL_SYSDIV_1 | SYSCTL_M3SSDIV_2 | SYSCTL_USE_PLL | (SYSCTL_SPLLIMULT_M & 0x0F));
memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
// Call Flash Initialization to setup flash waitstates// This function must reside in RAM FlashInit(); // Enable peripherals to operate when CPU is in sleep. SysCtlPeripheralClockGating(true);
// Enable all GPIOs PinoutSet(); set_v7_pin_wpu();
IntRegister(INT_UART1, UART1_Link_IntDmaHandler);
IntRegister(INT_UDMAERR, uDMAErrorHandler);
// 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);
IntEnable(INT_UDMAERR);
// Enable the uDMA controller. uDMAEnable();
// Point at the control table to use for channel control structures. uDMAControlBaseSet(ucControlTable);
setup_uart1_dma();
while(1) { ; }}
,
yunfei ma:
查了寄存器的值没看出来啥问题
,
yunfei ma:
设置也设置了
,
yunfei ma:
设置好以后,
uDMAChannelEnable(UDMA_CHANNEL_UART1TX);
使能通道就应该启动发送了,设置后,寄存器没有任何变化,不知道是不是正常
,
yunfei ma:
uart1里面的dr里面值还是0xaa,没有读,也没写
,
Green Deng:
抱歉啊,对这款芯片不太熟悉,包括uDMA模块也是。
这边建议你把问题发布到英文E2E论坛,英文论坛会有专门支持这款芯片的工程师为你解答。
另外,发布代码的话建议只附上关键的DMA+GPIO配置部分代码,否则这么大段代码应该很难给你一一审阅。且代码用编辑框下方“插入”中的“代码”来添加,不要直接粘贴在文本框内。
英文论坛链接:e2e.ti.com/…/c2000-microcontrollers-forum
,
yunfei ma:
没有公司邮箱,不让发:)
,
Green Deng:
可以注册一个钉钉邮箱,是可以发布帖子的