ADC inject trigger

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

ADC inject trigger

跳至解决方案
2,826 次查看
pandi
Contributor III

In mkv31f512vll12 controller how to configure ADC inject trigger with PWM Ontime  duty triggered how to configure?WhatsApp Image 2023-12-23 at 4.02.17 PM.jpeg

0 项奖励
回复
1 解答
2,562 次查看
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

I have tested on my TWR-KV31 board, I can enter ADC ISR multiple times, so it is okay.

For your issue, you do not set the ADCx_SC2[]ADTRG] bit, because you set it, then clear it with the two lines.

ADC0->SC2 = ADC_SC2_ADTRG(1); // hardware triggered

 

ADC0->SC2= ADC_SC2_ADACT(1);//conversion start

Pls use the following code, I run it, it works fine.

BR

XiangJun Rong

 

void FTM_TrigAdc(void)

 

{

 

SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK | SIM_SCGC6_FTM0_MASK;

 

SIM->SCGC5 |= 0x3E00; // enable port A/B/C/D/E clock

 

 

 

PORTC->PCR[1] = PORT_PCR_MUX(4);

 

GPIOC->PDDR |= 0x40; // PTC direction register, PTD6 is in output mode

 

#if 0

 

FTM0->SC = 0x00;

 

FTM0->CONF = FTM_CONF_BDMMODE(3);

 

FTM0->FMS = 0x00;

 

FTM0->MODE |= FTM_MODE_WPDIS_MASK | FTM_MODE_FAULTM(0x05);

 

FTM0->MOD = 19999;

 

 

 

FTM0->CONTROLS[0].CnSC = FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK;

 

//FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK;

 

 

 

FTM0->CONTROLS[0].CnV = 9999;

 

 

FTM0->COMBINE = FTM_COMBINE_COMBINE2_MASK;

 

FTM0->COMBINE |= FTM_COMBINE_DTEN1_MASK;

 

FTM0->DEADTIME = FTM_DEADTIME_DTVAL(31); // dead time is 31 system clock cycles

 

FTM0->CNTIN = 0x00;

 

FTM0->SC = FTM_SC_CLKS(0x01) |FTM_SC_CPWMS(0);

 

asm("nop");

 

FTM0->EXTTRIG |= FTM_EXTTRIG_CH0TRIG_MASK ;

 

//FTM0->EXTTRIG |= FTM_EXTTRIG_INITTRIGEN_MASK;

 

FTM0->CONF |= FTM_CONF_GTBEEN_MASK; // Enable global time base

 

FTM0->CONF |= FTM_CONF_GTBEOUT_MASK;

#endif

FTM0->SC=0x00;

FTM0->CONF=0xC0; //set up BDM in 11

FTM0->FMS=0x00; //clear the WPEN so that WPDIS is set in FTM0->_MODE register

FTM0->MODE|=0x05; //enable write the FTM CnV register

FTM0->MOD=1000;

FTM0->CONTROLS[0].CnSC=0x28; //High_Low_high for center-alignment

FTM0->CONTROLS[1].CnSC=0x28;

FTM0->CONTROLS[2].CnSC=0x28;

FTM0->CONTROLS[3].CnSC=0x28;

FTM0->CONTROLS[4].CnSC=0x28;

FTM0->CONTROLS[5].CnSC=0x28;

FTM0->CONTROLS[6].CnSC=0x28;

FTM0->COMBINE=0x020202; //complementary mode for CH0&CH1, CH2&CH3 of FTM0->

FTM0->COMBINE|=0x101010; // dead timer insertion enabled in complementary mode //for CH0&CH1 of FTM0->

FTM0->DEADTIME=0x1F; //dead time is 31 system clock cycles

FTM0->CNTIN=0x00;

FTM0->CONTROLS[1].CnV=500; //in complementary, C0V/C2V/C4V are used to control duty cycle.

FTM0->CONTROLS[0].CnV=500; //in complementary mode, C1V/C3V/C5V are not used.

FTM0->CONTROLS[2].CnV=500;

FTM0->CONTROLS[3].CnV=500;

FTM0->CONTROLS[4].CnV=500;

FTM0->CONTROLS[5].CnV=1000;

//triggering ADC at the center point of PWM signal while PWM is set up in //center alignment mode

FTM0->SC=0x28; //PWM center alignment, system clock driving, dividing by 1

asm("nop");

//set that FTM0_C5V to trigger ADC, in complementary, C5V is not used to //control duty cycle

FTM0->EXTTRIG|=0x08;

//NVIC->ISER[1] |= (1 << 7);

 

//NVIC->ICPR[0] |= (1 << 7);

 

 

 

//FTM0->SC |= FTM_SC_TOIE_MASK;

 

}

 

void FTM0_IRQHandler(void)

 

{

 

if (FTM0->STATUS & FTM_STATUS_CH0F_MASK)

 

{

 

FTM0->STATUS &= ~FTM_STATUS_CH0F_MASK; // Clear the channel flag

 

//ADC0->SC1[0] = ADC_SC1_AIEN_MASK | ADC_SC1_ADCH(8); // Start ADC conversion on channel 8

 

}

 

}

 

void AdcInit(void)

 

