主题中讨论的其他器件: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 通道以便它可以执行传输
}