Tool/software: TI C/C++ Compiler
I can read two voltage from ADC 9 and ADC 11, but I can't use udma to save the two ADC value to array.
I don't know how to config udma with two adc channel.
I try use udma repeatedly ,but failed.
can you help me .I want to read ADC9 and ADC11 voltage use udma. that I can get the two voltage value from array.
thank you ! if you can ,can you give me some demo adbut use two adc with udma.
my code ( udna part is error,and I cannot confirm adc part is correct ):
#include <stdint.h> #include <stdbool.h> #include "inc/hw_memmap.h" #include "driverlib/rom.h" #include "driverlib/pin_map.h" #include "driverlib/sysctl.h" #include "driverlib/uart.h" #include "driverlib/udma.h" #include "driverlib/adc.h" #include "rom_map.h" #include "hw_adc.h" #include "driverlib/gpio.h" #include <string.h> #include "stdio.h" #include "drv_adc.h" #include <rtthread.h> #include "hw_memmap.h" #include "hw_ints.h" #include "tiva_timer.h" #include "interrupt.h" #include "rom.h" #include "plc_config.h" uint32_t g_ui32SysClock; //***************************************************************************** // // 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 size of the memory transfer source and destination buffers (in words). // //***************************************************************************** #define MEM_BUFFER_SIZE 1024 //***************************************************************************** // // 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 count of uDMA errors. This value is incremented by the uDMA error // handler. // //***************************************************************************** static volatile uint32_t g_ui32uDMAErrCount = 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 volatile uint32_t g_ui32MemXferCount = 0; //***************************************************************************** // // The count of times the uDMA interrupt occurred but the uDMA transfer was not // complete. This should remain 0. // //***************************************************************************** static volatile uint32_t g_ui32BadISR = 0; #define ADC_BUFF_SIZE 64 extern char HardVer[5]; uint32_t adc_value; float R=0; float TEMP=0; uint16_t g_temp; uint16_t g_vol; uint16_t g_ele; //***************************************************************************** // // Initializes the uDMA software channel to perform a memory to memory uDMA // transfer. // //***************************************************************************** void InitADC0Transfer(void) { uint_fast16_t ui16Idx; // // Fill the source memory buffer with a simple incrementing pattern. // for(ui16Idx = 0; ui16Idx < MEM_BUFFER_SIZE; ui16Idx++) { g_ui32SrcBuf[ui16Idx] = ui16Idx; } // // Enable interrupts from the uDMA software channel. // IntEnable(INT_UDMA); // // Put the attributes in a known state for the uDMA software channel. // These should already be disabled by default. // uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0, 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. // uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | 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. // uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | 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. // uDMAChannelEnable(UDMA_CHANNEL_ADC0); uDMAChannelRequest(UDMA_CHANNEL_ADC0); } //***************************************************************************** // // 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 = uDMAErrorStatusGet(); // // If there is a uDMA error, then clear the error and increment // the error counter. // if(ui32Status) { 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 = uDMAChannelModeGet(UDMA_CHANNEL_ADC0); if(ui32Mode == UDMA_MODE_STOP) { // // Increment the count of completed transfers. // g_ui32MemXferCount++; // // Configure it for another transfer. // uDMAChannelTransferSet(UDMA_CHANNEL_ADC0, UDMA_MODE_AUTO, g_ui32SrcBuf, g_ui32DstBuf, MEM_BUFFER_SIZE); // // Initiate another transfer. // uDMAChannelEnable(UDMA_CHANNEL_ADC0); uDMAChannelRequest(UDMA_CHANNEL_ADC0); } // // If the channel is not stopped, then something is wrong. // else { g_ui32BadISR++; } } void ADC_Init(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); //ADC0 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);//ADC GPIO-B VER GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_4);//ADC PIN ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0); ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH10 | ADC_CTL_IE |ADC_CTL_END); ADCSequenceEnable(ADC0_BASE, 1); ADCIntClear(ADC0_BASE, 1); ADCIntEnable(ADC0_BASE, 1); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE); GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_5); ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0); ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH8 | ADC_CTL_IE |ADC_CTL_END); ADCSequenceEnable(ADC0_BASE, 3); ADCIntClear(ADC0_BASE, 3); ADCIntEnable(ADC0_BASE, 3); SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);//ADC GPIO-E GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_5);// ADCSequenceConfigure(ADC0_BASE, 2, ADC_TRIGGER_PROCESSOR, 0); ADCSequenceStepConfigure(ADC0_BASE, 2, 0, ADC_CTL_CH11 | ADC_CTL_IE |ADC_CTL_END); ADCSequenceEnable(ADC0_BASE, 2); ADCIntClear(ADC0_BASE, 2); ADCIntEnable(ADC0_BASE, 2); IntEnable(INT_ADC0SS0); return; } void DMA_init(void) { // // 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 uDMAEnable(); // // Point at the control table to use for channel control structures. // uDMAControlBaseSet(pui8ControlTable); // // Initialize the uDMA memory to memory transfers. // InitADC0Transfer(); } void AI_thread(void* parameter) { int i,value; float V,I,RV; float ch_read; uint32_t p_ADC_buff[100]; ADC_Init(); // DMA_init(); while(1) { // read first voltage value use ADC for(i=0;i<100;i++) { ADCProcessorTrigger(ADC0_BASE,3); while(!ADCIntStatus(ADC0_BASE, 3, false)) { } ADCIntClear(ADC0_BASE, 3); ADCSequenceDataGet(ADC0_BASE, 3, &p_ADC_buff[i]); } for(i=0, value=0; i<100; i++) { value += p_ADC_buff[i]; } value = value /100; ch_read = value*3.3/4096.0; V = ch_read *100.0*1000.0/12.0; // V is right value ///////////////////////////////////////// read second voltage value use ADC for(i=0;i<100;i++) { ADCProcessorTrigger(ADC0_BASE,2); while(!ADCIntStatus(ADC0_BASE, 2, false)) { } ADCIntClear(ADC0_BASE, 2); ADCSequenceDataGet(ADC0_BASE, 2, &p_ADC_buff[i]); } for(i=0, value=0; i<100; i++) { value += p_ADC_buff[i]; } value = value /100; ch_read = value*3.3/4096.0; RV = ch_read/(100.0/10.0)/12.0; // RV is right value of voltage rt_thread_delay(20); } }
#include <stdint.h> #include <stdbool.h> #include "inc/hw_memmap.h" #include "driverlib/rom.h" #include "driverlib/pin_map.h" #include "driverlib/sysctl.h" #include "driverlib/uart.h" #include "driverlib/udma.h" #include "driverlib/adc.h" #include "rom_map.h" #include "hw_adc.h" #include "driverlib/gpio.h" #include <string.h> #include "stdio.h" #include "drv_adc.h" #include <rtthread.h> #include "hw_memmap.h" #include "hw_ints.h" #include "tiva_timer.h" #include "interrupt.h" #include "rom.h" #include "plc_config.h" uint32_t g_ui32SysClock; //***************************************************************************** // // 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 size of the memory transfer source and destination buffers (in words). // //***************************************************************************** #define MEM_BUFFER_SIZE 1024 //***************************************************************************** // // 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 count of uDMA errors. This value is incremented by the uDMA error // handler. // //***************************************************************************** static volatile uint32_t g_ui32uDMAErrCount = 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 volatile uint32_t g_ui32MemXferCount = 0; //***************************************************************************** // // The count of times the uDMA interrupt occurred but the uDMA transfer was not // complete. This should remain 0. // //***************************************************************************** static volatile uint32_t g_ui32BadISR = 0; #define ADC_BUFF_SIZE 64 extern char HardVer[5]; uint32_t adc_value; float R=0; float TEMP=0; uint16_t g_temp; uint16_t g_vol; uint16_t g_ele; //***************************************************************************** // // Initializes the uDMA software channel to perform a memory to memory uDMA // transfer. // //***************************************************************************** void InitADC0Transfer(void) { uint_fast16_t ui16Idx; // // Fill the source memory buffer with a simple incrementing pattern. // for(ui16Idx = 0; ui16Idx < MEM_BUFFER_SIZE; ui16Idx++) { g_ui32SrcBuf[ui16Idx] = ui16Idx; } // // Enable interrupts from the uDMA software channel. // IntEnable(INT_UDMA); // // Put the attributes in a known state for the uDMA software channel. // These should already be disabled by default. // uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0, 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. // uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | 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. // uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | 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. // uDMAChannelEnable(UDMA_CHANNEL_ADC0); uDMAChannelRequest(UDMA_CHANNEL_ADC0); } //***************************************************************************** // // 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 = uDMAErrorStatusGet(); // // If there is a uDMA error, then clear the error and increment // the error counter. // if(ui32Status) { 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 = uDMAChannelModeGet(UDMA_CHANNEL_ADC0); if(ui32Mode == UDMA_MODE_STOP) { // // Increment the count of completed transfers. // g_ui32MemXferCount++; // // Configure it for another transfer. // uDMAChannelTransferSet(UDMA_CHANNEL_ADC0, UDMA_MODE_AUTO, g_ui32SrcBuf, g_ui32DstBuf, MEM_BUFFER_SIZE); // // Initiate another transfer. // uDMAChannelEnable(UDMA_CHANNEL_ADC0); uDMAChannelRequest(UDMA_CHANNEL_ADC0); } // // If the channel is not stopped, then something is wrong. // else { g_ui32BadISR++; } } void ADC_Init(void) { SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0); //?a??ADC0 SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);//?a??ADC GPIO-B VER GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_4);//????ADC ��y??PIN ADCSequenceConfigure(ADC0_BASE, 1, ADC_TRIGGER_PROCESSOR, 0);//D����D����??��?????D����D��?����?���䣤�����?��??��??0 ADCSequenceStepConfigure(ADC0_BASE, 1, 0, ADC_CTL_CH10 | ADC_CTL_IE |ADC_CTL_END); //2��?�������̨�10 VER ADCSequenceEnable(ADC0_BASE, 1);//��1?��2��?��D����D��1?�� ADCIntClear(ADC0_BASE, 1); //??3y?D??����?? ADCIntEnable(ADC0_BASE, 1);//ADC?D??��1?�� SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);//?a??ADC GPIO-E ��??1��?���� GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_5);//????ADC ��y??PIN ADCSequenceConfigure(ADC0_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);//D����D����??��?????D����D��?����?���䣤�����?��??��??0 ADCSequenceStepConfigure(ADC0_BASE, 3, 0, ADC_CTL_CH8 | ADC_CTL_IE |ADC_CTL_END); //2��?�������̨�8 ��??1��?���� ADCSequenceEnable(ADC0_BASE, 3);//��1?��2��?��D����D��1?�� ADCIntClear(ADC0_BASE, 3); //??3y?D??����?? ADCIntEnable(ADC0_BASE, 3);//ADC?D??��1?�� SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);//?a??ADC GPIO-E ��??1��?���� GPIOPinTypeADC(GPIO_PORTB_BASE, GPIO_PIN_5);//????ADC ��y??PIN ADCSequenceConfigure(ADC0_BASE, 2, ADC_TRIGGER_PROCESSOR, 0);//D����D����??��?????D����D��?����?���䣤�����?��??��??0 ADCSequenceStepConfigure(ADC0_BASE, 2, 0, ADC_CTL_CH11 | ADC_CTL_IE |ADC_CTL_END); //2��?�������̨�8 ��??1��?���� ADCSequenceEnable(ADC0_BASE, 2);//��1?��2��?��D����D��1?�� ADCIntClear(ADC0_BASE, 2); //??3y?D??����?? ADCIntEnable(ADC0_BASE, 2);//ADC?D??��1?�� IntEnable(INT_ADC0SS0);//��1?��ADC2��?��D����D?D?? return; } void DMA_init(void) { // // 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 uDMAEnable(); // // Point at the control table to use for channel control structures. // uDMAControlBaseSet(pui8ControlTable); // // Initialize the uDMA memory to memory transfers. // InitADC0Transfer(); } void AI_thread(void* parameter) { int i,value; float V,I,RV; float ch_read; uint32_t p_ADC_buff[100]; ADC_Init(); // DMA_init(); while(1) { // read first voltage value use ADC for(i=0;i<100;i++) { ADCProcessorTrigger(ADC0_BASE,3); while(!ADCIntStatus(ADC0_BASE, 3, false)) { } ADCIntClear(ADC0_BASE, 3); ADCSequenceDataGet(ADC0_BASE, 3, &p_ADC_buff[i]); } for(i=0, value=0; i<100; i++) { value += p_ADC_buff[i]; } value = value /100; ch_read = value*3.3/4096.0; V = ch_read *100.0*1000.0/12.0; // V is right value ///////////////////////////////////////// read second voltage value use ADC for(i=0;i<100;i++) { ADCProcessorTrigger(ADC0_BASE,2); while(!ADCIntStatus(ADC0_BASE, 2, false)) { } ADCIntClear(ADC0_BASE, 2); ADCSequenceDataGet(ADC0_BASE, 2, &p_ADC_buff[i]); } for(i=0, value=0; i<100; i++) { value += p_ADC_buff[i]; } value = value /100; ch_read = value*3.3/4096.0; RV = ch_read/(100.0/10.0)/12.0; // RV is right value of voltage rt_thread_delay(20); } }