TI中文支持网
TI专业的中文技术问题搜集分享网站

EK-TM4C1294XL: ADC1 cannot interrupt, but ADC0 has no problem with the same code

Part Number:EK-TM4C1294XL

#include "bsp.h"
#include "inc/hw_memmap.h"
#include "inc/hw_adc.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/adc.h"
#include "driverlib/udma.h"
#include "driverlib/timer.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#define DMA_CHANNEL UDMA_CHANNEL_ADC1  // 使用 ADC1 的 DMA 通道

// 全局变量
uint16_t Data[ADC_SAMPLE_BUF_SIZE];  // 存储完整 ADC 数据的数组
volatile uint8_t flag = 0;// 标志采集是否完成
uint16_t ADCBuffer1[DMA_TRANSFER_SIZE];  // 缓冲区1
uint16_t ADCBuffer2[DMA_TRANSFER_SIZE];  // 缓冲区2
uint16_t bufferIndex = 0;// 当前搬移到 Data 数组的索引
uint16_t totalSamples = 0;// 记录已搬移的总样本数
static uint8_t ControlTable[2048] __attribute__((aligned(1024)));  // DMA 控制表

BUFFER_STATUS BufferStatus[2];  // 缓冲区状态

// ADC 队列 1 中断服务程序
void ADC1SS0_Handler(void) {// 修改为 ADC1 的中断处理函数// 清中断标志ADCIntClear(ADC1_BASE, 0);ADCIntClearEx(ADC1_BASE, ADC_INT_DMA_SS0);if ((uDMAChannelModeGet(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT) == UDMA_MODE_STOP) && (BufferStatus[0] == FILLING)) {BufferStatus[0] = FULL;BufferStatus[1] = FILLING;} else if ((uDMAChannelModeGet(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT) == UDMA_MODE_STOP) && (BufferStatus[1] == FILLING)) {BufferStatus[0] = FILLING;BufferStatus[1] = FULL;}if (BufferStatus[0] == FULL) {BufferStatus[0] = EMPTY;//使能另一个传输块uDMAChannelTransferSet(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT,UDMA_MODE_PINGPONG,(void *)(ADC1_BASE + ADC_O_SSFIFO0),ADCBuffer1, DMA_TRANSFER_SIZE);//启动DMA通道uDMAChannelEnable(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT);for (uint16_t i = 0; i < DMA_TRANSFER_SIZE; i++)Data[totalSamples++] = ADCBuffer1[i];} else if (BufferStatus[1] == FULL) {BufferStatus[1] = EMPTY;uDMAChannelTransferSet(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT,UDMA_MODE_PINGPONG,(void *)(ADC1_BASE + ADC_O_SSFIFO0),ADCBuffer2, DMA_TRANSFER_SIZE);uDMAChannelEnable(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT);for (uint16_t i = 0; i < DMA_TRANSFER_SIZE; i++)Data[totalSamples++] = ADCBuffer2[i];}if (totalSamples >= ADC_SAMPLE_BUF_SIZE) {flag = 1;StopADC();}
}

