提问:
近期,我在学习msp432p401r单片机时,想用msp的adc进行多通道采集,然后加上dma数据转运。以下是代码起初我是直接用的dma里的adc通道,发现不行。然后我就仿照官方例程里的进行数组到数组间的转运 resultsBuffer -->adc 的转运,结果还是失败了
在主函数里我就是显示了一下数组里的值,发现程序卡死。希望能得到大佬的帮助。
#include "headfile.h"
#include "adc.h"
#include "ml_oled.h"
//左到右 4.3 4.4 4.5 4.6 4.7
// 10 9 8 7 6
uint16_t adc[5];
uint16_t resultsBuffer[5];
void ADC_config(void)
{
/* 启用浮点运算的FPU */
MAP_FPU_enableModule();
MAP_FPU_enableLazyStacking();
/* Initializing ADC (MCLK/1/1) */
MAP_ADC14_enableModule(); //使能ADC14模块
MAP_ADC14_initModule(ADC_CLOCKSOURCE_MCLK, ADC_PREDIVIDER_4, ADC_DIVIDER_5, ADC_NOROUTE); //初始化ADC 时钟 分频 通道 2.4MHz
MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P4, GPIO_PIN5 | GPIO_PIN6 | GPIO_PIN7| GPIO_PIN3| GPIO_PIN4, GPIO_TERTIARY_MODULE_FUNCTION);
// MAP_GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, GPIO_PIN1 | GPIO_PIN2, GPIO_TERTIARY_MODULE_FUNCTION); //
MAP_ADC14_configureMultiSequenceMode(ADC_MEM6, ADC_MEM10, true);
MAP_ADC14_configureConversionMemory(ADC_MEM6, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A6, ADC_NONDIFFERENTIAL_INPUTS);
MAP_ADC14_configureConversionMemory(ADC_MEM7, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A7, ADC_NONDIFFERENTIAL_INPUTS);
MAP_ADC14_configureConversionMemory(ADC_MEM8, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A8, ADC_NONDIFFERENTIAL_INPUTS);
MAP_ADC14_configureConversionMemory(ADC_MEM9, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A9, ADC_NONDIFFERENTIAL_INPUTS);
MAP_ADC14_configureConversionMemory(ADC_MEM10, ADC_VREFPOS_INTBUF_VREFNEG_VSS, ADC_INPUT_A10, ADC_NONDIFFERENTIAL_INPUTS);
ADC14_enableInterrupt(ADC_INT10);
/* Enabling Interrupts */
MAP_Interrupt_enableInterrupt(INT_ADC14); //ADC模块的中断
MAP_Interrupt_enableMaster();
/* Setting up the sample timer to automatically step through the sequence
* convert.
*/
ADC14_enableSampleTimer(ADC_AUTOMATIC_ITERATION);
/* Triggering the start of the sample */
MAP_ADC14_enableConversion(); //使能开始转换(触发后 自动ADC上电)
MAP_ADC14_toggleConversionTrigger(); //开启第一次软件触发
}
////////////////////DMA配置///////////////////////////////
/* DMA Control Table 这一段是必须要有的*///
#if defined(__TI_COMPILER_VERSION__)
#pragma DATA_ALIGN(controlTable, 1024)
#elif defined(__IAR_SYSTEMS_ICC__)
#pragma data_alignment = 1024
#elif defined(__GNUC__)
__attribute__((aligned(1024)))
#elif defined(__CC_ARM)
__align(1024)
#endif
uint8_t controlTable[1024];
/**************************************/
#define DAM_SIZE 1024
uint16_t data_array1[DAM_SIZE]; // DMA数组
void DMA_config(void)
{
MAP_WDT_A_holdTimer(); // 关闭看门狗
memset(data_array1, 0x11, DAM_SIZE); // 目标数组初始化
DMA_enableModule(); // 使能DMA模块
DMA_setControlBase(controlTable); // 设置控制表基地址
DMA_disableChannelAttribute(DMA_CH0_RESERVED0,
UDMA_ATTR_ALTSELECT | UDMA_ATTR_USEBURST |
UDMA_ATTR_HIGH_PRIORITY |
UDMA_ATTR_REQMASK); // 禁用通道特征
DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH0_RESERVED0, UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_16 | UDMA_ARB_1);
// 设置通道控制参数 ADC映射 主数据结构 16位数据大小 源地址增量 目标地址增量 仲裁大小
DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH0_RESERVED0, UDMA_MODE_AUTO, resultsBuffer, adc, 5);
// 设置通道传输参数 ADC映射 主数据结构 自动模式 源数据 目标数据 传输数量
MAP_Interrupt_disableSleepOnIsrExit();
DMA_requestChannel(0);
// DMA_assignChannel(DMA_CH0_RESERVED0); // 指定外设映射
DMA_assignInterrupt(DMA_INT0, 0);
Interrupt_enableInterrupt(INT_DMA_INT0);
DMA_clearInterruptFlag(0);
Interrupt_enableMaster();
DMA_enableChannel(0);
ADC14_enableConversion();
DMA_requestSoftwareTransfer(0); //
}
void DMA_INT1_IRQHandler(void)
{
DMA_requestChannel(0);
DMA_assignChannel(DMA_CH0_RESERVED0); // 指定外设映射
DMA_assignInterrupt(DMA_INT0, 0);
Interrupt_enableInterrupt(INT_DMA_INT0);
DMA_clearInterruptFlag(0);
DMA_enableChannel(0);
ADC14_enableConversion();
/* Switch between primary and alternate bufferes with DMA's PingPong mode */
DMA_setChannelControl(UDMA_PRI_SELECT | DMA_CH0_RESERVED0,
UDMA_SIZE_16 | UDMA_SRC_INC_16 | UDMA_DST_INC_16 | UDMA_ARB_1);
DMA_setChannelTransfer(UDMA_PRI_SELECT | DMA_CH0_RESERVED0,
UDMA_MODE_AUTO, resultsBuffer,
adc, 5);
DMA_requestSoftwareTransfer(0);
}
void ADC14_IRQHandler(void)
{
uint_fast64_t status = MAP_ADC14_getEnabledInterruptStatus();
MAP_ADC14_clearInterruptFlag(status);
if (ADC_INT10 & status)
{
MAP_ADC14_getMultiSequenceResult(resultsBuffer);
}
}
|