摘录自官方的例程,这里面用到了好几个中断,中断函数表的配置,需要自己去配置的
//***************************************************************************** // // udma_demo.c - uDMA example. // // Copyright (c) 2012-2014 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.0.12573 of the EK-TM4C123GXL Firmware Package. // //***************************************************************************** #include <stdint.h> #include <stdbool.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/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 FTDI virtual COM port and running at 115,200, //! 8-N-1, is used to display messages from this application. // //***************************************************************************** //***************************************************************************** // // 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_SIZE256 #define UART_RXBUF_SIZE256 //***************************************************************************** // // 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 CPU usage in percent, in 16.16 fixed point format. // //***************************************************************************** static uint32_t g_ui32CPUUsage; //***************************************************************************** // // 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 ui8ControlTable[1024]; #elif defined(ccs) #pragma DATA_ALIGN(ui8ControlTable, 1024) uint8_t ui8ControlTable[1024]; #else uint8_t ui8ControlTable[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) {while(1){//// Hang on runtime error.//} } #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++;}//// Call the CPU usage tick function. This function will compute the amount// of cycles used by the CPU since the last call and return the result in// percent in fixed point 16.16 format.//g_ui32CPUUsage = CPUUsageTick(); } //***************************************************************************** // // 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;//// Check for the primary control structure to indicate complete.//ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_SW);if(ui32Mode == UDMA_MODE_STOP){//// Increment the count of completed transfers.//g_ui32MemXferCount++;//// 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);}//// If the channel is not stopped, then something is wrong.//else{g_ui32BadISR++;} } //***************************************************************************** // // 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 UART1IntHandler(void) {uint32_t ui32Status;uint32_t ui32Mode;//// Read the interrupt status of the UART.//ui32Status = ROM_UARTIntStatus(UART1_BASE, 1);//// Clear any pending status, even though there should be none since no UART// interrupts were enabled. If UART error interrupts were enabled, then// those interrupts could occur here and should be handled. Since uDMA is// used for both the RX and TX, then neither of those interrupts should be// enabled.//ROM_UARTIntClear(UART1_BASE, ui32Status);//// Check the DMA control table to see if the ping-pong "A" transfer is// complete. The "A" transfer uses receive buffer "A", and the primary// control structure.//ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART1RX | UDMA_PRI_SELECT);//// If the primary control structure indicates stop, that means the "A"// receive buffer is done. The uDMA controller should still be receiving// data into the "B" buffer.//if(ui32Mode == UDMA_MODE_STOP){//// Increment a counter to indicate data was received into buffer A. In// a real application this would be used to signal the main thread that// data was received so the main thread can process the data.//g_ui32RxBufACount++;//// Set up the next transfer for the "A" buffer, using the primary// control structure. When the ongoing receive into the "B" buffer is// done, the uDMA controller will switch back to this one. This// example re-uses buffer A, 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_CHANNEL_UART1RX | UDMA_PRI_SELECT,UDMA_MODE_PINGPONG,(void *)(UART1_BASE + UART_O_DR),g_ui8RxBufA, sizeof(g_ui8RxBufA));}//// Check the DMA control table to see if the ping-pong "B" transfer is// complete. The "B" transfer uses receive buffer "B", and the alternate// control structure.//ui32Mode = ROM_uDMAChannelModeGet(UDMA_CHANNEL_UART1RX | UDMA_ALT_SELECT);//// If the alternate control structure indicates stop, that means the "B"// receive buffer is done. The uDMA controller should still be receiving// data into the "A" buffer.//if(ui32Mode == UDMA_MODE_STOP){//// Increment a counter to indicate data was received into buffer A. In// a real application this would be used to signal the main thread that// data was received so the main thread can process the data.//g_ui32RxBufBCount++;//// 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_CHANNEL_UART1RX | UDMA_ALT_SELECT,UDMA_MODE_PINGPONG,(void *)(UART1_BASE + UART_O_DR),g_ui8RxBufB, sizeof(g_ui8RxBufB));}//// If the UART1 DMA TX channel is disabled, that means the TX DMA transfer// is done.//if(!ROM_uDMAChannelIsEnabled(UDMA_CHANNEL_UART1TX)){//// Start another DMA transfer to UART1 TX.//ROM_uDMAChannelTransferSet(UDMA_CHANNEL_UART1TX | UDMA_PRI_SELECT,UDMA_MODE_BASIC, g_ui8TxBuf,(void *)(UART1_BASE + UART_O_DR),sizeof(g_ui8TxBuf));//// The uDMA TX channel must be re-enabled.//ROM_uDMAChannelEnable(UDMA_CHANNEL_UART1TX);} } //***************************************************************************** // // 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 InitUART1Transfer(void) {unsigned int uIdx;//// Fill the TX buffer with a simple data pattern.//for(uIdx = 0; uIdx < UART_TXBUF_SIZE; uIdx++){g_ui8TxBuf[uIdx] = uIdx;}//// 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_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_TX4_8, UART_FIFO_RX4_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 | 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 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_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_CHANNEL_UART1RX | 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_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));//// Put the attributes in a known state for the uDMA UART1TX channel. These// should already be disabled by default.//ROM_uDMAChannelAttributeDisable(UDMA_CHANNEL_UART1TX,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_CHANNEL_UART1TX, 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_CHANNEL_UART1TX | 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_CHANNEL_UART1TX | UDMA_PRI_SELECT,UDMA_MODE_BASIC, g_ui8TxBuf,(void *)(UART1_BASE + UART_O_DR),sizeof(g_ui8TxBuf));//// 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_CHANNEL_UART1RX);ROM_uDMAChannelEnable(UDMA_CHANNEL_UART1TX); } //***************************************************************************** // // Initializes the uDMA software channel to perform a memory to memory uDMA // transfer. // //***************************************************************************** void InitSWTransfer(void) {unsigned int uIdx;//// Fill the source memory buffer with a simple incrementing pattern.//for(uIdx = 0; uIdx < MEM_BUFFER_SIZE; uIdx++){g_ui32SrcBuf[uIdx] = uIdx;}//// 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); } //***************************************************************************** // // Configure the UART and its pins. This must be called before UARTprintf(). // //***************************************************************************** void ConfigureUART(void) {//// Enable the GPIO Peripheral used by the UART.//ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);//// Enable UART0//ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UART0);ROM_SysCtlPeripheralSleepEnable(SYSCTL_PERIPH_UART0);//// Configure GPIO Pins for UART mode.//ROM_GPIOPinConfigure(GPIO_PA0_U0RX);ROM_GPIOPinConfigure(GPIO_PA1_U0TX);ROM_GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);//// Use the internal 16MHz oscillator as the UART clock source.//UARTClockSourceSet(UART0_BASE, UART_CLOCK_PIOSC);//// Initialize the UART for console I/O.//UARTStdioConfig(0, 115200, 16000000); } //***************************************************************************** // // 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) {static uint32_t ui32PrevSeconds;static uint32_t ui32PrevXferCount;static uint32_t ui32PrevUARTCount = 0;uint32_t ui32XfersCompleted;uint32_t ui32BytesTransferred;//// Enable lazy stacking for interrupt handlers. This allows floating-point// instructions to be used within interrupt handlers, but at the expense of// extra stack usage.//ROM_FPULazyStackingEnable();//// Set the clocking to run from the PLL at 50 MHz.//ROM_SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN |SYSCTL_XTAL_16MHZ);//// Enable peripherals to operate when CPU is in sleep.//ROM_SysCtlPeripheralClockGating(true);//// Enable the GPIO port that is used for the on-board LED.//ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);//// Enable the GPIO pins for the LED (PF2).//ROM_GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_2);//// Initialize the UART.//ConfigureUART();UARTprintf("\033[2JuDMA Example\n");//// Show the clock frequency on the display.//UARTprintf("Tiva C Series @ %u MHz\n\n", ROM_SysCtlClockGet() / 1000000);//// Show statistics headings.//UARTprintf("CPUMemoryUARTRemaining\n");UARTprintf("Usage Transfers Transfers Time\n");//// Configure SysTick to occur 100 times per second, to use as a time// reference. Enable SysTick to generate interrupts.//ROM_SysTickPeriodSet(ROM_SysCtlClockGet() / SYSTICKS_PER_SECOND);ROM_SysTickIntEnable();ROM_SysTickEnable();//// Initialize the CPU usage measurement routine.//CPUUsageInit(ROM_SysCtlClockGet(), SYSTICKS_PER_SECOND, 2);//// 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(ui8ControlTable);//// Initialize the uDMA memory to memory transfers.//InitSWTransfer();//// Initialize the uDMA UART transfers.//InitUART1Transfer();//// Remember the current SysTick seconds count.//ui32PrevSeconds = g_ui32Seconds;//// Remember the current count of memory buffer transfers.//ui32PrevXferCount = g_ui32MemXferCount;//// Loop until the button is pressed. The processor is put to sleep// in this loop so that CPU utilization can be measured.//while(1){//// Check to see if one second has elapsed. If so, the make some// updates.//if(g_ui32Seconds != ui32PrevSeconds){//// Turn on the LED as a heartbeat//GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);//// Print a message to the display showing the CPU usage percent.// The fractional part of the percent value is ignored.//UARTprintf("\r%3d%%", g_ui32CPUUsage >> 16);//// Remember the new seconds count.//ui32PrevSeconds = g_ui32Seconds;//// Calculate how many memory transfers have occurred since the last// second.//ui32XfersCompleted = g_ui32MemXferCount - ui32PrevXferCount;//// Remember the new transfer count.//ui32PrevXferCount = g_ui32MemXferCount;//// Compute how many bytes were transferred in the memory transfer// since the last second.//ui32BytesTransferred = ui32XfersCompleted * MEM_BUFFER_SIZE * 4;//// Print a message showing the memory transfer rate.//if(ui32BytesTransferred >= 100000000){UARTprintf("%3d MB/s", ui32BytesTransferred / 1000000);}else if(ui32BytesTransferred >= 10000000){UARTprintf("%2d.%01d MB/s ", ui32BytesTransferred / 1000000,(ui32BytesTransferred % 1000000) / 100000);}else if(ui32BytesTransferred >= 1000000){UARTprintf("%1d.%02d MB/s ", ui32BytesTransferred / 1000000,(ui32BytesTransferred % 1000000) / 10000);}else if(ui32BytesTransferred >= 100000){UARTprintf("%3d KB/s", ui32BytesTransferred / 1000);}else if(ui32BytesTransferred >= 10000){UARTprintf("%2d.%01d KB/s ", ui32BytesTransferred / 1000,(ui32BytesTransferred % 1000) / 100);}else if(ui32BytesTransferred >= 1000){UARTprintf("%1d.%02d KB/s ", ui32BytesTransferred / 1000,(ui32BytesTransferred % 1000) / 10);}else if(ui32BytesTransferred >= 100){UARTprintf("%3d B/s", ui32BytesTransferred);}else if(ui32BytesTransferred >= 10){UARTprintf("%2d B/s", ui32BytesTransferred);}else{UARTprintf("%1d B/s", ui32BytesTransferred);}//// Calculate how many UART transfers have occurred since the last// second.//ui32XfersCompleted = (g_ui32RxBufACount + g_ui32RxBufBCount -ui32PrevUARTCount);//// Remember the new UART transfer count.//ui32PrevUARTCount = g_ui32RxBufACount + g_ui32RxBufBCount;//// Compute how many bytes were transferred by the UART. The number// of bytes received is multiplied by 2 so that the TX bytes// transferred are also accounted for.//ui32BytesTransferred = ui32XfersCompleted * UART_RXBUF_SIZE * 2;//// Print a message showing the UART transfer rate.//if(ui32BytesTransferred >= 1000000){UARTprintf("%1d.%02d MB/s ", ui32BytesTransferred / 1000000,(ui32BytesTransferred % 1000000) / 10000);}else if(ui32BytesTransferred >= 100000){UARTprintf("%3d KB/s", ui32BytesTransferred / 1000);}else if(ui32BytesTransferred >= 10000){UARTprintf("%2d.%01d KB/s ", ui32BytesTransferred / 1000,(ui32BytesTransferred % 1000) / 100);}else if(ui32BytesTransferred >= 1000){UARTprintf("%1d.%02d KB/s ", ui32BytesTransferred / 1000,(ui32BytesTransferred % 1000) / 10);}else if(ui32BytesTransferred >= 100){UARTprintf("%3d B/s", ui32BytesTransferred);}else if(ui32BytesTransferred >= 10){UARTprintf("%2d B/s", ui32BytesTransferred);}else{UARTprintf("%1d B/s", ui32BytesTransferred);}//// Print a spinning line to make it more apparent that there is// something happening.//UARTprintf("%2ds", 10 - ui32PrevSeconds);//// Turn off the LED.//GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);}//// Put the processor to sleep if there is nothing to do. This allows// the CPU usage routine to measure the number of free CPU cycles.// If the processor is sleeping a lot, it can be hard to connect to// the target with the debugger.//ROM_SysCtlSleep();//// See if we have run int32_t enough and exit the loop if so.//if(g_ui32Seconds >= 10){break;}}//// Indicate on the display that the example is stopped.//UARTprintf("\nStopped\n");//// Loop forever with the CPU not sleeping, so the debugger can connect.//while(1){//// Turn on the GREEN LED.//GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, GPIO_PIN_2);//// Delay for a bit.//SysCtlDelay(SysCtlClockGet() / 20 / 3);//// Turn off the GREEN LED.//GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 0);//// Delay for a bit.//SysCtlDelay(SysCtlClockGet() / 20 / 3);} }
xyz549040622:
中断服务函数的配置,CCS中在启动文件startup_ccs.c中修改的
//***************************************************************************** // // startup_ccs.c - Startup code for use with TI's Code Composer Studio. // // Copyright (c) 2012-2014 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.0.12573 of the EK-TM4C123GXL Firmware Package. // //*****************************************************************************#include <stdint.h> #include "inc/hw_nvic.h" #include "inc/hw_types.h"//***************************************************************************** // // Forward declaration of the default fault handlers. // //***************************************************************************** void ResetISR(void); static void NmiSR(void); static void FaultISR(void); static void IntDefaultHandler(void);//***************************************************************************** // // External declaration for the reset handler that is to be called when the // processor is started // //***************************************************************************** extern void _c_int00(void);//***************************************************************************** // // Linker variable that marks the top of the stack. // //***************************************************************************** extern uint32_t __STACK_TOP;//***************************************************************************** // // External declarations for the interrupt handlers used by the application. // //***************************************************************************** extern void SysTickHandler(void); extern void UART1IntHandler(void); extern void uDMAIntHandler(void); extern void uDMAErrorHandler(void);//***************************************************************************** // // The vector table.Note that the proper constructs must be placed on this to // ensure that it ends up at physical address 0x0000.0000 or at the start of // the program if located at a start address other than 0. // //***************************************************************************** #pragma DATA_SECTION(g_pfnVectors, ".intvecs") void (* const g_pfnVectors[])(void) = {(void (*)(void))((uint32_t)&__STACK_TOP),// The initial stack pointerResetISR,// The reset handlerNmiSR,// The NMI handlerFaultISR,// The hard fault handlerIntDefaultHandler,// The MPU fault handlerIntDefaultHandler,// The bus fault handlerIntDefaultHandler,// The usage fault handler0,// Reserved0,// Reserved0,// Reserved0,// ReservedIntDefaultHandler,// SVCall handlerIntDefaultHandler,// Debug monitor handler0,// ReservedIntDefaultHandler,// The PendSV handlerSysTickHandler,// The SysTick handlerIntDefaultHandler,// GPIO Port AIntDefaultHandler,// GPIO Port BIntDefaultHandler,// GPIO Port CIntDefaultHandler,// GPIO Port DIntDefaultHandler,// GPIO Port EIntDefaultHandler,// UART0 Rx and TxUART1IntHandler,// UART1 Rx and TxIntDefaultHandler,// SSI0 Rx and TxIntDefaultHandler,// I2C0 Master and SlaveIntDefaultHandler,// PWM FaultIntDefaultHandler,// PWM Generator 0IntDefaultHandler,// PWM Generator 1IntDefaultHandler,// PWM Generator 2IntDefaultHandler,// Quadrature Encoder 0IntDefaultHandler,// ADC Sequence 0IntDefaultHandler,// ADC Sequence 1IntDefaultHandler,// ADC Sequence 2IntDefaultHandler,// ADC Sequence 3IntDefaultHandler,// Watchdog timerIntDefaultHandler,// Timer 0 subtimer AIntDefaultHandler,// Timer 0 subtimer BIntDefaultHandler,// Timer 1 subtimer AIntDefaultHandler,// Timer 1 subtimer BIntDefaultHandler,// Timer 2 subtimer AIntDefaultHandler,// Timer 2 subtimer BIntDefaultHandler,// Analog Comparator 0IntDefaultHandler,// Analog Comparator 1IntDefaultHandler,// Analog Comparator 2IntDefaultHandler,// System Control (PLL, OSC, BO)IntDefaultHandler,// FLASH ControlIntDefaultHandler,// GPIO Port FIntDefaultHandler,// GPIO Port GIntDefaultHandler,// GPIO Port HIntDefaultHandler,// UART2 Rx and TxIntDefaultHandler,// SSI1 Rx and TxIntDefaultHandler,// Timer 3 subtimer AIntDefaultHandler,// Timer 3 subtimer BIntDefaultHandler,// I2C1 Master and SlaveIntDefaultHandler,// Quadrature Encoder 1IntDefaultHandler,// CAN0IntDefaultHandler,// CAN10,// Reserved0,// ReservedIntDefaultHandler,// HibernateIntDefaultHandler,// USB0IntDefaultHandler,// PWM Generator 3uDMAIntHandler,// uDMA Software TransferuDMAErrorHandler,// uDMA ErrorIntDefaultHandler,// ADC1 Sequence 0IntDefaultHandler,// ADC1 Sequence 1IntDefaultHandler,// ADC1 Sequence 2IntDefaultHandler,// ADC1 Sequence 30,// Reserved0,// ReservedIntDefaultHandler,// GPIO Port JIntDefaultHandler,// GPIO Port KIntDefaultHandler,// GPIO Port LIntDefaultHandler,// SSI2 Rx and TxIntDefaultHandler,// SSI3 Rx and TxIntDefaultHandler,// UART3 Rx and TxIntDefaultHandler,// UART4 Rx and TxIntDefaultHandler,// UART5 Rx and TxIntDefaultHandler,// UART6 Rx and TxIntDefaultHandler,// UART7 Rx and Tx0,// Reserved0,// Reserved0,// Reserved0,// ReservedIntDefaultHandler,// I2C2 Master and SlaveIntDefaultHandler,// I2C3 Master and SlaveIntDefaultHandler,// Timer 4 subtimer AIntDefaultHandler,// Timer 4 subtimer B0,// Reserved0,// Reserved0,// Reserved0,// Reserved0,// Reserved0,// Reserved0,// Reserved0,// Reserved0,// Reserved0,// Reserved0,// Reserved0,// Reserved0,// Reserved0,// Reserved0,// Reserved0,// Reserved0,// Reserved0,// Reserved0,// Reserved0,// ReservedIntDefaultHandler,// Timer 5 subtimer AIntDefaultHandler,// Timer 5 subtimer BIntDefaultHandler,// Wide Timer 0 subtimer AIntDefaultHandler,// Wide Timer 0 subtimer BIntDefaultHandler,// Wide Timer 1 subtimer AIntDefaultHandler,// Wide Timer 1 subtimer BIntDefaultHandler,// Wide Timer 2 subtimer AIntDefaultHandler,// Wide Timer 2 subtimer BIntDefaultHandler,// Wide Timer 3 subtimer AIntDefaultHandler,// Wide Timer 3 subtimer BIntDefaultHandler,// Wide Timer 4 subtimer AIntDefaultHandler,// Wide Timer 4 subtimer BIntDefaultHandler,// Wide Timer 5 subtimer AIntDefaultHandler,// Wide Timer 5 subtimer BIntDefaultHandler,// FPU0,// Reserved0,// ReservedIntDefaultHandler,// I2C4 Master and SlaveIntDefaultHandler,// I2C5 Master and SlaveIntDefaultHandler,// GPIO Port MIntDefaultHandler,// GPIO Port NIntDefaultHandler,// Quadrature Encoder 20,// Reserved0,// ReservedIntDefaultHandler,// GPIO Port P (Summary or P0)IntDefaultHandler,// GPIO Port P1IntDefaultHandler,// GPIO Port P2IntDefaultHandler,// GPIO Port P3IntDefaultHandler,// GPIO Port P4IntDefaultHandler,// GPIO Port P5IntDefaultHandler,// GPIO Port P6IntDefaultHandler,// GPIO Port P7IntDefaultHandler,// GPIO Port Q (Summary or Q0)IntDefaultHandler,// GPIO Port Q1IntDefaultHandler,// GPIO Port Q2IntDefaultHandler,// GPIO Port Q3IntDefaultHandler,// GPIO Port Q4IntDefaultHandler,// GPIO Port Q5IntDefaultHandler,// GPIO Port Q6IntDefaultHandler,// GPIO Port Q7IntDefaultHandler,// GPIO Port RIntDefaultHandler,// GPIO Port SIntDefaultHandler,// PWM 1 Generator 0IntDefaultHandler,// PWM 1 Generator 1IntDefaultHandler,// PWM 1 Generator 2IntDefaultHandler,// PWM 1 Generator 3IntDefaultHandler// PWM 1 Fault };//***************************************************************************** // // This is the code that gets called when the processor first starts execution // following a reset event.Only the absolutely necessary set is performed, // after which the application supplied entry() routine is called.Any fancy // actions (such as making decisions based on the reset cause register, and // resetting the bits in that register) are left solely in the hands of the // application. // //***************************************************************************** void ResetISR(void) {//// Jump to the CCS C initialization routine.This will enable the// floating-point unit as well, so that does not need to be done here.//__asm(".global _c_int00\n""b.w_c_int00"); }//***************************************************************************** // // This is the code that gets called when the processor receives a NMI.This // simply enters an infinite loop, preserving the system state for examination // by a debugger. // //***************************************************************************** static void NmiSR(void) {//// Enter an infinite loop.//while(1){} }//***************************************************************************** // // This is the code that gets called when the processor receives a fault // interrupt.This simply enters an infinite loop, preserving the system state // for examination by a debugger. // //***************************************************************************** static void FaultISR(void) {//// Enter an infinite loop.//while(1){} }//***************************************************************************** // // This is the code that gets called when the processor receives an unexpected // interrupt.This simply enters an infinite loop, preserving the system state // for examination by a debugger. // //***************************************************************************** static void IntDefaultHandler(void) {//// Go into an infinite loop.//while(1){} }
user6024197:
回复 xyz549040622:
如果启动文件是startup_rvmdk.S该怎么修改