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.
#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); }
#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); }
#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); }
已解决上述问题 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); }