// 初始化 ADC 和 DMA
void bsp_InitAdc0(void) {  // 修改为初始化 ADC1 的函数BufferStatus[0] = FILLING;BufferStatus[1] = EMPTY;// 启用外设SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);// 配置 GPIOGPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);  // PE3 作为 ADC 输入引脚// 启用并配置 DMAuDMAEnable();uDMAControlBaseSet(ControlTable);uDMAChannelAttributeDisable(DMA_CHANNEL, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);// 设置 DMA 主控制块uDMAChannelControlSet(DMA_CHANNEL | UDMA_PRI_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);// 设置 DMA 副控制块uDMAChannelControlSet(DMA_CHANNEL | UDMA_ALT_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);// 设置 DMA 传输(主缓冲区)uDMAChannelTransferSet(DMA_CHANNEL | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC1_BASE + ADC_O_SSFIFO0), ADCBuffer1, DMA_TRANSFER_SIZE);// 设置 DMA 传输(副缓冲区)uDMAChannelTransferSet(DMA_CHANNEL | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC1_BASE + ADC_O_SSFIFO0), ADCBuffer2, DMA_TRANSFER_SIZE);uDMAChannelAttributeEnable(DMA_CHANNEL, UDMA_ATTR_USEBURST);uDMAChannelEnable(DMA_CHANNEL);// 配置 ADCADCClockConfigSet(ADC1_BASE, ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_FULL, 1);SysCtlDelay(10);ADCSequenceDisable(ADC1_BASE, 0);ADCSequenceConfigure(ADC1_BASE, 0, ADC_TRIGGER_TIMER, 0);ADCSequenceStepConfigure(ADC1_BASE, 0, 0, ADC_CTL_CH0 | ADC_CTL_END);ADCSequenceEnable(ADC1_BASE, 0);ADCSequenceDMAEnable(ADC1_BASE, 0);ADCIntEnableEx(ADC1_BASE, ADC_INT_DMA_SS0);IntEnable(INT_ADC1SS0);  // 修改为 ADC1 的中断使能IntMasterEnable();// 配置定时器TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC);TimerLoadSet(TIMER0_BASE, TIMER_A, (SysCtlClockGet() / 1000) - 1);TimerControlTrigger(TIMER0_BASE, TIMER_A, true);
}

// 启动 ADC
void StartADC(void) {// 重置标志和计数器flag = 0;totalSamples = 0;// 重新初始化缓冲区状态BufferStatus[0] = FILLING;BufferStatus[1] = EMPTY;// 清除可能残留的中断标志ADCIntClear(ADC1_BASE, 0);// 启用 DMA 通道uDMAChannelEnable(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT);uDMAChannelEnable(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT);// 重新使能 ADC 采样序列ADCSequenceEnable(ADC1_BASE, 0);IntEnable(INT_ADC1SS0);  // 修改为 ADC1 的中断使能// 启用定时器,触发 ADC 采样TimerEnable(TIMER0_BASE, TIMER_A);
}

// 停止 ADC
void StopADC(void) {// 禁用定时器TimerDisable(TIMER0_BASE, TIMER_A);// 禁用 DMA 通道uDMAChannelDisable(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT);uDMAChannelDisable(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT);// 禁用 ADC 采样序列0//ADCSequenceDisable(ADC1_BASE, 0);  // 可选,视需要而定// 禁用 ADC 中断ADCIntDisable(ADC1_BASE, 0);IntDisable(INT_ADC1SS0);// 确保清除所有中断标志ADCIntClear(ADC1_BASE, 0);
}

After changing ADC0 to ADC1, I cannot access ADC1 interrupt.

Alice:

您好,

  

  请参考接口驱动手册。

TivaWareTm Peripheral Driver Library for C Series User's Guide (Rev. E)

,

PandaFeng:

adc1不需要配置时钟吗 我没找到别的config接口

,

PandaFeng:

ADC1不需要配置吗 没找到相关config接口

,

Alice:

您好, 都用ADC0_BASE。

,

PandaFeng:

感谢您,能帮我审计下这样的代码能否正确启动和停止adc吗?再次感谢

,

Alice:

您好,请参考示例代码。

,

PandaFeng:

