主题中讨论的其他器件:TM4C123、 TM4C123AH6PM、 TM4C1294NCPDT
你好。
我在这个论坛上找到了一段代码、用于设置带有 uDMA 的定时器触发 ADC。 链接: e2e.ti.com/.../2025521
我已经阅读了 TivaWare 用户指南、并了解了函数的作用以及设置的总体过程
整个过程。 但是、这对我不起作用。 它在专用于存储数据的数组中为我提供零。
我将添加代码功能的摘要、代码中存在一些冗余、我将保留这些冗余。
我正在使用 Keil、并已将 TARGET_IS_TM4C123_RB1、PART_TM4C123AH6PM 放入预处理器符号中。
- START 和 STOP 是冗余变量、用于测量中断发生的频率以及 SysTick 计数器及其处理程序。 如果我错了、请纠正我的问题。
- ADCseq0Handler 是在8级深度 FIFO 满时触发的。 然后、我们有 一个 uDMAChannelTransferSet、它应该负责接下来的64个样本。 然后 FIFO 将开始满、我们会再次运行。
- main() 设置时钟频率,启用计时器 ADC0、UDMA 和 Porte。 我们设置 SysTick 周期并将计时器周期(重复)设置为1/16000 s
- init_adc() 将 ADC 的时钟设置为8MHz (必要步骤),禁用中断和序列发生器。
- StepConfigure 将 ADC0的 SEQ 0配置为优先级为0、通道1作为输入、以引起中断、这是最后一步。 (现在 FIFO 中的所有其他步骤会发生什么情况?)
- 在特定的 uDMA 通道上、我们禁用不需要的属性(不知道它们是什么)、并启用突发传输。 控制参数是主结构体、数据大小、源地址不会递增、因为它们都来自同一个 FIFO、目的地址将递增、并且我们在64次这样的传输后进行仲裁
- 然后、我们设置阵列的地址并启用中断
我将得到数组中的所有0。 我已经检查了一个简单的 ADC 程序、即模拟输入配置是否正确。
我希望有人能帮助我解决所有这些问题。 我觉得应该设置的所有内容都已经设置好了、但由于我没有这方面的经验、我找不到错误。
欢迎提出任何建议。
Update1:我发现程序卡在 SysTickHandler 中,由于没有必要,我已将其删除,但它在 SS0 Handler 处停止。
Update2:在"ROM_TimerEnable (TIMER0_BASE、TIMER_A)"行之后、第一个元素加载正确的值、但所有其他元素都具有相同的值、大概是随机的。 此外、我在 SS0处理程序的开头放置了一个断点、但它从未达到?
update3:当然、中断有问题 。 基本 SysTick 处理程序不会执行、只是会停止。 感谢每个人的努力,我希望很快解决这个问题。
最终更新:启动具有不同的矢量名称! 这就是导致所有这一切的原因。 感谢 Bob Crosby、希望您不要花太多时间来看看这个、 CB1_mobile、感谢 John Piliounis 和 Phil LaFayette10的建议、您的代码比我的代码好! UDMA_ARB_1而不是 UDMA_ARB_1024
#include #include include "inc/hw_ints.h" #include "inc/hw_memmap.h" #include "inc/hw_adc.h" #include "inc/hw_types.h" #include "inc/hw_uma.h" #include "driverlib/driver.h" #driverlib/driver.h" #include "driverlib/driver.h"#driverlib#driver.h"#include "driverlib.driver.h"#driverlib#driverlib#driverlib.driver.h"#include "driverlib#driverlib.driver.h"#include "driverlib.driver.h"#driverlib#driverlib.driverlib#driver.h"#include "driver.h"#driverlib#driverlib.driverlib.driverlib#driverlib.driver.h"#include "driver.h"#include "driverlib.driverlib#driverlib.driver.h"#include "driver.h"#driverlib#driverlib. 64 #pragma DATA_ALIGN (ucControlTable、1024) uint8_t ucControlTable[1024]; 静态 uint16_t ADC_OUT[ADC_SAMPLE_BUF_SIZE]; uint32_t n=0; void init_adc (void); 静态 uint32_t g_ui32DMAErrCount = 0; 静态 uint32_t g_ui32SysTickCount; 易失性 uint32_t start、stop; void uDMAErrorHandler (void) { uint32_t ui32Status; ui32Status = ROM_uDMAErrorStatusGet (); if (ui32状态) { ROM_uDMAErrorStatusClear (); G_ui32DMAErrCount++; } } void SysTickIntHandler (void) { // //更新我们的系统节拍计数器。 // G_ui32SysTickCount++; } void ADCseq0Handler() { 停止= g_ui32SysTickCount; ADCIntClear (ADC0_BASE、0); N++; if (!ROM_uDMAChannelIsEnabled (UDMA_CHANGE_ADC0)) { uDMAChannelTransferSet (UDMA_CHANGE_ADC0 | UDMA_PRI_SELECT、UDMA_MODE_BASIC、(void *)(ADC0_BASE + ADC_O_SSFIFO0)、&ADC_OUT、ADC_SAMPLE_BUF_SIZE); uDMAChannelEnable (UDMA_CHANGE_ADC0); } START = STOP; } int main (void) { SysCtlClockSet (SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHz); SysCtlDelay (20); ROM_SysCtlPeripheralEnable (SYSCTL_Periph_TIMER0); SysCtlPeripheralEnable (SYSCTL_Periph_ADC0);//启用 ADC 模块的时钟 SysCtlDelay (10);//设置外设使能的时间 SysCtlPeripheralEnable (SYSCTL_Periph_UDMA);//启用 UDMA 的时钟 SysCtlDelay (10); SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);//启用端口 E 的时钟 SysCtlDelay (30); ROM_SysTickPeriodSet (SysCtlClockGet ()/1000000);//将 SysTic 计数器的周期设置为1us ROM_SysTickIntEnable(); ROM_SysTickEnable(); ROM_TimerConfigure (TIMER0_BASE、TIMER_CFG_PERIODICASE); ROM_TimerLoadSet (TIMER0_BASE、TIMER_A、ROM_SysCtlClockGet ()/16000 -1);//TODO:此处设置定时器装载值 ROM_TimerControlTrigger (TIMER0_BASE、TIMER_A、TRUE); GPIOPinTypeADC (GPIO_Porte _BASE、GPIO_PIN_2); SysCtlDelay (80); IntMasterEnable(); init_adc(); TimerEnable (TIMER0_BASE、TIMER_A); start = g_ui32SysTickCount; while (1) { } } void init_adc() { ADCClockConfigSet (ADC0_BASE、ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_Half、1); SysCtlDelay (10);//设置时钟配置的时间 IntDisable (INT_ADC0SS0); ADCIntDisable (ADC0_BASE、0); ADCSequenceDisable (ADC0_BASE、0); //禁用序列后,现在可以安全地加载新的配置参数 ADCSequenceConfigure (ADC0_BASE、0、ADC_TRIGGER_TIMER、0); ADCSequenceStepConfigure (ADC0_BASE、0、0、ADC_CTL_CH1| ADC_CTL_END | ADC_CTL_IE); ADCSequenceEnable (ADC0_BASE、0);//设置配置后、重新启用序列发生器 ADCIntClear (ADC0_BASE、0); uDMAEnable();//启用 UDMA uDMAControlBaseSet (ucControlTable); ADCSequenceDMAEnable (ADC0_BASE、0); //允许基于采样序列发生器(SS0)的 FIFO 级别生成 DMA 请求 uDMAChannelAttributeDisable (UDMA_CHANGE_ADC0、UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIOR| UDMA_ATTR_REQMASK); uDMAChannelAttributeEnable (UDMA_CHANGE_ADC0、UDMA_ATTR_USEBURST); //仅允许突发传输 uDMAChannelControlSet (UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT、UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_ARC_16 | UDMA_INC_1024); uDMAChannelTransferSet (UDMA_CHANGE_ADC0 | UDMA_PRI_SELECT、UDMA_MODE_BASIC、(void *)(ADC0_BASE + ADC_O_SSFIFO0)、&ADC_OUT、ADC_SAMPLE_BUF_SIZE); ADCIntEnable (ADC0_BASE、0); IntEnable (INT_ADC0SS0); uDMAChannelEnable (UDMA_CHANGE_ADC0);//启用 DMA 通道以便它可以执行传输 }