NXP MCU 技术论坛
直播中

刀马旦

11年用户 702经验值
私信 关注
[资料]

【解放MCU】飞思卡尔KL25使用TPM2触发ADC

单片机进行定时模拟数据采集通常做法是:定时器中断中触发adc转换,adc转换完毕触发中断,在adc中断中保存adc结果。

kl25提供了丰富的内部信号联接。可以大大解放mcu。

参见kl25民间中文数据手册第3章芯片配置中3.2.1 模块之间的相互关系。

举例使用TPM2触发ADC

//8M晶体
  1. #define AD_DOTS 32      //20ms  采样 32点
  2. #define TPM2_tiME     (INT32U)20000*8/AD_DOTS       //定时器时间,单位us

  3. INT16S wpAdcResultDma[AD_DOTS];

  4. void tpm2init(void)
  5. {
  6.         OSC0_CR |= OSC_CR_ERCLKEN_MASK;
  7.         SIM_SCGC6 |= SIM_SCGC6_TPM2_MASK;
  8.         SIM_SOPT2 |= SIM_SOPT2_TPMSRC(2); //晶体

  9.         TPM2_CNT = 0;
  10.         TPM2_MOD = TPM2_TIME;    //20ms  采样 32点
  11.         TPM2_SC = TPM_SC_CMOD(0);
  12.         SIM_SOPT7 |= SIM_SOPT7_ADC0ALTTRGEN_MASK | SIM_SOPT7_ADC0TRGSEL(0x0a);//tpm2触发ad
  13.         TPM2_CONF = TPM_CONF_TRGSEL_TPM2OF;
  14.         TPM2_SC = TPM_SC_TOIE_MASK|TPM_SC_CMOD(1);
  15.         TPM2_C0SC = TPM_CnSC_MSA_MASK|TPM_CnSC_CHIE_MASK;
  16. }

进一步解放adc。采用dma方式进行
  1. void adc_dma_init(void)
  2. {
  3.         SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK;
  4.         PORTE_PCR20 = PORT_PCR_MUX(0);    //开启管脚模拟功能
  5.         PORTE_PCR21 = PORT_PCR_MUX(0);    //开启管脚模拟功能  

  6.         SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK;

  7.         disable_irq(INT_ADC0 - 16);

  8.         Master_Adc_Config.CONFIG1  = ADLPC_NORMAL | ADC_CFG1_ADIV(ADIV_1) | ADLSMP_LONG | ADC_CFG1_MODE(MODE_16) | ADC_CFG1_ADICLK(ADICLK_BUS_2);
  9.         Master_Adc_Config.CONFIG2  = MUXSEL_ADCA | ADACKEN_ENABLED | ADHSC_HISPEED | ADC_CFG2_ADLSTS(ADLSTS_2);
  10.         Master_Adc_Config.COMPARE1 = 0x1234u ;
  11.         Master_Adc_Config.COMPARE2 = 0x5678u ;
  12.         Master_Adc_Config.STATUS2  = ADTRG_SW | ACFE_DISABLED | ACFGT_GREATER | ACREN_DISABLED | DMAEN_DISABLED | ADC_SC2_REFSEL(REFSEL_EXT);
  13.         Master_Adc_Config.STATUS3  = CAL_OFF | ADCO_SINGLE | AVGE_ENABLED | ADC_SC3_AVGS(AVGS_32);
  14.         Master_Adc_Config.STATUS1A = AIEN_OFF | DIFF_DIFFERENTIAL | ADC_SC1_ADCH(0);
  15.         Master_Adc_Config.STATUS1B = AIEN_OFF | DIFF_DIFFERENTIAL | ADC_SC1_ADCH(0);

  16.         ADC_Config_Alt(ADC0_BASE_PTR, &Master_Adc_Config);  // config ADC
  17.         ADC_Cal(ADC0_BASE_PTR);                    // do the calibration
  18.         ADC_Read_Cal(ADC0_BASE_PTR,&CalibrationStore[1]);   // store the cal

  19.         //校准完毕后根据实际需要改变配置
  20.         Master_Adc_Config.STATUS1A = AIEN_ON | DIFF_DIFFERENTIAL | ADC_SC1_ADCH(0);
  21.         Master_Adc_Config.STATUS1B = AIEN_OFF | DIFF_DIFFERENTIAL | ADC_SC1_ADCH(0);
  22.         //硬件触发,dma方式
  23.         Master_Adc_Config.STATUS2  = ADTRG_HW | ACFE_DISABLED | ACFGT_GREATER | ACREN_DISABLED | DMAEN_ENABLED | ADC_SC2_REFSEL(REFSEL_EXT);

  24.         ADC_Config_Alt(ADC0_BASE_PTR, &Master_Adc_Config);  // config ADC
  25. }

  26.         disable_irq(INT_DMA1-16);
  27.         dmaInitPerToMem (MKL_DMA1, 40, (void*)&ADC0_RA, wpAdcResultDma, AD_DOTS*2, 1);//使用的ZLG的库
  28.         enable_irq(INT_DMA1-16);set_irq_priority(INT_DMA1-16, 1);

  29. void dma1_isr(void)
  30. {
  31.         DMA_DSR_BCR1 |= DMA_DSR_BCR_DONE_MASK;
  32.         DMA_DCR1 &= ~DMA_DCR_EINT_MASK;
  33.         DMAMUX0_CHCFG(MKL_DMA1) = 0x00;         // 禁能DMAMUX
  34.         bFlag = 1;//建立完成标志,供主程序进行查询
  35. }

中断函数的写法相信大家应该已经摸索出套路了吧:
  1. extern void dma1_isr(void);

  2. #undef  VECTOR_017
  3. #define VECTOR_017 dma1_is
这样就可以。

回帖(4)

ianhom

2015-1-30 14:06:15
好巧,我之前几天刚好搞定这个
举报

suyong_yq

2015-2-9 13:10:35
“kl25民间中文数据手册”,民间。。。大中华区这么重要的市场,官方不出中文版啊,这是太信任国内的基础教育了。
举报

刘宇莹

2016-8-1 22:17:09
硬件触发没成功 不知道是哪里没配对
举报

lzhiaohiua

2018-6-27 08:55:02
谢谢楼主的分享
举报

更多回帖

发帖
×
20
完善资料,
赚取积分