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.

Unable to understand a part of code for ARM

Status
Not open for further replies.

garvind25

Full Member level 3
Joined
Oct 28, 2012
Messages
176
Helped
0
Reputation
0
Reaction score
1
Trophy points
1,298
Activity points
3,066
Hi there,

I was going through Mazidi's STM32 book and came across this code:

Code:
#include "stm32fxx.h"

void delayMs(int n);

int main(void){

 RCC -> AHB1ENR |= 1; 
 GPIOA -> MODER &= ~0x00000C00;
 GPIOA -> MODER |= 0x00000400; 
 
 while(1) {
 
  GPIO -> ODR |= 0X00000020;
  delayMs(500);
  GPIO -> ODR &= ~0X00000020;
  delayMs(500);  
  }
}

[B]void delayMs(int n) {

 int i;
 for(; n>0; n--)
  for (i=0; i<3195; i++);[/B]

}

This is basically a code to blink an LED with .5 sec on /off period. The code in bold letters seems to be a clock generator. Depending on the value passed to delayMs routine by the main program (here it is 500) the clock pulse gets generated. in this case, it seems to generate a on/off pulse of 1 sec time period with 50 % duty cycle.

I am unable to understand how this clock pulse generation code works. How has the upper limit of i (3195) been calculated? As per the other examples in the book, the same code is used to generate a clock pulse of 8ms etc (by passing n=8 to delayMs from main program).

Also is there any simpler way to generate a generic clock pulse signal of required on/off time duration?

Looking forward to any answers.

Thanks and Regards,
Arvind Gupta
 

Hi,

This is a dirty solution of a busy ms delay.

Dirty, because it works only with the given processor (archetecture) and a known processor_clock_frequency.

The inner loop runs 3159 times (0 ...3194), every loop needs a known count of clock cycles.
And (3159 x clock_cycles_per_loop) / clock frequency = run time = 1ms.

Use the same function on a different processir or with different clock frequency, then you don't get 1ms anymore.

Do you know the game "packman"? It suffered from exactly this problem.

Klaus
 
OK thanks. So can you suggest a general way of generating a 1 sec clock with 05 sec on/off time ?

Regards,
Arvind Gupta
 

Hi,

I prefer a timer solution, mainly because of absolute accuracy and because of the low (no) processing power.
But to make it independent of processor and clock frequency it needs some software and a RTC or any other absolute reference.

Klaus
 

One of the great dangers of using a delay timer such as the one in Post #1 is that any compiler optimisation can result in no delay at all.
The compiler sees a code line such as:
Code:
for (i=0; i<3195; i++);
and sees that nothing changes except for the value of 'i'. Therefore, the functionally equivalent code is:
Code:
i = 0;
i = 3195;
Again, any smart compiler will remove the first instruction as it has no effect beyond this code block.
It then applies the same logic to the outer 'for' loop and therefore can replace the whole function with:
Code:
return;
and still generate functionally equivalent code. While it does not do what you want, it does do exactly what you have told the compiler to do.
If the compiler generates code that is long enough for the CPU to spend any time in there at all (such as adding a 'nop' to the inner loop and altering the 'magic numbers') then the delay will be extended if any interrupts are processed while in the function.
Use of timers (as mentioned above) is by far the best way if you want repeatable, stable delays.
Susan
 

OK. Thanks for the replies. I could not come back to the post as I was away from home. Anyways, since I am beginning to write C codes for ARM MCUs, can I ask anyone to provide or point me to a simple code to blink an LED using the internal clock (maybe 16 MHz) of the MCU/ using an external crystal? This will serve me as a template to try out other codes. I am planning to use STM32 F446 MCUs.

Regards,
Arvind Gupta.
 

How you go about this also depends on what support tools you want (or have) to use.
If you use the STM32CubeMX tool, it will generate the bulk of the code for you and all you need to do (in this case) is to add in the code to the main 'while' look to toggle the GPIO pin and call a delay function. There are many examples on the Internet as to how to do this.
In my experience, one of the harder parts of writing code for ARM processors (at least a the beginning of the learning curve) is how to set everything up - RCC, GPIOs etc.. There are books and examples on the Internet that will show you what needs to be done. I've found "Mastering STM32" by Carmine Noviello to be useful (although there are a couple of mistakes in the version I looked at - I hope they have been corrected in later editions). I'm sure there are many other books and tutorials out there.
Susan
 

OK thanks. I was planning to use Proteus and one of the STM32F0 MCUs supported by it. I can draw the actual schematic on this software and see the program toggle the LED on the schematic. Hence I suppose I will have to write the entire code (and not only a small part as compared to STMCube MX tool - the advantage here would that I dont have to get myself a development board). Writing a full code involves setting the RCC and GPIOs through various steps. That's why it is tedious for a beginner like me and I needed someone to point to an code to start of with. Hope someone will understand.

Arvind Gupta.
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top