Periodic ADC read with interrupt

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Periodic ADC read with interrupt

2,338 Views
irmantasbudrys
Contributor III

Hello All,

I am using FRDM DEV BRD KEAZ128 and S32.  I want to read ADC value every 1ms. To do that I need timer interrupt every 1ms. Any suggestions how to do it?  Are where any code examples?

Best Regards,

IB

0 Kudos
Reply
5 Replies

1,344 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Irmanta,

You can use the FTM as timer, when the FTM reach 1ms, then do the ADC converstion.

  Please refer to this sample code:

SDK Software Drivers for KEAZ128_KEAZ64 using S32DS

  After you download it, you can the FTM_ADC sample code from folder: SDK-DRIVER-FRDM-KEA-S32DS\KEAZ128 Drivers testcode and Examples (for S32DS)\KEAZ128 Lab code examples

  Then modify the FTM timer to 1ms.

Wish it helps you!

If you still have question, please let me know!


Have a great day,
Jingjing

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

1,344 Views
irmantasbudrys
Contributor III

Hello,

Thanks for that.

I am thinking which method is better to use for reading ADC value every 1ms:

a) Use PIT interrupt every 1ms to read ADC?

b) use FTM interrupt every 1ms to read ADC?

Which method would be better? What is the difference between them?

I found that example mentioned above, but is where any examples to read ADC value every x ms  in S32 KEA_Driver_Lib?

Best Regards,

IB

0 Kudos
Reply

1,344 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Irmantas,

  1. Which method would be better? What is the difference between them?

    PIT and FTM just the different timer, but both of them are the timer.

    The PIT module is an array of timers that can be used to raise interrupts and triggers. This device contains one PIT module with two channels and supporting chained timer mode.

    The FTM timer contains up to six channels which support input capture, output compare and the generation of PWM signals to control electric motor and power management applications. FTM time reference is a 16-bit counter which can be used as an unsigned or signed counter.

  FTM have more function than PIT, it can output the PWM wave in the FTM channel, but PIT is just the timer.

    So, if you want just want to use the timer function, actually, both FTM and PIT you can use.

    2. Is where any examples to read ADC value every x ms  in S32 KEA_Driver_Lib?

    Just one example is enough, when you want to use the difference x ms, you just need to calculate the value for the timer, you can according the PIT and  FTM module timing formula to calculate it. More details, please refer to the reference manual, chapter PIT and FTM.


Have a great day,
Jingjing

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply

1,344 Views
irmantasbudrys
Contributor III

Hello Jingjing,

Well that is the problem because one example is not enough. I need to read ADC value every x ms  and to send data via UART (using printf () function). Blinking red LED indicates me interrupt frequency. 

I am modifying LAB6 - FTM & ADC Module. But  I not sure how to configure clock to interrupt every x ms (for example every 1ms).

Questions:

a) I don't understand what frequency is core clock and bus clock?   

b) How to make interrupt every 1 ms from FTM2? Please you can explain me how to do it.

c) In a code below I am trying to get 1s interrupt  but it is 1,72s...

I think functions FTM2_Init_Output_Cmp();  and  FTM2_SetPeriod(0, 187499); are not working properly because I can change value for period but period is not changing.

d)  Maybe I should do something with Timer overflow flag ( configure TOF, and TOIE registers)  to get precise interrupt every x ms? Any examples? 

e) Maybe I should Trigger ADC with FTM ? I not sure which method is best for me. Please advice.

/******************************************************************************

*    LAB6 - FTM & ADC Module                          *

*    FRDM+KEA128 Board  *

*                                                                             *

*    This lab demonstrates how to use the ADC module to read the analog  *

*    value of the on-board potentiometer and use FTM to blink LEDs.  *

*    The application reads the potentiometer, ADC channel 10.                 *

*    LED will change color and speed according to the ADC value.              *

*    FLEX timer is used for that.                                             *

*    Target Board is FRDM+KEA128  *

******************************************************************************/

