EmbeddedRelated.com
Forums
The 2024 Embedded Online Conference

ADC returns 0 when used with PWM on LPC2148

Started by "ben...@yahoo.com [lpc2000]" December 5, 2014
I am writing some code for the LPC2148. I have some working ADC code using AD0.3 on P0.30. After adding PWM using PWM5 on P0.21 with match interrupts, the ADC always returns 0. I have been unable to determine why. Any help would be appreciated. Here is the code for each:

ADC Code:
// Select P0.30 as AD0.3
PINSEL1 |= (1 << 28);

int GetADCResult(void)
{
int result = 0;

// Perform ADC acquire and conversion
// Initialize ADC converter
AD0CR = (1<<3) // Use channel 3
| ((15-1) << 8) // 4.0MHz Clock (60.0MHz / 15)
| (1<<21) // Power up ADC
| (0<<16); // Burst Mode off

AD0CR |= (0<<26) | (0<<25) | (1<<24); // start conversion
while((AD0DR3 & (1<<31)) == 0);

// Get the result from bits 6 to 15
result = (AD0DR3>>6) & 0x3FF;

return result;
}

PWM Code:

void InitPWM(void)
{
// ----- Configure PWM interrupt (slot 8) -----

// PWM Interrupt is an IRQ interrupt so clear bit
VICIntSelect &= ~(1 << 8);
// Set PWM interrupt to slot 0 and enable slot
VICVectCntl0 = (1<<5) | 8;
// Set the address of ISR for slot 0
VICVectAddr0 = (unsigned) PWM_ISR;

// ---- PLL0 has been setup with CCLK 60Mhz and PCLK also = 60Mhz.
// === Configure P0.21 for Output as PWM5 ============= // Period: 4 ms
// Duty Cycle: 12.5%
// Pulse duration: 0.5 ms
// ----------------
PINSEL1 = (1 << 10); // Select PWM5 output for P0.21
PWMPCR = 0x0; // Select Single Edge PWM
PWMPR = PWM_PRESCALE-1; // 1 micro-second resolution
PWMMR0 = 400; // 400 ticks i.e 400*1us = 4ms period duration
PWMMR5 = 50; // 0.5 ms Initial pulse duration i.e width
PWMMCR = (1<<1) | (1<<0) // Reset PWMTC and interrupt on PWMMR0 match
| (1<<15); // interrupt on PWMMR5 match
PWMLER = (1<<0) | (1<<5); // update MR0 and MR5
PWMPCR = (1<<13); // Enable PWM output for PWM5
PWMTCR = (1<<1) ; //Reset PWM Timer and Prescale counters
// Enable
PWMTCR = (1<<0) | (1<<3); // enable counters and PWM Mode output
}
void PWM_ISR(void)
{
long regVal = PWMIR;

// Check PWM Interrupt Register to determine which match
// generated the interrupt.
if (PWMIR & (1<<0)) // PMMMR0 match - beginning of period
{
// Do X
}
else if (PWMIR & (1<<9)) // PWMMR4 match - beginning of pulse
{
// Do Y
}

PWMIR = regVal; // Clear Interrupt Register
VICVectAddr = 0x0; //End of ISR
}

An Engineer's Guide to the LPC2100 Series

Please ignore this. I posted here and thought it got cancelled, so I sent an email with the same problem.
Probably the best sample code around for the LPC2148 is at
LPC2148 Demo Code Overview http://www.jcwren.com/arm

LPC2148 Demo Code Overview http://www.jcwren.com/arm The latest demo code version is 1.44, dated 12-Jan-2009 View the latest README file Download the latest tar+gzip'ed version (Linux) Download the latest zipped version (Windows)

View on www.jcwren.com http://www.jcwren.com/arm
Preview by Yahoo

Among other things, there is no need for an interrupt handler to create PWM and it usually isn't necessary to reconfigure the ADC just to start a conversion.

Read over JC's code and see if it helps.

Richard
Thanks for the link, I will take a look.

I plan to use the ISR to do some work down the road, so I do need it.
That's fine, there is no reason not to use it. Except that unless the work is directly related to the PWM, it might be better to do it in a Timer interrupt. For certain, no PWM calculations need to be done in an interrupt.

Richard

The 2024 Embedded Online Conference