Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

lpc2138 timer led toggle

Status
Not open for further replies.

eray81

Junior Member level 3
Joined
Jan 1, 2012
Messages
29
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,461
Hi,
I want to toggle a pin with timer0. I wrote the code below but it doesnt work.
help please ;-)

Code:
#include <LPC21xx.H> 

void T0isr(void)	__irq;

   volatile int i=0;
volatile int num=0;
int main(void)
{
IODIR0 = 0XFFFFFFFF;

T0IR = 1;  
T0CCR = 0;		  
T0PR = 12000;		  
T0MR0 = 4;				
T0MCR = 3;				
T0TCR = 1;	


VICVectAddr4 = (unsigned)T0isr;		//Set the timer ISR vector address
VICVectCntl4 = 0x00000024;			//Set channel
VICIntEnable |= 0x00000010;			//Enable the interrupt



}

void T0isr(void)	__irq
{

T0IR = 1; 
if(++i==100){
 	IO0SET = 0x00000001;  
 i=0;
 }
  }
 
Last edited by a moderator:

You code can only set the pin to 1 , if you want to toggle the pin you can use something like IO0PIN ^= 0x00000001;
You should also use VICVectAddr = 0; before you exit the interrupt



Code C - [expand]
1
2
3
4
5
6
7
8
9
void T0isr(void) __irq
{
    if(++i==100) {
        IO0PIN ^= 0x00000001;
        i=0;
    }
    T0IR = 1;           /* Clear MAT0.0 interrupt flag */
    VICVectAddr = 0;    /* Acknowledge Interrupt */
}



Alex
 

thanks but it doesnt work again. may the timer register configs be wrong? ( I want to toggle pin0.0 for 500ms)
 

With a T0PR = 12000; the timer is counting peripheral_clock/12000 , if you have 60 MHz core and 1/4 for the peripherals (15 MHz ) this results to 1.2499KHz you get an interrupt every 3.2ms

It should work , I don't see anything wrong, are you using a hardware of simulator?

Have you tried with a simple blinking pin using a delay to see if it works?
 

I use Proteus and , yes i have tried with a simple blinking pin using a delay and it works fine. I dont understand what the problem is :s....
 

Code:
PLLCFG = 0x00000024;				      	// Set multiplier and divider of PLL to give 60.00 Mhz
PLLCON = 0x00000001;				      	// Enable the PLL

PLLFEED = 0x000000AA;						// Update PLL registers with feed sequence
PLLFEED = 0x00000055;

while (!(PLLSTAT & 0x00000400)) 			// test Lock bit
{
;
}
PLLCON = 0x00000003;				      	// Connect the PLL

PLLFEED = 0x000000AA;				   		//Update PLL registers
PLLFEED = 0x00000055;

VPBDIV = 0x00000002;
 
Last edited by a moderator:

Did you place a breakpoint in the interrupt to see if it is actually called?
Did you check the timer to see if it is counting ok and what happens when it reaches the match value?
 

Your Oscillator and PLL initialization looks correct.

However, after looking over your code I noticed you were missing a SuperLoop, which would prevent the code execution from exiting main().

Code:
#include <LPC21xx.H> 

void T0isr(void)	__irq;

   volatile int i=0;
volatile int num=0;
int main(void)
{
IODIR0 = 0XFFFFFFFF;

T0IR = 1;  
T0CCR = 0;		  
T0PR = 12000;		  
T0MR0 = 4;				
T0MCR = 3;				
T0TCR = 1;	


VICVectAddr4 = (unsigned)T0isr;		//Set the timer ISR vector address
VICVectCntl4 = 0x00000024;			//Set channel
VICIntEnable |= 0x00000010;			//Enable the interrupt

[COLOR="#FF0000"]while(1){};[/COLOR]  //Add SuperLoop

}

void T0isr(void)	__irq
{

T0IR = 1; 
if(++i==100){
 	IO0SET = 0x00000001;  
 i=0;
 }
  }

The absence of a SuperLoop could definitely be an issue.

Depending on your compiler, you may need to add some superfluous code within the SuperLoops code block to prevent it from being removed during optimization.