/**********************************************************************************************

* External objects

**********************************************************************************************/

#include "derivative.h" /* include peripheral declarations */

#include "GPIO.h"

#include "ADC.h"

#include "FTM.h"

#include "uart.h"

#include "ics.h"

#include "printf.h"

/**********************************************************************************************

* Global variables

**********************************************************************************************/

/**********************************************************************************************

* Constants and macros

**********************************************************************************************/

#define PTH0 24 /* For RED LED */

#define LED0_TOGGLE OUTPUT_TOGGLE(H1,PTH0)

#define LED0_OFF OUTPUT_CLEAR(H1,PTH0);

#define LED0_ON OUTPUT_SET(H1,PTH0);

/**********************************************************************************************

* Local types

**********************************************************************************************/

/**********************************************************************************************

* Local function prototypes

*********************************************************************************************/

void Enable_Interrupt(uint8_t vector_number);

void FTM2_Interrupt();

//uint32_t ADC_FTM_ValueFunction();

/**********************************************************************************************

* Local variables

**********************************************************************************************/

uint8_t color=0;

uint16_t adc_value = 0;

uint8_t dec=10;

uint16_t adc_total=0;

uint16_t Result = 0;

/**********************************************************************************************

* Local functions

**********************************************************************************************/

/**********************************************************************************************

* Global functions

**********************************************************************************************/

/***********************************************************************************************

* @brief    GPIO_Init - Initialize the LEDs as outputs, SWs as inputs.

* @param    none

* @return   none

************************************************************************************************/

void GPIO_Init()

{

  CONFIG_PIN_AS_GPIO(H1,PTH0,OUTPUT); /* Configure RED LED as an output */

  LED0_OFF; /* Turn off RED */

}

/***********************************************************************************************

* @brief    main() - Program entry function

* @param    none

* @return   none

************************************************************************************************/

int main(void)

{

  /* Initialize Core Clock to MHz, Bus Clock to MHz  */

  /* Perform processor initialization */

  ICS_ConfigType ICS_set={0}; /* Declaration of ICS_setup structure */

  ICS_set.u8ClkMode=ICS_CLK_MODE_FEI; //FLL engaged internal clock//

  ICS_set.bdiv=0; // 0= divides by 1. Bus Frequency Divider//

  ICS_Init(&ICS_set);             /* Initialization of Core clock at 48 MHz, Bus clock at 24 MHz */

  /* Initialize UART  */

  UART_ConfigType UART_Config={{0}};

  UART_Config.sctrl1settings.bits.bM=0;   /* 8 bit mode*/

  UART_Config.sctrl1settings.bits.bPe=0; /* No hardware parity generation or checking*/

  UART_Config.bSbns=0; /* One stop bit*/

  UART_Config.sctrl2settings.bits.bRe=1; /* Enable Receiver*/

  UART_Config.sctrl2settings.bits.bTe=1; /* Enable Transmitter*/

  UART_Config.u32SysClkHz = 24000000;   /* Bus clock in Hz*/

  UART_Config.u32Baudrate = 9600;     /* UART baud rate */

  UART_Init(UART2,&UART_Config); /*Initialization of UART utilities*/

  /* Configure button pins as inputs and LED pins as outputs */

  GPIO_Init();

  /* Initialize the FTM2 module in Output Compare mode,

  * and interrupt at every 46875 counts, equal to every 300 ms */

  FTM2_Init_Output_Cmp();

  FTM2_SetPeriod(0, 187499);

  /* Initialize the ADC module and read at Channel 10 and 8bit conversion mode is imposed */

  ADC_Init(10,TWELVE_BIT); /* Configure ADC channel 10 in 8-bit resolution mode */

  /* Enable FTM interrupt */

  Enable_Interrupt(FTM2_IRQn);

  while(1);

   return 0;

}

/***********************************************************************************************

* @brief    FTM2_Interrupt() - User Function called by the FTM2 module on each timer interrupt.

* @param    none

* @return   none

************************************************************************************************/

