Hi guys...I'm a newbie in ARM7 programming.I have a readymade hardware board of LPC2148.I'm doing a simple blinking action on it.I'm supplying the processor with 12MHz frequency as its processor clock.And i hve read in net somewhere tht each for loop [for(x=0;x<1;x++)] takes 12-13 cycles to execute.So by rough calculation the value of the delay counter should be 1000000 for 1sec delay.But my delay turns out to be 4-5sec. I have deactivated the MAM block and also PLL0 i.e., I'm using the external supplied oscillator as the clock source for the processor. I havn't used the timer module to get the desired delay till now..as i need to brush up the theories behind it first.But whether it is absolutely necessary to use the timer block to produce the 1sec delay?? plz answer my post some one..thanks in advance.My code is given below --
#include "LPC214x.H" /* Fosc = external supplied crystal frequency Fcclk = Processor clock or o/p of PLL0 Pclk = The VPB clock frquency.The o/p of the VPB driver Fcco = the frequency of the PLL current controlled oscillator */ void init_clock() { /* PLL0CON = 0x03; // PLL0 is enabled & connected as the clock source of the microcontroller PLL0CFG = 0x24; // The i/p crystal oscillator frequency is multiplied in the PLL0 block by a fator of 5(=4+1) PLL0FEED == 0xAA; // 0xAA and 0x55 should be feed into this register for the PLL0FEED == 0x55; // changes in PLL0CON and PLL0CFG to take place actively VPBDIV = 0x01; // The Pclk frequency = Fcclk frequecy..not necessary. // by default the GPIO are selacted as legacy ports */ PLL0CON=0x0; // these 4 lins are as given by blink.c.Though the result is nt coming as expected.the above commented out result are my first try to supply the processor with 60MHz clock supply // the PLL is nt connected as the clock source for the processor PLL0FEED=0xAA; PLL0FEED=0x55; VPBDIV=0x00; MAMCR = 0x00; // Any MAM function is disabled..i.e } void delay() { unsigned long int i; for(i=0;i<250000;i++); } // with 12MHZ clock supply the time delay is cmng as 1sec if the delay value is 250000 but it should be 1000000 according to my calculation // in this void main(void) { unsigned long dword=0x00000000; unsigned char min_hand=0; init_clock(); PINSEL1 &= 0x00000000; // all the pins of port1 are selected as GPIO IODIR1 = 0x00FF0000; // the pin 16 to 23 are configuered as the o/p pins. IOCLR1 = 0xFFFFFFFF; while(1) { min_hand++; dword = dword>>16; dword++; dword = dword <<16; IOSET1 |= dword; // IOPIN1 = IOSET1; delay(); if(min_hand /60 == 0) { min_hand=0; delay(); } IOCLR1 = 0xFFFFFFFF; delay(); } }
Could you also confirm the PCLK of your Timer0?
void delay() { T0PR = 0x0000270F; T0MR0 = 0x000004B0 ; T0TCR = 0x01; // the timer0 is activated while(T0TC != T0MR0); T0MCR = 0x00000002; // Timer Counter will be in reset condition if the match between the MR0 and TC happens. T0TCR = 0x02; /* when the match happens the Timer0 is resetted and deactivated and it is again activated while the next delay is called */ }
This is incorrect! You need to re-write it.
or remove the line in red, and see what will happen.
Sorry. -> or remove the line in red, and see what will happen. <- It is my mistake.
It should be: remove the line of
T0MCR = 0x00000002;
and see what will happen.
External frequency->Fosc -> 12MHZ Processor clock->Fcclk -> 12Mhz VPB clock -> Pclk -> 12MHz
And one more thing if the line T0MCR = 0x00000002; is not there then TC will never be resetted until and unless it reaches the value 0xFFFFFFFF.But thats not at all required..so the line must be there...
I haven't had time to check through your individual configuration bits. But resetting the timer is something you do when running the timer continuously. You let the timer tick until it reaches the match, and then restart from zero again for the next cycle. But you are calling delay() as a one-off call so why bother about the timer resetting for a next delay cycle?
That was one of the things I discussed in my first post - that you try to do a 1s delay in your loop, instead of trying to synchronize your loop with a 1s timer. The two concepts may sound similar but one of them will result in 1s+delta repeat time for the loop, and one will result in 1s repeat time.
When using timers in polling mode, the timer is normally just compared with the planned stop value. Most people runs the timer free-running, where it uses the full 32-bit span and then restarts the next turn. Such a delay would then capture the timer value on entry to the delay. Then it would continuously poll the timer value and compute t1-t0 using unsigned integers. If the difference between the two values is >= the number of ticks to wait, then the delay function can return. Such code will not suffer from the timer counter wrapping as long as you don't try to have delays longer than the number size that fits in the counter. And such code can use the same timer for many different timing issues.
The normal use for the auto-reset is with an interrupt handler. Each time the timer counter gets reset, you let the timer create an interrupt. This interrupt may count uptimes or perform other quick things, but long before the interrupt handler ended (or even was entered) the timer would already be busy counting the next period.
Please replace your delay() with the below code, and give it a try.
void delay() { T0PR = 0x0000270F; // Prescale Register = 9999 T0MR0 = 0x000004B0; // Match Register = 1200 T0MCR = 0x00000004; // Stop on MR0: the TC and PC will be stopped // and TCR[0] will be set to 0 if MR0 matches the TC. T0TCR = 0x02; // Counter Reset T0TCR = 0x01; // Counter Enable while(T0TC != T0MR0); }
I am not good at explanation due to my limited English ability and technical ability. If my code works (please give it a try.), I will try to explain my perspective.
sir,plz dnt understand me as arrogant if i seem to..its my sheer luck that u all are trying to teach me something..a hearty thanks to u all for this.....i have incorporate the code snippet in my code..but it hasn't worked.After the output becomes 00000001,i.e., after the first LED blinks there is a gap of almost 30 secs until the TC value becomes 0x000004B0 after that the value of TC stabilises and the out put started changing in a random fashion and sometimes the TCR is shown as reset and sometimes its being enabled.This continues...
while(T0TC != T0MR0);
There are always problems with testing for exact match with fast-running timers.
If the timer is not auto-reset, then the T0TC match may be missed, in which case the timer continues the full 2^32 ticks before restarting and giving the program a second chance.
And if automatically reset to zero, then it can be hard to catch the maximum value before the reset.
It is normally best to let it free-run and look for either (if the timer is reset before the delay loop):
while (T0TC < timeout_value) ;
or have the timer constantly free-running and do:
unsigned t0,t1; ... t0 = T0TC; while (T0TC - t0 < timeout_value) ;
If really using the reset feature together with polling, then it is possible to mask the timer interrupt, but have the polling code look for the interrupt flag from the timer match. The reset bit can then be used to automatically start the next period delay, letting the next call to the delay function wait one second minus the time used in the main loop.
Hi kaushik ghosh,
Per Westermark is an intelligent expert, you should read his posts carefully, and consider what he said. He is very good at explanation.
Sorry for that I didn't provide useful help.
Did you test my code with the simulator?
If you test my code with the simulator, maybe you could give it a second chance, test it with the real hardware.
I have rewritten the delay code as told by per westermark...but with due respect to u sir...still my problem remains i.e., the delay is not produced as 1sec..but the 0x00000001 stays until the TC value become 0x000004B0 and then the output becomes random and the TCR once gets enabled and next time gets reset.At the same time the TC doesnt get resetted as it was in my previous code..but it continues counting the values post 0x000004B0.But whenever i changed it to my previous code all the effects remain same just the TC is resetted once it reach the value 0x000004B0.
My problem is not with the matching of the TC with the preset value in MR0..as that part is working fine..i.e., the matching is happening and can be tracked..though i have checked it in the simulator..I want to activate the timer block to count upto 1sec and then disable it.Next time the same function is to be repeated when the delay function is called..This is my expectation from the code.But this is not happening...
below are the delay code originally rewritten by me
and this is the code as suggested by per westermark
void delay() { unsigned long check_value = 0x000004B0; T0PR = 0x0000270F; // T0MR0 = 0x000004B0 ; T0TCR = 0x01; // the timer0 is activated while(T0TC <= check_value); T0MCR = 0x00000002; // Timer Counter will be in reset condition if the match between the MR0 and TC happens. T0TCR = 0x02; /* when the match happens the Timer0 is resetted and deactivated and it is again activated while the next delay is called */ }
@ John Linq
I have checked ur code already and have posted the result in my last post..Plz go through it..there by the term "code snippet" that i mention was actually ur delay sub-function...that i put into my code.and i have told there what was the result...
The below code has been tested on my LPC2368. And the LED blinks regularly with a 1 second interval.
#include "LPC23xx.h" void delay(void) { /* My PCLK of Timer0 is 18Mhz */ T0PR = 9999; // Prescale Register = 9999 T0MR0 = 900; // Match Register = 900 T0MCR = 0x00000004; // Stop on MR0: the TC and PC will be stopped // and TCR[0] will be set to 0 if MR0 matches the TC. T0TCR = 0x02; // Counter Reset T0TCR = 0x01; // Counter Enable while(T0TC != T0MR0); } int main(void) { FIO3DIR |= (1<<26); // 1 for Output while(1) { FIO3CLR = (1<<26); delay(); FIO3SET = (1<<26); delay(); } }
Thanks for ur help...As my Pclk is 12MHz i have used 1200 as the matched value in T0MR0 register.Else i have put ur code fully in mine,but the result is same as i previously explained here i.e, in short its not working.I have checked the result both in the simulator and in the hardware.
One more question if u have put 9999 in ur PR that means the TC will increase after every 10000 clk cycles..in that case if ur Pclk is 18MHz the value at which the TC register should match with the MR0 register, for 1sec delay, should be 1800...not 900.So how are you getting a 1sec delay..plz clarify this point.
Turn on the LED for 0.5 sec. Turn off the LED for 0.5 sec. Totally 1.0 sec.
Ok I understand,So why doesnt ur code run on my code.whats the problem with it????