adc interrupt

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

adc interrupt

1,827 次查看
IuliaB
Contributor I

Hello! Im  using an S32K144 board. I made a program where I light different colors on my led depending on the potentiometer value, but I did that in polling mode, where I wait until the conversion is done. I want to do it now by interrupts, but I'm not sure how to continue from this

ADC.c

 

#include "ADC.h"
uint32_t adcResultInmv=0;
uint32_t adcConvDone = 0;
void ADC_init(void) {

PCC->PCCn[PCC_ADC0_INDEX] &=~ PCC_PCCn_CGC_MASK; /* Disable clock to change PCS */
PCC->PCCn[PCC_ADC0_INDEX] |= PCC_PCCn_PCS(1); /* PCS=1: Select SOSCDIV2 */
PCC->PCCn[PCC_ADC0_INDEX] |= PCC_PCCn_CGC_MASK; /* Enable bus clock in ADC */

ADC0->SC1[0] = ADC_SC1_AIEN_MASK | /* AIEN=1: enable interrupt trigger */
ADC_SC1_ADCH(8); /* ADCH=8: serial number 0 selects channel 8 */
ADC0->CFG1 = 0x000000004; /* ADICLK=0: Input clk=ALTCLK1=SOSCDIV2 */
/* ADIV=0: Prescaler=1 */
/* MODE=1: 12-bit conversion */
ADC0->CFG2 = 0x00000000C; /* SMPLTS=12(default): sample time is 13 ADC clks */
ADC0->SC2 = 0x00000000; /* ADTRG=0: SW trigger */
/* ACFE,ACFGT,ACREN=0: Compare func disabled */
/* DMAEN=0: DMA disabled */
/* REFSEL=0: Voltage reference pins= VREFH, VREEFL */
ADC0->SC3 = 0x00000000; /* CAL=0: Do not start calibration sequence */
/* ADCO=0: One conversion performed */
/* AVGE,AVGS=0: HW average function disabled */
S32_NVIC->ICPR[39 / 32] = (1 << (39 % 32));
S32_NVIC->ISER[39 / 32] = (1 << (39 % 32));
S32_NVIC->IP[39] = (10 << 4);

}

void convertAdcChan(uint16_t adcChan) { /* For SW trigger mode, SC1[0] is used */
ADC0->SC1[0]&=~ADC_SC1_ADCH_MASK; /* Clear prior ADCH bits */
ADC0->SC1[0] = ADC_SC1_ADCH(adcChan); /* Initiate Conversion*/
}

uint8_t adc_complete(void) {
return ((ADC0->SC1[0] & ADC_SC1_COCO_MASK)>>ADC_SC1_COCO_SHIFT); /* Wait for completion */
}

uint32_t read_adc_chx(void) {
uint16_t adc_result=0;
adc_result=ADC0->R[0]; /* For SW trigger mode, R[0] is used */
return (uint32_t) ((5000*adc_result)/0xFFF); /* Convert result to mv for 0-5V range */
}


void ADC0_IRQHandler(void)
{
adcResultInmv = read_adc_chx();

adcConvDone = 1;
}

 

 

 

 

 

 

 

main.c

#include "S32K144.h" /* include peripheral declarations S32K144 */
#include "clocks_and_modes.h"
#include "ADC.h"

#define PTC12 12 /* SW2*/
#define PTC13 13 /* SW3 */
#define PTD0 0 /*Blue LED*/
#define PTD15 15 /* Red LED */
#define PTD16 16 /* Green LED*/


void PORT_init (void) {

PCC->PCCn[PCC_PORTD_INDEX ]|=0x40000000; /* Enable clock for PORTD */
PCC->PCCn[PCC_PORTC_INDEX]=0x40000000; /* Enable clock for PORTC */

PORTD->PCR[PTD0] = 0x00000100; /* Port D0: MUX = GPIO */
PORTD->PCR[PTD15] = 0x00000100; /* Port D15: MUX = GPIO */
PORTD->PCR[PTD16] = 0x00000100; /* Port D16: MUX = GPIO */

PTD->PDDR |= 1<<PTD0; /* Port D0: Data Direction= output */
PTD->PDDR |= 1<<PTD15; /* Port D15: Data Direction= output */
PTD->PDDR |= 1<<PTD16; /* Port D16: Data Direction= output */

PTC->PDDR =0; /* PTC: Data Direction= input */
PORTC->PCR[12] = 0x00000110; /*Port C12: MUX = GPIO */
PORTC->PCR[13] = 0x00000110; /*Port C13: MUX = GPIO */

}