void FTM2_Interrupt()

{

  (void)FTM2_C0SC;   /* Read to clear flag */

  FTM2_C0SC ^= FTM_CnSC_CHF_MASK;   /* Clear flag */

  adc_value=ADC_Read(10); /* Read ADC value from channel 10 */

   adc_total+=adc_value ;

  dec--;

  if (dec==0)

  {

  Result=adc_total;

  printf("\nPOTENTIOMETER conversion value:%d\n",Result);//IB added

  Result=0;

  adc_total=0;

  dec=10;

  LED0_TOGGLE;

  }

}

/***********************************************************************************************

* @brief    FTM2_IRQHandler - Interrupt for FTM channels, Call user function.

* @param    none

* @return   none

************************************************************************************************/

void FTM2_IRQHandler()

{

  FTM2_Interrupt();

}

//////////////////////////////

/////////////////////////////code copy from FTM.C//////////////////////////////////////

void FTM2_Init_Output_Cmp()

{

  /*System Clock Gating Control Register*/

  SIM_SCGC |= SIM_SCGC_FTM2_MASK; /* Enable Clock for FTM2 */

  FTM2_SC |= FTM_SC_PS(7); /* Select Prescaler in this case 128. 24 Mhz /128 =187.50 Khz. */

  /* Counter increase by one every 5,333 us */

   /* Enable Channel 0*/

  FTM2_C0SC |= FTM_CnSC_CHIE_MASK; /* Enable channel 0 interrupt */

  FTM2_C0SC |= FTM_CnSC_MSA_MASK;  /* Channel as Output compare mode */

   /*Select interrupt frequency*/

  FTM2_C0V = 187499; // IB modified

  FTM2_SC |= FTM_SC_CLKS(1); /*FTM2 use system clock*/

   }

void FTM2_SetPeriod(uint8_t ch, uint32_t period)

{

FTM2_C0V = FTM_CnV_VAL(period) ;

}

Best Regards,

IB

0 Kudos
Reply

1,344 Views
kerryzhou
NXP TechSupport
NXP TechSupport

Hi Irmantas,

a) I don't understand what frequency is core clock and bus clock?

Answer: Please read the KEA128 reference manual to get some basic knowlege:

http://www.nxp.com/files/microcontrollers/doc/ref_manual/KEA128RM.pdf?fasp=1&WT_TYPE=Reference%20Man...

Chapter 5 Clock Distribution

Core clock: ICSOUTCLK divided by DIV1, clocks the ARM Cortex-M0+ core. It's the CPU HCLK

Bus clock: System clock divided by DIV2, clocks the bus slaves and peripherals

b) How to make interrupt every 1 ms from FTM2? Please you can explain me how to do it.

Answer: Please read the KEA128 reference manualchapter 26: Flextimer module.

If you choose 24Mhz clock as your FTM clock source, then if you want to get 1ms FTM overflow interrupt.

Set your MOD register =24000, after you enable the overflow interrupt, you will get 1ms interrupt.

c) In a code below I am trying to get 1s interrupt  but it is 1,72s...

I think functions FTM2_Init_Output_Cmp();  and  FTM2_SetPeriod(0, 187499); are not working properly because I can change value for period but period is not changing.

When you set the period, you should make sure the MOD register can input that value, MOD is the 16bit register, the max data is 65535, so you should calculate your timer data.

d)  Maybe I should do something with Timer overflow flag ( configure TOF, and TOIE registers)  to get precise interrupt every x ms? Any examples?

You need to write it by yourself, we don't have it directly.

You can write it by the timer formular.

Timer x = n/FTM clocks ; n is the MODE value, FTM clock is the FTM input clock after the prescaler.

e) Maybe I should Trigger ADC with FTM ? I not sure which method is best for me. Please advice.

Of course you can use FTM, please refer to the project which I give you.Other code, you need to add it by yourself.

If you meet the question, just let me know.


Have a great day,
Jingjing

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
Reply