Editing Embedded Programming Tips and Tricks

Jump to: navigation, search

Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.
Latest revision Your text
Line 1: Line 1:
=Fast Division=
+
===Fast Division===
 
On microcontrollers without a divide instruction very fast division can be done by bit shifting a variable right.<br>
 
On microcontrollers without a divide instruction very fast division can be done by bit shifting a variable right.<br>
 
Each shift does a divide by two.<br>
 
Each shift does a divide by two.<br>
  
 
For example<br>
 
For example<br>
   ''Y = Y >> 1; (Will result in a divide by 2)<br>''
+
   ''Y = Y >> 1  Will result in a divide by 2<br>''
 
or<br>
 
or<br>
   ''X = X >> 4; (Will result in a divide by 16)<br>''
+
   ''X = X >> 4  Will result in a divide by 16<br>''
  
By adding a multiplication you can achieve a limited number of other divisions.<br>
+
By adding a multiplication you can achieve other, more complex, divisions.<br>
  
 
For example<br>
 
For example<br>
Line 18: Line 18:
 
Be sure to do the multiply first, otherwise bits will be lost.<br>
 
Be sure to do the multiply first, otherwise bits will be lost.<br>
 
Also be sure the variable size is large enough to store the multiplied value.<br>
 
Also be sure the variable size is large enough to store the multiplied value.<br>
 
=Repeating Code Using Interrupts=
 
 
When writing embedded code you will quite often need to trigger code at a regular interval. (for example flashing an led)<br>
 
Over your entire project there maybe many different code segments you wish to execute at different rates.
 
To do this it can be useful to dedicate one of the microcontrollers hardware timers to perform all these timing tasks.
 
 
Since it's bad practice to put lots of code inside an interrupt handler the best approach is to just set flags and then test these flags inside your main program loop.
 
 
 
Such a system might look like this
 
 
===AVR===
 
<pre>
 
 
#define off 0
 
#define on 1
 
 
volatile uint16_t clk1000ms=1; // initializing them to 1 insures there is an initial delay cycle when
 
volatile uint16_t clk100ms=1;  // the code first starts, otherwise they would all happen at
 
volatile uint8_t clk10ms=1;    // once during first run.
 
 
ISR (TIMER0_OVF_vect)
 
{
 
if (clk1000ms!=off)
 
{
 
clk1000ms++;
 
if (clk1000ms>=10001) clk1000ms=off;
 
}
 
if (clk100ms!=off)
 
{
 
clk100ms++;
 
if (clk100ms>=1001) clk100ms=off;
 
}
 
if (clk10ms!=off)
 
{
 
clk10ms++;
 
if (clk10ms>=101) clk10ms=off;
 
}
 
// Timer clock is 1mhz, timer is 8bit.
 
// Now we set the timer register to 156 so it takes 100 timer clocks to overflow.
 
// This will mean the interrupt code executes at 1mhz/100 = 10000Hz
 
TCNT0 = 156;
 
}
 
 
void main(void)
 
{
 
 
if (clk1000ms==off)
 
{
 
// put code here to run every second
 
 
clk1000ms = on;
 
}
 
if (clk100ms==off)
 
{
 
// put code here to run 10 times a second
 
 
clk100ms = on;
 
}
 
if (clk10ms==off)
 
{
 
// put code here to run 100 times a second
 
 
clk10ms = on;
 
}
 
 
}
 
</pre>
 

Please note that all contributions to EEVblog Electronics Resource Wiki may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see EEVblog Electronics Resource Wiki:Copyrights for details). Do not submit copyrighted work without permission!

To edit this page, please solve the following task below and enter the answer in the box (more info):

Cancel | Editing help (opens in new window)