{

 

SIM->SCGC5 |= 0x3E00; // enable port A/B/C/D/E clock

 

SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK; // enable ADC0 clock

 

ADC0->CFG1 = ADC_CFG1_ADIV(4) | ADC_CFG1_MODE(1) | ADC_CFG1_ADICLK(0); // ADC clock is bus clock/2, bus clock is 20M, ADC clock is 10MHz

 

ADC0->CFG2 = 0x00;

 

ADC0->SC2 = ADC_SC2_ADTRG(1); // hardware triggered

 

 

 

ADC0->SC2|= ADC_SC2_ADACT(1);//conversion start

 

ADC0->SC3 = 0x00;

 

ADC0->SC1[0] = ADC_SC1_AIEN_MASK | ADC_SC1_ADCH(8);

 

SIM->SOPT7 = SIM_SOPT7_ADC0TRGSEL(0x08)| SIM_SOPT7_ADC0ALTTRGEN_MASK;

 

 

 

NVIC_EnableIRQ(ADC0_IRQn);

 

__ASM("CPSIE I");

 

}

uint32_t sample[10];

void ADC0_IRQHandler(void)

 

{

 

if (ADC0->SC1[0] & ADC_SC1_COCO_MASK)

 

{

// ADC0->SC1[0] = ADC_SC1_AIEN_MASK | ADC_SC1_ADCH(8);

GPIOC->PTOR = 0x40; // Toggle indicator

 

sample[0] = ADC0->R[0];

 

}

 

}

 

在原帖中查看解决方案

0 项奖励
回复
17 回复数
2,793 次查看
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

If you want to use hardware triggering mode, you have to configure:

1)set the ADCx_SC2[ADTRG] bit, it means that the ADC will be triggered by the hardware instead of software

2)configure the SIM_SOPT7 register, it defines the triggering source of ADC. For detailed inf, pls refer to section 3.7.1.7 ADC triggers in the RM of KV31

xiangjun_rong_0-1704173157320.png

For example, if you select PIT trigger 0, you have to configure the PIT channel0 so that PIT channel0 can generate triggering signal, while configure SIM_SOPT7[ADCxTRGSEL]=4;

Hope it can help you

BR

XiangJun Rong

0 项奖励
回复
2,783 次查看
pandi
Contributor III
破坏者
 

 hi,

xiangjun_rong, 

 ADC inject trigger with PWM Ontime duty trigger  register level code or function level code guide me how to configure step by step

#include "board.h"

#include "fsl_debug_console.h"

#include "fsl_adc16.h"

#include "fsl_ftm.h"

#include "fsl_common.h"

#include "pin_mux.h"

#include"fsl_port.h"

//#include"pin_mux.c"

#include <stdio.h>

#include "peripherals.h"

 

#define DEMO_ADC16_BASE ADC0

#define DEMO_ADC16_CHANNEL_GROUP 0U

#define DEMO_ADC16_USER_CHANNEL 8U

 

#define DEMO_PWM_BASE FTM0

#define DEMO_PWM_CHANNEL 0U

 

volatile uint32_t pwmDutyCyclePercent = 0;

uint32_t result = 0;

adc16_channel_config_t adc16ChannelConfigStruct;

//volatile uint32_t read = *((uint32_t*)0x00080000);

void BOARD_InitPWM(void) {

ftm_config_t ftmInfo;

FTM_GetDefaultConfig(&ftmInfo);

 

/* Initialize FTM module */

FTM_Init(DEMO_PWM_BASE, &ftmInfo);

 

/* Set the PWM period */

FTM_SetTimerPeriod(DEMO_PWM_BASE, kFTM_SystemClock);

 

/* Configure the PWM channel */

ftm_chnl_pwm_signal_param_t ftmParam;

ftmParam.chnlNumber = DEMO_PWM_CHANNEL;

ftmParam.level = kFTM_HighTrue;

ftmParam.dutyCyclePercent = 30;

ftmParam.firstEdgeDelayPercent = 0;

// PORT_SetPinMux(BOARD_FTM0_CH0_PORT, BOARD_FTM0_CH0_PIN, kPORT_MuxAlt4);

 

FTM_SetupPwm(DEMO_PWM_BASE, &ftmParam, 1U, kFTM_EdgeAlignedPwm, 25000U, kFTM_SystemClock);

//PORT_SetPinMux(BOARD_FTM0_CH0_PORT, BOARD_FTM0_CH0_PIN, kPORT_MuxAlt4);

//PORT_SetPinMux(PORTE,1,1);

//PORT_SetPinMux(BOARD_FTM0_CH0_PORT, BOARD_FTM0_CH0_PIN, kPORT_MuxAlt4);

 

/* Start the PWM */

FTM_StartTimer(DEMO_PWM_BASE, kFTM_SystemClock);

}

 

void BOARD_InitADC(void) {

adc16_config_t adc16ConfigStruct;

 

ADC16_GetDefaultConfig(&adc16ConfigStruct);

adc16ConfigStruct.resolution = kADC16_ResolutionSE12Bit; // Change as needed

ADC16_Init(DEMO_ADC16_BASE, &adc16ConfigStruct);

/* Configure ADC channel */

adc16ChannelConfigStruct.channelNumber = DEMO_ADC16_USER_CHANNEL;

adc16ChannelConfigStruct.enableInterruptOnConversionCompleted = false;

adc16ChannelConfigStruct.enableDifferentialConversion = false;

ADC16_SetChannelConfig(DEMO_ADC16_BASE, DEMO_ADC16_CHANNEL_GROUP, &adc16ChannelConfigStruct);

/* Enable the Injected Conversion */

// ADC16_EnableHardwareTrigger(DEMO_ADC16_BASE, true);

ADC16_EnableHardwareTrigger(DEMO_ADC16_BASE , false);

//ADC16_EnableInjectedSequences(DEMO_ADC16_BASE , false);

}

