#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.

