| 63 |
Some of the more important parts of the code are: |
Some of the more important parts of the code are: |
| 64 |
|
|
| 65 |
\par Note [1]: |
\par Note [1]: |
| 66 |
|
As the AVR microcontroller series has been developed during the past |
| 67 |
|
years, new features have been added over time. Even though the basic |
| 68 |
|
concepts of the timer/counter1 are still the same as they used to be |
| 69 |
|
back in early 2001 when this simple demo was written initially, the |
| 70 |
|
names of registers and bits have been changed slightly to reflect the |
| 71 |
|
new features. Also, the port and pin mapping of the output compare |
| 72 |
|
match 1A (or 1 for older devices) pin which is used to control the LED |
| 73 |
|
varies between different AVRs. The file <tt>iocompat.h</tt> tries to |
| 74 |
|
abstract between all this differences using some preprocessor \c #ifdef |
| 75 |
|
statements, so the actual program itself can operate on a common set of |
| 76 |
|
symbolic names. |
| 77 |
|
|
| 78 |
|
\par Note [2]: |
| 79 |
The \c PWM is being used in 10-bit mode, so we need a 16-bit variable to |
The \c PWM is being used in 10-bit mode, so we need a 16-bit variable to |
| 80 |
remember the current value. |
remember the current value. |
| 81 |
|
|
| 82 |
\par Note [2]: |
\par Note [3]: |
| 83 |
ISR() is a macro that marks the function as an interrupt routine. In this |
ISR() is a macro that marks the function as an interrupt routine. In this |
| 84 |
case, the function will get called when the timer overflows. Setting up |
case, the function will get called when timer 1 overflows. Setting up |
| 85 |
interrupts is explained in greater detail in \ref avr_interrupts. |
interrupts is explained in greater detail in \ref avr_interrupts. |
| 86 |
|
|
| 87 |
\par Note [3]: |
\par Note [4]: |
| 88 |
This section determines the new value of the \c PWM. |
This section determines the new value of the \c PWM. |
| 89 |
|
|
| 90 |
\par Note [4]: |
\par Note [5]: |
| 91 |
Here's where the newly computed value is loaded into the \c PWM register. |
Here's where the newly computed value is loaded into the \c PWM register. |
| 92 |
Since we are in an interrupt routine, it is safe to use a 16-bit assignment |
Since we are in an interrupt routine, it is safe to use a 16-bit assignment |
| 93 |
to the register. Outside of an interrupt, the assignment should only be |
to the register. Outside of an interrupt, the assignment should only be |
| 95 |
routine could also access this register (or another register that uses |
routine could also access this register (or another register that uses |
| 96 |
\c TEMP), see the appropriate \ref faq_16bitio "FAQ entry". |
\c TEMP), see the appropriate \ref faq_16bitio "FAQ entry". |
| 97 |
|
|
| 98 |
\par Note [5]: |
\par Note [6]: |
| 99 |
This routine gets called after a reset. It initializes the \c PWM and enables |
This routine gets called after a reset. It initializes the \c PWM and enables |
| 100 |
interrupts. |
interrupts. |
| 101 |
|
|
| 102 |
\par Note [6]: |
\par Note [7]: |
| 103 |
The main loop of the program does nothing -- all the work is done by the |
The main loop of the program does nothing -- all the work is done by the |
| 104 |
interrupt routine! If this was a real product, we'd probably put a \c SLEEP |
interrupt routine! The <tt>sleep_mode()</tt> puts the processor on sleep |
| 105 |
instruction in this loop to conserve power. |
until the next interrupt, to conserve power. Of course, that probably |
| 106 |
|
won't be noticable as we are still driving a LED, it is merely mentioned |
| 107 |
|
here to demonstrate the basic principle. |
| 108 |
|
|
| 109 |
\par Note [7]: |
\par Note [8]: |
| 110 |
Early AVR devices saturate their outputs at rather low currents when |
Early AVR devices saturate their outputs at rather low currents when |
| 111 |
sourcing current, so the LED can be connected directly, the resulting |
sourcing current, so the LED can be connected directly, the resulting |
| 112 |
current through the LED will be about 15 mA. For modern parts (at |
current through the LED will be about 15 mA. For modern parts (at |
| 133 |
building of the project into several compiles and one link. |
building of the project into several compiles and one link. |
| 134 |
|
|
| 135 |
\verbatim |
\verbatim |
| 136 |
$ avr-gcc -g -Os -mmcu=at90s2333 -c demo.c |
$ avr-gcc -g -Os -mmcu=atmega8 -c demo.c |
| 137 |
\endverbatim |
\endverbatim |
| 138 |
|
|
| 139 |
The compilation will create a \c demo.o file. Next we link it into a binary |
The compilation will create a \c demo.o file. Next we link it into a binary |
| 140 |
called \c demo.elf. |
called \c demo.elf. |
| 141 |
|
|
| 142 |
\verbatim |
\verbatim |
| 143 |
$ avr-gcc -g -mmcu=at90s2333 -o demo.elf demo.o |
$ avr-gcc -g -mmcu=atmega8 -o demo.elf demo.o |
| 144 |
\endverbatim |
\endverbatim |
| 145 |
|
|
| 146 |
It is important to specify the MCU type when linking. The compiler uses the \c |
It is important to specify the MCU type when linking. The compiler uses the \c |
| 191 |
which is shown below). |
which is shown below). |
| 192 |
|
|
| 193 |
\verbatim |
\verbatim |
| 194 |
$ avr-gcc -g -mmcu=at90s2313 -Wl,-Map,demo.map -o demo.elf demo.o |
$ avr-gcc -g -mmcu=atmega8 -Wl,-Map,demo.map -o demo.elf demo.o |
| 195 |
\endverbatim |
\endverbatim |
| 196 |
|
|
| 197 |
\dontinclude demo.map |
\dontinclude demo.map |
| 207 |
\skipline *(.fini2) |
\skipline *(.fini2) |
| 208 |
\until __eeprom_end |
\until __eeprom_end |
| 209 |
|
|
| 210 |
The last address in the \c .text segment is location \c 0xf2 ( denoted by \c |
The last address in the \c .text segment is location \c 0x114 ( denoted by \c |
| 211 |
_etext ), so the instructions use up 242 bytes of FLASH. |
_etext ), so the instructions use up 276 bytes of FLASH. |
| 212 |
|
|
| 213 |
The \c .data segment (where initialized static variables are stored) starts |
The \c .data segment (where initialized static variables are stored) starts |
| 214 |
at location \c 0x60, which is the first address after the register bank on a |
at location \c 0x60, which is the first address after the register bank on an |
| 215 |
2313 processor. |
ATmega8 processor. |
| 216 |
|
|
| 217 |
The next available address in the \c .data segment is also location \c 0x60, |
The next available address in the \c .data segment is also location \c 0x60, |
| 218 |
so the application has no initialized data. |
so the application has no initialized data. |