This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Dear sir,
I am Using __delay_cycles(); function in my code, I have some questions on it.
1.How __delay_cycles(10000) works internally, And which clock source will select ?
2.The value (10000) is in terms of what ?
3.How to calculate this delay value, means time period ?
Here is the code :
#include <msp430g2231.h>
void main (void)
{
WDTCTL = WDTPW + WDTHOLD ;
for(;;)
{
P1DIR |= BIT0+BIT6;
P1OUT ^= BIT0;
__delay_cycles(10000);
{
P1OUT ^=BIT6;
__delay_cycles(20000);
}
}
}
If any mistakes Sorry.
Thank You.
delay_cycles(x) is stopping in the code and waiting for x MCLK cycles.
So for example if you are working at 1 MHz in your code
delay_cycles(1000) will halt the code for 1000 * 1/1MHz
its ok for testing to use delay_cycles but in a real programm you shouldnt use it, since it really stops the whole programm for that time, if you are relying on Interrupts and some time-critical code delay_cycles will probably mess your code up.
By the way, which Timer does this function use ?
Its a good thing to keep track of it, especially when you are using TIMERs in your application.
Not exactly.seb said:delay_cycles(x) is stopping in the code and waiting for x MCLK cycles.
This intrinsic instructs the compiler to generate some code that will take exactly the given number of MCLK cycles to execute.
AFAIK, it does NOT disable interrupts during execution. It just wastes CPU cycles. So any interrupts will extend the delay by their own execution time.
This won't happen if the delay is done by the timer: any interrupt happening during (but not at the end of) the delay will not extend a timer-based delay.
Dear Sir,
Your information was right with calculation(Number of count*1/Selected Frequency), But i made one experiment on __delay_cycle();, I had given number of count value 1, with the calculation it should give 1us delay but it is giving 6.60us delay i checked this with Oscilloscope. for information i have attached code and two images here.
How to know the Default frequency is 1MHz with MCLK, Can we able to check the MCLK frequency with inserting any code or functions ?
#include <msp430g2553.h>
void main (void)
{
WDTCTL = WDTPW + WDTHOLD ;
P1DIR |= BIT0;
for(;;)
{
P1OUT ^= BIT0;
__delay_cycles(1);
}
}
With __delay_cycles(1);
With __delay_cycles(10);
If any mistakes sorry.
Thank you.
how do you set your MCLK to 1 MHz, could you post the clock module code in here?
Are you using an external Oscillator like a quarz, or is the internal DCO?
Thanks for your Oscilloscope shots anyway, but if you dont know what MCLK you are working with how can you ever know how long 1 delay cycle is?
I dont know if your MSP430 has it but some bigger MSP430 ( bigger = more pins like 80 ) have a MCLK pin, on which the actual MCLK clock can be measured, so perhaps yours has one too.
Mallappa T said:for(;;)
{
P1OUT ^= BIT0;
__delay_cycles(1);
}
You can't measure exact delay_cycles time using such approach because for(;;) cycle handling and also port I/O consume CPU cycles so definitely results will be more than 1us high or low time. Also you don't use DCO calibration constants, most probably your clock is not 1MHz but somewhere in 800..1000 kHz range.
First improvement would be like this:
for(;;)
{
P1OUT |= BIT0;
__delay_cycles(1000);
P1OUT &= ~BIT0;
}
Even then you shall calculate cycles for port I/O and compensate for it.
The scope shows the total execution time for the loop.Mallappa T said:I had given number of count value 1, with the calculation it should give 1us delay but it is giving 6.60us delay i checked this with Oscilloscope.
It includes 1 MCLK cycle for the delay, but also 4 MCLK cycles for the pin toggle and 2 cycles for the jump to the loop start. 7 cycles in total.
Test it without any delay, you'll get ~5.7µs then :)
You MCLK frequency is apparently 1.05MHz. Which is pretty much the average default speed on 2x family.
Mallappa T said:How __delay_cycles(10000) works internally ?
The debugger disassembly window will show you.
Peter
For those interested here's the assembly code for __delay_cycles(100):
; Begin 100 cycle delay
PUSHM.A #1, r13
MOV.W #30, r13
$1: SUB.W #1, r13
JNE $1
POPM.A #1, r13
; End 100 cycle delay ;
Hi guys
Happy holidays
I am using delay_cycles inside a loop, like this
// This function will give us 1ms wait time, so for getting 10 ms, // then delay_ms(10) will give 10ms and delay_ms(100) will give 100ms void delay_ms(unsigned int ms) { unsigned int i; for (i = 0; i<= ms; i++) __delay_cycles(6000); // 6000 will give us 1ms //(1/6MHz)*X=1ms MCLK= 6MHz (MCLK is the source for delay cycles) //X=6000....this gives 1 ms }
However, I am not getting the right no. for example, if I use
delay_ms(10)+ delay_ms(10)+ delay_ms(40)
i.e. I am calling these inside my program, then I will not get 60 ms (I am checking this on the oscilloscope), but I will get 99 ms instead.
And when using delay_ms(170) (170 ms in total, as I am calling delay_ms multiple times) then I get 190 ms!
Would you please advice me what is wrong?
I am setting the MCLK to DCO/ 2. DCO is 12 MHZ calibrated.
Thank you
Won't that for loop perform the __delay_cycles one more iteration than required?Murtadha A said:for (i = 0; i<= ms; i++) __delay_cycles(6000); // 6000 will give us 1ms
I.e. should the loop be:
for (i = 0; i< ms; i++) __delay_cycles(6000); // 6000 will give us 1ms
Yes you are right and I corrected it, but this will not make a big change as its 1 ms only
Which device are you using?Murtadha A said:Yes you are right and I corrected it, but this will not make a big change as its 1 ms only
E.g. if you are using a FRAM based device and running code from FRAM their might be extra wait-states, based upon the CPU frequency, which is causing the delay to be larger than expected.
Correct, using a MSP430G2553 and therefore no FRAM and no wait states.Murtadha A said:I am using MSP430G2553, so FRAM is not applicable is I am not wrong!
Some other comments:
a) Are there any interrupts running during the delay loop, as interrupts will increase the delay?
b) Have you checked the DCO is set to the expected frequency, e.g. by outputting SMCLK on P1.4?
Software delay loops will not be accurate and waste mcu cycles.
The two timers in a G2553 have CCR1 and CCR2 that you can set to toggle a pin in hardware, with CCR0 value being the freq
So give up on __delay and learn msp-counters today.
If you only have one task, using WDT as a timer probably easiest (though you loose out on having the safe guard of a WDT)
Set a var for how many numbers of WTD IRQ triggers you should sleep, enable WDT IRQ, go to sleep (set-lpmbits)
WDT_ISR subtracts the counter var, when reached zero, disable its own IRQ, clear-lpmbits-on-exit.
As to save power the WDT should run from a 32K crystal so you can go in to lpm3.
It gets a little harder when you have few task wanting to sleep a some random lengths.
You would need a event-machine that jumps to state-machines.
If you have 3 task, they each could use CCRx in a free running timmerA, saves you from sorting sleep intervals and making a smart task scheduler.
TimerA should use a aclk/div8/div4 to save power and will give you 1ms to 64sec delay options, the CCRx ISR should just set as event flag and do a clear-lpmbits-on-exit
Grabbing current freerunning TA0 value have to done twice and cmp as it comes from a different clock domain if you use aclk.
**Attention** This is a public forum