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. |