#include "bsp.h"
#include "inc/hw_memmap.h"
#include "inc/hw_adc.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/adc.h"
#include "driverlib/udma.h"
#include "driverlib/timer.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#define DMA_CHANNEL UDMA_CHANNEL_ADC1// 全局变量
uint16_t Data[ADC_SAMPLE_BUF_SIZE];// 存储完整 ADC 数据的数组
volatile uint8_t flag = 0;// 标志采集是否完成
uint16_t ADCBuffer1[DMA_TRANSFER_SIZE];// 缓冲区1
uint16_t ADCBuffer2[DMA_TRANSFER_SIZE];// 缓冲区2
uint16_t bufferIndex = 0;// 当前搬移到 Data 数组的索引
uint16_t totalSamples = 0;// 记录已搬移的总样本数
static uint8_t ControlTable[1024] __attribute__((aligned(1024)));// DMA 控制表BUFFER_STATUS BufferStatus[2];// 缓冲区状态// ADC 队列 0 中断服务程序
void ADC1SS0_Handler(void) {// 清中断标志ADCIntClear(ADC1_BASE, 0);ADCIntClearEx(ADC1_BASE, ADC_INT_DMA_SS0);if ((uDMAChannelModeGet(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT) ==UDMA_MODE_STOP) && (BufferStatus[0] == FILLING)) {BufferStatus[0] = FULL;BufferStatus[1] = FILLING;} else if ((uDMAChannelModeGet(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT) ==UDMA_MODE_STOP) && (BufferStatus[1] == FILLING)) {BufferStatus[0] = FILLING;BufferStatus[1] = FULL;}if(BufferStatus[0] == FULL) {BufferStatus[0] = EMPTY;//使能另一个传输块uDMAChannelTransferSet(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT,UDMA_MODE_PINGPONG,(void *)(ADC1_BASE + ADC_O_SSFIFO0),ADCBuffer1, DMA_TRANSFER_SIZE);//启动DMA通道uDMAChannelEnable(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT);for(uint16_t i =0 ;i<DMA_TRANSFER_SIZE ; i++)Data[totalSamples++]=ADCBuffer1[i];} else if(BufferStatus[1] == FULL) {BufferStatus[1] = EMPTY;uDMAChannelTransferSet(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT,UDMA_MODE_PINGPONG,(void *)(ADC1_BASE + ADC_O_SSFIFO0),ADCBuffer2, DMA_TRANSFER_SIZE);uDMAChannelEnable(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT);for(uint16_t i =0 ;i<DMA_TRANSFER_SIZE ; i++)Data[totalSamples++]=ADCBuffer2[i];}if(totalSamples >=ADC_SAMPLE_BUF_SIZE){flag=1;StopADC();}
}// 初始化 ADC 和 DMA
void bsp_InitAdc0(void) {BufferStatus[0] = FILLING;BufferStatus[1] = EMPTY;// 启用外设SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);// 配置 GPIOGPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);// PE3 作为 ADC 输入引脚// 启用并配置 DMAuDMAEnable();uDMAControlBaseSet(ControlTable);uDMAChannelAttributeDisable(DMA_CHANNEL, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);// 设置 DMA 主控制块uDMAChannelControlSet(DMA_CHANNEL | UDMA_PRI_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);// 设置 DMA 副控制块uDMAChannelControlSet(DMA_CHANNEL | UDMA_ALT_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);// 设置 DMA 传输(主缓冲区)uDMAChannelTransferSet(DMA_CHANNEL | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC1_BASE + ADC_O_SSFIFO0), &ADCBuffer1, DMA_TRANSFER_SIZE);// 设置 DMA 传输(副缓冲区)uDMAChannelTransferSet(DMA_CHANNEL | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC1_BASE + ADC_O_SSFIFO0), &ADCBuffer2, DMA_TRANSFER_SIZE);uDMAChannelAttributeEnable(DMA_CHANNEL, UDMA_ATTR_USEBURST);uDMAChannelEnable(DMA_CHANNEL);// 配置 ADCADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_FULL, 1);SysCtlDelay(10);ADCSequenceDisable(ADC1_BASE, 0);ADCSequenceConfigure(ADC1_BASE, 0, ADC_TRIGGER_TIMER, 0);ADCSequenceStepConfigure(ADC1_BASE, 0, 0, ADC_CTL_CH0 | ADC_CTL_END);ADCSequenceEnable(ADC1_BASE, 0);ADCSequenceDMAEnable(ADC1_BASE, 0);ADCIntEnableEx(ADC1_BASE, ADC_INT_DMA_SS0);IntEnable(INT_ADC1SS0);IntMasterEnable();// 配置定时器TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC);TimerLoadSet(TIMER0_BASE, TIMER_A, (SysCtlClockGet() / 1000) - 1);TimerControlTrigger(TIMER0_BASE, TIMER_A, true);
}// 启动 ADC
// 启动 ADC
void StartADC(void) {// 重置标志和计数器flag = 0;totalSamples = 0;// 重新初始化缓冲区状态BufferStatus[0] = FILLING;BufferStatus[1] = EMPTY;// 清除可能残留的中断标志ADCIntClear(ADC1_BASE, 0);// 重新设置 DMA 通道,保证它们处于正确的传输模式uDMAChannelTransferSet(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT,UDMA_MODE_PINGPONG,(void *)(ADC1_BASE + ADC_O_SSFIFO0),ADCBuffer1, DMA_TRANSFER_SIZE);uDMAChannelTransferSet(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT,UDMA_MODE_PINGPONG,(void *)(ADC1_BASE + ADC_O_SSFIFO0),ADCBuffer2, DMA_TRANSFER_SIZE);// 启用 DMA 通道uDMAChannelEnable(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT);uDMAChannelEnable(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT);// 重新使能 ADC 采样序列ADCSequenceEnable(ADC1_BASE, 0);IntEnable(INT_ADC1SS0);// 启用定时器,触发 ADC 采样TimerEnable(TIMER0_BASE, TIMER_A);
}// 停止 ADC
void StopADC(void) {// 禁用定时器TimerDisable(TIMER0_BASE, TIMER_A);// 禁用 DMA 通道uDMAChannelDisable(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT);uDMAChannelDisable(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT);// 禁用 ADC 采样序列0//ADCSequenceDisable(ADC1_BASE, 0);// 禁用 ADC 中断ADCIntDisable(ADC1_BASE, 0);IntDisable(INT_ADC1SS0);// 确保清除所有中断标志ADCIntClear(ADC1_BASE, 0);}

您好,按照你的说法,修改 ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_FULL, 1);  仍然进不去中断

