Hi,
I am using lpc1768. By using Timer, i have generated a square wave with time period of 16ms. The ON period should be 1ms and OFF period should be 15ms. I used two match registers MR0 and MR1. I done with MR0 for OFF period and MR1 for ON period. But am getting the signal as 15ms as ON period and 1ms as OFF period. Plz suggest some solutions.
Thank You
feed your signal thru an inverter. then you will get what you want. you can use a transistor or a fet or a ttl device or a cmos device. there are lots of other options too. use the one that you have access to. you could write a program for a cortex a-8 that samples a port pin and feeds the inverted input to an output pin; but that might be a slight overkill for your problem.
alternatively, read the manual for the part, determine what you are doing and adjust that so you then do what you want.
Look into Your Timer ISR properly. (or post the code atleast). The port pin (on which signal is generated) is cleared (reset) when it needs to be Set and vice versa.
use an inverter If in case (custom) board is already designed and manufactured, adding an inverter will not be possible (time, more importantly, & money may be wasted in redesigning).
Personally, Wont prefer giving such advice.
I assume the suggestion of an inverter was written in irony, since it seems so obvious the OP is stuck based on a refusal to activate the grey matter between the ears and ponder the code and the very well-written timer documentation.
It really shouldn't take many seconds to figure out good solutions to resolve this issue.
I assume the suggestion of an inverter was written in irony
Wasn't the use of a cortex a8 dedicated to the task of inversion of a single line a clue?
When and Where did OP mention cortex a8? OP mentions LPC1768 which happens to be Cortex-M3 series controller by NXP.
you could write a program for a cortex a-8 that samples a port pin and feeds the inverted input to an output pin; but that might be a slight overkill for your problem. From the question itself, its very clear that the OP is unable to perform one of the simplest task of Toggling a pin correctly, and here you are, advicing OP to travel the globe.
You need to ask Dhaval Solanki.
"When and Where did OP mention cortex a8?"
Sometimes, it helps to read all posts in a thread, to pick up the required context.
No one in this thread have claimed that the OP has a Cortex A8. But the (very correct) insinuations is that the OP forgot to turn on the brain today.
If match pins are used for full hardware operation, then I see at least three different solutions by just playing with the code.
If having the ISR explicitly play with processor pins, then there are at least 2 different software options to invert the logic.
None of the alternatives are advanced. All of them can be considered obvious.
The OP seems to have selected this forum as the first step in his thought process, instead of using it as a fallback when actually stuck after having spent some time with this issue.
I am posting ma Code here.
#include "lpc17xx.h" #include "type.h" #include "timer.h" extern uint32_t timer0_m0_counter, timer1_m0_counter; extern uint32_t timer0_m1_counter, timer1_m1_counter; int main (void) { uint32_t i; SystemInit(); LPC_PINCON->PINSEL1&=~(3<<10); LPC_GPIO0->FIODIR|=(1<<21); LPC_GPIO0->FIOCLR|=(1<<21); LPC_GPIO1->FIODIR |= 1<<29; // P1.29 = Outputs LPC_GPIO1->FIOCLR = 1<<29; // Turn-OFF LED for ( i = 0; i < 2; i++ ) { init_timer( i , TIME_INTERVAL ); enable_timer( i ); } /*Timer pgm*/ void TIMER0_IRQHandler (void) { if ( LPC_TIM0->IR & (0x1<<0) ) { LPC_TIM0->IR = 0x1<<0; /* clear interrupt flag */ timer0_m0_counter++; if (LPC_GPIO0->FIOPIN & (1<<21)) { LPC_GPIO0->FIOCLR|=(1<<21); LPC_GPIO1->FIOCLR = 1<<29; // Turn-OFF LED LPC_TIM0->MCR = (0x3<<3);//|(0x3<<3); /* Interrupt and Reset on MR1 */ } } if ( LPC_TIM0->IR & (0x1<<1) ) { LPC_TIM0->IR = 0x1<<1; /* clear interrupt flag */ timer0_m1_counter++; LPC_GPIO0->FIOSET|=(1<<21); LPC_GPIO1->FIOSET = 1<<29; // Turn-ON LED LPC_TIM0->MCR = (0x3<<0);//|(0x3<<3); /* Interrupt and Reset on MR0 */ } if ( LPC_TIM0->IR & (0x1<<4) ) { LPC_TIM0->IR = 0x1<<4; /* clear interrupt flag */ timer0_capture0++; } if ( LPC_TIM0->IR & (0x1<<5) ) { LPC_TIM0->IR = 0x1<<5; /* clear interrupt flag */ timer0_capture1++; } return; } uint32_t init_timer ( uint8_t timer_num, uint32_t TimerInterval ) { uint32_t pclkdiv, pclk; if ( timer_num == 0 ) { timer0_m0_counter = 0; timer0_m1_counter = 0; timer0_capture0 = 0; timer0_capture1 = 0; LPC_SC->PCONP |= (0x01<<1); #if TIMER_MATCH LPC_PINCON->PINSEL3 &= ~((0x3<<24)|(0x3<<26)); LPC_PINCON->PINSEL3 |= ((0x3<<24)|(0x3<<26)); #else LPC_PINCON->PINSEL3 &= ~((0x3<<20)|(0x3<<22)); LPC_PINCON->PINSEL3 |= ((0x3<<20)|(0x3<<22)); #endif LPC_TIM0->IR = 0x0F; /* Clear MATx interrupt include DMA request */ /* By default, the PCLKSELx value is zero, thus, the PCLK for all the peripherals is 1/4 of the SystemFrequency. */ /* Bit 2~3 is for TIMER0 */ pclkdiv = (LPC_SC->PCLKSEL0 >> 2) & 0x03; switch ( pclkdiv ) { case 0x00: default: pclk = SystemFrequency/4; break; case 0x01: pclk = SystemFrequency; break; case 0x02: pclk = SystemFrequency/2; break; case 0x03: pclk = SystemFrequency/8; break; } //LPC_TIM0->PR = pclk/1000000; /* set prescaler to get 1 M counts/sec */ LPC_TIM0->MR0 = TIME_INTERVALmS * 15 * 18; /* Set up 10 mS interval */ LPC_TIM0->MR1 = TIME_INTERVALmS * 1 * 18; /* Set up 10 mS interval */ #if TIMER_MATCH LPC_TIM0->EMR &= ~(0xFF<<4); LPC_TIM0->EMR |= ((0x3<<4)|(0x3<<6)); #else /* Capture 0 and 1 on rising edge, interrupt enable. */ LPC_TIM0->CCR = (0x1<<0)|(0x1<<2)|(0x1<<3)|(0x1<<5); #endif LPC_TIM0->MCR = (0x3<<0)|(0x3<<3); /* Interrupt and Reset on MR0 and MR1 */ NVIC_EnableIRQ(TIMER0_IRQn); return (TRUE); } else if ( timer_num == 1 ) { timer1_m0_counter = 0; timer1_m1_counter = 0; timer1_capture0 = 0; timer1_capture1 = 0; LPC_SC->PCONP |= (0x1<<2); #if TIMER_MATCH LPC_PINCON->PINSEL3 &= ~((0x3<<12)|(0x3<<18)); LPC_PINCON->PINSEL3 |= ((0x3<<12)|(0x3<<18)); #else LPC_PINCON->PINSEL3 &= ~((0x3<<4)|(0x3<<6)); LPC_PINCON->PINSEL3 |= ((0x3<<4)|(0x3<<6)); #endif LPC_TIM1->IR = 0x0F; /* Clear MATx interrupt include DMA request */ /* By default, the PCLKSELx value is zero, thus, the PCLK for all the peripherals is 1/4 of the SystemFrequency. */ /* Bit 4~5 is for TIMER0 */ pclkdiv = (LPC_SC->PCLKSEL0 >> 4) & 0x03; switch ( pclkdiv ) { case 0x00: default: pclk = SystemFrequency/4; break; case 0x01: pclk = SystemFrequency; break; case 0x02: pclk = SystemFrequency/2; break; case 0x03: pclk = SystemFrequency/8; break; } LPC_TIM1->PR = pclk/1000000; /* set prescaler to get 1 M counts/sec */ LPC_TIM1->MR0 = TIME_INTERVALmS * 10; /* Set up 10 mS interval */ LPC_TIM1->MR1 = TIME_INTERVALmS * 10; /* Set up 10 mS interval */ #if TIMER_MATCH LPC_TIM1->EMR &= ~(0xFF<<4); LPC_TIM1->EMR |= ((0x3<<4)|(0x3<<6)); #else /* Capture 0/1 on rising edge, interrupt enable. */ LPC_TIM1->CCR = (0x1<<0)|(0x1<<2)|(0x1<<3)|(0x1<<5); #endif LPC_TIM1->MCR = (0x3<<0)|(0x3<<3); /* Interrupt and Reset on MR0 and MR1 */ NVIC_EnableIRQ(TIMER1_IRQn); return (TRUE); } return (FALSE); }
Why are you using two match registers but only managing to have your ISR behave as if the timer had just a single match register?
Don't you recognize that there can be multiple matches (and multiple match interrupts) without any reset in between? Why else would there be an option to configure the chip to reset (or to not reset) the timer on each of the individual match values?
By the way - driving processor pins from the interrupt means there will always be latencies and jitter involved. The ISR isn't always trigged at exact time when you get a match. And then you spend a number of instructions just to figure out what to do. Match pins can toggle with zero ISR intervention. Match pins can produce that 15ms + 1ms cycle completely without ISR intervention - so the ISR would only be needed if you want your counters incremented.
Have you actually spent time reading the timer chapter? And look at available sample code? And then returned back and read the timer chapter of the processor users manual a second time?
First i have done without reset. But its not working...
Well, you would normally have one match register produce a interrupt+reset while the other only produces an interrupt.
And you make MR0 = 15ms and MR1 = 16ms. Or MR0 = 1ms and MR1 = 16ms.
Then you get a 16ms cycle that either have 1+15 or 15+1 - both alternatives can give the correct output - the only difference is with of the periods it starts with directly when you initialize the timer.
But in the end, it is important to note that things often doesn't work on first try. The task then isn't to rewrite the code randomly and see what happens. You instead take one step back and try to compare what you think you instructed the processor to do, with that the processor manual describes the processor to do. And the debugger can be used to look at state and compare with the state you assumed you would have.
Random "work around" changes are seldom producing good solutions.
Why dont you use keil simulator? Or Connect a debugger and check whats actually happening?
Is posting a thread and waiting for the reply the fastest method to solve the problem [given the nature of the problem. It can be solved by studying the example codes also]??
Actually in the MCR register i have given reset and interrupt in both MR) and MR1 register. Thats why i didnt get. Now am getting the expected signal.
And that was why I explicitly wondered why you played with two match registers while still configuring the timer to reset on every match making it impossible to reach any second match value.
So next thing - are you aware that if you use the match output pins, then you can have the timer drive these pins with zero ISR involved? And zero jitter from interrupt response time or varying code paths of any code sequences?