void FTM0_IRQHandler(void) {

/* Clear interrupt flag */

FTM_ClearStatusFlags(DEMO_PWM_BASE, kFTM_Chnl0Flag);

 

/* Update PWM duty cycle based on some condition */

pwmDutyCyclePercent = (result * 100U) / 4095U;

FTM_UpdatePwmDutycycle(DEMO_PWM_BASE, DEMO_PWM_CHANNEL, kFTM_EdgeAlignedPwm, pwmDutyCyclePercent);

 

}

/*void HardFault_Handler(void){

while(1){

}

}*/

 

int main(void) {

BOARD_InitPWM();

BOARD_InitADC();

 

/* Enable FTM0 interrupt */

EnableIRQ(FTM0_IRQn);

FTM_EnableInterrupts(DEMO_PWM_BASE, kFTM_Chnl0InterruptEnable);

NVIC_SetPriority(FTM0_IRQn, 0);

 

while (1) {

/* Start an injected conversion with software trigger */

ADC16_SetChannelConfig(DEMO_ADC16_BASE, DEMO_ADC16_CHANNEL_GROUP, &adc16ChannelConfigStruct);

//ADC16_DoSoftwareTrigger(DEMO_ADC16_BASE);

//PORT_SetPinMux(BOARD_FTM0_CH0_PORT, BOARD_FTM0_CH0_PIN, kPORT_MuxAlt4);

 

/* Wait for the conversion to complete */

while (0U == (kADC16_ChannelConversionDoneFlag & ADC16_GetChannelStatusFlags(DEMO_ADC16_BASE, DEMO_ADC16_CHANNEL_GROUP)))

{

}

 

/* Read ADC result */

result = ADC16_GetChannelConversionValue(DEMO_ADC16_BASE, DEMO_ADC16_CHANNEL_GROUP);

 

/* Print the result or use it as needed */

PRINTF("ADC Result: %d\r\n", result);

 

/* Delay for a while */

SDK_DelayAtLeastUs(1000000U, SystemCoreClock);

}

return 0;

}

 this program adc inject trigger method if any changes let me know

   BR

PANDI

 

 

0 项奖励
回复
2,758 次查看
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

Pls refer to the attached an5142.pdf, in the section 3.7. FTM triggering ADC, the FTM triggering ADC is discussed and the code is given.

But You use both the FTM diver and ADC driver instead of writing register.

anyway, you have to write the following registers:

1)set the ADCx_SC2[ADTRG] bit, it means that the ADC will be triggered by the hardware instead of software

2)configure the SIM_SOPT7 register to select the triggering source

3)write the FTM0_EXTTRIG to select which CVx register can generate the triggering signal.

I suppose that you can use the code directly.

Hope it can help you

BR

XiangJun Rong

void FTM_TrigAdc(void)
{
SIM_SCGC6|=0x03000000; //enable FTM0 and FTM0 module clock
SIM_SCGC5=SIM_SCGC5|0x3E00; //enable port A/B/C/D/E clock
PORTC_PCR7=0x100; //PTC7 in GPIO mode
GPIOC_PDDR=0x80; //PTC direction register, PTC7 is in output mode
FTM0_SC=0x00;
FTM0_CONF=0xC0; //set up BDM in 11
FTM0_FMS=0x00; //clear the WPEN so that WPDIS is set in FTM0_MODE register
FTM0_MODE|=0x05; //enable write the FTM CnV register
FTM0_MOD=1000;
FTM0_C0SC=0x28; //High_Low_high for center-alignment
FTM0_C1SC=0x28;
FTM0_C2SC=0x28;
FTM0_C3SC=0x28;
FTM0_C4SC=0x28;
FTM0_C5SC=0x28;
FTM0_C6SC=0x28;
FTM0_COMBINE=0x020202; //complementary mode for CH0&CH1, CH2&CH3 of FTM0
FTM0_COMBINE|=0x101010; // dead timer insertion enabled in complementary mode //for CH0&CH1 of FTM0
FTM0_DEADTIME=0x1F; //dead time is 31 system clock cycles
FTM0_CNTIN=0x00;
FTM0_C1V=500; //in complementary, C0V/C2V/C4V are used to control duty cycle.
FTM0_C0V=500; //in complementary mode, C1V/C3V/C5V are not used.
FTM0_C2V=500;
FTM0_C3V=500;
FTM0_C4V=500;
FTM0_C5V=1000;
//triggering ADC at the center point of PWM signal while PWM is set up in //center alignment mode
FTM0_SC=0x28; //PWM center alignment, system clock driving, dividing by 1
asm("nop");
//set that FTM0_C5V to trigger ADC, in complementary, C5V is not used to //control duty cycle
FTM0_EXTTRIG|=0x08;
}
unsigned int sample[8];
void AdcInit(void)
{
SIM_SCGC5=SIM_SCGC5|0x3E00; //enable port A/B/C/D/E clock
SIM_SCGC3|=0x08000000; //enable ADC1 clock
ADC1_CFG1=0x44; //adc clock is bus clock/2, busclock is 20M, ADC clock is 10MHz
ADC1_CFG2=0x00;
ADC1_SC2=0x40; //hardware triggered,
ADC1_SC3=0x00; //not continuous conversion
ADC1_SC1A=0x54; //interrupt enable and select ADC1_DM1 channel
//set that FTM0 to trigger ADC1
SIM_SOPT7=0x8800; //FTM0 trigger ADC1, alternative triggering, only ADC1_SC1A //conversion is valid
NVICIP58=0x30; //setting interrupt of ADC1
PWM Features
Features of the FlexTimer Module, Rev. 0, 06/2015
Freescale Semiconductor, Inc. 13
NVICICPR1|=1<<26; //clear the pending register of interrupt source 58
NVICISER1|=1<<26; //set the interrupt source of ADC1
asm("cpsie i"); //interrupt enable
}
void ADC_ISR(void)
{
GPIOC_PTOR=0x80; //toggle indicator
sample[0]=ADC1_RA;
asm("nop");
//ADC1_SC1A=0x14; //interrupt enable and select ADC1_DM1 channel
}

