This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

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);

    // 配置 GPIO
    GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);  // PE3 作为 ADC 输入引脚

    // 启用并配置 DMA
    uDMAEnable();
    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);

    // 配置 ADC
    ADCClockConfigSet(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.

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

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

  • 您好, 都用ADC0_BASE。

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

  • 您好,请参考示例代码。

  • #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);
    
        // 配置 GPIO
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);  // PE3 作为 ADC 输入引脚
    
        // 启用并配置 DMA
        uDMAEnable();
        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);
    
        // 配置 ADC
        ADCClockConfigSet(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);  仍然进不去中断

  • #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);
    
        // 配置 GPIO
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);  // PE3 作为 ADC 输入引脚
    
        // 启用并配置 DMA
        uDMAEnable();
        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);
    
        // 配置 ADC
        ADCClockConfigSet(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);仍然进不去中断 

  • 您好,

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

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

  • 您好,

          

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

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

  • 已解决上述问题 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);
    
        // 配置 GPIO
        GPIOPinTypeADC(GPIO_PORTE_BASE, GPIO_PIN_3);  // PE3 作为 ADC 输入引脚
    
        // 启用并配置 DMA
        uDMAEnable();
        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);
    
        // 配置 ADC
        ADCClockConfigSet(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);
    	
    	
    		
    }

  • 您好,

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