串口DMA传输配置完以后在while主循环里面要怎么操作串口啊 我看官方例程里面是串口中断里面重新配置uDMAChannelTransferSet,主循环里面就计计次数
官方例程是乒乓模式的 但是我没有这么大的数据量 就写了个基本模式的代码 功能是发送字节0xaa 串口调试助手什么也收不到
下面放代码
void UART_init(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART2);
HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
HWREG(GPIO_PORTD_BASE + GPIO_O_CR) = 0xFF;
GPIOPinConfigure(GPIO_PD7_U2TX);
GPIOPinConfigure(GPIO_PD6_U2RX);
GPIOPinTypeUART(GPIO_PORTD_BASE,GPIO_PIN_7|GPIO_PIN_6);
UARTConfigSetExpClk(UART2_BASE,SysCtlClockGet(),115200,
UART_CONFIG_WLEN_8|
UART_CONFIG_STOP_ONE|UART_CONFIG_PAR_NONE);
UARTEnable(UART2_BASE);
UARTDMAEnable(UART2_BASE,UART_DMA_TX|UART_DMA_RX);
uDMAChannelAttributeDisable(UDMA_CH0_UART2RX,
UDMA_ATTR_ALTSELECT |
UDMA_ATTR_HIGH_PRIORITY |
UDMA_ATTR_REQMASK);
uDMAChannelControlSet(UDMA_CH0_UART2RX | UDMA_PRI_SELECT,
UDMA_SIZE_8 |
UDMA_SRC_INC_NONE |
UDMA_DST_INC_NONE |
UDMA_ARB_1);
uDMAChannelTransferSet(UDMA_CH0_UART2RX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC,
(void *)(UART0_BASE + UART_O_DR),
RxBuf,
sizeof(RxBuf));
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOD);
SysCtlPeripheralEnable(SYSCTL_PERIPH_UART2);
HWREG(GPIO_PORTD_BASE + GPIO_O_LOCK) = GPIO_LOCK_KEY;
HWREG(GPIO_PORTD_BASE + GPIO_O_CR) = 0xFF;
GPIOPinConfigure(GPIO_PD7_U2TX);
GPIOPinConfigure(GPIO_PD6_U2RX);
GPIOPinTypeUART(GPIO_PORTD_BASE,GPIO_PIN_7|GPIO_PIN_6);
UARTConfigSetExpClk(UART2_BASE,SysCtlClockGet(),115200,
UART_CONFIG_WLEN_8|
UART_CONFIG_STOP_ONE|UART_CONFIG_PAR_NONE);
UARTEnable(UART2_BASE);
UARTDMAEnable(UART2_BASE,UART_DMA_TX|UART_DMA_RX);
uDMAChannelAttributeDisable(UDMA_CH0_UART2RX,
UDMA_ATTR_ALTSELECT |
UDMA_ATTR_HIGH_PRIORITY |
UDMA_ATTR_REQMASK);
uDMAChannelControlSet(UDMA_CH0_UART2RX | UDMA_PRI_SELECT,
UDMA_SIZE_8 |
UDMA_SRC_INC_NONE |
UDMA_DST_INC_NONE |
UDMA_ARB_1);
uDMAChannelTransferSet(UDMA_CH0_UART2RX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC,
(void *)(UART0_BASE + UART_O_DR),
RxBuf,
sizeof(RxBuf));
uDMAChannelAttributeDisable(UDMA_CH1_UART2TX,
UDMA_ATTR_ALTSELECT |
UDMA_ATTR_HIGH_PRIORITY |
UDMA_ATTR_REQMASK);
uDMAChannelControlSet(UDMA_CH1_UART2TX | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE |
UDMA_DST_INC_NONE |
UDMA_ARB_1);
uDMAChannelTransferSet(UDMA_CH1_UART2TX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, TxBuf,
(void *)(UART0_BASE + UART_O_DR),
sizeof(TxBuf));
UDMA_ATTR_ALTSELECT |
UDMA_ATTR_HIGH_PRIORITY |
UDMA_ATTR_REQMASK);
uDMAChannelControlSet(UDMA_CH1_UART2TX | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE |
UDMA_DST_INC_NONE |
UDMA_ARB_1);
uDMAChannelTransferSet(UDMA_CH1_UART2TX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, TxBuf,
(void *)(UART0_BASE + UART_O_DR),
sizeof(TxBuf));
uDMAChannelEnable(UDMA_CH0_UART2RX);
uDMAChannelEnable(UDMA_CH1_UART2TX);
uDMAChannelRequest(UDMA_CH0_UART2RX);
uDMAChannelRequest(UDMA_CH1_UART2TX);
uDMAChannelEnable(UDMA_CH1_UART2TX);
uDMAChannelRequest(UDMA_CH0_UART2RX);
uDMAChannelRequest(UDMA_CH1_UART2TX);
UARTIntEnable(UART2_BASE, UART_INT_DMARX);
UARTIntEnable(UART2_BASE, UART_INT_DMATX);
IntEnable(INT_UART2);
}
UARTIntEnable(UART2_BASE, UART_INT_DMATX);
IntEnable(INT_UART2);
}
void UART2IntHandler(void)
{
uint32_t ui32Status;
uint32_t ui32Mode;
{
uint32_t ui32Status;
uint32_t ui32Mode;
ui32Status = UARTIntStatus(UART2_BASE, 1);
UARTIntClear(UART2_BASE, ui32Status);
UARTIntClear(UART2_BASE, ui32Status);
ui32Mode = uDMAChannelModeGet(UDMA_CH1_UART2TX | UDMA_PRI_SELECT);
if(ui32Mode == UDMA_MODE_STOP)
{
uDMAChannelTransferSet(UDMA_CH1_UART2TX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, TxBuf,
(void *)(UART2_BASE + UART_O_DR),
sizeof(TxBuf));
uDMAChannelEnable(UDMA_CH1_UART2TX);
uDMAChannelRequest(UDMA_CH1_UART2TX);
}
if(ui32Mode == UDMA_MODE_STOP)
{
uDMAChannelTransferSet(UDMA_CH1_UART2TX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC, TxBuf,
(void *)(UART2_BASE + UART_O_DR),
sizeof(TxBuf));
uDMAChannelEnable(UDMA_CH1_UART2TX);
uDMAChannelRequest(UDMA_CH1_UART2TX);
}
if(!uDMAChannelIsEnabled(UDMA_CH0_UART2RX))
{
uDMAChannelTransferSet(UDMA_CH0_UART2RX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC,
(void *)(UART2_BASE + UART_O_DR),RxBuf,
sizeof(RxBuf));
uDMAChannelEnable(UDMA_CH0_UART2RX);
uDMAChannelRequest(UDMA_CH0_UART2RX);
}
}
{
uDMAChannelTransferSet(UDMA_CH0_UART2RX | UDMA_PRI_SELECT,
UDMA_MODE_BASIC,
(void *)(UART2_BASE + UART_O_DR),RxBuf,
sizeof(RxBuf));
uDMAChannelEnable(UDMA_CH0_UART2RX);
uDMAChannelRequest(UDMA_CH0_UART2RX);
}
}
void UDMA_Init(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
IntEnable(INT_UDMAERR);
uDMAEnable();
uDMAControlBaseSet(pui8ControlTable);
uDMAChannelAssign(UDMA_CH0_UART2RX);
uDMAChannelAssign(UDMA_CH1_UART2TX);
}
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
IntEnable(INT_UDMAERR);
uDMAEnable();
uDMAControlBaseSet(pui8ControlTable);
uDMAChannelAssign(UDMA_CH0_UART2RX);
uDMAChannelAssign(UDMA_CH1_UART2TX);
}
uint8_t RxBuf[1];
uint8_t TxBuf[1]={0xaa};
uint8_t TxBuf[1]={0xaa};
int main()
{
FPULazyStackingEnable();
FPUEnable();
SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
UDMA_Init();
UART_init();
while(1)
{
}
{
FPULazyStackingEnable();
FPUEnable();
SysCtlClockSet(SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHZ);
UDMA_Init();
UART_init();
while(1)
{
}
}
xyz549040622:
主存和DMA接口之间有一条直接数据通路。DMA方式传送数据不需要经过CPU,所以你配置好,直接给目标地址放数据就好了。
user5813287:
回复 xyz549040622:
现在是我配置好了 能发送了 但是如果数据内容长了 发几次后数据内容就乱了 发一个字节要间隔几微秒才能保证发送顺序 或者拉低波特率 但是还是会乱 现在是没有给串口配置中断的 直接写了个发送的函数
Susan Yang:
回复 user5813287:
请您参考下下面的代码
//***************************************************************************** // // udma_demo.c - uDMA example. // // Copyright (c) 2013-2017 Texas Instruments Incorporated.All rights reserved. // Software License Agreement //// Texas Instruments (TI) is supplying this software for use solely and // exclusively on TI's microcontroller products. The software is owned by // TI and/or its suppliers, and is protected under applicable copyright // laws. You may not combine this software with "viral" open-source // software in order to form a larger program. //// THIS SOFTWARE IS PROVIDED "AS IS" AND WITH ALL FAULTS. // NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT // NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. TI SHALL NOT, UNDER ANY // CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR CONSEQUENTIAL // DAMAGES, FOR ANY REASON WHATSOEVER. //// This is part of revision 2.1.4.178 of the EK-TM4C1294XL Firmware Package. // //*****************************************************************************#include <stdint.h> #include <stdbool.h> #include <string.h> #include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_types.h" #include "inc/hw_uart.h" #include "driverlib/fpu.h" #include "driverlib/gpio.h" #include "driverlib/interrupt.h" #include "driverlib/pin_map.h" #include "driverlib/rom.h" #include "driverlib/rom_map.h" #include "driverlib/sysctl.h" #include "driverlib/systick.h" #include "driverlib/uart.h" #include "driverlib/udma.h" #include "utils/cpu_usage.h" #include "utils/uartstdio.h" #include "utils/ustdlib.h"//***************************************************************************** // //! \addtogroup example_list //! <h1>uDMA (udma_demo)</h1> //! //! This example application demonstrates the use of the uDMA controller to //! transfer data between memory buffers, and to transfer data to and from a //! UART.The test runs for 10 seconds before exiting. //! //! UART0, connected to the ICDI virtual COM port and running at 115,200, //! 8-N-1, is used to display messages from this application. // //*****************************************************************************//**************************************************************************** // // System clock rate in Hz. // //**************************************************************************** uint32_t g_ui32SysClock;//***************************************************************************** // // The number of SysTick ticks per second used for the SysTick interrupt. // //***************************************************************************** #define SYSTICKS_PER_SECOND100//***************************************************************************** // // The size of the memory transfer source and destination buffers (in words). // //***************************************************************************** #define MEM_BUFFER_SIZE1024//***************************************************************************** // // The size of the UART transmit and receive buffers.They do not need to be // the same size. // //***************************************************************************** #define UART_TXBUF_SIZE10 #define UART_RXBUF_SIZE10//***************************************************************************** // // The source and destination buffers used for memory transfers. // //***************************************************************************** static uint32_t g_ui32SrcBuf[MEM_BUFFER_SIZE]; static uint32_t g_ui32DstBuf[MEM_BUFFER_SIZE];//***************************************************************************** // // The transmit and receive buffers used for the UART transfers.There is one // transmit buffer and a pair of recieve ping-pong buffers. // //***************************************************************************** static uint8_t g_ui8TxBuf[UART_TXBUF_SIZE]; static uint8_t g_ui8RxBufA[UART_RXBUF_SIZE]; static uint8_t g_ui8RxBufB[UART_RXBUF_SIZE];//***************************************************************************** // // The count of uDMA errors.This value is incremented by the uDMA error // handler. // //***************************************************************************** static uint32_t g_ui32uDMAErrCount = 0;//***************************************************************************** // // The count of times the uDMA interrupt occurred but the uDMA transfer was not // complete.This should remain 0. // //***************************************************************************** static uint32_t g_ui32BadISR = 0;//***************************************************************************** // // The count of UART buffers filled, one for each ping-pong buffer. // //***************************************************************************** static uint32_t g_ui32RxBufACount = 0; static uint32_t g_ui32RxBufBCount = 0;//***************************************************************************** // // The count of memory uDMA transfer blocks.This value is incremented by the // uDMA interrupt handler whenever a memory block transfer is completed. // //***************************************************************************** static uint32_t g_ui32MemXferCount = 0;//***************************************************************************** // // The number of seconds elapsed since the start of the program.This value is // maintained by the SysTick interrupt handler. // //***************************************************************************** static uint32_t g_ui32Seconds = 0;//***************************************************************************** // // The control table used by the uDMA controller.This table must be aligned // to a 1024 byte boundary. // //***************************************************************************** #if defined(ewarm) #pragma data_alignment=1024 uint8_t pui8ControlTable[1024]; #elif defined(ccs) #pragma DATA_ALIGN(pui8ControlTable, 1024) uint8_t pui8ControlTable[1024]; #else uint8_t pui8ControlTable[1024] __attribute__ ((aligned(1024))); #endif//***************************************************************************** // // The error routine that is called if the driver library encounters an error. // //***************************************************************************** #ifdef DEBUG void __error__(char *pcFilename, uint32_t ui32Line) { } #endif//***************************************************************************** // // The interrupt handler for the SysTick timer.This handler will increment a // seconds counter whenever the appropriate number of ticks has occurred.It // will also call the CPU usage tick function to find the CPU usage percent. // //***************************************************************************** void SysTickHandler(void) {static uint32_t ui32TickCount = 0;//// Increment the tick counter.//ui32TickCount++;//// If the number of ticks per second has occurred, then increment the// seconds counter.// //if(!(ui32TickCount % SYSTICKS_PER_SECOND)) //{ //g_ui32Seconds++; //}}//***************************************************************************** // // The interrupt handler for uDMA errors.This interrupt will occur if the // uDMA encounters a bus error while trying to perform a transfer.This // handler just increments a counter if an error occurs. // //***************************************************************************** void uDMAErrorHandler(void) {uint32_t ui32Status;//// Check for uDMA error bit//ui32Status = ROM_uDMAErrorStatusGet();//// If there is a uDMA error, then clear the error and increment// the error counter.//if(ui32Status){ROM_uDMAErrorStatusClear();g_ui32uDMAErrCount++;} }//***************************************************************************** // // The interrupt handler for uDMA interrupts from the memory channel.This // interrupt will increment a counter, and then restart another memory // transfer. // //***************************************************************************** void uDMAIntHandler(void) {uint32_t ui32Mode,status;//// Check for the primary control structure to indicate complete.//status = ROM_uDMAIntStatus();uDMAIntClear(status);ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_SW);if(ui32Mode == UDMA_MODE_STOP){//// Configure it for another transfer.//ROM_uDMAChannelTransferSet(UDMA_CHANNEL_SW, UDMA_MODE_AUTO,g_ui32SrcBuf, g_ui32DstBuf,MEM_BUFFER_SIZE);//// Initiate another transfer.//ROM_uDMAChannelEnable(UDMA_CHANNEL_SW);ROM_uDMAChannelRequest(UDMA_CHANNEL_SW);}}//***************************************************************************** // // The interrupt handler for UART1.This interrupt will occur when a DMA // transfer is complete using the UART1 uDMA channel.It will also be // triggered if the peripheral signals an error.This interrupt handler will // switch between receive ping-pong buffers A and B.It will also restart a TX // uDMA transfer if the prior transfer is complete.This will keep the UART // running continuously (looping TX data back to RX). // //***************************************************************************** void UART3IntHandler(void) {uint32_t ui32Status;uint32_t ui32Mode;ui32Status = ROM_UARTIntStatus(UART3_BASE, 1);ROM_UARTIntClear(UART3_BASE, ui32Status);ui32Mode = ROM_uDMAChannelModeGet(UDMA_CH16_UART3RX | UDMA_PRI_SELECT);if(ui32Mode == UDMA_MODE_STOP){ROM_uDMAChannelTransferSet(UDMA_CH16_UART3RX | UDMA_PRI_SELECT,UDMA_MODE_PINGPONG,(void *)(UART3_BASE + UART_O_DR),g_ui8RxBufA, sizeof(g_ui8RxBufA));}ui32Mode = ROM_uDMAChannelModeGet(UDMA_CH16_UART3RX | UDMA_ALT_SELECT);if(ui32Mode == UDMA_MODE_STOP){//// Set up the next transfer for the "B" buffer, using the alternate// control structure.When the ongoing receive into the "A" buffer is// done, the uDMA controller will switch back to this one.This// example re-uses buffer B, but a more sophisticated application could// use a rotating set of buffers to increase the amount of time that// the main thread has to process the data in the buffer before it is// reused.//ROM_uDMAChannelTransferSet(UDMA_CH16_UART3RX | UDMA_ALT_SELECT,UDMA_MODE_PINGPONG,(void *)(UART3_BASE + UART_O_DR),g_ui8RxBufA, sizeof(g_ui8RxBufB));////!!!!!!!!!!!!!!!!!!!!!!!}ui32Status = ROM_UARTIntStatus(UART3_BASE, 1);ROM_UARTIntClear(UART3_BASE, ui32Status); //ROM_UARTIntClear(UART3_BASE, UART_INT_DMATX );if(!ROM_uDMAChannelIsEnabled(UDMA_CH17_UART3TX)) //if(ROM_UARTIntStatus(UART3_BASE, UART_INT_DMATX)){ROM_uDMAChannelTransferSet(UDMA_CH17_UART3TX | UDMA_PRI_SELECT,UDMA_MODE_BASIC, g_ui8TxBuf,(void *)(UART3_BASE + UART_O_DR),sizeof(g_ui8TxBuf));ROM_uDMAChannelEnable(UDMA_CH17_UART3TX); //ui32Status = ROM_UARTIntStatus(UART3_BASE, 1); //ROM_UARTIntClear(UART3_BASE, ui32Status); ////ROM_UARTIntClear(UART3_BASE, UART_INT_DMATX );} } void UART3Init(){ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOJ);ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART3);ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART3);GPIOPinConfigure(GPIO_PJ0_U3RX);GPIOPinConfigure(GPIO_PJ1_U3TX);ROM_GPIOPinTypeUART(GPIO_PORTJ_BASE,GPIO_PIN_0|GPIO_PIN_1);ROM_UARTConfigSetExpClk(UART3_BASE, g_ui32SysClock, 115200,UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE |UART_CONFIG_PAR_NONE);ROM_UARTFIFOLevelSet(UART3_BASE, UART_FIFO_TX4_8, UART_FIFO_RX4_8);ROM_UARTEnable(UART3_BASE);ROM_UARTDMAEnable(UART3_BASE, UART_DMA_RX | UART_DMA_TX); //HWREG(UART3_BASE + UART_O_CTL) |= UART_CTL_LBE;ROM_uDMAChannelAssign(UDMA_CH16_UART3RX);ROM_uDMAChannelAssign(UDMA_CH17_UART3TX);//// Enable the UART DMA TX/RX interrupts.//ROM_UARTIntEnable(UART3_BASE, UART_INT_DMATX | UART_INT_DMARX);//// Enable the UART peripheral interrupts.//ROM_IntEnable(INT_UART3);} void uDMA_U3Rx(){//// Put the attributes in a known state for the uDMA UART1RX channel.These// should already be disabled by default.//ROM_uDMAChannelAttributeDisable(UDMA_CH16_UART3RX,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_CH16_UART3RX | UDMA_PRI_SELECT,UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |UDMA_ARB_4);//// 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_CH16_UART3RX | UDMA_ALT_SELECT,UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |UDMA_ARB_4);//// 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_CH16_UART3RX | UDMA_PRI_SELECT,UDMA_MODE_PINGPONG,//UDMA_MODE_PINGPONG,UDMA_MODE_BASIC(void *)(UART3_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_CH16_UART3RX | UDMA_ALT_SELECT,UDMA_MODE_PINGPONG,(void *)(UART3_BASE + UART_O_DR),g_ui8RxBufA, sizeof(g_ui8RxBufA));//!!!!!!!!!!!!!!!!!!!ROM_uDMAChannelEnable(UDMA_CH16_UART3RX);} void uDMA_U4Tx(uint32_t size, uint8_t *data){//// Put the attributes in a known state for the uDMA UART1TX channel.These// should already be disabled by default.//ROM_uDMAChannelAttributeDisable(UDMA_CH17_UART3TX,UDMA_ATTR_ALTSELECT |UDMA_ATTR_HIGH_PRIORITY |UDMA_ATTR_REQMASK);//// Set the USEBURST attribute for the uDMA UART TX channel.This will// force the controller to always use a burst when transferring data from// the TX buffer to the UART.This is somewhat more effecient bus usage// than the default which allows single or burst transfers.//ROM_uDMAChannelAttributeEnable(UDMA_CH17_UART3TX, UDMA_ATTR_USEBURST);//// Configure the control parameters for the UART TX.The uDMA UART TX// channel is used to transfer a block of data from a buffer to the UART.// The data size is 8 bits.The source address increment is 8-bit bytes// since the data is coming from a buffer.The destination increment is// none since the data is to be written to the UART data register.The// arbitration size is set to 4, which matches the UART TX FIFO trigger// threshold.//ROM_uDMAChannelControlSet(UDMA_CH17_UART3TX | UDMA_PRI_SELECT,UDMA_SIZE_8 | UDMA_SRC_INC_8 |UDMA_DST_INC_NONE |UDMA_ARB_4);//// Set up the transfer parameters for the uDMA UART TX channel.This will// configure the transfer source and destination and the transfer size.// Basic mode is used because the peripheral is making the uDMA transfer// request.The source is the TX buffer and the destination is the UART// data register.//ROM_uDMAChannelTransferSet(UDMA_CH17_UART3TX | UDMA_PRI_SELECT,UDMA_MODE_BASIC, data,(void *)(UART3_BASE + UART_O_DR),size);//// Now both the uDMA UART TX and 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_CH17_UART3TX);} //***************************************************************************** // // Initializes the UART1 peripheral and sets up the TX and RX uDMA channels. // The UART is configured for loopback mode so that any data sent on TX will be // received on RX.The uDMA channels are configured so that the TX channel // will copy data from a buffer to the UART TX output.And the uDMA RX channel // will receive any incoming data into a pair of buffers in ping-pong mode. // //***************************************************************************** void InitUART4Transfer(void) {UART3Init();uDMA_U3Rx();uDMA_U4Tx(sizeof(g_ui8TxBuf),g_ui8TxBuf);}//***************************************************************************** // // Initializes the uDMA software channel to perform a memory to memory uDMA // transfer. // //***************************************************************************** void InitSWTransfer(void) { //uint_fast16_t ui16Idx;//// Enable interrupts from the uDMA software channel.//ROM_IntEnable(INT_UDMA);//// Put the attributes in a known state for the uDMA software channel.// These should already be disabled by default.//ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_SW,UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT |(UDMA_ATTR_HIGH_PRIORITY |UDMA_ATTR_REQMASK));//// Configure the control parameters for the SW channel.The SW channel// will be used to transfer between two memory buffers, 32 bits at a time.// Therefore the data size is 32 bits, and the address increment is 32 bits// for both source and destination.The arbitration size will be set to 8,// which causes the uDMA controller to rearbitrate after 8 items are// transferred.This keeps this channel from hogging the uDMA controller// once the transfer is started, and allows other channels cycles if they// are higher priority.//ROM_uDMAChannelControlSet(UDMA_CHANNEL_SW | UDMA_PRI_SELECT,UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 |UDMA_ARB_8);//// Set up the transfer parameters for the software channel.This will// configure the transfer buffers and the transfer size.Auto mode must be// used for software transfers.//ROM_uDMAChannelTransferSet(UDMA_CHANNEL_SW | UDMA_PRI_SELECT,UDMA_MODE_AUTO, g_ui32SrcBuf, g_ui32DstBuf,MEM_BUFFER_SIZE);//// Now the software channel is primed to start a transfer.The channel// must be enabled.For software based transfers, a request must be// issued.After this, the uDMA memory transfer begins.//ROM_uDMAChannelEnable(UDMA_CHANNEL_SW);ROM_uDMAChannelRequest(UDMA_CHANNEL_SW); }void uDMA_Init(){//// Enable the uDMA controller at the system level.Enable it to continue// to run while the processor is in sleep.//ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UDMA);//// Enable the uDMA controller error interrupt.This interrupt will occur// if there is a bus error during a transfer.//ROM_IntEnable(INT_UDMAERR);//// Enable the uDMA controller.//ROM_uDMAEnable();//// Point at the control table to use for channel control structures.//ROM_uDMAControlBaseSet(pui8ControlTable);} void delay_s(int s) {ROM_SysCtlDelay((g_ui32SysClock / (3 )) * s); // more accurate} //***************************************************************************** // // This example demonstrates how to use the uDMA controller to transfer data // between memory buffers and to and from a peripheral, in this case a UART. // The uDMA controller is configured to repeatedly transfer a block of data // from one memory buffer to another.It is also set up to repeatedly copy a // block of data from a buffer to the UART output.The UART data is looped // back so the same data is received, and the uDMA controlled is configured to // continuously receive the UART data using ping-pong buffers. // // The processor is put to sleep when it is not doing anything, and this allows // collection of CPU usage data to see how much CPU is being used while the // data transfers are ongoing. // //***************************************************************************** int main(void) {//// Set the clocking to run directly from the crystal at 120MHz.//g_ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_16MHZ |SYSCTL_OSC_MAIN |SYSCTL_USE_PLL |SYSCTL_CFG_VCO_480), 120000000);uDMA_Init();//// Initialize the uDMA memory to memory transfers.//InitSWTransfer();//// Initialize the uDMA UART transfers.// //InitUART4Transfer();UART3Init();uDMA_U3Rx();uDMA_U4Tx(sizeof(g_ui8TxBuf),g_ui8TxBuf);//// Loop until the button is pressed.The processor is put to sleep// in this loop so that CPU utilization can be measured.//while(1){uint_fast16_t ui16Idx;//// Fill the TX buffer with a simple data pattern.//for(ui16Idx = 0; ui16Idx < UART_TXBUF_SIZE; ui16Idx++){g_ui8TxBuf[ui16Idx] = ui16Idx;}delay_s(10);for(ui16Idx = 0; ui16Idx < UART_TXBUF_SIZE; ui16Idx++){g_ui8TxBuf[ui16Idx] = 0x70;}delay_s(10);for(ui16Idx = 0; ui16Idx < UART_TXBUF_SIZE; ui16Idx++){g_ui8TxBuf[ui16Idx] = 0x71;}delay_s(10);}}
user6024197:
回复 Susan Yang:
请问startup_rvmdk.S怎么配置,我用的Keil写的程序
xyz549040622:
回复 user6024197:
直接点开.s文件,把自己写的中断函数替换默认的中断函数就好了。
user6024197:
回复 xyz549040622:
就是我直接替换会出现这种情况
user6024197:
回复 Susan Yang:
请问这些例程,你们是从哪里找到的,很多都说是官网,但哪个官网,是培训官网还是TI官网,我没找到
xyz549040622:
回复 user6024197:
我们一般说的官网,是指TI的官方TIVAWARE开发包中的例程。你官网下载离线的开发包安装就好了。下载链接如下所示:
www.ti.com.cn/…/SW-TM4C
Susan Yang:
回复 user6024197:
您也可以在下面的链接找到
dev.ti.com/…/node
user6024197:
回复 Susan Yang:
谢谢