0 项奖励
回复
2,748 次查看
pandi
Contributor III

hi

xiangjun_rong

I`m changing to register level program but ADC value not reading please guide me

 

void FTM_TrigAdc(void) {

// Enable clock for ADC0 and FTM0

SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK | SIM_SCGC6_FTM0_MASK;

 

// Enable clock for port B and E

SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTE_MASK;

 

// Configure pin multiplexing for FTM0 channels

PORTB->PCR[18] = PORT_PCR_MUX(3); // FTM0_CH1, PTB18

PORTB->PCR[19] = PORT_PCR_MUX(3); // FTM0_CH0, PTB19

PORTE->PCR[1] = PORT_PCR_MUX(3); // FTM0_CH2, PTE1

 

// Configure FTM0 for PWM

FTM0->SC = 0x00;

FTM0->CONF = FTM_CONF_BDMMODE(3);

FTM0->FMS = 0x00;

FTM0->MODE |= FTM_MODE_WPDIS_MASK | FTM_MODE_FAULTM(0x05);

FTM0->MOD = 1000;

 

// Configure channels for complementary mode

for (int i = 0; i < 7; ++i) {

FTM0->CONTROLS[i].CnSC = FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK;

FTM0->CONTROLS[i].CnV = 500;

}

 

// Enable dead time insertion

FTM0->COMBINE = FTM_COMBINE_COMBINE0_MASK | FTM_COMBINE_COMBINE1_MASK | FTM_COMBINE_COMBINE2_MASK |

FTM_COMBINE_COMBINE3_MASK;

FTM0->COMBINE |= FTM_COMBINE_DTEN0_MASK | FTM_COMBINE_DTEN1_MASK | FTM_COMBINE_DTEN2_MASK |

FTM_COMBINE_DTEN3_MASK;

FTM0->DEADTIME = FTM_DEADTIME_DTVAL(31);

 

// Configure FTM0 for PWM center alignment, system clock driving, dividing by 1

FTM0->SC = FTM_SC_CLKS(1) | FTM_SC_PS(0x00);

 

// Set FTM0_C5V to trigger ADC

FTM0->EXTTRIG |= FTM_EXTTRIG_CH5TRIG_MASK;

 

// Set FTM0_C5SC to PWM

FTM0->CONTROLS[5].CnSC = FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK;

 

__NOP();

}

void AdcInit(void)

{

//SIM->SCGC5 |= 0x3E00;

SIM->SCGC5 |= 0x3E00;//enable port A/B/C/D/E clock

SIM->SCGC6|= SIM_SCGC6_ADC1_MASK; //enable ADC1 clock

ADC1->CFG1 = ADC_CFG1_ADIV(1) | ADC_CFG1_MODE(1) | ADC_CFG1_ADICLK(0); // adc clock is bus clock/2, bus clock is 20M, ADC clock is 10MHz

ADC1->CFG2 = 0x00;

ADC1->SC2 = ADC_SC2_ADTRG_MASK; //hardware triggered,

ADC1->SC3 = 0x00; //not continuous conversion

ADC1->SC1[0] = ADC_SC1_AIEN_MASK | ADC_SC1_ADCH(4); //interrupt enable and select ADC1_DM1 channel

//set that FTM0 to trigger ADC1

SIM->SOPT7 = SIM_SOPT7_ADC1TRGSEL(0x09) | SIM_SOPT7_ADC1ALTTRGEN_MASK;//FTM0 trigger ADC1, alternative triggering, only ADC1_SC1A //conversion is valid

NVIC->ISER[1] |= (1 << 26);//setting interrupt of ADC1

 

__ASM("CPSIE I"); //interrupt enable

}

void ADC_ISR(void)

{

GPIOC->PTOR = 0x80; // toggle indicator

sample[1] = ADC1->R[0];

//sample[1]=ADC1->R[1];

__NOP();

//ADC1_SC1A=0x14; //interrupt enable and select ADC1_DM1 channel

}

BR

PANDI

0 项奖励
回复
2,730 次查看
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

For KV31, the ADC1 interrupt vector is 73.

NVIC->ISER[2] |= (1 << 9); //setting interrupt of ADC1

//NVIC->ICPR[2] |= (1 << 9); //clear interrupt  pending bit

Pls check if you can enter ADC1 ISR.

Hope it can help you

BR

XiangJun Rong

0 项奖励
回复
2,718 次查看
pandi
Contributor III

hi

xiangjun_rong

  This code ADC inject trigger. Correct

or not if not means which line in change to program please guide me

void FTM_TrigAdc(void)

{

SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK | SIM_SCGC6_FTM0_MASK;

SIM->SCGC5 |= 0x3E00; // enable port A/B/C/D/E clock

//PORTD->PCR[6] = PORT_PCR_MUX(3);

PORTC->PCR[1] = PORT_PCR_MUX(4);// PDC6 as FTM0_CH6

GPIOC->PDDR |= 0x40; // PTC direction register, PTD6 is in output mode

 

FTM0->SC = 0x00;

FTM0->CONF = FTM_CONF_BDMMODE(3);

FTM0->FMS = 0x00;

FTM0->MODE |= FTM_MODE_WPDIS_MASK | FTM_MODE_FAULTM(0x05);

FTM0->MOD = 699-1;

 

FTM0->CONTROLS[0].CnSC = FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK; // High_Low_high for center-alignment

FTM0->CONTROLS[0].CnV = 349; // in complementary, C6V is used to control duty cycle

 

FTM0->COMBINE = FTM_COMBINE_COMBINE2_MASK;

FTM0->COMBINE |= FTM_COMBINE_DTEN1_MASK;

FTM0->DEADTIME = FTM_DEADTIME_DTVAL(31); // dead time is 31 system clock cycles

FTM0->CNTIN = 0x00;

 

// triggering ADC at the center point of PWM signal while PWM is set up in center alignment mode

FTM0->SC = FTM_SC_CLKS(1) | FTM_SC_PS(0x00); // PWM center alignment, system clock driving, dividing by 1

asm("nop");

 

FTM0->EXTTRIG |= FTM_EXTTRIG_CH5TRIG_MASK;

//FTM0->EXTTRIG |= FTM_EXTTRIG_CH6TRIG_MASK;

NVIC->ISER[0] |= (1 << 9);

FTM0->SC |= FTM_SC_TOIE_MASK;

}

void FTM0_IRQHandler(void)

{

GPIOC->PTOR = 0x40; // Toggle indicator

sample[0] = ADC0->R[0]; // Store ADC sample value

__NOP();

FTM0->SC &= ~FTM_SC_TOF_MASK; // Clear Timer Overflow Flag

}

 

void AdcInit(void)

{

SIM->SCGC5 |= 0x3E00; // enable port A/B/C/D/E clock

SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK; // enable ADC0 clock

ADC0->CFG1 = ADC_CFG1_ADIV(1) | ADC_CFG1_MODE(1) | ADC_CFG1_ADICLK(0); // ADC clock is bus clock/2, bus clock is 20M, ADC clock is 10MHz

ADC0->CFG2 = 0x00;

ADC0->SC2 = ADC_SC2_ADTRG_MASK; // hardware triggered

ADC0->SC2= ADC_SC2_ADACT_MASK ;//conversion start

ADC0->SC3 = 0x00;

ADC0->SC1[0] = ADC_SC1_AIEN_MASK | ADC_SC1_ADCH(8); // interrupt enable and select ADC0_SE8 channel

 

// set FTM0 to trigger ADC0

SIM->SOPT7 = SIM_SOPT7_ADC0TRGSEL(0x0A) | SIM_SOPT7_ADC0ALTTRGEN_MASK; // FTM0 trigger ADC0

 

// Enable ADC0 interrupt in NVIC

NVIC_EnableIRQ(ADC0_IRQn);

__ASM("CPSIE I");

}

 

void ADC0_IRQHandler(void)

{

GPIOC->PTOR = 0x40; // toggle indicator

sample[0] = ADC0->R[0];

__NOP();

}

 

int main(void)

{

BOARD_InitBootPins();

BOARD_InitBootClocks();

BOARD_InitBootPeripherals();

 

AdcInit();

FTM_TrigAdc();

SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK | SIM_SCGC6_FTM0_MASK;

 

#ifndef BOARD_INIT_DEBUG_CONSOLE_PERIPHERAL

BOARD_InitDebugConsole();

#endif

 

//PRINTF("Hello World\r\n");

//PRINTF("Hello World\r\n");

PRINTF("%d",sample[0]);

volatile static int i = 0;

while(1)

{

i++;

//GETCHAR();

 

//sample[0] = ADC0->R[0];

__asm volatile ("nop");

}

return 0;

}

BR

PANDI

0 项奖励
回复
2,677 次查看
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

1)As I attached the ADC triggering source, the FTM0 index is 4b'1000 or 8, so you have to use the line:

SIM->SOPT7 = SIM_SOPT7_ADC0TRGSEL(0x08) | SIM_SOPT7_ADC0ALTTRGEN_MASK; // FTM0 trigger ADC0

2)For the ADC0 interrupt vector is 39, so you have to write the line:

 

xiangjun_rong_0-1704420002628.png

NVIC->ISER[1] |= (1 << 7); //39-32=7

3)The FTM0 triggers ADC0 and the ADC0 generates interrupt after conversion is over, so it is unnecessary to have FTM generate interrupt. pls comment the line:

//FTM0->SC |= FTM_SC_TOIE_MASK;

4)I suppose that you know the mechanism of the FTM0 triggering ADC0, if you set the line:

FTM0->EXTTRIG |= FTM_EXTTRIG_CH5TRIG_MASK;

SIM->SOPT7 = SIM_SOPT7_ADC0TRGSEL(0x08) | SIM_SOPT7_ADC0ALTTRGEN_MASK; // FTM0 trigger ADC0

when the FTM0 counter reaches up to the value of FTM0_C5V, the FTM0 triggering event will happen, because the SIM->SOPT7 = SIM_SOPT7_ADC0TRGSEL(0x08); the FTM0 triggering event will route to ADC0, because the ADC0 is configured as hardware triggering, the analog channel in ADC0_SC1[0] will be converted with FTM0 triggering event.

So you have to initialize the FTM0_C5V and the ADC0_SC1[0]

I suggest you use the original code in the AN, because the code is based on K40, you use KV31, so you have to change the code to adapt to KV31.

Hope it can help you

BR

XiangJun Rong

 

0 项奖励
回复
2,643 次查看
pandi
Contributor III

hi

xiangjun_rong

I`m configuration all peripheral but inject trigger not working if anything missing you have to guide me 

