请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
器件型号:TM4C129EKCPDT 工具/软件:TI C/C++编译器
我可以从 ADC 9和 ADC,读取两个电压、但无法使用 UDMA 将两个 ADC 值保存到数组中。
我不知道如何使用两个 ADC 通道配置 UDMA。
我尝试重复使用 uDMA,但失败了。
我想使用 UDMA 读取 ADC9和 ADC11电压吗? 我可以从 数组获取两个电压值。
谢谢! 如果可以,您能给我一些演示,但使用两个 带有 uDMA 的 ADC。
我的代码(udna 部件出错,我无法 确认 ADC 部件是否正确):
#include #include #include "inc/hw_memmap.h" #include "driverlib/rom.h" #include "driverlib/pin_map.h" #include "driverlib/sysctl.h" #include "driverlib/uart.h" #include "driverlib/uart.h" #include "driverlib/udma.h" #include "driverlib_rom.h"#include "#include "driverlib_rom.h"#include "#include "#include "driverlib_rom.h" #include "stdio.h" #include "drv_adc.h" #include #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; //*************** // // uDMA 控制器使用的控制表。 此表必须与 1024字节边界对齐//。 //// ***************** #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 pu8ControlTable[1024]____(dio_attend_)(_1024) *(_1024)(_diforitudi8ControlTable_)*(_1024) // //内存传输源和目的缓冲区的大小(以字为单位)。 //// ***************** #define MEM_buffer_size 1024 //********* // //用于内存传输的源和目的缓冲区。 //// ***************** 静态 uint32_t g_ui32SrcBuf[MEM_buffer_size]; 静态 uint32_t g_ui32DstBuf[MEM_buffer_size]; //********* // // uDMA 错误的计数。 此值由 UDMA 错误 //处理程序递增。 //// ***************** 静态易失性 uint32_t g_ui32uDMAErrCount = 0; //********* // //内存 uDMA 传输块的计数。 每当一个内存块传输完成时、这个值由// uDMA 中断处理程序递增。 //// ***************** 静态易失性 uint32_t g_ui32MemXferCount = 0; //********* // //发生 UDMA 中断但 UDMA 传输未 完成的次数//。 这应该保持为0。 //// ***************** 静态易失性 uint32_t g_ui32BadISR = 0; #defineADC_buff _size64 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; //********* // //初始化 UDMA 软件通道以执行内存到内存的 UDMA //传输。 //// ***************** void InitADC0Transfer (void) { uint_fast16_t ui16Idx; // //用简单的递增模式填充源存储器缓冲区。 // for (ui16Idx = 0;ui16Idx < MEM_buffer_size;ui16Idx++) { G_ui32SrcBuf[ui16Idx]= ui16Idx; } // //启用来自 uDMA 软件通道的中断。 // IntEnable (INT_UDMA); // //将 UDMA 软件通道的属性置于已知状态。 //默认情况下,这些应该已经被禁用。 // uDMAChannelAttributeDisable (UDMA_CHANGE_ADC0、 UDMA_ATTR_USEBURST | UDMA_ATTR_ALTSELECT | (UDMA_ATTR_HIGH_PRIOR| uDMA_attr_REQMASK); // //配置 SW 通道的控制参数。 开关通道 //将用于在两个存储器缓冲区之间传输,每次32位。 //因此数据大小为32位,地址增量为32位 //用于源和目的。 仲裁数目将设置为8、 //这会导致 UDMA 控制器在8个项目后重新比特率 //已转移。 这可以防止该通道占用 UDMA 控制器 //一旦传输开始,就允许其他通道循环(如果有) //具有更高的优先级。 // uDMAChannelControlSet (UDMA_CHANGE_ADC0 | UDMA_PRI_SELECT、 UDMA_SIZE_32 | UDMA_SRC_INC_32 | UDMA_DST_INC_32 | UDMA_ARB_8); // //设置软件通道的传输参数。 这将会 //配置传输缓冲区和传输大小。 必须为自动模式 //用于软件传输。 // uDMAChannelTransferSet (UDMA_CHANGE_ADC0 | UDMA_PRI_SELECT、 UDMA_MODE_AUTO、g_ui32SrcBuf、g_ui32DstBuf、 MEM_buffer_size); // //现在软件通道被启动一个传输。 通道 //必须启用。 对于基于软件的传输、必须有一个请求 //已印发。 之后、UDMA 存储器传输开始。 // uDMAChannelEnable (UDMA_CHANGE_ADC0); uDMAChannelRequest (UDMA_CHANGE_ADC0); } //********* // // uDMA 错误的中断处理程序。 如果 // uDMA 在尝试执行传输时遇到总线错误,则会发生此中断。 此 //处理程序仅在发生错误时递增计数器。 //// ***************** void uDMAErrorHandler (void) { uint32_t ui32Status; // //检查 uDMA 错误位 // ui32Status = uDMAErrorStatusGet (); // //如果存在 uDMA 错误,则清除该错误并递增 //错误计数器。 // if (ui32状态) { uDMAErrorStatusClear (); G_ui32uDMAErrCount++; } } //********* // //内存通道中 uDMA 中断的中断处理程序。 此 //中断将递增计数器,然后重新启动另一个内存 //传输。 //// ***************** void uDMAIntHandler (void) { uint32_t ui32模式; // //检查主控制结构体以指示完成。 // ui32Mode = uDMAChannelModeGet (UDMA_CHANGE_ADC0); if (ui32Mode = uDMA_MODE_STOP) { // //递增已完成传输的计数。 // G_ui32MemXferCount++; // //为另一个传输配置它。 // uDMAChannelTransferSet (UDMA_CHANGE_ADC0、UDMA_MODE_AUTO、 G_ui32SrcBuf、g_ui32DstBuf、 MEM_buffer_size); // //启动另一个传输。 // uDMAChannelEnable (UDMA_CHANGE_ADC0); uDMAChannelRequest (UDMA_CHANGE_ADC0); } // //如果通道未停止,则说明有问题。 // 其他 { 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 引脚 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) { // //在系统级别启用 uDMA 控制器。 使其继续 //在处理器处于睡眠状态时运行。 // SysCtlPeripheralEnable (SYSCTL_Periph_UDMA); SysCtlPeripheralSlepEnable (SYSCTL_Periph_UDMA); // //启用 uDMA 控制器错误中断。 将发生该中断 //如果在传输过程中出现总线错误。 // IntEnable (INT_UDMAERR); //启用 UDMA uDMAEnable(); // //指向控制表以用于通道控制结构体。 // uDMAControlBaseSet (pui8ControlTable); // //初始化 UDMA 内存到内存的传输。 // InitADC0Transfer(); } void ai_thread (void*参数) { int i、value; 浮动 V、I、RV; float ch_read; uint32_t p_adc_buff [100]; ADC_Init(); // dma_init(); while (1) { //读取第一个电压值使用 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++) { 值+= p_adc_buff [i]; } 值=值/100; ch_read = Value*3.3/4096.0; v = ch_read * 100.0*1000.0/12.0;// V 是正确的值 ////////////////////////////////////////////////////////////////////////////////////////// 使用 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++) { 值+= p_adc_buff [i]; } 值=值/100; ch_read = Value*3.3/4096.0; RV = ch_read/(100.0/10.0)/12.0;// RV 是正确的电压值 rt_thread_delay (20); } }