AVR Embedded Tutorial - Entry Lazarus and Arduino: what changed
Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.
Title: AVR Embedded Tutorial - Entry Lazarus and Arduino
| Old | New | Line | |
|---|---|---|---|
| 1 | + | ## Build Lazarus with AVR crosscompiler for Arduino Nano/Uno | |
| 2 | + | ||
| 3 | + | [](</File:lazarus-avr.png> "mini") | |
| 4 | + | ||
| 5 | + | The tutorial was tested with: | |
| 6 | + | ||
| 7 | + | * Linux Mint 18.2 64bit | |
| 8 | + | * Arduino IDE 1.8.5 | |
| 9 | + | * FPCUPdeluxe V1.6.6e (Should always be the newest!) | |
| 10 | + | * svn 1.9.3 | |
| 11 | + | * FPC 3.1.1 (created with FPCUPdeluxe) | |
| 12 | + | * Lazarus 1.9 (created with FPCUPdeluxe) | |
| 13 | + | ||
| 14 | + | The same tools are required under Windows , except the Linux Mint . | |
| 15 | + | ||
| 16 | + | ## Tools required | |
| 17 | + | ||
| 18 | + | ### Software | |
| 19 | + | ||
| 20 | + | FPCUPdeluxe: | |
| 21 | + | ||
| 22 | + | * <https://github.com/newpascal/fpcupdeluxe/releases> \- fpcupdeluxe for creating the AVR cross compiler. (Download: fpcupdeluxe- [OS]). | |
| 23 | + | ||
| 24 | + | Arduino software: | |
| 25 | + | ||
| 26 | + | * <https://www.arduino.cc/en/Main/Software> \- Arduino software. Used for avrdude. | |
| 27 | + | ||
| 28 | + | Subversion: | |
| 29 | + | ||
| 30 | + | * Ubuntu / Debian: | |
| 31 | + | ||
| 32 | + | ``` | |
| 33 | + | sudo apt-get install subversion | |
| 34 | + | ``` | |
| 35 | + | ||
| 36 | + | * SuSE: | |
| 37 | + | ||
| 38 | + | ``` | |
| 39 | + | sudo zypper install subversion | |
| 40 | + | ``` | |
| 41 | + | ||
| 42 | + | * Windows: | |
| 43 | + | ||
| 44 | + | Should be installed automatically by FPCUPdeluxe, otherwise download and install from [here](<https://sourceforge.net/projects/win32svn/?source=typ_redirect>). | |
| 45 | + | ||
| 46 | + | ### Hardware | |
| 47 | + | ||
| 48 | + | * Arduino Uno or Nano, preferably with an ATmega328p. | |
| 49 | + | ||
| 50 | + | ## Install FPCUPdeluxe | |
| 51 | + | ||
| 52 | + | It is best to copy the download of FPCUPdeluxe into a new empty folder and then start the copied file in the file manager with a double click. Linux asks if the file should be made executable, answer yes. The FPCUPdeluxe GUI should then start. | |
| 53 | + | ||
| 54 | + | ## Build Lazarus with FPCUPdeluxe | |
| 55 | + | ||
| 56 | + | ### Build trunk | |
| 57 | + | ||
| 58 | + | * Set the top left list boxes **FPC version** and **Lazarus version** to **trunk** or **embedded** which are both in the **Basic tab**. | |
| 59 | + | * Build the Lazarus base trunk/embedded version with `Install/update FPC+Laz`. | |
| 60 | + | ||
| 61 | + | If everything goes through without errors you get the current trunk from FPC and Lazarus. Normal desktop applications can now be created with this. There should be an icon for Lazarus_fpcupdeluxe on the Desktop. | |
| 62 | + | ||
| 63 | + |  **Note:** Note: SVN repositories may experience difficulties. If so, don't give up, just try again later ;-) What also helps, run FPCUPdeluxe twice in a row. A non-current FPCUPdeluxe can also cause difficulties. If something doesn't work, you can ask in the [Lazarus forum](<https://forum.lazarus.freepascal.org/index.php/topic,34645.0.html>), the author is very helpful. | |
| 64 | + | ||
| 65 | + | ### Build AVR Cross compiler | |
| 66 | + | ||
| 67 | + | Press the `Setup+` button in the **Cross tab** to open a dialog with further options. Set the following there: | |
| 68 | + | ||
| 69 | + | * CPU: avr | |
| 70 | + | * OS: embedded | |
| 71 | + | * Cross Build Options Overide: -Cpavr5 | |
| 72 | + | * Cross SubArch Overide: avr5 | |
| 73 | + | * Close dialog with Ok | |
| 74 | + | ||
| 75 | + | Select the following check boxes in the **Cross tab** : | |
| 76 | + | ||
| 77 | + | * CPU: avr | |
| 78 | + | * OS: embedded | |
| 79 | + | ||
| 80 | + | Press the `Install compiler` button and the cross compiler will be built. If everything went correctly, you can exit from FPCUPdeluxe. | |
| 81 | + | ||
| 82 | + | ## Install drivers | |
| 83 | + | ||
| 84 | + | ### Windows | |
| 85 | + | ||
| 86 | + | * For original Arduinos, the drivers are supplied with the Arduino IDE. | |
| 87 | + | * For clones it may be necessary to install drivers. Mostly this is the 340-341 driver. From Windows 10, these drivers are also included with the operating system. | |
| 88 | + | ||
| 89 | + | ### Linux | |
| 90 | + | ||
| 91 | + | * With current Linux, eg Mint/Ubuntu/Debian the drivers are already installed. (SusE: someone would need to test.) | |
| 92 | + | ||
| 93 | + | Most of the time, the COM ports (USB-UART) have to be accessible by users. This is done with the following command: | |
| 94 | + | ``` | |
| 95 | + | sudo adduser $USER dialout | |
| 96 | + | ``` | |
| 97 | + | ||
| 98 | + | ## Prepare Lazarus | |
| 99 | + | ||
| 100 | + | ### Start with `F9` | |
| 101 | + | ||
| 102 | + | If you try to start with `F9`, you always get an error message. You can prevent this. Change the following in Lazarus: | |
| 103 | + | ||
| 104 | + | * "Tools -> Settings ... -> Keyboard layout -> Commands from the menu 'Start' -> Start program", set to Unknown . | |
| 105 | + | * "Tools -> Settings ... -> Keyboard layout -> Commands from the menu 'Start' -> Start without debugger", remove the ticks from Shift and Ctrl. | |
| 106 | + | ||
| 107 | + | So you can upload and start normally with `F9`. | |
| 108 | + | ||
| 109 | + | But you have to consider that the debugger is also disabled if you then write a normal PC program with Lazarus! | |
| 110 | + | ||
| 111 | + | ### Code tools | |
| 112 | + | ||
| 113 | + | It is possible that the code tools cannot find the Atmega328p unit. If this happens, then the following step is necessary: | |
| 114 | + | ||
| 115 | + | * "Tools -> Reread FPC source code directory" | |
| 116 | + | ||
| 117 | + | ### Readable ASM code creation | |
| 118 | + | ||
| 119 | + | If you want to see the source as assembler code, the following step is necessary: | |
| 120 | + | ||
| 121 | + | * Enter "Project -> Project Settings ... -> User-defined settings -> User-defined settings" -al , this creates an *.s file that contains the program as ASM code. | |
| 122 | + | ||
| 123 | + | ### Faulty optimization | |
| 124 | + | ||
| 125 | + | I have experienced a program not working properly because the compiler incorrectly optimised the code. So you should switch off code optimization with {$ O-} at the beginning of the program. | |
| 126 | + | ||
| 127 | + | ## First project | |
| 128 | + | ||
| 129 | + | ### Create a new project | |
| 130 | + | ||
| 131 | + | * "File -> New ... -> Simple Program" - create a new project. | |
| 132 | + | * "Project -> Project Settings ... -> Configuration and Goals" - set the following: | |
| 133 | + | * Target operating system (-T): Embedded | |
| 134 | + | * Target CPU family (-P): avr | |
| 135 | + | * Target processor (-Cp): AVR5 | |
| 136 | + | * "Project -> Project Settings ... -> Debug" : Remove the check mark "Generate debugger information for GDB" . | |
| 137 | + | * "Project -> Project settings ... -> User-defined settings -> User-defined settings still enter -WpATMEGA328P . | |
| 138 | + | * "Project -> Project Settings ... -> Compiler Commands -> Execute After" | |
| 139 | + | * Remove the Compile and Recompile ticks. | |
| 140 | + | * Enter the following into the command: `/home/tux/Programme/arduino-1.8.5/hardware/tools/avr/bin/avrdude -C/home/tux/Programme/arduino-1.8.5/hardware/tools/avr/etc/avrdude.conf -v -patmega328p -carduino -P/dev/ttyUSB0 -b57600 -Uflash:w:Project1.hex:i ` | |
| 141 | + | * When using a [USB ISP-Programmer Stick for AVR](<https://www.diamex.de/dxshop/DIAMEX-USB-ISP-Programmer-Stick-fuer-AVR>) and installing AVRdude WITHOUT Arduino, the command above is recommended as follows: `/usr/bin/avrdude -cstk500v2 -pm16 -P/dev/ttyACM0 -b57600 -Uflash: w:$Path($(OutputFile))$NameOnly($(TargetFile)). hex` _ATTENTION - The µC used for the command above is an ATMega16_ | |
| 142 | + | * or see [[AVR Embedded Tutorial|Various programmers]]. | |
| 143 | + | ||
| 144 | + |  **Note:** Note: Arduino nanos have been in circulation with new bootloaders since the beginning of 2018. It may be enough to change this parameter: -b115200 | |
| 145 | + | ||
| 146 | + | More information in the [Arduino Forum](<https://forum.arduino.cc/index.php?topic=542414.0>). | |
| 147 | + | ||
| 148 | + |  **Note:** Note: The paths still have to be adapted to your own installation. | |
| 149 | + | ||
| 150 | + | Windows: It must be avrdude with ".exe", "avrdude" alone is not enough, even if it is with Arduino without .exe. | |
| 151 | + | ||
| 152 | + |  **Note:** Note: The Com-Port is called differently under Linux and Windows: | |
| 153 | + | ||
| 154 | + | * Linux: /dev/ttyUSBx or /dev/ttyACMx | |
| 155 | + | * Windows: COMx | |
| 156 | + | ||
| 157 | + | As a recommendation, I would take this project as a template and build all new projects on top of it. Setting the whole thing up for a new project each time is a bit tedious. | |
| 158 | + | ||
| 159 | + | ## Start project | |
| 160 | + | ||
| 161 | + | Nothing should now be standing in the way of your first blink program (source in the next section). Compile and upload the program with `F9`. If everything worked, the LED at pin 13 should flash about every second. | |
| 162 | + | ||
| 163 | + | ## Different sources for getting started | |
| 164 | + | ||
| 165 | + | ### Pin 13 blinker | |
| 166 | + | ``` | |
| 167 | + | program Project1; | |
| 168 | + | const | |
| 169 | + | BP5 = 5; // Pin 13 of the Arduino | |
| 170 | + | dl = 250000; // About 1/2 sec | |
| 171 | + | ||
| 172 | + | procedure delay(t : int32); | |
| 173 | + | var | |
| 174 | + | i : Int32; | |
| 175 | + | begin | |
| 176 | + | for i := 0 to t do begin | |
| 177 | + | asm | |
| 178 | + | nop; | |
| 179 | + | end; | |
| 180 | + | end; | |
| 181 | + | end; | |
| 182 | + | ||
| 183 | + | begin | |
| 184 | + | DDRB := DDRB or (1 shl BP5); // switch port to output | |
| 185 | + | repeat | |
| 186 | + | PORTB := PORTB or (1 shl BP5); // port to high | |
| 187 | + | delay(dl); // waiting | |
| 188 | + | ||
| 189 | + | PORTB := PORTB and not (1 shl BP5); // port on low | |
| 190 | + | delay(dl); // waiting | |
| 191 | + | until 1 = 2; // infinite loop | |
| 192 | + | end. | |
| 193 | + | ``` | |
| 194 | + | ||
| 195 | + | ### Serial input/output | |
| 196 | + | ||
| 197 | + | A terminal with the following settings is required for serial output: | |
| 198 | + | ||
| 199 | + | * Baud rate: 9600 | |
| 200 | + | * Bits: 8 | |
| 201 | + | * Stop bits: 1 | |
| 202 | + | * Parity: none | |
| 203 | + | ||
| 204 | + | ``` | |
| 205 | + | program Project1; | |
| 206 | + | const | |
| 207 | + | CPU_Clock = 16000000; // Arduino clock frequency, default 16MHz. | |
| 208 | + | Baud = 9600; // baud rate | |
| 209 | + | Divider = CPU_Clock div(16 * baud) - 1; | |
| 210 | + | ||
| 211 | + | procedure UARTInit; | |
| 212 | + | begin | |
| 213 | + | UBRR0 := divider ; | |
| 214 | + | ||
| 215 | + | UCSR0A := (0 shl U2X0); | |
| 216 | + | UCSR0B := (1 shl TXEN0) or (1 shl RXEN0); | |
| 217 | + | UCSR0C := (% 011 shl UCSZ0); | |
| 218 | + | end; | |
| 219 | + | ||
| 220 | + | procedure UARTSendChar(c : char); | |
| 221 | + | begin | |
| 222 | + | while UCSR0A and (1 shl UDRE0) = 0 do begin | |
| 223 | + | end; | |
| 224 | + | UDR0 := byte(c); | |
| 225 | + | end; | |
| 226 | + | ||
| 227 | + | function UARTReadChar : char; | |
| 228 | + | begin | |
| 229 | + | while UCSR0A and (1 shl RXC0) = 0 do begin | |
| 230 | + | end; | |
| 231 | + | Result := char(UDR0); | |
| 232 | + | end; | |
| 233 | + | ||
| 234 | + | procedure UARTSendString(s : ShortString); | |
| 235 | + | var | |
| 236 | + | i : integer; | |
| 237 | + | begin | |
| 238 | + | for i := 1 to length(s) do begin | |
| 239 | + | UARTSendChar(s[i]); | |
| 240 | + | end; | |
| 241 | + | end; | |
| 242 | + | ||
| 243 | + | begin | |
| 244 | + | UARTInit; | |
| 245 | + | repeat | |
| 246 | + | if UARTReadChar = #32 then begin | |
| 247 | + | UARTSendString('Hello World!'#13#10); | |
| 248 | + | end; | |
| 249 | + | until 1 = 2; | |
| 250 | + | end. | |
| 251 | + | ``` | |
| 252 | + | ||
| 253 | + | ||
| 254 | + | ||
| 255 | + | ### Simple timer interrupt | |
| 256 | + | ||
| 257 | + | Pin 13 is switched to HIGH every second. | |
| 258 | + | ``` | |
| 259 | + | program Project1; | |
| 260 | + | const | |
| 261 | + | BP5 = 5; // Pin 13 of the Arduino | |
| 262 | + | ||
| 263 | + | procedure sei; assembler; | |
| 264 | + | asm | |
| 265 | + | Sei | |
| 266 | + | end; | |
| 267 | + | ||
| 268 | + | procedure Timer2_Interrupt; alias : 'TIMER2_OVF_ISR'; interrupt; public; | |
| 269 | + | const | |
| 270 | + | counter : integer = 0; | |
| 271 | + | cl = 16000000 div 1024 div 256 div 2; // 16'000'000Hz / Clock / TCNT / 2 = 0.5sec | |
| 272 | + | begin | |
| 273 | + | Inc(counter); | |
| 274 | + | if count = cl then begin | |
| 275 | + | PORTB := PORTB or (1 shl BP5); | |
| 276 | + | end; | |
| 277 | + | if count > = cl * 2 then begin | |
| 278 | + | PORTB := PORTB and not (1 shl BP5); | |
| 279 | + | count := 0; | |
| 280 | + | end; | |
| 281 | + | end; | |
| 282 | + | ||
| 283 | + | begin | |
| 284 | + | DDRB := DDRB or (1 shl BP5) ; // Pin 13 output | |
| 285 | + | ||
| 286 | + | TCCR2A := %00; // Normal timer | |
| 287 | + | TCCR2B := % 111; // clock / 1024 | |
| 288 | + | TIMSK2 := (1 shl TOIE2); // enable timer2 overflow interrupt | |
| 289 | + | sei(); // turn on interrupts | |
| 290 | + | ||
| 291 | + | repeat | |
| 292 | + | // do something | |
| 293 | + | until 1 = 2; | |
| 294 | + | end. | |
| 295 | + | ``` | |
| 296 | + | ||
| 297 | + | ## Reinstalling the OS | |
| 298 | + | ||
| 299 | + | * Linux: If you reinstall the OS, it is not enough to back up the cross-compiler. Remedy: Run FPCUdeluxe again. | |
| 300 | + | * Windows: Unknown. | |
| 301 | + | ||
| 302 | + | ## Conclusion | |
| 303 | + | ||
| 304 | + | For those who have already programmed with the Arduino IDE, they will have certainly found that there are a lot of ready-made libraries. You can code something very easily and quickly, but there is a lot hidden there. | |
| 305 | + | ||
| 306 | + | With Lazarus, you have to do everything yourself and thus deal with the registers of the AVR microcontroller. But this also has a big advantage, you know what you are doing. You can also generate more optimized code in this way. | |
| 307 | + | ||
| 308 | + | Thank you | |
| 309 | + | ||
| 310 | + | The most important thing at the end: | |
| 311 | + | ||
| 312 | + | * A big thank you to the developer of FPCUPdeluxe! | |
| 313 | + | ||
| 314 | + | * Without this ingenious tool, AVR with Lazarus would still be a forceps delivery! | |
| 315 | + | ||
| 316 | + | ## See also | |
| 317 | + | ||
| 318 | + | * [[AVR Embedded Tutorial|AVR Embedded Tutorials]] \- Overview | |
| 319 | + | ||
| 320 | + | --- | |
| 321 | + | *From the Free Pascal wiki, page "AVR Embedded Tutorial - Entry Lazarus and Arduino", as the Internet Archive kept it on 2024-09-14, last changed on 2020-12-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).* |