void AdcInit(void)

{

SIM->SCGC5 |= 0x3E00; // enable port A/B/C/D/E clock

SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK; // enable ADC0 clock

ADC0->CFG1 = ADC_CFG1_ADIV(1) | ADC_CFG1_MODE(1) | ADC_CFG1_ADICLK(0); // ADC clock is bus clock/2, bus clock is 20M, ADC clock is 10MHz

ADC0->CFG2 = 0x00;

ADC0->SC2 = ADC_SC2_ADTRG(1); // hardware triggered

 

ADC0->SC2= ADC_SC2_ADACT(1);//conversion start

ADC0->SC3 = 0x00;

ADC0->SC1[0] = ADC_SC1_AIEN_MASK | ADC_SC1_ADCH(8);

SIM->SOPT7 = SIM_SOPT7_ADC0TRGSEL(0x08)| SIM_SOPT7_ADC0ALTTRGEN_MASK;

 

NVIC_EnableIRQ(ADC0_IRQn);

__ASM("CPSIE I");

}

void FTM_TrigAdc(void)

{

SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK | SIM_SCGC6_FTM0_MASK;

SIM->SCGC5 |= 0x3E00; // enable port A/B/C/D/E clock

//PORTD->PCR[6] = PORT_PCR_MUX(3);

PORTC->PCR[1] = PORT_PCR_MUX(4);

GPIOC->PDDR |= 0x40; // PTC direction register, PTD6 is in output mode

 

FTM0->SC = 0x00;

FTM0->CONF = FTM_CONF_BDMMODE(3);

FTM0->FMS = 0x00;

FTM0->MODE |= FTM_MODE_WPDIS_MASK | FTM_MODE_FAULTM(0x05);

FTM0->MOD = 19999;

 

FTM0->CONTROLS[0].CnSC = FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK;

//FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK;

//FTM0->SC = FTM_CnSC_ELSB(1) | FTM_CnSC_ELSA(0);

FTM0->CONTROLS[0].CnV = 9999;

 

FTM0->COMBINE = FTM_COMBINE_COMBINE2_MASK;

FTM0->COMBINE |= FTM_COMBINE_DTEN1_MASK;

FTM0->DEADTIME = FTM_DEADTIME_DTVAL(31); // dead time is 31 system clock cycles

FTM0->CNTIN = 0x00;

FTM0->SC = FTM_SC_CLKS(0x01) |FTM_SC_CPWMS(0);

asm("nop");

//FTM0->EXTTRIG |= FTM_EXTTRIG_CH0TRIG_MASK ;

FTM0->EXTTRIG |= FTM_EXTTRIG_INITTRIGEN_MASK;

FTM0->CONF |= FTM_CONF_GTBEEN_MASK; // Enable global time base

FTM0->CONF |= FTM_CONF_GTBEOUT_MASK;

NVIC->ISER[1] |= (1 << 7);

//NVIC->ICPR[0] |= (1 << 7);

 

//FTM0->SC |= FTM_SC_TOIE_MASK;

}