,

PandaFeng:

#include "bsp.h"
#include "inc/hw_memmap.h"
#include "inc/hw_adc.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/adc.h"
#include "driverlib/udma.h"
#include "driverlib/timer.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#define DMA_CHANNEL UDMA_CHANNEL_ADC1// 全局变量
uint16_t Data[ADC_SAMPLE_BUF_SIZE];// 存储完整 ADC 数据的数组
volatile uint8_t flag = 0;// 标志采集是否完成
uint16_t ADCBuffer1[DMA_TRANSFER_SIZE];// 缓冲区1
uint16_t ADCBuffer2[DMA_TRANSFER_SIZE];// 缓冲区2
uint16_t bufferIndex = 0;// 当前搬移到 Data 数组的索引
uint16_t totalSamples = 0;// 记录已搬移的总样本数
static uint8_t ControlTable[1024] __attribute__((aligned(1024)));// DMA 控制表BUFFER_STATUS BufferStatus[2];// 缓冲区状态// ADC 队列 0 中断服务程序
void ADC1SS0_Handler(void) {// 清中断标志ADCIntClear(ADC1_BASE, 0);ADCIntClearEx(ADC1_BASE, ADC_INT_DMA_SS0);if ((uDMAChannelModeGet(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT) ==UDMA_MODE_STOP) && (BufferStatus[0] == FILLING)) {BufferStatus[0] = FULL;BufferStatus[1] = FILLING;} else if ((uDMAChannelModeGet(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT) ==UDMA_MODE_STOP) && (BufferStatus[1] == FILLING)) {BufferStatus[0] = FILLING;BufferStatus[1] = FULL;}if(BufferStatus[0] == FULL) {BufferStatus[0] = EMPTY;//使能另一个传输块uDMAChannelTransferSet(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT,UDMA_MODE_PINGPONG,(void *)(ADC1_BASE + ADC_O_SSFIFO0),ADCBuffer1, DMA_TRANSFER_SIZE);//启动DMA通道uDMAChannelEnable(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT);for(uint16_t i =0 ;i<DMA_TRANSFER_SIZE ; i++)Data[totalSamples++]=ADCBuffer1[i];} else if(BufferStatus[1] == FULL) {BufferStatus[1] = EMPTY;uDMAChannelTransferSet(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT,UDMA_MODE_PINGPONG,(void *)(ADC1_BASE + ADC_O_SSFIFO0),ADCBuffer2, DMA_TRANSFER_SIZE);uDMAChannelEnable(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT);for(uint16_t i =0 ;i<DMA_TRANSFER_SIZE ; i++)Data[totalSamples++]=ADCBuffer2[i];}if(totalSamples >=ADC_SAMPLE_BUF_SIZE){flag=1;StopADC();}
}// 初始化 ADC 和 DMA
void bsp_InitAdc0(void) {BufferStatus[0] = FILLING;BufferStatus[1] = EMPTY;// 启用外设SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC1);SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);// 配置 GPIOGPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);// PE3 作为 ADC 输入引脚// 启用并配置 DMAuDMAEnable();uDMAControlBaseSet(ControlTable);uDMAChannelAttributeDisable(DMA_CHANNEL, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);// 设置 DMA 主控制块uDMAChannelControlSet(DMA_CHANNEL | UDMA_PRI_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);// 设置 DMA 副控制块uDMAChannelControlSet(DMA_CHANNEL | UDMA_ALT_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);// 设置 DMA 传输(主缓冲区)uDMAChannelTransferSet(DMA_CHANNEL | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC1_BASE + ADC_O_SSFIFO0), &ADCBuffer1, DMA_TRANSFER_SIZE);// 设置 DMA 传输(副缓冲区)uDMAChannelTransferSet(DMA_CHANNEL | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC1_BASE + ADC_O_SSFIFO0), &ADCBuffer2, DMA_TRANSFER_SIZE);uDMAChannelAttributeEnable(DMA_CHANNEL, UDMA_ATTR_USEBURST);uDMAChannelEnable(DMA_CHANNEL);// 配置 ADCADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_FULL, 1);SysCtlDelay(10);ADCSequenceDisable(ADC1_BASE, 0);ADCSequenceConfigure(ADC1_BASE, 0, ADC_TRIGGER_TIMER, 0);ADCSequenceStepConfigure(ADC1_BASE, 0, 0, ADC_CTL_CH0 | ADC_CTL_END);ADCSequenceEnable(ADC1_BASE, 0);ADCSequenceDMAEnable(ADC1_BASE, 0);ADCIntEnableEx(ADC1_BASE, ADC_INT_DMA_SS0);IntEnable(INT_ADC1SS0);IntMasterEnable();// 配置定时器TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC);TimerLoadSet(TIMER0_BASE, TIMER_A, (SysCtlClockGet() / 1000) - 1);TimerControlTrigger(TIMER0_BASE, TIMER_A, true);
}// 启动 ADC
// 启动 ADC
void StartADC(void) {// 重置标志和计数器flag = 0;totalSamples = 0;// 重新初始化缓冲区状态BufferStatus[0] = FILLING;BufferStatus[1] = EMPTY;// 清除可能残留的中断标志ADCIntClear(ADC1_BASE, 0);// 重新设置 DMA 通道,保证它们处于正确的传输模式uDMAChannelTransferSet(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT,UDMA_MODE_PINGPONG,(void *)(ADC1_BASE + ADC_O_SSFIFO0),ADCBuffer1, DMA_TRANSFER_SIZE);uDMAChannelTransferSet(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT,UDMA_MODE_PINGPONG,(void *)(ADC1_BASE + ADC_O_SSFIFO0),ADCBuffer2, DMA_TRANSFER_SIZE);// 启用 DMA 通道uDMAChannelEnable(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT);uDMAChannelEnable(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT);// 重新使能 ADC 采样序列ADCSequenceEnable(ADC1_BASE, 0);IntEnable(INT_ADC1SS0);// 启用定时器,触发 ADC 采样TimerEnable(TIMER0_BASE, TIMER_A);
}// 停止 ADC
void StopADC(void) {// 禁用定时器TimerDisable(TIMER0_BASE, TIMER_A);// 禁用 DMA 通道uDMAChannelDisable(UDMA_CHANNEL_ADC1 | UDMA_PRI_SELECT);uDMAChannelDisable(UDMA_CHANNEL_ADC1 | UDMA_ALT_SELECT);// 禁用 ADC 采样序列0//ADCSequenceDisable(ADC1_BASE, 0);// 禁用 ADC 中断ADCIntDisable(ADC1_BASE, 0);IntDisable(INT_ADC1SS0);// 确保清除所有中断标志ADCIntClear(ADC1_BASE, 0);}

 改为ADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_FULL, 1);仍然进不去中断 