BigDog
 

The final version of my code is below and works but when i will add SuperLoops code it doesnt work. And i dont use PLL config.

Code:
#include <LPC21xx.H> 

void T0isr(void)__irq;
			
volatile int i=0;
volatile int sayi=0;
int main(void)
{
VPBDIV= 0X00000002;
T0TC=0x00000005;     
T0PR=15;  
T0MCR=0x00000006;     
T0MR0=150;     
T0EMR=0x0031;     
T0TCR=0x01;     
IODIR1 = 0X00000000;
	

VICVectAddr4 = (unsigned)T0isr;		//Set the timer ISR vector address
VICVectCntl4 = 0x00000024;			//Set channel
VICIntEnable |= 0x00000010;			//Enable the interrupt

	 
}


void T0isr(void) __irq
{
    
    T0IR = 1;           /* Clear MAT0.0 interrupt flag */
    VICVectAddr = 0;    /* Acknowledge Interrupt */
}

With this code i can toggle MAT0.0 pin by changing the T0PR and T0MR0, but i couldnt achieve the 500ms toggle action.
 
Last edited by a moderator:

The final version of my code is below and works but when i will add SuperLoops code it doesnt work.

If the presence of additional code, like a simply loop structure, in main() prevents the ISR or Timer from function as expected, then you'll got bigger issues to deal with.

After all what good is an ISR, if it fails to perform if there is any other code in main()?

The whole point of an ISR is to service interrupts from outside the main code structure.

With this code i can toggle MAT0.0 pin by changing the T0PR and T0MR0, but i couldnt achieve the 500ms toggle action.

I would suspect the code is, in fact, not executing in the expected fashion and you are seeing the residual effects of possible repeated rebooting.

What compiler/version are you using?

BigDog
 

I am using Keil uVision MDK-Lite version 4.20. As a matter I am new with lpc21xx series and i am trying to learn the basic architecture of them.
 

Do you have a JTAG programmer/debugger, a bootloader with FLASHMagic or other means?

I'll need to see what the closest LPC ARM I have available here to the LPC2138, before I can properly test your code.

BigDog
 

No i dont have any of them. I can just simulate the code with Proteus/ISIS.
 

Can you upload the project file here, just zip it and attach in the post.
 

I've corrected your code and successfully simulated it with both KEIL and Proteus. The ISR is called every .5 second (500ms) generating a blinking LED of 1Hz.

The code was also successfully tested on a LPC210X Development Board, the closest LPC to the LCP2138 I had available.

main.c
Code:
// Fosc = 12MHz
// CCLK = 60MHz
// PCLK = CCLK/4 = 15MHz

 #include <LPC21xx.H> 

__irq void T0isr(void);

unsigned long i=0;	// Dummy Count Variable for SuperLoop

int main(void)
{
IODIR0 = 0XFFFFFFFF;

T0MR0 = 7500000L;	  // Set Timer Duration to .5 Seconds (500ms)  TimerDuration * PCLK = .5 * 15MHz = 7500000
T0PR = 0;			  // Set Timer Prescaler to None
T0MCR = 3;			  // Interrupt and Reset on Counts	
T0TCR = 1;			  // Timer0 Enabled
	


VICVectAddr4 = (unsigned long)T0isr;	// Set Timer ISR Vector Address
VICVectCntl4 = 0x00000024;				//Assign Interrupt Vector to Timer0
VICIntEnable = 0x00000010;				//Enable Timer0 Interrupt

while(1){i++;};  // SuperLoop to Keep Execution in main()

}

__irq void T0isr(void)		  // Timer0 ISR
{

 	IO0PIN ^= 0x00000001;  	 // Toggle P0.0 Output

  	T0IR = 1;				 // Clear Interrupt Flag
	VICVectAddr = 0;		 // Acknowledge Interrupt
 }

I have also attached both the KEIL project and Proteus Simulation files in a ZIP format.

BigDog
 

Attachments

  • eray81.zip
    104.2 KB · Views: 76

Thank you very much, it works clearly. :wink:
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top