【经验】32位MCU的LDMA实现ADC至RAM的数据传输调试方法
SILICON LABS的EFM32PG/ EFM32JG系列32位MCU具有超低功耗、高性能、丰富的外设等特点,被广泛使用于各种行业。EFM32PG/ EFM32JG的LDMA相比于series 0的DMA具有更多的传输方式,更适合应用于电池供电的产品。
本文为大家介绍EFM32PG的LDMA实现ADC至RAM的数据传输调试方法。详细的工作过程是:MCU在EM2模式,开启LETIMER0定时触发ADC采样,ADC采样的结果存入ADC的FIFO,FIFO存满后通过LDMA将数据存入到定义的数组中。硬件是基于EFM32PG的SLSTK3401A,软件基于Simplicity Studio V3。
1、ADC初始化
ADC初始化函数如下。ADC要想在EM2或EM3模式下工作,ADC_CLK必须选择AUXHFRCO时钟源。配置ADC触发LDMA的条件,ADC0具有4个FIFO,此例程的条件是4个FIFO存满后触发LDMA。配置当LDMA触发条件满足时是否唤醒LDMA,并且配置ADC的时钟为异步时钟模式。关闭ADC的中断,使能PRS。
void setupAdc(void)
{
CMU->ADCCTRL = 0x00000010;
CMU_ClockEnable(cmuClock_ADC0, true);
CMU_AUXHFRCOFreqSet(cmuAUXHFRCOFreq_4M0Hz);
ADC_Init_TypeDef init =
{
adcOvsRateSel2, /* 2x oversampling (if enabled). */
adcWarmupNormal, /* ADC shutdown after each conversion. */
_ADC_CTRL_TIMEBASE_DEFAULT, /* Use HW default value. */
_ADC_CTRL_PRESC_DEFAULT, /* Use HW default value. */
false, /* Do not use tailgate. */
adcEm2ClockOnDemand /* ADC disabled in EM2 */
};
ADC_InitSingle_TypeDef singleInit =
{
adcPRSSELCh0, /* PRS ch0 (if enabled). */
adcAcqTime1, /* 1 ADC_CLK cycle acquisition time. */
adcRefVDD, /* VDD reference. */
adcRes12Bit, /* 12 bit resolution. */
adcPosSelAPORT4XCH1, /* Select node BUS0XCH0 as posSel */
adcNegSelVSS, /* Select node BUS0XCH1 as negSel */
false, /* Single ended input. */
true, /* PRS enabled. */
false, /* Right adjust. */
false, /* Deactivate conversion after one scan sequence. */
false, /* No EM2 DMA wakeup from single FIFO DVL */
false /* Discard new data on full FIFO. */
};
/* Init common settings for both single conversion and scan mode- */
/* Set timebase to 10, this gives 11 cycles which equals 1us at 11 MHz. */
init.timebase = ADC_TimebaseCalc(CMU_AUXHFRCOBandGet());
/* Set ADC clock prescaler to 0, we are using 11MHz HFRCO, which results in HFPERCLK < 13MHz- */
init.prescale = ADC_PrescaleCalc(1000000, CMU_AUXHFRCOBandGet());
ADC_Init(ADC0, &init);
/* Init for single conversion use, measure channel 0 with Vdd as reference. */
/* Using Vdd as reference removes the 5us warmup time for the bandgap reference. */
singleInit.reference = adcRefVDD;
// singleInit.input = adcSingleInpCh0;
/* Resolution can be set lower for even more energy efficient operation. */
singleInit.resolution = adcRes12Bit;
/* Assuming we are mesuring a low impedance source we can safely use the shortest */
/* acquisition time. */
singleInit.acqTime = adcAcqTime1;
singleInit.singleDmaEm2Wu = true; //EM2 DMA available
ADC_InitSingle(ADC0, &singleInit);
ADC0->SINGLEFIFOCLEAR = ADC_SINGLEFIFOCLEAR_SINGLEFIFOCLEAR;
/* Set data valid level to trigger DMA */
ADC0->SINGLECTRLX |= (4 - 1) << _ADC_SINGLECTRLX_DVL_SHIFT;
/* Set DMA availability in EM2 and ADC EM2 clock configuration */
BUS_RegBitWrite(&ADC0->CTRL, _ADC_CTRL_SINGLEDMAWU_SHIFT, 1);
BUS_RegMaskedWrite(&ADC0->CTRL,
_ADC_CTRL_ADCCLKMODE_MASK | _ADC_CTRL_ASYNCCLKEN_MASK,
adcEm2ClockOnDemand);
/* Enable ADC Interrupt when Single Conversion Complete. */
/* This is necessary for WFE (wait for event) to work. */
/* Notice that enabling the interrupt in the NVIC is not needed. */
//ADC0->IEN = ADC_IEN_SINGLE;
//ADC_IntEnable(ADC0,ADC_IEN_SINGLE);
//NVIC_EnableIRQ(ADC0_IRQn);
}
2、外围反射系统(PRS)初始化
PRS初始化函数如下,选择触发源是LETIMER0和触发信号LETIMER0CH0。
void setupPrs(void)
{
CMU_ClockEnable(cmuClock_PRS, true);
PRS_SourceAsyncSignalSet(0, PRS_CH_CTRL_SOURCESEL_LETIMER0, PRS_CH_CTRL_SIGSEL_LETIMER0CH0);
}
3、LETIMER0初始化
LETIMER0初始化函数如下,定时时间为2.5ms。
void setupLetimer(void)
{
LETIMER_Init_TypeDef letimerInit = LETIMER_INIT_DEFAULT;
letimerInit.ufoa0 = letimerUFOAToggle; /* Toggle outout on underflow */
letimerInit.comp0Top = true; /* Reload CNT from TOP on underflow */
CMU_ClockEnable(cmuClock_LETIMER0, true);
LETIMER_Init(LETIMER0, &letimerInit);
LETIMER_CompareSet(LETIMER0, 0, 41); /* Toggle every 2.5ms */
LETIMER_RepeatSet(LETIMER0, 0, 1); /* Set REP0 to a non-zero value to generate output */
LETIMER0->ROUTEPEN = LETIMER_ROUTEPEN_OUT0PEN;
LETIMER_Enable(LETIMER0, true);
}
4、LDMA初始化
LDMA使用默认初始化函数即可,如下。
void setupLdma(void)
{
LDMA_Init_t ldmaInit = LDMA_INIT_DEFAULT;
LDMA_Init( &ldmaInit );
}
5、设置ADC控制LDMA
函数如下,LDMA传输配置成外设至memory,外设选择ADC0_Single,传输的源地址为&ADC0->SINGLEDATA,目标地址为&adcBuffer。
void adcLdmaSetup(void)
{
/* Macro for single mode ADC */
LDMA_TransferCfg_t adcSingleTx =
LDMA_TRANSFER_CFG_PERIPHERAL(ldmaPeripheralSignal_ADC0_SINGLE);
/* Macro for ADC data transfer, common for single and scan mode */
LDMA_Descriptor_t xfer =
LDMA_DESCRIPTOR_SINGLE_P2M_BYTE(&ADC0->SINGLEDATA, &adcBuffer, ADC_BUFFER_SIZE);
/* Initialize descriptor for ADC LDMA transfer */
descLink1 = xfer;
descLink1.xfer.doneIfs = 0;
descLink1.xfer.blockSize = ldmaCtrlBlockSizeUnit4;
descLink1.xfer.ignoreSrec = 1;
descLink1.xfer.size = ldmaCtrlSizeWord;
/* Start ADC LMDA transfer */
LDMA_StartTransfer(USE_DMA_CHANNEL, (void*)&adcSingleTx, (void*)&descLink1);
while (!LDMA_TransferDone(USE_DMA_CHANNEL))
{
EMU_EnterEM2(false);
}
}
主函数如下:
/**************************************************************************//**
* @brief Main function
*****************************************************************************/
int main(void) {
EMU_DCDCInit_TypeDef dcdcInit = EMU_DCDCINIT_STK_DEFAULT;
/* Chip errata */
CHIP_Init();
/* If first word of user data page is non-zero, enable eA Profiler trace */
/* Init DCDC regulator and HFXO with kit specific parameters */
EMU_DCDCInit(&dcdcInit);
CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFRCO); // use HFRCO
CMU_HFRCOBandSet(cmuHFRCOFreq_16M0Hz); // set 16MHz Frequency
/* Use LFRCO as LFA clock for LETIMER and PCNT */
CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO);
CMU_ClockEnable(cmuClock_CORELE, true);
setupAdc();
setupPrs();
setupLetimer();
setupLdma();
while (1) {
adcLdmaSetup();
}
}
以上的配置,可以实现ADC0的采集数据通过LDMA传输至adcBuffer的数组中,根据此工程,工程师可以快速熟悉EFM32PG系列MCU的ADC、PRS以及LDMA等外设的应用。
工程源代码网址:https://www.sekorm.com/doc/135859.html。
世强元件电商版权所有,转载请注明来源及链接。
- |
- +1 赞 0
- 收藏
- 评论 0
本网站所有内容禁止转载,否则追究法律责任!
相关推荐
【经验】如何充分利用 EFM32功耗模式来实现电池供电低功耗设计?
Silicon Labs的EFM32系列MCU,拥有EM0~EM4共“5+”种能量模式,将工作模式与休眠模式交替进行,便可获得最优的平均功耗。
设计经验 发布时间 : 2017-09-29
【经验】32位MCU LEUART位周期抖动大,该如何解决?
Silicon Labs 32位MCU EFM32,当基于32.768kHz时钟使用LEUART(@9600bps)进行通讯的时候,发现存约1%误码,原因是什么?如何解决?
设计经验 发布时间 : 2019-09-06
【经验】如何使用32位超低功耗MCU外设反射系统功能?
外设反射系统(PRS)是 Silicon Labs EFM32系列MCU专有的外设互联总线,它允许不同的外设无需CPU干预即可直接相互通信。
设计经验 发布时间 : 2019-09-02
世界上最节能的微控制器EFM32之十大低功耗奥秘
Silicon Labs EFM32 32 位微控制器系列是世界上最为节能的微控制器,特别适用于低功耗和能源敏感型应用,包括能源、水表和燃气表、楼宇自动化、警报及安防和便携式医疗/健身器材。本文着重强调10个Silicon Labs32位MCU功耗低的因素。
新产品 发布时间 : 2016-07-11
【应用】32位MCU在中高端音频处理系统中的应用
音频信号处理涉及多方面,如采集、去除噪声等等,普通MCU很难用一颗芯片集成如此众多的功能。
新应用 发布时间 : 2017-07-18
【应用】1MByte Flash空间 32位MCU助力无线中继器数据传输
Silicon Labs EFM32JG系列MCU,采用功能强大的 32 位 ARM® Cortex®-M3 内核,EM4H 休眠模式(128 字节 RAM 保留)功耗只有0.39uA,集成AES、ECC 和 SHA 的硬件加密引擎和真随机数发生器(TRNG)
新应用 发布时间 : 2018-03-06
如何读取EFM32系列32位MCU的多通道AD扫描采样数据?
EFM32系列单片机ADC的数据保存寄存器有两个,一个是单通道模式的采样数据保存寄存器,一个是扫描模式的采样数据保存寄存器。如果使用多通道扫描采样,那么每个通道采样完成后会产生一个ADC扫描模式中断,用户需要在中断里面读取该通道的扫描采样数据以便存储下一个通道的采样数据。建议使用DMA读取方式,将DMA的触发源设置为ADC的扫描模式事件,这样就可以实现不用进入ADC中断以及MCU的参与即可完成ADC扫描采样数据的保存和读取。
技术问答 发布时间 : 2017-05-05
【产品】8位、16位、32位MCU究竟该如何选择?
本文介绍8位、16位、32位MCU的差异特性。
新产品 发布时间 : 2016-04-02
【产品】高达65 GPIOs的EFM32 Pearl Gecko低功耗32位MCU,可适用于电池供电应用
Silicon Labs EFM32 Pearl Gecko 32 位 MCU 系列具有超低电流活动模式以及节能模式下的快速唤醒,使其可适用于电池供电应用或其他需要高性能和低功耗特性的系统。该产品的设计旨在平衡性能和电力消耗,使电池供电的物联网、健康/健身联网装置,以及智能家居和工厂自动化设备能同时兼备高性能与低功耗运行的优势。
新产品 发布时间 : 2019-04-18
32位MCU EFM32LG330在上电时,其IO会比VDD先上电,从而导致MCU工作异常,应如何处理?
解决方法如下:1、最根本的解决方法,通过调整滤波电容或供电途径,确保VDD先于IO口得电;2、当出现死机时,可以通过拉低复位管脚,来确保解除死机状态。
技术问答 发布时间 : 2017-05-05
32位单片机EFM32 Gemstone系列(EFM32JG/PG)的LETIMER和RTCC的时钟源可以使用HFCLKLE吗?
与Classic系列EFM32不同,Silicon Labs 低功耗32位MCU EFM32JG/PG上HFCLKLE不能用作LETIMER和RTCC的时钟源。LETIMER和RTCC可以使用LFRCO,LFXO或者ULFRCO作为时钟源。
技术问答 发布时间 : 2017-09-28
【产品】全球最节能的EFM32G842 32位微控制器,功耗低至180μA/MHz,助力电池供电系统
Silicon Labs推出了目前全球最为节能EFM32G842微控制器,仅具有模拟集成功能和行业标准的32 位 ARM Cortex-M3 处理器性能,还拥有创新的低能耗技术从能源节省模式中唤醒时间短以及外设选择范围广等优点,能够完美适用于电池供电系统和要求高性能、低能耗的系统。
新产品 发布时间 : 2018-11-10
【经验】EFM32系列低功耗32位MCU芯片加密详解
本文主要介绍以Silicon Labs EFM32系列低功耗32位MCU为核心的方案打造加密系统。
设计经验 发布时间 : 2017-10-27
如何为Silicon Labs 32位低功耗MCU EFM32GG230F512实现基于RTC的软件无滴答日历?
在Silicon Labs 32位低功耗MCU EFM32GG230F512上实现软件方式的无滴答日历,可以通过使用日历标准C库 time.h, 在time.h中实现的timer()函数基于RTC计数值来计 算日历时间。
技术问答 发布时间 : 2017-10-10
【产品】安特卫普大学教授将EFM32™ 32位MCU带进实验室,成为电池供电应用的理想选择
Weyn教授开始寻找一款易于学习、使用并性能良好的MCU。他以适用于课堂的多功能性为原则评估了多个平台,同时还希望这款MCU也在真实世界中有所应用。他选择了EFM32 Gecko系列MCU,而他的实验室则以Gecko架构为基础构建。
应用方案 发布时间 : 2018-10-01
电子商城
现货市场
服务
可定制板装式压力传感器支持产品量程从5inch水柱到100 psi气压;数字输出压力传感器压力范围0.5~60inH2O,温度补偿范围-20~85ºС;模拟和数字低压传感器可以直接与微控制器通信,具备多种小型SIP和DIP封装可选择。
提交需求>
可定制显示屏的尺寸0.96”~15.6”,分辨率80*160~3840*2160,TN/IPS视角,支持RGB、MCU、SPI、MIPI、LVDS、HDMI接口,配套定制玻璃、背光、FPCA/PCBA。
最小起订量: 1000 提交需求>
登录 | 立即注册
提交评论