,

Alice:

您好,

      您单步调试一下,确认一下问题。

,

PandaFeng:

卡在时钟配置上  我加了初始化ADC0外设后 就不会卡住 但仍然进不去中断

,

Alice:

您好,

      

         请对照这个帖子的解决方法检查您的代码。

         TM4C123GH6PM: ADC0 works but ADC1 not – Arm-based microcontrollers forum – Arm-based microcontrollers – TI E2E support forums      

,

PandaFeng:

已解决上述问题 ADC1的DMA通道搞错

帮我看看下面的新问题,我通过定时器触发ADC采样,最大采样率只能达到1M,如果我把定时器触发改成2M,采出来的波形仍然是1M采样率采出来的波形。但小于1M时,采样率正常

#include "bsp.h"
#include "inc/hw_memmap.h"
#include "inc/hw_adc.h"
#include "driverlib/sysctl.h"
#include "driverlib/gpio.h"
#include "driverlib/adc.h"
#include "driverlib/udma.h"
#include "driverlib/timer.h"
#include "driverlib/interrupt.h"
#include "driverlib/pin_map.h"
#include "string.h"
#define DMA_CHANNEL UDMA_CHANNEL_ADC0// 全局变量
uint16_t Data[ADC_SAMPLE_BUF_SIZE];// 存储完整 ADC 数据的数组
volatile uint8_t flag = 0;// 标志采集是否完成
uint16_t ADCBuffer1[DMA_TRANSFER_SIZE];// 缓冲区1
uint16_t ADCBuffer2[DMA_TRANSFER_SIZE];// 缓冲区2
uint16_t bufferIndex = 0;// 当前搬移到 Data 数组的索引
uint16_t totalSamples = 0;// 记录已搬移的总样本数
static uint8_t ControlTable[1024] __attribute__((aligned(1024)));// DMA 控制表BUFFER_STATUS BufferStatus[2];// 缓冲区状态// ADC 队列 0 中断服务程序
void ADC0SS0_Handler(void) {// 清中断标志ADCIntClear(ADC0_BASE, 0);ADCIntClearEx(ADC0_BASE, ADC_INT_DMA_SS0);if ((uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT) ==UDMA_MODE_STOP) && (BufferStatus[0] == FILLING)) {BufferStatus[0] = FULL;BufferStatus[1] = FILLING;} else if ((uDMAChannelModeGet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT) ==UDMA_MODE_STOP) && (BufferStatus[1] == FILLING)) {BufferStatus[0] = FILLING;BufferStatus[1] = FULL;}if(BufferStatus[0] == FULL) {BufferStatus[0] = EMPTY;//使能另一个传输块uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT,UDMA_MODE_PINGPONG,(void *)(ADC0_BASE + ADC_O_SSFIFO0),ADCBuffer1, DMA_TRANSFER_SIZE);//启动DMA通道uDMAChannelEnable(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT);
//for(uint16_t i =0 ;i<DMA_TRANSFER_SIZE ; i++)
//Data[totalSamples++]=ADCBuffer1[i];memcpy(Data+totalSamples,ADCBuffer1,DMA_TRANSFER_SIZE*sizeof(uint16_t));totalSamples+=1024;} else if(BufferStatus[1] == FULL) {BufferStatus[1] = EMPTY;uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT,UDMA_MODE_PINGPONG,(void *)(ADC0_BASE + ADC_O_SSFIFO0),ADCBuffer2, DMA_TRANSFER_SIZE);uDMAChannelEnable(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT);
//for(uint16_t i =0 ;i<DMA_TRANSFER_SIZE ; i++)
//Data[totalSamples++]=ADCBuffer2[i];memcpy(Data+totalSamples,ADCBuffer2,DMA_TRANSFER_SIZE*sizeof(uint16_t));totalSamples+=1024;}if(totalSamples >=ADC_SAMPLE_BUF_SIZE){flag=1;StopADC();}
}// 初始化 ADC 和 DMA
void bsp_InitAdc0(void) {BufferStatus[0] = FILLING;BufferStatus[1] = EMPTY;// 启用外设SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC0);SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER0);SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOE);// 配置 GPIOGPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);// PE3 作为 ADC 输入引脚// 启用并配置 DMAuDMAEnable();uDMAControlBaseSet(ControlTable);uDMAChannelAttributeDisable(UDMA_CHANNEL_ADC0, UDMA_ATTR_ALTSELECT | UDMA_ATTR_HIGH_PRIORITY | UDMA_ATTR_REQMASK);// 设置 DMA 主控制块uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);// 设置 DMA 副控制块uDMAChannelControlSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_SIZE_16 | UDMA_SRC_INC_NONE | UDMA_DST_INC_16 | UDMA_ARB_1);// 设置 DMA 传输(主缓冲区)uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO0), &ADCBuffer1, DMA_TRANSFER_SIZE);// 设置 DMA 传输(副缓冲区)uDMAChannelTransferSet(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT, UDMA_MODE_PINGPONG, (void *)(ADC0_BASE + ADC_O_SSFIFO0), &ADCBuffer2, DMA_TRANSFER_SIZE);uDMAChannelAttributeEnable(UDMA_CHANNEL_ADC0, UDMA_ATTR_USEBURST);uDMAChannelEnable(UDMA_CHANNEL_ADC0);// 配置 ADCADCClockConfigSet(ADC0_BASE, ADC_CLOCK_SRC_PIOSC | ADC_CLOCK_RATE_FULL, 1);SysCtlDelay(10);ADCSequenceDisable(ADC0_BASE, 0);ADCSequenceConfigure(ADC0_BASE, 0, ADC_TRIGGER_TIMER, 0);ADCSequenceStepConfigure(ADC0_BASE, 0, 0, ADC_CTL_CH0 | ADC_CTL_END);ADCSequenceEnable(ADC0_BASE, 0);ADCSequenceDMAEnable(ADC0_BASE, 0);ADCIntEnableEx(ADC0_BASE, ADC_INT_DMA_SS0);IntEnable(INT_ADC0SS0);IntMasterEnable();// 配置定时器TimerConfigure(TIMER0_BASE, TIMER_CFG_SPLIT_PAIR | TIMER_CFG_A_PERIODIC);TimerLoadSet(TIMER0_BASE, TIMER_A, (SystemCoreClock / 2000000) - 1);TimerControlTrigger(TIMER0_BASE, TIMER_A, true);
}// 启动 ADC
void StartADC(void) {// 重置标志和计数器flag = 0;totalSamples = 0;// 重新初始化缓冲区状态BufferStatus[0] = FILLING;BufferStatus[1] = EMPTY;// 清除可能残留的中断标志ADCIntClear(ADC0_BASE, 0);// 启用 DMA 通道uDMAChannelEnable(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT);uDMAChannelEnable(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT);// 重新使能 ADC 采样序列ADCSequenceEnable(ADC0_BASE, 0);IntEnable(INT_ADC0SS0);// 启用定时器,触发 ADC 采样TimerEnable(TIMER0_BASE, TIMER_A);
}// 停止 ADC
void StopADC(void) {// 禁用定时器TimerDisable(TIMER0_BASE, TIMER_A);// 禁用 DMA 通道uDMAChannelDisable(UDMA_CHANNEL_ADC0 | UDMA_PRI_SELECT);uDMAChannelDisable(UDMA_CHANNEL_ADC0 | UDMA_ALT_SELECT);// 禁用 ADC 中断ADCIntDisable(ADC0_BASE, 0);IntDisable(INT_ADC0SS0);// 确保清除所有中断标志ADCIntClear(ADC0_BASE, 0);}

,

Alice:

您好,

      为方便问题归类,新问题,请重新发帖专题讨论,谢谢。

赞(0)
未经允许不得转载:TI中文支持网 » EK-TM4C1294XL: ADC1 cannot interrupt, but ADC0 has no problem with the same code
分享到: 更多 (0)