void WDOG_disable (void){

WDOG->CNT=0xD928C520; /* Unlock watchdog */
WDOG->TOVAL=0x0000FFFF; /* Maximum timeout value */
WDOG->CS = 0x00002100; /* Disable watchdog */
}

int main(void)
{
uint32_t adcResultInMv=0;

WDOG_disable(); /* Disable WDOG*/
SOSC_init_8MHz(); /* Initialize system oscillator for 8 MHz xtal */
SPLL_init_160MHz(); /* Initialize SPLL to 160 MHz with 8 MHz SOSC */
NormalRUNmode_80MHz(); /* Init clocks: 80 MHz sysclk & core, 40 MHz bus, 20 MHz flash */
PORT_init(); /* Init port clocks and gpio outputs */
ADC_init(); /* Init ADC resolution 12 bit*/

for(;;)
{
convertAdcChan(12); /* Convert Channel AD12 to pot on EVB */
/* while(adc_complete()==0){} */ /* Wait for conversion complete flag */
adcResultInMv = read_adc_chx(); /* Get channel's conversion results in mv */

if(PTC->PDIR & (1<<PTC13)) {
PTD->PSOR |= 1<<PTD16;
PTD-> PCOR |= 1<<PTD15| 1<<PTD0;
}
else { /* If BTN0 was not pushed */
PTD-> PSOR |= 1<<PTD15| 1<<PTD0; /* Set Output on port D0 (LED off) */
}


if ((adcResultInMv > 3000)&&(adcResultInMv < 5000 )) { /* If 2.5 < result < 5V */
PTD->PSOR |= 1<<PTD0 | 1<<PTD15; /* turn off blue, green LEDs */
PTD->PCOR |= 1<<PTD16; /* turn on GREEN LED */
}
else if ((adcResultInMv >1500)&&(adcResultInMv <3000)) { /* If 1.5< result < 2.5V */
PTD->PSOR |= 1<<PTD0 | 1<<PTD16; /* turn off blue, red LEDs */
PTD->PCOR |= 1<<PTD15; /* turn on RED LED */
}
else if ((adcResultInMv >0)&&(adcResultInMv <1500)) { /* If 0 <result < 1.5V */
PTD->PSOR |= 1<<PTD15 | 1<<PTD16; /* turn off red, green LEDs */
PTD->PCOR |= 1<<PTD0; /* turn on BLUE LED */
}

convertAdcChan(29); /* Convert chan 29, Vrefsh */
/* while(adc_complete()==0){} */ /* Wait for conversion complete flag */
adcResultInMv = read_adc_chx(); /* Get channel's conversion results in mv */
}
}

0 项奖励
回复
5 回复数

1,791 次查看
JRoberto
NXP TechSupport
NXP TechSupport

Hello @IuliaB 

If I'm understanding correctly your question... you need information on how to configure the ADC interruption?

Best Regards!.

0 项奖励
回复

1,786 次查看
IuliaB
Contributor I

Yes

 

标记 (1)
0 项奖励
回复

1,747 次查看
JRoberto
NXP TechSupport
NXP TechSupport

Hello @IuliaB 

 

I reviewed the RTD's example named Adc_Pdb_Ip_example_S32K144 and I believe it contains the behavior you desire.

 

Best Regards!

0 项奖励
回复

1,734 次查看
IuliaB
Contributor I

@JRoberto Im sorry but I dont know where to find it

0 项奖励
回复

1,726 次查看
JRoberto
NXP TechSupport
NXP TechSupport

@IuliaB 

You can find this and more useful examples in the RTD development package. 

You can install it from its homepage at: Real-Time Drivers (RTD) | NXP Semiconductors

Also, I'm attaching the example to this reply.

Additionally, here is an example of how to use RTD drivers to create a simple project

HOWTO: Create a Blinking LED example project using... - NXP Community

Best Regards!

0 项奖励
回复