void FTM0_IRQHandler(void)

{

if (FTM0->STATUS & FTM_STATUS_CH0F_MASK)

{

FTM0->STATUS &= ~FTM_STATUS_CH0F_MASK; // Clear the channel flag

ADC0->SC1[0] = ADC_SC1_AIEN_MASK | ADC_SC1_ADCH(8); // Start ADC conversion on channel 8

}

}

void ADC0_IRQHandler(void)

{

if (ADC0->SC1[0] & ADC_SC1_COCO_MASK)

{

GPIOC->PTOR = 0x40; // Toggle indicator

sample[0] = ADC0->R[0];

}

}

BR

PANDI

0 项奖励
回复
2,574 次查看
pandi
Contributor III

Hi

@xiangjun_rong 

 

This program inject ADC trigger or not if inject trigger not means please you guide me i`m configure all peripheral in the program please check it . if any other changes you have guide me

void FTM_TrigAdc(void)

{

SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK | SIM_SCGC6_FTM0_MASK;

SIM->SCGC5 |= 0x3E00; // enable port A/B/C/D/E clock

 

PORTC->PCR[1] = PORT_PCR_MUX(4);

GPIOC->PDDR |= 0x40; // PTC direction register, PTD6 is in output mode

 

FTM0->SC = 0x00;

FTM0->CONF = FTM_CONF_BDMMODE(3);

FTM0->FMS = 0x00;

FTM0->MODE |= FTM_MODE_WPDIS_MASK | FTM_MODE_FAULTM(0x05);

FTM0->MOD = 19999;

 

FTM0->CONTROLS[0].CnSC = FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK;

//FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK;

 

FTM0->CONTROLS[0].CnV = 9999;

 

FTM0->COMBINE = FTM_COMBINE_COMBINE2_MASK;

FTM0->COMBINE |= FTM_COMBINE_DTEN1_MASK;

FTM0->DEADTIME = FTM_DEADTIME_DTVAL(31); // dead time is 31 system clock cycles

FTM0->CNTIN = 0x00;

FTM0->SC = FTM_SC_CLKS(0x01) |FTM_SC_CPWMS(0);

asm("nop");

FTM0->EXTTRIG |= FTM_EXTTRIG_CH0TRIG_MASK ;

//FTM0->EXTTRIG |= FTM_EXTTRIG_INITTRIGEN_MASK;

FTM0->CONF |= FTM_CONF_GTBEEN_MASK; // Enable global time base

FTM0->CONF |= FTM_CONF_GTBEOUT_MASK;

NVIC->ISER[1] |= (1 << 7);

//NVIC->ICPR[0] |= (1 << 7);

 

//FTM0->SC |= FTM_SC_TOIE_MASK;

}

void FTM0_IRQHandler(void)

{

if (FTM0->STATUS & FTM_STATUS_CH0F_MASK)

{

FTM0->STATUS &= ~FTM_STATUS_CH0F_MASK; // Clear the channel flag

ADC0->SC1[0] = ADC_SC1_AIEN_MASK | ADC_SC1_ADCH(8); // Start ADC conversion on channel 8

}

}

void AdcInit(void)

{

SIM->SCGC5 |= 0x3E00; // enable port A/B/C/D/E clock

SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK; // enable ADC0 clock

ADC0->CFG1 = ADC_CFG1_ADIV(1) | ADC_CFG1_MODE(1) | ADC_CFG1_ADICLK(0); // ADC clock is bus clock/2, bus clock is 20M, ADC clock is 10MHz

ADC0->CFG2 = 0x00;

ADC0->SC2 = ADC_SC2_ADTRG(1); // hardware triggered

 

ADC0->SC2= ADC_SC2_ADACT(1);//conversion start

ADC0->SC3 = 0x00;

ADC0->SC1[0] = ADC_SC1_AIEN_MASK | ADC_SC1_ADCH(8);

SIM->SOPT7 = SIM_SOPT7_ADC0TRGSEL(0x08)| SIM_SOPT7_ADC0ALTTRGEN_MASK;

 

NVIC_EnableIRQ(ADC0_IRQn);

__ASM("CPSIE I");

}

void ADC0_IRQHandler(void)

{

if (ADC0->SC1[0] & ADC_SC1_COCO_MASK)

{

GPIOC->PTOR = 0x40; // Toggle indicator

sample[0] = ADC0->R[0];

}

}

BR

PANDI

0 项奖励
回复
2,563 次查看
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

I have tested on my TWR-KV31 board, I can enter ADC ISR multiple times, so it is okay.

For your issue, you do not set the ADCx_SC2[]ADTRG] bit, because you set it, then clear it with the two lines.

ADC0->SC2 = ADC_SC2_ADTRG(1); // hardware triggered

 

ADC0->SC2= ADC_SC2_ADACT(1);//conversion start

Pls use the following code, I run it, it works fine.

BR

XiangJun Rong

 

void FTM_TrigAdc(void)

 

{

 

SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK | SIM_SCGC6_FTM0_MASK;

 

SIM->SCGC5 |= 0x3E00; // enable port A/B/C/D/E clock

 

 

 

PORTC->PCR[1] = PORT_PCR_MUX(4);

 

GPIOC->PDDR |= 0x40; // PTC direction register, PTD6 is in output mode

 

#if 0

 

FTM0->SC = 0x00;

 

FTM0->CONF = FTM_CONF_BDMMODE(3);

 

FTM0->FMS = 0x00;

 

FTM0->MODE |= FTM_MODE_WPDIS_MASK | FTM_MODE_FAULTM(0x05);

 

FTM0->MOD = 19999;

 

 

 

FTM0->CONTROLS[0].CnSC = FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK;

 

//FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK;

 

 

 

FTM0->CONTROLS[0].CnV = 9999;

 

 

FTM0->COMBINE = FTM_COMBINE_COMBINE2_MASK;

 

FTM0->COMBINE |= FTM_COMBINE_DTEN1_MASK;

 

FTM0->DEADTIME = FTM_DEADTIME_DTVAL(31); // dead time is 31 system clock cycles

 

FTM0->CNTIN = 0x00;

 

FTM0->SC = FTM_SC_CLKS(0x01) |FTM_SC_CPWMS(0);

 

asm("nop");

 

FTM0->EXTTRIG |= FTM_EXTTRIG_CH0TRIG_MASK ;

 

//FTM0->EXTTRIG |= FTM_EXTTRIG_INITTRIGEN_MASK;

 

FTM0->CONF |= FTM_CONF_GTBEEN_MASK; // Enable global time base

 

FTM0->CONF |= FTM_CONF_GTBEOUT_MASK;

#endif

FTM0->SC=0x00;

FTM0->CONF=0xC0; //set up BDM in 11

FTM0->FMS=0x00; //clear the WPEN so that WPDIS is set in FTM0->_MODE register

FTM0->MODE|=0x05; //enable write the FTM CnV register

FTM0->MOD=1000;

FTM0->CONTROLS[0].CnSC=0x28; //High_Low_high for center-alignment

FTM0->CONTROLS[1].CnSC=0x28;

FTM0->CONTROLS[2].CnSC=0x28;

FTM0->CONTROLS[3].CnSC=0x28;

FTM0->CONTROLS[4].CnSC=0x28;

FTM0->CONTROLS[5].CnSC=0x28;

FTM0->CONTROLS[6].CnSC=0x28;

FTM0->COMBINE=0x020202; //complementary mode for CH0&CH1, CH2&CH3 of FTM0->

FTM0->COMBINE|=0x101010; // dead timer insertion enabled in complementary mode //for CH0&CH1 of FTM0->

FTM0->DEADTIME=0x1F; //dead time is 31 system clock cycles

FTM0->CNTIN=0x00;

FTM0->CONTROLS[1].CnV=500; //in complementary, C0V/C2V/C4V are used to control duty cycle.

FTM0->CONTROLS[0].CnV=500; //in complementary mode, C1V/C3V/C5V are not used.

FTM0->CONTROLS[2].CnV=500;

FTM0->CONTROLS[3].CnV=500;

FTM0->CONTROLS[4].CnV=500;

FTM0->CONTROLS[5].CnV=1000;

//triggering ADC at the center point of PWM signal while PWM is set up in //center alignment mode

FTM0->SC=0x28; //PWM center alignment, system clock driving, dividing by 1

asm("nop");

//set that FTM0_C5V to trigger ADC, in complementary, C5V is not used to //control duty cycle

FTM0->EXTTRIG|=0x08;

//NVIC->ISER[1] |= (1 << 7);

 

//NVIC->ICPR[0] |= (1 << 7);

 

 

 

//FTM0->SC |= FTM_SC_TOIE_MASK;

 

}

 

void FTM0_IRQHandler(void)

 

{

 

if (FTM0->STATUS & FTM_STATUS_CH0F_MASK)

 

{

 

FTM0->STATUS &= ~FTM_STATUS_CH0F_MASK; // Clear the channel flag

 

//ADC0->SC1[0] = ADC_SC1_AIEN_MASK | ADC_SC1_ADCH(8); // Start ADC conversion on channel 8

 

}

 

}

 

void AdcInit(void)

 

{

 

SIM->SCGC5 |= 0x3E00; // enable port A/B/C/D/E clock

 

SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK; // enable ADC0 clock

 

ADC0->CFG1 = ADC_CFG1_ADIV(4) | ADC_CFG1_MODE(1) | ADC_CFG1_ADICLK(0); // ADC clock is bus clock/2, bus clock is 20M, ADC clock is 10MHz

 

ADC0->CFG2 = 0x00;

 

ADC0->SC2 = ADC_SC2_ADTRG(1); // hardware triggered

 

 

 

ADC0->SC2|= ADC_SC2_ADACT(1);//conversion start

 

ADC0->SC3 = 0x00;

 

ADC0->SC1[0] = ADC_SC1_AIEN_MASK | ADC_SC1_ADCH(8);

 

SIM->SOPT7 = SIM_SOPT7_ADC0TRGSEL(0x08)| SIM_SOPT7_ADC0ALTTRGEN_MASK;

 

 

 

NVIC_EnableIRQ(ADC0_IRQn);

 

__ASM("CPSIE I");

 

}

uint32_t sample[10];

void ADC0_IRQHandler(void)

 

{

 

if (ADC0->SC1[0] & ADC_SC1_COCO_MASK)

 

{

// ADC0->SC1[0] = ADC_SC1_AIEN_MASK | ADC_SC1_ADCH(8);

GPIOC->PTOR = 0x40; // Toggle indicator

 

sample[0] = ADC0->R[0];

 

}

 

}

 

0 项奖励
回复
2,477 次查看
pandi
Contributor III

Hi

@xiangjun_rong Thanks

This program working . Its possible 4 ADC0 channel and 4 PWM  with FTM0 triggering method how to configure? guide me

 

BR

PANDI

0 项奖励
回复
2,403 次查看
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

It is okay to sample 4 ADC channel synchronized.

The KV31 has 2 ADC modules, ADC0 and ADC1, each ADC has two converters: SC1A and SC1B, so  it is okay, but the PDB module must be involved.

This is the solution.

FTM triggers PDB, the PDB generates timing to trigger both ADC0 and ADC1.

Pls refer to the ticket and check if it is helpful.

https://community.nxp.com/t5/Kinetis-Microcontrollers/KV56-Trigger-HSADC-with-PDB/m-p/1473870#M63331

BR

XiangJun Rong

 

0 项奖励
回复
2,172 次查看
pandi
Contributor III

HI 

@xiangjun_rong 

okey,

Its possible for KV31 4 ADC channels continuously trigger FTM 0 .if you have sample program give to me help for us

thank you

BR

PANDI

0 项奖励
回复
2,112 次查看
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

I means that the FTM0 trigger 4 ADC channel via PDB.

Pls refer to the an:

https://www.nxp.com.cn/docs/en/application-note/AN4822.pdf

Hope it can help you

BR

XiangJun Rong

0 项奖励
回复
2,034 次查看
pandi
Contributor III

HI

@xiangjun_rong 

Thank you

0 项奖励
回复
2,553 次查看
pandi
Contributor III
Hi
xiangjun_rong
Thank you for your answer
This program ADC value 950 range only varying KV31F512VLL12 IN 12 bit ADC why 950 range ?I`m using 12 bit ADC watch variable sample[0] only 950

BR
PANDI
0 项奖励
回复
2,522 次查看
xiangjun_rong
NXP TechSupport
NXP TechSupport

Hi,

You set the line:

DC0->CFG1 = ADC_CFG1_ADIV(4) | ADC_CFG1_MODE(1) | ADC_CFG1_ADICLK(0);

Mode bits is 01 in binary, so the ADC resolution is 12 bits.

The 3.3V full range is 0xFFF or 4095. The tested voltage on ADC channel is (950/4095)*3.3V=0.76V.

Hope it can help you

BR

XiangJun Rong

xiangjun_rong_0-1704853384564.png

 

0 项奖励
回复