<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://www.mikrocontroller.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mthomas</id>
	<title>Mikrocontroller.net - Benutzerbeiträge [de]</title>
	<link rel="self" type="application/atom+xml" href="https://www.mikrocontroller.net/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mthomas"/>
	<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/articles/Spezial:Beitr%C3%A4ge/Mthomas"/>
	<updated>2026-04-27T17:44:41Z</updated>
	<subtitle>Benutzerbeiträge</subtitle>
	<generator>MediaWiki 1.39.7</generator>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=ARM-ASM-Tutorial&amp;diff=101200</id>
		<title>ARM-ASM-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=ARM-ASM-Tutorial&amp;diff=101200"/>
		<updated>2019-10-10T19:06:22Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* Data processing */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Kategorie:ARM]][[Kategorie:STM32]][[Kategorie:Entwicklungstools]][[Kategorie:Programmiersprachen]]The [[ARM]] processor architecture is widely used in all kinds of industrial applications and also a significant number of hobby and maker projects. This tutorial aims to teach the fundamentals of programming ARM processors in assembly language.&lt;br /&gt;
&lt;br /&gt;
Tutorial by [[Benutzer:Erlkoenig|Niklas Gürtler]]. [https://www.mikrocontroller.net/topic/482409 Thread in Forum] for feedback and questions.&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
=== Why assembly? ===&lt;br /&gt;
Today, there is actually little reason to use assembly language for entire projects, because high-quality optimizing compilers for high-level languages (especially C and C++) are readily available as free open source software and because the ARM architecture is specifically optimized for high-level languages. However, knowledge in assembly is still useful for debugging certain problems, writing low-level software such as bootloaders and operating system kernels, and reverse engineering software for which no source code is available. Occasionally it is necessary to manually optimize some performance-critical code section. Sometimes claims are made that ARM processors can’t be programmed in assembly. Therefore, this tutorial will show that this is very well possible by showing how to write entire (small) applications entirely in the ARM assembly language!&lt;br /&gt;
&lt;br /&gt;
As most of the resources and tools for ARM focus on C programming and because of the complexity of the ARM ecosystem, the largest difficulty in getting started with ARM assembly is not the language itself, but rather using the tools correctly and finding relevant documentation. Therefore, this tutorial will focus on the development environment and how the written assembly code is transformed into the final program. With a good understanding of the environment, all the ARM instructions can be learned simply by reading the architecture documentation.&lt;br /&gt;
&lt;br /&gt;
Because of the complex ecosystem around ARM, a general introduction of the ARM processor market is necessary.&lt;br /&gt;
&lt;br /&gt;
=== About ARM ===&lt;br /&gt;
Arm Holdings is the company behind the ARM architecture. Arm does not manufacture any processors themselves, but designs the “blueprints” for processor cores, which are then licensed by various semiconductor companies such as ST, TI, NXP and many others, who combine the processor with various support hardware (most notably flash and RAM memories) and peripheral modules to produce a final complete processor IC. Some of these peripheral modules are even licensed from other companies – for example, the USB controller modules by Synopsys are found in many different processors from various manufacturers.&lt;br /&gt;
&lt;br /&gt;
Because of this licensing model, ARM processor cores are found in a very large variety of products for which software can be developed using a single set of tools (especially compiler, assembler and debugger). This makes knowledge about the ARM architecture, particularly the ARM assembly language, useful for a large range of applications.&lt;br /&gt;
&lt;br /&gt;
Since the ARM processor cores always require additional hardware modules to function, both the ARM-made processor core and the manufacturer-specific periphery modules have to be considered when developing software for ARM systems. For example, the instruction set is defined by ARM and software tools (compiler, assembler) need to be configured for the correct instruction set version, while the clock configuration is manufacturer-specific and needs to be addressed by initialization code specifically made for one processor.&lt;br /&gt;
&lt;br /&gt;
=== Architecture and processor variants ===&lt;br /&gt;
A processor’s architecture defines the interface between hardware and software. Its most important part is the instruction set, but it also defines e.g. hardware behavior under exceptional circumstances (e.g. memory access errors, division by zero, etc.). Processor architectures evolve, so they have multiple versions and variants. They also define optional functionality that may or may not be present in a processor (e.g. a floating-point unit). For ARM, the architectures are documented exhaustively in the “ARM Architecture Reference Manuals”.&lt;br /&gt;
&lt;br /&gt;
While the architecture is an abstract concept, a processor core is a concrete definition of a processor (e.g. as a silicon layout or HDL) that implements a certain architecture. Code that only uses knowledge of the architecture (e.g. an algorithm that does not access any periphery) will run on any processor implementing this architecture. Arm, as mentioned, designs processor cores for their own architectures, but some companies develop custom processors that conform to an ARM architecture, for example Apple and Qualcomm.&lt;br /&gt;
&lt;br /&gt;
ARM architectures are numbered, starting with ARMv1 up until the most recent ARMv8. ARMv6 is the oldest architecture still in significant use, while ARMv7 is the most widespread one. Suffixes are appended to the version to denote variants of the architecture; e.g. ARMv7-M is for small embedded systems while ARMv7-A for more powerful processors. ARMv7E-M adds digital signal processing capabilities including saturating and SIMD operations.&lt;br /&gt;
&lt;br /&gt;
Older ARM processors are named ARM1, ARM2 …, while after ARM11 the name “Cortex” was introduced. The Cortex-M family, including e.g. Cortex-M3 and Cortex-M4 (implementing ARMv7-M and ARMv7E-M architecture, respectively) is designed for microcontrollers, where power consumption, memory size, chip size and latency are important. The Cortex-A family, including e.g. Cortex-A8 and Cortex-A17 (both implementing ARMv7-A architecture) is intended for powerful processors (called “application processors”) for e.g. multimedia and communication products, particularly smartphones and tablets. These processors have much more processing power, typically feature high-bandwidth interfaces to the external world, and are designed to be used with high-level operating systems, most notably Linux (and Android).&lt;br /&gt;
&lt;br /&gt;
An overview of ARM processors and their implemented architecture version can be found on [https://en.wikipedia.org/wiki/ARM_architecture#Cores Wikipedia].&lt;br /&gt;
This tutorial will focus on the Cortex-M microcontrollers, as these are much easier to program without an operating system and because assembly language is less relevant on Cortex-A processors. However, the large range of ARM-based devices necessitates flexibility in the architecture specification and software tools, which sometimes complicates their use.&lt;br /&gt;
&lt;br /&gt;
There is actually not a single, but three instruction sets for ARM processors:&lt;br /&gt;
* The “A32” instruction set for 32bit ARM architectures, also simply called “ARM” instruction set, favors speed over program memory consumption. All instructions are 4 bytes in size.&lt;br /&gt;
* The “A64” instruction set is for the new 64bit ARM processors&lt;br /&gt;
* The “T32” instruction set for 32bit ARM architectures, also known as “Thumb”, favors program memory consumption over speed. Most instructions are 2 bytes in size, and some are 4 bytes.&lt;br /&gt;
&lt;br /&gt;
The 64bit Cortex-A application processors support all three instruction sets, while the 32bit ones only A32 and T32. The Cortex-M microcontrollers only support T32. Therefore, this tutorial will only talk about “thumb2”, the second version of the “T32” instruction set.&lt;br /&gt;
&lt;br /&gt;
== Prerequisites ==&lt;br /&gt;
First, suitable hardware and software need to be selected for demonstrating the usage of assembly language. For this tutorial, the choice of the specific microcontroller is of no great significance. However, to ensure that the example codes are easily transferable to your setup, it is recommended to use the same components.&lt;br /&gt;
&lt;br /&gt;
=== Mikrocontroller selection ===&lt;br /&gt;
For the microcontroller, an [https://www.st.com/en/microcontrollers-microprocessors/stm32f103c8.html STM32F103C8] or [https://www.st.com/en/microcontrollers-microprocessors/stm32f103rb.html STM32F103RB] by STMicroelectronics will be used. Both controllers are identical except for the flash size (64 KiB vs 128 KiB) and number of pins (48 vs 64). These controllers belong to ST’s “mainstream” entry-level- family and are quite popular among hobbyist developers with many existing online resources. Several development boards with these controllers are available, for example: [https://www.st.com/en/evaluation-tools/nucleo-f103rb.html Nucleo-F103], “[https://os.mbed.com/users/hudakz/code/STM32F103C8T6_Hello/ Blue Pill]” (search for “stm32f103c8t6” on AliExpress, Ebay or Amazon), [https://www.olimex.com/Products/Duino/STM32/OLIMEXINO-STM32/open-source-hardware Olimexino-STM32], [https://www.olimex.com/Products/ARM/ST/STM32-P103/ STM32-P103], [https://www.olimex.com/Products/ARM/ST/STM32-H103/ STM32-H103], [https://www.st.com/en/evaluation-tools/stm3210e-eval.html STM3210E-EVAL].&lt;br /&gt;
&lt;br /&gt;
=== Processor type &amp;amp; documentation ===&lt;br /&gt;
First, the microcontroller manufacturer’s documentation is used to find out what kind of ARM processor core and architecture is used for the chosen chip. This information is used to find all the relevant documentation.&lt;br /&gt;
&lt;br /&gt;
* The first source of information is the [https://www.st.com/resource/en/datasheet/stm32f103rb.pdf STM32F103RB/C8 datasheet]. According to the headline, this is a &#039;&#039;&#039;medium-density&#039;&#039;&#039; device. This term is ST-specific and denotes a product family with certain features. The very first paragraph states that this microcontroller uses a &#039;&#039;&#039;Cortex-M3&#039;&#039;&#039; processor core with 72 MHz. This document also contains the electrical characteristics and pinouts.&lt;br /&gt;
* The next important document is the [https://www.st.com/resource/en/reference_manual/cd00171190.pdf STM32F103 reference manual] that contains detailed descriptions of the periphery. Particularly, detailed information about periphery registers and bits can be found here.&lt;br /&gt;
* The [https://developer.arm.com/ip-products/processors/cortex-m/cortex-m3 ARM developer website] provides information about the Cortex-M3 processor core, particularly the [https://static.docs.arm.com/100165/0201/arm_cortexm3_processor_trm_100165_0201_01_en.pdf ARM Cortex-M3 Processor Technical Reference Manual]. According to chapter 1.5.3, this processor implements the &#039;&#039;&#039;ARMv7-M architecture&#039;&#039;&#039;.&lt;br /&gt;
* The architecture is documented in the [https://static.docs.arm.com/ddi0403/ed/DDI0403E_d_armv7m_arm.pdf ARMv7M Architecture Reference Manual]. Particularly, it contains the complete documentation of the instruction set.&lt;br /&gt;
&lt;br /&gt;
For any serious STM32 development, you should be familiar with all these documents.&lt;br /&gt;
&lt;br /&gt;
=== Debug adapter ===&lt;br /&gt;
There are many different ways of getting your program to run on an STM32 controller. A debug adapter is not only capable of writing software to the controller’s flash, but can also analyze the program’s behavior while it is running. This allows you to run the program one instruction at a time, analyze program flow and memory contents and find the cause of crashes. While it is not strictly necessary to use such a debugger, it can save a lot of time during development. Since entry-level models are available cheaply, not using one doesn’t even save money. Debuggers connect to a host PC via USB (some via Ethernet) and to the microcontroller (“target”) via JTAG oder SWD. While these two interfaces are closely related and perform the same function, SWD uses fewer pins (2 instead of 4, excluding reset and ground). Most STM32 controllers support JTAG, and all support SWD.&lt;br /&gt;
&lt;br /&gt;
Documenting all possible way of flashing and debugging STM32 controllers is beyond the scope of this tutorial; a lot of information is already available online on that topic. Therefore, this tutorial will assume that the [https://www.st.com/en/development-tools/st-link-v2.html ST-Link] debug adapter by STMicroelectronics is used, which is cheap and popular among hobbyists. Some of the aforementioned boards even include an ST-Link adapter, which can also be used “stand-alone” to flash an externally connected microcontroller. The examples should work with other adapters as well; please consult the appropriate documentation on how to use them.&lt;br /&gt;
&lt;br /&gt;
=== Development Software ===&lt;br /&gt;
On the software part, several tools are needed for developing microcontroller firmware. Using a complete Integrated Development Environment (IDE) saves time and simplifies repetitive steps but hides some important steps that are necessary to gain a basic understanding of the process. Therefore, this tutorial will show the usage of the basic command line tools to demonstrate the underlying principles. Of course, for productive development, using an IDE is a sensible choice. The tools presented will work on Windows, Linux and Mac OS X (untested).&lt;br /&gt;
&lt;br /&gt;
First, a text editor for writing assembly code is needed. Any good editor such as Notepad++, gedit or Kate is sufficient. When using Windows, the [https://www.st.com/en/development-tools/stsw-link004.html ST-Link Utility] can be useful, but is not strictly required.&lt;br /&gt;
&lt;br /&gt;
Next, an assembler toolchain is needed to translate the written assembly code into machine code. For this, the [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm GNU Arm Embedded Toolchain] is used. This is a collection of open source tools for writing software in Assembly, C and C++ for Cortex-M microcontrollers. Even though the package is maintained by ARM, the software is created by a community of open-source developers. For this tutorial, only the contained applications “binutils” (includes assembler &amp;amp; linker) and “GDB” (debugger) are really needed, but if you later decide to work with C or C++ code, the contained compilers will come in handy. Apart from that, this package is also shipped as part of several IDEs such as SW4STM32, Atollic TrueSTUDIO, emIDE, Embedded Studio and even Arduino – so if you (later) wish to work with one of these, your assembly code will be compatible with it.&lt;br /&gt;
&lt;br /&gt;
Another component is required to talk with the debug adapter. For the ST-Link, this is done by [http://openocd.org/ OpenOCD], which communicates with the adapter via USB. Other adapters such as the J-Link ship with their own software.&lt;br /&gt;
&lt;br /&gt;
Lastly, a calculator that supports binary and hexadecimal modes can be very helpful. Both the default Gnome calculator and the Windows calculator (calc.exe) are suitable.&lt;br /&gt;
&lt;br /&gt;
== Setup ==&lt;br /&gt;
Follow the instructions in the next chapters to set up your development environment.&lt;br /&gt;
&lt;br /&gt;
=== Hardware ===&lt;br /&gt;
The only thing that needs to be done hardware-wise is connecting the debugger with your microcontroller. If you are using a development board with an integrated debugger (such as the Nucleo-F103), this is achieved by setting the jumpers accordingly (see the board’s documentation – for e.g. the Nucleo-F103, both “CN2” jumpers need to be connected). When using an external debugger, connect the “GND”, “JTMS/SWDIO” and “JTCK/SWCLK” pins of debugger and microcontroller. Connect the debugger’s “nRESET” (or “nTRST” if it only has that) pin to the microcontroller’s “NRST” input.&lt;br /&gt;
&lt;br /&gt;
If your board has jumpers or solder bridges for the “BOOT0” pin, make sure that the pin is low. Applying power to the microcontroller board is typically done via USB.&lt;br /&gt;
&lt;br /&gt;
=== Software ===&lt;br /&gt;
==== Linux ====&lt;br /&gt;
Some linux distributions ship with packages for the ARM toolchain. Unfortunately, these are often outdated and also configured slightly differently than the aforementioned package maintained by ARM. Therefore, to be consistent with the examples, it is strongly recommended to use the package by ARM.&lt;br /&gt;
&lt;br /&gt;
Download the Linux binary tarball from the [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads downloads page] and extract it to some directory whose path does not contain any spaces. The extracted directory contains a subdirectory called “bin”. Copy the full path to that directory (e.g. “/home/user/gcc-arm-none-eabi-8-2019-q3-update/bin”).&lt;br /&gt;
&lt;br /&gt;
Add this path to the “PATH” environment variable. On Ubuntu/Debian systems, this can be done via:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=sh&amp;gt;&lt;br /&gt;
echo &#039;export PATH=&amp;quot;${PATH}:/home/user/gcc-arm-none-eabi-8-2019-q3-update/bin&amp;quot;&#039; | sudo tee /etc/profile.d/gnu-arm-embedded.sh&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
OpenOCD can be installed via the package manager, e.g. (Ubuntu/Debian):&lt;br /&gt;
&amp;lt;source lang=sh&amp;gt;&lt;br /&gt;
sudo apt-get install openocd&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
After that, log out and back in (or just reboot). In a terminal, type &amp;lt;code&amp;gt;arm-none-eabi-as -version&amp;lt;/code&amp;gt;. The output should look similar to this:&lt;br /&gt;
&amp;lt;source lang=sh&amp;gt;&lt;br /&gt;
$ arm-none-eabi-as -version&lt;br /&gt;
GNU assembler (GNU Tools for Arm Embedded Processors 8-2019-q3-update) 2.32.0.20190703&lt;br /&gt;
Copyright (C) 2019 Free Software Foundation, Inc.&lt;br /&gt;
This program is free software; you may redistribute it under the terms of&lt;br /&gt;
the GNU General Public License version 3 or later.&lt;br /&gt;
This program has absolutely no warranty.&lt;br /&gt;
This assembler was configured for a target of `arm-none-eabi&#039;.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Similarly, for &amp;lt;code&amp;gt;openocd -v&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;source lang=sh&amp;gt;&lt;br /&gt;
$ openocd -v&lt;br /&gt;
Open On-Chip Debugger 0.10.0&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
	http://openocd.org/doc/doxygen/bugs.html&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an error message appears, the installation isn’t correct.&lt;br /&gt;
&lt;br /&gt;
==== Windows ====&lt;br /&gt;
[[File:ArmAsmTutorial_GccOptions.png|300px|thumb|right|Options for installing GCC]]Download the Windows installer from the [https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads downloads page] and run it. Enable the options “Add path to environment variable” and “Add registry information”, and disable “Show Readme” and “Launch gccvar.bat”.&lt;br /&gt;
&lt;br /&gt;
A Windows package for OpenOCD can be obtained from the [https://github.com/gnu-mcu-eclipse/openocd/releases gnu-mcu-eclipse downloads page]. Download the appropriate file, e.g. &amp;quot; gnu-mcu-eclipse-openocd-0.10.0-12-20190422-2015-win64.zip”. The archive contains a path like “GNU MCU Eclipse/OpenOCD/0.10.0-12-20190422-2015”. Extract the contents of the inner directory (i.e. the subdirectories “bin”, “doc”, “scripts”…) into some directory whose path does not contain any spaces, e.g. “C:\OpenOCD”. You should now have a directory “C:\OpenOCD\bin” or similar. Copy its full path.&lt;br /&gt;
&lt;br /&gt;
[[File:ArmAsmTutorial_PcProperties.png|300px|thumb|right|Opening PC properties]][[File:ArmAsmTutorial_SetEnvVar.png|300px|thumb|right|Setting environment variable]]Set the “Path” environment variable to include this path: Right-Click on “This PC”, then “Properties” → “Advanced System Settings”→ “Environment Variables”. In the lower list (labeled “System variables”), select “Path”. Click “Edit” → “New”, paste the path, and click “OK” multiple times.&lt;br /&gt;
&lt;br /&gt;
Open a &#039;&#039;new&#039;&#039; command window (Windows Key + R, type “cmd” + Return). Type &amp;lt;code&amp;gt;arm-none-eabi-as -version&amp;lt;/code&amp;gt;. The output should look similar to this:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
C:\&amp;gt;arm-none-eabi-as -version&lt;br /&gt;
GNU assembler (GNU Tools for Arm Embedded Processors 8-2019-q3-update) 2.32.0.20190703&lt;br /&gt;
Copyright (C) 2019 Free Software Foundation, Inc.&lt;br /&gt;
This program is free software; you may redistribute it under the terms of&lt;br /&gt;
the GNU General Public License version 3 or later.&lt;br /&gt;
This program has absolutely no warranty.&lt;br /&gt;
This assembler was configured for a target of `arm-none-eabi&#039;.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Similarly, for &amp;lt;code&amp;gt;openocd -v&amp;lt;/code&amp;gt;:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
C:\&amp;gt;openocd -v&lt;br /&gt;
GNU MCU Eclipse OpenOCD, 64-bitOpen On-Chip Debugger 0.10.0+dev-00593-g23ad80df4 (2019-04-22-20:25)&lt;br /&gt;
Licensed under GNU GPL v2&lt;br /&gt;
For bug reports, read&lt;br /&gt;
    	http://openocd.org/doc/doxygen/bugs.html&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If an error message appears, the installation isn’t correct.&lt;br /&gt;
&lt;br /&gt;
== Writing assembly applications ==&lt;br /&gt;
The full source code of the examples in the following chapters contain be found on [https://github.com/Erlkoenig90/ArmAsmTutorial GitHub]. The name of the corresponding directory is given after each example code below.&lt;br /&gt;
=== First rudimentary program ===&lt;br /&gt;
After the software setup, you can begin setting up a first project. Create an empty directory for that, e.g. “prog1”.&lt;br /&gt;
&lt;br /&gt;
Inside the project directory, create your first assembly file “prog1.S” (“.S” being the file name extension for assembly files in GNU context) with the following content:&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.word 0x20000400&lt;br /&gt;
.word 0x080000ed&lt;br /&gt;
.space 0xe4&lt;br /&gt;
&lt;br /&gt;
nop		@ Do Nothing&lt;br /&gt;
b .		@ Endless loop&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “EmptyProgram”&lt;br /&gt;
&lt;br /&gt;
When this file is sent to the assembler, it will translate the instructions into binary machine code, with 2 or 4 bytes per instruction. These bytes are concatenated to form a program image, which is later written into the controller’s flash memory. Therefore, assembly code more or less directly describes flash memory contents.&lt;br /&gt;
&lt;br /&gt;
The lines starting with a dot “.” are assembler directives that control the assembler’s operation. Only some of those directives emit bytes that will end up in flash memory. The @ symbol starts a comment.&lt;br /&gt;
&lt;br /&gt;
The first line lets the assembler use the new “unified” instruction syntax (“UAL” - Unified Assembler Language) instead of the old ARM syntax. The second line declares the used processor Cortex-M3, which the assembler needs to know in order to recognize the instructions available on that processor. The third line instructs the assembler to use the Thumb (T32) instruction set. We can’t start putting instructions in flash memory right away, as the processor expects a certain data structure to reside at the very beginning of the memory. This is what the “.word” and “.space” instructions create. These will be explained later.&lt;br /&gt;
&lt;br /&gt;
The first “real” instruction is “nop”, which will be the first instruction executed after the processor starts. “nop” is short for “No OPeration” - it causes the processor to do nothing and continue with the next instruction. This next instruction is “b .”. “b” is short for “branch” and instructs the processor to jump to a certain “target” location, i.e. execute the instruction at that target next. In assembly language, the dot “.” represents the current location in program memory. Therefore, “b .” instructs the processor to jump to this very instruction, i.e. execute it again and again in an endless loop. Such an endless loop is frequently found at the end of microcontroller programs, as it prevents the processor from executing random data that is located in flash memory after the program.&lt;br /&gt;
&lt;br /&gt;
To translate this assembly code, open a terminal (linux) / command window (Windows). Enter the project directory by typing &amp;lt;code&amp;gt;cd &amp;lt;Path to Project Directory&amp;gt;&amp;lt;/code&amp;gt;. Call the assembler like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=sh&amp;gt;&lt;br /&gt;
arm-none-eabi-as -g prog1.S -o prog1.o&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This instructs the assembler to translate the source file “prog1.S” into an object file “prog1.o”. This is an intermediary file that contains binary machine code, but is not a complete program yet. The “-g”-Option tells the assembler to include debug information, which does not influence the program itself, but makes debugging easier. To turn this object file into a final program, call the linker like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=sh&amp;gt;&lt;br /&gt;
arm-none-eabi-ld prog1.o -o prog1.elf -Ttext=0x8000000&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This creates a file “prog1.elf” that contains the whole generated program. The “-Ttext” option instructs the linker to assume 0x8000000 as the start address of the flash memory. The linker might output a warning like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;arm-none-eabi-ld: warning: cannot find entry symbol _start; defaulting to 0000000008000000&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is not relevant for executing the program without an operating system and can be ignored.&lt;br /&gt;
&lt;br /&gt;
=== Flashing the program ===&lt;br /&gt;
To download the compiled application to the microcontroller that has been attached via ST-Link, use OpenOCD like so:&lt;br /&gt;
&amp;lt;source lang=sh&amp;gt;&lt;br /&gt;
openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg -c &amp;quot;program prog1.elf verify reset exit&amp;quot;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Unfortunately, the application does not do anything that can be observed from the outside, except perhaps increase the current consumption.&lt;br /&gt;
=== Starting the debugger ===&lt;br /&gt;
To check whether the program is actually running, start a debugging session to closely observe the processor’s behavior. First, run OpenOCD such that it acts as a GDB server:&lt;br /&gt;
&amp;lt;source lang=sh&amp;gt;&lt;br /&gt;
openocd -f interface/stlink-v2.cfg -f target/stm32f1x.cfg&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Then, open a new terminal/command window and start a GDB session:&lt;br /&gt;
&amp;lt;source lang=sh&amp;gt;&lt;br /&gt;
arm-none-eabi-gdb prog1.elf&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
GDB provides its own interactive text-based user interface. First, type this command to let GDB connect to the already running OpenOCD instance:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
target remote :3333&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Then, stop the currently running program:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
monitor reset halt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
If this fails, hold your board’s reset button just before executing the command and repeat until it succeeds. GDB can also download code to flash memory by simply typing:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
load&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Which will overwrite the previously flashed program (which, in this case, is identical anyways). After loading the program, reset the controller again:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
monitor reset halt&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Now, examine the contents of the CPU registers:&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
info reg&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The output should look something like&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
r0             0x0                 0&lt;br /&gt;
r1             0x0                 0&lt;br /&gt;
r2             0x0                 0&lt;br /&gt;
r3             0x0                 0&lt;br /&gt;
r4             0x0                 0&lt;br /&gt;
r5             0x0                 0&lt;br /&gt;
r6             0x0                 0&lt;br /&gt;
r7             0x0                 0&lt;br /&gt;
r8             0x0                 0&lt;br /&gt;
r9             0x0                 0&lt;br /&gt;
r10            0x0                 0&lt;br /&gt;
r11            0x0                 0&lt;br /&gt;
r12            0x0                 0&lt;br /&gt;
sp             0x0                 0x0&lt;br /&gt;
lr             0x0                 0&lt;br /&gt;
pc             0x8000000           0x8000000 &amp;lt;_stack+133693440&amp;gt;&lt;br /&gt;
xPSR           0x1000000           16777216&lt;br /&gt;
msp            0x20000400          0x20000400&lt;br /&gt;
psp            0x27e3fa34          0x27e3fa34&lt;br /&gt;
primask        0x0                 0&lt;br /&gt;
basepri        0x0                 0&lt;br /&gt;
faultmask      0x0                 0&lt;br /&gt;
control        0x0                 0&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
At this point, the processor is ready to start executing your program. The processor is halted just before the first instruction, which is “nop”. You can let the processor execute one single instruction (i.e. the “nop”) by typing&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
stepi&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
If you type &amp;lt;code&amp;gt;info reg&amp;lt;/code&amp;gt; again, you will see that PC is now “0x80000ee”, i.e. the processor is about to execute the next instruction, “b .”. When you do &amp;lt;source&amp;gt;stepi&amp;lt;/source&amp;gt; again (repeatedly), nothing more will happen – the controller is stuck in the mentioned endless loop, exactly as intended. You can instruct the processor to run the program continuously, without stopping after each instruction by typing&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
continue&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
You can interrupt the running program by pressing “Ctrl+C”. Run the commands&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
kill&lt;br /&gt;
quit&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
to exit GDB. You can terminate OpenOCD by pressing “Ctrl+C” in its terminal.&lt;br /&gt;
=== Using processor registers ===&lt;br /&gt;
The example program hasn’t done anything useful, but any “real” program will need to process some data. On ARM, any data processing is done via the processor registers. The 32bit ARM platforms have 16 processor registers, each of which is 32bit in size. The last three of those (r13-r15) have a special meaning and can only be used with certain restrictions. The first thirteen (r0-r12) can be used freely by the application code for data processing.&lt;br /&gt;
&lt;br /&gt;
All calculations (e.g. addition, multiplication, logical and/or) need to be performed on those processor registers. To process data from memory, it first has to be loaded into a register, then processed, and stored back into memory. This is typical for RISC platforms and is known as a “load-store-architecture”. &lt;br /&gt;
&lt;br /&gt;
As the starting point for any calculation, some specific values need to be put into the registers. The easiest way to do that is:&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r0, =123456789&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The number 123456789 will be encoded as part of the program, and the instruction lets the processor copy it into the register “r0”. Any number and any register in the range r0-r13 can be used instead.&lt;br /&gt;
&lt;br /&gt;
The instruction “mov” can be used to copy the contents from one register to another:&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
mov r1, r0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
This copies r0 to r1. Unlike some other processor architectures, “mov” can not be used to access memory, but only the processor registers.&lt;br /&gt;
&lt;br /&gt;
In ARM, 32bit numbers are called &amp;quot;words&amp;quot; and are most frequently used. 16bit numbers are known as half-words, and 8bit numbers as bytes, as usual.&lt;br /&gt;
=== Accessing periphery ===&lt;br /&gt;
To write microcontroller programs that interact with the outside world, access to the controller’s periphery modules is required. Interaction with periphery happens mainly through periphery registers (also known as “special function registers”, SFR). Despite their name, they work quite differently from processor registers. Instead of numbers, they have addresses (in the range of 0x40000000-0x50000000) that are not contiguous (i.e. there are gaps), they cannot be directly used for data processing but need to be explicitly read and written before and after any calculations. Not all of them are 32bit; many have only 16bit, and some of those bits may not exist and can’t be accessed. The microcontroller manufacturer’s documentation uses names for these registers, but the assembler doesn’t know these. Therefore, the assembly code needs to use the numerical addresses.&lt;br /&gt;
&lt;br /&gt;
The easiest way to get the microcontroller to do something that produces some visible result is to send a signal via an output pin to turn on an LED. Using a pin to send/receive arbitrary software-defined signals is called “GPIO” (General Purpose Input/Output). First, choose a pin – for example, PA8 (this one is available on all package variants). Connect an LED to this pin and to GND (“active high”). Use a series resistor to limit the current to max. 15mA (the absolute maximum being 25mA), e.g. 100Ω for a 3,3V supply and a standard LED. For higher loads (e.g. high-power LEDs or a relay) use an appropriate transistor.&lt;br /&gt;
&lt;br /&gt;
As with most microcontrollers, the pins are grouped into so-called “ports”, each of which has up to 16 pins. The ports are named by letters of the alphabet, i.e. “GPIOA”, “GPIOB”, “GPIOC” etc. The number of ports and pins varies among the individual microcontroller types. The 16 pins of one port can be read or written in one single step.&lt;br /&gt;
&lt;br /&gt;
==== Clock Configuration ====&lt;br /&gt;
Many ARM controllers feature a certain trap: Most periphery modules are disabled by default to save power. The software has to explicitly enable the needed modules. On STM32 controllers, this is done via the “RCC” (Reset and Clock Control) module. Particularly, this module allows the software to disable/enable the clock signal for each periphery module. Because MOSFET-based circuits (virtually all modern ICs) only draw power if a clock signal is applied, turning off the clock of unused modules can reduce the power usage considerably.&lt;br /&gt;
&lt;br /&gt;
This is documented in the aforementioned reference manual in chapter 7. The subchapter 7.3.7 describes the periphery register “RCC_APB2ENR” which allows you to configure the clock signal for some peripheral modules. This register has 32 bits, of which 14 are “reserved”, i.e. can’t be used and should only be written with zeroes. Each of the available 18 bits enables one specific periphery module if set to “1” or disables it if set to “0”. According to the manual, the reset value of this register is 0, so all periphery modules are disabled by default. In order to turn on the GPIOA module to which the desired pin PA8 belongs, the bit “IOPAEN” needs to be set to “1”. This is bit number two in the register. Since registers can only be accessed to as a whole (individual bits can’t be addressed), a 32bit-value where bit two is “1” and all others are kept as “0” needs to be written. This value is 0x00000004.&lt;br /&gt;
&lt;br /&gt;
To write to the register, its address needs to be given in the code. The addresses of the periphery registers are grouped by the periphery modules they belong to - each periphery module (e.g. RCC, GPIOA, GPIOB, USB, …) has its own base address. The addresses of the individual registers are specified as an offset that needs to be added to this base address to obtain the full absolute address of the register. Chapter 7.3.7 specifies the offset address of RCC_APB2ENR as “0x18”. Chapter 3.3 specifies the base addresses of all periphery modules – RCC is given as “0x40021000”. So, the absolute address of RCC_APB2ENR is “0x40021000+ 0x18=0x40021018”.&lt;br /&gt;
&lt;br /&gt;
In short: To enable GPIOA, the value &#039;&#039;&#039;0x00000004&#039;&#039;&#039; needs to be written to address &#039;&#039;&#039;0x40021018&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
According to the “load-store” principle, ARM processors can’t do this in a single step. Both the value to be written and the address need to reside in processor registers in order to perform the write access. So, what needs to done is:&lt;br /&gt;
* Load the value 0x00000004 into a register&lt;br /&gt;
* Load the value 0x40021018 into another register&lt;br /&gt;
* Store the value from the first register into the memory location specified by the second register.&lt;br /&gt;
This last step is performed by the “STR” instruction as follows:&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.word 0x20000400&lt;br /&gt;
.word 0x080000ed&lt;br /&gt;
.space 0xe4&lt;br /&gt;
&lt;br /&gt;
ldr r0, =0x00000004&lt;br /&gt;
ldr r1, =0x40021018&lt;br /&gt;
str r0, [r1]			@ Set IOPAEN bit in RCC_APB2ENR to 1 to enable GPIOA&lt;br /&gt;
b .&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The square brackets are required but just serve as a reminder to the programmer that the contents of “r1” is used as an address. After the “str” instruction, the GPIOA periphery is enabled, but doesn’t do anything yet.&lt;br /&gt;
&lt;br /&gt;
==== GPIO Configuration ====&lt;br /&gt;
By default, all GPIO pins are configured as “input”, even if there is no software to process the input data. Since inputs are “high-impedance”, i.e. only a very small current can flow into/out of the pin, the risk of (accidental) short-circuits and damage to the microcontroller is minimized. However, this current is too small to light up an LED, so you have to configure the pin PA8 as “output”. The STM32 support multiple output modes, of which the right one for the LED is “General Purpose Output Push-Pull, 2 MHz”.&lt;br /&gt;
&lt;br /&gt;
Access and configuration of GPIO pins is achieved via the registers of the GPIO periphery. The STM32 have multiple identical instances of GPIO modules, which are named GPIOA, GPIOB, … Each of those instances has a distinct base address, which are again described in chapter 3.3 of the reference manual (e.g. “0x40010800” for GPIOA, “0x40010C00” for GPIOB etc.). The registers of the GPIO module are described in chapter 9.2, and there is one instance of each register per GPIO module. To access a specific register of a specific GPIO module, the base address of that module needs to be added to the offset address of the register. For example, “GPIOA_IDR” has address “0x40010800+0x08=0x40010808”, while “GPIOB_ODR” has address “0x40010C00+0x0C= 0x40010C0C”.&lt;br /&gt;
&lt;br /&gt;
Configuration of the individual GPIO pins happens through the “GPIOx_CRL” and “GPIOx_CRH” registers (“x” is a placeholder for the concrete GPIO module) – see chapters 9.2.1 and 9.2.2. Both registers are structured identically, where each pin uses 4 bits, so each of the two registers handles 8 pins in 8x4=32 bits. Pins 0-7 are configured by “GPIOx_CRL” and pins 8-15 by “GPIOx_CRH”. Pin 0 is configured by bits 0-3 of “GPIOx_CRL”, pin 1 by bits 4-7 of “GPIOx_CRL”, pin 8 by bits 0-3 of “GPIOx_CRH” and so on.&lt;br /&gt;
&lt;br /&gt;
The 4 bits per pin are split into two 2-bit fields: “MODE” occupies bits 0-1, and “CNF” bits 2-3. “MODE” selects from input and output modes (with different speeds). In output mode, “CNF” determines whether the output value is configured from software (“General Purpose” mode) or driven by some other periphery module (“Alternate function” mode), and whether two transistors (“Push-pull”) or one (“open-drain”) are used to drive the output. In input mode, “CNF” selects from analog mode (for ADC), floating input and input with pull-up/down resistors (depending on the value in the “GPIOx_ODR” register).&lt;br /&gt;
&lt;br /&gt;
Therefore, to configure pin PA8 into “General Purpose Output Push-Pull, 2 MHz” mode, bits 0-3 of “GPIOA_CRH” need to be set to value “2”. The default value of “4” configures the pin as “input”. To keep the other pins at their “input” configuration, the value “0x44444442” needs to be written to register “GPIOA_CRH”, which has address “0x40010804”:&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r0, =0x44444442&lt;br /&gt;
ldr r1, =0x40010804&lt;br /&gt;
str r0, [r1]			@ Set CNF8:MODE8 in GPIOA_CRH to 2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Writing GPIO pins ====&lt;br /&gt;
The GPIO pin still outputs the dafult value, which is 0 for “low”. To turn on the LED, the output has to be set to “1” for “high”. This is achieved via the GPIOA_ODR register, which has 16bits, one for each pin (see chapter 9.2.4). To enable the LED, set bit 8 to one:&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.word 0x20000400&lt;br /&gt;
.word 0x080000ed&lt;br /&gt;
.space 0xe4&lt;br /&gt;
&lt;br /&gt;
ldr r0, =0x00000004&lt;br /&gt;
ldr r1, =0x40021018&lt;br /&gt;
str r0, [r1]			@ Set IOPAEN bit in RCC_APB2ENR to 1 to enable GPIOA&lt;br /&gt;
&lt;br /&gt;
ldr r0, =0x44444442&lt;br /&gt;
ldr r1, =0x40010804&lt;br /&gt;
str r0, [r1]			@ Set CNF8:MODE8 in GPIOA_CRH to 2&lt;br /&gt;
&lt;br /&gt;
ldr r0, =0x100&lt;br /&gt;
ldr r1, =0x4001080C&lt;br /&gt;
str r0, [r1]			@ Set ODR8 in GPIOA_ODR to 1 to set PA8 high&lt;br /&gt;
&lt;br /&gt;
b .&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “SetPin”&lt;br /&gt;
&lt;br /&gt;
This program enables the GPIOA periphery clock, configures PA8 as output, and sets it to high. If you run it on your microcontroller, you should see the LED turn on – the first program to have a visible effect!&lt;br /&gt;
&lt;br /&gt;
=== Data processing ===&lt;br /&gt;
ARM supports many instructions for mathematical operations. For example, addition can be performed as:&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r0, =222&lt;br /&gt;
ldr r1, =111&lt;br /&gt;
add r2, r0, r1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
This will first load the value 222 into register r0, load 111 into r1, and finally add r0 and r1 and store the result (i.e. 333) in r2. The operand for the result is (almost) always put on the left, while the input operand(s) follow on the right.&lt;br /&gt;
&lt;br /&gt;
You can also overwrite an input register with the result:&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
add r0, r0, r1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
This will write the result to r0, overwriting the previous value. This is commonly shortened to&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
add r0, r1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The output operand can be omitted, and the first input (here: r0) will be overwritten. This applies to most data processing instructions. Other frequently used data processing instructions that are used in a similar fashion are:&lt;br /&gt;
* &#039;&#039;&#039;sub&#039;&#039;&#039; for subtraction&lt;br /&gt;
* &#039;&#039;&#039;mul&#039;&#039;&#039; for multiplication&lt;br /&gt;
* &#039;&#039;&#039;and&#039;&#039;&#039; for bitwise and&lt;br /&gt;
* &#039;&#039;&#039;orr&#039;&#039;&#039; for bitwise or&lt;br /&gt;
* &#039;&#039;&#039;eor&#039;&#039;&#039; for bitwise exclusive or (“xor”)&lt;br /&gt;
* &#039;&#039;&#039;lsl&#039;&#039;&#039; for logical left shift&lt;br /&gt;
* &#039;&#039;&#039;lsr&#039;&#039;&#039; for logical right shift&lt;br /&gt;
&lt;br /&gt;
Most of these instructions can not only take registers as input, but also immediate arguments. Such an argument is encoded directly into the instruction without needing to put it into a register first. Immediate arguments need to be prefixed by a hash sign #, and can be decimal, hexadecimal or binary. For example,&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
add r0, r0, #23&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
adds 23 to the register r0 and stores the result in r0. This can again be shortened to&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
add r0, #23&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Such immediate arguments can not be arbitrarily large, because they need to fit inside the instruction, which is 16 or 32 bit in size and also needs some room for the instruction and register numbers as well. So, if you want to add a large number, you have to use “ldr” first as shown to load it into a register.&lt;br /&gt;
&lt;br /&gt;
Try out the above examples and use GDB to examine their behavior. Use GDB’s “info reg” command to display the register contents. Don&#039;t forget to execute both the “arm-none-eabi-as” and “arm-none-eabi-ld” commands to translate the program.&lt;br /&gt;
&lt;br /&gt;
=== Reading periphery registers ===&lt;br /&gt;
The last example works, but has a flaw: Even though only a few bits per register need to be modified, the code overwrites all the bits in the register at once. The bits that should not be modified are just overwritten with their respective default value. If some of those bits had been changed before – for example to enable some other periphery module – these changes would be lost. Keeping track of the state of the register throughout the program is hardly practical. Since ARM does not permit modifying individual bits, the solution is to read the whole register, modify the bits as needed, and write the result back. This is called a “read-modify-write” cycle.&lt;br /&gt;
&lt;br /&gt;
Reading registers is done via the “ldr” instruction. As with “str”, the address needs to be written into a processor register beforehand, and the instruction stores the read data into a processor register as well. Starting the with the “RCC_APB2ENR” register, you can read it via:&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r1, =0x40021018&lt;br /&gt;
ldr r0, [r1]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Even though the two “ldr” instruction look similar, they work differently – the first one loads a fixed value into a register (r1), while the second loads data from the periphery register into r1.&lt;br /&gt;
&lt;br /&gt;
The loaded value should then be modified by setting bit two to “1”. This can be done with the “orr” instruction:&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
orr r0, r0, #4&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
After that, we can store r0 as before.&lt;br /&gt;
&lt;br /&gt;
With the GPIOA_CRH register, it’s slightly more complicated: The bits 0, 2 and 3 need to be cleared, while bit 1 needs to be set to 1. The other bits (4-31) need to keep their value. To clear the bits, use the “and” instruction after loading the current periphery register value:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r1, =0x40010804&lt;br /&gt;
ldr r0, [r1]&lt;br /&gt;
and r0, #0xfffffff0&lt;br /&gt;
orr r0, #2&lt;br /&gt;
str r0, [r1]			@ Set CNF8:MODE8 in GPIOA_CRH to 2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For the “GPIOx_ODR” registers, such tricks are not needed, as there is a special “GPIOx_BSRR” register which simplifies writing individual bits: This register can not be read, and writing zeroes to any bit has no effect on the GPIO state. However, if a 1 is written to any of the bits 0-15, the corresponding GPIO pin is set to high (i.e. the corresponding bit in ODR set to 1). If any of the bits 16-31 is written to 1, the corresponding pin is set to low. So, the pin can be set to 1 like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r1, =0x40010810&lt;br /&gt;
ldr r0, =0x100&lt;br /&gt;
str r0, [r1]			@ Set BS8 in GPIOA_BSRR to 1 to set PA8 high&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, the modified program is:&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.word 0x20000400&lt;br /&gt;
.word 0x080000ed&lt;br /&gt;
.space 0xe4&lt;br /&gt;
&lt;br /&gt;
ldr r1, =0x40021018&lt;br /&gt;
ldr r0, [r1]&lt;br /&gt;
orr r0, r0, #4&lt;br /&gt;
str r0, [r1]			@ Set IOPAEN bit in RCC_APB2ENR to 1 to enable GPIOA&lt;br /&gt;
&lt;br /&gt;
ldr r1, =0x40010804&lt;br /&gt;
ldr r0, [r1]&lt;br /&gt;
and r0, #0xfffffff0&lt;br /&gt;
orr r0, #2&lt;br /&gt;
str r0, [r1]			@ Set CNF8:MODE8 in GPIOA_CRH to 2&lt;br /&gt;
&lt;br /&gt;
ldr r1, =0x40010810&lt;br /&gt;
ldr r0, =0x100&lt;br /&gt;
str r0, [r1]			@ Set BS8 in GPIOA_BSRR to 1 to set PA8 high&lt;br /&gt;
&lt;br /&gt;
b .&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “SetPin2”&lt;br /&gt;
=== Jump instructions ===&lt;br /&gt;
For a traditional “hello world” experience, the LED should not only light up, but blink, i.e. turn on and off repeatedly. Setting pin PA8 to low level can be achieved by writing a 1 to bit 24 in the “GPIO_BSRR” register:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r1, =0x40010810&lt;br /&gt;
ldr r0, =0x1000000&lt;br /&gt;
str r0, [r1]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By pasting the this behind the instructions for turning on the LED, it will be turned on and off again. To get the LED to blink, those two blocks need to be repeated endlessly, i.e. at the end of the code there needs to be an instruction for jumping back to the beginning.&lt;br /&gt;
&lt;br /&gt;
A simple endless loop was already explained: The “b .” instruction, which just executes itself repeatedly. To have it jump somewhere else, the dot needs to be substituted for the desired target address, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.word 0x20000400&lt;br /&gt;
.word 0x080000ed&lt;br /&gt;
.space 0xe4&lt;br /&gt;
&lt;br /&gt;
ldr r1, =0x40021018&lt;br /&gt;
ldr r0, [r1]&lt;br /&gt;
orr r0, r0, #4&lt;br /&gt;
str r0, [r1]			@ Set IOPAEN bit in RCC_APB2ENR to 1 to enable GPIOA&lt;br /&gt;
&lt;br /&gt;
ldr r1, =0x40010804&lt;br /&gt;
ldr r0, [r1]&lt;br /&gt;
and r0, #0xfffffff0&lt;br /&gt;
orr r0, #2&lt;br /&gt;
str r0, [r1]			@ Set CNF8:MODE8 in GPIOA_CRH to 2&lt;br /&gt;
&lt;br /&gt;
ldr r1, =0x40010810&lt;br /&gt;
ldr r0, =0x100&lt;br /&gt;
str r0, [r1]			@ Set BS8 in GPIOA_BSRR to 1 to set PA8 high&lt;br /&gt;
&lt;br /&gt;
ldr r1, =0x40010810&lt;br /&gt;
ldr r0, =0x1000000&lt;br /&gt;
str r0, [r1]			@ Set BR8 in GPIOA_BSRR to 1 to set PA8 low&lt;br /&gt;
&lt;br /&gt;
b 0x8000104&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “Blink”&lt;br /&gt;
&lt;br /&gt;
The address specified is an absolute address, which is the address of the “ldr” instruction at the beginning of the block for setting the pin to high. Actually, the branch instruction “b” is not capable of jumping directly to such an absolute address - again, because a 32 bit wide address can&#039;t be encoded in a 16/32 bit wide instruction. Instead, the assembler calculates the distance of the jump target and the location of the “b” instruction, and stores it into the instruction. When jumping backwards, this distance is negative.&lt;br /&gt;
&lt;br /&gt;
When executing program code, the processor always stores the address of the currently executed instruction plus four in the r15 register, which is therefore also known as PC, the program counter. When encountering a “b” instruction, the processor adds the contained distance value to the PC value to calculate the absolute address of the jump target before jumping there.&lt;br /&gt;
&lt;br /&gt;
This means that “b” performs a relative jump, and even if the whole machine code section were moved somewhere else in memory, the code would still work. However, the assembly language syntax does not really represent this, as the assembler expects absolute addresses which it then transforms into relative ones.&lt;br /&gt;
&lt;br /&gt;
Specifying the target address directly as shown is very impractical, as it has to be calculated manually, and if the section of code is moved or modified, the address needs to be changed. To rectify this, the assembler supports labels: You can assign a name to a certain code location, and use this name to refer to the code location instead of specifying the address as a number. A label is defined by writing its name followed by a colon:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
BlinkLoop:&lt;br /&gt;
&lt;br /&gt;
ldr r1, =0x40010810&lt;br /&gt;
ldr r0, =0x100&lt;br /&gt;
str r0, [r1]			@ Set BS8 in GPIOA_BSRR to 1 to set PA8 high&lt;br /&gt;
&lt;br /&gt;
ldr r1, =0x40010810&lt;br /&gt;
ldr r0, =0x1000000&lt;br /&gt;
str r0, [r1]			@ Set BR8 in GPIOA_BSRR to 1 to set PA8 low&lt;br /&gt;
&lt;br /&gt;
b BlinkLoop&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “Blink2”&lt;br /&gt;
&lt;br /&gt;
This is purely a feature of the assembler – the generated machine code will be identical to the previous example. In “b BlinkLoop”, the assembler substitutes the label for the address it represents to calculate the relative jump distance. The assembler actually provides no direct way of directly specifying the relative offset that will be encoded in the instruction, but it can be done like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
b (.+4+42*2)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The resulting instruction will contain “42” as the jump offset. As suggested by the syntax, the processor multiples this number by 2 (since instructions can only reside at even memory addresses, it would waste one bit of memory to specify the number directly) and adds to it the address of the “b” instruction plus 4. The assembly syntax is designed to represent the end result of the operation, so the assembler reverses the peculiar pre-calculations of the processor. If you want to do this calculation yourself, you have to again undo the assembler’s own calculation with the expression shown above. There is usually no reason to do that, though.&lt;br /&gt;
&lt;br /&gt;
=== Counting Loops ===&lt;br /&gt;
The above example for a blinking LED does not really work yet – the LED blinks so fast the human eye can’t see it. The LED will just appear slightly dim. To achieve a proper blinking frequency, the code needs to be slowed down. The easiest way for that is to have the processor execute a large number of “dummy” instructions between setting the pin high and low. Simply placing many “nop” instructions isn’t possible though, as there is simply not enough program memory to store all of them. The solution is a loop that executes the same instructions a specific number of times (as opposed to the endless loops from the examples above). To do that, the processor has to count the number of loop iterations. It is actually easier to count &#039;&#039;down&#039;&#039; than up, so start by loading the desired number of iterations into a register and begin the loop by subtracting “1”:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r2, =1000000&lt;br /&gt;
subs r2, #1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now, the processor should make a decision: If the register has reached zero, terminate the loop; else, continue by again subtracting “1”. The ARM math instructions can automatically perform some tests on the result to check whether it is positive/negative or zero and whether an overflow occurred. To enable those checks, append an “s” to the instruction name – hence, “subs” instead of “sub”. The result of these checks is automatically stored in the “Application Program Status Register” (APSR) – the contained bits N, Z, C, V indicate whether the result was negative, zero, set the carry bit or caused an overflow. This register is usually not accessed directly. Instead, use the conditional variant of the “b” instruction, where two letters are appended to indicate the desired condition. The jump is only performed if the condition is met; otherwise, the instruction does nothing. The available condition codes are described in the chapter “Condition Codes” of this tutorial. The conditions are formulated in terms of the mentioned bits of the APSR. For example, the “bne” instruction only performs a jump if the zero (Z) flag is &#039;&#039;not&#039;&#039; set, i.e. when the result of the last math instruction (with an “s” appended) was &#039;&#039;not&#039;&#039; zero. The “beq” instruction is the opposite of that – it only performs a jump if the result &#039;&#039;was&#039;&#039; zero.&lt;br /&gt;
&lt;br /&gt;
So, to perform the jump back to the beginning of the loop, add a label before the “subs” instruction, and put a “bne” instruction after the “subs” that jumps to this label if the counter has not reached zero yet:&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r2, =1000000&lt;br /&gt;
delay1:&lt;br /&gt;
subs r2, #1&lt;br /&gt;
bne delay1			@ Iterate delay loop&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The actual loop consists only of the two instructions “subs” and “bne”. By placing two of those loops (with two different labels!) in between the blocks that turn the pins on and off, the blink frequency is lowered sufficiently such that it becomes visible:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.word 0x20000400&lt;br /&gt;
.word 0x080000ed&lt;br /&gt;
.space 0xe4&lt;br /&gt;
&lt;br /&gt;
ldr r1, =0x40021018&lt;br /&gt;
ldr r0, [r1]&lt;br /&gt;
orr r0, r0, #4&lt;br /&gt;
str r0, [r1]			@ Set IOPAEN bit in RCC_APB2ENR to 1 to enable GPIOA&lt;br /&gt;
&lt;br /&gt;
ldr r1, =0x40010804&lt;br /&gt;
ldr r0, [r1]&lt;br /&gt;
and r0, #0xfffffff0&lt;br /&gt;
orr r0, #2&lt;br /&gt;
str r0, [r1]			@ Set CNF8:MODE8 in GPIOA_CRH to 2&lt;br /&gt;
&lt;br /&gt;
BlinkLoop:&lt;br /&gt;
ldr r1, =0x40010810&lt;br /&gt;
ldr r0, =0x100&lt;br /&gt;
str r0, [r1]			@ Set BS8 in GPIOA_BSRR to 1 to set PA8 high&lt;br /&gt;
&lt;br /&gt;
ldr r2, =1000000&lt;br /&gt;
delay1:&lt;br /&gt;
subs r2, #1&lt;br /&gt;
bne delay1			@ Iterate delay loop&lt;br /&gt;
&lt;br /&gt;
ldr r1, =0x40010810&lt;br /&gt;
ldr r0, =0x1000000&lt;br /&gt;
str r0, [r1]			@ Set BR8 in GPIOA_BSRR to 1 to set PA8 low&lt;br /&gt;
&lt;br /&gt;
ldr r2, =1000000&lt;br /&gt;
delay2:&lt;br /&gt;
subs r2, #1&lt;br /&gt;
bne delay2			@ Iterate delay loop&lt;br /&gt;
&lt;br /&gt;
b BlinkLoop&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “BlinkDelay”&lt;br /&gt;
&lt;br /&gt;
You might notice that the registers r0-r2 are loaded with the same values over and over again. To make the code both shorter and faster, take advantage of the available processor registers, and load the values that don’t change &#039;&#039;before&#039;&#039; the loop. Then, just use them inside the loop:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.word 0x20000400&lt;br /&gt;
.word 0x080000ed&lt;br /&gt;
.space 0xe4&lt;br /&gt;
&lt;br /&gt;
ldr r1, =0x40021018&lt;br /&gt;
ldr r0, [r1]&lt;br /&gt;
orr r0, r0, #4&lt;br /&gt;
str r0, [r1]			@ Set IOPAEN bit in RCC_APB2ENR to 1 to enable GPIOA&lt;br /&gt;
&lt;br /&gt;
ldr r1, =0x40010804&lt;br /&gt;
ldr r0, [r1]&lt;br /&gt;
and r0, #0xfffffff0&lt;br /&gt;
orr r0, #2&lt;br /&gt;
str r0, [r1]			@ Set CNF8:MODE8 in GPIOA_CRH to 2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ldr r0, =0x40010810		@ Load address of GPIOA_BSRR&lt;br /&gt;
ldr r1, =0x100			@ Register value to set pin to high&lt;br /&gt;
ldr r2, =0x1000000		@ Register value to set pin to low&lt;br /&gt;
ldr r3, =1000000		@ Iterations for delay loop&lt;br /&gt;
&lt;br /&gt;
BlinkLoop:&lt;br /&gt;
str r1, [r0]			@ Set BS8 in GPIOA_BSRR to 1 to set PA8 high&lt;br /&gt;
&lt;br /&gt;
mov r4, r3&lt;br /&gt;
delay1:&lt;br /&gt;
subs r4, #1&lt;br /&gt;
bne delay1			@ Iterate delay loop&lt;br /&gt;
&lt;br /&gt;
str r2, [r0]			@ Set BR8 in GPIOA_BSRR to 1 to set PA8 low&lt;br /&gt;
&lt;br /&gt;
mov r4, r3&lt;br /&gt;
delay2:&lt;br /&gt;
subs r4, #1&lt;br /&gt;
bne delay2			@ Iterate delay loop&lt;br /&gt;
&lt;br /&gt;
b BlinkLoop&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “BlinkDelay2”&lt;br /&gt;
&lt;br /&gt;
=== Using RAM ===&lt;br /&gt;
Until now, all data in the example codes was stored in periphery or processor registers. In all but the most simple programs, larger amounts of data have to be processed for which the thirteen general-purpose processor registers aren’t enough. For this, the microcontroller features a block of SRAM that stores 20 KiB of data. Accessing data in RAM works similar to accessing periphery registers – load the address in a processor register and use “ldr” and “str” to read and write the data. After reset, the RAM contains just random ones and zeroes, so before the first read access, some value has to be stored.&lt;br /&gt;
&lt;br /&gt;
As the programmer decides what data to place where, they have to keep track which address in memory contains what piece of data. You can use the assembler to help keeping track by declaring what kind of memory blocks you need and giving them names. To do this, you must first tell the assembler that the next directives refer to data instead of instructions with the “.data” directive. Then, use the “.space” directive for each block of memory you need. To assign names to the blocks, place a label definition (using a colon) right &#039;&#039;before&#039;&#039; that. After the definitions, put a “.text” directive to make sure the instructions after that will properly go to program memory (flash):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.data&lt;br /&gt;
var1:&lt;br /&gt;
	.space 4		@ Reserve 4 bytes for memory block “var1”&lt;br /&gt;
var2:&lt;br /&gt;
	.space 1		@ Reserve 1 byte for memory block “var2”&lt;br /&gt;
&lt;br /&gt;
.text&lt;br /&gt;
@ Instructions go here...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, a data block of 4 bytes is reserved and named “var1”. Another block of 1 byte is named “var2”. Note that just inserting these lines will not modify the assembler output – these are just instructions to the assembler itself. To access these memory blocks, you can use “var1” and “var2” just like literal addresses. Load them into registers and use these with “ldr” and “str” like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.word 0x20000400&lt;br /&gt;
.word 0x080000ed&lt;br /&gt;
.space 0xe4&lt;br /&gt;
&lt;br /&gt;
.data&lt;br /&gt;
var1:&lt;br /&gt;
	.space 4		@ Reserve 4 bytes for memory block “var1”&lt;br /&gt;
var2:&lt;br /&gt;
	.space 1		@ Reserve 1 byte for memory block “var2”&lt;br /&gt;
&lt;br /&gt;
.text&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ldr r0, =var1			@ Get address of var1&lt;br /&gt;
ldr r1, =0x12345678&lt;br /&gt;
str r1, [r0]			@ Store 0x12345678 into memory block “var1”&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ldr r1, [r0]			@ Read memory block “var1”&lt;br /&gt;
and r1, #0xFF		@ Set bits 8..31 to zero&lt;br /&gt;
ldr r0, =var2			@ Get address of var2&lt;br /&gt;
strb r1, [r0]			@ Store a single byte into var2&lt;br /&gt;
&lt;br /&gt;
b .&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “RAMVariables”&lt;br /&gt;
&lt;br /&gt;
Note the use of “strb” - it works similar to “str”, but only stores a single byte. Since the processor register r1 is of course 32bit in size, only the lower 8 bits are stored, and the rest is ignored. &lt;br /&gt;
&lt;br /&gt;
There is still something missing – nowhere in the code is there any address of the RAM. To tell the linker where the RAM is located, pass the option &amp;lt;code&amp;gt;-Tdata=0x20000000&amp;lt;/code&amp;gt; to the &amp;lt;code&amp;gt;arm-none-eabi-ld&amp;lt;/code&amp;gt; call to tell the linker that this is the address of the first byte of RAM.&lt;br /&gt;
&lt;br /&gt;
If you run this program via GDB, you can use the commands &amp;lt;code&amp;gt;x/1xw &amp;amp;var1&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;x/1xb &amp;amp;var2&amp;lt;/code&amp;gt; to read the data stored in memory. After this quick introduction a more abstract overview is indicated.&lt;br /&gt;
&lt;br /&gt;
== Memory Management ==&lt;br /&gt;
If there is one thing that sets higher and lower level programming languages apart, it’s probably memory management. Assembly programmers have to think about memory, addresses, layout of program and data structures all the time. Assembler and linker provide some help which needs to be utilized effectively. Therefore, this chapter will explain some more fundamentals of the ARM architecture and how the toolchain works.&lt;br /&gt;
&lt;br /&gt;
=== Address space ===&lt;br /&gt;
In the examples so far, addresses where used for periphery register accesses and jump instructions without really explaining what they mean, so it’s time to catch up with that. To access periphery registers and memory locations in any memory type (RAM, Flash, EEPROM…), an address is required, which identifies the desired location. On most platforms, addresses are simply unsigned integers. The set of all possible addresses that can be accessed in a uniform way is called an “address space”. Some platforms such as AVR have multiple address spaces (for Flash, EEPROM, and RAM+periphery) where each memory needs to be accessed in a distinct way and the programmer needs to know which address space an address belongs to – e.g. all three memory types have a memory location with address 123.&lt;br /&gt;
&lt;br /&gt;
However, the ARM architecture uses only a single large address space where addresses are 32bit unsigned integers in the range of 0-4294967295. Each address refers to one byte of 8 bits. The address space is divided into several smaller ranges, each of which refers to a specific type of memory. For the STM32F103, this is documented in the datasheet in chapter 4. All addresses in all memory types are accessed in the same way – directly via the “ldr” and “str” instructions, or by executing code from a certain location, which can be achieved by jumping to the respective address with the “b” instruction. This also makes it possible to execute from RAM – simply perform a jump to an address that refers to some code located in RAM. Note that there are large gaps between the individual ranges in address space; attempting to access those usually leads to a crash.&lt;br /&gt;
&lt;br /&gt;
While the addresses of periphery are fixed and defined by the manufacturer, the layout of program code and data in memory can be set by the programmer rather freely. Up until now, the example programs defined the flash memory contents in a linear fashion by listing the instructions on the order they should appear in flash memory. However, when translating multiple assembly source files into one program, the order in which the contents from those files appears in the final program isn’t defined a priori. Also, even though in the last example the memory blocks for RAM were defined &#039;&#039;before&#039;&#039; the code, the code actually comes first in address space. What makes all this work is the Linker.&lt;br /&gt;
&lt;br /&gt;
=== The Linker ===&lt;br /&gt;
Usually the last step in translating source code into a usable program, the linker is an often overlooked, sometimes misunderstood but important and useful tool, if applied correctly. Many introductions into programming forego explaining its workings in detail, but as any trade, embedded development requires mastery of the tools! A good understanding of the linker can save time solving strange errors and allow you to implement some less common use cases, such as utilizing multiple RAM blocks present in some microcontrollers, executing code from RAM or defining complex memory layouts as sometimes required by RTOSes.&lt;br /&gt;
&lt;br /&gt;
[[File:ArmAsmTutorial_Linking.svg|300px|thumb|right|Translation of native applications using assembler, compiler and linker]]You have already used a linker – the command &amp;lt;code&amp;gt;arm-none-eabi-ld&amp;lt;/code&amp;gt; calls the GNU linker that is shipped with the GNU toolchain. Until now, only one assembly source files was translated for each program. To translate a larger program that consists of three assembly files “file1.S”, “file2.S” and “file3.s”, the assembler would be called three times to produce three object code files “file1.o”, “file2.o” and “file3.o”. The linker would then be called to combine all three into a single output file.&lt;br /&gt;
&lt;br /&gt;
When translating any of these assembly files, the assembler does not know of the existence of the other files. Therefore, it can’t know whether the contents of any other file will end up in flash memory before the currently processed file, and also can’t know the final location in flash memory of the machine code it is emitting and placing in the object file (ending .o). This means that the object file does not contain any absolute addresses (except for those of periphery registers, as these were specified explicitly). For example, when loading the address of the RAM data blocks (“ldr r0, =var1”) the assembler doesn’t know the address, only the linker does. Therefore, the assembler puts a placeholder in the object file that will be overwritten by the linker. A jump (“b” instruction) to a label defined in another assembly file works similarly; the assembler uses a placeholder for the address. For the jump instructions we used inside the same file (e.g. “b BlinkLoop”), a placeholder is not necessary, as the assembler can calculate the distance of the label and the instruction and generate the relative jump itself. However, if the target resides within a different section (see below), this isn’t possible, and a placeholder becomes necessary. As the contents of object files has no fixed address and can be moved around by the linker, these files are called relocatable.&lt;br /&gt;
&lt;br /&gt;
On Unix Systems (including Linux), the Executable and Linkable Format (ELF) is used for both object files and executable program files. This format is also used by ARM, and the GNU ARM toolchain. Because it was originally intended to be used with operating systems, some of its concepts don’t perfectly map the embedded use case. The object (.o) files created by the assembler and linker, and also the final program (usually no ending, but in embedded contexts and also in above example commands, .elf is used) are all in ELF format. The specification of ELF for ARM can be found [https://developer.arm.com/architectures/system-architectures/software-standards/abi here], and the generic specification for ELF on which the ARM ELF variant is based can be found [http://www.sco.com/developers/gabi/2003-12-17/contents.html here].&lt;br /&gt;
&lt;br /&gt;
ELF files are structured into sections. Each section may contain code, data, debug information (used by GDB) and other things. In an object file, the sections have no fixed address. In the final program file, they have one. Sections also have various attributes that indicate whether its contents is executable code or data, is read-only and whether memory should be allocated for it. The linker combines and reorders the sections from the object files (“input sections”) and places them into sections in the final program file (“output sections”) while assigning them absolute addresses.&lt;br /&gt;
&lt;br /&gt;
Another important aspect are symbols. A symbol defines a name for an address. The address of a symbol may be defined as an absolute number (e.g. 0x08000130) or as an offset relative to the beginning of a section (e.g. “start address of section .text plus 0x130”). Labels defined in assembly source code define symbols in the resulting object file. For example, the “var1” label defined in the last example results in a symbol “var1” in the “prog1.o” file whose address is set to be equal to the beginning of “.data”. The symbol “var” is defined similarly, but with an offset of 4. After the linking process, the “prog1.elf” file contains a “.data” section with absolute address 0x20000000, and so the “var1” and “var2” symbols get absolute addresses as well.&lt;br /&gt;
&lt;br /&gt;
As mentioned, the assembler puts placeholders in the object files when it doesn’t know the address of something. In ELF files, there placeholders are called “relocation entries” and they reference symbols by name. When the linker sees such a relocation entry in one of its input files, it searches for a symbol in the input files with a matching name and fills in its address. If no symbol with that name was found, it emits this dreaded error:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;(.text+0x132): undefined reference to `Foo&#039;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Google finds almost a million results for that message, but knowing how the linker operates makes it easy to understand and solve – since the symbol was not found in any object file, make sure it is spelled correctly and that the object file that contains it is actually fed to the linker.&lt;br /&gt;
&lt;br /&gt;
=== Linker Scripts ===&lt;br /&gt;
A linker script is a text file written in a linker-specific language that controls how the linker maps input sections to output sections. The example project hasn’t explicitly specified one yet, which lets the linker use a built-in default one. This has worked so far, but results in a slightly mixed up program file (unsuitable symbols) and has some other disadvantages. Therefore, it’s time to do things properly and write a linker script. Linker scripts aren’t usually created on a per-project basis, but usually provided by the microcontroller manufacturer to fit a certain controller’s memory layout. To learn how they work, a quick introduction into writing one will follow. The full documentation can be found [https://sourceware.org/binutils/docs/ld/Scripts.html here].&lt;br /&gt;
&lt;br /&gt;
It’s customary to name the linker script after the controller they are intended for, so create a text file “stm32f103rb.ld” or “stm32f103c8.ld” with the following contents:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
MEMORY {&lt;br /&gt;
	FLASH	: ORIGIN = 0x8000000,	LENGTH = 128K&lt;br /&gt;
	SRAM	: ORIGIN = 0x20000000,	LENGTH = 20K&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
SECTIONS {&lt;br /&gt;
	.text : {&lt;br /&gt;
		*(.text)&lt;br /&gt;
	} &amp;gt;FLASH&lt;br /&gt;
	&lt;br /&gt;
	.data (NOLOAD) : {&lt;br /&gt;
		*(.data)&lt;br /&gt;
	} &amp;gt;SRAM&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “LinkerScriptSimple”&lt;br /&gt;
&lt;br /&gt;
This is this minimum viable linker script for a microcontroller. If you are using a STM32F103C8, replace the 128K by 64K. The lines inside the “MEMORY” block define the available memory regions on your microcontroller by specifying their start address and size within the address space. The names “FLASH” and “SRAM” can be chosen arbitrarily, as they have no special meaning. This memory definition has no meaning outside of the linker script, as it is just an internal helper for writing the script; it can even be left out and replaced by some manual address calculations.&lt;br /&gt;
&lt;br /&gt;
The interesting part happens inside the “SECTIONS” command. Each sub-entry defines an output section that will end up in the final program file. These can be named arbitrarily, but the names “.text” and “.data” for executable code and data storage respectively are usually used. The asterisk expressions “*(.text)” and “(*.data)” tell the linker to put the contents of the input sections “.text” and “.data” at that place in the output section. In this case, the names for the input sections and output sections are identical. The input section names “.data”, “.text” (and some more) are used by the assembler and C and C++ compilers by default, so even though they can be changed, it’s best to keep them. You can however name the output sections arbitrarily, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
SECTIONS {&lt;br /&gt;
	.FlashText : {&lt;br /&gt;
		*(.text)&lt;br /&gt;
	} &amp;gt;FLASH&lt;br /&gt;
	&lt;br /&gt;
	.RamData (NOLOAD) : {&lt;br /&gt;
		*(.data)&lt;br /&gt;
	} &amp;gt;SRAM&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The commands “&amp;gt;FLASH” and “&amp;gt;SRAM” tell the linker to calculate the address of the output sections according to the respective memory declaration above: The first output section with a “&amp;gt;FLASH” command will end up at address 0x8000000, the next with “&amp;gt;FLASH” right after that section and so on. The “&amp;gt;SRAM” works the same way with the start address “0x20000000”. The “NOLOAD” attribute does not change the linker’s behavior, but marks the corresponding output section as “not-loadable”, such that OpenOCD and GDB will not attempt to write it into RAM – the program has to take care of initializing any RAM data anyways when running stand-alone.&lt;br /&gt;
&lt;br /&gt;
To specify the filename of the linker script, use the “-T” option:&lt;br /&gt;
&amp;lt;source lang=sh&amp;gt;&lt;br /&gt;
arm-none-eabi-ld prog1.o -o prog1.elf -T stm32f103rb.ld&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
The &amp;lt;code&amp;gt;-Tdata&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;-Ttext&amp;lt;/code&amp;gt; aren’t needed anymore, as the addresses are now defined in the linker script.&lt;br /&gt;
&lt;br /&gt;
Since the linker script defines the sizes of the memory regions, the linker can now warn you when your program consumes too much memory (either flash or RAM):&lt;br /&gt;
&amp;lt;pre&amp;gt;arm-none-eabi-ld: prog1.elf section `.text&#039; will not fit in region `FLASH&#039;&lt;br /&gt;
arm-none-eabi-ld: region `FLASH&#039; overflowed by 69244 bytes&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Reserving memory blocks ====&lt;br /&gt;
Using the processor’s stack will be explained later, but you can already use the linker script to assign a memory block for it. It’s best to allocate memory for the stack at the &#039;&#039;beginning&#039;&#039; of SRAM, so put this before the “*(.data)” command:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;. = . + 0x400;&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inside a linker script, the dot “.” refers to the current address in the output file; therefore, this command increments the address by 0x400, leaving an “empty” block of that size. The “.data” input section will be located after that, at address 0x20000400.&lt;br /&gt;
&lt;br /&gt;
==== Defining symbols in linker scripts ====&lt;br /&gt;
&lt;br /&gt;
As mentioned before, the controller requires a certain data structure called the “vector table” to reside at the very beginning of flash memory. It is defined in the assembler source file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.word 0x20000400&lt;br /&gt;
.word 0x080000ed&lt;br /&gt;
.space 0xe4&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The “.word” directive tells the assembler to output the given 32bit-number. Just like processor instructions, these numbers are put into the current section (.text by default, .data if specified) and therefore end up in flash memory. The first 32bit-number, which occupies the first 4 bytes in flash memory, is the initial value of the stack pointer which will be explained later. This number should be equal to the address of the first byte &#039;&#039;after&#039;&#039; the memory block that was reserved for the stack. The reserved block starts at address 0x20000000 and has size 0x400, so the correct number is 0x20000400. However, if the size of the reserved block was modified in the linker script, the above assembly line needs to be adjusted as well. To avoid any inconsistencies, and to be able to manage everything related to the memory-layout centrally in the linker script, it is desirable to replace the number in the assembly source file with a symbol expression. To do this, define a symbol in the linker script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
.data (NOLOAD) : {&lt;br /&gt;
	. = . + 0x400;&lt;br /&gt;
	_StackEnd = .;&lt;br /&gt;
	*(.data)&lt;br /&gt;
} &amp;gt;SRAM&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “LinkerScriptSymbols”&lt;br /&gt;
&lt;br /&gt;
This will define a symbol “_StackEnd” to have the value of “.”, which is the current address, which at this point is 0x20000400. In the assembly source file, you can now replace the number with the symbol:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.word _StackEnd&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The assembler will put a placeholder in the object file, which the linker will overwrite with the value of 0x20000400. This modification will not change the output file, but avoids putting absolute addresses in source files. The name “_StackEnd” was chosen arbitrarily; since names that start with an underscore and a capital letter may not be used in C and C++ programs, there is no possibility of conflict if any C/C++ source is added later. Typically, all symbols that are part of the runtime environment and should be “invisible” to C/C++ code are named this way. The same rule applies to names starting with two underscores.&lt;br /&gt;
&lt;br /&gt;
The second entry of the vector table is the address of the very first instruction to be executed after reset. Currently the address is hard-coded as the first address after the vector table. If you wanted to insert some other code before this first instruction, this number would have to be changed. This is obviously impractical, and therefore the number should be replaced by a label as well. Since the code executed at reset is commonly known as the “reset handler”, define it like that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.word _StackEnd&lt;br /&gt;
.word Reset_Handler&lt;br /&gt;
.space 0xe4&lt;br /&gt;
&lt;br /&gt;
.type Reset_Handler, %function&lt;br /&gt;
Reset_Handler:&lt;br /&gt;
&lt;br /&gt;
@ Put code here&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The “.type” directive tells the assembler that the label refers to executable code. The exact meaning of this will be covered later. Leave the “.space” directive alone for now.&lt;br /&gt;
&lt;br /&gt;
==== Absolute section placement ====&lt;br /&gt;
The vector table needs to be at the beginning of flash memory, and the examples have relied on the assembler putting the first things from the source file into flash memory first. This stops working if you use multiple source files. You can use the linker script to make sure the vector table is always at the beginning of flash memory. To do that, you first have to separate the vector table from the rest of the code so that the linker can handle it specially. This is done by placing the vector table in its own section:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.section .VectorTable, &amp;quot;a&amp;quot;&lt;br /&gt;
.word _StackEnd&lt;br /&gt;
.word Reset_Handler&lt;br /&gt;
.space 0xe4&lt;br /&gt;
&lt;br /&gt;
.text&lt;br /&gt;
.type Reset_Handler, %function&lt;br /&gt;
Reset_Handler:&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “LinkerScriptAbsolutePlacement”&lt;br /&gt;
&lt;br /&gt;
The “.section” directive instructs the assembler to put the following data into the custom section “.VectorTable”. The “a” flag marks this section as allocable, which is required to have the linker allocate memory for it. To place the vector table at the beginning of flash memory, define a new output section in the linker script:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
MEMORY {&lt;br /&gt;
	FLASH	: ORIGIN = 0x8000000,	LENGTH = 128K&lt;br /&gt;
	SRAM	: ORIGIN = 0x20000000,	LENGTH =  20K&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
SECTIONS {&lt;br /&gt;
	.VectorTable : {&lt;br /&gt;
		*(.VectorTable)&lt;br /&gt;
	} &amp;gt;FLASH&lt;br /&gt;
	&lt;br /&gt;
	.text : {&lt;br /&gt;
		*(.text)&lt;br /&gt;
	} &amp;gt;FLASH&lt;br /&gt;
	&lt;br /&gt;
	.data (NOLOAD) : {&lt;br /&gt;
		. = . + 0x400;&lt;br /&gt;
		_StackEnd = .;&lt;br /&gt;
		*(.data)&lt;br /&gt;
	} &amp;gt;SRAM&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This puts the .VectorTable input section into the equally-named output section. It is also possible to put it into .text alongside the code:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
MEMORY {&lt;br /&gt;
	FLASH	: ORIGIN = 0x8000000,	LENGTH = 128K&lt;br /&gt;
	SRAM	: ORIGIN = 0x20000000,	LENGTH =  20K&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
SECTIONS {&lt;br /&gt;
	.text : {&lt;br /&gt;
		*(.VectorTable)&lt;br /&gt;
		*(.text)&lt;br /&gt;
	} &amp;gt;FLASH&lt;br /&gt;
	&lt;br /&gt;
	.data (NOLOAD) : {&lt;br /&gt;
		. = . + 0x400;&lt;br /&gt;
		_StackEnd = .;&lt;br /&gt;
		*(.data)&lt;br /&gt;
	} &amp;gt;SRAM&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Even though both variants produce the same flash image, the first one is slightly nicer to work with in GDB. The modified LED-blinker application now looks like:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.section .VectorTable, &amp;quot;a&amp;quot;&lt;br /&gt;
.word _StackEnd&lt;br /&gt;
.word Reset_Handler&lt;br /&gt;
.space 0xe4&lt;br /&gt;
&lt;br /&gt;
.text&lt;br /&gt;
.type Reset_Handler, %function&lt;br /&gt;
Reset_Handler:&lt;br /&gt;
&lt;br /&gt;
ldr r1, =0x40021018&lt;br /&gt;
ldr r0, [r1]&lt;br /&gt;
orr r0, r0, #4&lt;br /&gt;
str r0, [r1]			@ Set IOPAEN bit in RCC_APB2ENR to 1 to enable GPIOA&lt;br /&gt;
&lt;br /&gt;
ldr r1, =0x40010804&lt;br /&gt;
ldr r0, [r1]&lt;br /&gt;
and r0, #0xfffffff0&lt;br /&gt;
orr r0, #2&lt;br /&gt;
str r0, [r1]			@ Set CNF8:MODE8 in GPIOA_CRH to 2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ldr r0, =0x40010810		@ Load address of GPIOA_BSRR&lt;br /&gt;
ldr r1, =0x100			@ Register value to set pin to high&lt;br /&gt;
ldr r2, =0x1000000		@ Register value to set pin to low&lt;br /&gt;
ldr r3, =1000000		@ Iterations for delay loop&lt;br /&gt;
&lt;br /&gt;
BlinkLoop:&lt;br /&gt;
str r1, [r0]			@ Set BS8 in GPIOA_BSRR to 1 to set PA8 high&lt;br /&gt;
&lt;br /&gt;
mov r4, r3&lt;br /&gt;
delay1:&lt;br /&gt;
subs r4, #1&lt;br /&gt;
bne delay1			@ Iterate delay loop&lt;br /&gt;
&lt;br /&gt;
str r2, [r0]			@ Set BR8 in GPIOA_BSRR to 1 to set PA8 low&lt;br /&gt;
&lt;br /&gt;
mov r4, r3&lt;br /&gt;
delay2:&lt;br /&gt;
subs r4, #1&lt;br /&gt;
bne delay2			@ Iterate delay loop&lt;br /&gt;
&lt;br /&gt;
b BlinkLoop&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Program Structure ===&lt;br /&gt;
Because the vector table is usually the same for all projects, it is handy to move it into a separate file, for example called “vectortable.S”:&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.section .VectorTable, &amp;quot;a&amp;quot;&lt;br /&gt;
.word _StackEnd&lt;br /&gt;
.word Reset_Handler&lt;br /&gt;
.space 0xe4&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Assemble and link this source code with two assembler commands:&lt;br /&gt;
&amp;lt;source lang=sh&amp;gt;&lt;br /&gt;
arm-none-eabi-as -g prog1.S -o prog1.o&lt;br /&gt;
arm-none-eabi-as -g vectortable.S -o vectortable.o&lt;br /&gt;
arm-none-eabi-ld prog1.o vectortable.o -o prog1.elf -T stm32f103rb.ld&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will result in the dreaded “undefined reference” error. To alleviate this, use the “.global” directive in the main source file “prog1.S”:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.type Reset_Handler, %function&lt;br /&gt;
.global Reset_Handler&lt;br /&gt;
Reset_Handler:&lt;br /&gt;
@ Code here ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will tell the assembler to make the symbol “Reset_Handler” visible globally, such that it can be used from other files. By default, the assembler creates a &#039;&#039;local&#039;&#039; symbol for each label, which can’t be used from other source files (same as &#039;&#039;static&#039;&#039; in C). The symbol is still there in the final program file, though - it can be used for debugging purposes.&lt;br /&gt;
&lt;br /&gt;
== More assembly techniques ==&lt;br /&gt;
After having set up the project for using the linker properly, some more aspects of assembly programming will be introduced.&lt;br /&gt;
&lt;br /&gt;
=== Instruction set state ===&lt;br /&gt;
As mentioned before, ARM application processors support both the T32 and A32/A64 “ARM” instruction sets, and are capable of dynamically switching between them. This can be used to encode time-critical program parts in the faster A32/64 instruction set, and less critical parts in the T32 “thumb” instruction set to save memory. Actually, reducing program size may improve performance too, because the cache memories may become more effective.&lt;br /&gt;
&lt;br /&gt;
Even though the Cortex-M microcontrollers based on the ARMv7-M architecture do not support the A32/A64 instruction sets, some of the switching-logic is still there, requiring the program code to work accordingly. The switch between the instruction sets happens when jumping with the “bx” “Branch and Exchange” and “blx” “Branch with Link and Exchange” instructions. Since all instructions are of size 2 or 4, and code may only be stored at even addresses, the lowest bit of the address of any instruction is always zero. When performing a jump with “bx” or “blx”, the lowest bit of the target address is used to indicate the instruction set of the jump target: If the bit is “1”, the processor expects the code to be T32, else A32.&lt;br /&gt;
&lt;br /&gt;
Another specialty of the “bx” and “blx” instructions is that they take the jump target address from a register instead as encoding it in the instruction directly. This called an indirect jump. An example of such a jump is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r0, =SomeLabel&lt;br /&gt;
bx r0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Such indirect jumps are necessary if the difference of the jump target address and the jump instruction is too large to be encoded in the instruction itself for a relative jump. Also, sometimes you want to jump to an address that has been passed from another part of the program, which e.g. happens in C/C++ code when using function pointers or virtual functions.&lt;br /&gt;
&lt;br /&gt;
In these cases, you need to make sure that the lowest bit of the address passed to “bx/blx” via a register has the lowest bit set, to indicate that the target code is T32. Otherwise, the code will crash. This can be achieved by telling the assembler that the target label refers to code (and not data) via the already mentioned “.type” directive:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.type SomeLabel, %function&lt;br /&gt;
SomeLabel:&lt;br /&gt;
@ Some code...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
That way, when you refer to the label to load its address into a register, the lowest bit will be set. Actually, using “.type” for all code labels is a good idea, even though it does not matter if you only refer to a label via the “b” instruction (including the conditional variant) which does not encode the lowest bit and does not attempt to perform an instruction set switch.&lt;br /&gt;
&lt;br /&gt;
As was already shown, there is another case where the lowest bit matters: when specifying the address of the reset handler (and later, exception handler functions) in the vector table, the bit must be set, so the “.type” directive is necessary here too:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.type Reset_Handler, %function&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you were writing code for a Cortex-A processor, you would use “.arm” instead of “.thumb” to have your code (or performance critical parts of it) encoded as A32. The “.type” directive would be used as well, and the assembler would clear the lowest bit in the address to ensure the code is executed as A32. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.cpu cortex-a8&lt;br /&gt;
.syntax unified&lt;br /&gt;
&lt;br /&gt;
@ Small but slower code here&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.type Block1, %function&lt;br /&gt;
Block1:&lt;br /&gt;
ldr r0, =Block2&lt;br /&gt;
bx r0&lt;br /&gt;
&lt;br /&gt;
@ Larger but faster code here&lt;br /&gt;
.arm&lt;br /&gt;
&lt;br /&gt;
.type Block2, %function&lt;br /&gt;
Block2:&lt;br /&gt;
@ ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The directive “.code 32” has the same meaning as “.arm”, and “.code 16” the same as “.thumb” (although the name is slightly misleading, as T32 instructions can be 32 bit as well). There is also “.type Label, %object” to declare some label refers to data in flash or RAM; this is optional, but helps in working with analysis tools (see below).&lt;br /&gt;
&lt;br /&gt;
=== Constants ===&lt;br /&gt;
The previous examples contain a lot of numbers (esp. addresses), the meaning of which is not obvious to the reader - so called “magic numbers”. As code is typically read many times more than written/modified, readability is important, even for assembly code. Therefore, it is common practice to define constants that assign names to numbers such as addresses, and use names instead of the number directly.&lt;br /&gt;
&lt;br /&gt;
The assembler actually does not provide any dedicated mechanism for defining constants. Instead, symbols as introduced before are used. You can define a symbol in any of the following ways:&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
RCC_APB2ENR = 0x40021018&lt;br /&gt;
.set GPIOA_CRH, 0x40010804&lt;br /&gt;
.equ GPIOA_ODR, 0x4001080C&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
and then use it in place of the number:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r1, =RCC_APB2ENR&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Replacing (almost) all numbers in the source code for the LED blinker by constants yields a source code like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
RCC_APB2ENR = 0x40021018&lt;br /&gt;
RCC_APB2ENR_IOPAEN = 4&lt;br /&gt;
GPIOA_CRH = 0x40010804&lt;br /&gt;
&lt;br /&gt;
GPIOA_BSRR = 0x40010810&lt;br /&gt;
GPIOx_BSRR_BS8 = 0x100&lt;br /&gt;
GPIOx_BSRR_BR8 = 0x1000000&lt;br /&gt;
&lt;br /&gt;
GPIOx_CRx_GP_PP_10MHz = 1&lt;br /&gt;
GPIOx_CRx_GP_PP_2MHz = 2&lt;br /&gt;
GPIOx_CRx_GP_PP_50MHz = 3&lt;br /&gt;
&lt;br /&gt;
GPIOx_CRx_GP_OD_10MHz = 1|4&lt;br /&gt;
GPIOx_CRx_GP_OD_2MHz = 2|4&lt;br /&gt;
GPIOx_CRx_GP_OD_50MHz = 3|4&lt;br /&gt;
&lt;br /&gt;
GPIOx_CRx_AF_PP_10MHz = 1|8&lt;br /&gt;
GPIOx_CRx_AF_PP_2MHz = 2|8&lt;br /&gt;
GPIOx_CRx_AF_PP_50MHz = 3|8&lt;br /&gt;
&lt;br /&gt;
GPIOx_CRx_AF_OD_10MHz = 1|4|8&lt;br /&gt;
GPIOx_CRx_AF_OD_2MHz = 2|4|8&lt;br /&gt;
GPIOx_CRx_AF_OD_50MHz = 3|4|8&lt;br /&gt;
&lt;br /&gt;
GPIOx_CRx_IN_ANLG = 0&lt;br /&gt;
GPIOx_CRx_IN_FLOAT = 4&lt;br /&gt;
GPIOx_CRx_IN_PULL = 8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
DelayLoopIterations = 1000000&lt;br /&gt;
&lt;br /&gt;
.text&lt;br /&gt;
.type Reset_Handler, %function&lt;br /&gt;
.global Reset_Handler&lt;br /&gt;
Reset_Handler:&lt;br /&gt;
&lt;br /&gt;
ldr r1, =RCC_APB2ENR&lt;br /&gt;
ldr r0, [r1]&lt;br /&gt;
orr r0, r0, #RCC_APB2ENR_IOPAEN&lt;br /&gt;
str r0, [r1]        	@ Set IOPAEN bit in RCC_APB2ENR to 1 to enable GPIOA&lt;br /&gt;
&lt;br /&gt;
ldr r1, =GPIOA_CRH&lt;br /&gt;
ldr r0, [r1]&lt;br /&gt;
and r0, #0xfffffff0&lt;br /&gt;
orr r0, #GPIOx_CRx_GP_PP_2MHz&lt;br /&gt;
str r0, [r1]        	@ Set CNF8:MODE8 in GPIOA_CRH to 2&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
ldr r0, =GPIOA_BSRR    	@ Load address of GPIOA_BSRR&lt;br /&gt;
ldr r1, =GPIOx_BSRR_BS8        	@ Register value to set pin to high&lt;br /&gt;
ldr r2, =GPIOx_BSRR_BR8    	@ Register value to set pin to low&lt;br /&gt;
ldr r3, =DelayLoopIterations    	@ Iterations for delay loop&lt;br /&gt;
&lt;br /&gt;
BlinkLoop:&lt;br /&gt;
str r1, [r0]        	@ Set BS8 in GPIOA_BSRR to 1 to set PA8 high&lt;br /&gt;
&lt;br /&gt;
mov r4, r3&lt;br /&gt;
delay1:&lt;br /&gt;
subs r4, #1&lt;br /&gt;
bne delay1        	@ Iterate delay loop&lt;br /&gt;
&lt;br /&gt;
str r2, [r0]        	@ Set BR8 in GPIOA_BSRR to 1 to set PA8 low&lt;br /&gt;
&lt;br /&gt;
mov r4, r3&lt;br /&gt;
delay2:&lt;br /&gt;
subs r4, #1&lt;br /&gt;
bne delay2        	@ Iterate delay loop&lt;br /&gt;
&lt;br /&gt;
b BlinkLoop&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “BlinkConstants”&lt;br /&gt;
&lt;br /&gt;
This is much more readable than before. In fact, you could even leave out the comments, as the code becomes more self-documenting. The addresses of periphery registers are defined individually, but the bits for the GPIO registers are the same for each GPIO module, so the names include an “x” to denote that they apply to all GPIO modules.&lt;br /&gt;
&lt;br /&gt;
The “CRL”/“CRH” registers get a special treatment. Since the individual bits have little direct meaning, it would be pointless to name them. Instead, 15 symbols are defined to denote the 15 possible modes of operation per pin (combinations of input/output, open-drain vs. push-pull, analog vs. digital, floating vs. pull-resistors, and output driver slew rate). Each of the 15 symbols has a 4 bit value that needs to be written into the appropriate 4 bits of the register. To configure e.g. PA10 as General Purpose Open-Drain with 10 MHz slew rate:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r1, =GPIOA_CRH&lt;br /&gt;
ldr r0, [r1]&lt;br /&gt;
and r0, #0xfffff0ff&lt;br /&gt;
orr r0, #(GPIOx_CRx_GP_OD_10MHz&amp;lt;&amp;lt;8)&lt;br /&gt;
str r0, [r1]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
C-like arithmetic operators can be used in constant expressions, like + - * / and bitwise operators like | (or), &amp;amp; (and), &amp;lt;&amp;lt; (left shift) and &amp;gt;&amp;gt; (right shift). Note that these calculations are always done by the assembler. In the example, or | is used to combine bit values.&lt;br /&gt;
&lt;br /&gt;
Since these constants are actually symbols, they can collide with assembler labels, so you must not define a symbol with the same name as any label.&lt;br /&gt;
&lt;br /&gt;
A different kind of constants are register aliases. Using the “.req” directive, you can define a name for a processor register:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
MyData .req r7&lt;br /&gt;
ldr MyData, =123&lt;br /&gt;
add MyData, 3&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be useful for large assembly blocks where the meaning of register data is not obvious. It also allows you to re-assign registers without having to modify many lines of code.&lt;br /&gt;
=== The Stack ===&lt;br /&gt;
In computer science, a stack is a dynamic data structure where data can be added and removed flexibly. Like a stack of books, the last element that was put on top must be taken and removed first (LIFO-structure - Last In, First Out). Adding an element is usually called “push”, and reading &amp;amp; removing “pop”.&lt;br /&gt;
&lt;br /&gt;
Many processor architectures including ARM feature circuitry to deal with such a structure efficiently. Like most others, ARM does not provide a dedicated memory area for this - it just facilitates using an area that the programmer reserved for this purpose as a stack. Therefore, a part of the SRAM needs to be reserved for the stack.&lt;br /&gt;
&lt;br /&gt;
On ARM, the program stores processor registers on the stack, i.e. 32bit per element. The stack is commonly used when the contents of some register will be needed again later after it has been overwritten by some complex operation that needs many registers. These accesses always come in pairs:&lt;br /&gt;
&lt;br /&gt;
* Some operation that writes to r0&lt;br /&gt;
* &#039;&#039;&#039;Push&#039;&#039;&#039; (save) r0 to the stack&lt;br /&gt;
* Some operation that overwrites r0&lt;br /&gt;
* &#039;&#039;&#039;Pop&#039;&#039;&#039; (restore) r0 from the stack&lt;br /&gt;
* Use the value in r0 which is the same as initially assigned&lt;br /&gt;
&lt;br /&gt;
ARM’s instructions for accessing the stack are unsurprisingly called “push” and “pop”. They can save/restore any of the registers r0-r12 and r14, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r0, =1000000&lt;br /&gt;
@ Use r0 ...&lt;br /&gt;
push { r0 }	@ Save value 1000000&lt;br /&gt;
&lt;br /&gt;
@ … Some code that overwrites r0 …&lt;br /&gt;
&lt;br /&gt;
pop { r0 }	@ Restore value 1000000&lt;br /&gt;
@ Continue using r0 ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It is also possible to save/restore multiple registers in one go:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r0, =1000000&lt;br /&gt;
ldr r1, =1234567&lt;br /&gt;
@ Use r0 and r1 ...&lt;br /&gt;
push { r0, r1 }	@ Save values 1000000 and 1234567&lt;br /&gt;
&lt;br /&gt;
@ … Some code that overwrites r0 and r1 …&lt;br /&gt;
&lt;br /&gt;
pop { r0, r2 }	@ Restore 1000000 into r0 and 1234567 into r2&lt;br /&gt;
@ Continue using r0 and r2...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
It does not matter to which register the data is read back - in the previous example, the value that was held in r1 is restored into r2. In larger applications, many store-restore pairs will be nested:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r0, =1000000&lt;br /&gt;
@ Use r0 ...&lt;br /&gt;
push { r0 }	@ Save value 1000000&lt;br /&gt;
&lt;br /&gt;
@ Inner Code Block:&lt;br /&gt;
&lt;br /&gt;
ldr r0, =123&lt;br /&gt;
@ Use r0 …&lt;br /&gt;
&lt;br /&gt;
push { r0 }	@ Save value 123&lt;br /&gt;
&lt;br /&gt;
@ Inner-Inner Code Block that overwrites r0&lt;br /&gt;
&lt;br /&gt;
pop { r0 }	@ Restore value 123&lt;br /&gt;
@ Continue using r0 ...&lt;br /&gt;
&lt;br /&gt;
pop { r0 }	@ Restore value 1000000 into r0&lt;br /&gt;
&lt;br /&gt;
@ Continue using r0 …&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The “inner” push-pop pair works with value 123, and the “outer” push-pop pair works with value 1000000.  Assuming that the stack was empty at the beginning, it will contain 1000000 after the first “push”, and both 1000000 and 123 after the second push. After the first “pop” it contains only 1000000 again, and is empty after the second “pop”.&lt;br /&gt;
&lt;br /&gt;
At the beginning of a push-pop pair, the current contents of the stack is irrelevant - it may be empty or contain many elements. After the “pop”, the stack will be restored to its previous state. This makes it possible to (almost) arbitrarily nest push-pop-pairs - after any inner push-pop-pair has completed, the stack is in the same state as before entering the inner pair, so the “pop” part of the outer pair doesn’t even notice the stack was manipulated in between. This is why it is important to make sure that each “push” has a matching “pop”, and vice-versa.&lt;br /&gt;
&lt;br /&gt;
As mentioned, an area of memory has to be reserved for the stack. Access to the stack memory is managed via the stack pointer (SP). The stack pointer resides in the processor register r13, and “sp” is an alias for that. As the name implies, the stack pointer contains a 32bit memory address - specifically, the address of the first byte in the stack that contains any saved data.&lt;br /&gt;
&lt;br /&gt;
When storing a 32bit register value using “push”, the stack pointer is &#039;&#039;&#039;first&#039;&#039;&#039; decremented by 4 before the value is written at the newly calculated address. To restore a value, the address currently stored in the stack pointer is read from memory, after which the stack pointer is incremented by 4. This is called a “full-descending” stack (see the ARM Architecture Reference Manual, chapter B1.5.6). On ARMv7-A (Cortex-A), this behaviour can be changed, but on ARMv7-M, it is dictated by the exception handling logic, which will be explained later.&lt;br /&gt;
&lt;br /&gt;
An implication of this is that if the stack is empty, the stack pointer contains the address of the first byte &#039;&#039;&#039;after&#039;&#039;&#039; the stack memory area. If the stack is completely full, it contains the address of the very first byte &#039;&#039;&#039;inside&#039;&#039;&#039; the stack memory area. This means that the stack grows &#039;&#039;&#039;downward&#039;&#039;&#039;. Since the stack is empty at program start, the stack pointer therefore needs to be initialized to the first address after the memory area. Before executing the first instruction, the processor loads the first 4 bytes from the flash into the stack pointer. This is why “_StackEnd” was defined and used to place the address of the first byte after the stack memory region into the first 4 bytes of flash.&lt;br /&gt;
&lt;br /&gt;
The stack pointer must always be a multiple of 4 (see chapter B5.1.3 in the ARM Architecture Reference Manual). It is a common error (which is even present in the example projects by ST!) to initialize the stack pointer to the last address &#039;&#039;inside&#039;&#039; the stack memory area (e.g. 0x200003FF instead of 0x20000400), which is not divisible by four. This can cause the application to crash or “just” slow it down. Actually, the [http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka4127.html ARM ABI requires] the stack pointer to be a multiple of 8 for public software interfaces, which is important for e.g. the “printf” C function. So, when calling any external code, make sure the stack pointer is a multiple of 8.&lt;br /&gt;
&lt;br /&gt;
In the previous examples, the stack memory area was defined with a size of 0x400, i.e. 1KiB. Choosing an appropriate stack size is critical for an application; if it is too small, the application will crash, if it is too large, memory is wasted that could be used otherwise. Traditionally, the stack is configured to reside at the &#039;&#039;end&#039;&#039; of available memory, e.g. 0x20005000 for the STM32F103. As the linker starts allocating memory for data (using “.data” in assembly or global/static variables in C) at the beginning of the memory, the stack is as far away from that regular data as possible, minimizing the chance of a collision. However, if the stack grows continuously, the stack pointer might end up pointing into the regular data area (“.data” or C globals) or heap memory (used by “malloc” in C). In that case, writing to the stack silently overwrites some of the regular data. This can result in all kinds of hard to find errors. Therefore, the example codes put the stack area at the &#039;&#039;beginning&#039;&#039; of RAM, and the regular data after that - if the stack grows too large, the stack pointer will reach values below 0x20000000, and any access will result in an immediate “clean” crash. It is probably easy to find the code location that allocates too much stack memory, and possibly increase the stack size. Using the Cortex-M3’s memory protection unit (MPU) enables even more sophisticated strategies, but that is out of scope for this tutorial.&lt;br /&gt;
=== Function calls ===&lt;br /&gt;
Many programming languages feature a “function” concept. Also known as a “procedures” or “subprograms”, functions are the most basic building blocks of larger applications, and applying them correctly is key for clean, reusable code. The assembler does not know about functions directly, so you have to build them yourself. A function is a block of code (i.e. a sequence of instructions) that you can jump to, does some work, and then jumps back to the place from which the first jump originated. This ability to jump back is the main difference from any other block of assembly code. To make this explicit, such a jump to a function is known as a “call” (as in “calling a function”). The location in code that starts the jump to the function is known as the “caller”, and the called function as “callee”. From the perspective of the caller, calling a function resembles a “user-defined” instruction - it performs some operation after which the code of the caller continues as before. To make the jump back possible, the address of the &#039;&#039;next&#039;&#039; instruction after the one that started the function call needs to be saved, so that the function can jump back to that location (without calling the function directly again).&lt;br /&gt;
&lt;br /&gt;
This is done via the Link Register (LR), which is the processor register r14. Function calls are performed with the “bl” instruction. This instruction performs a jump, much like the well-known “b”, but also saves the address of the next instruction in LR. When the function is finished, it returns to the caller by jumping to the address stored in LR. As already mentioned, jumping to a location from a register is called an indirect jump, which is performed by the “bx” instruction. So, to return from a function, use “bx lr”:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.text&lt;br /&gt;
.type Reset_Handler, %function&lt;br /&gt;
.global Reset_Handler&lt;br /&gt;
Reset_Handler:&lt;br /&gt;
&lt;br /&gt;
bl EnableClockGPIOA		@ Call function to enable GPIOA&#039;s peripheral clock&lt;br /&gt;
&lt;br /&gt;
@ Some more code ...&lt;br /&gt;
ldr r1, =GPIOA_CRH&lt;br /&gt;
ldr r0, [r1]&lt;br /&gt;
and r0, #0xfffffff0&lt;br /&gt;
orr r0, #GPIOx_CRx_GP_PP_2MHz&lt;br /&gt;
str r0, [r1]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.type EnableClockGPIOA, %function&lt;br /&gt;
EnableClockGPIOA:&lt;br /&gt;
	ldr r1, =RCC_APB2ENR&lt;br /&gt;
	ldr r0, [r1]&lt;br /&gt;
	orr r0, r0, #RCC_APB2ENR_IOPAEN&lt;br /&gt;
	str r0, [r1]	@ Set IOPAEN bit in RCC_APB2ENR to 1 to enable GPIOA&lt;br /&gt;
	bx lr	@ Return to caller&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, the code to enable the clock for GPIOA was packaged into a function. To enable this clock, only a single line is now required - “bl EnableClockGPIOA”.&lt;br /&gt;
&lt;br /&gt;
When calling a function, the “bl” instruction automatically makes sure to set the lowest bit in LR such that the subsequent “bx lr” will not crash because of an attempted instruction set switch, which is not possible on Cortex-M. If you need to call a function indirectly, use “blx” with a register, and remember to ensure that the lowest bit is set, typically via “.type YourFunction, %function”. Usually, all the code of an application resides within functions, with the possible exception of the Reset_Handler. The order in which functions are defined in the source files does not matter, as the linker will always automatically fill in the correct addresses. If you want to put functions in separate source files, remember to use “.global FunctionName” to make sure the symbol is visible to other files.&lt;br /&gt;
==== Using the stack for functions ====&lt;br /&gt;
In large applications it is common for functions to call other functions in a deeply nested fashion. However, a function implemented as shown can’t do that - using “bl” would overwrite the LR, and so the return address of the outer function would be lost, and that function couldn’t ever return. The solution is to use the stack: At the beginning of a function that calls other functions, use “push” to save the LR, and at the end use “pop” to restore it. For example, the blink program could be restructured like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
RCC_APB2ENR = 0x40021018&lt;br /&gt;
RCC_APB2ENR_IOPAEN = 4&lt;br /&gt;
GPIOA_CRH = 0x40010804&lt;br /&gt;
&lt;br /&gt;
GPIOA_BSRR = 0x40010810&lt;br /&gt;
GPIOx_BSRR_BS8 = 0x100&lt;br /&gt;
GPIOx_BSRR_BR8 = 0x1000000&lt;br /&gt;
&lt;br /&gt;
GPIOx_CRx_GP_PP_2MHz = 2&lt;br /&gt;
&lt;br /&gt;
DelayLoopIterations = 1000000&lt;br /&gt;
&lt;br /&gt;
.text&lt;br /&gt;
.type Reset_Handler, %function&lt;br /&gt;
.global Reset_Handler&lt;br /&gt;
Reset_Handler:&lt;br /&gt;
	bl EnableClockGPIOA&lt;br /&gt;
	bl ConfigurePA8&lt;br /&gt;
	ldr r5, =5						@ Number of LED flashes.&lt;br /&gt;
	bl Blink&lt;br /&gt;
	b .&lt;br /&gt;
&lt;br /&gt;
.type Blink, %function&lt;br /&gt;
Blink:&lt;br /&gt;
	push { lr }&lt;br /&gt;
	ldr r0, =GPIOA_BSRR				@ Load address of GPIOA_BSRR&lt;br /&gt;
	ldr r1, =GPIOx_BSRR_BS8			@ Register value to set pin to high&lt;br /&gt;
	ldr r2, =GPIOx_BSRR_BR8			@ Register value to set pin to low&lt;br /&gt;
	ldr r3, =DelayLoopIterations	@ Iterations for delay loop&lt;br /&gt;
&lt;br /&gt;
	BlinkLoop:&lt;br /&gt;
		str r1, [r0]				@ Set BS8 in GPIOA_BSRR to 1 to set PA8 high&lt;br /&gt;
&lt;br /&gt;
		bl Delay&lt;br /&gt;
&lt;br /&gt;
		str r2, [r0]				@ Set BR8 in GPIOA_BSRR to 1 to set PA8 low&lt;br /&gt;
&lt;br /&gt;
		bl Delay&lt;br /&gt;
&lt;br /&gt;
		subs r5, #1&lt;br /&gt;
		bne BlinkLoop&lt;br /&gt;
	&lt;br /&gt;
	pop { lr }&lt;br /&gt;
	bx lr&lt;br /&gt;
&lt;br /&gt;
.type EnableClockGPIOA, %function&lt;br /&gt;
EnableClockGPIOA:&lt;br /&gt;
	ldr r1, =RCC_APB2ENR&lt;br /&gt;
	ldr r0, [r1]&lt;br /&gt;
	orr r0, r0, #RCC_APB2ENR_IOPAEN&lt;br /&gt;
	str r0, [r1]					@ Set IOPAEN bit in RCC_APB2ENR to 1 to enable GPIOA&lt;br /&gt;
	bx lr	@ Return to caller&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.type ConfigurePA8, %function&lt;br /&gt;
ConfigurePA8:&lt;br /&gt;
	ldr r1, =GPIOA_CRH&lt;br /&gt;
	ldr r0, [r1]&lt;br /&gt;
	and r0, #0xfffffff0&lt;br /&gt;
	orr r0, #GPIOx_CRx_GP_PP_2MHz&lt;br /&gt;
	str r0, [r1]					@ Set CNF8:MODE8 in GPIOA_CRH to 2&lt;br /&gt;
	bx lr&lt;br /&gt;
&lt;br /&gt;
.type Delay, %function&lt;br /&gt;
Delay:&lt;br /&gt;
	mov r4, r3&lt;br /&gt;
	DelayLoop:&lt;br /&gt;
	subs r4, #1&lt;br /&gt;
	bne DelayLoop					@ Iterate delay loop&lt;br /&gt;
	bx lr&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “BlinkFunctions”&lt;br /&gt;
&lt;br /&gt;
The Reset_Handler just became much prettier. There now are functions for enabling the GPIOA clock, configuring PA8 as output, and one that delays execution so that the LED blinking is visible. The “Blink” function performs the blinking, but only for 5 flashes, after which it returns (an endless blink-loop wouldn’t be good for demonstrating returns). As you see, LR is saved on the stack to allow “Blink” to call further functions.&lt;br /&gt;
&lt;br /&gt;
The two lines&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
pop { lr }&lt;br /&gt;
bx lr&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
are actually longer than necessary. It is actually possible to directly load the return address from the stack into the program counter, PC:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
pop { pc }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This way, the return address that was saved on the stack is directly used for the jump back. Just the same way, you can use “push” and “pop” to save and restore any other registers while your function is running.&lt;br /&gt;
==== Calling Convention ====&lt;br /&gt;
Actually building a large program as shown in the last example is a bad idea. The “Delay” function requires 1000000 to reside in r4. The “Blink” function relies on “Delay” not overwriting r0-r2, and r5, and requires the number of flashes to be given via r5. Such requirements can quickly grow into an intricate web of interdependencies, that make it impossible to write larger functions that call several sub-functions or restructure anything. Therefore, it is common to use a calling convention, which defines which registers a function may overwrite, which it should keep, how it should use the stack, and how to pass information back to the caller.&lt;br /&gt;
&lt;br /&gt;
When building an entire application out of your own assembly code, you can invent your own calling convention. However, it is always a good idea to use existing standards: The AAPCS defines a calling convention for ARM. This convention is also followed by C and C++ compilers, so using it makes your code automatically compatible with those. The Cortex-M interrupt mechanism follows it too, which would make it awkward to adapt code that uses some other convention to Interrupts. The specification of the calling convention is quite complex, so here is a quick summary of the basics:&lt;br /&gt;
&lt;br /&gt;
* Functions may only modify the registers r0-3 and r12. If more registers are needed, they have to be saved and restored using the stack. The APSR may be modified too.&lt;br /&gt;
* The LR is used as shown for the return address.&lt;br /&gt;
* When returning (via “bx lr”) the stack should be exactly in the same state as during the jump to the function (via “bl”).&lt;br /&gt;
* The registers r0-r3 may be used to pass additional information to a function, called parameters, and the function may overwrite them.&lt;br /&gt;
* The register r0 may be used to pass a result value back to the caller, which is called the return value.&lt;br /&gt;
&lt;br /&gt;
This means that when you call a function, you must assume registers r0-r3 and r12 may be overwritten but the others keep their values. In other words, the registers r0-r3 and r12 are (if at all) saved &#039;&#039;outside&#039;&#039; the function (“caller-save”), and the registers r4-r11 are (if at all) saved &#039;&#039;inside&#039;&#039; the function (“callee-save”).&lt;br /&gt;
&lt;br /&gt;
A function that does not call any other functions is called a “leaf-function” (as it is a leaf in the call tree). If such a function is simple, it might not require to touch the stack at all, as the return value is just saved in a register (LR) and it might only overwrite the registers r0-r3 and r12, which the caller can make sure to contain no important data. This makes small functions efficient, as register accesses are faster than memory accesses, such as to the stack.&lt;br /&gt;
&lt;br /&gt;
If all your functions follow the calling convention, you can call any function from anywhere and be sure about what it overwrites, even if it calls many other functions on its own. Restructuring the LED blinker could look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
RCC_APB2ENR = 0x40021018&lt;br /&gt;
RCC_APB2ENR_IOPAEN = 4&lt;br /&gt;
GPIOA_CRH = 0x40010804&lt;br /&gt;
&lt;br /&gt;
GPIOA_BSRR = 0x40010810&lt;br /&gt;
GPIOx_BSRR_BS8 = 0x100&lt;br /&gt;
GPIOx_BSRR_BR8 = 0x1000000&lt;br /&gt;
&lt;br /&gt;
GPIOx_CRx_GP_PP_2MHz = 2&lt;br /&gt;
&lt;br /&gt;
DelayLoopIterations = 1000000&lt;br /&gt;
&lt;br /&gt;
.text&lt;br /&gt;
.type Reset_Handler, %function&lt;br /&gt;
.global Reset_Handler&lt;br /&gt;
Reset_Handler:&lt;br /&gt;
	bl EnableClockGPIOA&lt;br /&gt;
	bl ConfigurePA8&lt;br /&gt;
	ldr r0, =5&lt;br /&gt;
	bl Blink&lt;br /&gt;
	b .&lt;br /&gt;
&lt;br /&gt;
.type Blink, %function&lt;br /&gt;
Blink:&lt;br /&gt;
	push { r4-r7, lr }&lt;br /&gt;
	ldr r4, =GPIOA_BSRR    	@ Load address of GPIOA_BSRR&lt;br /&gt;
	ldr r5, =GPIOx_BSRR_BS8        	@ Register value to set pin to high&lt;br /&gt;
	ldr r6, =GPIOx_BSRR_BR8    	@ Register value to set pin to low&lt;br /&gt;
	mov r7, r0                    	@ Number of LED flashes.&lt;br /&gt;
&lt;br /&gt;
	BlinkLoop:&lt;br /&gt;
    	str r5, [r4]        	@ Set BS8 in GPIOA_BSRR to 1 to set PA8 high&lt;br /&gt;
&lt;br /&gt;
    	ldr r0, =DelayLoopIterations    	@ Iterations for delay loop&lt;br /&gt;
    	bl Delay&lt;br /&gt;
&lt;br /&gt;
    	str r6, [r4]        	@ Set BR8 in GPIOA_BSRR to 1 to set PA8 low&lt;br /&gt;
&lt;br /&gt;
    	ldr r0, =DelayLoopIterations    	@ Iterations for delay loop&lt;br /&gt;
    	bl Delay&lt;br /&gt;
&lt;br /&gt;
    	subs r7, #1&lt;br /&gt;
    	bne BlinkLoop&lt;br /&gt;
    &lt;br /&gt;
	pop { r4-r7, pc }&lt;br /&gt;
&lt;br /&gt;
.type EnableClockGPIOA, %function&lt;br /&gt;
EnableClockGPIOA:&lt;br /&gt;
	ldr r1, =RCC_APB2ENR&lt;br /&gt;
	ldr r0, [r1]&lt;br /&gt;
	orr r0, r0, #RCC_APB2ENR_IOPAEN&lt;br /&gt;
	str r0, [r1]	@ Set IOPAEN bit in RCC_APB2ENR to 1 to enable GPIOA&lt;br /&gt;
	bx lr	@ Return to caller&lt;br /&gt;
&lt;br /&gt;
.type ConfigurePA8, %function&lt;br /&gt;
ConfigurePA8:&lt;br /&gt;
	ldr r1, =GPIOA_CRH&lt;br /&gt;
	ldr r0, [r1]&lt;br /&gt;
	and r0, #0xfffffff0&lt;br /&gt;
	orr r0, #GPIOx_CRx_GP_PP_2MHz&lt;br /&gt;
	str r0, [r1]        	@ Set CNF8:MODE8 in GPIOA_CRH to 2&lt;br /&gt;
	bx lr&lt;br /&gt;
&lt;br /&gt;
@ Parameters: r0 = Number of iterations&lt;br /&gt;
.type Delay, %function&lt;br /&gt;
Delay:&lt;br /&gt;
	DelayLoop:&lt;br /&gt;
	subs r0, #1&lt;br /&gt;
	bne DelayLoop        	@ Iterate delay loop&lt;br /&gt;
	bx lr&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “BlinkFunctionCallingConvention”&lt;br /&gt;
&lt;br /&gt;
The three small functions at the end only use registers r0 and r1, which they are free to overwrite. The “Delay” function expects the number of iterations as a parameter in r0, which it then modifies. Therefore, the “Blink” function fills r0 before every call to “Delay”. Alternatively, “Delay” could use a fixed iteration count, i.e. the “ldr” could be moved into “Delay”. As the “Blink” function must assume that “Delay” overwrites r0-r3 and r12, it keeps its own data in r4-r7, which are guaranteed to be retained according to the calling convention. Since “Blink”, in turn, must preserve these registers for the function that called it, it uses “push” and “pop” to save and restore them. Note the shortened syntax “r4-r7” in the instructions. The number of LED flashes is passed in r0 as a parameter; as this register will be overwritten, this number is moved to r7.&lt;br /&gt;
&lt;br /&gt;
Alternatively, “Blink” could re-load the constants each time they are used in r1/r2, such that only one register (r4) needs to be saved as it is needed to count the number of flashes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.type Blink, %function&lt;br /&gt;
Blink:&lt;br /&gt;
    push { r4, lr }&lt;br /&gt;
    &lt;br /&gt;
    mov r4, r0&lt;br /&gt;
&lt;br /&gt;
    BlinkLoop:&lt;br /&gt;
   	 ldr r1, =GPIOA_BSRR   	 @ Load address of GPIOA_BSRR&lt;br /&gt;
   	 ldr r2, =GPIOx_BSRR_BS8   		 @ Register value to set pin to high&lt;br /&gt;
   	 str r2, [r1]   		 @ Set BS8 in GPIOA_BSRR to 1 to set PA8 high&lt;br /&gt;
&lt;br /&gt;
   	 ldr r0, =DelayLoopIterations   	 @ Iterations for delay loop&lt;br /&gt;
   	 bl Delay&lt;br /&gt;
&lt;br /&gt;
   	 ldr r1, =GPIOA_BSRR   	 @ Load address of GPIOA_BSRR&lt;br /&gt;
   	 ldr r2, =GPIOx_BSRR_BR8   	 @ Register value to set pin to low&lt;br /&gt;
   	 str r2, [r1]   		 @ Set BR8 in GPIOA_BSRR to 1 to set PA8 low&lt;br /&gt;
&lt;br /&gt;
   	 ldr r0, =DelayLoopIterations   	 @ Iterations for delay loop&lt;br /&gt;
   	 bl Delay&lt;br /&gt;
&lt;br /&gt;
   	 subs r4, #1&lt;br /&gt;
   	 bne BlinkLoop&lt;br /&gt;
    &lt;br /&gt;
    pop { r4, pc }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “BlinkFunctionCallingConvention2”&lt;br /&gt;
&lt;br /&gt;
A third variant would not use any of the callee-save-registers (r4-r11) at all, and instead just save r0 before the function calls and restore it as needed&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.type Blink, %function&lt;br /&gt;
Blink:&lt;br /&gt;
	push { lr }&lt;br /&gt;
	&lt;br /&gt;
	BlinkLoop:&lt;br /&gt;
		push { r0 }&lt;br /&gt;
		&lt;br /&gt;
		ldr r1, =GPIOA_BSRR					@ Load address of GPIOA_BSRR&lt;br /&gt;
		ldr r2, =GPIOx_BSRR_BS8				@ Register value to set pin to high&lt;br /&gt;
		str r2, [r1]						@ Set BS8 in GPIOA_BSRR to 1 to set PA8 high&lt;br /&gt;
&lt;br /&gt;
		ldr r0, =DelayLoopIterations		@ Iterations for delay loop&lt;br /&gt;
		bl Delay&lt;br /&gt;
&lt;br /&gt;
		ldr r1, =GPIOA_BSRR					@ Load address of GPIOA_BSRR&lt;br /&gt;
		ldr r2, =GPIOx_BSRR_BR8				@ Register value to set pin to low&lt;br /&gt;
		str r2, [r1]						@ Set BR8 in GPIOA_BSRR to 1 to set PA8 low&lt;br /&gt;
&lt;br /&gt;
		ldr r0, =DelayLoopIterations		@ Iterations for delay loop&lt;br /&gt;
		bl Delay&lt;br /&gt;
&lt;br /&gt;
		pop { r0 }&lt;br /&gt;
		subs r0, #1&lt;br /&gt;
		bne BlinkLoop&lt;br /&gt;
	&lt;br /&gt;
	pop { pc }&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “BlinkFunctionCallingConvention3”&lt;br /&gt;
&lt;br /&gt;
The frequent stack accesses would however make this slower. Be sure to always document the meaning (and units, if applicable) of parameters e.g. via comments.&lt;br /&gt;
=== Conditional Execution ===&lt;br /&gt;
As mentioned, the conditional variants of the “b” instruction (e.g. “bne”) can be used to execute certain blocks of code only if a certain condition is met. First, more ways to formulate conditions will be shown. Next, the ARM instruction “it” will be introduced, which makes executing small blocks of code conditionally more efficient.&lt;br /&gt;
==== Conditions ====&lt;br /&gt;
All conditions for conditional execution depend on the outcome of some mathematical operation. When instructions such as “adds”, “subs”, “ands” are used, they update the flags in the APSR register depending on the outcome, which are then read by the conditional variants of “b” to decide whether to actually perform the jump.&lt;br /&gt;
&lt;br /&gt;
Often it is necessary to compare two numbers without actually doing a calculation. This can be done with the “cmp” instruction to which you can pass two registers or a register and a literal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
cmp r0, #42&lt;br /&gt;
cmp r0, r1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The “cmp” instruction is very similar to “subs” - it subtracts the second operand from the first, but doesn’t save the result anywhere, i.e. the registers keep their values. Just the flags in the APSR are updated according to the result, just as with “subs”. For example, if both operands were equal, the result of the subtraction is zero, and the zero flag will be set. So, to test whether two numbers are equal:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
cmp r0, #42&lt;br /&gt;
beq TheAnswer&lt;br /&gt;
&lt;br /&gt;
@ This is executed if r0 is not 42&lt;br /&gt;
&lt;br /&gt;
TheAnswer:&lt;br /&gt;
@ This is executed if r0 is 42&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The “bne” instruction is the opposite of “beq”.&lt;br /&gt;
&lt;br /&gt;
The “tst” instruction works similarly to “cmp”, but instead of subtracting, perform a bitwise “and” operation - like the “ands” instruction, but without keeping the result. This way, you can test whether a bit in a register is set:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
tst r0, #4&lt;br /&gt;
beq BitNotSet&lt;br /&gt;
&lt;br /&gt;
@ This is executed if bit 2 in r0 is set&lt;br /&gt;
&lt;br /&gt;
BitNotSet:&lt;br /&gt;
@ This is executed if bit 2 in r0 is not set&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A more useful use case for “tst” is to pass the same register twice. Applying “and” to the same value twice yields the same result as the input, so “tst” in this case effectively checks the properties of the input (negative/positive, zero):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
tst r0, r0&lt;br /&gt;
beq ValueZero&lt;br /&gt;
&lt;br /&gt;
@ This is executed if r0 is not zero&lt;br /&gt;
&lt;br /&gt;
ValueZero:&lt;br /&gt;
@ This is executed if r0 is zero&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There is also the “teq” instruction which performs an exclusive or operation.&lt;br /&gt;
&lt;br /&gt;
As mentioned, the suffixes “eq” and “ne” are called condition codes. ARM has 14 of those which define how the flags in the APSR form the condition. The details about how a subtraction (by “subs” or “cmp”) sets the flags in the APSR and how their interpretation by the different condition codes correlates to the mathematical result are somewhat complicated, involving the way the 2’s complement format works and relying on the fact that subtracting works by adding a negated number. Instead of diving into all the details, a table with a more high-level view and a practical interpretation of the condition should be more helpful:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot; | Code&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot; | Meaning&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot; | Unsigned /&amp;lt;br/&amp;gt;Signed&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot; | Flags&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot; | Condition after&amp;lt;br/&amp;gt;“cmp/subs r0, r1”&lt;br /&gt;
! style=&amp;quot;text-align:left;&amp;quot; | Condition after&amp;lt;br/&amp;gt;“tst r0, r1”&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | EQ&lt;br /&gt;
| Equal&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | U+S&lt;br /&gt;
| Z==1&lt;br /&gt;
| r0 = r1&lt;br /&gt;
| r0 = 0&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | NE&lt;br /&gt;
| Not equal&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | U+S&lt;br /&gt;
| Z==0&lt;br /&gt;
| r0 ≠ r1&lt;br /&gt;
| r0 ≠ 0&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | MI&lt;br /&gt;
| Negative&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | S&lt;br /&gt;
| N==1&lt;br /&gt;
| ---&lt;br /&gt;
| r0 &amp;lt; 0&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | PL&lt;br /&gt;
| Positive or Zero&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | S&lt;br /&gt;
| N==0&lt;br /&gt;
| ---&lt;br /&gt;
| r0 ≥ 0&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | VS&lt;br /&gt;
| Overflow&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | S&lt;br /&gt;
| V==1&lt;br /&gt;
| r0-r1 out of range¹&lt;br /&gt;
| ---&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | VC&lt;br /&gt;
| No Overflow&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | S&lt;br /&gt;
| V==0&lt;br /&gt;
| r0-r1 in range¹&lt;br /&gt;
| ---&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | HS&lt;br /&gt;
| Unsigned higher or same&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | U&lt;br /&gt;
| C==1&lt;br /&gt;
| r0 ≥ r1&lt;br /&gt;
| ---&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | LO&lt;br /&gt;
| Unsigned lower&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | U&lt;br /&gt;
| C==0&lt;br /&gt;
| r0 &amp;lt; r1&lt;br /&gt;
| ---&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | HI&lt;br /&gt;
| Unsigned higher&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | U&lt;br /&gt;
| C==1 and Z==0&lt;br /&gt;
| r0 &amp;gt; r1&lt;br /&gt;
| ---&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | LS&lt;br /&gt;
| Unsigned lower or same&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | U&lt;br /&gt;
| C==0 or Z==1&lt;br /&gt;
| r0 ≤ r1&lt;br /&gt;
| ---&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | GE&lt;br /&gt;
| Signed greater or equal&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | S&lt;br /&gt;
| N==V&lt;br /&gt;
| r0 ≥ r1&lt;br /&gt;
| ---&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | LT&lt;br /&gt;
| Signed less than&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | S&lt;br /&gt;
| N!=V&lt;br /&gt;
| r0 &amp;lt; r1&lt;br /&gt;
| ---&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | GT&lt;br /&gt;
| Signed greater than&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | S&lt;br /&gt;
| Z==0 and N==V&lt;br /&gt;
| r0 &amp;gt; r1&lt;br /&gt;
| ---&lt;br /&gt;
|-&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | LE&lt;br /&gt;
| Signed less or equal&lt;br /&gt;
| style=&amp;quot;text-align:center;&amp;quot; | S&lt;br /&gt;
| Z==1 or N!=V&lt;br /&gt;
| r0 ≤ r1&lt;br /&gt;
| ---&lt;br /&gt;
|}&lt;br /&gt;
1: Range meaning the numbers from -(2^31) until (2^31-1), inclusive&lt;br /&gt;
&lt;br /&gt;
To determine which condition code you need, first think about whether the number is unsigned (range 0 to 2^32-1) or is using two&#039;s complement to represent signed numbers (range -2^31 to 2^31-1). Ignore all rows in the table with the wrong format.&lt;br /&gt;
&lt;br /&gt;
If you want to compare two numbers, use the “cmp” instruction, and search for the desired condition within the “cmp”-condition column of the table. If you want to test a single number&#039;s properties, use the “tst”-column. Use the condition code from the first column with the conditional “b” instruction (“bne”, “beq”, “bmi”, “bpl”, “bhs”, ... ) right after the appropriate “cmp”/”tst” instruction.&lt;br /&gt;
&lt;br /&gt;
Note that all the condition codes have a corresponding inverse code that has exactly the negated meaning. Most also have a swapped partner code, using which is equivalent to swapping the operands for cmp. &lt;br /&gt;
==== The IT instruction ====&lt;br /&gt;
Jumping is inefficient, so having many conditional jumps may slow down your program. The ARM architecture offers a way to make a few instructions conditional without requiring a jump via the “it” (if-then) instruction. It is used in place of a conditional jump after an instruction that set the flags (“cmp”, “tst”, “adds”…) and also needs a condition code. The next instruction right after the it will then only be executed when the condition is met, and skipped otherwise. You have to repeat the condition code and add it to that instruction; this is just to make the code clearer and avoid confusion.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r4, =GPIOA_BSRR				@ Load address of GPIOA_BSRR&lt;br /&gt;
ldr r5, =GPIOx_BSRR_BS8			@ Register value to set pin to high&lt;br /&gt;
&lt;br /&gt;
ldr r0, =1						@ Load some date to compare&lt;br /&gt;
ldr r1, =2&lt;br /&gt;
&lt;br /&gt;
cmp r0, r1						@ Perform comparison&lt;br /&gt;
&lt;br /&gt;
it hi							@ Make the next instruction conditional&lt;br /&gt;
strhi r5, [r4]					@ Set BS8 in GPIOA_BSRR to 1 to set PA8 high&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This checks if r0 is higher than r1 (it isn’t), and only sets the pin PA8 to high if this condition is met. Up to 4 instructions can be made conditional like this; for each one, an additional “t” has to be appended to the “it” instruction:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
cmp r0, r1						@ Perform comparison&lt;br /&gt;
&lt;br /&gt;
ittt hi							@ Make the next instruction conditional&lt;br /&gt;
ldrhi r4, =GPIOA_BSRR				@ Load address of GPIOA_BSRR&lt;br /&gt;
ldrhi r5, =GPIOx_BSRR_BS8			@ Register value to set pin to high&lt;br /&gt;
strhi r5, [r4]					@ Set BS8 in GPIOA_BSRR to 1 to set PA8 high&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can also add instructions that will be executed if the condition was &#039;&#039;not&#039;&#039; met (like an “else”-case in high-level-languages), by appending “e” instead of “t” to the “it” instruction. Since the “t” in “it” is fixed, the first instruction is always executed if the condition is met; only the next three instructions can be either a “then” case (“t”) or “else” case (“e”). You also have to provide the inverted condition code for the “else”-instructions:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r4, =GPIOA_BSRR				@ Load address of GPIOA_BSRR&lt;br /&gt;
ldr r5, =GPIOx_BSRR_BS8			@ Register value to set pin to high&lt;br /&gt;
ldr r6, =GPIOx_BSRR_BR8			@ Register value to set pin to low&lt;br /&gt;
&lt;br /&gt;
ldr r0, =1						@ Load some date to compare&lt;br /&gt;
ldr r1, =2&lt;br /&gt;
&lt;br /&gt;
cmp r0, r1						@ Perform comparison&lt;br /&gt;
&lt;br /&gt;
ite hi							@ Make the next two instructions conditional (if-then-else)&lt;br /&gt;
strhi r5, [r4]					@ Set BS8 in GPIOA_BSRR to 1 to set PA8 high&lt;br /&gt;
strls r6, [r4]					@ Set BR8 in GPIOA_BSRR to 1 to set PA8 low&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are several restrictions on which instructions may appear within an it-block. Most importantly, instructions that set the flags are forbidden here, as is the “b” instruction except for the last instruction in an “it” block. Directly jumping to one of the conditional instructions is forbidden too.&lt;br /&gt;
&lt;br /&gt;
In T32 code, only the conditional “b” instruction is capable of encoding a condition code together with some operation, so the “it” instruction is provided to make any instruction conditional. On A32, most instructions include a condition code and can therefore be conditional, and the “it” instruction is actually ignored by the assembler here. You can and should still put “it” into code intended for A32, as this makes it compatible with T32. This is one of the reasons why A32 is more time-efficient, and T32 more space-efficient.&lt;br /&gt;
&lt;br /&gt;
Conditional instructions sometimes make surprisingly compact programs. For example, the euclidean algorithm for calculating the greatest common divisor (gcd) of two numbers can be written in ARM assembly like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
gcd:&lt;br /&gt;
	cmp r0, r1&lt;br /&gt;
	ite gt&lt;br /&gt;
	subgt r0, r0, r1&lt;br /&gt;
	suble r1, r1, r0&lt;br /&gt;
	bne gcd&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
While the C equivalent is actually longer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
int gcd(int a, int b) {&lt;br /&gt;
	while (a != b) {&lt;br /&gt;
		if (a &amp;gt; b)&lt;br /&gt;
			a = a - b;&lt;br /&gt;
		else&lt;br /&gt;
			b = b - a;&lt;br /&gt;
	}&lt;br /&gt;
	return a;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The usage of conditional instructions is also [https://developer.arm.com/docs/dui0801/latest/condition-codes/example-showing-the-benefits-of-conditional-instructions-in-a32-and-t32-code faster] than using conditional jumps. Note that the final “bne” instruction is independent of the “if-then” block; it just directly uses the result of “cmp”.&lt;br /&gt;
=== 8/16 bit arithmetic ===&lt;br /&gt;
So far, all numbers had 32 bit. However, especially for space reasons, smaller numbers are needed with 8 or 16 bit. Cortex-M3 doesn&#039;t provide any instructions for calculating 8 or 16 bit numbers directly. Instead, after loading such a number from memory into a processor register, it has to be extended into 32bit to allow the 32bit instructions to work properly. When storing the result back, only the lower 8/16 bit are used. If 8/16bit overflow behavior is required (i.e. overflow at -128/127 for 8bit signed, 0/256 for 8bit unsigned, -32768/32767 for 16bit signed, 0/65536 for 16bit unsigned) for calculations, the numbers have to be truncated after each calculation. This actually makes it slightly less efficient to deal with smaller numbers.&lt;br /&gt;
&lt;br /&gt;
A 16bit value (“halfword”) can be read from memory with the ldrh instruction:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r0, =SomeAddress&lt;br /&gt;
ldrh r1, [r0]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
“ldrh” loads 16bit from memory, writes them into the lower 16 bits of the destination register (here: r1), and sets the upper 16bits to zero. If the value is signed, it has to be sign-extended so that it can be used with 32bit-calculations:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r0, =SomeAddress&lt;br /&gt;
ldrh r1, [r0]&lt;br /&gt;
sxth r1, r1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The “sxth” instruction copies the sign bit (i.e. bit 15) into the upper 16 bits (“sign-extension”); this makes sure that negative 16bit-numers keep their value when interpreted as 32 bits. The “ldrsh” instruction combines both “ldrh” and “sxth”. “ldrb”, “sxtb”, “ldrsb” are for loading and sign-extending 8bit-values and the combination of both, respectively.&lt;br /&gt;
&lt;br /&gt;
To simulate 8/16bit overflow behaviour after a mathematical operation, use uxtb/uxth for unsigned 8/16 bit numbers, or sxtb/sxth for signed 8/16 bit numbers:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
add r0, #1&lt;br /&gt;
uxth r0, r0&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The “uxth”/”uxtb” instructions copy the lower 16/8 bits of a register into another one, setting the upper 16/24 bits to zero. This way, if r0 contained 65535 before, the result will be 0 instead of 65536 after using “uxth”.&lt;br /&gt;
&lt;br /&gt;
This is a common trap when coding in C - when using e.g. the &amp;quot;uint16_t&amp;quot; type for local variables such as loop counters, this implicitly requests 16bit overflow behavior, requiring the truncating after each calculation, even though the overflow may actually never happen. This is why e.g. uint16_fast_t should be used for local variables, as this is 32 bit on ARM, which is faster.&lt;br /&gt;
=== Alignment ===&lt;br /&gt;
There are certain restrictions on the address when accessing data in memory using the “str”/”ldr” variants:&lt;br /&gt;
* The “ldrd”/”strd”/”ldm”/”stm” instructions, which can load/store multiple registers at once, always require the address to be a multiple of 4. If it isn’t, the program will crash.&lt;br /&gt;
* The “ldr”/”str” instructions require the address to be a multiple of 4, and “strh”/”ldrh” require it to be a multiple of 2. If it isn’t, the behaviour depends on the ARM version:&lt;br /&gt;
** On ARMv6-M and before, the program will crash.&lt;br /&gt;
** On ARMv7-M:&lt;br /&gt;
*** If the CCR.UNALIGN_TRP is set to zero (the default), the access will be slow&lt;br /&gt;
*** If the CCR.UNALIGN_TRP bit is set to one, the program will crash, emulating the ARMv6-M behaviour&lt;br /&gt;
&lt;br /&gt;
For “strb”/”ldrb” there are no such requirements.&lt;br /&gt;
&lt;br /&gt;
The number of which the address needs to be a multiple of is called the “alignment” (e.g. 2-byte-alignment, 4-byte-alignment, …). An access with an address that is a multiple of 2/4 as specified above is called an “aligned access”; others are called “unaligned access” (which are slow or cause a crash).&lt;br /&gt;
&lt;br /&gt;
Even though slow accesses may be acceptable, it is still a good idea to make sure all accesses are always correctly aligned in case the code is ported to an ARM version or operating system that requires it. The addresses of periphery registers are already aligned correctly, so there is no need to worry. When placing data in RAM however, you should make sure that the addresses of the individual elements that are accessed via one of the “ldr” variants are aligned properly. For example, if a previous example code was modified like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.data&lt;br /&gt;
var2:&lt;br /&gt;
	.space 1		@ Reserve 1 byte for memory block “var2”&lt;br /&gt;
var1:&lt;br /&gt;
	.space 4		@ Reserve 4 bytes for memory block “var1”&lt;br /&gt;
&lt;br /&gt;
.text&lt;br /&gt;
@ Instructions go here...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The address of “var1” will not be a multiple of 4, and an access via “ldr” would be unaligned. This could be improved by adding a space of 3 bytes in between:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.data&lt;br /&gt;
var2:&lt;br /&gt;
	.space 1		@ Reserve 1 byte for memory block “var2”&lt;br /&gt;
	.space 3&lt;br /&gt;
var1:&lt;br /&gt;
	.space 4		@ Reserve 4 bytes for memory block “var1”&lt;br /&gt;
&lt;br /&gt;
.text&lt;br /&gt;
@ Instructions go here...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This would require you to keep in mind all the other things in memory that were declared before, which is impractical especially if multiple assembly files are used. Therefore, the assembler offers the “.align” directive:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.data&lt;br /&gt;
var2:&lt;br /&gt;
	.space 1		@ Reserve 1 byte for memory block “var2”&lt;br /&gt;
	.align 2&lt;br /&gt;
var1:&lt;br /&gt;
	.space 4		@ Reserve 4 bytes for memory block “var1”&lt;br /&gt;
&lt;br /&gt;
.text&lt;br /&gt;
@ Instructions go here...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When using “.align X”, the assembler makes sure that the next address will be a multiple of 2^X, so in this case, a multiple of 2^2=4. The assembler will therefore insert 0 to 2^X-1 bytes of space. The section containing the directive in the object code file will also be marked to require that alignment, such that the linker will automatically place it at the appropriate location in address space.&lt;br /&gt;
=== Offset addressing ===&lt;br /&gt;
The various “ldr”/”str” instructions can optionally perform some calculation on the address before executing the memory access. What is shown for “ldr” here works for “str” and the variants for halfwords and bytes equivalently. There are several variants for this. This first one adds a fixed offset that is encoded within the instruction itself to the address:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r0, [r1, #8]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This adds 8 to r1 and uses the result as the address to access. The number can also be negative. This variant is useful for accessing members of a heterogeneous container organized like a C struct or the registers in a periphery module. For example, you can load the base address of a periphery module into a register, and then access the various registers using offset-addressing without having to load each address individually:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
GPIOA=0x40010800&lt;br /&gt;
GPIOx_CRH = 0x04&lt;br /&gt;
GPIOx_BSRR = 0x10&lt;br /&gt;
&lt;br /&gt;
GPIOx_BSRR_BS8 = 0x100&lt;br /&gt;
GPIOx_BSRR_BR8 = 0x1000000&lt;br /&gt;
&lt;br /&gt;
GPIOx_CRx_GP_PP_2MHz = 2&lt;br /&gt;
&lt;br /&gt;
.text&lt;br /&gt;
.type Reset_Handler, %function&lt;br /&gt;
.global Reset_Handler&lt;br /&gt;
Reset_Handler:&lt;br /&gt;
	bl EnableClockGPIOA&lt;br /&gt;
&lt;br /&gt;
	ldr r1, =GPIOA&lt;br /&gt;
	&lt;br /&gt;
	ldr r0, [r1, #GPIOx_CRH]&lt;br /&gt;
	and r0, #0xfffffff0&lt;br /&gt;
	orr r0, #GPIOx_CRx_GP_PP_2MHz&lt;br /&gt;
	str r0, [r1, #GPIOx_CRH]		@ Set CNF8:MODE8 in GPIOA_CRH to 2&lt;br /&gt;
	&lt;br /&gt;
	ldr r0, =GPIOx_BSRR_BS8			@ Register value to set pin to high&lt;br /&gt;
	str r0, [r1, #GPIOx_BSRR]		@ Set BS8 in GPIOA_BSRR to 1 to set PA8 high&lt;br /&gt;
&lt;br /&gt;
	b .&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “OffsetAddressing”&lt;br /&gt;
&lt;br /&gt;
This way, you can avoid repeated loads of similar addresses. This variant is also capable of writing the newly calculated address back into the address register by appending a “!”:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r0, [r1, #8]!&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This will add 8 to r1, write the result into r1, and also use it as an address from which to load 4 bytes and store them into r0. The variant&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r0, [r1], #8&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
works just the opposite - r1 is used as an address from which to load the data, and “r1+8” is written back to r1. The next variant adds two registers to obtain the memory address:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r0, [r1, r2]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This loads the data from the address calculated by “r1+r2”. The second register (here: r2) can also be optionally shifted left by a fixed number of bits in the range 0-3:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r0, [r1, r2, lsl #2]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This shifts r2 left by two bits (i.e. multiplies it by 4), adds it to r1, and uses that as the address (r2 itself is not modified).&lt;br /&gt;
=== Iterating arrays ===&lt;br /&gt;
The offset addressing mechanism is perfectly suited to iterating arrays. This could be used to make an array defining a sequence of LED flashes that is iterated by the LED blinker application. Such an array would contain the duration of each on-and off-cycle (as passed to the “Delay” function) and be placed in flash memory:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.text&lt;br /&gt;
.type Reset_Handler, %function&lt;br /&gt;
.global Reset_Handler&lt;br /&gt;
Reset_Handler:&lt;br /&gt;
	bl EnableClockGPIOA&lt;br /&gt;
	bl ConfigurePA8&lt;br /&gt;
	bl Blink&lt;br /&gt;
	b .&lt;br /&gt;
&lt;br /&gt;
.type Blink, %function&lt;br /&gt;
Blink:&lt;br /&gt;
	push { r4-r8, lr }&lt;br /&gt;
	ldr r4, =GPIOA_BSRR		@ Load address of GPIOA_BSRR&lt;br /&gt;
	ldr r5, =GPIOx_BSRR_BS8			@ Register value to set pin to high&lt;br /&gt;
	ldr r6, =GPIOx_BSRR_BR8		@ Register value to set pin to low&lt;br /&gt;
	ldr r7, =BlinkTable   			 @ Move address of &amp;quot;BlinkTable&amp;quot; into r7&lt;br /&gt;
	ldr r8, =BlinkTableEnd   		 @ Move address of &amp;quot;BlinkTableEnd&amp;quot; into r8&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	BlinkLoop:&lt;br /&gt;
		str r5, [r4]			@ Set BS8 in GPIOA_BSRR to 1 to set PA8 high&lt;br /&gt;
&lt;br /&gt;
		ldr r0, [r7], #4		@ Load delay iterations from table and increment address&lt;br /&gt;
		bl Delay&lt;br /&gt;
&lt;br /&gt;
		str r6, [r4]			@ Set BR8 in GPIOA_BSRR to 1 to set PA8 low&lt;br /&gt;
&lt;br /&gt;
		ldr r0, [r7], #4		@ Load delay iterations from table and increment address&lt;br /&gt;
		bl Delay&lt;br /&gt;
&lt;br /&gt;
		cmp r7, r8&lt;br /&gt;
		blo BlinkLoop&lt;br /&gt;
	&lt;br /&gt;
	pop { r4-r8, pc }&lt;br /&gt;
&lt;br /&gt;
.align 2&lt;br /&gt;
.type BlinkTable, %object&lt;br /&gt;
BlinkTable:&lt;br /&gt;
	.word	1000000, 1000000, 1000000, 1000000, 1000000, 1000000&lt;br /&gt;
	.word	2500000, 1000000, 2500000, 1000000, 2500000, 1000000&lt;br /&gt;
	.word	1000000, 1000000, 1000000, 1000000, 1000000, 1000000&lt;br /&gt;
BlinkTableEnd:&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “BlinkPattern”&lt;br /&gt;
&lt;br /&gt;
The “.word” directive is used to place a sequence of 32bit- numbers into flash memory. The label “BlinkTable” will refer the the start address of the array, and “BlinkTableEnd” to the first address &#039;&#039;after&#039;&#039; the array. These two addresses are loaded into registers before the loop. The “.align” directive is used to make sure the 32bit-words are stored at properly aligned addresses. Inside the loop, the “ldr” instruction is used to load a 32bit-word from the array and pass it to the “Delay” function. The r7 register is advanced by 4 bytes to the next 32bit-word. This is done twice, for the on-and off-time. At the end of the loop, the address register is compared with the address of “BlinkTableEnd” - until that address has been reached, the loop will continue.&lt;br /&gt;
&lt;br /&gt;
Another possibility is to keep the base address of the array in a register, and increment another register that contains the offset:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.type Blink, %function&lt;br /&gt;
Blink:&lt;br /&gt;
	push { r4-r9, lr }&lt;br /&gt;
	ldr r4, =GPIOA_BSRR		@ Load address of GPIOA_BSRR&lt;br /&gt;
	ldr r5, =GPIOx_BSRR_BS8	@ Register value to set pin to high&lt;br /&gt;
	ldr r6, =GPIOx_BSRR_BR8	@ Register value to set pin to low&lt;br /&gt;
	ldr r7, =BlinkTable			@ Move address of &amp;quot;BlinkTable&amp;quot; into r7&lt;br /&gt;
	ldr r8, =0&lt;br /&gt;
	ldr r9, =18&lt;br /&gt;
&lt;br /&gt;
	BlinkLoop:&lt;br /&gt;
		str r5, [r4]			@ Set BS8 in GPIOA_BSRR to 1 to set PA8 high&lt;br /&gt;
&lt;br /&gt;
		ldr r0, [r7, r8, lsl #2]		@ Load delay iterations from table&lt;br /&gt;
		add r8, #1&lt;br /&gt;
		bl Delay&lt;br /&gt;
&lt;br /&gt;
		str r6, [r4]			@ Set BR8 in GPIOA_BSRR to 1 to set PA8 low&lt;br /&gt;
&lt;br /&gt;
		ldr r0, [r7, r8, lsl #2]		@ Load delay iterations from table&lt;br /&gt;
		add r8, #1&lt;br /&gt;
		bl Delay&lt;br /&gt;
&lt;br /&gt;
		cmp r8, r9&lt;br /&gt;
		blo BlinkLoop&lt;br /&gt;
	&lt;br /&gt;
	pop { r4-r9, pc }&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “BlinkPattern2”&lt;br /&gt;
&lt;br /&gt;
Here, r8 is incremented in steps of 1 to denote the index in the array. The “lsl” syntax for “ldr” is used to multiply r8 by 4 (since each word is 4 bytes in size) and add it to r7, which contains the array’s base address. At the end of the loop, r8 is compared with 18, which is the number of entries in the array. This variant is actually less efficient, as it needs to keep both the base address and the index in registers and also has to increment the index in each iteration.&lt;br /&gt;
=== Literal loads ===&lt;br /&gt;
&lt;br /&gt;
Regardless of architecture, any processor obviously needs to work with addresses in its own address space a lot. ARM can do calculations with its 32bit addresses just fine, but there is a bottleneck: The instruction set itself. To work with any address, it needs to be initially loaded into a processor register, but ARM instructions are only 16 or 32bit in size - not enough space for an arbitrary 32bit number plus the instruction encoding. Allowing even larger instructions (e.g. 40 bit) would complicate matters, so ARM instead uses several tricks to deal with this problem, which will be discussed here.&lt;br /&gt;
&lt;br /&gt;
The “ldr r0, =1234” syntax allows you to load any arbitrary 32bit numbers, but is not actually a machine code instruction, but is translated by the assembler into one. In this chapter, the actual instructions for loading immediate numbers are discussed.&lt;br /&gt;
&lt;br /&gt;
==== The “mov”-instruction ====&lt;br /&gt;
The most basic way of loading an immediate number into a register is the “mov” instruction:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
mov r0, #1234&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This allows you to load any 16bit number (0 to 2^16-1) into a register. “mov” also includes some clever encodings that allow you to load certain commonly-used patterns:&lt;br /&gt;
&lt;br /&gt;
* Any 32bit number that consists of one byte of arbitrary bits (i.e. 8 adjacent arbitrary bits) at any location, and zeros otherwise, e.g. 0x00000045, 0x00045000, 0x7f800000.&lt;br /&gt;
* Any 32bit number that consists of the same byte repeated 2 or 4 times in fixed places, as in 0x23002300, 0x00230023, 0x23232323&lt;br /&gt;
* The bit-wise negated result of any of these two patterns, e.g. 0xffffffba, 0xfffbafff, 0x807fffff or 0xdcffdcff. The assembler will actually use the “mvn” instruction for this, which works identically to “mov”, but negates the value.&lt;br /&gt;
&lt;br /&gt;
By specifying a number that falls into one of these patterns, the assembler will automatically use the appropriate encoding. The first two ways of encoding numbers are not only available with “mov”, but also several other mathematical instructions that expect some immediate value: “add”, “and”, “bic”, “cmn”, “cmp”, “eor”, “mov”, “mvn”, “orn”, “orr”, “rsb”, “sbc”, “sub”, “teq”, “tst”. In the ARM Architecture Reference Manual, check the description of the instructions and look out for “ThumbExpandImm” to see whether it supports the first two patterns above.&lt;br /&gt;
&lt;br /&gt;
You can also use the “mvn” instruction directly, e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
mov r0, #0xf807ffff&lt;br /&gt;
mvn r0, #0x07f80000&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
both lines are identical and write the number 0xf807ffff into r0.&lt;br /&gt;
==== The “movt” instruction ====&lt;br /&gt;
While supporting many common patterns, this does not allow arbitrary 32 bit numbers. One way to load any 32bit number is to split the number into two 16bit halves, and use both “mov” and “movt” to combine these two half-words into one register:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
mov r0, #0xabcd&lt;br /&gt;
movt r0, #0x1234&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The “movt” instruction loads the given number into the upper 16 bits of the register, so this example loads 0x1234abcd into r0. The order is important, as “mov” overwrites the upper 16 bits with zeros, but “movt” keeps the lower 16 bits. If a single “mov” can&#039;t fit the desired number, the combination of “mov” and “movt” is the fastest way of loading any 32bit number. As two 32bit instructions are needed, this consumes 8 bytes of program memory. If you want to load the address of a symbol into a register, you need to tell the assembler to split it automatically. This can be achieved by prefixing the symbol with “:lower16:” or “:upper16:”, e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
movw r0, #:lower16:GPIOA_BSRR&lt;br /&gt;
movt r0, #:upper16:GPIOA_BSRR&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that “movw” needs to be specified in this case to explicitly tell the assembler to use the “mov” variant that accepts 16bit numbers (which it otherwise does automatically when a direct value is given).&lt;br /&gt;
==== PC-relative loads ====&lt;br /&gt;
The other way of loading arbitrary 32bit values into registers is to place the value directly in flash memory, and load it from there using “ldr”:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
@ Some code …&lt;br /&gt;
mov r0, … address of Literal ...&lt;br /&gt;
ldr r1, [r0]&lt;br /&gt;
@ More code …&lt;br /&gt;
Literal:&lt;br /&gt;
    .word 0x12345678&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, there is a Chicken-And-Egg problem - the address of “Literal” is a 32bit number itself, so how to load it into r0? Luckily, there is a register that contains a number close to the one needed - the program counter (PC, r15) indicates the address of the instruction currently being executed. By reading it and adding a small offset that fits into the instruction itself, the address of “Literal” can be obtained, provided that “Literal” is located close enough. Consider this example of the EnableClockGPIOA function:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.align 2&lt;br /&gt;
.type EnableClockGPIOA, %function&lt;br /&gt;
EnableClockGPIOA:&lt;br /&gt;
	add r1, pc, #12&lt;br /&gt;
	ldr r1, [r1]&lt;br /&gt;
	ldr r0, [r1]&lt;br /&gt;
	orr r0, r0, #RCC_APB2ENR_IOPAEN&lt;br /&gt;
	str r0, [r1]	@ Set IOPAEN bit in RCC_APB2ENR to 1 to enable GPIOA&lt;br /&gt;
	bx lr	@ Return to caller&lt;br /&gt;
    &lt;br /&gt;
.align 2&lt;br /&gt;
	.word RCC_APB2ENR&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The 32bit-value “RCC_APB2ENR” is stored in flash memory. The “add” instruction is used to add the offset 12 to the address of the instruction itself to obtain the address of said 32bit-value, which is then loaded via “ldr”. The offset 12 is actually not easy to calculate and even depends on the alignment of the “add” instruction itself (hence the “.align” to ensure a consistent example). The assembler is capable of doing the calculation on its own, for which the “adr” instruction is used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.align 2&lt;br /&gt;
.type EnableClockGPIOA, %function&lt;br /&gt;
EnableClockGPIOA:&lt;br /&gt;
	adr r1, LiteralRCC_APB2ENR&lt;br /&gt;
	ldr r1, [r1]&lt;br /&gt;
	ldr r0, [r1]&lt;br /&gt;
	orr r0, r0, #RCC_APB2ENR_IOPAEN&lt;br /&gt;
	str r0, [r1]    @ Set IOPAEN bit in RCC_APB2ENR to 1 to enable GPIOA&lt;br /&gt;
	bx lr    @ Return to caller&lt;br /&gt;
&lt;br /&gt;
.align 2&lt;br /&gt;
LiteralRCC_APB2ENR:&lt;br /&gt;
	.word RCC_APB2ENR&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The label LiteralRCC_APB2ENR refers to the address of the 32bit-value in memory. “adr” is actually a variant of “add” that instructs the assembler to calculate the offset and place it into the instruction itself, which then lets the processor add it to PC and write the result to r1. This address is then used by “ldr”.&lt;br /&gt;
&lt;br /&gt;
The “adr” instruction is useful when the address of some literal is explicitly needed; for example, in the blinker program, it can be used to obtain the addresses of the array:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
adr r7, BlinkTable   			 @ Move address of &amp;quot;BlinkTable&amp;quot; into r7&lt;br /&gt;
adr r8, BlinkTableEnd   		 @ Move address of &amp;quot;BlinkTableEnd&amp;quot; into r8&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
However, for loading a single value, the address is actually not needed. In this case, “adr” and “ldr” can be combined:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.type EnableClockGPIOA, %function&lt;br /&gt;
EnableClockGPIOA:&lt;br /&gt;
	ldr r1, LiteralRCC_APB2ENR&lt;br /&gt;
	ldr r0, [r1]&lt;br /&gt;
	orr r0, r0, #RCC_APB2ENR_IOPAEN&lt;br /&gt;
	str r0, [r1]    @ Set IOPAEN bit in RCC_APB2ENR to 1 to enable GPIOA&lt;br /&gt;
	bx lr    @ Return to caller&lt;br /&gt;
&lt;br /&gt;
.align 2&lt;br /&gt;
LiteralRCC_APB2ENR:&lt;br /&gt;
	.word RCC_APB2ENR&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This special variant of “ldr” lets the assembler calculate to offset as with “adr”, adds it to “PC” at runtime and loads the data found at the address into r1. This is much easier than the first variant, as all calculations are done automatically. It is still somewhat cumbersome having to write three lines just to obtain a single 32bit value. Therefore, the assembler offers this already introduced syntax:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
ldr r1, =RCC_APB2ENR&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a special command for the assembler. If possible, the assembler will use the “mov” or “mvn” instruction to load the value. If the value won’t fit, it will be put into flash memory, and a “ldr” instruction as above will be used. In this case, the “ldr rX, =...” syntax is equivalent to the combination of specifying a label for the value, the “.word” directive and “ldr rX, &amp;lt;Label&amp;gt;”. Therefore, this syntax is usually the best way to load immediates.&lt;br /&gt;
&lt;br /&gt;
The assembler places the literals at the end of the file. If the file is long, the offset will be too long for the “ldr” and “adr” instructions and the assembler will emit an error. You can instruct the assembler to place all literals that have been declared so far at a specific point using the “.ltorg” directive. It is recommended to place an “.ltorg” after each function (after the “bx lr”) - just make sure that execution will never reach there. If a single function is so long that an “.ltorg” at the end is too far away from “ldr”/”adr” at the beginning, you can place an “.ltorg” somewhere in the middle and jump over it with “b”.&lt;br /&gt;
&lt;br /&gt;
In summary, the following rules can help make literal loads more efficient&lt;br /&gt;
* Avoid literal loads if possible; try to calculate needed values from other values that have already been loaded, possibly by using offset-addressing in “ldr”/”str”&lt;br /&gt;
* When accessing multiple registers of a single periphery module, load its base address once and use offset addressing to access the individual registers&lt;br /&gt;
* If you need a pointer to a location in flash memory, try using “adr”&lt;br /&gt;
* If speed is important, use “movw”+”movt” to load the value&lt;br /&gt;
* Else, use “ldr rX, =...” to have the assembler choose the optimal encoding&lt;br /&gt;
* Place “.ltorg” after each function&lt;br /&gt;
&lt;br /&gt;
The “ldr … =” instruction can also be used to load any immediate 32bit value into the PC to cause a jump to that address, simply by specifying “pc” as the target register. If you perform an ordinary branch (via “b” or “bl”) to some function whose address is too far away from the current code location, the linker will insert a “wrapper” function that does exactly that to perform the “far” jump. That function is called a “veneer”.&lt;br /&gt;
=== The SysTick timer ===&lt;br /&gt;
An important aspect of many embedded systems is to control timing of technical processes. In the blinker example, the timing of the LED flashes was handled by having the processor execute dummy instructions to pass time. It is however virtually impossible to accurately predict the runtime of any piece of code on a complex processor such as ARM ones, and the runtime may vary among multiple runs and depending on the actual micro controller and its configuration. For a simple LED blinker this may be acceptable, but not for e.g. a closed loop controller for some mechanical actor. Therefore, almost all micro controllers and also application processors feature one or more hardware timers, which allow to measure time independently of the execution speed of the software. Timer features vary widely among different processors, but that basic idea is to increment or decrement some digital counter at each clock cycle and trigger some event when it reaches a certain value. &lt;br /&gt;
&lt;br /&gt;
All ARMv7-M processors feature the so-called “SysTick”-Timer as part of the processor core itself. This is a rather simple 24bit-timer that counts from a configurable value back to zero, then resets to that value and triggers an event. This timer is frequently used as a time base for RTOS or other runtime libraries. The timer uses three periphery registers: “RVR” contains the value from which to count down. “CVR” contains the current value, and “CSR” contains some status and control bits. The timer can be used for the “Delay” function like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
SCS = 0xe000e000&lt;br /&gt;
SCS_SYST_CSR = 0x10&lt;br /&gt;
SCS_SYST_RVR = 0x14&lt;br /&gt;
SCS_SYST_CVR = 0x18&lt;br /&gt;
&lt;br /&gt;
@ Parameters: r0 = Number of iterations&lt;br /&gt;
.type Delay, %function&lt;br /&gt;
Delay:&lt;br /&gt;
	ldr r1, =SCS&lt;br /&gt;
	add r0, r0, r0, lsl #1&lt;br /&gt;
	&lt;br /&gt;
	str r0, [r1, #SCS_SYST_RVR]&lt;br /&gt;
	ldr r0, =0&lt;br /&gt;
	str r0, [r1, #SCS_SYST_CVR]&lt;br /&gt;
	&lt;br /&gt;
	ldr r0, =5&lt;br /&gt;
	str r0, [r1, #SCS_SYST_CSR]&lt;br /&gt;
	&lt;br /&gt;
DelayLoop:&lt;br /&gt;
	ldr r0, [r1, #SCS_SYST_CSR]&lt;br /&gt;
	tst r0, #0x10000&lt;br /&gt;
	beq DelayLoop&lt;br /&gt;
	&lt;br /&gt;
	ldr r0, =0&lt;br /&gt;
	str r0, [r1, #SCS_SYST_CSR]&lt;br /&gt;
	&lt;br /&gt;
	bx lr&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The SysTick is part of the “System Control Space”, SCS. The SCS base address is defined as a symbol, and the relative addresses of the registers as well. The count value is stored in “RVR”, after which “CVR” has to be set to zero. The timer is started by writing “5” into the “CSR” register. The loop repeatedly reads the “CSR” register and continues until bit 16 is set. The “tst” instruction is used to perform an “and” operation with the register contents and an immediate value without keeping the result while just updating the flags. At the end, the “CSR” register is set to zero to disable the timer. The “add” instruction at the beginning is used to multiply the count value by 3: r0 is shifted left by one, i.e. multiplied by two, and then added to itself, as in r0*2^1+r0. This is a common trick to quickly multiply by constants. By including this multiplication, the duration is the same as with the previous “Delay” variant, which, on this microcontroller, uses about 3 cycles per loop iteration.&lt;br /&gt;
&lt;br /&gt;
Managing timing this way (or any other kind of “Delay” function) is still not very accurate. The time needed to call the function, start the timer, return, and set the pins is added to the actual duration and may also vary each time. The timing errors accumulate over time - a clock implemented this way will quickly go wrong. The proper way to achieve accurate timing is to start the timer once, let it run continuously, and react to its events. The internal clock source used by the microcontroller is also quite inaccurate (up to 2.5% deviation), which can be improved upon by a quartz crystal (typical accuracy of e.g. 0.005%), which will be covered later. Reacting to events instead of calling a function that executes dummy code requires restructuring the program code, without using any kind of “Delay” function.&lt;br /&gt;
&lt;br /&gt;
To do that, the timer is started once at program startup and kept running. After setting the LED pin, wait for the timer event, and repeat. In the last example, the values 3000000 and 7500000 are used for the timer register (3x1000000 and 3x2500000, respectively). Changing the timer value while it is running continuously is problematic, so one fixed value should be used; to achieve variable blinker duration, multiple timer events need to be counted. The greatest common denominator of the two numbers is 1500000, so to achieve the two different times, 2 and 5 timer events need to be registered, respectively. Since these numbers fit into a single byte, the table entries and corresponding access instructions are changed to byte. A function “StartSysTick” is implemented to start the timer once, and a function “WaitSysTick” to wait for a given number of timer events:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
RCC_APB2ENR = 0x40021018&lt;br /&gt;
RCC_APB2ENR_IOPAEN = 4&lt;br /&gt;
GPIOA_CRH = 0x40010804&lt;br /&gt;
&lt;br /&gt;
GPIOA_BSRR = 0x40010810&lt;br /&gt;
GPIOx_BSRR_BS8 = 0x100&lt;br /&gt;
GPIOx_BSRR_BR8 = 0x1000000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
GPIOx_CRx_GP_PP_2MHz = 2&lt;br /&gt;
&lt;br /&gt;
SCS = 0xe000e000&lt;br /&gt;
SCS_SYST_CSR = 0x10&lt;br /&gt;
SCS_SYST_RVR = 0x14&lt;br /&gt;
SCS_SYST_CVR = 0x18&lt;br /&gt;
TimerValue=1500000&lt;br /&gt;
&lt;br /&gt;
.text&lt;br /&gt;
.type Reset_Handler, %function&lt;br /&gt;
.global Reset_Handler&lt;br /&gt;
Reset_Handler:&lt;br /&gt;
	bl EnableClockGPIOA&lt;br /&gt;
	bl ConfigurePA8&lt;br /&gt;
	ldr r0, =TimerValue&lt;br /&gt;
	bl StartSysTick&lt;br /&gt;
	bl Blink&lt;br /&gt;
	b .&lt;br /&gt;
&lt;br /&gt;
.type Blink, %function&lt;br /&gt;
Blink:&lt;br /&gt;
	push { r4-r8, lr }&lt;br /&gt;
	ldr r4, =GPIOA_BSRR				@ Load address of GPIOA_BSRR&lt;br /&gt;
	ldr r5, =GPIOx_BSRR_BS8			@ Register value to set pin to high&lt;br /&gt;
	ldr r6, =GPIOx_BSRR_BR8			@ Register value to set pin to low&lt;br /&gt;
	adr r7, BlinkTable				@ Move address of &amp;quot;BlinkTable&amp;quot; into r8&lt;br /&gt;
	adr r8, BlinkTableEnd			@ Move address of &amp;quot;BlinkTableEnd&amp;quot; into r9&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	BlinkLoop:&lt;br /&gt;
		str r5, [r4]				@ Set BS8 in GPIOA_BSRR to 1 to set PA8 high&lt;br /&gt;
&lt;br /&gt;
		ldrb r0, [r7], #1			@ Load delay iterations from table and increment address&lt;br /&gt;
		bl WaitSysTick&lt;br /&gt;
&lt;br /&gt;
		str r6, [r4]				@ Set BR8 in GPIOA_BSRR to 1 to set PA8 low&lt;br /&gt;
&lt;br /&gt;
		ldrb r0, [r7], #1			@ Load delay iterations from table and increment address&lt;br /&gt;
		bl WaitSysTick&lt;br /&gt;
&lt;br /&gt;
		cmp r7, r8&lt;br /&gt;
		blo BlinkLoop&lt;br /&gt;
	&lt;br /&gt;
	pop { r4-r8, pc }&lt;br /&gt;
&lt;br /&gt;
.align 2&lt;br /&gt;
.type BlinkTable, %object&lt;br /&gt;
BlinkTable:&lt;br /&gt;
	.byte	2, 2, 2, 2, 2, 2&lt;br /&gt;
	.byte	5, 2, 5, 2, 5, 2&lt;br /&gt;
	.byte	2, 2, 2, 2, 2, 2&lt;br /&gt;
BlinkTableEnd:&lt;br /&gt;
.align 2&lt;br /&gt;
&lt;br /&gt;
.type EnableClockGPIOA, %function&lt;br /&gt;
EnableClockGPIOA:&lt;br /&gt;
	ldr r1, =RCC_APB2ENR&lt;br /&gt;
	ldr r0, [r1]&lt;br /&gt;
	orr r0, r0, #RCC_APB2ENR_IOPAEN&lt;br /&gt;
	str r0, [r1]					@ Set IOPAEN bit in RCC_APB2ENR to 1 to enable GPIOA&lt;br /&gt;
	bx lr	@ Return to caller&lt;br /&gt;
&lt;br /&gt;
.type ConfigurePA8, %function&lt;br /&gt;
ConfigurePA8:&lt;br /&gt;
	ldr r1, =GPIOA_CRH&lt;br /&gt;
	ldr r0, [r1]&lt;br /&gt;
	and r0, #0xfffffff0&lt;br /&gt;
	orr r0, #GPIOx_CRx_GP_PP_2MHz&lt;br /&gt;
	str r0, [r1]					@ Set CNF8:MODE8 in GPIOA_CRH to 2&lt;br /&gt;
	bx lr&lt;br /&gt;
	.ltorg&lt;br /&gt;
&lt;br /&gt;
@ r0 = Count-Down value for timer&lt;br /&gt;
.type InitializeSysTick, %function&lt;br /&gt;
StartSysTick:&lt;br /&gt;
	ldr r1, =SCS&lt;br /&gt;
&lt;br /&gt;
	str r0, [r1, #SCS_SYST_RVR]&lt;br /&gt;
	ldr r0, =0&lt;br /&gt;
	str r0, [r1, #SCS_SYST_CVR]&lt;br /&gt;
&lt;br /&gt;
	ldr r0, =5&lt;br /&gt;
	str r0, [r1, #SCS_SYST_CSR]&lt;br /&gt;
&lt;br /&gt;
	bx lr&lt;br /&gt;
&lt;br /&gt;
@ r0 = Number of timer events to wait for&lt;br /&gt;
.type WaitSysTick, %function   &lt;br /&gt;
WaitSysTick:&lt;br /&gt;
	ldr r1,	 =SCS&lt;br /&gt;
	&lt;br /&gt;
WaitSysTickLoop:&lt;br /&gt;
	ldr r2, [r1, #SCS_SYST_CSR]&lt;br /&gt;
	tst r2, #0x10000&lt;br /&gt;
	beq WaitSysTickLoop&lt;br /&gt;
&lt;br /&gt;
	subs r0, #1&lt;br /&gt;
	bne WaitSysTickLoop&lt;br /&gt;
&lt;br /&gt;
	bx lr&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “BlinkSysTick”&lt;br /&gt;
&lt;br /&gt;
This way, the blinker frequency will be as stable and accurate as possible with the given clock source.&lt;br /&gt;
=== Exceptions &amp;amp; Interrupts ===&lt;br /&gt;
Exceptions and interrupts play an important role in low-level development. They provide a facility for hardware to notify the software of events, such as received data blocks or a timer event. On ARM, interrupts are a sub-group of exceptions – there are some “system-level” exceptions mostly for dealing with processor errors and providing operating system support, while interrupts are “special” exceptions for events signaled by periphery modules. When writing “regular” microcontroller software, you will mostly work with interrupts.&lt;br /&gt;
&lt;br /&gt;
Exceptions (and interrupts) interrupt normal program flow, and cause the processor to execute some other piece of code which is called the exception handler or Interrupt Service Routine (ISR) (even for the “system-level” exceptions that are not interrupts). After dealing with the indicated event, the ISR typically returns and normal program flow resumes. As exceptions can interrupt the program anytime, data (and periphery) may be in any kind of inconsistent state, so special care must be taken to avoid corrupting program state in an ISR. The ARMv7-M processor (including the Cortex-M3) provide sophisticated support for exceptions, with configurable priorities and nested exception calls. This chapter will only cover the basics for using exceptions.&lt;br /&gt;
&lt;br /&gt;
On ARMv7-M, exception handlers are implemented as regular functions, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.type SysTick_Handler, %function&lt;br /&gt;
.global SysTick_Handler&lt;br /&gt;
SysTick_Handler:&lt;br /&gt;
	@ Handle event ...&lt;br /&gt;
	bx lr&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Like any other function, it has a label, returns with “bx lr”, and is also made globally visible to other source files using “.global”. The “.type … %function” is required here for the same reason as for the already-mentioned “Reset_Handler”. Exception handlers can be located anywhere in flash memory, among the other regular functions. To tell the processor where the exception handlers for the various exception types are located, the vector table needs to be adjusted. Until now, the vector table was defined as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.section .VectorTable, &amp;quot;a&amp;quot;&lt;br /&gt;
.word _StackEnd&lt;br /&gt;
.word Reset_Handler&lt;br /&gt;
.space 0xe4&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Recall that the first 32bit-word in flash memory contains the initial stack pointer (defined via “.word _StackEnd”) and the second word contains the address of the first instruction of the program (defined via “.word Reset_Handler”). Actually, resetting the controller is an exception too, and the code to be executed after reset (or start-up) is the handler for the reset exception (hence the name “Reset_Handler”). The next 228 bytes of flash memory contain 57 32bit-addresses of the handlers of the other exceptions, including interrupts. The “.space” directive just fills those with zeroes. To tell the processor the address of an exception handler, the appropriate entry in this table needs to be set to that address. In chapter 10.1.2, table 63 of the controller’s reference manual, the format of the vector table, and which exception’s address should go where, is defined. Only the interrupts up until position 42 actually exist on the STM32F103RB/C8, as defined in chapter 2.3.5 of the datasheet; everything from “TIM8_BRK” is only present on larger controllers. According to the table, the SysTick exception handler’s address needs to be put at location 0x3C relative to the beginning of flash memory. Since the first 8 bytes are already occupied, 0x34 bytes of space are needed after those first 8 bytes.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.section .VectorTable, &amp;quot;a&amp;quot;&lt;br /&gt;
.word _StackEnd&lt;br /&gt;
.word Reset_Handler&lt;br /&gt;
.space 0x34&lt;br /&gt;
.word SysTick_Handler&lt;br /&gt;
.space 0xac&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this modification, the SysTick_Handler function is now declared as the handler for the SysTick exception. By default, the SysTick timer does not trigger an exception. To do that, you have to set bit 2 in the SCS_SYST_CSR register. By placing the logic for the blinker into the timer&#039;s ISR, you get an interrupt-based blinker:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
RCC_APB2ENR = 0x40021018&lt;br /&gt;
RCC_APB2ENR_IOPAEN = 4&lt;br /&gt;
GPIOA_CRH = 0x40010804&lt;br /&gt;
&lt;br /&gt;
GPIOA_BSRR = 0x40010810&lt;br /&gt;
GPIOx_BSRR_BS8 = 0x100&lt;br /&gt;
GPIOx_BSRR_BR8 = 0x1000000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
GPIOx_CRx_GP_PP_2MHz = 2&lt;br /&gt;
&lt;br /&gt;
SCS = 0xe000e000&lt;br /&gt;
SCS_SYST_CSR = 0x10&lt;br /&gt;
SCS_SYST_RVR = 0x14&lt;br /&gt;
SCS_SYST_CVR = 0x18&lt;br /&gt;
TimerValue=1500000&lt;br /&gt;
&lt;br /&gt;
.data&lt;br /&gt;
Variables:&lt;br /&gt;
BlinkStep:&lt;br /&gt;
	.space 1&lt;br /&gt;
TimerEvents:&lt;br /&gt;
	.space 1&lt;br /&gt;
&lt;br /&gt;
.text&lt;br /&gt;
.type Reset_Handler, %function&lt;br /&gt;
.global Reset_Handler&lt;br /&gt;
Reset_Handler:&lt;br /&gt;
	ldr r0, =Variables&lt;br /&gt;
	ldr r1, =0&lt;br /&gt;
	str r1, [r0, #(BlinkStep-Variables)]&lt;br /&gt;
	ldr r1, BlinkTable&lt;br /&gt;
	str r1, [r0, #(TimerEvents-Variables)]&lt;br /&gt;
	&lt;br /&gt;
	bl EnableClockGPIOA&lt;br /&gt;
	bl ConfigurePA8&lt;br /&gt;
	&lt;br /&gt;
	ldr r1, =GPIOx_BSRR_BS8&lt;br /&gt;
	ldr r0, =GPIOA_BSRR			@ Load address of GPIOA_BSRR&lt;br /&gt;
	str r1, [r0]&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	ldr r0, =TimerValue&lt;br /&gt;
	bl StartSysTick&lt;br /&gt;
	SleepLoop:&lt;br /&gt;
		wfi&lt;br /&gt;
		b SleepLoop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.type SysTick_Handler, %function&lt;br /&gt;
.global SysTick_Handler&lt;br /&gt;
SysTick_Handler:&lt;br /&gt;
	ldr r0, =SCS&lt;br /&gt;
	ldr r0, [r0, #SCS_SYST_CSR]&lt;br /&gt;
	tst r0, #0x10000&lt;br /&gt;
	beq Return&lt;br /&gt;
	&lt;br /&gt;
	ldr r0, =Variables&lt;br /&gt;
	&lt;br /&gt;
	ldrb r1, [r0, #(BlinkStep-Variables)]&lt;br /&gt;
	&lt;br /&gt;
	cmp r1, #(BlinkTableEnd-BlinkTable)&lt;br /&gt;
	bhs Return&lt;br /&gt;
	&lt;br /&gt;
	ldrb r3, [r0, #(TimerEvents-Variables)]&lt;br /&gt;
	subs r3, #1&lt;br /&gt;
	&lt;br /&gt;
	itt ne&lt;br /&gt;
	strbne r3, [r0, #(TimerEvents-Variables)]&lt;br /&gt;
	bne Return&lt;br /&gt;
	&lt;br /&gt;
	add r1, #1&lt;br /&gt;
	cmp r1, #(BlinkTableEnd-BlinkTable)&lt;br /&gt;
	bhs SkipRestart&lt;br /&gt;
	&lt;br /&gt;
	ldr r2, =BlinkTable&lt;br /&gt;
	ldrb r3, [r2, r1]&lt;br /&gt;
	strb r3, [r0, #(TimerEvents-Variables)]&lt;br /&gt;
&lt;br /&gt;
SkipRestart:&lt;br /&gt;
	strb r1, [r0, #(BlinkStep-Variables)]&lt;br /&gt;
	&lt;br /&gt;
	ands r1, #1&lt;br /&gt;
	ite eq&lt;br /&gt;
	ldreq r1, =GPIOx_BSRR_BS8&lt;br /&gt;
	ldrne r1, =GPIOx_BSRR_BR8&lt;br /&gt;
	&lt;br /&gt;
	ldr r0, =GPIOA_BSRR			@ Load address of GPIOA_BSRR&lt;br /&gt;
	str r1, [r0]&lt;br /&gt;
&lt;br /&gt;
Return:&lt;br /&gt;
	bx lr&lt;br /&gt;
&lt;br /&gt;
.align 2&lt;br /&gt;
BlinkTable:&lt;br /&gt;
	.byte	2, 2, 2, 2, 2, 2&lt;br /&gt;
	.byte	5, 2, 5, 2, 5, 2&lt;br /&gt;
	.byte	2, 2, 2, 2, 2&lt;br /&gt;
BlinkTableEnd:&lt;br /&gt;
&lt;br /&gt;
.align 2&lt;br /&gt;
&lt;br /&gt;
.type EnableClockGPIOA, %function&lt;br /&gt;
EnableClockGPIOA:&lt;br /&gt;
	ldr r1, =RCC_APB2ENR&lt;br /&gt;
	ldr r0, [r1]&lt;br /&gt;
	orr r0, r0, #RCC_APB2ENR_IOPAEN&lt;br /&gt;
	str r0, [r1]			@ Set IOPAEN bit in RCC_APB2ENR to 1 to enable GPIOA&lt;br /&gt;
	bx lr	@ Return to caller&lt;br /&gt;
&lt;br /&gt;
.type ConfigurePA8, %function&lt;br /&gt;
ConfigurePA8:&lt;br /&gt;
	ldr r1, =GPIOA_CRH&lt;br /&gt;
	ldr r0, [r1]&lt;br /&gt;
	and r0, #0xfffffff0&lt;br /&gt;
	orr r0, #GPIOx_CRx_GP_PP_2MHz&lt;br /&gt;
	str r0, [r1]			@ Set CNF8:MODE8 in GPIOA_CRH to 2&lt;br /&gt;
	bx lr&lt;br /&gt;
	.ltorg&lt;br /&gt;
&lt;br /&gt;
@ r0 = Count-Down value for timer&lt;br /&gt;
.type InitializeSysTick, %function&lt;br /&gt;
StartSysTick:&lt;br /&gt;
	ldr r1, =SCS&lt;br /&gt;
&lt;br /&gt;
	str r0, [r1, #SCS_SYST_RVR]&lt;br /&gt;
	ldr r0, =0&lt;br /&gt;
	str r0, [r1, #SCS_SYST_CVR]&lt;br /&gt;
&lt;br /&gt;
	ldr r0, =7&lt;br /&gt;
	str r0, [r1, #SCS_SYST_CSR]&lt;br /&gt;
&lt;br /&gt;
	bx lr&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “BlinkSysTickInterrupt”&lt;br /&gt;
&lt;br /&gt;
The regular program flow now consists only of initializing the periphery, timer, and the first step of the blinker (setting the pin high). After that, the processor should do nothing but wait for exceptions, which is achieved by a simple endless loop. The “wfi” instruction suspends the processor; when an exception occurs, the processor will wake up, execute the ISR, and return execution after the “wfi”. Therefore, “wfi” is usually put in an endless loop as shown. This technique can reduce the processor’s power consumption significantly, as it is only running when something needs to be done, as indicated via interrupts. The ISR first checks whether the interrupt flag in the timer register is set - this is necessary, since exceptions can sometimes occur “spuriously”, i.e. without an actual event causing it. The decision whether to set or reset the pin state is taken based on the lowest bit of the table index, such that the output alternates between 1 and 0.&lt;br /&gt;
&lt;br /&gt;
The code inside the ISR needs to know which step in the blinking sequence is currently active, and how many timer events have already occurred inside the current step. Therefore, two 1-byte-variables are stored in RAM. To access them, offset addressing is used, where r0 contains the base address of the variables in memory, and the offsets inside “ldrb” and “strb” are set accordingly. The last number of the blink sequence table is omitted, since it is actually superfluous, because no action is taken after the last delay has elapsed. Because the table size is now odd, an “.align” directive after it is required. Always putting “.align” after outputting data is a good idea anyways.&lt;br /&gt;
&lt;br /&gt;
Since exceptions can occur at any point in regular program flow, the processor registers may contain some data that will be used after the exception handler returns. Therefore, if the exception handler writes anything into the registers, they need to be restored when returning from the exception. Upon exception entry, the Cortex-M3/4 processors automatically store the registers r0-r3, r12, r14 (LR) and APSR (including the flags) on the stack. The link register is filled with a special “dummy” value, and when the exception handler returns via “bx lr” using this value, the processor restores said registers to their previous state. This effectively means that you can implement exception handlers like any other function, i.e. freely overwrite r0-r3, r12 and the flags and push/pop r4-r11 and the LR if needed.&lt;br /&gt;
=== Macros ===&lt;br /&gt;
The assembler provides a few mechanisms to make assembly-language development easier. One of those are macros, which allow you to define snippets of assembly code that you can then insert easily whenever you need them. While looking similar to function invocations, the code inside the macro is actually copied each time the macro is used, so don’t overuse them. Macros are started with “.macro” and end at the next “.endm” directive. For example, the following macro sets the LED pin to 0 or 1:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.macro SETLED value&lt;br /&gt;
	ldr r0, =GPIOA_BSRR&lt;br /&gt;
	ldr r1, =(((!\value) &amp;lt;&amp;lt; 24) | (\value&amp;lt;&amp;lt;8))&lt;br /&gt;
	str r1, [r0]&lt;br /&gt;
.endm&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
SETLED 0&lt;br /&gt;
SETLED 1&lt;br /&gt;
.endm&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The macro name is defined as “SETLED”, and a single parameter with name “value” is given. By typing “\type”, the value of the parameter is substituted in the macro body. Some bit-shifting is used to calculate the right bit pattern to write into BSRR to set or reset the pin accordingly.&lt;br /&gt;
=== Weak symbols ===&lt;br /&gt;
As explained before, labels defined in assembly files get translated into symbols in the object code files, which are resolved by the linker. Sometimes it is desirable to provide a “default” or “fallback” implementation of some function (or data block) which is only used when no other implementation is given. This can be achieved by marking the “fallback” variant with “.weak”:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.type Function1, %function&lt;br /&gt;
.global Function1&lt;br /&gt;
.weak Function1&lt;br /&gt;
Function1:&lt;br /&gt;
	@ Default implementation …&lt;br /&gt;
…&lt;br /&gt;
bl Function1	@ Call the function&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
With this code alone, “Function1” will be used normally. If you put another function with the same name in a different assembly source file, that second variant will be used.&lt;br /&gt;
=== Symbol aliases ===&lt;br /&gt;
It is also possible to define aliases for symbols using “.thumb_set”, which sets the address accordingly. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.type Function1, %function&lt;br /&gt;
.global Function1&lt;br /&gt;
Function1:&lt;br /&gt;
	@ Some Code&lt;br /&gt;
&lt;br /&gt;
.thumb_set Function2, Function1&lt;br /&gt;
…&lt;br /&gt;
bl Function2	@ Call the function&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
When trying to call “Function2”, the linker will automatically fill in the address of “Function1”. This can also be combined with “.weak” to define a weak alias:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.type Function1, %function&lt;br /&gt;
.global Function1&lt;br /&gt;
Function1:&lt;br /&gt;
	@ Some Code&lt;br /&gt;
&lt;br /&gt;
.weak Function2&lt;br /&gt;
.thumb_set Function2, Function1&lt;br /&gt;
…&lt;br /&gt;
bl Function2	@ Call the function&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you now define another “Function2” in a different assembly source file, that will be used. If not, “Function1” will be called, which is the target of the alias definition. This is useful if you want to define one default implementation for several different functions, for each of which you need one “.weak” and one “.thumb_set” directive.&lt;br /&gt;
=== Improved vector table ===&lt;br /&gt;
The techniques from the last three sections can be used to improve the definition of the vector table. The way it was defined before is not very flexible; to insert new entries, you have to calculate the new gap sizes and offsets. First, define a default handler ISR that is called by exceptions for which no other ISR is defined, and a macro that defines an alias for one exception with the default handler as the target, and finally a table of all exceptions by using the macro:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.macro defisr name&lt;br /&gt;
	.global \name&lt;br /&gt;
	.weak \name&lt;br /&gt;
	.thumb_set \name, Default_Handler&lt;br /&gt;
	.word \name&lt;br /&gt;
.endm&lt;br /&gt;
&lt;br /&gt;
.global VectorTable&lt;br /&gt;
.section .VectorTable, &amp;quot;a&amp;quot;&lt;br /&gt;
.type VectorTable, %object&lt;br /&gt;
VectorTable:&lt;br /&gt;
.word _StackEnd&lt;br /&gt;
defisr Reset_Handler&lt;br /&gt;
defisr NMI_Handler&lt;br /&gt;
defisr HardFault_Handler&lt;br /&gt;
defisr MemManage_Handler&lt;br /&gt;
defisr BusFault_Handler&lt;br /&gt;
defisr UsageFault_Handler&lt;br /&gt;
.word 0&lt;br /&gt;
.word 0&lt;br /&gt;
.word 0&lt;br /&gt;
.word 0&lt;br /&gt;
defisr SVC_Handler&lt;br /&gt;
defisr DebugMon_Handler&lt;br /&gt;
.word 0&lt;br /&gt;
defisr PendSV_Handler&lt;br /&gt;
defisr SysTick_Handler&lt;br /&gt;
defisr WWDG_IRQHandler&lt;br /&gt;
defisr PVD_IRQHandler&lt;br /&gt;
defisr TAMPER_IRQHandler&lt;br /&gt;
defisr RTC_IRQHandler&lt;br /&gt;
defisr FLASH_IRQHandler&lt;br /&gt;
defisr RCC_IRQHandler&lt;br /&gt;
defisr EXTI0_IRQHandler&lt;br /&gt;
defisr EXTI1_IRQHandler&lt;br /&gt;
defisr EXTI2_IRQHandler&lt;br /&gt;
defisr EXTI3_IRQHandler&lt;br /&gt;
defisr EXTI4_IRQHandler&lt;br /&gt;
defisr DMA1_Channel1_IRQHandler&lt;br /&gt;
defisr DMA1_Channel2_IRQHandler&lt;br /&gt;
defisr DMA1_Channel3_IRQHandler&lt;br /&gt;
defisr DMA1_Channel4_IRQHandler&lt;br /&gt;
defisr DMA1_Channel5_IRQHandler&lt;br /&gt;
defisr DMA1_Channel6_IRQHandler&lt;br /&gt;
defisr DMA1_Channel7_IRQHandler&lt;br /&gt;
defisr ADC1_2_IRQHandler&lt;br /&gt;
defisr USB_HP_CAN1_TX_IRQHandler&lt;br /&gt;
defisr USB_LP_CAN1_RX0_IRQHandler&lt;br /&gt;
defisr CAN1_RX1_IRQHandler&lt;br /&gt;
defisr CAN1_SCE_IRQHandler&lt;br /&gt;
defisr EXTI9_5_IRQHandler&lt;br /&gt;
defisr TIM1_BRK_IRQHandler&lt;br /&gt;
defisr TIM1_UP_IRQHandler&lt;br /&gt;
defisr TIM1_TRG_COM_IRQHandler&lt;br /&gt;
defisr TIM1_CC_IRQHandler&lt;br /&gt;
defisr TIM2_IRQHandler&lt;br /&gt;
defisr TIM3_IRQHandler&lt;br /&gt;
defisr TIM4_IRQHandler&lt;br /&gt;
defisr I2C1_EV_IRQHandler&lt;br /&gt;
defisr I2C1_ER_IRQHandler&lt;br /&gt;
defisr I2C2_EV_IRQHandler&lt;br /&gt;
defisr I2C2_ER_IRQHandler&lt;br /&gt;
defisr SPI1_IRQHandler&lt;br /&gt;
defisr SPI2_IRQHandler&lt;br /&gt;
defisr USART1_IRQHandler&lt;br /&gt;
defisr USART2_IRQHandler&lt;br /&gt;
defisr USART3_IRQHandler&lt;br /&gt;
defisr EXTI15_10_IRQHandler&lt;br /&gt;
defisr RTCAlarm_IRQHandler&lt;br /&gt;
defisr USBWakeUp_IRQHandler&lt;br /&gt;
&lt;br /&gt;
.text&lt;br /&gt;
&lt;br /&gt;
.type Default_Handler, %function&lt;br /&gt;
.global Default_Handler&lt;br /&gt;
Default_Handler:&lt;br /&gt;
	bkpt&lt;br /&gt;
	b.n Default_Handler&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
There are a few empty entries in the table that are not used by the processor. At the beginning, there is still the definition for the initial stack pointer and the “Reset_Handler”. If you replace your “vectortable.S” by this code, you get a “proper” vector table. The “SysTick_Handler” will continue to work as before, and if you need to define any other ISR, for example for USART1, just define a function by the exact name “USART1_IRQHandler”. The address of this function will automatically be put in the vector table. If an exception without a corresponding ISR occurs, the “Default_Handler” will be called, which uses the “bkpt” instruction to force a breakpoint via the attached debugger. This helps debugging missed exceptions while avoiding to define several individual dummy handler functions.&lt;br /&gt;
=== .include ===&lt;br /&gt;
Having to put the register and bit definitions (“RCC_APB2ENR”, “RCC_APB2ENR_IOPAEN”, ...) in each assembly source file is redundant and error-prone. Instead, you can put them into a separate file (e.g. called “stm32f103.inc”) and use the “.include” directive to reference it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.include &amp;quot;stm32f103.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
@ Normal code ...&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The assembler will read the code from the included file and pretend it was written instead of the “.include” line. This can help improve code structure. While working on the project structure, you can also restructure the definitions for the GPIO registers to facilitate offset addressing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
GPIOA = 0x40010800&lt;br /&gt;
&lt;br /&gt;
GPIOx_CRH = 0x4&lt;br /&gt;
GPIOx_BSRR = 0x10&lt;br /&gt;
GPIOx_BSRR_BS8 = 0x100&lt;br /&gt;
GPIOx_BSRR_BR8 = 0x1000000&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The next example incorporates these changes in addressing the registers.&lt;br /&gt;
=== Local Labels ===&lt;br /&gt;
Having to invent unique labels for all jump targets inside functions (e.g. for conditional code and loops) can be tedious. When using a disassembler (see below), each label will appear as its own functions. Therefore, the GNU assembler supports local labels. These are labels whose name consist only a number. Local names need not be unique; several labels called e.g. “1” may exist in one file. To perform a jump to a local label, use the number and append a “f” or “b” to indicate whether to jump forward or backward. Local labels can not be exported with the “.global” directive. The interrupt-based blinker can be modified like this using local labels:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.include &amp;quot;stm32f103.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
TimerValue=1500000&lt;br /&gt;
&lt;br /&gt;
.data&lt;br /&gt;
Variables:&lt;br /&gt;
BlinkStep:&lt;br /&gt;
	.space 1&lt;br /&gt;
TimerEvents:&lt;br /&gt;
	.space 1&lt;br /&gt;
&lt;br /&gt;
.text&lt;br /&gt;
.type Reset_Handler, %function&lt;br /&gt;
.global Reset_Handler&lt;br /&gt;
Reset_Handler:&lt;br /&gt;
	ldr r0, =Variables&lt;br /&gt;
	ldr r1, =0&lt;br /&gt;
	str r1, [r0, #(BlinkStep-Variables)]&lt;br /&gt;
	ldr r1, BlinkTable&lt;br /&gt;
	str r1, [r0, #(TimerEvents-Variables)]&lt;br /&gt;
	&lt;br /&gt;
	bl EnableClockGPIOA&lt;br /&gt;
	bl ConfigurePA8&lt;br /&gt;
	&lt;br /&gt;
	ldr r1, =GPIOx_BSRR_BS8&lt;br /&gt;
	ldr r0, =GPIOA				@ Load address of GPIOA_BSRR&lt;br /&gt;
	str r1, [r0, #GPIOx_BSRR]&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	ldr r0, =TimerValue&lt;br /&gt;
	bl StartSysTick&lt;br /&gt;
	1:&lt;br /&gt;
		wfi&lt;br /&gt;
		b 1b&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
.type SysTick_Handler, %function&lt;br /&gt;
.global SysTick_Handler&lt;br /&gt;
SysTick_Handler:&lt;br /&gt;
	ldr r0, =SCS&lt;br /&gt;
	ldr r0, [r0, #SCS_SYST_CSR]&lt;br /&gt;
	tst r0, #0x10000&lt;br /&gt;
	beq 2f&lt;br /&gt;
	&lt;br /&gt;
	ldr r0, =Variables&lt;br /&gt;
	&lt;br /&gt;
	ldrb r1, [r0, #(BlinkStep-Variables)]&lt;br /&gt;
	&lt;br /&gt;
	cmp r1, #(BlinkTableEnd-BlinkTable)&lt;br /&gt;
	bhs 2f&lt;br /&gt;
	&lt;br /&gt;
	ldrb r3, [r0, #(TimerEvents-Variables)]&lt;br /&gt;
	subs r3, #1&lt;br /&gt;
	&lt;br /&gt;
	itt ne&lt;br /&gt;
	strbne r3, [r0, #(TimerEvents-Variables)]&lt;br /&gt;
	bne 2f&lt;br /&gt;
	&lt;br /&gt;
	add r1, #1&lt;br /&gt;
	cmp r1, #(BlinkTableEnd-BlinkTable)&lt;br /&gt;
	bhs 1f&lt;br /&gt;
	&lt;br /&gt;
	ldr r2, =BlinkTable&lt;br /&gt;
	ldrb r3, [r2, r1]&lt;br /&gt;
	strb r3, [r0, #(TimerEvents-Variables)]&lt;br /&gt;
&lt;br /&gt;
1:&lt;br /&gt;
	strb r1, [r0, #(BlinkStep-Variables)]&lt;br /&gt;
	&lt;br /&gt;
	ands r1, #1&lt;br /&gt;
	ite eq&lt;br /&gt;
	ldreq r1, =GPIOx_BSRR_BS8&lt;br /&gt;
	ldrne r1, =GPIOx_BSRR_BR8&lt;br /&gt;
	&lt;br /&gt;
	ldr r0, =GPIOA			@ Load address of GPIOA_BSRR&lt;br /&gt;
	str r1, [r0, #GPIOx_BSRR]&lt;br /&gt;
&lt;br /&gt;
2:&lt;br /&gt;
	bx lr&lt;br /&gt;
&lt;br /&gt;
.align 2&lt;br /&gt;
.type BlinkTable,%object	&lt;br /&gt;
BlinkTable:&lt;br /&gt;
	.byte	2, 2, 2, 2, 2, 2&lt;br /&gt;
	.byte	5, 2, 5, 2, 5, 2&lt;br /&gt;
	.byte	2, 2, 2, 2, 2&lt;br /&gt;
BlinkTableEnd:&lt;br /&gt;
&lt;br /&gt;
.align 2&lt;br /&gt;
&lt;br /&gt;
.type EnableClockGPIOA, %function&lt;br /&gt;
EnableClockGPIOA:&lt;br /&gt;
	ldr r1, =RCC&lt;br /&gt;
	ldr r0, [r1, #RCC_APB2ENR]&lt;br /&gt;
	orr r0, r0, #(1 &amp;lt;&amp;lt; RCC_APB2ENR_IOPAEN)&lt;br /&gt;
	str r0, [r1, #RCC_APB2ENR]			@ Set IOPAEN bit in RCC_APB2ENR to 1 to enable GPIOA&lt;br /&gt;
	bx lr	@ Return to caller&lt;br /&gt;
&lt;br /&gt;
.type ConfigurePA8, %function&lt;br /&gt;
ConfigurePA8:&lt;br /&gt;
	ldr r1, =GPIOA&lt;br /&gt;
	ldr r0, [r1, #GPIOx_CRH]&lt;br /&gt;
	and r0, #0xfffffff0&lt;br /&gt;
	orr r0, #GPIOx_CRx_GP_PP_2MHz&lt;br /&gt;
	str r0, [r1, #GPIOx_CRH]			@ Set CNF8:MODE8 in GPIOA_CRH to 2&lt;br /&gt;
	bx lr&lt;br /&gt;
	.ltorg&lt;br /&gt;
&lt;br /&gt;
@ r0 = Count-Down value for timer&lt;br /&gt;
.type InitializeSysTick, %function&lt;br /&gt;
StartSysTick:&lt;br /&gt;
	ldr r1, =SCS&lt;br /&gt;
&lt;br /&gt;
	str r0, [r1, #SCS_SYST_RVR]&lt;br /&gt;
	ldr r0, =0&lt;br /&gt;
	str r0, [r1, #SCS_SYST_CVR]&lt;br /&gt;
&lt;br /&gt;
	ldr r0, =7&lt;br /&gt;
	str r0, [r1, #SCS_SYST_CSR]&lt;br /&gt;
&lt;br /&gt;
	bx lr&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “BlinkLocalLabels”&lt;br /&gt;
=== Initializing RAM ===&lt;br /&gt;
The blinker program uses 2 byte-variables in memory, which have to be initialized to some value at startup. For large programs with many variables, this quickly becomes hard to maintain and also inefficient. Assembler and linker can help producing an “image” of how the RAM contents should look like after initializing, and place this image in flash memory alongside the normal program data. At startup, this image can be simply copied 1:1 into RAM in a loop. Most programs contain many variables that will be initialized with zero, so placing a (possibly large) block of zeroes in flash memory is wasteful; therefore, an additional loop is used to initialize all zero-variables to zero. Both techniques are also employed by C and C++ compilers, so implementing the initialization code is required there too. First, change the declaration of your variables by using “.byte”, “.hword” and “.word” and include the desired initialization value. Variables that should be initialized by zero get to be placed after a “.bss” directive to put them into the equally-named section. They don’t get an initialization value but just reserved space by using “.space”:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.data&lt;br /&gt;
TimerEvents:&lt;br /&gt;
	.byte 2&lt;br /&gt;
&lt;br /&gt;
.bss&lt;br /&gt;
BlinkStep:&lt;br /&gt;
	.space 1&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
From the assembler’s point of view, the initialization data - in this case, just one byte of value “2” - will directly end up in RAM. However, this is not possible on microcontrollers, as the RAM always contains random data on startup and isn’t automatically initialized. To achieve that, change the linker script as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
MEMORY {&lt;br /&gt;
	FLASH	: ORIGIN = 0x8000000,	LENGTH = 128K&lt;br /&gt;
	SRAM	: ORIGIN = 0x20000000,	LENGTH =  20K&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
SECTIONS {&lt;br /&gt;
	.VectorTable : {&lt;br /&gt;
		*(.VectorTable)&lt;br /&gt;
	} &amp;gt;FLASH&lt;br /&gt;
	&lt;br /&gt;
	.text : {&lt;br /&gt;
		*(.text)&lt;br /&gt;
		. = ALIGN(4);&lt;br /&gt;
	} &amp;gt;FLASH&lt;br /&gt;
	&lt;br /&gt;
	.stack (NOLOAD) : {&lt;br /&gt;
		. = . + 0x400;&lt;br /&gt;
		_StackEnd = .;&lt;br /&gt;
	} &amp;gt;SRAM&lt;br /&gt;
	&lt;br /&gt;
	.data : {&lt;br /&gt;
		_DataStart = .;&lt;br /&gt;
		*(.data);&lt;br /&gt;
		. = ALIGN(4);&lt;br /&gt;
		_DataEnd = .;&lt;br /&gt;
	} &amp;gt;SRAM AT &amp;gt;FLASH&lt;br /&gt;
	&lt;br /&gt;
	_DataLoad = LOADADDR(.data);&lt;br /&gt;
	&lt;br /&gt;
	.bss : {&lt;br /&gt;
		_BssStart = .;&lt;br /&gt;
		*(.bss);&lt;br /&gt;
		. = ALIGN(4);&lt;br /&gt;
		_BssEnd = .;&lt;br /&gt;
	} &amp;gt;SRAM&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “BlinkInitRAM”&lt;br /&gt;
&lt;br /&gt;
The stack got put in its own section with the “NOLOAD” attribute, since it doesn’t need initializing. The data is now put in the “.data” section. The initial data for that section is put into flash memory via the “&amp;gt;SRAM AT &amp;gt;FLASH” construct. The addresses of symbols inside the “.data” section are still the addresses in RAM, so accesses to the symbols from assembly code still work. The symbol “_DataStart” is assigned the beginning of the initialized data in RAM, and “_DataEnd” the end. The “LOADADDR” function is used to get the beginning of the initialization data in flash, and assign it to “_DataLoad”. The “.bss” section contains all the variables that should be zero-initialized, and the symbols “_BssStart” and “_BssEnd” are set to its beginning and end address, respectively. As the beginning and size of the stack are already a multiple of 4, the beginning of “.data” is as well. The size of .data might not be a multiple of 4 however, so an “.=ALIGN(4)” command is inserted right before the definition of “_DataEnd”. This adds 0-3 dummy bytes by incrementing the location counter to make sure the address is a multiple of 4. The same thing is done right before “_BssEnd” and also at the end of the “.text” section, to make sure that “_BssEnd” and “_DataLoad” are multiples of 4 as well.&lt;br /&gt;
&lt;br /&gt;
The only thing left is the actual initialization of the RAM. To do that, change the “Reset_Handler” as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.text&lt;br /&gt;
.type Reset_Handler, %function&lt;br /&gt;
.global Reset_Handler&lt;br /&gt;
Reset_Handler:&lt;br /&gt;
	ldr r0, =_DataStart&lt;br /&gt;
	ldr r1, =_DataEnd&lt;br /&gt;
	ldr r2, =_DataLoad&lt;br /&gt;
&lt;br /&gt;
	b 2f&lt;br /&gt;
1:	ldr r3, [r2], #4&lt;br /&gt;
	str r3, [r0], #4&lt;br /&gt;
2:	cmp r0, r1&lt;br /&gt;
	blo 1b&lt;br /&gt;
	&lt;br /&gt;
	ldr r0, =_BssStart&lt;br /&gt;
	ldr r1, =_BssEnd&lt;br /&gt;
	ldr r2, =0&lt;br /&gt;
&lt;br /&gt;
	b 2f&lt;br /&gt;
1:	str r2, [r0], #4&lt;br /&gt;
2:	cmp r0, r1&lt;br /&gt;
	blo 1b&lt;br /&gt;
&lt;br /&gt;
	bl EnableClockGPIOA&lt;br /&gt;
	bl ConfigurePA8&lt;br /&gt;
&lt;br /&gt;
	ldr r1, =GPIOx_BSRR_BS8&lt;br /&gt;
	ldr r0, =GPIOA					@ Load address of GPIOA_BSRR&lt;br /&gt;
	str r1, [r0, #GPIOx_BSRR]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	ldr r0, =TimerValue&lt;br /&gt;
	bl StartSysTick&lt;br /&gt;
	1:&lt;br /&gt;
		wfi&lt;br /&gt;
		b 1b&lt;br /&gt;
	.ltorg&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The explicit initialization of the variables was removed. Instead, the addresses for “_DataStart”, “_DataEnd” and “_DataLoad” that were defined in the linker script are loaded. Then, a short loop repeatedly loads a word from flash (i.e. starting with “_DataLoad”) and stores it into RAM (starting at “_DataStart”). The address pointers are incremented by the “ldr”/”str” instructions after the access. The pointer for the RAM location is compared with the end of the RAM area (“_DataEnd”) to decide whether to jump back to the beginning of the loop. To start the loop, a jump directly to the comparison is performed; this avoids the need to do the comparison at the beginning and inside of the loop. The second loop performs the zero-initialization of the area between “_BssStart” and “_BssEnd”; it works similarly, but does not need to load any data.&lt;br /&gt;
&lt;br /&gt;
Unfortunately, the program as shown can’t be translated - as the two variables now reside in two different sections (“.data” and “.bss”), the offset addressing in the “SysTick_Handler” doesn’t work anymore. Therefore, direct addressing has to be used:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.type SysTick_Handler, %function&lt;br /&gt;
.global SysTick_Handler&lt;br /&gt;
SysTick_Handler:&lt;br /&gt;
	ldr r0, =SCS&lt;br /&gt;
	ldr r0, [r0, #SCS_SYST_CSR]&lt;br /&gt;
	tst r0, #0x10000&lt;br /&gt;
	beq 2f&lt;br /&gt;
	&lt;br /&gt;
	ldr r0, =BlinkStep&lt;br /&gt;
	&lt;br /&gt;
	ldrb r1, [r0]&lt;br /&gt;
	&lt;br /&gt;
	cmp r1, #(BlinkTableEnd-BlinkTable)&lt;br /&gt;
	bhs 2f&lt;br /&gt;
	&lt;br /&gt;
	ldr r0, =TimerEvents&lt;br /&gt;
	ldrb r3, [r0]&lt;br /&gt;
	subs r3, #1&lt;br /&gt;
	&lt;br /&gt;
	itt ne&lt;br /&gt;
	strbne r3, [r0]&lt;br /&gt;
	bne 2f&lt;br /&gt;
	&lt;br /&gt;
	add r1, #1&lt;br /&gt;
	cmp r1, #(BlinkTableEnd-BlinkTable)&lt;br /&gt;
	bhs 1f&lt;br /&gt;
	&lt;br /&gt;
	ldr r2, =BlinkTable&lt;br /&gt;
	ldrb r3, [r2, r1]&lt;br /&gt;
	strb r3, [r0]&lt;br /&gt;
&lt;br /&gt;
1:&lt;br /&gt;
	ldr r0, =BlinkStep&lt;br /&gt;
	strb r1, [r0]&lt;br /&gt;
	&lt;br /&gt;
	ands r1, #1&lt;br /&gt;
	ite eq&lt;br /&gt;
	ldreq r1, =GPIOx_BSRR_BS8&lt;br /&gt;
	ldrne r1, =GPIOx_BSRR_BR8&lt;br /&gt;
	&lt;br /&gt;
	ldr r0, =GPIOA				@ Load address of GPIOA_BSRR&lt;br /&gt;
	str r1, [r0, #GPIOx_BSRR]&lt;br /&gt;
&lt;br /&gt;
2:&lt;br /&gt;
	bx lr&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
=== Peripheral interrupts ===&lt;br /&gt;
Interrupts, i.e. exceptions called by periphery modules, need a little extra code compared to the “core” exceptions including the SysTick. The Cortex-M’s interrupt controller (the NVIC) contains several registers for configuring these interrupts. It is possible to configure the priority and manually trigger interrupts, but for most applications, the only necessary thing to do is enabling the desired interrupt. This is done via the registers “NVIC_ISER0” through “NVIC_ISER15”, which are documented in the ARMv7M Architecture Reference Manual in chapter B3.4.4. Each of those registers contains 32 bits with which 32 of the interrupts can be enabled. The STM32F103RB/C8 has 43 interrupts, so only two of the possible 16 registers are present. The number of interrupts is given in chapter 2.3.5 of the controller’s datasheet. So, to enable some interrupt x, the bit “x mod 32” in register NVIC_ISER&#039;&#039;y&#039;&#039; with y=x/32 has to be set. This register’s address is 0xE000E100+y*4. Given an interrupt’s number in r0, the following function does just that:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
NVIC_ISER0 = 0xE000E100&lt;br /&gt;
&lt;br /&gt;
@ r0 = IRQ Number&lt;br /&gt;
.type EnableIRQ, %function&lt;br /&gt;
EnableIRQ:&lt;br /&gt;
	ldr r1, =NVIC_ISER0&lt;br /&gt;
	&lt;br /&gt;
	movs r2, #1&lt;br /&gt;
	and r3, r0, #0x1F&lt;br /&gt;
	lsls r2, r2, r3&lt;br /&gt;
	&lt;br /&gt;
	lsrs r3, r0, #5&lt;br /&gt;
	lsls r3, r3, #2&lt;br /&gt;
	&lt;br /&gt;
	str r2, [r1, r3]&lt;br /&gt;
&lt;br /&gt;
	bx lr&lt;br /&gt;
	.ltorg&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Example name: “BlinkTIM1”&lt;br /&gt;
&lt;br /&gt;
The “and” instruction calculates “x mod 32”, and the following left-shift (“lsls”) calculates the value where bit “x mod 32” is one, and all others are zero. To calculate the offset address “y*4”, i.e. “(x/32)*4”, the register is first shifted right by 5 bits and then shifted back left by 2 bits. This is the same as shifting 3 bits right and zeroing out the lower 2 bits; but two shift instructions actually consume less program memory space. Finally, the calculated value is written into the register by using offset addressing.&lt;br /&gt;
&lt;br /&gt;
In addition to enabling the interrupt in the processor core’s NVIC, it also has to be enabled in the periphery module. Many periphery modules support several different events, each of which has to be enabled in the periphery’s register individually. Depending on the controller, these can be mapped to one single processor interrupt (and hence, one single ISR) or multiple ones, and need to be configured in the NVIC appropriately.&lt;br /&gt;
&lt;br /&gt;
This example uses the STM32’s periphery timer TIM1 instead of the SysTick timer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.include &amp;quot;stm32f103.inc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
TimerValue=1500&lt;br /&gt;
TimerPrescaler=1000&lt;br /&gt;
&lt;br /&gt;
.data&lt;br /&gt;
TimerEvents:&lt;br /&gt;
	.byte 2&lt;br /&gt;
&lt;br /&gt;
.bss&lt;br /&gt;
BlinkStep:&lt;br /&gt;
	.space 1&lt;br /&gt;
&lt;br /&gt;
.text&lt;br /&gt;
.type Reset_Handler, %function&lt;br /&gt;
.global Reset_Handler&lt;br /&gt;
Reset_Handler:&lt;br /&gt;
	ldr r0, =_DataStart&lt;br /&gt;
	ldr r1, =_DataEnd&lt;br /&gt;
	ldr r2, =_DataLoad&lt;br /&gt;
&lt;br /&gt;
	b 2f&lt;br /&gt;
1:	ldr r3, [r2], #4&lt;br /&gt;
	str r3, [r0], #4&lt;br /&gt;
2:	cmp r0, r1&lt;br /&gt;
	blo 1b&lt;br /&gt;
	&lt;br /&gt;
	ldr r0, =_BssStart&lt;br /&gt;
	ldr r1, =_BssEnd&lt;br /&gt;
	ldr r2, =0&lt;br /&gt;
&lt;br /&gt;
	b 2f&lt;br /&gt;
1:	str r2, [r0], #4&lt;br /&gt;
2:	cmp r0, r1&lt;br /&gt;
	blo 1b&lt;br /&gt;
&lt;br /&gt;
	bl EnableClockGPIOA&lt;br /&gt;
	bl EnableClockTIM1&lt;br /&gt;
	bl ConfigurePA8&lt;br /&gt;
&lt;br /&gt;
	ldr r1, =GPIOx_BSRR_BS8&lt;br /&gt;
	ldr r0, =GPIOA&lt;br /&gt;
	str r1, [r0, #GPIOx_BSRR]&lt;br /&gt;
&lt;br /&gt;
	ldr r0, =TIM1_UP_IRQn&lt;br /&gt;
	bl EnableIRQ&lt;br /&gt;
	bl StartTIM1&lt;br /&gt;
	1:&lt;br /&gt;
		wfi&lt;br /&gt;
		b 1b&lt;br /&gt;
	.ltorg&lt;br /&gt;
&lt;br /&gt;
.type TIM1_UP_IRQHandler, %function&lt;br /&gt;
.global TIM1_UP_IRQHandler&lt;br /&gt;
TIM1_UP_IRQHandler:&lt;br /&gt;
	ldr r0, =TIM1&lt;br /&gt;
	ldr r2, =(~(1 &amp;lt;&amp;lt; TIMx_SR_UIF))&lt;br /&gt;
	&lt;br /&gt;
	ldr r1, [r0, #TIMx_SR]&lt;br /&gt;
	bics r1, r2&lt;br /&gt;
	beq 2f&lt;br /&gt;
	&lt;br /&gt;
	str r2, [r0, #TIMx_SR]&lt;br /&gt;
	&lt;br /&gt;
	ldr r0, =BlinkStep&lt;br /&gt;
	&lt;br /&gt;
	ldrb r1, [r0]&lt;br /&gt;
	&lt;br /&gt;
	cmp r1, #(BlinkTableEnd-BlinkTable)&lt;br /&gt;
	bhs 2f&lt;br /&gt;
	&lt;br /&gt;
	ldr r0, =TimerEvents&lt;br /&gt;
	ldrb r3, [r0]&lt;br /&gt;
	subs r3, #1&lt;br /&gt;
	&lt;br /&gt;
	itt ne&lt;br /&gt;
	strbne r3, [r0]&lt;br /&gt;
	bne 2f&lt;br /&gt;
	&lt;br /&gt;
	add r1, #1&lt;br /&gt;
	cmp r1, #(BlinkTableEnd-BlinkTable)&lt;br /&gt;
	bhs 1f&lt;br /&gt;
	&lt;br /&gt;
	ldr r2, =BlinkTable&lt;br /&gt;
	ldrb r3, [r2, r1]&lt;br /&gt;
	strb r3, [r0]&lt;br /&gt;
&lt;br /&gt;
1:&lt;br /&gt;
	ldr r0, =BlinkStep&lt;br /&gt;
	strb r1, [r0]&lt;br /&gt;
	&lt;br /&gt;
	ands r1, #1&lt;br /&gt;
	ite eq&lt;br /&gt;
	ldreq r1, =GPIOx_BSRR_BS8&lt;br /&gt;
	ldrne r1, =GPIOx_BSRR_BR8&lt;br /&gt;
	&lt;br /&gt;
	ldr r0, =GPIOA&lt;br /&gt;
	str r1, [r0, #GPIOx_BSRR]&lt;br /&gt;
&lt;br /&gt;
2:&lt;br /&gt;
	bx lr&lt;br /&gt;
&lt;br /&gt;
.align 2&lt;br /&gt;
.type BlinkTable,%object	&lt;br /&gt;
BlinkTable:&lt;br /&gt;
	.byte	2, 2, 2, 2, 2, 2&lt;br /&gt;
	.byte	5, 2, 5, 2, 5, 2&lt;br /&gt;
	.byte	2, 2, 2, 2, 2&lt;br /&gt;
BlinkTableEnd:&lt;br /&gt;
&lt;br /&gt;
.align 2&lt;br /&gt;
&lt;br /&gt;
.type EnableClockGPIOA, %function&lt;br /&gt;
EnableClockGPIOA:&lt;br /&gt;
	ldr r1, =RCC&lt;br /&gt;
	ldr r0, [r1, #RCC_APB2ENR]&lt;br /&gt;
	orr r0, r0, #(1 &amp;lt;&amp;lt; RCC_APB2ENR_IOPAEN)&lt;br /&gt;
	str r0, [r1, #RCC_APB2ENR]				@ Set IOPAEN bit in RCC_APB2ENR to 1 to enable GPIOA&lt;br /&gt;
	bx lr	@ Return to caller&lt;br /&gt;
&lt;br /&gt;
.type EnableClockTIM1, %function&lt;br /&gt;
EnableClockTIM1:&lt;br /&gt;
	ldr r1, =RCC&lt;br /&gt;
	ldr r0, [r1, #RCC_APB2ENR]&lt;br /&gt;
	orr r0, r0, #(1 &amp;lt;&amp;lt; RCC_APB2ENR_TIM1EN)&lt;br /&gt;
	str r0, [r1, #RCC_APB2ENR]				@ Set TIM1EN bit in RCC_APB2ENR to 1 to enable TIM1&lt;br /&gt;
	bx lr	@ Return to caller&lt;br /&gt;
	.ltorg&lt;br /&gt;
&lt;br /&gt;
.type ConfigurePA8, %function&lt;br /&gt;
ConfigurePA8:&lt;br /&gt;
	ldr r1, =GPIOA&lt;br /&gt;
	ldr r0, [r1, #GPIOx_CRH]&lt;br /&gt;
	and r0, #0xfffffff0&lt;br /&gt;
	orr r0, #GPIOx_CRx_GP_PP_2MHz&lt;br /&gt;
	str r0, [r1, #GPIOx_CRH]				@ Set CNF8:MODE8 in GPIOA_CRH to 2&lt;br /&gt;
	bx lr&lt;br /&gt;
	.ltorg&lt;br /&gt;
&lt;br /&gt;
@ r0 = Count-Down value for timer&lt;br /&gt;
.type InitializeSysTick, %function&lt;br /&gt;
StartTIM1:&lt;br /&gt;
	ldr r0, =TIM1&lt;br /&gt;
	ldr r1, =(1 &amp;lt;&amp;lt; TIMx_CR1_URS)&lt;br /&gt;
	str r1, [r0, #TIMx_CR1]&lt;br /&gt;
	&lt;br /&gt;
	ldr r1, =TimerPrescaler&lt;br /&gt;
	str r1, [r0, #TIMx_PSC]&lt;br /&gt;
	&lt;br /&gt;
	ldr r1, =TimerValue&lt;br /&gt;
	str r1, [r0, #TIMx_ARR]&lt;br /&gt;
	&lt;br /&gt;
	ldr r1, =(1 &amp;lt;&amp;lt; TIMx_DIER_UIE)&lt;br /&gt;
	str r1, [r0, #TIMx_DIER]&lt;br /&gt;
	&lt;br /&gt;
	ldr r1, =(1 &amp;lt;&amp;lt; TIMx_EGR_UG)&lt;br /&gt;
	str r1, [r0, #TIMx_EGR]&lt;br /&gt;
	&lt;br /&gt;
	dsb&lt;br /&gt;
&lt;br /&gt;
	ldr r1, =(1 &amp;lt;&amp;lt; TIMx_CR1_CEN)&lt;br /&gt;
	str r1, [r0, #TIMx_CR1]&lt;br /&gt;
&lt;br /&gt;
	bx lr&lt;br /&gt;
	.ltorg&lt;br /&gt;
&lt;br /&gt;
@ r0 = IRQ Number&lt;br /&gt;
.type EnableIRQ, %function&lt;br /&gt;
EnableIRQ:&lt;br /&gt;
	ldr r1, =NVIC_ISER0&lt;br /&gt;
	&lt;br /&gt;
	movs r2, #1&lt;br /&gt;
	and r3, r0, #0x1F&lt;br /&gt;
	lsls r2, r2, r3&lt;br /&gt;
	&lt;br /&gt;
	lsrs r3, r0, #5&lt;br /&gt;
	lsls r3, r3, #2&lt;br /&gt;
	&lt;br /&gt;
	str r2, [r1, r3]&lt;br /&gt;
&lt;br /&gt;
	bx lr&lt;br /&gt;
	.ltorg&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The corresponding stm32f103.inc file with the added definitions for the timer registers is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
GPIOA = 0x40010800&lt;br /&gt;
&lt;br /&gt;
GPIOx_CRH = 0x4&lt;br /&gt;
GPIOx_BSRR = 0x10&lt;br /&gt;
GPIOx_BSRR_BS8 = 0x100&lt;br /&gt;
GPIOx_BSRR_BR8 = 0x1000000&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
GPIOx_CRx_GP_PP_2MHz = 2&lt;br /&gt;
&lt;br /&gt;
SCS = 0xe000e000&lt;br /&gt;
SCS_SYST_CSR = 0x10&lt;br /&gt;
SCS_SYST_RVR = 0x14&lt;br /&gt;
SCS_SYST_CVR = 0x18&lt;br /&gt;
&lt;br /&gt;
RCC = 0x40021000&lt;br /&gt;
RCC_APB2ENR = 0x18&lt;br /&gt;
RCC_APB2ENR_IOPAEN = 2&lt;br /&gt;
RCC_APB2ENR_TIM1EN = 11&lt;br /&gt;
&lt;br /&gt;
RCC_CR = 0x0&lt;br /&gt;
RCC_CR_PLLRDY = 25&lt;br /&gt;
RCC_CR_PLLON = 24&lt;br /&gt;
RCC_CR_HSERDY = 17&lt;br /&gt;
RCC_CR_HSEON = 16&lt;br /&gt;
RCC_CR_HSION = 0&lt;br /&gt;
&lt;br /&gt;
RCC_CFGR = 0x04&lt;br /&gt;
RCC_CFGR_PLLMUL = 18&lt;br /&gt;
RCC_CFGR_USBPRE = 22&lt;br /&gt;
RCC_CFGR_PLLXTPRE = 17&lt;br /&gt;
RCC_CFGR_PLLSRC = 16&lt;br /&gt;
RCC_CFGR_PPRE2 = 11&lt;br /&gt;
RCC_CFGR_PPRE1 = 8&lt;br /&gt;
RCC_CFGR_HPRE = 4&lt;br /&gt;
RCC_CFGR_SWS = 2&lt;br /&gt;
RCC_CFGR_SW = 0&lt;br /&gt;
&lt;br /&gt;
FLASH=0x40022000&lt;br /&gt;
FLASH_ACR=0&lt;br /&gt;
FLASH_ACR_PRFTBE = 4&lt;br /&gt;
FLASH_ACR_HLFCYA = 3&lt;br /&gt;
FLASH_ACR_LATENCY = 0&lt;br /&gt;
&lt;br /&gt;
TIM1 = 0x40012C00&lt;br /&gt;
&lt;br /&gt;
TIMx_CR1 = 0&lt;br /&gt;
TIMx_CR1_ARPE = 7&lt;br /&gt;
TIMx_CR1_URS = 2&lt;br /&gt;
TIMx_CR1_CEN = 0&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
TIMx_DIER = 0xC&lt;br /&gt;
TIMx_DIER_UIE = 0&lt;br /&gt;
&lt;br /&gt;
TIMx_SR = 0x10&lt;br /&gt;
TIMx_SR_UIF = 0&lt;br /&gt;
&lt;br /&gt;
TIMx_EGR = 0x14&lt;br /&gt;
TIMx_EGR_UG = 0&lt;br /&gt;
&lt;br /&gt;
TIMx_PSC = 0x28&lt;br /&gt;
TIMx_ARR = 0x2C&lt;br /&gt;
&lt;br /&gt;
TIM1_UP_IRQn = 25&lt;br /&gt;
&lt;br /&gt;
NVIC_ISER0 = 0xE000E100&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The source code enables the timer’s clock in the RCC before configuring it. The timer supports both a freely configurable prescaler for dividing the clock and a freely configurable maximum value, both of which are set by the StartTIM1 function. The TIMx_DIER_UIE bit is set to enable the interrupt for the so-called “update event”, which is triggered whenever the timer reaches the maximum value. A delicate sequence of register accesses is required to start the timer with the right configuration but without triggering the interrupt right away: To apply the modified settings immediately, the “TIMx_EGR_UG” bit is set to trigger an “artificial” update event. To prevent this from also triggering the interrupt, the “TIMx_CR1_URS” bit is set and cleared before and after, respectively. The timer is started by setting the “TIMx_CR1_CEN” bit at the end. Before that, a “dsb” instruction is inserted. This “Data Synchronization Barrier” waits until all write accesses before that have been completely processed - usually, the processors pipeline is working on several instructions at once. Because the timer configuration needs to be truly finished before starting the timer, this instruction is required. There are some other situations where the processor is too fast for the periphery and needs to be temporarily halted by a “dsb”. If some periphery-accessing code works in step-by-step mode while debugging, but not when executing normally, a well-placed “dsb” might help.&lt;br /&gt;
&lt;br /&gt;
The ISR “TIM1_UP_IRQHandler” is used for the timer. It checks the “TIMx_SR_UIF” bit to verify an update event has actually happened. In that case, the register is overwritten with the value 0xFFFFFFFE, i.e. all bits are written with “1” except the UIF bit. Writing ones has no effect on the bits in this register, and writing a zero clears the respective bit. Therefore, this write access clears the UIF bit but keeps the others. These interrupt flags must always be cleared as soon as possible in the ISR, or the periphery might trigger the interrupt again immediately. The rest of the ISR stays the same.&lt;br /&gt;
=== Analysis tools ===&lt;br /&gt;
When working on a low level directly with linker scripts and assembly code, it is frequently necessary to directly verify the translation output, as you can’t rely on a compiler doing it right automatically, and flashing the program each time to see whether it works isn’t the most efficient way. This was, in fact, important in creating the example codes for this tutorial. The “binutils” package, of which assembler and linker are part of, offers a few tools that help with analyzing the assembler’s and linker’s output.&lt;br /&gt;
==== Disassembler ====&lt;br /&gt;
As the name implies, a disassembler is the opposite of an assembler - it turns binary machine code back into a (more or less) readable textual representation. If you feed an ELF file generated by the assembler or linker into the disassembler, it will read the header information to tell apart data (i.e. constants) and code, get names of symbols (and therefore, labels) and can even tell which instructions were generated from which assembly source file, if it was assembler with debug information (i.e. the “-g” flag was used). If you disassemble a binary flash image, the disassembler doesn’t have all those information and will produce a much less readable output and attempt to decode data bytes as instructions.&lt;br /&gt;
&lt;br /&gt;
The disassembler from binutils is called “objdump”. Invoking it on the blinker looks like this:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ arm-none-eabi-objdump -d -s prog1.elf&lt;br /&gt;
&lt;br /&gt;
prog1.elf: 	file format elf32-littlearm&lt;br /&gt;
&lt;br /&gt;
Contents of section .VectorTable:&lt;br /&gt;
 8000000 00040020 ed000008 ed010008 ed010008  ... ............&lt;br /&gt;
 8000010 ed010008 ed010008 ed010008 00000000  ................&lt;br /&gt;
 8000020 00000000 00000000 00000000 ed010008  ................&lt;br /&gt;
 8000030 ed010008 00000000 ed010008 49010008  ............I...&lt;br /&gt;
 8000040 ed010008 ed010008 ed010008 ed010008  ................&lt;br /&gt;
 8000050 ed010008 ed010008 ed010008 ed010008  ................&lt;br /&gt;
 8000060 ed010008 ed010008 ed010008 ed010008  ................&lt;br /&gt;
 8000070 ed010008 ed010008 ed010008 ed010008  ................&lt;br /&gt;
 8000080 ed010008 ed010008 ed010008 ed010008  ................&lt;br /&gt;
 8000090 ed010008 ed010008 ed010008 ed010008  ................&lt;br /&gt;
 80000a0 ed010008 ed010008 ed010008 ed010008  ................&lt;br /&gt;
 80000b0 ed010008 ed010008 ed010008 ed010008  ................&lt;br /&gt;
 80000c0 ed010008 ed010008 ed010008 ed010008  ................&lt;br /&gt;
 80000d0 ed010008 ed010008 ed010008 ed010008  ................&lt;br /&gt;
 80000e0 ed010008 ed010008 ed010008       	............    &lt;br /&gt;
Contents of section .text:&lt;br /&gt;
 80000ec 0f481049 104a03e0 52f8043b 40f8043b  .H.I.J..R..;@..;&lt;br /&gt;
 80000fc 8842f9d3 0d480e49 4ff00002 01e040f8  .B...H.IO.....@.&lt;br /&gt;
 800010c 042b8842 fbd300f0 47f800f0 4bf84ff4  .+.B....G...K.O.&lt;br /&gt;
 800011c 80710848 01600848 00f058f8 30bffde7  .q.H.`.H..X.0...&lt;br /&gt;
 800012c 00040020 04040020 f0010008 04040020  ... ... .......&lt;br /&gt;
 800013c 08040020 10080140 60e31600 4ff0e020  ... ...@`...O..&lt;br /&gt;
 800014c 006910f4 803f1dd0 1a480178 b1f1110f  .i...?...H.x....&lt;br /&gt;
 800015c 18d21948 0378013b 1cbf0370 12e001f1  ...H.x.;...p....&lt;br /&gt;
 800016c 0101b1f1 110f02d2 144a535c 03701148  .........JS\.p.H&lt;br /&gt;
 800017c 017011f0 01010cbf 4ff48071 4ff08071  .p......O..qO..q&lt;br /&gt;
 800018c 0f480160 70470202 02020202 05020502  .H.`pG..........&lt;br /&gt;
 800019c 05020202 02020200 0a490868 40f00400  .........I.h@...&lt;br /&gt;
 80001ac 08607047 08490868 20f00f00 40f00200  .`pG.I.h ...@...&lt;br /&gt;
 80001bc 08607047 04040020 00040020 92010008  .`pG... ... ....&lt;br /&gt;
 80001cc 10080140 18100240 04080140 4ff0e021  ...@...@...@O..!&lt;br /&gt;
 80001dc 48614ff0 00008861 4ff00700 08617047  HaO....aO....apG&lt;br /&gt;
 80001ec 00befde7                         	....       	 &lt;br /&gt;
Contents of section .data:&lt;br /&gt;
 20000400 02000000                         	....       	 &lt;br /&gt;
Contents of section .ARM.attributes:&lt;br /&gt;
 0000 41200000 00616561 62690001 16000000  A ...aeabi......&lt;br /&gt;
 0010 05436f72 7465782d 4d330006 0a074d09  .Cortex-M3....M.&lt;br /&gt;
 0020 02                               	.          	 &lt;br /&gt;
Contents of section .debug_line:&lt;br /&gt;
 0000 98000000 02001e00 00000201 fb0e0d00  ................&lt;br /&gt;
 0010 01010101 00000001 00000100 70726f67  ............prog&lt;br /&gt;
 0020 312e5300 00000000 000502ec 00000803  1.S.............&lt;br /&gt;
 0030 15012121 22212f2f 21222121 30212f21  ..!!&amp;quot;!//!&amp;quot;!!0!/!&lt;br /&gt;
 0040 222f302f 21232130 21036120 2f2f362f  &amp;quot;/0/!#!0!.a //6/&lt;br /&gt;
 0050 030c2e32 030a2e2f 212f2222 222f2221  ...2.../!/&amp;quot;&amp;quot;&amp;quot;/&amp;quot;!&lt;br /&gt;
 0060 21222121 222f2f22 21212321 222f212f  !&amp;quot;!!&amp;quot;//&amp;quot;!!#!&amp;quot;/!/&lt;br /&gt;
 0070 30212303 0d9e2121 2f212421 212f2f21  0!#...!!/!$!!//!&lt;br /&gt;
 0080 03422035 030c2e03 0d2e0311 2e36030b  .B 5.........6..&lt;br /&gt;
 0090 2e30212f 222f2202 01000101 3b000000  .0!/&amp;quot;/&amp;quot;.....;...&lt;br /&gt;
 00a0 02002400 00000201 fb0e0d00 01010101  ..$.............&lt;br /&gt;
 00b0 00000001 00000100 76656374 6f727461  ........vectorta&lt;br /&gt;
 00c0 626c652e 53000000 00000005 02ec0100  ble.S...........&lt;br /&gt;
 00d0 0803d000 01210201 000101         	.....!.....	 &lt;br /&gt;
Contents of section .debug_info:&lt;br /&gt;
 0000 22000000 02000000 00000401 00000000  &amp;quot;...............&lt;br /&gt;
 0010 ec000008 ec010008 00000000 08000000  ................&lt;br /&gt;
 0020 12000000 01802200 00000200 14000000  ......&amp;quot;.........&lt;br /&gt;
 0030 04019c00 0000ec01 0008f001 00082100  ..............!.&lt;br /&gt;
 0040 00000800 00001200 00000180       	............    &lt;br /&gt;
Contents of section .debug_abbrev:&lt;br /&gt;
 0000 01110010 06110112 01030e1b 0e250e13  .............%..&lt;br /&gt;
 0010 05000000 01110010 06110112 01030e1b  ................&lt;br /&gt;
 0020 0e250e13 05000000                	.%......   	 &lt;br /&gt;
Contents of section .debug_aranges:&lt;br /&gt;
 0000 1c000000 02000000 00000400 00000000  ................&lt;br /&gt;
 0010 ec000008 00010000 00000000 00000000  ................&lt;br /&gt;
 0020 1c000000 02002600 00000400 00000000  ......&amp;amp;.........&lt;br /&gt;
 0030 ec010008 04000000 00000000 00000000  ................&lt;br /&gt;
Contents of section .debug_str:&lt;br /&gt;
 0000 70726f67 312e5300 2f746d70 2f746573  prog1.S./tmp/tes&lt;br /&gt;
 0010 7400474e 55204153 20322e32 392e3531  t.GNU AS 2.29.51&lt;br /&gt;
 0020 00766563 746f7274 61626c65 2e5300	.vectortable.S.&lt;br /&gt;
&lt;br /&gt;
Disassembly of section .text:&lt;br /&gt;
&lt;br /&gt;
080000ec &amp;lt;Reset_Handler&amp;gt;:&lt;br /&gt;
 80000ec:    480f 		 ldr    r0, [pc, #60]    ; (800012c &amp;lt;Reset_Handler+0x40&amp;gt;)&lt;br /&gt;
 80000ee:    4910 		 ldr    r1, [pc, #64]    ; (8000130 &amp;lt;Reset_Handler+0x44&amp;gt;)&lt;br /&gt;
 80000f0:    4a10 		 ldr    r2, [pc, #64]    ; (8000134 &amp;lt;Reset_Handler+0x48&amp;gt;)&lt;br /&gt;
 80000f2:    e003 		 b.n    80000fc &amp;lt;Reset_Handler+0x10&amp;gt;&lt;br /&gt;
 80000f4:    f852 3b04     ldr.w    r3, [r2], #4&lt;br /&gt;
 80000f8:    f840 3b04     str.w    r3, [r0], #4&lt;br /&gt;
 80000fc:    4288 		 cmp    r0, r1&lt;br /&gt;
 80000fe:    d3f9 		 bcc.n    80000f4 &amp;lt;Reset_Handler+0x8&amp;gt;&lt;br /&gt;
 8000100:    480d 		 ldr    r0, [pc, #52]    ; (8000138 &amp;lt;Reset_Handler+0x4c&amp;gt;)&lt;br /&gt;
 8000102:    490e 		 ldr    r1, [pc, #56]    ; (800013c &amp;lt;Reset_Handler+0x50&amp;gt;)&lt;br /&gt;
 8000104:    f04f 0200     mov.w    r2, #0&lt;br /&gt;
 8000108:    e001 		 b.n    800010e &amp;lt;Reset_Handler+0x22&amp;gt;&lt;br /&gt;
 800010a:    f840 2b04     str.w    r2, [r0], #4&lt;br /&gt;
 800010e:    4288 		 cmp    r0, r1&lt;br /&gt;
 8000110:    d3fb 		 bcc.n    800010a &amp;lt;Reset_Handler+0x1e&amp;gt;&lt;br /&gt;
 8000112:    f000 f847     bl    80001a4 &amp;lt;EnableClockGPIOA&amp;gt;&lt;br /&gt;
 8000116:    f000 f84b     bl    80001b0 &amp;lt;ConfigurePA8&amp;gt;&lt;br /&gt;
 800011a:    f44f 7180     mov.w    r1, #256    ; 0x100&lt;br /&gt;
 800011e:    4808 		 ldr    r0, [pc, #32]    ; (8000140 &amp;lt;Reset_Handler+0x54&amp;gt;)&lt;br /&gt;
 8000120:    6001 		 str    r1, [r0, #0]&lt;br /&gt;
 8000122:    4808 		 ldr    r0, [pc, #32]    ; (8000144 &amp;lt;Reset_Handler+0x58&amp;gt;)&lt;br /&gt;
 8000124:    f000 f858     bl    80001d8 &amp;lt;StartSysTick&amp;gt;&lt;br /&gt;
 8000128:    bf30 		 wfi&lt;br /&gt;
 800012a:    e7fd 		 b.n    8000128 &amp;lt;Reset_Handler+0x3c&amp;gt;&lt;br /&gt;
 800012c:    20000400     .word    0x20000400&lt;br /&gt;
 8000130:    20000404     .word    0x20000404&lt;br /&gt;
 8000134:    080001f0     .word    0x080001f0&lt;br /&gt;
 8000138:    20000404     .word    0x20000404&lt;br /&gt;
 800013c:    20000408     .word    0x20000408&lt;br /&gt;
 8000140:    40010810     .word    0x40010810&lt;br /&gt;
 8000144:    0016e360     .word    0x0016e360&lt;br /&gt;
&lt;br /&gt;
08000148 &amp;lt;SysTick_Handler&amp;gt;:&lt;br /&gt;
 8000148:    f04f 20e0     mov.w    r0, #3758153728    ; 0xe000e000&lt;br /&gt;
 800014c:    6900 		 ldr    r0, [r0, #16]&lt;br /&gt;
 800014e:    f410 3f80     tst.w    r0, #65536    ; 0x10000&lt;br /&gt;
 8000152:    d01d 		 beq.n    8000190 &amp;lt;SysTick_Handler+0x48&amp;gt;&lt;br /&gt;
 8000154:    481a 		 ldr    r0, [pc, #104]    ; (80001c0 &amp;lt;ConfigurePA8+0x10&amp;gt;)&lt;br /&gt;
 8000156:    7801 		 ldrb    r1, [r0, #0]&lt;br /&gt;
 8000158:    f1b1 0f11     cmp.w    r1, #17&lt;br /&gt;
 800015c:    d218 		 bcs.n    8000190 &amp;lt;SysTick_Handler+0x48&amp;gt;&lt;br /&gt;
 800015e:    4819 		 ldr    r0, [pc, #100]    ; (80001c4 &amp;lt;ConfigurePA8+0x14&amp;gt;)&lt;br /&gt;
 8000160:    7803 		 ldrb    r3, [r0, #0]&lt;br /&gt;
 8000162:    3b01 		 subs    r3, #1&lt;br /&gt;
 8000164:    bf1c 		 itt    ne&lt;br /&gt;
 8000166:    7003 		 strbne    r3, [r0, #0]&lt;br /&gt;
 8000168:    e012 		 bne.n    8000190 &amp;lt;SysTick_Handler+0x48&amp;gt;&lt;br /&gt;
 800016a:    f101 0101     add.w    r1, r1, #1&lt;br /&gt;
 800016e:    f1b1 0f11     cmp.w    r1, #17&lt;br /&gt;
 8000172:    d202 		 bcs.n    800017a &amp;lt;SysTick_Handler+0x32&amp;gt;&lt;br /&gt;
 8000174:    4a14 		 ldr    r2, [pc, #80]    ; (80001c8 &amp;lt;ConfigurePA8+0x18&amp;gt;)&lt;br /&gt;
 8000176:    5c53 		 ldrb    r3, [r2, r1]&lt;br /&gt;
 8000178:    7003 		 strb    r3, [r0, #0]&lt;br /&gt;
 800017a:    4811 		 ldr    r0, [pc, #68]    ; (80001c0 &amp;lt;ConfigurePA8+0x10&amp;gt;)&lt;br /&gt;
 800017c:    7001 		 strb    r1, [r0, #0]&lt;br /&gt;
 800017e:    f011 0101     ands.w    r1, r1, #1&lt;br /&gt;
 8000182:    bf0c 		 ite    eq&lt;br /&gt;
 8000184:    f44f 7180     moveq.w    r1, #256    ; 0x100&lt;br /&gt;
 8000188:    f04f 7180     movne.w    r1, #16777216    ; 0x1000000&lt;br /&gt;
 800018c:    480f 		 ldr    r0, [pc, #60]    ; (80001cc &amp;lt;ConfigurePA8+0x1c&amp;gt;)&lt;br /&gt;
 800018e:    6001 		 str    r1, [r0, #0]&lt;br /&gt;
 8000190:    4770 		 bx    lr&lt;br /&gt;
&lt;br /&gt;
08000192 &amp;lt;BlinkTable&amp;gt;:&lt;br /&gt;
 8000192:    0202 0202 0202 0205 0205 0205 0202 0202 	................&lt;br /&gt;
 80001a2:                                             	.&lt;br /&gt;
&lt;br /&gt;
080001a3 &amp;lt;BlinkTableEnd&amp;gt;:&lt;br /&gt;
    ...&lt;br /&gt;
&lt;br /&gt;
080001a4 &amp;lt;EnableClockGPIOA&amp;gt;:&lt;br /&gt;
 80001a4:    490a 		 ldr    r1, [pc, #40]    ; (80001d0 &amp;lt;ConfigurePA8+0x20&amp;gt;)&lt;br /&gt;
 80001a6:    6808 		 ldr    r0, [r1, #0]&lt;br /&gt;
 80001a8:    f040 0004     orr.w    r0, r0, #4&lt;br /&gt;
 80001ac:    6008 		 str    r0, [r1, #0]&lt;br /&gt;
 80001ae:    4770 		 bx    lr&lt;br /&gt;
&lt;br /&gt;
080001b0 &amp;lt;ConfigurePA8&amp;gt;:&lt;br /&gt;
 80001b0:    4908 		 ldr    r1, [pc, #32]    ; (80001d4 &amp;lt;ConfigurePA8+0x24&amp;gt;)&lt;br /&gt;
 80001b2:    6808 		 ldr    r0, [r1, #0]&lt;br /&gt;
 80001b4:    f020 000f     bic.w    r0, r0, #15&lt;br /&gt;
 80001b8:    f040 0002     orr.w    r0, r0, #2&lt;br /&gt;
 80001bc:    6008 		 str    r0, [r1, #0]&lt;br /&gt;
 80001be:    4770 		 bx    lr&lt;br /&gt;
 80001c0:    20000404     .word    0x20000404&lt;br /&gt;
 80001c4:    20000400     .word    0x20000400&lt;br /&gt;
 80001c8:    08000192     .word    0x08000192&lt;br /&gt;
 80001cc:    40010810     .word    0x40010810&lt;br /&gt;
 80001d0:    40021018     .word    0x40021018&lt;br /&gt;
 80001d4:    40010804     .word    0x40010804&lt;br /&gt;
&lt;br /&gt;
080001d8 &amp;lt;StartSysTick&amp;gt;:&lt;br /&gt;
 80001d8:    f04f 21e0     mov.w    r1, #3758153728    ; 0xe000e000&lt;br /&gt;
 80001dc:    6148 		 str    r0, [r1, #20]&lt;br /&gt;
 80001de:    f04f 0000     mov.w    r0, #0&lt;br /&gt;
 80001e2:    6188 		 str    r0, [r1, #24]&lt;br /&gt;
 80001e4:    f04f 0007     mov.w    r0, #7&lt;br /&gt;
 80001e8:    6108 		 str    r0, [r1, #16]&lt;br /&gt;
 80001ea:    4770 		 bx    lr&lt;br /&gt;
&lt;br /&gt;
080001ec &amp;lt;Default_Handler&amp;gt;:&lt;br /&gt;
 80001ec:    be00 		 bkpt    0x0000&lt;br /&gt;
 80001ee:    e7fd 		 b.n    80001ec &amp;lt;Default_Handler&amp;gt;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is a lot of information. The “-d” flag tells objdump to disassemble code sections, and the “-s” flag lets it output data sections. At first, it prints the contents of “.VectorTable”. Each line is prefixed with the address of where this data is found in memory. Then, the 32bit data blocks from the vector table are output. The disassembler prints the bytes in the order they appear in memory, which, since the Cortex-M3 uses little endian, is reversed - for example, the printed “ed000008” actually refers to the address “0x080000ed”, which is the address of the “Reset_Handler” with the lowest bit set to one, as it is a thumb function. Most of the addresses in the vector table reflect the address of the default handler, 0x080001ec, except for the zero-entries and the SysTick_Handler. The contents of the “.text” section is the hexadecimal representation of the machine code, and hardly readable. The “.data” section contains a single “two” - this is the “02” put into “TimerEvents”. The contents of “.ARM.attributes:” and the various “.debug” sections is not very interesting, as it does not end up on the controller, and is only read by the various analysis tools to provide nicer output.&lt;br /&gt;
&lt;br /&gt;
After that comes the actual disassembly. This is a list of all the instructions in the code section. The list is grouped by the symbols found in the input file. For C Code, each symbol usually matches one function, so each block in the disassembly represents one C function. In assembly code, if you put non-local labels into a function, that function will be split into multiple blocks by the disassembler, making it harder to read - the main reason for using local labels. Each instruction is translated into one line inside the blocks. The first column is the address where that instruction is found. The next column contains the hexadecimal representation of the 2 or 4 bytes that make up the machine code of that instruction, i.e. the actual content of flash memory. After that comes a textual representation of that instruction, as inferred by the disassembler. If the instruction contains some number, the disassembler sometimes outputs a semicolon followed by some interpretation of that number. If the instruction employs PC-relative addressing, that interpretation will be the absolute address. As many instructions have multiple spellings, there can be discrepancies between the original code and the disassembly. The disassembler will also output data, such as the “BlinkTable” and the literal pools, as such. Using the “.type” directive is helpful in that case so that the disassembler does not attempt to interpret the data bytes as code.&lt;br /&gt;
&lt;br /&gt;
objdump can also be used to disassembly raw binary files that can be obtained by reading back the flash memory of some controller. To do this, use this command line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=sh&amp;gt;&lt;br /&gt;
$ arm-none-eabi-objdump -b binary -m arm -D prog1.bin -Mforce-thumb --adjust-vma=0x08000000&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The address of the binary in flash memory is specified so that the printed instruction addresses are correct. However, as the disassembler can’t tell data and code apart, the result will be of limited use. If you have to analyze a binary without having an ELF file or the source code, a more sophisticated disassembler such as IDA Pro is helpful. If you have the code and only need the disassembler to identify potential problems with the project (esp. the linker script), objdump is usually sufficient.&lt;br /&gt;
==== readelf ====&lt;br /&gt;
The “readelf” program is a powerful utility that can read and output various information from ELF files. The most useful option is the “-S” flag, which lets readelf print a summary of the sections in the respective file, e.g.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ arm-none-eabi-readelf -S prog1.elf&lt;br /&gt;
There are 15 section headers, starting at offset 0x11268:&lt;br /&gt;
&lt;br /&gt;
Section Headers:&lt;br /&gt;
  [Nr] Name          	Type        	Addr 	Off	Size   ES Flg Lk Inf Al&lt;br /&gt;
  [ 0]               	NULL        	00000000 000000 000000 00  	0   0  0&lt;br /&gt;
  [ 1] .VectorTable  	PROGBITS    	08000000 010000 0000ec 00   A  0   0  1&lt;br /&gt;
  [ 2] .text         	PROGBITS    	080000ec 0100ec 000104 00  AX  0   0  4&lt;br /&gt;
  [ 3] .stack        	NOBITS      	20000000 020000 000400 00  WA  0   0  1&lt;br /&gt;
  [ 4] .data         	PROGBITS    	20000400 010400 000004 00  WA  0   0  1&lt;br /&gt;
  [ 5] .bss          	NOBITS      	20000404 010404 000004 00  WA  0   0  1&lt;br /&gt;
  [ 6] .ARM.attributes   ARM_ATTRIBUTES  00000000 010404 000021 00  	0   0  1&lt;br /&gt;
  [ 7] .debug_line   	PROGBITS    	00000000 010425 0000db 00  	0   0  1&lt;br /&gt;
  [ 8] .debug_info   	PROGBITS    	00000000 010500 00004c 00  	0   0  1&lt;br /&gt;
  [ 9] .debug_abbrev 	PROGBITS    	00000000 01054c 000028 00  	0   0  1&lt;br /&gt;
  [10] .debug_aranges	PROGBITS    	00000000 010578 000040 00  	0   0  8&lt;br /&gt;
  [11] .debug_str    	PROGBITS    	00000000 0105b8 00002f 01  MS  0   0  1&lt;br /&gt;
  [12] .symtab       	SYMTAB      	00000000 0105e8 0006a0 10 	13  45  4&lt;br /&gt;
  [13] .strtab       	STRTAB      	00000000 010c88 000550 00  	0   0  1&lt;br /&gt;
  [14] .shstrtab     	STRTAB      	00000000 0111d8 000090 00  	0   0  1&lt;br /&gt;
Key to Flags:&lt;br /&gt;
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),&lt;br /&gt;
  L (link order), O (extra OS processing required), G (group), T (TLS),&lt;br /&gt;
  C (compressed), x (unknown), o (OS specific), E (exclude),&lt;br /&gt;
  y (purecode), p (processor specific)&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For each section, one line is output. The sections “.strtab”, “.shstrtab”, “.symtab” and “NULL” are an integral part of ELF and always present. The “.debug” sections are present if the source was assembled with the “-g” flag.	The “.ARM.attributes” section defines for which ARM processor the contained code was translated. These sections don’t end up on the microcontroller. The remaining sections were defined in the linker script: “.VectorTable” contains the addresses of the exception handlers, “.text” contains the program code and constant data for flash memory, “.stack” the stack in RAM, “.data” contains variables in RAM and “.bss” contains zero-initialized variables in RAM. For these sections, the column “Type” contains either “PROGBITS” or “NOBITS” that tells you whether the section in the ELF file actually contains some data - this is only the case for “.VectorTable”, “.text” and “.data”. The sections “.bss” and “.stack” only reserve memory that is written at runtime, but the ELF file doesn’t contain data to be written in these sections. The column “Addr” defines where this section begins in the address space. The most useful column is “Size”: If you sum up the sizes of the sections “.VectorTable”, “.text” and “.data”, you can obtain the used flash memory. By summing ob “.data”, “.stack” and “.bss”, you get the used amount of RAM. Note that “.data” is counted twice, as the initialization data is stored in flash.&lt;br /&gt;
==== nm ====&lt;br /&gt;
The “nm” utility prints the symbols defined in an ELF file, for example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ arm-none-eabi-nm prog1.elf&lt;br /&gt;
080001ec W ADC1_2_IRQHandler&lt;br /&gt;
20000404 b BlinkStep&lt;br /&gt;
08000192 t BlinkTable&lt;br /&gt;
080001a3 t BlinkTableEnd&lt;br /&gt;
20000408 B _BssEnd&lt;br /&gt;
20000404 B _BssStart&lt;br /&gt;
…&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This can be helpful in analyzing errors in linker scripts where symbols might get assigned wrong addresses.&lt;br /&gt;
==== addr2line ====&lt;br /&gt;
The “addr2line” utility reads the debug information from an ELF file to determine which line in which source file produced the instruction found at a particular given address. For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=sh&amp;gt;&lt;br /&gt;
$ arm-none-eabi-addr2line 0x080000f0 -e prog1.elf&lt;br /&gt;
/tmp/test/prog1.S:24&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Here, line 24 of “prog1.S” contains the assembler command that produced the instruction that ends up at address 0x080000f0.&lt;br /&gt;
&lt;br /&gt;
==== objcopy ====&lt;br /&gt;
The “objcopy” utility allows you to translate program files between different formats. It is useful to convert the ELF files to both the Intel Hex format and a simple binary representation. For example,&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=sh&amp;gt;&lt;br /&gt;
arm-none-eabi-objcopy -O ihex prog1.elf prog1.hex&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
produces a “.hex” file that contains an image of the flash contents in hexadecimal form. With&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=sh&amp;gt;&lt;br /&gt;
arm-none-eabi-objcopy -O binary prog1.elf prog1.bin&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
a binary file is createed which contains an exact 1:1 image of the flash contents. Some flashing tools require these formats instead of ELF, and viewing the binary file with a hex editor can be interesting as well.&lt;br /&gt;
&lt;br /&gt;
=== Interfacing C and C++ code ===&lt;br /&gt;
Since assembly is rarely used to implement entire complex projects, but mostly for few time-critical or especially low-level routines that are part of larger code bases written in a high-level-language, interfacing C and assembly code is an important topic, which will be covered here. While it is possible to write the main project structure in assembly and integrate some C modules, it is usually done the other way round. Most of the code shown is already ready to be included in C programs. Most of this topic works the same way for C++, apart from C++ exceptions (not to be confused with ARM processor exceptions) - but these are rarely used on embedded targets anyways.&lt;br /&gt;
&lt;br /&gt;
If you compile C, C++ and assembly code into individual .o object files, you can link these together using “ld” as before. However, C and C++ code usually requires access to the respective standard library, and “ld” doesn’t link these by default - therefore it is neccessary to substitute “ld” for a call to “gcc” or “g++” for C or C++, respectively. This will call “ld” internally and pass the required libraries.&lt;br /&gt;
==== Environment setup for C and C++ ====&lt;br /&gt;
Many C projects use a reset handler and vector table implemented in assembly, although writing them in C is possible too. As required by the C standard, C programs start with the “main()” function, so the (assembly) reset handler should setup the environment such that it is ready for C, and then call “main”. The C code might then later call some assembly functions or inline assembly. When using C++ code, or some GCC extension for C code, it is required to call some additional functions before calling “main”. This is used by C++ to call the constructors of global objects. The C and C++ compilers emit a table of function pointers to functions that should be called at startup. This table has to be put into flash memory by modifying the linker script as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source&amp;gt;&lt;br /&gt;
.text : {&lt;br /&gt;
	*(.text)&lt;br /&gt;
	. = ALIGN(4);&lt;br /&gt;
&lt;br /&gt;
	_InitArrayStart = .;&lt;br /&gt;
	*(SORT(.preinit_array*))&lt;br /&gt;
	*(SORT(.init_array*))&lt;br /&gt;
	_InitArrayEnd = .;&lt;br /&gt;
} &amp;gt;FLASH&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The table of function pointers is sorted to keep the order needed by the compiler. The symbols “_InitArrayStart” and “_InitArrayEnd” mark beginning and end of that table. A reset handler that performs the memory initialization as before and calls the table of initialization functions could look like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
.syntax unified&lt;br /&gt;
.cpu cortex-m3&lt;br /&gt;
.thumb&lt;br /&gt;
&lt;br /&gt;
.text&lt;br /&gt;
.type Reset_Handler, %function&lt;br /&gt;
.global Reset_Handler&lt;br /&gt;
Reset_Handler:&lt;br /&gt;
	ldr r0, =_DataStart&lt;br /&gt;
	ldr r1, =_DataEnd&lt;br /&gt;
	ldr r2, =_DataLoad&lt;br /&gt;
&lt;br /&gt;
	b 2f&lt;br /&gt;
1:	ldr r3, [r2], #4&lt;br /&gt;
	str r3, [r0], #4&lt;br /&gt;
2:	cmp r0, r1&lt;br /&gt;
	blo 1b&lt;br /&gt;
	&lt;br /&gt;
	ldr r0, =_BssStart&lt;br /&gt;
	ldr r1, =_BssEnd&lt;br /&gt;
	ldr r2, =0&lt;br /&gt;
&lt;br /&gt;
	b 2f&lt;br /&gt;
1:	str r2, [r0], #4&lt;br /&gt;
2:	cmp r0, r1&lt;br /&gt;
	blo 1b&lt;br /&gt;
&lt;br /&gt;
	ldr r4, =_InitArrayStart&lt;br /&gt;
	ldr r5, =_InitArrayEnd&lt;br /&gt;
	&lt;br /&gt;
	b 2f&lt;br /&gt;
1:	ldr r0, [r4], #4&lt;br /&gt;
	blx r0&lt;br /&gt;
2:	cmp r4, r5&lt;br /&gt;
	blo 1b&lt;br /&gt;
&lt;br /&gt;
	bl main&lt;br /&gt;
1:	bkpt&lt;br /&gt;
	b 1b&lt;br /&gt;
	.ltorg&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that for iterating the table, registers r4 and r5 are used, since the called functions may not overwrite those. The “blx” instruction is needed to perform the indirect function call. When everything is set up, the main function is called. For embedded programs, the main function should never return (i.e. contain an endless loop). If it does, that’s an error, and to make it easier to find, an endless loop with a forced breakpoint is put right after the call to “main”.&lt;br /&gt;
==== Calling functions ====&lt;br /&gt;
To call assembly functions from C code and vice-versa, the assembly functions should observe the calling convention, as mentioned before. C functions can be called just like assembly functions from assembly code, by placing the parameters in register r0-r3 and on the stack, calling the function using “bl” and retrieving the return value from r0. To call an assembly function from C code, you need to declare it in C first just like a C function. For example, to call a function that takes 2 integer arguments and returns an integer:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
int AssemblyFunction (int a, int b);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you now define a function named “AssemblyFunction” in your assembly code and export it via “.global”, you can call it from C code just like any function.&lt;br /&gt;
==== Accessing global variables ====&lt;br /&gt;
Global variables defined in C can be accessed from assembly code just like variables defined in assembly code, by using the variable’s name. To access an assembly variable from C code, you need to declare it first by specifying the type. For example, to declare an integer variable:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=c&amp;gt;&lt;br /&gt;
extern int AssemblyVariable;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you now define a variable named “AssemblyVariable” in your assembly code and export it via “.global”, you can access it from C code just like any variable. The “extern” is required to make sure the C code doesn’t attempt to declare another variable of the same name.&lt;br /&gt;
=== Clock configuration ===&lt;br /&gt;
By default, STM32 controllers use an internal RC-oscillator with 8 MHz as a clock source for the core and periphery. This oscillator is too inaccurate for implementing a clock or using serial interfaces such as UART, USB or CAN. To obtain a more accurate clock, an external quartz crystal is usually applied. Many STM32 boards feature an 8 MHz crystal. To use it, some initialization code is required that activates the microcontroller’s built-in crystal-oscillator circuit and switches the clock input to that. The STM32 controllers also include a PLL which can multiply some input clock by a configurable factor before feeding it to the processor core and peripherals. This way, a precise and fast clock can be achieved -  the STM32F103 supports up to 72 MHz core frequency. Unfortunately, flash memory is not capable of keeping up with such a high frequency. Therefore, when enabling a fast clock, the flash memory needs to be configured to use wait states depending on the frequency.&lt;br /&gt;
&lt;br /&gt;
The following function configures the flash wait states, enables the crystal oscillator, configures the PLL to multiply the input clock by a factor of 9, and use that as the system clock. The prescaler for the internal bus APB1 is set to 2. Assuming an 8 MHz crystal, this achieves the maximum performance possible with this microcontroller - 72 MHz for the core and APB2 domain, 36 MHz for APB1. If a different crystal is used, the PLL factors have to be adjusted.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=asm&amp;gt;&lt;br /&gt;
RCC = 0x40021000&lt;br /&gt;
&lt;br /&gt;
RCC_CR = 0x0&lt;br /&gt;
RCC_CR_PLLRDY = 25&lt;br /&gt;
RCC_CR_PLLON = 24&lt;br /&gt;
RCC_CR_HSERDY = 17&lt;br /&gt;
RCC_CR_HSEON = 16&lt;br /&gt;
RCC_CR_HSION = 0&lt;br /&gt;
&lt;br /&gt;
RCC_CFGR = 0x04&lt;br /&gt;
RCC_CFGR_PLLMUL = 18&lt;br /&gt;
RCC_CFGR_USBPRE = 22&lt;br /&gt;
RCC_CFGR_PLLXTPRE = 17&lt;br /&gt;
RCC_CFGR_PLLSRC = 16&lt;br /&gt;
RCC_CFGR_PPRE2 = 11&lt;br /&gt;
RCC_CFGR_PPRE1 = 8&lt;br /&gt;
RCC_CFGR_HPRE = 4&lt;br /&gt;
RCC_CFGR_SWS = 2&lt;br /&gt;
RCC_CFGR_SW = 0&lt;br /&gt;
&lt;br /&gt;
FLASH=0x40022000&lt;br /&gt;
FLASH_ACR=0&lt;br /&gt;
FLASH_ACR_PRFTBE = 4&lt;br /&gt;
FLASH_ACR_HLFCYA = 3&lt;br /&gt;
FLASH_ACR_LATENCY = 0&lt;br /&gt;
&lt;br /&gt;
.type ConfigureSysClock, %function&lt;br /&gt;
.global ConfigureSysClock&lt;br /&gt;
ConfigureSysClock:&lt;br /&gt;
	@ Turn on HSE&lt;br /&gt;
	ldr r0, =RCC&lt;br /&gt;
	ldr r1, =((1 &amp;lt;&amp;lt; RCC_CR_HSION)|(1 &amp;lt;&amp;lt; RCC_CR_HSEON))&lt;br /&gt;
	str r1, [r0, #RCC_CR]&lt;br /&gt;
	&lt;br /&gt;
	@ Configure (but not start yet) PLL&lt;br /&gt;
	@ Mul = 9, Prediv = 1, APB1 Prescaler = 2, APB2 Prescaler = 1, AHB Prescaler = 1&lt;br /&gt;
	ldr r2, =(((9-2)&amp;lt;&amp;lt;RCC_CFGR_PLLMUL)|(1 &amp;lt;&amp;lt; RCC_CFGR_USBPRE)|(1 &amp;lt;&amp;lt; RCC_CFGR_PLLSRC)|(4 &amp;lt;&amp;lt; RCC_CFGR_PPRE1))&lt;br /&gt;
	str r2, [r0, #RCC_CFGR]&lt;br /&gt;
&lt;br /&gt;
	@ Pre-Calculate value for RCC_CR&lt;br /&gt;
	orr r1, #(1 &amp;lt;&amp;lt; RCC_CR_PLLON)&lt;br /&gt;
&lt;br /&gt;
	&lt;br /&gt;
	@ Wait for HSE ready&lt;br /&gt;
1:	ldr r3, [r0, #RCC_CR]&lt;br /&gt;
	ands r3, #(1 &amp;lt;&amp;lt; RCC_CR_HSERDY)&lt;br /&gt;
	beq 1b&lt;br /&gt;
	&lt;br /&gt;
	@ Turn on PLL&lt;br /&gt;
	str r1, [r0, #RCC_CR]&lt;br /&gt;
	&lt;br /&gt;
	@ Pre-Calculate value for RCC_CFGR&lt;br /&gt;
	orr r2, #(2 &amp;lt;&amp;lt; RCC_CFGR_SW)&lt;br /&gt;
	&lt;br /&gt;
	@ Wait for PLL ready&lt;br /&gt;
1:	ldr r3, [r0, #RCC_CR]&lt;br /&gt;
	ands r3, #(1 &amp;lt;&amp;lt; RCC_CR_PLLRDY)&lt;br /&gt;
	beq 1b&lt;br /&gt;
	&lt;br /&gt;
	@ Set flash wait states to 2&lt;br /&gt;
	ldr r0, =FLASH&lt;br /&gt;
	ldr r3, =((1&amp;lt;&amp;lt;FLASH_ACR_PRFTBE)|(2&amp;lt;&amp;lt;FLASH_ACR_LATENCY))&lt;br /&gt;
	str r3, [r0, #FLASH_ACR]&lt;br /&gt;
	ldr r0, =RCC&lt;br /&gt;
	&lt;br /&gt;
	@ Switch system clock to PLL&lt;br /&gt;
	str r2, [r0, #RCC_CFGR]&lt;br /&gt;
&lt;br /&gt;
	@ Pre-Calculate value for RCC_CR&lt;br /&gt;
	bic r1, #(1 &amp;lt;&amp;lt; RCC_CR_HSION)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	@ Wait for switch to PLL&lt;br /&gt;
1:	ldr r3, [r0, #RCC_CFGR]&lt;br /&gt;
	and r3, #(3 &amp;lt;&amp;lt; RCC_CFGR_SWS)&lt;br /&gt;
	cmp r3, #(2 &amp;lt;&amp;lt; RCC_CFGR_SWS)&lt;br /&gt;
	bne 1b&lt;br /&gt;
	&lt;br /&gt;
	@ Turn off HSI to save power&lt;br /&gt;
	str r1, [r0, #RCC_CR]&lt;br /&gt;
	&lt;br /&gt;
	bx lr&lt;br /&gt;
	.ltorg&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Many projects perform the clock configuration by the reset handler before calling the main function. If you want to follow that practice, place a “bl ConfigureSysClock” as the first instruction in the “Reset_Handler” - this way, all the setup will run with the higher clock frequency, making start-up faster. This and the completed startup code from the previous chapters is implemented in the “startup.S” file in the example repository. If you use it, put your code in the “main” function, where RAM and system clock will already be initialized. This is shown in the “BlinkStartup” example.&lt;br /&gt;
&lt;br /&gt;
=== Project template &amp;amp; makefile ===&lt;br /&gt;
To quickly start your own project, a project template is supplied in the examples repository under the directory [https://github.com/Erlkoenig90/ArmAsmTutorial/tree/master/ProjectTemplate-STM32F103RB ProjectTemplate-STM32F103RB]. Put your own application code in the program.S file. The startup.S and vectortable.S contain the reset handler with RAM initialization and the vector table with default handler, respectively. A linker script is included too.&lt;br /&gt;
&lt;br /&gt;
The project also contains a makefile. This allows you to quickly translate your project without having to type the assembler and linker commands. Simply type&lt;br /&gt;
&amp;lt;source lang=sh&amp;gt;&lt;br /&gt;
make&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
To translate the code and produce program.elf, program.bin and program.hex files. All “.S” files in the directory will be automatically translated. Writing makefiles is a complex topic on its own with a lot of information already available on the web, so no further explanations on that will be made here.&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Bitmanipulation&amp;diff=89414</id>
		<title>Bitmanipulation</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Bitmanipulation&amp;diff=89414"/>
		<updated>2015-07-27T19:41:21Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* AVR-Assembler */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Bitoperatoren ==&lt;br /&gt;
&lt;br /&gt;
Bitoperatoren stammen ursprünglich aus dem Bereich des Maschinen-Codes und Assembler, existieren aber auch in den meisten Hochsprachen, wie C.&lt;br /&gt;
&lt;br /&gt;
* &amp;gt;&amp;gt; = Rechts schieben&lt;br /&gt;
* &amp;lt;&amp;lt; = Links schieben (Bsp: &#039;&#039;a&amp;lt;&amp;lt;b&#039;&#039; ist das gleiche wie &#039;&#039;a * 2^b&#039;&#039;; bzw. bei 1&amp;lt;&amp;lt;3 wird die 1 um drei Stellen nach links geschoben)&lt;br /&gt;
* |  = binäres ODER&lt;br /&gt;
* &amp;amp;  = binäres UND&lt;br /&gt;
* ^  = binäres Exklusives ODER&lt;br /&gt;
* usw.&lt;br /&gt;
&lt;br /&gt;
Bitoperatoren in dieser Schreibweise können in Assemblercode für&lt;br /&gt;
konstante Ausdrücke benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, (1&amp;lt;&amp;lt;3) | (1&amp;lt;&amp;lt;1) | (1&amp;lt;&amp;lt;2) | (1&amp;lt;&amp;lt;0)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
wird zu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, 8 | 2 | 4 | 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
wird zu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, 15&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bitmaske ==&lt;br /&gt;
&lt;br /&gt;
Im Folgenden ist häufiger von dem Begriff &#039;&#039;Bitmaske&#039;&#039; die Rede. Damit wird eine Folge von einzelnen Bit bezeichnet, die den Zustand Null (&#039;0&#039;) oder Eins (&#039;1&#039;) darstellen können.&lt;br /&gt;
&lt;br /&gt;
Bitmasken werden im allgemeinen dazu verwendet, um unter Anwendung eines Operators (z.&amp;amp;nbsp;B. UND, ODER, XOR), eine Eingabe zu manipulieren. Das Ergebnis ist dann die Anwendung des Operators auf die Eingabe und der Bitmaske.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Operator eine Funktion mit zwei Argumenten ist, dann lässt sich dessen Anwendung wie folgt schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Ergebnis = Operator( Eingabe, Bitmaske )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Bitmaske ist häufig eine Konstante, da diese z.&amp;amp;nbsp;B. die Information über die Position einer Information in einem Register darstellt. Das kann z.&amp;amp;nbsp;B. ein Überlaufflag in einem Timer Statusregister sein.&lt;br /&gt;
&lt;br /&gt;
== Bits setzen ==&lt;br /&gt;
&lt;br /&gt;
Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] auf Eins gesetzt werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#ODER | ODER]]-Verknüpfung erreicht.  Alle Bits, welche in der Bitmaske &#039;1&#039; sind, werden auf &#039;1&#039; gesetzt. Alle Bits, die in der Maske auf &#039;0&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR-Assembler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
sbr r16, 0b11110000     ; setzt Bits 4-7 in r16, ist ein Pseudobefehl&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
ori r16, 0b11110000     ; setzt Bits 4-7 in r16, ori ist identisch mit sbr&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
sbi PORTB, 5            ; setzt Bit 5 in PortB&lt;br /&gt;
sbi PORTB, PB5          ; identisch, besser lesbar&lt;br /&gt;
                        ; funktioniert nur für die IO-Register 0..0x1F&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register mit I/O Adresse 0x20..0x3F muss&lt;br /&gt;
                        ; in/out verwendet werden&lt;br /&gt;
in  r16, TIMSK          ; setzt Bit TOIE1 in TIMSK&lt;br /&gt;
sbr r16, (1&amp;lt;&amp;lt;TOIE1)    &lt;br /&gt;
out TIMSK, r16&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register oberhalb der I/O Adresse 0x3F muss&lt;br /&gt;
                        ; lds/sts verwednet werden&lt;br /&gt;
                        ; setzt Bit RXCIE0 in UCSR0B&lt;br /&gt;
lds r16, UCSR0B &lt;br /&gt;
sbr r16, (1&amp;lt;&amp;lt;RXCIE0)    &lt;br /&gt;
sts UCSR0B, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Man beachte den Unterschied! Eine &amp;quot;5&amp;quot; würde von sbr als &amp;quot;setze Bit 2 und 0&amp;quot; gedeutet (=0b00000101), während sbi sie als &amp;quot;setze Bit 5&amp;quot; versteht. Der Befehl &#039;&#039;&#039;sbr&#039;&#039;&#039; erwartet ein Bit&#039;&#039;&#039;muster&#039;&#039;&#039; für eine ODER-Verknüpfung, während der Befehlt &#039;&#039;&#039;sbi&#039;&#039;&#039; die Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; benötigt. Darauf sind auch die Includefiles von Atmel im AVR-Studio (Assembler) als auch [[WinAVR]] (C) ausgelegt. Die Namen der Bits sind als Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; definiert. Das ist wichtig, wenn man Register von grossen AVRs manipuliert, z.&amp;amp;nbsp;B. ATmega48. Hier muss aus der Bitnummer über eine Schiebeoperation erst das Bit&#039;&#039;&#039;muster&#039;&#039;&#039; gemacht werden.&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB |= 0xF0;   // Kurzschreibweise, entspricht PORTB = PORTB | 0xF0; bitweises ODER&lt;br /&gt;
&lt;br /&gt;
/* übersichtlicher mittels Bit-Definitionen */&lt;br /&gt;
#define MEINBIT0 0&lt;br /&gt;
#define MEINBIT1 1&lt;br /&gt;
#define MEINBIT2 2&lt;br /&gt;
&lt;br /&gt;
PORTB |= ((1 &amp;lt;&amp;lt; MEINBIT0) | (1 &amp;lt;&amp;lt; MEINBIT2)); // setzt Bit 0 und 2 in PORTB auf &amp;quot;1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die letzte Zeile &amp;quot;entschlüsselt&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;(1 &amp;lt;&amp;lt; n)&#039;&#039;&#039; : Zuerst wird durch die &#039;&amp;lt;&amp;lt;&#039;-Ausdrücke eine &amp;quot;1&amp;quot; n-mal nach links geschoben.  Dies ergibt somit (in Binärschreibweise) 0b00000001 für (1 &amp;lt;&amp;lt; MEINBIT0) und 0b00000100 für (1 &amp;lt;&amp;lt; MEINBIT2).&lt;br /&gt;
# &#039;&#039;&#039;|&#039;&#039;&#039; : Das Ergebnis wird bitweise ODER-verknüpft, also 0b00000001 &#039;&#039;or&#039;&#039; 0b00000100 wird zu 0b00000101.&lt;br /&gt;
# &#039;&#039;&#039;|=&#039;&#039;&#039; : Diese Maske wird mit dem aktuellen Inhalt von PORTB bitweise ODER-verknüpft und das Ergebnis PORTB wieder zugewiesen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB |= variable;         // Kurzschreibweise&lt;br /&gt;
PORTB  = PORTB | variable; // lange Schreibweise&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Ist PORTB vorher z.&amp;amp;nbsp;B. 0b01111010, dann ist der Inhalt nach der Operation 0b01111010 &#039;&#039;or&#039;&#039; 0b00000101 = 0b01111111, die gewünschten Bits sind somit gesetzt!&lt;br /&gt;
&lt;br /&gt;
Anmerkung: Will man das gezeigte Beispiel der Bitmanipulation auf größere Datentypen anwenden, ist zu beachten, dass der Compiler in der Operation (1 &amp;lt;&amp;lt; MEINBIT1) stillschweigend gemäss, den C-Regeln, die 1 als Integer Typ ansieht. Beim AVR-GCC bedeutet das 16-Bit/signed und die folgende Operation bringt ggf. nicht das gewünschte Ergebnis. (Stichwort: &amp;quot;Integer Promotion&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Angenommen Bit 15 soll in einer 32-Bit weiten Variable gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define MEINBIT15 15&lt;br /&gt;
#define MEINBIT42 42&lt;br /&gt;
&lt;br /&gt;
uint32_t reg_32; /* uint32_t definiert per typedef z.&amp;amp;nbsp;B. in stdint.h */&lt;br /&gt;
uint64_t reg_64; /* uint64_t definiert per typedef z.&amp;amp;nbsp;B. in stdint.h */&lt;br /&gt;
&lt;br /&gt;
reg_32 |= (1 &amp;lt;&amp;lt; MEINBIT15);              /* FEHLER: Setzt die Bits 31 - 15, da ((int)1 &amp;lt;&amp;lt; 15) == 0xFFFF8000 */&lt;br /&gt;
&lt;br /&gt;
reg_32 |= ((uint32_t)1 &amp;lt;&amp;lt; MEINBIT15);    /* Hier wird nur Bit 15 gesetzt. */&lt;br /&gt;
reg_32 |= (1U &amp;lt;&amp;lt; MEINBIT15);             /* */&lt;br /&gt;
reg_32 |= (1L &amp;lt;&amp;lt; MEINBIT15);             /* andere Schreibweise. */&lt;br /&gt;
reg_64 |= (1LL &amp;lt;&amp;lt; MEINBIT42);            /* Hier wird nur Bit 42 gesetzt,&lt;br /&gt;
                                            andere Schreibweise für 64 Bit (long long). */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei Compilern für 32bit Controller (z.&amp;amp;nbsp;B. ARM7TDMI) sind Integers per default 32-bit und Konstanten sind somit implizit ebenfalls 32-bit. Man sollte aber dennoch die oben gezeigte Vorgehenweise verwenden, um Probleme zu vermeiden die entstehen könnten, wenn Code unter verschiedenen Plattformen/Compilern verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
== Bits löschen ==&lt;br /&gt;
&lt;br /&gt;
Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] auf Null gesetzt werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#UND | UND]]-Verknüpfung erreicht. Alle Bits, welche in der Bitmaske &#039;0&#039; sind, werden auf &#039;0&#039; gesetzt. Alle Bits, die in der Maske auf &#039;1&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR-Assembler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
cbr r16, 0b00001111     ; löscht Bits 0-3 in r16, ist ein Pseudobefehl &lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
andi r16, 0b11110000    ; löscht Bits 0-3 in r16, andi ist identisch mit cbr&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
andi r16, ~0b00001111   ; andere Schreibweise, hier wird die Bitmaske durch ~ invertiert&lt;br /&gt;
                        ; dadurch kann man einfach alle zu löschenden Bit als &#039;1&#039; angeben&lt;br /&gt;
                        ; so wie bei den Bitmasken für das setzen von Bits (positive Logik)&lt;br /&gt;
&lt;br /&gt;
cbi PORTB, 5            ; löscht Bit 5 in PortB&lt;br /&gt;
cbi PORTB, PB5          ; identisch, besser lesbar&lt;br /&gt;
                        ; funktioniert nur für die IO-Register 0..31&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register mit I/O Adresse 0x20..0x3F muss&lt;br /&gt;
                        ; in/out verwendet werden weil dieser Bereich nicht&lt;br /&gt;
                        ; bitadressierbar ist&lt;br /&gt;
in  r16, TIMSK          ; löscht Bit TOIE1 in TIMSK&lt;br /&gt;
cbr r16, 1&amp;lt;&amp;lt;TOIE1    &lt;br /&gt;
out TIMSK, r16&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register oberhalb der I/O Adresse 0x3F muss&lt;br /&gt;
                        ; lds/sts verwednet werden&lt;br /&gt;
                        ; löscht Bit RXCIE0 in UCSR0B&lt;br /&gt;
lds r16, UCSR0B &lt;br /&gt;
cbr r16, 1&amp;lt;&amp;lt;RXCIE0&lt;br /&gt;
sts UCSR0B, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier gilt: Man beachte den Unterschied! Eine &amp;quot;5&amp;quot; würde von cbr als &amp;quot;lösche Bit 2 und 0&amp;quot; gedeutet, während cbi sie als &amp;quot;lösche Bit 5&amp;quot; versteht. Der Befehl &#039;&#039;&#039;cbr&#039;&#039;&#039; erwartet ein Bit&#039;&#039;&#039;muster&#039;&#039;&#039; für eine UND-NOT-Verknüpfung (nicht zu verwechseln mit NAND), während der Befehl &#039;&#039;&#039;cbi&#039;&#039;&#039; die Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; benötigt. Darauf sind auch die Includefiles von Atmel im AVR-Studio (Assembler) als auch [[WinAVR]] ausgelegt. Die Namen der Bits sind als Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; definiert. Das ist wichtig, wenn man Register von grossen AVRs manipuliert, z.&amp;amp;nbsp;B. ATmega48. Hier muss aus der Bitnummer über eine Schiebeoperation &amp;lt;&amp;lt; erst das Bit&#039;&#039;&#039;muster&#039;&#039;&#039; gemacht werden.&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB &amp;amp;= 0xF0;   // entspricht PORTB = PORTB &amp;amp; 0xF0; bitweises UND&lt;br /&gt;
                 // Bits 0-3 (das &amp;quot;niederwertige&amp;quot; Nibble) werden geloescht &lt;br /&gt;
&lt;br /&gt;
/* übersichtlicher mittels Bit-Definitionen */ &lt;br /&gt;
#define MEINBIT0 0&lt;br /&gt;
#define MEINBIT1 1  &lt;br /&gt;
#define MEINBIT2 2  &lt;br /&gt;
&lt;br /&gt;
PORTB &amp;amp;= ~((1 &amp;lt;&amp;lt; MEINBIT0) | (1 &amp;lt;&amp;lt; MEINBIT2)); // löscht Bit 0 und 2 in PORTB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die letzte Zeile entschlüsselt:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;(1 &amp;lt;&amp;lt; n)&#039;&#039;&#039; : Zuerst wird durch die &#039;&amp;lt;&amp;lt;&#039;-Ausdrücke eine &amp;quot;1&amp;quot; n-mal nach links geschoben. Dies ergibt somit (in Binärschreibweise) 0b00000001 für (1 &amp;lt;&amp;lt; MEINBIT0) und 0b00000100 für (1 &amp;lt;&amp;lt; MEINBIT2).&lt;br /&gt;
# &#039;&#039;&#039;|&#039;&#039;&#039; : Das Ergebnis wird bitweise ODER-verknüpft also 0b00000001 &#039;&#039;or&#039;&#039; 0b00000100 wird zu 0b00000101.&lt;br /&gt;
# &#039;&#039;&#039;~&#039;&#039;&#039; : Der Wert in der Klammer wird bitweise invertiert, aus 0b00000101 wird 0b11111010.&lt;br /&gt;
# &#039;&#039;&#039;&amp;amp;=&#039;&#039;&#039; : PORTB wird mit der berechneten Maske UND-verknüpft und das Ergebnis wieder PORTB zugewiesen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB &amp;amp;= variable;          // Kurzschreibweise&lt;br /&gt;
PORTB  = PORTB &amp;amp; variable;  // lange Schreibweise&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Ist PORTB vorher z.&amp;amp;nbsp;B. 0b01111111, dann ist der Inhalt nach der Operation 0b01111111 &#039;&#039;and&#039;&#039; 0b11111010 = 0b01111010, die gewünschten Bits 0 und 2 sind somit gelöscht.&lt;br /&gt;
&lt;br /&gt;
Die C-Ausdrücke mittels Definitionen von Bitnummern und Schieboperator (&amp;lt;&amp;lt;) sehen auf den ersten Blick etwas &amp;quot;erschreckend&amp;quot; aus und sind mehr &amp;quot;Tipparbeit&amp;quot;, funktionieren aber universell und sind deutlicher und nachvollziehbarer als &amp;quot;handoptimierte&amp;quot; Konstanten. Bei eingeschalteter Optimierung löst der Compiler die Ausdücke mit konstanten Werten bereits zur Compilierungszeit auf und es entsteht kein zusätzlicher Maschinencode. Bei AVR sind die Definitionen meist Teil der Entwicklungsumgebungen (bei avr-libc z.&amp;amp;nbsp;B. implizit durch #include &amp;lt;avr/io.h&amp;gt;). Sie entsprechen den Angaben und Beispielen in den Datenblättern und sind damit de-facto ein Standard beim Zugriff auf Bits in Hardware-Registern.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Wichtiger Hinweis&#039;&#039;&#039;: Die ODER-Verknüpfung und die anschliessende Invertierung kann man nicht vertauschen! (Theorem von DeMorgan) Folgendes Beispiel soll die Richtigkeit der Aussage zeigen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 ~(0b0001 | 0b0010) == 0b1100&lt;br /&gt;
  ~0b0001 | ~0b0010 == 0b1111&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Noch ein wichtiger Hinweis&#039;&#039;&#039;: Der operator ~ mit einem Operanden vom Typ int negiert nur so viele bits, wie der Typ int hat.&lt;br /&gt;
Will man ein bit in einer breiteren Variablen löschen, dann sollte die nach links zu shiftende 1 den Typ dieser Variablen haben.&lt;br /&gt;
&lt;br /&gt;
Ein Programm, welches das verdeutlicht:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, const char* argv[])&lt;br /&gt;
{&lt;br /&gt;
    int bit = 60;&lt;br /&gt;
    uint64_t ui64;&lt;br /&gt;
    printf(&amp;quot;sizeof(int)=%d\n&amp;quot;, (int)sizeof(int));&lt;br /&gt;
    &lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;    &lt;br /&gt;
    ui64 &amp;amp;= ~(1&amp;lt;&amp;lt;60); /* Keine Wirkung bei sizeof(int) &amp;lt; 8 */&lt;br /&gt;
    /* gcc warnt sogar:    &lt;br /&gt;
     * gcc -Wall bit_clear.c -o bit_clear&lt;br /&gt;
     * bit_clear.c: In function ‘main’:&lt;br /&gt;
     * bit_clear.c:11:5: warning: left shift count &amp;gt;= width of type [enabled by default]&lt;br /&gt;
     */    &lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;    &lt;br /&gt;
    ui64 &amp;amp;= ~((uint64_t)1&amp;lt;&amp;lt;60); /* ok */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;&lt;br /&gt;
    ui64 &amp;amp;= ~(1LL&amp;lt;&amp;lt;60); /* auch ok, und kürzer. */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;&lt;br /&gt;
    ui64 &amp;amp;= ~(1&amp;lt;&amp;lt;bit); /* Ohne Warnung, und funktioniert manchmal, je nach Optimierung */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
/* Ausgabe auf meinem PC ohne Optimierung:&lt;br /&gt;
 * sizeof(int)=4&lt;br /&gt;
 * 0&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * Ausgabe auf meinem PC mit -O2&lt;br /&gt;
 * 0&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * 0&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Niederwertigstes gesetztes Bit löschen (Standard C) ===&lt;br /&gt;
&lt;br /&gt;
Folgender Code löscht von allen 1-Bits in einer Integer-Variable das niederwertigste, unabhängig von der Position desselben.&lt;br /&gt;
&lt;br /&gt;
Beispiel: 01101000 -&amp;gt; 01100000&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t byte;&lt;br /&gt;
&lt;br /&gt;
byte = irgendwas();&lt;br /&gt;
&lt;br /&gt;
byte = byte &amp;amp; (byte - 1); /* Diese seltsame Operation löscht das&lt;br /&gt;
                             niederwertigste 1-Bit */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Byte  :  01101000 &lt;br /&gt;
Byte-1:  01100111&lt;br /&gt;
Ergebnis:01100000&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Das funktioniert also mit jeder beliebigen Zahl.&lt;br /&gt;
&lt;br /&gt;
Dies kann bspw. zur schnellen Paritätsgenerierung eingesetzt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t pareven(uint8_t byte) {&lt;br /&gt;
  uint8_t par = 0;&lt;br /&gt;
&lt;br /&gt;
  while(byte) {&lt;br /&gt;
    byte = byte &amp;amp; (byte - 1);&lt;br /&gt;
    par = ~par;&lt;br /&gt;
  }&lt;br /&gt;
  return par;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das genannte gilt natürlich nicht nur für 8-Bit-Integers, sondern für beliebige, vom Compiler unterstützte Wortlängen.&lt;br /&gt;
&lt;br /&gt;
== Bits invertieren ==&lt;br /&gt;
&lt;br /&gt;
Im allgemeinen Sprachgebrauch oft Toggeln genannt (aus dem Englischen). Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] invertiert (getoggelt) werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#XOR_.28Exlusives_Oder.29 | XOR]]-Verknüpfung erreicht. Alle Bits, welche in der Bitmaske &#039;1&#039; sind, werden invertiert. Alle Bits, die in der Maske auf &#039;0&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR Assembler ===&lt;br /&gt;
&lt;br /&gt;
Bei [[AVR]]s erlaubt dies folgender Assemblercode. Hier wird ein Ausgangspin invertiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
  sbic  PortB, 0    ; Überspringe den nächsten Befehl, wenn das Bit 0 im Port gelöscht ist&lt;br /&gt;
  rjmp  ClrBitNow   ; Springe zu ClrBitNow   &lt;br /&gt;
  sbi   PortB, 0    ; Setze Bit 0 in PortB&lt;br /&gt;
  rjmp  BitReady    ; Springe BitReady&lt;br /&gt;
ClrBitNow:&lt;br /&gt;
   cbi  PortB, 0    ; Lösche Bit 0 in PortB&lt;br /&gt;
BitReady:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Noch kürzer gehts so:&amp;lt;br&amp;gt;&lt;br /&gt;
Die zweite Zeile mit dem Befehl &#039;&#039;&#039;ldi&#039;&#039;&#039; lädt die Bitmaske, in welcher die zu toggelnden Bits auf &#039;1&#039; gesetzt sind. In diesem Beispiel wird das dritte Bit invertiert. Der Vorteil dieser Methode ist neben der Kürze und Übersichtlichkeit auch die Möglichkeit, bis zu 8 Bit gleichzeitig zu toggeln. Diese Methode ist natürlich auch auf normale Daten anwendbar, nicht nur auf IO-Ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
 in     R24, PORTE   ; Daten lesen&lt;br /&gt;
 ldi    R25, 0x04    ; Bitmaske laden, hier Bit #2&lt;br /&gt;
 eor    R24, R25     ; Exklusiv ODER&lt;br /&gt;
 out    PORTE, R24   ; Daten zurückschreiben&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine andere Möglichkeit gibt es, wenn man nur das 8. Bit kippen will:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
 in      r16, PORTB&lt;br /&gt;
 subi    r16, 0x80&lt;br /&gt;
 out     PORTB, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 PORTB ^= (1&amp;lt;&amp;lt;PB0);    /* XOR, Kurzschreibweise, PORTB = PORTB ^ (1&amp;lt;&amp;lt;PB0) */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Neuere ATmegas ===&lt;br /&gt;
&lt;br /&gt;
Bei den neueren ATmegas (z.&amp;amp;nbsp;B. ATmega48) kann man IO-Pins direkt ohne den Umweg über Register togglen, indem man das entsprechende Bit im PINx-Register &#039;&#039;&#039;setzt&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
sbi PIND, 2       ; Bit 2 von Port D togglen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 8051er ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
cpl bitadresse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bits prüfen ==&lt;br /&gt;
&lt;br /&gt;
Will man prüfen ob ein oder mehrere Bits in einer Variable gesetzt oder gelöscht sind, muss man sie mit einer Bitmaske UND verknüpfen. Die Bitmaske muss an den Stellen der zu prüfenden Bits eine &#039;1&#039; haben, an allen anderen eine &#039;0&#039;.&lt;br /&gt;
&lt;br /&gt;
* Ist das Ergebnis gleich Null, sind alle geprüften Bits gelöscht.&lt;br /&gt;
* Ist das Ergebnis ungleich Null, ist mindestens ein geprüftes Bit gesetzt.&lt;br /&gt;
* Ist das Ergebnis gleich der Bitmaske, sind alle geprüften Bits gesetzt.&lt;br /&gt;
&lt;br /&gt;
=== AVR Assembler ===&lt;br /&gt;
&lt;br /&gt;
Der AVR hat spezielle Befehle um direkt einzelne Bits in den CPU-Registern r0..r31 sowie den IO-Registern 0..0x1F zu prüfen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
; Befehle zur Prüfung von einzelnen Bits&lt;br /&gt;
&lt;br /&gt;
    sbrs    r16,3       ; überspringe den nächsten Befehl, wenn in r16 Bit #3 gesetzt ist&lt;br /&gt;
    rjmp    bit_ist_nicht_gesetzt&lt;br /&gt;
&lt;br /&gt;
    sbrc    r16,5       ; überspringe den nächsten Befehl, wenn in r16 Bit #5 gelöscht ist&lt;br /&gt;
    rjmp    bit_ist_nicht_geloescht&lt;br /&gt;
&lt;br /&gt;
    sbis    timsk,3     ; überspringe den nächsten Befehl, wenn in timsk Bit #3 gesetzt ist&lt;br /&gt;
    rjmp    bit_ist_nicht_gesetzt&lt;br /&gt;
&lt;br /&gt;
    sbic    timsk,5     ; überspringe den nächsten Befehl, wenn in timsk Bit #5 gelöscht ist&lt;br /&gt;
    rjmp    bit_ist_nicht_geloescht&lt;br /&gt;
&lt;br /&gt;
; Befehle zur Prüfung von mehreren Bits&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    breq    alle_bits_sind_geloescht&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    brne    mind_ein_bit_ist_gesetzt&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    cpi     r16,0b1010&lt;br /&gt;
    breq    alle_bits_sind_gesetzt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    // prüfe ob Bit 4 in der Variable tmp gelöscht ist&lt;br /&gt;
    // die Klammer ist wichtig &lt;br /&gt;
    if (!(tmp &amp;amp; 0x10)) {        &lt;br /&gt;
       // hier die Anweisungen, wenn das Bit gelöscht ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 und Bit 4 in der Variable tmp gelöscht sind&lt;br /&gt;
    // die Klammer ist wichtig! &lt;br /&gt;
    if ((tmp &amp;amp; 0x11) == 0) {        &lt;br /&gt;
       // hier die Anweisungen, wenn beide Bits gelöscht sind&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 oder Bit 4 in der Variable tmp gesetzt ist&lt;br /&gt;
    if (tmp &amp;amp; 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn mindestens ein Bit gesetzt ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 oder Bit 4 in der Variable tmp gelöscht sind&lt;br /&gt;
    if (~tmp &amp;amp; 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn mindestens ein Bit gelöscht ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 4 in der Variable tmp gesetzt ist &lt;br /&gt;
    if (tmp &amp;amp; 0x10) {        &lt;br /&gt;
       // hier die Anweisungen, wenn das Bit gesetzt ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 und Bit 4 in der Variable tmp gesetzt sind&lt;br /&gt;
    // die Klammer ist wichtig! &lt;br /&gt;
    if ((tmp &amp;amp; 0x11) == 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn beide Bits gesetzt sind&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hilfsfunktionen zur Bitmanipulation in C/C++ ==&lt;br /&gt;
Um &amp;quot;einfacher&amp;quot; elementare Bitmanipulationen durchzuführen bietet es sich an einige Hilfsfunktionen zu definieren. Dabei gibt es zwei verschiedene Möglichkeiten diese zu realiseren:&lt;br /&gt;
* Als C-Makro [[C_Makros]]&lt;br /&gt;
* Als Inline-Funktion&lt;br /&gt;
In beiden Fällen wird bei eingeschalteter Optimierung letztendlich vom Compiler ein sehr kompakter (und identischer!) Code erzeugt, jedoch ist dringend von der Verwendung von Makros abzuraten (siehe [[Makro]] )!&lt;br /&gt;
Im Fehlerfall zeigt der Compiler bei der Verwendung vom Makros keine eindeutigen Fehlermeldungen an, da es sich um simple Ersetzungen handelt - bei der Verwendung von Inline-Funktionen hingegen gibt es eine &amp;quot;brauchbare&amp;quot; Fehlermeldung!&lt;br /&gt;
&lt;br /&gt;
=== Beispiele - Inline Variante ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Achtung: Zugriffe erfolgen über Pointer&lt;br /&gt;
// PORTA, PB2 setzen&lt;br /&gt;
BIT_SET(&amp;amp;PORTA, PB2);&lt;br /&gt;
&lt;br /&gt;
// PORTC, PB0 löschen&lt;br /&gt;
BIT_CLEAR(&amp;amp;PORTC, PB0);&lt;br /&gt;
&lt;br /&gt;
// PORTA, PB2 direkt setzen&lt;br /&gt;
// HIGH&lt;br /&gt;
BIT_BOOL_SET(&amp;amp;PORTA, PB2, 1);&lt;br /&gt;
&lt;br /&gt;
// LOW&lt;br /&gt;
BIT_BOOL_SET(&amp;amp;PORTA, PB2, 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beispiele - MakroVariante ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Achtung: Zugriffe erfolgen direkt über die Variablen/Portnamen&lt;br /&gt;
// PORTA, PB2 setzen&lt;br /&gt;
BIT_SET(PORTA, PB2);&lt;br /&gt;
&lt;br /&gt;
// PORTC, PB0 löschen&lt;br /&gt;
BIT_CLEAR(PORTC, PB0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um die Hilfsfunktionen verwenden zu können einfach folgenden Code in eine neue Header-Datei (z.B. BitIO.h) kopieren:&lt;br /&gt;
&lt;br /&gt;
=== Hilfsfunktionen als Inline-Methoden ===&lt;br /&gt;
Achtung: Wenn nur ein C Compiler verwendet wird, kennt dieser den Typ &amp;quot;bool&amp;quot; nicht, dieser muss dann vorher definiert werden!&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *  BitIO.h&lt;br /&gt;
 *	@author 	Andi Dittrich &amp;lt;http://andidittrich.de&amp;gt;&lt;br /&gt;
 *	@version	1.0&lt;br /&gt;
 *	@license	MIT Style X11 License&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;inttypes.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef BITIO_H_&lt;br /&gt;
#define BITIO_H_&lt;br /&gt;
&lt;br /&gt;
// set bit&lt;br /&gt;
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target |= (1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// set clear&lt;br /&gt;
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target &amp;amp;= ~(1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// bit toogle&lt;br /&gt;
static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target ^= (1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// set bit by boolean&lt;br /&gt;
static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable){&lt;br /&gt;
	if (enable){&lt;br /&gt;
		BIT_SET(target, bit);&lt;br /&gt;
	}else{&lt;br /&gt;
		BIT_CLEAR(target, bit);&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif /* BITIO_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hilfsfunktionen als C-Makro (nicht empfohlen) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* Bit setzen */&lt;br /&gt;
#define set_bit(var, bit) ((var) |= (1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
 &lt;br /&gt;
/* Bit löschen */&lt;br /&gt;
#define clear_bit(var, bit) ((var) &amp;amp;= (unsigned)~(1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
 &lt;br /&gt;
/* Bit togglen */&lt;br /&gt;
#define toggle_bit(var,bit) ((var) ^= (1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bitmanipulation beim MSP430 ==&lt;br /&gt;
&lt;br /&gt;
Beim MSP430 und dessen Compilern sind die Bitnamen meist anders definiert. Und zwar nicht als Bitnummer, sondern als Bitmuster. Darum schreibt man dort die Bitzugriffe in C anders. Das kann auch bei anderen Mikrocontrollern bzw. C-Compilern so sein. Wichtig ist, dass man seine eignen Definitionen in der gleichen Weise wie der Compiler anlegt, um Verwirrung zu vermeiden, siehe [[Strukturierte Programmierung auf Mikrocontrollern]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Definition von Bitnamen in den Headerfiles des Compilers&lt;br /&gt;
&lt;br /&gt;
#define PD4 4               // Definition im AVR GCC als Bitnummer&lt;br /&gt;
#define PD5 5&lt;br /&gt;
&lt;br /&gt;
#define P14 (1&amp;lt;&amp;lt;4)          // Definition im MSP430 GCC als Bitmuster&lt;br /&gt;
#define P15 (1&amp;lt;&amp;lt;5)&lt;br /&gt;
&lt;br /&gt;
// Bitmanipulation im Programm&lt;br /&gt;
 &lt;br /&gt;
   DDRD = (1&amp;lt;&amp;lt;PD5) | (1&amp;lt;&amp;lt;PD4);   // AVR GCC&lt;br /&gt;
   P1DIR = P15 | P14;            // MSP430 GCC&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/179566#1729219 Forumsbeitrag:] Bits aus einem Array extrahieren&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/169509#1631439 Forumsbeitrag:] Bits für ein Schieberegister zusammenstellen, TLC5941&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/353071?goto=3947567#3947567 Forumsbeitrag:] TLC5947 und ATmega16 Bitmanipulation&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/15466?goto=107726#107720 Forumsbeitrag:] Bitreihenfolge ändern&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/23866?goto=new#177674 Forumsbeitrag:] Wie drehe ich eine Bitreihenfolge um?&lt;br /&gt;
* [http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/AVR-Built_002din-Functions.html AVR Build-in Functions], spezielle Funktion im avr-gcc zur schnellen Bitvertauschung, engl.&lt;br /&gt;
&lt;br /&gt;
[[Category:8051]]&lt;br /&gt;
[[Category:AVR-Arithmetik]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Bitmanipulation&amp;diff=89413</id>
		<title>Bitmanipulation</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Bitmanipulation&amp;diff=89413"/>
		<updated>2015-07-27T19:41:01Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* AVR-Assembler */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Bitoperatoren ==&lt;br /&gt;
&lt;br /&gt;
Bitoperatoren stammen ursprünglich aus dem Bereich des Maschinen-Codes und Assembler, existieren aber auch in den meisten Hochsprachen, wie C.&lt;br /&gt;
&lt;br /&gt;
* &amp;gt;&amp;gt; = Rechts schieben&lt;br /&gt;
* &amp;lt;&amp;lt; = Links schieben (Bsp: &#039;&#039;a&amp;lt;&amp;lt;b&#039;&#039; ist das gleiche wie &#039;&#039;a * 2^b&#039;&#039;; bzw. bei 1&amp;lt;&amp;lt;3 wird die 1 um drei Stellen nach links geschoben)&lt;br /&gt;
* |  = binäres ODER&lt;br /&gt;
* &amp;amp;  = binäres UND&lt;br /&gt;
* ^  = binäres Exklusives ODER&lt;br /&gt;
* usw.&lt;br /&gt;
&lt;br /&gt;
Bitoperatoren in dieser Schreibweise können in Assemblercode für&lt;br /&gt;
konstante Ausdrücke benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, (1&amp;lt;&amp;lt;3) | (1&amp;lt;&amp;lt;1) | (1&amp;lt;&amp;lt;2) | (1&amp;lt;&amp;lt;0)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
wird zu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, 8 | 2 | 4 | 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
wird zu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, 15&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bitmaske ==&lt;br /&gt;
&lt;br /&gt;
Im Folgenden ist häufiger von dem Begriff &#039;&#039;Bitmaske&#039;&#039; die Rede. Damit wird eine Folge von einzelnen Bit bezeichnet, die den Zustand Null (&#039;0&#039;) oder Eins (&#039;1&#039;) darstellen können.&lt;br /&gt;
&lt;br /&gt;
Bitmasken werden im allgemeinen dazu verwendet, um unter Anwendung eines Operators (z.&amp;amp;nbsp;B. UND, ODER, XOR), eine Eingabe zu manipulieren. Das Ergebnis ist dann die Anwendung des Operators auf die Eingabe und der Bitmaske.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Operator eine Funktion mit zwei Argumenten ist, dann lässt sich dessen Anwendung wie folgt schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Ergebnis = Operator( Eingabe, Bitmaske )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Bitmaske ist häufig eine Konstante, da diese z.&amp;amp;nbsp;B. die Information über die Position einer Information in einem Register darstellt. Das kann z.&amp;amp;nbsp;B. ein Überlaufflag in einem Timer Statusregister sein.&lt;br /&gt;
&lt;br /&gt;
== Bits setzen ==&lt;br /&gt;
&lt;br /&gt;
Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] auf Eins gesetzt werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#ODER | ODER]]-Verknüpfung erreicht.  Alle Bits, welche in der Bitmaske &#039;1&#039; sind, werden auf &#039;1&#039; gesetzt. Alle Bits, die in der Maske auf &#039;0&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR-Assembler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
sbr r16, 0b11110000     ; setzt Bits 4-7 in r16, ist ein Pseudobefehl&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
ori r16, 0b11110000     ; setzt Bits 4-7 in r16, ori ist identisch mit sbr&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
sbi PORTB, 5            ; setzt Bit 5 in PortB&lt;br /&gt;
sbi PORTB, PB5          ; identisch, besser lesbar&lt;br /&gt;
                        ; funktioniert nur für die IO-Register 0..0x1F&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register mit I/O Adresse 0x20..0x3F muss&lt;br /&gt;
                        ; in/out verwendet werden&lt;br /&gt;
in  r16, TIMSK          ; setzt Bit TOIE1 in TIMSK&lt;br /&gt;
sbr r16, (1&amp;lt;&amp;lt;TOIE1)    &lt;br /&gt;
out TIMSK, r16&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register oberhalb der I/O Adresse 0x3F muss&lt;br /&gt;
                        ; lds/sts verwednet werden&lt;br /&gt;
                        ; setzt Bit RXCIE0 in UCSR0B&lt;br /&gt;
lds r16, UCSR0B &lt;br /&gt;
sbr r16, (1&amp;lt;&amp;lt;RXCIE0)    &lt;br /&gt;
sts UCSR0B, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Man beachte den Unterschied! Eine &amp;quot;5&amp;quot; würde von sbr als &amp;quot;setze Bit 2 und 0&amp;quot; gedeutet (=0b00000101), während sbi sie als &amp;quot;setze Bit 5&amp;quot; versteht. Der Befehl &#039;&#039;&#039;sbr&#039;&#039;&#039; erwartet ein Bit&#039;&#039;&#039;muster&#039;&#039;&#039; für eine ODER-Verknüpfung, während der Befehlt &#039;&#039;&#039;sbi&#039;&#039;&#039; die Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; benötigt. Darauf sind auch die Includefiles von Atmel im AVR-Studio (Assembler) als auch [[WinAVR]] (C) ausgelegt. Die Namen der Bits sind als Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; definiert. Das ist wichtig, wenn man Register von grossen AVRs manipuliert, z.&amp;amp;nbsp;B. ATmega48. Hier muss aus der Bitnummer über eine Schiebeoperation erst das Bit&#039;&#039;&#039;muster&#039;&#039;&#039; gemacht werden.&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB |= 0xF0;   // Kurzschreibweise, entspricht PORTB = PORTB | 0xF0; bitweises ODER&lt;br /&gt;
&lt;br /&gt;
/* übersichtlicher mittels Bit-Definitionen */&lt;br /&gt;
#define MEINBIT0 0&lt;br /&gt;
#define MEINBIT1 1&lt;br /&gt;
#define MEINBIT2 2&lt;br /&gt;
&lt;br /&gt;
PORTB |= ((1 &amp;lt;&amp;lt; MEINBIT0) | (1 &amp;lt;&amp;lt; MEINBIT2)); // setzt Bit 0 und 2 in PORTB auf &amp;quot;1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die letzte Zeile &amp;quot;entschlüsselt&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;(1 &amp;lt;&amp;lt; n)&#039;&#039;&#039; : Zuerst wird durch die &#039;&amp;lt;&amp;lt;&#039;-Ausdrücke eine &amp;quot;1&amp;quot; n-mal nach links geschoben.  Dies ergibt somit (in Binärschreibweise) 0b00000001 für (1 &amp;lt;&amp;lt; MEINBIT0) und 0b00000100 für (1 &amp;lt;&amp;lt; MEINBIT2).&lt;br /&gt;
# &#039;&#039;&#039;|&#039;&#039;&#039; : Das Ergebnis wird bitweise ODER-verknüpft, also 0b00000001 &#039;&#039;or&#039;&#039; 0b00000100 wird zu 0b00000101.&lt;br /&gt;
# &#039;&#039;&#039;|=&#039;&#039;&#039; : Diese Maske wird mit dem aktuellen Inhalt von PORTB bitweise ODER-verknüpft und das Ergebnis PORTB wieder zugewiesen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB |= variable;         // Kurzschreibweise&lt;br /&gt;
PORTB  = PORTB | variable; // lange Schreibweise&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Ist PORTB vorher z.&amp;amp;nbsp;B. 0b01111010, dann ist der Inhalt nach der Operation 0b01111010 &#039;&#039;or&#039;&#039; 0b00000101 = 0b01111111, die gewünschten Bits sind somit gesetzt!&lt;br /&gt;
&lt;br /&gt;
Anmerkung: Will man das gezeigte Beispiel der Bitmanipulation auf größere Datentypen anwenden, ist zu beachten, dass der Compiler in der Operation (1 &amp;lt;&amp;lt; MEINBIT1) stillschweigend gemäss, den C-Regeln, die 1 als Integer Typ ansieht. Beim AVR-GCC bedeutet das 16-Bit/signed und die folgende Operation bringt ggf. nicht das gewünschte Ergebnis. (Stichwort: &amp;quot;Integer Promotion&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Angenommen Bit 15 soll in einer 32-Bit weiten Variable gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define MEINBIT15 15&lt;br /&gt;
#define MEINBIT42 42&lt;br /&gt;
&lt;br /&gt;
uint32_t reg_32; /* uint32_t definiert per typedef z.&amp;amp;nbsp;B. in stdint.h */&lt;br /&gt;
uint64_t reg_64; /* uint64_t definiert per typedef z.&amp;amp;nbsp;B. in stdint.h */&lt;br /&gt;
&lt;br /&gt;
reg_32 |= (1 &amp;lt;&amp;lt; MEINBIT15);              /* FEHLER: Setzt die Bits 31 - 15, da ((int)1 &amp;lt;&amp;lt; 15) == 0xFFFF8000 */&lt;br /&gt;
&lt;br /&gt;
reg_32 |= ((uint32_t)1 &amp;lt;&amp;lt; MEINBIT15);    /* Hier wird nur Bit 15 gesetzt. */&lt;br /&gt;
reg_32 |= (1U &amp;lt;&amp;lt; MEINBIT15);             /* */&lt;br /&gt;
reg_32 |= (1L &amp;lt;&amp;lt; MEINBIT15);             /* andere Schreibweise. */&lt;br /&gt;
reg_64 |= (1LL &amp;lt;&amp;lt; MEINBIT42);            /* Hier wird nur Bit 42 gesetzt,&lt;br /&gt;
                                            andere Schreibweise für 64 Bit (long long). */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei Compilern für 32bit Controller (z.&amp;amp;nbsp;B. ARM7TDMI) sind Integers per default 32-bit und Konstanten sind somit implizit ebenfalls 32-bit. Man sollte aber dennoch die oben gezeigte Vorgehenweise verwenden, um Probleme zu vermeiden die entstehen könnten, wenn Code unter verschiedenen Plattformen/Compilern verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
== Bits löschen ==&lt;br /&gt;
&lt;br /&gt;
Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] auf Null gesetzt werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#UND | UND]]-Verknüpfung erreicht. Alle Bits, welche in der Bitmaske &#039;0&#039; sind, werden auf &#039;0&#039; gesetzt. Alle Bits, die in der Maske auf &#039;1&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR-Assembler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
cbr r16, 0b00001111     ; löscht Bits 0-3 in r16, ist ein Pseudobefehl &lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
andi r16, 0b11110000    ; löscht Bits 0-3 in r16, andi ist identisch mit cbr&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
andi r16, ~0b00001111   ; andere Schreibweise, hier wird die Bitmaske durch ~ invertiert&lt;br /&gt;
                        ; dadurch kann man einfach alle zu löschenden Bit als &#039;1&#039; angeben&lt;br /&gt;
                        ; so wie bei den Bitmasken für das setzen von Bits (positive Logik)&lt;br /&gt;
&lt;br /&gt;
cbi PORTB, 5            ; löscht Bit 5 in PortB&lt;br /&gt;
cbi PORTB, PB5          ; identisch, besser lesbar&lt;br /&gt;
                        ; funktioniert nur für die IO-Register 0..31&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register mit I/O Adresse 0x20..0x3F muss&lt;br /&gt;
                        ; in/out verwendet werden weil dieser Bereich nicht&lt;br /&gt;
                        ; bitadressierbar ist&lt;br /&gt;
in  r16, TIMSK          ; löscht Bit TOIE1 in TIMSK&lt;br /&gt;
cbr r16, 1&amp;lt;&amp;lt;TOIE1    &lt;br /&gt;
out TIMSK, r16&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register oberhalb der I/O Adresse 0x3F muss&lt;br /&gt;
                        ; lds/sts verwednet werden&lt;br /&gt;
                        ; löscht Bit RXCIE0 in UCSR0B&lt;br /&gt;
lds r16, UCSR0B &lt;br /&gt;
cbr r16, 1&amp;lt;&amp;lt;RXCIE0&lt;br /&gt;
sts UCSR0B, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier gilt: Man beachte den Unterschied! Eine &amp;quot;5&amp;quot; würde von cbr als &amp;quot;lösche Bit 2 und 0&amp;quot; gedeutet, während cbi sie als &amp;quot;lösche Bit 5&amp;quot; versteht. Der Befehl &#039;&#039;&#039;cbr&#039;&#039;&#039; erwartet ein Bit&#039;&#039;&#039;muster&#039;&#039;&#039; für eine UND-NOT-Verknüpfung (nicht zu verwechseln mit NAND), während der Befehl &#039;&#039;&#039;cbi&#039;&#039;&#039; die Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; benötigt. Darauf sind auch die Includefiles von Atmel im AVR-Studio (Assembler) als auch [[WinAVR]] ausgelegt. Die Namen der Bits sind als Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; definiert. Das ist wichtig, wenn man Register von grossen AVRs manipuliert, z.&amp;amp;nbsp;B. ATmega48. Hier muss aus der Bitnummer über eine Schiebeoperation &amp;lt;&amp;lt; erst das Bit&#039;&#039;&#039;muster&#039;&#039;&#039; gemacht werden.&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB &amp;amp;= 0xF0;   // entspricht PORTB = PORTB &amp;amp; 0xF0; bitweises UND&lt;br /&gt;
                 // Bits 0-3 (das &amp;quot;niederwertige&amp;quot; Nibble) werden geloescht &lt;br /&gt;
&lt;br /&gt;
/* übersichtlicher mittels Bit-Definitionen */ &lt;br /&gt;
#define MEINBIT0 0&lt;br /&gt;
#define MEINBIT1 1  &lt;br /&gt;
#define MEINBIT2 2  &lt;br /&gt;
&lt;br /&gt;
PORTB &amp;amp;= ~((1 &amp;lt;&amp;lt; MEINBIT0) | (1 &amp;lt;&amp;lt; MEINBIT2)); // löscht Bit 0 und 2 in PORTB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die letzte Zeile entschlüsselt:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;(1 &amp;lt;&amp;lt; n)&#039;&#039;&#039; : Zuerst wird durch die &#039;&amp;lt;&amp;lt;&#039;-Ausdrücke eine &amp;quot;1&amp;quot; n-mal nach links geschoben. Dies ergibt somit (in Binärschreibweise) 0b00000001 für (1 &amp;lt;&amp;lt; MEINBIT0) und 0b00000100 für (1 &amp;lt;&amp;lt; MEINBIT2).&lt;br /&gt;
# &#039;&#039;&#039;|&#039;&#039;&#039; : Das Ergebnis wird bitweise ODER-verknüpft also 0b00000001 &#039;&#039;or&#039;&#039; 0b00000100 wird zu 0b00000101.&lt;br /&gt;
# &#039;&#039;&#039;~&#039;&#039;&#039; : Der Wert in der Klammer wird bitweise invertiert, aus 0b00000101 wird 0b11111010.&lt;br /&gt;
# &#039;&#039;&#039;&amp;amp;=&#039;&#039;&#039; : PORTB wird mit der berechneten Maske UND-verknüpft und das Ergebnis wieder PORTB zugewiesen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB &amp;amp;= variable;          // Kurzschreibweise&lt;br /&gt;
PORTB  = PORTB &amp;amp; variable;  // lange Schreibweise&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Ist PORTB vorher z.&amp;amp;nbsp;B. 0b01111111, dann ist der Inhalt nach der Operation 0b01111111 &#039;&#039;and&#039;&#039; 0b11111010 = 0b01111010, die gewünschten Bits 0 und 2 sind somit gelöscht.&lt;br /&gt;
&lt;br /&gt;
Die C-Ausdrücke mittels Definitionen von Bitnummern und Schieboperator (&amp;lt;&amp;lt;) sehen auf den ersten Blick etwas &amp;quot;erschreckend&amp;quot; aus und sind mehr &amp;quot;Tipparbeit&amp;quot;, funktionieren aber universell und sind deutlicher und nachvollziehbarer als &amp;quot;handoptimierte&amp;quot; Konstanten. Bei eingeschalteter Optimierung löst der Compiler die Ausdücke mit konstanten Werten bereits zur Compilierungszeit auf und es entsteht kein zusätzlicher Maschinencode. Bei AVR sind die Definitionen meist Teil der Entwicklungsumgebungen (bei avr-libc z.&amp;amp;nbsp;B. implizit durch #include &amp;lt;avr/io.h&amp;gt;). Sie entsprechen den Angaben und Beispielen in den Datenblättern und sind damit de-facto ein Standard beim Zugriff auf Bits in Hardware-Registern.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Wichtiger Hinweis&#039;&#039;&#039;: Die ODER-Verknüpfung und die anschliessende Invertierung kann man nicht vertauschen! (Theorem von DeMorgan) Folgendes Beispiel soll die Richtigkeit der Aussage zeigen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 ~(0b0001 | 0b0010) == 0b1100&lt;br /&gt;
  ~0b0001 | ~0b0010 == 0b1111&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Noch ein wichtiger Hinweis&#039;&#039;&#039;: Der operator ~ mit einem Operanden vom Typ int negiert nur so viele bits, wie der Typ int hat.&lt;br /&gt;
Will man ein bit in einer breiteren Variablen löschen, dann sollte die nach links zu shiftende 1 den Typ dieser Variablen haben.&lt;br /&gt;
&lt;br /&gt;
Ein Programm, welches das verdeutlicht:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, const char* argv[])&lt;br /&gt;
{&lt;br /&gt;
    int bit = 60;&lt;br /&gt;
    uint64_t ui64;&lt;br /&gt;
    printf(&amp;quot;sizeof(int)=%d\n&amp;quot;, (int)sizeof(int));&lt;br /&gt;
    &lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;    &lt;br /&gt;
    ui64 &amp;amp;= ~(1&amp;lt;&amp;lt;60); /* Keine Wirkung bei sizeof(int) &amp;lt; 8 */&lt;br /&gt;
    /* gcc warnt sogar:    &lt;br /&gt;
     * gcc -Wall bit_clear.c -o bit_clear&lt;br /&gt;
     * bit_clear.c: In function ‘main’:&lt;br /&gt;
     * bit_clear.c:11:5: warning: left shift count &amp;gt;= width of type [enabled by default]&lt;br /&gt;
     */    &lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;    &lt;br /&gt;
    ui64 &amp;amp;= ~((uint64_t)1&amp;lt;&amp;lt;60); /* ok */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;&lt;br /&gt;
    ui64 &amp;amp;= ~(1LL&amp;lt;&amp;lt;60); /* auch ok, und kürzer. */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;&lt;br /&gt;
    ui64 &amp;amp;= ~(1&amp;lt;&amp;lt;bit); /* Ohne Warnung, und funktioniert manchmal, je nach Optimierung */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
/* Ausgabe auf meinem PC ohne Optimierung:&lt;br /&gt;
 * sizeof(int)=4&lt;br /&gt;
 * 0&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * Ausgabe auf meinem PC mit -O2&lt;br /&gt;
 * 0&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * 0&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Niederwertigstes gesetztes Bit löschen (Standard C) ===&lt;br /&gt;
&lt;br /&gt;
Folgender Code löscht von allen 1-Bits in einer Integer-Variable das niederwertigste, unabhängig von der Position desselben.&lt;br /&gt;
&lt;br /&gt;
Beispiel: 01101000 -&amp;gt; 01100000&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t byte;&lt;br /&gt;
&lt;br /&gt;
byte = irgendwas();&lt;br /&gt;
&lt;br /&gt;
byte = byte &amp;amp; (byte - 1); /* Diese seltsame Operation löscht das&lt;br /&gt;
                             niederwertigste 1-Bit */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Byte  :  01101000 &lt;br /&gt;
Byte-1:  01100111&lt;br /&gt;
Ergebnis:01100000&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Das funktioniert also mit jeder beliebigen Zahl.&lt;br /&gt;
&lt;br /&gt;
Dies kann bspw. zur schnellen Paritätsgenerierung eingesetzt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t pareven(uint8_t byte) {&lt;br /&gt;
  uint8_t par = 0;&lt;br /&gt;
&lt;br /&gt;
  while(byte) {&lt;br /&gt;
    byte = byte &amp;amp; (byte - 1);&lt;br /&gt;
    par = ~par;&lt;br /&gt;
  }&lt;br /&gt;
  return par;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das genannte gilt natürlich nicht nur für 8-Bit-Integers, sondern für beliebige, vom Compiler unterstützte Wortlängen.&lt;br /&gt;
&lt;br /&gt;
== Bits invertieren ==&lt;br /&gt;
&lt;br /&gt;
Im allgemeinen Sprachgebrauch oft Toggeln genannt (aus dem Englischen). Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] invertiert (getoggelt) werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#XOR_.28Exlusives_Oder.29 | XOR]]-Verknüpfung erreicht. Alle Bits, welche in der Bitmaske &#039;1&#039; sind, werden invertiert. Alle Bits, die in der Maske auf &#039;0&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR Assembler ===&lt;br /&gt;
&lt;br /&gt;
Bei [[AVR]]s erlaubt dies folgender Assemblercode. Hier wird ein Ausgangspin invertiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
  sbic  PortB, 0    ; Überspringe den nächsten Befehl, wenn das Bit 0 im Port gelöscht ist&lt;br /&gt;
  rjmp  ClrBitNow   ; Springe zu ClrBitNow   &lt;br /&gt;
  sbi   PortB, 0    ; Setze Bit 0 in PortB&lt;br /&gt;
  rjmp  BitReady    ; Springe BitReady&lt;br /&gt;
ClrBitNow:&lt;br /&gt;
   cbi  PortB, 0    ; Lösche Bit 0 in PortB&lt;br /&gt;
BitReady:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Noch kürzer gehts so:&amp;lt;br&amp;gt;&lt;br /&gt;
Die zweite Zeile mit dem Befehl &#039;&#039;&#039;ldi&#039;&#039;&#039; lädt die Bitmaske, in welcher die zu toggelnden Bits auf &#039;1&#039; gesetzt sind. In diesem Beispiel wird das dritte Bit invertiert. Der Vorteil dieser Methode ist neben der Kürze und Übersichtlichkeit auch die Möglichkeit, bis zu 8 Bit gleichzeitig zu toggeln. Diese Methode ist natürlich auch auf normale Daten anwendbar, nicht nur auf IO-Ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
 in     R24, PORTE   ; Daten lesen&lt;br /&gt;
 ldi    R25, 0x04    ; Bitmaske laden, hier Bit #2&lt;br /&gt;
 eor    R24, R25     ; Exklusiv ODER&lt;br /&gt;
 out    PORTE, R24   ; Daten zurückschreiben&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine andere Möglichkeit gibt es, wenn man nur das 8. Bit kippen will:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
 in      r16, PORTB&lt;br /&gt;
 subi    r16, 0x80&lt;br /&gt;
 out     PORTB, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 PORTB ^= (1&amp;lt;&amp;lt;PB0);    /* XOR, Kurzschreibweise, PORTB = PORTB ^ (1&amp;lt;&amp;lt;PB0) */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Neuere ATmegas ===&lt;br /&gt;
&lt;br /&gt;
Bei den neueren ATmegas (z.&amp;amp;nbsp;B. ATmega48) kann man IO-Pins direkt ohne den Umweg über Register togglen, indem man das entsprechende Bit im PINx-Register &#039;&#039;&#039;setzt&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
sbi PIND, 2       ; Bit 2 von Port D togglen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 8051er ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
cpl bitadresse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bits prüfen ==&lt;br /&gt;
&lt;br /&gt;
Will man prüfen ob ein oder mehrere Bits in einer Variable gesetzt oder gelöscht sind, muss man sie mit einer Bitmaske UND verknüpfen. Die Bitmaske muss an den Stellen der zu prüfenden Bits eine &#039;1&#039; haben, an allen anderen eine &#039;0&#039;.&lt;br /&gt;
&lt;br /&gt;
* Ist das Ergebnis gleich Null, sind alle geprüften Bits gelöscht.&lt;br /&gt;
* Ist das Ergebnis ungleich Null, ist mindestens ein geprüftes Bit gesetzt.&lt;br /&gt;
* Ist das Ergebnis gleich der Bitmaske, sind alle geprüften Bits gesetzt.&lt;br /&gt;
&lt;br /&gt;
=== AVR Assembler ===&lt;br /&gt;
&lt;br /&gt;
Der AVR hat spezielle Befehle um direkt einzelne Bits in den CPU-Registern r0..r31 sowie den IO-Registern 0..0x1F zu prüfen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
; Befehle zur Prüfung von einzelnen Bits&lt;br /&gt;
&lt;br /&gt;
    sbrs    r16,3       ; überspringe den nächsten Befehl, wenn in r16 Bit #3 gesetzt ist&lt;br /&gt;
    rjmp    bit_ist_nicht_gesetzt&lt;br /&gt;
&lt;br /&gt;
    sbrc    r16,5       ; überspringe den nächsten Befehl, wenn in r16 Bit #5 gelöscht ist&lt;br /&gt;
    rjmp    bit_ist_nicht_geloescht&lt;br /&gt;
&lt;br /&gt;
    sbis    timsk,3     ; überspringe den nächsten Befehl, wenn in timsk Bit #3 gesetzt ist&lt;br /&gt;
    rjmp    bit_ist_nicht_gesetzt&lt;br /&gt;
&lt;br /&gt;
    sbic    timsk,5     ; überspringe den nächsten Befehl, wenn in timsk Bit #5 gelöscht ist&lt;br /&gt;
    rjmp    bit_ist_nicht_geloescht&lt;br /&gt;
&lt;br /&gt;
; Befehle zur Prüfung von mehreren Bits&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    breq    alle_bits_sind_geloescht&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    brne    mind_ein_bit_ist_gesetzt&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    cpi     r16,0b1010&lt;br /&gt;
    breq    alle_bits_sind_gesetzt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    // prüfe ob Bit 4 in der Variable tmp gelöscht ist&lt;br /&gt;
    // die Klammer ist wichtig &lt;br /&gt;
    if (!(tmp &amp;amp; 0x10)) {        &lt;br /&gt;
       // hier die Anweisungen, wenn das Bit gelöscht ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 und Bit 4 in der Variable tmp gelöscht sind&lt;br /&gt;
    // die Klammer ist wichtig! &lt;br /&gt;
    if ((tmp &amp;amp; 0x11) == 0) {        &lt;br /&gt;
       // hier die Anweisungen, wenn beide Bits gelöscht sind&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 oder Bit 4 in der Variable tmp gesetzt ist&lt;br /&gt;
    if (tmp &amp;amp; 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn mindestens ein Bit gesetzt ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 oder Bit 4 in der Variable tmp gelöscht sind&lt;br /&gt;
    if (~tmp &amp;amp; 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn mindestens ein Bit gelöscht ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 4 in der Variable tmp gesetzt ist &lt;br /&gt;
    if (tmp &amp;amp; 0x10) {        &lt;br /&gt;
       // hier die Anweisungen, wenn das Bit gesetzt ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 und Bit 4 in der Variable tmp gesetzt sind&lt;br /&gt;
    // die Klammer ist wichtig! &lt;br /&gt;
    if ((tmp &amp;amp; 0x11) == 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn beide Bits gesetzt sind&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hilfsfunktionen zur Bitmanipulation in C/C++ ==&lt;br /&gt;
Um &amp;quot;einfacher&amp;quot; elementare Bitmanipulationen durchzuführen bietet es sich an einige Hilfsfunktionen zu definieren. Dabei gibt es zwei verschiedene Möglichkeiten diese zu realiseren:&lt;br /&gt;
* Als C-Makro [[C_Makros]]&lt;br /&gt;
* Als Inline-Funktion&lt;br /&gt;
In beiden Fällen wird bei eingeschalteter Optimierung letztendlich vom Compiler ein sehr kompakter (und identischer!) Code erzeugt, jedoch ist dringend von der Verwendung von Makros abzuraten (siehe [[Makro]] )!&lt;br /&gt;
Im Fehlerfall zeigt der Compiler bei der Verwendung vom Makros keine eindeutigen Fehlermeldungen an, da es sich um simple Ersetzungen handelt - bei der Verwendung von Inline-Funktionen hingegen gibt es eine &amp;quot;brauchbare&amp;quot; Fehlermeldung!&lt;br /&gt;
&lt;br /&gt;
=== Beispiele - Inline Variante ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Achtung: Zugriffe erfolgen über Pointer&lt;br /&gt;
// PORTA, PB2 setzen&lt;br /&gt;
BIT_SET(&amp;amp;PORTA, PB2);&lt;br /&gt;
&lt;br /&gt;
// PORTC, PB0 löschen&lt;br /&gt;
BIT_CLEAR(&amp;amp;PORTC, PB0);&lt;br /&gt;
&lt;br /&gt;
// PORTA, PB2 direkt setzen&lt;br /&gt;
// HIGH&lt;br /&gt;
BIT_BOOL_SET(&amp;amp;PORTA, PB2, 1);&lt;br /&gt;
&lt;br /&gt;
// LOW&lt;br /&gt;
BIT_BOOL_SET(&amp;amp;PORTA, PB2, 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beispiele - MakroVariante ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Achtung: Zugriffe erfolgen direkt über die Variablen/Portnamen&lt;br /&gt;
// PORTA, PB2 setzen&lt;br /&gt;
BIT_SET(PORTA, PB2);&lt;br /&gt;
&lt;br /&gt;
// PORTC, PB0 löschen&lt;br /&gt;
BIT_CLEAR(PORTC, PB0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um die Hilfsfunktionen verwenden zu können einfach folgenden Code in eine neue Header-Datei (z.B. BitIO.h) kopieren:&lt;br /&gt;
&lt;br /&gt;
=== Hilfsfunktionen als Inline-Methoden ===&lt;br /&gt;
Achtung: Wenn nur ein C Compiler verwendet wird, kennt dieser den Typ &amp;quot;bool&amp;quot; nicht, dieser muss dann vorher definiert werden!&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *  BitIO.h&lt;br /&gt;
 *	@author 	Andi Dittrich &amp;lt;http://andidittrich.de&amp;gt;&lt;br /&gt;
 *	@version	1.0&lt;br /&gt;
 *	@license	MIT Style X11 License&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;inttypes.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef BITIO_H_&lt;br /&gt;
#define BITIO_H_&lt;br /&gt;
&lt;br /&gt;
// set bit&lt;br /&gt;
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target |= (1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// set clear&lt;br /&gt;
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target &amp;amp;= ~(1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// bit toogle&lt;br /&gt;
static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target ^= (1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// set bit by boolean&lt;br /&gt;
static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable){&lt;br /&gt;
	if (enable){&lt;br /&gt;
		BIT_SET(target, bit);&lt;br /&gt;
	}else{&lt;br /&gt;
		BIT_CLEAR(target, bit);&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif /* BITIO_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hilfsfunktionen als C-Makro (nicht empfohlen) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* Bit setzen */&lt;br /&gt;
#define set_bit(var, bit) ((var) |= (1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
 &lt;br /&gt;
/* Bit löschen */&lt;br /&gt;
#define clear_bit(var, bit) ((var) &amp;amp;= (unsigned)~(1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
 &lt;br /&gt;
/* Bit togglen */&lt;br /&gt;
#define toggle_bit(var,bit) ((var) ^= (1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bitmanipulation beim MSP430 ==&lt;br /&gt;
&lt;br /&gt;
Beim MSP430 und dessen Compilern sind die Bitnamen meist anders definiert. Und zwar nicht als Bitnummer, sondern als Bitmuster. Darum schreibt man dort die Bitzugriffe in C anders. Das kann auch bei anderen Mikrocontrollern bzw. C-Compilern so sein. Wichtig ist, dass man seine eignen Definitionen in der gleichen Weise wie der Compiler anlegt, um Verwirrung zu vermeiden, siehe [[Strukturierte Programmierung auf Mikrocontrollern]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Definition von Bitnamen in den Headerfiles des Compilers&lt;br /&gt;
&lt;br /&gt;
#define PD4 4               // Definition im AVR GCC als Bitnummer&lt;br /&gt;
#define PD5 5&lt;br /&gt;
&lt;br /&gt;
#define P14 (1&amp;lt;&amp;lt;4)          // Definition im MSP430 GCC als Bitmuster&lt;br /&gt;
#define P15 (1&amp;lt;&amp;lt;5)&lt;br /&gt;
&lt;br /&gt;
// Bitmanipulation im Programm&lt;br /&gt;
 &lt;br /&gt;
   DDRD = (1&amp;lt;&amp;lt;PD5) | (1&amp;lt;&amp;lt;PD4);   // AVR GCC&lt;br /&gt;
   P1DIR = P15 | P14;            // MSP430 GCC&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/179566#1729219 Forumsbeitrag:] Bits aus einem Array extrahieren&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/169509#1631439 Forumsbeitrag:] Bits für ein Schieberegister zusammenstellen, TLC5941&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/353071?goto=3947567#3947567 Forumsbeitrag:] TLC5947 und ATmega16 Bitmanipulation&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/15466?goto=107726#107720 Forumsbeitrag:] Bitreihenfolge ändern&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/23866?goto=new#177674 Forumsbeitrag:] Wie drehe ich eine Bitreihenfolge um?&lt;br /&gt;
* [http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/AVR-Built_002din-Functions.html AVR Build-in Functions], spezielle Funktion im avr-gcc zur schnellen Bitvertauschung, engl.&lt;br /&gt;
&lt;br /&gt;
[[Category:8051]]&lt;br /&gt;
[[Category:AVR-Arithmetik]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Bitmanipulation&amp;diff=89412</id>
		<title>Bitmanipulation</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Bitmanipulation&amp;diff=89412"/>
		<updated>2015-07-27T19:40:39Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* AVR Assembler */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Bitoperatoren ==&lt;br /&gt;
&lt;br /&gt;
Bitoperatoren stammen ursprünglich aus dem Bereich des Maschinen-Codes und Assembler, existieren aber auch in den meisten Hochsprachen, wie C.&lt;br /&gt;
&lt;br /&gt;
* &amp;gt;&amp;gt; = Rechts schieben&lt;br /&gt;
* &amp;lt;&amp;lt; = Links schieben (Bsp: &#039;&#039;a&amp;lt;&amp;lt;b&#039;&#039; ist das gleiche wie &#039;&#039;a * 2^b&#039;&#039;; bzw. bei 1&amp;lt;&amp;lt;3 wird die 1 um drei Stellen nach links geschoben)&lt;br /&gt;
* |  = binäres ODER&lt;br /&gt;
* &amp;amp;  = binäres UND&lt;br /&gt;
* ^  = binäres Exklusives ODER&lt;br /&gt;
* usw.&lt;br /&gt;
&lt;br /&gt;
Bitoperatoren in dieser Schreibweise können in Assemblercode für&lt;br /&gt;
konstante Ausdrücke benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, (1&amp;lt;&amp;lt;3) | (1&amp;lt;&amp;lt;1) | (1&amp;lt;&amp;lt;2) | (1&amp;lt;&amp;lt;0)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
wird zu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, 8 | 2 | 4 | 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
wird zu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, 15&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bitmaske ==&lt;br /&gt;
&lt;br /&gt;
Im Folgenden ist häufiger von dem Begriff &#039;&#039;Bitmaske&#039;&#039; die Rede. Damit wird eine Folge von einzelnen Bit bezeichnet, die den Zustand Null (&#039;0&#039;) oder Eins (&#039;1&#039;) darstellen können.&lt;br /&gt;
&lt;br /&gt;
Bitmasken werden im allgemeinen dazu verwendet, um unter Anwendung eines Operators (z.&amp;amp;nbsp;B. UND, ODER, XOR), eine Eingabe zu manipulieren. Das Ergebnis ist dann die Anwendung des Operators auf die Eingabe und der Bitmaske.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Operator eine Funktion mit zwei Argumenten ist, dann lässt sich dessen Anwendung wie folgt schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Ergebnis = Operator( Eingabe, Bitmaske )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Bitmaske ist häufig eine Konstante, da diese z.&amp;amp;nbsp;B. die Information über die Position einer Information in einem Register darstellt. Das kann z.&amp;amp;nbsp;B. ein Überlaufflag in einem Timer Statusregister sein.&lt;br /&gt;
&lt;br /&gt;
== Bits setzen ==&lt;br /&gt;
&lt;br /&gt;
Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] auf Eins gesetzt werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#ODER | ODER]]-Verknüpfung erreicht.  Alle Bits, welche in der Bitmaske &#039;1&#039; sind, werden auf &#039;1&#039; gesetzt. Alle Bits, die in der Maske auf &#039;0&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR-Assembler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
sbr r16, 0b11110000     ; setzt Bits 4-7 in r16, ist ein Pseudobefehl&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
ori r16, 0b11110000     ; setzt Bits 4-7 in r16, ori ist identisch mit sbr&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
sbi PORTB, 5            ; setzt Bit 5 in PortB&lt;br /&gt;
sbi PORTB, PB5          ; identisch, besser lesbar&lt;br /&gt;
                        ; funktioniert nur für die IO-Register 0..0x1F&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register mit I/O Adresse 0x20..0x3F muss&lt;br /&gt;
                        ; in/out verwendet werden&lt;br /&gt;
in  r16, TIMSK          ; setzt Bit TOIE1 in TIMSK&lt;br /&gt;
sbr r16, (1&amp;lt;&amp;lt;TOIE1)    &lt;br /&gt;
out TIMSK, r16&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register oberhalb der I/O Adresse 0x3F muss&lt;br /&gt;
                        ; lds/sts verwednet werden&lt;br /&gt;
                        ; setzt Bit RXCIE0 in UCSR0B&lt;br /&gt;
lds r16, UCSR0B &lt;br /&gt;
sbr r16, (1&amp;lt;&amp;lt;RXCIE0)    &lt;br /&gt;
sts UCSR0B, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Man beachte den Unterschied! Eine &amp;quot;5&amp;quot; würde von sbr als &amp;quot;setze Bit 2 und 0&amp;quot; gedeutet (=0b00000101), während sbi sie als &amp;quot;setze Bit 5&amp;quot; versteht. Der Befehl &#039;&#039;&#039;sbr&#039;&#039;&#039; erwartet ein Bit&#039;&#039;&#039;muster&#039;&#039;&#039; für eine ODER-Verknüpfung, während der Befehlt &#039;&#039;&#039;sbi&#039;&#039;&#039; die Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; benötigt. Darauf sind auch die Includefiles von Atmel im AVR-Studio (Assembler) als auch [[WinAVR]] (C) ausgelegt. Die Namen der Bits sind als Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; definiert. Das ist wichtig, wenn man Register von grossen AVRs manipuliert, z.&amp;amp;nbsp;B. ATmega48. Hier muss aus der Bitnummer über eine Schiebeoperation erst das Bit&#039;&#039;&#039;muster&#039;&#039;&#039; gemacht werden.&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB |= 0xF0;   // Kurzschreibweise, entspricht PORTB = PORTB | 0xF0; bitweises ODER&lt;br /&gt;
&lt;br /&gt;
/* übersichtlicher mittels Bit-Definitionen */&lt;br /&gt;
#define MEINBIT0 0&lt;br /&gt;
#define MEINBIT1 1&lt;br /&gt;
#define MEINBIT2 2&lt;br /&gt;
&lt;br /&gt;
PORTB |= ((1 &amp;lt;&amp;lt; MEINBIT0) | (1 &amp;lt;&amp;lt; MEINBIT2)); // setzt Bit 0 und 2 in PORTB auf &amp;quot;1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die letzte Zeile &amp;quot;entschlüsselt&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;(1 &amp;lt;&amp;lt; n)&#039;&#039;&#039; : Zuerst wird durch die &#039;&amp;lt;&amp;lt;&#039;-Ausdrücke eine &amp;quot;1&amp;quot; n-mal nach links geschoben.  Dies ergibt somit (in Binärschreibweise) 0b00000001 für (1 &amp;lt;&amp;lt; MEINBIT0) und 0b00000100 für (1 &amp;lt;&amp;lt; MEINBIT2).&lt;br /&gt;
# &#039;&#039;&#039;|&#039;&#039;&#039; : Das Ergebnis wird bitweise ODER-verknüpft, also 0b00000001 &#039;&#039;or&#039;&#039; 0b00000100 wird zu 0b00000101.&lt;br /&gt;
# &#039;&#039;&#039;|=&#039;&#039;&#039; : Diese Maske wird mit dem aktuellen Inhalt von PORTB bitweise ODER-verknüpft und das Ergebnis PORTB wieder zugewiesen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB |= variable;         // Kurzschreibweise&lt;br /&gt;
PORTB  = PORTB | variable; // lange Schreibweise&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Ist PORTB vorher z.&amp;amp;nbsp;B. 0b01111010, dann ist der Inhalt nach der Operation 0b01111010 &#039;&#039;or&#039;&#039; 0b00000101 = 0b01111111, die gewünschten Bits sind somit gesetzt!&lt;br /&gt;
&lt;br /&gt;
Anmerkung: Will man das gezeigte Beispiel der Bitmanipulation auf größere Datentypen anwenden, ist zu beachten, dass der Compiler in der Operation (1 &amp;lt;&amp;lt; MEINBIT1) stillschweigend gemäss, den C-Regeln, die 1 als Integer Typ ansieht. Beim AVR-GCC bedeutet das 16-Bit/signed und die folgende Operation bringt ggf. nicht das gewünschte Ergebnis. (Stichwort: &amp;quot;Integer Promotion&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Angenommen Bit 15 soll in einer 32-Bit weiten Variable gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define MEINBIT15 15&lt;br /&gt;
#define MEINBIT42 42&lt;br /&gt;
&lt;br /&gt;
uint32_t reg_32; /* uint32_t definiert per typedef z.&amp;amp;nbsp;B. in stdint.h */&lt;br /&gt;
uint64_t reg_64; /* uint64_t definiert per typedef z.&amp;amp;nbsp;B. in stdint.h */&lt;br /&gt;
&lt;br /&gt;
reg_32 |= (1 &amp;lt;&amp;lt; MEINBIT15);              /* FEHLER: Setzt die Bits 31 - 15, da ((int)1 &amp;lt;&amp;lt; 15) == 0xFFFF8000 */&lt;br /&gt;
&lt;br /&gt;
reg_32 |= ((uint32_t)1 &amp;lt;&amp;lt; MEINBIT15);    /* Hier wird nur Bit 15 gesetzt. */&lt;br /&gt;
reg_32 |= (1U &amp;lt;&amp;lt; MEINBIT15);             /* */&lt;br /&gt;
reg_32 |= (1L &amp;lt;&amp;lt; MEINBIT15);             /* andere Schreibweise. */&lt;br /&gt;
reg_64 |= (1LL &amp;lt;&amp;lt; MEINBIT42);            /* Hier wird nur Bit 42 gesetzt,&lt;br /&gt;
                                            andere Schreibweise für 64 Bit (long long). */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei Compilern für 32bit Controller (z.&amp;amp;nbsp;B. ARM7TDMI) sind Integers per default 32-bit und Konstanten sind somit implizit ebenfalls 32-bit. Man sollte aber dennoch die oben gezeigte Vorgehenweise verwenden, um Probleme zu vermeiden die entstehen könnten, wenn Code unter verschiedenen Plattformen/Compilern verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
== Bits löschen ==&lt;br /&gt;
&lt;br /&gt;
Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] auf Null gesetzt werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#UND | UND]]-Verknüpfung erreicht. Alle Bits, welche in der Bitmaske &#039;0&#039; sind, werden auf &#039;0&#039; gesetzt. Alle Bits, die in der Maske auf &#039;1&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR-Assembler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
cbr r16, 0b00001111     ; löscht Bits 0-3 in r16, ist ein Pseudobefehl &lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
andi r16, 0b11110000    ; löscht Bits 0-3 in r16, andi ist identisch mit cbr&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
andi r16, ~0b00001111   ; andere Schreibweise, hier wird die Bitmaske durch ~ invertiert&lt;br /&gt;
                        ; dadurch kann man einfach alle zu löschenden Bit als &#039;1&#039; angeben&lt;br /&gt;
                        ; so wie bei den Bitmasken für das setzen von Bits (positive Logik)&lt;br /&gt;
&lt;br /&gt;
cbi PORTB, 5            ; löscht Bit 5 in PortB&lt;br /&gt;
cbi PORTB, PB5          ; identisch, besser lesbar&lt;br /&gt;
                        ; funktioniert nur für die IO-Register 0..31&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register mit I/O Adresse 0x20..0x3F muss&lt;br /&gt;
                        ; in/out verwendet werden weil dieser Bereich nicht&lt;br /&gt;
                        ; bitadressierbar ist&lt;br /&gt;
in  r16, TIMSK          ; löscht Bit TOIE1 in TIMSK&lt;br /&gt;
cbr r16, 1&amp;lt;&amp;lt;TOIE1    &lt;br /&gt;
out TIMSK, r16&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register oberhalb der I/O Adresse 0x3F muss&lt;br /&gt;
                        ; lds/sts verwednet werden&lt;br /&gt;
                        ; löscht Bit RXCIE0 in UCSR0B&lt;br /&gt;
lds r16, UCSR0B &lt;br /&gt;
cbr r16, 1&amp;lt;&amp;lt;RXCIE0&lt;br /&gt;
sts UCSR0B, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier gilt: Man beachte den Unterschied! Eine &amp;quot;5&amp;quot; würde von cbr als &amp;quot;lösche Bit 2 und 0&amp;quot; gedeutet, während cbi sie als &amp;quot;lösche Bit 5&amp;quot; versteht. Der Befehl &#039;&#039;&#039;cbr&#039;&#039;&#039; erwartet ein Bit&#039;&#039;&#039;muster&#039;&#039;&#039; für eine UND-NOT-Verknüpfung (nicht zu verwechseln mit NAND), während der Befehl &#039;&#039;&#039;cbi&#039;&#039;&#039; die Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; benötigt. Darauf sind auch die Includefiles von Atmel im AVR-Studio (Assembler) als auch [[WinAVR]] ausgelegt. Die Namen der Bits sind als Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; definiert. Das ist wichtig, wenn man Register von grossen AVRs manipuliert, z.&amp;amp;nbsp;B. ATmega48. Hier muss aus der Bitnummer über eine Schiebeoperation &amp;lt;&amp;lt; erst das Bit&#039;&#039;&#039;muster&#039;&#039;&#039; gemacht werden.&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB &amp;amp;= 0xF0;   // entspricht PORTB = PORTB &amp;amp; 0xF0; bitweises UND&lt;br /&gt;
                 // Bits 0-3 (das &amp;quot;niederwertige&amp;quot; Nibble) werden geloescht &lt;br /&gt;
&lt;br /&gt;
/* übersichtlicher mittels Bit-Definitionen */ &lt;br /&gt;
#define MEINBIT0 0&lt;br /&gt;
#define MEINBIT1 1  &lt;br /&gt;
#define MEINBIT2 2  &lt;br /&gt;
&lt;br /&gt;
PORTB &amp;amp;= ~((1 &amp;lt;&amp;lt; MEINBIT0) | (1 &amp;lt;&amp;lt; MEINBIT2)); // löscht Bit 0 und 2 in PORTB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die letzte Zeile entschlüsselt:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;(1 &amp;lt;&amp;lt; n)&#039;&#039;&#039; : Zuerst wird durch die &#039;&amp;lt;&amp;lt;&#039;-Ausdrücke eine &amp;quot;1&amp;quot; n-mal nach links geschoben. Dies ergibt somit (in Binärschreibweise) 0b00000001 für (1 &amp;lt;&amp;lt; MEINBIT0) und 0b00000100 für (1 &amp;lt;&amp;lt; MEINBIT2).&lt;br /&gt;
# &#039;&#039;&#039;|&#039;&#039;&#039; : Das Ergebnis wird bitweise ODER-verknüpft also 0b00000001 &#039;&#039;or&#039;&#039; 0b00000100 wird zu 0b00000101.&lt;br /&gt;
# &#039;&#039;&#039;~&#039;&#039;&#039; : Der Wert in der Klammer wird bitweise invertiert, aus 0b00000101 wird 0b11111010.&lt;br /&gt;
# &#039;&#039;&#039;&amp;amp;=&#039;&#039;&#039; : PORTB wird mit der berechneten Maske UND-verknüpft und das Ergebnis wieder PORTB zugewiesen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB &amp;amp;= variable;          // Kurzschreibweise&lt;br /&gt;
PORTB  = PORTB &amp;amp; variable;  // lange Schreibweise&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Ist PORTB vorher z.&amp;amp;nbsp;B. 0b01111111, dann ist der Inhalt nach der Operation 0b01111111 &#039;&#039;and&#039;&#039; 0b11111010 = 0b01111010, die gewünschten Bits 0 und 2 sind somit gelöscht.&lt;br /&gt;
&lt;br /&gt;
Die C-Ausdrücke mittels Definitionen von Bitnummern und Schieboperator (&amp;lt;&amp;lt;) sehen auf den ersten Blick etwas &amp;quot;erschreckend&amp;quot; aus und sind mehr &amp;quot;Tipparbeit&amp;quot;, funktionieren aber universell und sind deutlicher und nachvollziehbarer als &amp;quot;handoptimierte&amp;quot; Konstanten. Bei eingeschalteter Optimierung löst der Compiler die Ausdücke mit konstanten Werten bereits zur Compilierungszeit auf und es entsteht kein zusätzlicher Maschinencode. Bei AVR sind die Definitionen meist Teil der Entwicklungsumgebungen (bei avr-libc z.&amp;amp;nbsp;B. implizit durch #include &amp;lt;avr/io.h&amp;gt;). Sie entsprechen den Angaben und Beispielen in den Datenblättern und sind damit de-facto ein Standard beim Zugriff auf Bits in Hardware-Registern.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Wichtiger Hinweis&#039;&#039;&#039;: Die ODER-Verknüpfung und die anschliessende Invertierung kann man nicht vertauschen! (Theorem von DeMorgan) Folgendes Beispiel soll die Richtigkeit der Aussage zeigen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 ~(0b0001 | 0b0010) == 0b1100&lt;br /&gt;
  ~0b0001 | ~0b0010 == 0b1111&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Noch ein wichtiger Hinweis&#039;&#039;&#039;: Der operator ~ mit einem Operanden vom Typ int negiert nur so viele bits, wie der Typ int hat.&lt;br /&gt;
Will man ein bit in einer breiteren Variablen löschen, dann sollte die nach links zu shiftende 1 den Typ dieser Variablen haben.&lt;br /&gt;
&lt;br /&gt;
Ein Programm, welches das verdeutlicht:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, const char* argv[])&lt;br /&gt;
{&lt;br /&gt;
    int bit = 60;&lt;br /&gt;
    uint64_t ui64;&lt;br /&gt;
    printf(&amp;quot;sizeof(int)=%d\n&amp;quot;, (int)sizeof(int));&lt;br /&gt;
    &lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;    &lt;br /&gt;
    ui64 &amp;amp;= ~(1&amp;lt;&amp;lt;60); /* Keine Wirkung bei sizeof(int) &amp;lt; 8 */&lt;br /&gt;
    /* gcc warnt sogar:    &lt;br /&gt;
     * gcc -Wall bit_clear.c -o bit_clear&lt;br /&gt;
     * bit_clear.c: In function ‘main’:&lt;br /&gt;
     * bit_clear.c:11:5: warning: left shift count &amp;gt;= width of type [enabled by default]&lt;br /&gt;
     */    &lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;    &lt;br /&gt;
    ui64 &amp;amp;= ~((uint64_t)1&amp;lt;&amp;lt;60); /* ok */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;&lt;br /&gt;
    ui64 &amp;amp;= ~(1LL&amp;lt;&amp;lt;60); /* auch ok, und kürzer. */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;&lt;br /&gt;
    ui64 &amp;amp;= ~(1&amp;lt;&amp;lt;bit); /* Ohne Warnung, und funktioniert manchmal, je nach Optimierung */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
/* Ausgabe auf meinem PC ohne Optimierung:&lt;br /&gt;
 * sizeof(int)=4&lt;br /&gt;
 * 0&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * Ausgabe auf meinem PC mit -O2&lt;br /&gt;
 * 0&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * 0&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Niederwertigstes gesetztes Bit löschen (Standard C) ===&lt;br /&gt;
&lt;br /&gt;
Folgender Code löscht von allen 1-Bits in einer Integer-Variable das niederwertigste, unabhängig von der Position desselben.&lt;br /&gt;
&lt;br /&gt;
Beispiel: 01101000 -&amp;gt; 01100000&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t byte;&lt;br /&gt;
&lt;br /&gt;
byte = irgendwas();&lt;br /&gt;
&lt;br /&gt;
byte = byte &amp;amp; (byte - 1); /* Diese seltsame Operation löscht das&lt;br /&gt;
                             niederwertigste 1-Bit */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Byte  :  01101000 &lt;br /&gt;
Byte-1:  01100111&lt;br /&gt;
Ergebnis:01100000&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Das funktioniert also mit jeder beliebigen Zahl.&lt;br /&gt;
&lt;br /&gt;
Dies kann bspw. zur schnellen Paritätsgenerierung eingesetzt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t pareven(uint8_t byte) {&lt;br /&gt;
  uint8_t par = 0;&lt;br /&gt;
&lt;br /&gt;
  while(byte) {&lt;br /&gt;
    byte = byte &amp;amp; (byte - 1);&lt;br /&gt;
    par = ~par;&lt;br /&gt;
  }&lt;br /&gt;
  return par;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das genannte gilt natürlich nicht nur für 8-Bit-Integers, sondern für beliebige, vom Compiler unterstützte Wortlängen.&lt;br /&gt;
&lt;br /&gt;
== Bits invertieren ==&lt;br /&gt;
&lt;br /&gt;
Im allgemeinen Sprachgebrauch oft Toggeln genannt (aus dem Englischen). Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] invertiert (getoggelt) werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#XOR_.28Exlusives_Oder.29 | XOR]]-Verknüpfung erreicht. Alle Bits, welche in der Bitmaske &#039;1&#039; sind, werden invertiert. Alle Bits, die in der Maske auf &#039;0&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR Assembler ===&lt;br /&gt;
&lt;br /&gt;
Bei [[AVR]]s erlaubt dies folgender Assemblercode. Hier wird ein Ausgangspin invertiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
  sbic  PortB, 0    ; Überspringe den nächsten Befehl, wenn das Bit 0 im Port gelöscht ist&lt;br /&gt;
  rjmp  ClrBitNow   ; Springe zu ClrBitNow   &lt;br /&gt;
  sbi   PortB, 0    ; Setze Bit 0 in PortB&lt;br /&gt;
  rjmp  BitReady    ; Springe BitReady&lt;br /&gt;
ClrBitNow:&lt;br /&gt;
   cbi  PortB, 0    ; Lösche Bit 0 in PortB&lt;br /&gt;
BitReady:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Noch kürzer gehts so:&amp;lt;br&amp;gt;&lt;br /&gt;
Die zweite Zeile mit dem Befehl &#039;&#039;&#039;ldi&#039;&#039;&#039; lädt die Bitmaske, in welcher die zu toggelnden Bits auf &#039;1&#039; gesetzt sind. In diesem Beispiel wird das dritte Bit invertiert. Der Vorteil dieser Methode ist neben der Kürze und Übersichtlichkeit auch die Möglichkeit, bis zu 8 Bit gleichzeitig zu toggeln. Diese Methode ist natürlich auch auf normale Daten anwendbar, nicht nur auf IO-Ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
 in     R24, PORTE   ; Daten lesen&lt;br /&gt;
 ldi    R25, 0x04    ; Bitmaske laden, hier Bit #2&lt;br /&gt;
 eor    R24, R25     ; Exklusiv ODER&lt;br /&gt;
 out    PORTE, R24   ; Daten zurückschreiben&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine andere Möglichkeit gibt es, wenn man nur das 8. Bit kippen will:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
 in      r16, PORTB&lt;br /&gt;
 subi    r16, 0x80&lt;br /&gt;
 out     PORTB, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 PORTB ^= (1&amp;lt;&amp;lt;PB0);    /* XOR, Kurzschreibweise, PORTB = PORTB ^ (1&amp;lt;&amp;lt;PB0) */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Neuere ATmegas ===&lt;br /&gt;
&lt;br /&gt;
Bei den neueren ATmegas (z.&amp;amp;nbsp;B. ATmega48) kann man IO-Pins direkt ohne den Umweg über Register togglen, indem man das entsprechende Bit im PINx-Register &#039;&#039;&#039;setzt&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
sbi PIND, 2       ; Bit 2 von Port D togglen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 8051er ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
cpl bitadresse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bits prüfen ==&lt;br /&gt;
&lt;br /&gt;
Will man prüfen ob ein oder mehrere Bits in einer Variable gesetzt oder gelöscht sind, muss man sie mit einer Bitmaske UND verknüpfen. Die Bitmaske muss an den Stellen der zu prüfenden Bits eine &#039;1&#039; haben, an allen anderen eine &#039;0&#039;.&lt;br /&gt;
&lt;br /&gt;
* Ist das Ergebnis gleich Null, sind alle geprüften Bits gelöscht.&lt;br /&gt;
* Ist das Ergebnis ungleich Null, ist mindestens ein geprüftes Bit gesetzt.&lt;br /&gt;
* Ist das Ergebnis gleich der Bitmaske, sind alle geprüften Bits gesetzt.&lt;br /&gt;
&lt;br /&gt;
=== AVR Assembler ===&lt;br /&gt;
&lt;br /&gt;
Der AVR hat spezielle Befehle um direkt einzelne Bits in den CPU-Registern r0..r31 sowie den IO-Registern 0..0x1F zu prüfen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
; Befehle zur Prüfung von einzelnen Bits&lt;br /&gt;
&lt;br /&gt;
    sbrs    r16,3       ; überspringe den nächsten Befehl, wenn in r16 Bit #3 gesetzt ist&lt;br /&gt;
    rjmp    bit_ist_nicht_gesetzt&lt;br /&gt;
&lt;br /&gt;
    sbrc    r16,5       ; überspringe den nächsten Befehl, wenn in r16 Bit #5 gelöscht ist&lt;br /&gt;
    rjmp    bit_ist_nicht_geloescht&lt;br /&gt;
&lt;br /&gt;
    sbis    timsk,3     ; überspringe den nächsten Befehl, wenn in timsk Bit #3 gesetzt ist&lt;br /&gt;
    rjmp    bit_ist_nicht_gesetzt&lt;br /&gt;
&lt;br /&gt;
    sbic    timsk,5     ; überspringe den nächsten Befehl, wenn in timsk Bit #5 gelöscht ist&lt;br /&gt;
    rjmp    bit_ist_nicht_geloescht&lt;br /&gt;
&lt;br /&gt;
; Befehle zur Prüfung von mehreren Bits&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    breq    alle_bits_sind_geloescht&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    brne    mind_ein_bit_ist_gesetzt&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    cpi     r16,0b1010&lt;br /&gt;
    breq    alle_bits_sind_gesetzt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    // prüfe ob Bit 4 in der Variable tmp gelöscht ist&lt;br /&gt;
    // die Klammer ist wichtig &lt;br /&gt;
    if (!(tmp &amp;amp; 0x10)) {        &lt;br /&gt;
       // hier die Anweisungen, wenn das Bit gelöscht ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 und Bit 4 in der Variable tmp gelöscht sind&lt;br /&gt;
    // die Klammer ist wichtig! &lt;br /&gt;
    if ((tmp &amp;amp; 0x11) == 0) {        &lt;br /&gt;
       // hier die Anweisungen, wenn beide Bits gelöscht sind&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 oder Bit 4 in der Variable tmp gesetzt ist&lt;br /&gt;
    if (tmp &amp;amp; 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn mindestens ein Bit gesetzt ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 oder Bit 4 in der Variable tmp gelöscht sind&lt;br /&gt;
    if (~tmp &amp;amp; 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn mindestens ein Bit gelöscht ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 4 in der Variable tmp gesetzt ist &lt;br /&gt;
    if (tmp &amp;amp; 0x10) {        &lt;br /&gt;
       // hier die Anweisungen, wenn das Bit gesetzt ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 und Bit 4 in der Variable tmp gesetzt sind&lt;br /&gt;
    // die Klammer ist wichtig! &lt;br /&gt;
    if ((tmp &amp;amp; 0x11) == 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn beide Bits gesetzt sind&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hilfsfunktionen zur Bitmanipulation in C/C++ ==&lt;br /&gt;
Um &amp;quot;einfacher&amp;quot; elementare Bitmanipulationen durchzuführen bietet es sich an einige Hilfsfunktionen zu definieren. Dabei gibt es zwei verschiedene Möglichkeiten diese zu realiseren:&lt;br /&gt;
* Als C-Makro [[C_Makros]]&lt;br /&gt;
* Als Inline-Funktion&lt;br /&gt;
In beiden Fällen wird bei eingeschalteter Optimierung letztendlich vom Compiler ein sehr kompakter (und identischer!) Code erzeugt, jedoch ist dringend von der Verwendung von Makros abzuraten (siehe [[Makro]] )!&lt;br /&gt;
Im Fehlerfall zeigt der Compiler bei der Verwendung vom Makros keine eindeutigen Fehlermeldungen an, da es sich um simple Ersetzungen handelt - bei der Verwendung von Inline-Funktionen hingegen gibt es eine &amp;quot;brauchbare&amp;quot; Fehlermeldung!&lt;br /&gt;
&lt;br /&gt;
=== Beispiele - Inline Variante ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Achtung: Zugriffe erfolgen über Pointer&lt;br /&gt;
// PORTA, PB2 setzen&lt;br /&gt;
BIT_SET(&amp;amp;PORTA, PB2);&lt;br /&gt;
&lt;br /&gt;
// PORTC, PB0 löschen&lt;br /&gt;
BIT_CLEAR(&amp;amp;PORTC, PB0);&lt;br /&gt;
&lt;br /&gt;
// PORTA, PB2 direkt setzen&lt;br /&gt;
// HIGH&lt;br /&gt;
BIT_BOOL_SET(&amp;amp;PORTA, PB2, 1);&lt;br /&gt;
&lt;br /&gt;
// LOW&lt;br /&gt;
BIT_BOOL_SET(&amp;amp;PORTA, PB2, 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beispiele - MakroVariante ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Achtung: Zugriffe erfolgen direkt über die Variablen/Portnamen&lt;br /&gt;
// PORTA, PB2 setzen&lt;br /&gt;
BIT_SET(PORTA, PB2);&lt;br /&gt;
&lt;br /&gt;
// PORTC, PB0 löschen&lt;br /&gt;
BIT_CLEAR(PORTC, PB0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um die Hilfsfunktionen verwenden zu können einfach folgenden Code in eine neue Header-Datei (z.B. BitIO.h) kopieren:&lt;br /&gt;
&lt;br /&gt;
=== Hilfsfunktionen als Inline-Methoden ===&lt;br /&gt;
Achtung: Wenn nur ein C Compiler verwendet wird, kennt dieser den Typ &amp;quot;bool&amp;quot; nicht, dieser muss dann vorher definiert werden!&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *  BitIO.h&lt;br /&gt;
 *	@author 	Andi Dittrich &amp;lt;http://andidittrich.de&amp;gt;&lt;br /&gt;
 *	@version	1.0&lt;br /&gt;
 *	@license	MIT Style X11 License&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;inttypes.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef BITIO_H_&lt;br /&gt;
#define BITIO_H_&lt;br /&gt;
&lt;br /&gt;
// set bit&lt;br /&gt;
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target |= (1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// set clear&lt;br /&gt;
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target &amp;amp;= ~(1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// bit toogle&lt;br /&gt;
static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target ^= (1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// set bit by boolean&lt;br /&gt;
static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable){&lt;br /&gt;
	if (enable){&lt;br /&gt;
		BIT_SET(target, bit);&lt;br /&gt;
	}else{&lt;br /&gt;
		BIT_CLEAR(target, bit);&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif /* BITIO_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hilfsfunktionen als C-Makro (nicht empfohlen) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* Bit setzen */&lt;br /&gt;
#define set_bit(var, bit) ((var) |= (1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
 &lt;br /&gt;
/* Bit löschen */&lt;br /&gt;
#define clear_bit(var, bit) ((var) &amp;amp;= (unsigned)~(1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
 &lt;br /&gt;
/* Bit togglen */&lt;br /&gt;
#define toggle_bit(var,bit) ((var) ^= (1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bitmanipulation beim MSP430 ==&lt;br /&gt;
&lt;br /&gt;
Beim MSP430 und dessen Compilern sind die Bitnamen meist anders definiert. Und zwar nicht als Bitnummer, sondern als Bitmuster. Darum schreibt man dort die Bitzugriffe in C anders. Das kann auch bei anderen Mikrocontrollern bzw. C-Compilern so sein. Wichtig ist, dass man seine eignen Definitionen in der gleichen Weise wie der Compiler anlegt, um Verwirrung zu vermeiden, siehe [[Strukturierte Programmierung auf Mikrocontrollern]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Definition von Bitnamen in den Headerfiles des Compilers&lt;br /&gt;
&lt;br /&gt;
#define PD4 4               // Definition im AVR GCC als Bitnummer&lt;br /&gt;
#define PD5 5&lt;br /&gt;
&lt;br /&gt;
#define P14 (1&amp;lt;&amp;lt;4)          // Definition im MSP430 GCC als Bitmuster&lt;br /&gt;
#define P15 (1&amp;lt;&amp;lt;5)&lt;br /&gt;
&lt;br /&gt;
// Bitmanipulation im Programm&lt;br /&gt;
 &lt;br /&gt;
   DDRD = (1&amp;lt;&amp;lt;PD5) | (1&amp;lt;&amp;lt;PD4);   // AVR GCC&lt;br /&gt;
   P1DIR = P15 | P14;            // MSP430 GCC&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/179566#1729219 Forumsbeitrag:] Bits aus einem Array extrahieren&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/169509#1631439 Forumsbeitrag:] Bits für ein Schieberegister zusammenstellen, TLC5941&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/353071?goto=3947567#3947567 Forumsbeitrag:] TLC5947 und ATmega16 Bitmanipulation&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/15466?goto=107726#107720 Forumsbeitrag:] Bitreihenfolge ändern&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/23866?goto=new#177674 Forumsbeitrag:] Wie drehe ich eine Bitreihenfolge um?&lt;br /&gt;
* [http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/AVR-Built_002din-Functions.html AVR Build-in Functions], spezielle Funktion im avr-gcc zur schnellen Bitvertauschung, engl.&lt;br /&gt;
&lt;br /&gt;
[[Category:8051]]&lt;br /&gt;
[[Category:AVR-Arithmetik]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Bitmanipulation&amp;diff=89411</id>
		<title>Bitmanipulation</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Bitmanipulation&amp;diff=89411"/>
		<updated>2015-07-27T19:40:04Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* Neuere ATmegas */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Bitoperatoren ==&lt;br /&gt;
&lt;br /&gt;
Bitoperatoren stammen ursprünglich aus dem Bereich des Maschinen-Codes und Assembler, existieren aber auch in den meisten Hochsprachen, wie C.&lt;br /&gt;
&lt;br /&gt;
* &amp;gt;&amp;gt; = Rechts schieben&lt;br /&gt;
* &amp;lt;&amp;lt; = Links schieben (Bsp: &#039;&#039;a&amp;lt;&amp;lt;b&#039;&#039; ist das gleiche wie &#039;&#039;a * 2^b&#039;&#039;; bzw. bei 1&amp;lt;&amp;lt;3 wird die 1 um drei Stellen nach links geschoben)&lt;br /&gt;
* |  = binäres ODER&lt;br /&gt;
* &amp;amp;  = binäres UND&lt;br /&gt;
* ^  = binäres Exklusives ODER&lt;br /&gt;
* usw.&lt;br /&gt;
&lt;br /&gt;
Bitoperatoren in dieser Schreibweise können in Assemblercode für&lt;br /&gt;
konstante Ausdrücke benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, (1&amp;lt;&amp;lt;3) | (1&amp;lt;&amp;lt;1) | (1&amp;lt;&amp;lt;2) | (1&amp;lt;&amp;lt;0)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
wird zu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, 8 | 2 | 4 | 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
wird zu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, 15&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bitmaske ==&lt;br /&gt;
&lt;br /&gt;
Im Folgenden ist häufiger von dem Begriff &#039;&#039;Bitmaske&#039;&#039; die Rede. Damit wird eine Folge von einzelnen Bit bezeichnet, die den Zustand Null (&#039;0&#039;) oder Eins (&#039;1&#039;) darstellen können.&lt;br /&gt;
&lt;br /&gt;
Bitmasken werden im allgemeinen dazu verwendet, um unter Anwendung eines Operators (z.&amp;amp;nbsp;B. UND, ODER, XOR), eine Eingabe zu manipulieren. Das Ergebnis ist dann die Anwendung des Operators auf die Eingabe und der Bitmaske.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Operator eine Funktion mit zwei Argumenten ist, dann lässt sich dessen Anwendung wie folgt schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Ergebnis = Operator( Eingabe, Bitmaske )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Bitmaske ist häufig eine Konstante, da diese z.&amp;amp;nbsp;B. die Information über die Position einer Information in einem Register darstellt. Das kann z.&amp;amp;nbsp;B. ein Überlaufflag in einem Timer Statusregister sein.&lt;br /&gt;
&lt;br /&gt;
== Bits setzen ==&lt;br /&gt;
&lt;br /&gt;
Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] auf Eins gesetzt werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#ODER | ODER]]-Verknüpfung erreicht.  Alle Bits, welche in der Bitmaske &#039;1&#039; sind, werden auf &#039;1&#039; gesetzt. Alle Bits, die in der Maske auf &#039;0&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR-Assembler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
sbr r16, 0b11110000     ; setzt Bits 4-7 in r16, ist ein Pseudobefehl&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
ori r16, 0b11110000     ; setzt Bits 4-7 in r16, ori ist identisch mit sbr&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
sbi PORTB, 5            ; setzt Bit 5 in PortB&lt;br /&gt;
sbi PORTB, PB5          ; identisch, besser lesbar&lt;br /&gt;
                        ; funktioniert nur für die IO-Register 0..0x1F&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register mit I/O Adresse 0x20..0x3F muss&lt;br /&gt;
                        ; in/out verwendet werden&lt;br /&gt;
in  r16, TIMSK          ; setzt Bit TOIE1 in TIMSK&lt;br /&gt;
sbr r16, (1&amp;lt;&amp;lt;TOIE1)    &lt;br /&gt;
out TIMSK, r16&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register oberhalb der I/O Adresse 0x3F muss&lt;br /&gt;
                        ; lds/sts verwednet werden&lt;br /&gt;
                        ; setzt Bit RXCIE0 in UCSR0B&lt;br /&gt;
lds r16, UCSR0B &lt;br /&gt;
sbr r16, (1&amp;lt;&amp;lt;RXCIE0)    &lt;br /&gt;
sts UCSR0B, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Man beachte den Unterschied! Eine &amp;quot;5&amp;quot; würde von sbr als &amp;quot;setze Bit 2 und 0&amp;quot; gedeutet (=0b00000101), während sbi sie als &amp;quot;setze Bit 5&amp;quot; versteht. Der Befehl &#039;&#039;&#039;sbr&#039;&#039;&#039; erwartet ein Bit&#039;&#039;&#039;muster&#039;&#039;&#039; für eine ODER-Verknüpfung, während der Befehlt &#039;&#039;&#039;sbi&#039;&#039;&#039; die Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; benötigt. Darauf sind auch die Includefiles von Atmel im AVR-Studio (Assembler) als auch [[WinAVR]] (C) ausgelegt. Die Namen der Bits sind als Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; definiert. Das ist wichtig, wenn man Register von grossen AVRs manipuliert, z.&amp;amp;nbsp;B. ATmega48. Hier muss aus der Bitnummer über eine Schiebeoperation erst das Bit&#039;&#039;&#039;muster&#039;&#039;&#039; gemacht werden.&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB |= 0xF0;   // Kurzschreibweise, entspricht PORTB = PORTB | 0xF0; bitweises ODER&lt;br /&gt;
&lt;br /&gt;
/* übersichtlicher mittels Bit-Definitionen */&lt;br /&gt;
#define MEINBIT0 0&lt;br /&gt;
#define MEINBIT1 1&lt;br /&gt;
#define MEINBIT2 2&lt;br /&gt;
&lt;br /&gt;
PORTB |= ((1 &amp;lt;&amp;lt; MEINBIT0) | (1 &amp;lt;&amp;lt; MEINBIT2)); // setzt Bit 0 und 2 in PORTB auf &amp;quot;1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die letzte Zeile &amp;quot;entschlüsselt&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;(1 &amp;lt;&amp;lt; n)&#039;&#039;&#039; : Zuerst wird durch die &#039;&amp;lt;&amp;lt;&#039;-Ausdrücke eine &amp;quot;1&amp;quot; n-mal nach links geschoben.  Dies ergibt somit (in Binärschreibweise) 0b00000001 für (1 &amp;lt;&amp;lt; MEINBIT0) und 0b00000100 für (1 &amp;lt;&amp;lt; MEINBIT2).&lt;br /&gt;
# &#039;&#039;&#039;|&#039;&#039;&#039; : Das Ergebnis wird bitweise ODER-verknüpft, also 0b00000001 &#039;&#039;or&#039;&#039; 0b00000100 wird zu 0b00000101.&lt;br /&gt;
# &#039;&#039;&#039;|=&#039;&#039;&#039; : Diese Maske wird mit dem aktuellen Inhalt von PORTB bitweise ODER-verknüpft und das Ergebnis PORTB wieder zugewiesen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB |= variable;         // Kurzschreibweise&lt;br /&gt;
PORTB  = PORTB | variable; // lange Schreibweise&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Ist PORTB vorher z.&amp;amp;nbsp;B. 0b01111010, dann ist der Inhalt nach der Operation 0b01111010 &#039;&#039;or&#039;&#039; 0b00000101 = 0b01111111, die gewünschten Bits sind somit gesetzt!&lt;br /&gt;
&lt;br /&gt;
Anmerkung: Will man das gezeigte Beispiel der Bitmanipulation auf größere Datentypen anwenden, ist zu beachten, dass der Compiler in der Operation (1 &amp;lt;&amp;lt; MEINBIT1) stillschweigend gemäss, den C-Regeln, die 1 als Integer Typ ansieht. Beim AVR-GCC bedeutet das 16-Bit/signed und die folgende Operation bringt ggf. nicht das gewünschte Ergebnis. (Stichwort: &amp;quot;Integer Promotion&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Angenommen Bit 15 soll in einer 32-Bit weiten Variable gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define MEINBIT15 15&lt;br /&gt;
#define MEINBIT42 42&lt;br /&gt;
&lt;br /&gt;
uint32_t reg_32; /* uint32_t definiert per typedef z.&amp;amp;nbsp;B. in stdint.h */&lt;br /&gt;
uint64_t reg_64; /* uint64_t definiert per typedef z.&amp;amp;nbsp;B. in stdint.h */&lt;br /&gt;
&lt;br /&gt;
reg_32 |= (1 &amp;lt;&amp;lt; MEINBIT15);              /* FEHLER: Setzt die Bits 31 - 15, da ((int)1 &amp;lt;&amp;lt; 15) == 0xFFFF8000 */&lt;br /&gt;
&lt;br /&gt;
reg_32 |= ((uint32_t)1 &amp;lt;&amp;lt; MEINBIT15);    /* Hier wird nur Bit 15 gesetzt. */&lt;br /&gt;
reg_32 |= (1U &amp;lt;&amp;lt; MEINBIT15);             /* */&lt;br /&gt;
reg_32 |= (1L &amp;lt;&amp;lt; MEINBIT15);             /* andere Schreibweise. */&lt;br /&gt;
reg_64 |= (1LL &amp;lt;&amp;lt; MEINBIT42);            /* Hier wird nur Bit 42 gesetzt,&lt;br /&gt;
                                            andere Schreibweise für 64 Bit (long long). */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei Compilern für 32bit Controller (z.&amp;amp;nbsp;B. ARM7TDMI) sind Integers per default 32-bit und Konstanten sind somit implizit ebenfalls 32-bit. Man sollte aber dennoch die oben gezeigte Vorgehenweise verwenden, um Probleme zu vermeiden die entstehen könnten, wenn Code unter verschiedenen Plattformen/Compilern verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
== Bits löschen ==&lt;br /&gt;
&lt;br /&gt;
Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] auf Null gesetzt werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#UND | UND]]-Verknüpfung erreicht. Alle Bits, welche in der Bitmaske &#039;0&#039; sind, werden auf &#039;0&#039; gesetzt. Alle Bits, die in der Maske auf &#039;1&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR-Assembler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
cbr r16, 0b00001111     ; löscht Bits 0-3 in r16, ist ein Pseudobefehl &lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
andi r16, 0b11110000    ; löscht Bits 0-3 in r16, andi ist identisch mit cbr&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
andi r16, ~0b00001111   ; andere Schreibweise, hier wird die Bitmaske durch ~ invertiert&lt;br /&gt;
                        ; dadurch kann man einfach alle zu löschenden Bit als &#039;1&#039; angeben&lt;br /&gt;
                        ; so wie bei den Bitmasken für das setzen von Bits (positive Logik)&lt;br /&gt;
&lt;br /&gt;
cbi PORTB, 5            ; löscht Bit 5 in PortB&lt;br /&gt;
cbi PORTB, PB5          ; identisch, besser lesbar&lt;br /&gt;
                        ; funktioniert nur für die IO-Register 0..31&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register mit I/O Adresse 0x20..0x3F muss&lt;br /&gt;
                        ; in/out verwendet werden weil dieser Bereich nicht&lt;br /&gt;
                        ; bitadressierbar ist&lt;br /&gt;
in  r16, TIMSK          ; löscht Bit TOIE1 in TIMSK&lt;br /&gt;
cbr r16, 1&amp;lt;&amp;lt;TOIE1    &lt;br /&gt;
out TIMSK, r16&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register oberhalb der I/O Adresse 0x3F muss&lt;br /&gt;
                        ; lds/sts verwednet werden&lt;br /&gt;
                        ; löscht Bit RXCIE0 in UCSR0B&lt;br /&gt;
lds r16, UCSR0B &lt;br /&gt;
cbr r16, 1&amp;lt;&amp;lt;RXCIE0&lt;br /&gt;
sts UCSR0B, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier gilt: Man beachte den Unterschied! Eine &amp;quot;5&amp;quot; würde von cbr als &amp;quot;lösche Bit 2 und 0&amp;quot; gedeutet, während cbi sie als &amp;quot;lösche Bit 5&amp;quot; versteht. Der Befehl &#039;&#039;&#039;cbr&#039;&#039;&#039; erwartet ein Bit&#039;&#039;&#039;muster&#039;&#039;&#039; für eine UND-NOT-Verknüpfung (nicht zu verwechseln mit NAND), während der Befehl &#039;&#039;&#039;cbi&#039;&#039;&#039; die Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; benötigt. Darauf sind auch die Includefiles von Atmel im AVR-Studio (Assembler) als auch [[WinAVR]] ausgelegt. Die Namen der Bits sind als Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; definiert. Das ist wichtig, wenn man Register von grossen AVRs manipuliert, z.&amp;amp;nbsp;B. ATmega48. Hier muss aus der Bitnummer über eine Schiebeoperation &amp;lt;&amp;lt; erst das Bit&#039;&#039;&#039;muster&#039;&#039;&#039; gemacht werden.&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB &amp;amp;= 0xF0;   // entspricht PORTB = PORTB &amp;amp; 0xF0; bitweises UND&lt;br /&gt;
                 // Bits 0-3 (das &amp;quot;niederwertige&amp;quot; Nibble) werden geloescht &lt;br /&gt;
&lt;br /&gt;
/* übersichtlicher mittels Bit-Definitionen */ &lt;br /&gt;
#define MEINBIT0 0&lt;br /&gt;
#define MEINBIT1 1  &lt;br /&gt;
#define MEINBIT2 2  &lt;br /&gt;
&lt;br /&gt;
PORTB &amp;amp;= ~((1 &amp;lt;&amp;lt; MEINBIT0) | (1 &amp;lt;&amp;lt; MEINBIT2)); // löscht Bit 0 und 2 in PORTB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die letzte Zeile entschlüsselt:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;(1 &amp;lt;&amp;lt; n)&#039;&#039;&#039; : Zuerst wird durch die &#039;&amp;lt;&amp;lt;&#039;-Ausdrücke eine &amp;quot;1&amp;quot; n-mal nach links geschoben. Dies ergibt somit (in Binärschreibweise) 0b00000001 für (1 &amp;lt;&amp;lt; MEINBIT0) und 0b00000100 für (1 &amp;lt;&amp;lt; MEINBIT2).&lt;br /&gt;
# &#039;&#039;&#039;|&#039;&#039;&#039; : Das Ergebnis wird bitweise ODER-verknüpft also 0b00000001 &#039;&#039;or&#039;&#039; 0b00000100 wird zu 0b00000101.&lt;br /&gt;
# &#039;&#039;&#039;~&#039;&#039;&#039; : Der Wert in der Klammer wird bitweise invertiert, aus 0b00000101 wird 0b11111010.&lt;br /&gt;
# &#039;&#039;&#039;&amp;amp;=&#039;&#039;&#039; : PORTB wird mit der berechneten Maske UND-verknüpft und das Ergebnis wieder PORTB zugewiesen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB &amp;amp;= variable;          // Kurzschreibweise&lt;br /&gt;
PORTB  = PORTB &amp;amp; variable;  // lange Schreibweise&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Ist PORTB vorher z.&amp;amp;nbsp;B. 0b01111111, dann ist der Inhalt nach der Operation 0b01111111 &#039;&#039;and&#039;&#039; 0b11111010 = 0b01111010, die gewünschten Bits 0 und 2 sind somit gelöscht.&lt;br /&gt;
&lt;br /&gt;
Die C-Ausdrücke mittels Definitionen von Bitnummern und Schieboperator (&amp;lt;&amp;lt;) sehen auf den ersten Blick etwas &amp;quot;erschreckend&amp;quot; aus und sind mehr &amp;quot;Tipparbeit&amp;quot;, funktionieren aber universell und sind deutlicher und nachvollziehbarer als &amp;quot;handoptimierte&amp;quot; Konstanten. Bei eingeschalteter Optimierung löst der Compiler die Ausdücke mit konstanten Werten bereits zur Compilierungszeit auf und es entsteht kein zusätzlicher Maschinencode. Bei AVR sind die Definitionen meist Teil der Entwicklungsumgebungen (bei avr-libc z.&amp;amp;nbsp;B. implizit durch #include &amp;lt;avr/io.h&amp;gt;). Sie entsprechen den Angaben und Beispielen in den Datenblättern und sind damit de-facto ein Standard beim Zugriff auf Bits in Hardware-Registern.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Wichtiger Hinweis&#039;&#039;&#039;: Die ODER-Verknüpfung und die anschliessende Invertierung kann man nicht vertauschen! (Theorem von DeMorgan) Folgendes Beispiel soll die Richtigkeit der Aussage zeigen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 ~(0b0001 | 0b0010) == 0b1100&lt;br /&gt;
  ~0b0001 | ~0b0010 == 0b1111&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Noch ein wichtiger Hinweis&#039;&#039;&#039;: Der operator ~ mit einem Operanden vom Typ int negiert nur so viele bits, wie der Typ int hat.&lt;br /&gt;
Will man ein bit in einer breiteren Variablen löschen, dann sollte die nach links zu shiftende 1 den Typ dieser Variablen haben.&lt;br /&gt;
&lt;br /&gt;
Ein Programm, welches das verdeutlicht:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, const char* argv[])&lt;br /&gt;
{&lt;br /&gt;
    int bit = 60;&lt;br /&gt;
    uint64_t ui64;&lt;br /&gt;
    printf(&amp;quot;sizeof(int)=%d\n&amp;quot;, (int)sizeof(int));&lt;br /&gt;
    &lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;    &lt;br /&gt;
    ui64 &amp;amp;= ~(1&amp;lt;&amp;lt;60); /* Keine Wirkung bei sizeof(int) &amp;lt; 8 */&lt;br /&gt;
    /* gcc warnt sogar:    &lt;br /&gt;
     * gcc -Wall bit_clear.c -o bit_clear&lt;br /&gt;
     * bit_clear.c: In function ‘main’:&lt;br /&gt;
     * bit_clear.c:11:5: warning: left shift count &amp;gt;= width of type [enabled by default]&lt;br /&gt;
     */    &lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;    &lt;br /&gt;
    ui64 &amp;amp;= ~((uint64_t)1&amp;lt;&amp;lt;60); /* ok */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;&lt;br /&gt;
    ui64 &amp;amp;= ~(1LL&amp;lt;&amp;lt;60); /* auch ok, und kürzer. */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;&lt;br /&gt;
    ui64 &amp;amp;= ~(1&amp;lt;&amp;lt;bit); /* Ohne Warnung, und funktioniert manchmal, je nach Optimierung */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
/* Ausgabe auf meinem PC ohne Optimierung:&lt;br /&gt;
 * sizeof(int)=4&lt;br /&gt;
 * 0&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * Ausgabe auf meinem PC mit -O2&lt;br /&gt;
 * 0&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * 0&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Niederwertigstes gesetztes Bit löschen (Standard C) ===&lt;br /&gt;
&lt;br /&gt;
Folgender Code löscht von allen 1-Bits in einer Integer-Variable das niederwertigste, unabhängig von der Position desselben.&lt;br /&gt;
&lt;br /&gt;
Beispiel: 01101000 -&amp;gt; 01100000&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t byte;&lt;br /&gt;
&lt;br /&gt;
byte = irgendwas();&lt;br /&gt;
&lt;br /&gt;
byte = byte &amp;amp; (byte - 1); /* Diese seltsame Operation löscht das&lt;br /&gt;
                             niederwertigste 1-Bit */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Byte  :  01101000 &lt;br /&gt;
Byte-1:  01100111&lt;br /&gt;
Ergebnis:01100000&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Das funktioniert also mit jeder beliebigen Zahl.&lt;br /&gt;
&lt;br /&gt;
Dies kann bspw. zur schnellen Paritätsgenerierung eingesetzt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t pareven(uint8_t byte) {&lt;br /&gt;
  uint8_t par = 0;&lt;br /&gt;
&lt;br /&gt;
  while(byte) {&lt;br /&gt;
    byte = byte &amp;amp; (byte - 1);&lt;br /&gt;
    par = ~par;&lt;br /&gt;
  }&lt;br /&gt;
  return par;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das genannte gilt natürlich nicht nur für 8-Bit-Integers, sondern für beliebige, vom Compiler unterstützte Wortlängen.&lt;br /&gt;
&lt;br /&gt;
== Bits invertieren ==&lt;br /&gt;
&lt;br /&gt;
Im allgemeinen Sprachgebrauch oft Toggeln genannt (aus dem Englischen). Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] invertiert (getoggelt) werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#XOR_.28Exlusives_Oder.29 | XOR]]-Verknüpfung erreicht. Alle Bits, welche in der Bitmaske &#039;1&#039; sind, werden invertiert. Alle Bits, die in der Maske auf &#039;0&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR Assembler ===&lt;br /&gt;
&lt;br /&gt;
Bei [[AVR]]s erlaubt dies folgender Assemblercode. Hier wird ein Ausgangspin invertiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
  sbic  PortB, 0    ; Überspringe den nächsten Befehl, wenn das Bit 0 im Port gelöscht ist&lt;br /&gt;
  rjmp  ClrBitNow   ; Springe zu ClrBitNow   &lt;br /&gt;
  sbi   PortB, 0    ; Setze Bit 0 in PortB&lt;br /&gt;
  rjmp  BitReady    ; Springe BitReady&lt;br /&gt;
ClrBitNow:&lt;br /&gt;
   cbi  PortB, 0    ; Lösche Bit 0 in PortB&lt;br /&gt;
BitReady:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Noch kürzer gehts so:&amp;lt;br&amp;gt;&lt;br /&gt;
Die zweite Zeile mit dem Befehl &#039;&#039;&#039;ldi&#039;&#039;&#039; lädt die Bitmaske, in welcher die zu toggelnden Bits auf &#039;1&#039; gesetzt sind. In diesem Beispiel wird das dritte Bit invertiert. Der Vorteil dieser Methode ist neben der Kürze und Übersichtlichkeit auch die Möglichkeit, bis zu 8 Bit gleichzeitig zu toggeln. Diese Methode ist natürlich auch auf normale Daten anwendbar, nicht nur auf IO-Ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
 in     R24, PORTE   ; Daten lesen&lt;br /&gt;
 ldi    R25, 0x04    ; Bitmaske laden, hier Bit #2&lt;br /&gt;
 eor    R24, R25     ; Exklusiv ODER&lt;br /&gt;
 out    PORTE, R24   ; Daten zurückschreiben&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine andere Möglichkeit gibt es, wenn man nur das 8. Bit kippen will:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
 in      r16, PORTB&lt;br /&gt;
 subi    r16, 0x80&lt;br /&gt;
 out     PORTB, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 PORTB ^= (1&amp;lt;&amp;lt;PB0);    /* XOR, Kurzschreibweise, PORTB = PORTB ^ (1&amp;lt;&amp;lt;PB0) */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Neuere ATmegas ===&lt;br /&gt;
&lt;br /&gt;
Bei den neueren ATmegas (z.&amp;amp;nbsp;B. ATmega48) kann man IO-Pins direkt ohne den Umweg über Register togglen, indem man das entsprechende Bit im PINx-Register &#039;&#039;&#039;setzt&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
sbi PIND, 2       ; Bit 2 von Port D togglen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 8051er ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
cpl bitadresse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bits prüfen ==&lt;br /&gt;
&lt;br /&gt;
Will man prüfen ob ein oder mehrere Bits in einer Variable gesetzt oder gelöscht sind, muss man sie mit einer Bitmaske UND verknüpfen. Die Bitmaske muss an den Stellen der zu prüfenden Bits eine &#039;1&#039; haben, an allen anderen eine &#039;0&#039;.&lt;br /&gt;
&lt;br /&gt;
* Ist das Ergebnis gleich Null, sind alle geprüften Bits gelöscht.&lt;br /&gt;
* Ist das Ergebnis ungleich Null, ist mindestens ein geprüftes Bit gesetzt.&lt;br /&gt;
* Ist das Ergebnis gleich der Bitmaske, sind alle geprüften Bits gesetzt.&lt;br /&gt;
&lt;br /&gt;
=== AVR Assembler ===&lt;br /&gt;
&lt;br /&gt;
Der AVR hat spezielle Befehle um direkt einzelne Bits in den CPU-Registern r0..r31 sowie den IO-Registern 0..0x1F zu prüfen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
; Befehle zur Prüfung von einzelnen Bits&lt;br /&gt;
&lt;br /&gt;
    sbrs    r16,3       ; überspringe den nächsten Befehl, wenn in r16 Bit #3 gesetzt ist&lt;br /&gt;
    rjmp    bit_ist_nicht_gesetzt&lt;br /&gt;
&lt;br /&gt;
    sbrc    r16,5       ; überspringe den nächsten Befehl, wenn in r16 Bit #5 gelöscht ist&lt;br /&gt;
    rjmp    bit_ist_nicht_geloescht&lt;br /&gt;
&lt;br /&gt;
    sbis    timsk,3     ; überspringe den nächsten Befehl, wenn in timsk Bit #3 gesetzt ist&lt;br /&gt;
    rjmp    bit_ist_nicht_gesetzt&lt;br /&gt;
&lt;br /&gt;
    sbic    timsk,5     ; überspringe den nächsten Befehl, wenn in timsk Bit #5 gelöscht ist&lt;br /&gt;
    rjmp    bit_ist_nicht_geloescht&lt;br /&gt;
&lt;br /&gt;
; Befehle zur Prüfung von mehreren Bits&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    breq    alle_bits_sind_geloescht&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    brne    mind_ein_bit_ist_gesetzt&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    cpi     r16,0b1010&lt;br /&gt;
    breq    alle_bits_sind_gesetzt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    // prüfe ob Bit 4 in der Variable tmp gelöscht ist&lt;br /&gt;
    // die Klammer ist wichtig &lt;br /&gt;
    if (!(tmp &amp;amp; 0x10)) {        &lt;br /&gt;
       // hier die Anweisungen, wenn das Bit gelöscht ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 und Bit 4 in der Variable tmp gelöscht sind&lt;br /&gt;
    // die Klammer ist wichtig! &lt;br /&gt;
    if ((tmp &amp;amp; 0x11) == 0) {        &lt;br /&gt;
       // hier die Anweisungen, wenn beide Bits gelöscht sind&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 oder Bit 4 in der Variable tmp gesetzt ist&lt;br /&gt;
    if (tmp &amp;amp; 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn mindestens ein Bit gesetzt ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 oder Bit 4 in der Variable tmp gelöscht sind&lt;br /&gt;
    if (~tmp &amp;amp; 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn mindestens ein Bit gelöscht ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 4 in der Variable tmp gesetzt ist &lt;br /&gt;
    if (tmp &amp;amp; 0x10) {        &lt;br /&gt;
       // hier die Anweisungen, wenn das Bit gesetzt ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 und Bit 4 in der Variable tmp gesetzt sind&lt;br /&gt;
    // die Klammer ist wichtig! &lt;br /&gt;
    if ((tmp &amp;amp; 0x11) == 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn beide Bits gesetzt sind&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hilfsfunktionen zur Bitmanipulation in C/C++ ==&lt;br /&gt;
Um &amp;quot;einfacher&amp;quot; elementare Bitmanipulationen durchzuführen bietet es sich an einige Hilfsfunktionen zu definieren. Dabei gibt es zwei verschiedene Möglichkeiten diese zu realiseren:&lt;br /&gt;
* Als C-Makro [[C_Makros]]&lt;br /&gt;
* Als Inline-Funktion&lt;br /&gt;
In beiden Fällen wird bei eingeschalteter Optimierung letztendlich vom Compiler ein sehr kompakter (und identischer!) Code erzeugt, jedoch ist dringend von der Verwendung von Makros abzuraten (siehe [[Makro]] )!&lt;br /&gt;
Im Fehlerfall zeigt der Compiler bei der Verwendung vom Makros keine eindeutigen Fehlermeldungen an, da es sich um simple Ersetzungen handelt - bei der Verwendung von Inline-Funktionen hingegen gibt es eine &amp;quot;brauchbare&amp;quot; Fehlermeldung!&lt;br /&gt;
&lt;br /&gt;
=== Beispiele - Inline Variante ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Achtung: Zugriffe erfolgen über Pointer&lt;br /&gt;
// PORTA, PB2 setzen&lt;br /&gt;
BIT_SET(&amp;amp;PORTA, PB2);&lt;br /&gt;
&lt;br /&gt;
// PORTC, PB0 löschen&lt;br /&gt;
BIT_CLEAR(&amp;amp;PORTC, PB0);&lt;br /&gt;
&lt;br /&gt;
// PORTA, PB2 direkt setzen&lt;br /&gt;
// HIGH&lt;br /&gt;
BIT_BOOL_SET(&amp;amp;PORTA, PB2, 1);&lt;br /&gt;
&lt;br /&gt;
// LOW&lt;br /&gt;
BIT_BOOL_SET(&amp;amp;PORTA, PB2, 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beispiele - MakroVariante ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Achtung: Zugriffe erfolgen direkt über die Variablen/Portnamen&lt;br /&gt;
// PORTA, PB2 setzen&lt;br /&gt;
BIT_SET(PORTA, PB2);&lt;br /&gt;
&lt;br /&gt;
// PORTC, PB0 löschen&lt;br /&gt;
BIT_CLEAR(PORTC, PB0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um die Hilfsfunktionen verwenden zu können einfach folgenden Code in eine neue Header-Datei (z.B. BitIO.h) kopieren:&lt;br /&gt;
&lt;br /&gt;
=== Hilfsfunktionen als Inline-Methoden ===&lt;br /&gt;
Achtung: Wenn nur ein C Compiler verwendet wird, kennt dieser den Typ &amp;quot;bool&amp;quot; nicht, dieser muss dann vorher definiert werden!&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *  BitIO.h&lt;br /&gt;
 *	@author 	Andi Dittrich &amp;lt;http://andidittrich.de&amp;gt;&lt;br /&gt;
 *	@version	1.0&lt;br /&gt;
 *	@license	MIT Style X11 License&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;inttypes.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef BITIO_H_&lt;br /&gt;
#define BITIO_H_&lt;br /&gt;
&lt;br /&gt;
// set bit&lt;br /&gt;
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target |= (1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// set clear&lt;br /&gt;
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target &amp;amp;= ~(1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// bit toogle&lt;br /&gt;
static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target ^= (1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// set bit by boolean&lt;br /&gt;
static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable){&lt;br /&gt;
	if (enable){&lt;br /&gt;
		BIT_SET(target, bit);&lt;br /&gt;
	}else{&lt;br /&gt;
		BIT_CLEAR(target, bit);&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif /* BITIO_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hilfsfunktionen als C-Makro (nicht empfohlen) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* Bit setzen */&lt;br /&gt;
#define set_bit(var, bit) ((var) |= (1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
 &lt;br /&gt;
/* Bit löschen */&lt;br /&gt;
#define clear_bit(var, bit) ((var) &amp;amp;= (unsigned)~(1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
 &lt;br /&gt;
/* Bit togglen */&lt;br /&gt;
#define toggle_bit(var,bit) ((var) ^= (1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bitmanipulation beim MSP430 ==&lt;br /&gt;
&lt;br /&gt;
Beim MSP430 und dessen Compilern sind die Bitnamen meist anders definiert. Und zwar nicht als Bitnummer, sondern als Bitmuster. Darum schreibt man dort die Bitzugriffe in C anders. Das kann auch bei anderen Mikrocontrollern bzw. C-Compilern so sein. Wichtig ist, dass man seine eignen Definitionen in der gleichen Weise wie der Compiler anlegt, um Verwirrung zu vermeiden, siehe [[Strukturierte Programmierung auf Mikrocontrollern]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Definition von Bitnamen in den Headerfiles des Compilers&lt;br /&gt;
&lt;br /&gt;
#define PD4 4               // Definition im AVR GCC als Bitnummer&lt;br /&gt;
#define PD5 5&lt;br /&gt;
&lt;br /&gt;
#define P14 (1&amp;lt;&amp;lt;4)          // Definition im MSP430 GCC als Bitmuster&lt;br /&gt;
#define P15 (1&amp;lt;&amp;lt;5)&lt;br /&gt;
&lt;br /&gt;
// Bitmanipulation im Programm&lt;br /&gt;
 &lt;br /&gt;
   DDRD = (1&amp;lt;&amp;lt;PD5) | (1&amp;lt;&amp;lt;PD4);   // AVR GCC&lt;br /&gt;
   P1DIR = P15 | P14;            // MSP430 GCC&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/179566#1729219 Forumsbeitrag:] Bits aus einem Array extrahieren&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/169509#1631439 Forumsbeitrag:] Bits für ein Schieberegister zusammenstellen, TLC5941&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/353071?goto=3947567#3947567 Forumsbeitrag:] TLC5947 und ATmega16 Bitmanipulation&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/15466?goto=107726#107720 Forumsbeitrag:] Bitreihenfolge ändern&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/23866?goto=new#177674 Forumsbeitrag:] Wie drehe ich eine Bitreihenfolge um?&lt;br /&gt;
* [http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/AVR-Built_002din-Functions.html AVR Build-in Functions], spezielle Funktion im avr-gcc zur schnellen Bitvertauschung, engl.&lt;br /&gt;
&lt;br /&gt;
[[Category:8051]]&lt;br /&gt;
[[Category:AVR-Arithmetik]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Bitmanipulation&amp;diff=89410</id>
		<title>Bitmanipulation</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Bitmanipulation&amp;diff=89410"/>
		<updated>2015-07-27T19:39:34Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* 8051er */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Bitoperatoren ==&lt;br /&gt;
&lt;br /&gt;
Bitoperatoren stammen ursprünglich aus dem Bereich des Maschinen-Codes und Assembler, existieren aber auch in den meisten Hochsprachen, wie C.&lt;br /&gt;
&lt;br /&gt;
* &amp;gt;&amp;gt; = Rechts schieben&lt;br /&gt;
* &amp;lt;&amp;lt; = Links schieben (Bsp: &#039;&#039;a&amp;lt;&amp;lt;b&#039;&#039; ist das gleiche wie &#039;&#039;a * 2^b&#039;&#039;; bzw. bei 1&amp;lt;&amp;lt;3 wird die 1 um drei Stellen nach links geschoben)&lt;br /&gt;
* |  = binäres ODER&lt;br /&gt;
* &amp;amp;  = binäres UND&lt;br /&gt;
* ^  = binäres Exklusives ODER&lt;br /&gt;
* usw.&lt;br /&gt;
&lt;br /&gt;
Bitoperatoren in dieser Schreibweise können in Assemblercode für&lt;br /&gt;
konstante Ausdrücke benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, (1&amp;lt;&amp;lt;3) | (1&amp;lt;&amp;lt;1) | (1&amp;lt;&amp;lt;2) | (1&amp;lt;&amp;lt;0)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
wird zu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, 8 | 2 | 4 | 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
wird zu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, 15&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bitmaske ==&lt;br /&gt;
&lt;br /&gt;
Im Folgenden ist häufiger von dem Begriff &#039;&#039;Bitmaske&#039;&#039; die Rede. Damit wird eine Folge von einzelnen Bit bezeichnet, die den Zustand Null (&#039;0&#039;) oder Eins (&#039;1&#039;) darstellen können.&lt;br /&gt;
&lt;br /&gt;
Bitmasken werden im allgemeinen dazu verwendet, um unter Anwendung eines Operators (z.&amp;amp;nbsp;B. UND, ODER, XOR), eine Eingabe zu manipulieren. Das Ergebnis ist dann die Anwendung des Operators auf die Eingabe und der Bitmaske.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Operator eine Funktion mit zwei Argumenten ist, dann lässt sich dessen Anwendung wie folgt schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Ergebnis = Operator( Eingabe, Bitmaske )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Bitmaske ist häufig eine Konstante, da diese z.&amp;amp;nbsp;B. die Information über die Position einer Information in einem Register darstellt. Das kann z.&amp;amp;nbsp;B. ein Überlaufflag in einem Timer Statusregister sein.&lt;br /&gt;
&lt;br /&gt;
== Bits setzen ==&lt;br /&gt;
&lt;br /&gt;
Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] auf Eins gesetzt werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#ODER | ODER]]-Verknüpfung erreicht.  Alle Bits, welche in der Bitmaske &#039;1&#039; sind, werden auf &#039;1&#039; gesetzt. Alle Bits, die in der Maske auf &#039;0&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR-Assembler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
sbr r16, 0b11110000     ; setzt Bits 4-7 in r16, ist ein Pseudobefehl&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
ori r16, 0b11110000     ; setzt Bits 4-7 in r16, ori ist identisch mit sbr&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
sbi PORTB, 5            ; setzt Bit 5 in PortB&lt;br /&gt;
sbi PORTB, PB5          ; identisch, besser lesbar&lt;br /&gt;
                        ; funktioniert nur für die IO-Register 0..0x1F&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register mit I/O Adresse 0x20..0x3F muss&lt;br /&gt;
                        ; in/out verwendet werden&lt;br /&gt;
in  r16, TIMSK          ; setzt Bit TOIE1 in TIMSK&lt;br /&gt;
sbr r16, (1&amp;lt;&amp;lt;TOIE1)    &lt;br /&gt;
out TIMSK, r16&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register oberhalb der I/O Adresse 0x3F muss&lt;br /&gt;
                        ; lds/sts verwednet werden&lt;br /&gt;
                        ; setzt Bit RXCIE0 in UCSR0B&lt;br /&gt;
lds r16, UCSR0B &lt;br /&gt;
sbr r16, (1&amp;lt;&amp;lt;RXCIE0)    &lt;br /&gt;
sts UCSR0B, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Man beachte den Unterschied! Eine &amp;quot;5&amp;quot; würde von sbr als &amp;quot;setze Bit 2 und 0&amp;quot; gedeutet (=0b00000101), während sbi sie als &amp;quot;setze Bit 5&amp;quot; versteht. Der Befehl &#039;&#039;&#039;sbr&#039;&#039;&#039; erwartet ein Bit&#039;&#039;&#039;muster&#039;&#039;&#039; für eine ODER-Verknüpfung, während der Befehlt &#039;&#039;&#039;sbi&#039;&#039;&#039; die Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; benötigt. Darauf sind auch die Includefiles von Atmel im AVR-Studio (Assembler) als auch [[WinAVR]] (C) ausgelegt. Die Namen der Bits sind als Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; definiert. Das ist wichtig, wenn man Register von grossen AVRs manipuliert, z.&amp;amp;nbsp;B. ATmega48. Hier muss aus der Bitnummer über eine Schiebeoperation erst das Bit&#039;&#039;&#039;muster&#039;&#039;&#039; gemacht werden.&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB |= 0xF0;   // Kurzschreibweise, entspricht PORTB = PORTB | 0xF0; bitweises ODER&lt;br /&gt;
&lt;br /&gt;
/* übersichtlicher mittels Bit-Definitionen */&lt;br /&gt;
#define MEINBIT0 0&lt;br /&gt;
#define MEINBIT1 1&lt;br /&gt;
#define MEINBIT2 2&lt;br /&gt;
&lt;br /&gt;
PORTB |= ((1 &amp;lt;&amp;lt; MEINBIT0) | (1 &amp;lt;&amp;lt; MEINBIT2)); // setzt Bit 0 und 2 in PORTB auf &amp;quot;1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die letzte Zeile &amp;quot;entschlüsselt&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;(1 &amp;lt;&amp;lt; n)&#039;&#039;&#039; : Zuerst wird durch die &#039;&amp;lt;&amp;lt;&#039;-Ausdrücke eine &amp;quot;1&amp;quot; n-mal nach links geschoben.  Dies ergibt somit (in Binärschreibweise) 0b00000001 für (1 &amp;lt;&amp;lt; MEINBIT0) und 0b00000100 für (1 &amp;lt;&amp;lt; MEINBIT2).&lt;br /&gt;
# &#039;&#039;&#039;|&#039;&#039;&#039; : Das Ergebnis wird bitweise ODER-verknüpft, also 0b00000001 &#039;&#039;or&#039;&#039; 0b00000100 wird zu 0b00000101.&lt;br /&gt;
# &#039;&#039;&#039;|=&#039;&#039;&#039; : Diese Maske wird mit dem aktuellen Inhalt von PORTB bitweise ODER-verknüpft und das Ergebnis PORTB wieder zugewiesen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB |= variable;         // Kurzschreibweise&lt;br /&gt;
PORTB  = PORTB | variable; // lange Schreibweise&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Ist PORTB vorher z.&amp;amp;nbsp;B. 0b01111010, dann ist der Inhalt nach der Operation 0b01111010 &#039;&#039;or&#039;&#039; 0b00000101 = 0b01111111, die gewünschten Bits sind somit gesetzt!&lt;br /&gt;
&lt;br /&gt;
Anmerkung: Will man das gezeigte Beispiel der Bitmanipulation auf größere Datentypen anwenden, ist zu beachten, dass der Compiler in der Operation (1 &amp;lt;&amp;lt; MEINBIT1) stillschweigend gemäss, den C-Regeln, die 1 als Integer Typ ansieht. Beim AVR-GCC bedeutet das 16-Bit/signed und die folgende Operation bringt ggf. nicht das gewünschte Ergebnis. (Stichwort: &amp;quot;Integer Promotion&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Angenommen Bit 15 soll in einer 32-Bit weiten Variable gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define MEINBIT15 15&lt;br /&gt;
#define MEINBIT42 42&lt;br /&gt;
&lt;br /&gt;
uint32_t reg_32; /* uint32_t definiert per typedef z.&amp;amp;nbsp;B. in stdint.h */&lt;br /&gt;
uint64_t reg_64; /* uint64_t definiert per typedef z.&amp;amp;nbsp;B. in stdint.h */&lt;br /&gt;
&lt;br /&gt;
reg_32 |= (1 &amp;lt;&amp;lt; MEINBIT15);              /* FEHLER: Setzt die Bits 31 - 15, da ((int)1 &amp;lt;&amp;lt; 15) == 0xFFFF8000 */&lt;br /&gt;
&lt;br /&gt;
reg_32 |= ((uint32_t)1 &amp;lt;&amp;lt; MEINBIT15);    /* Hier wird nur Bit 15 gesetzt. */&lt;br /&gt;
reg_32 |= (1U &amp;lt;&amp;lt; MEINBIT15);             /* */&lt;br /&gt;
reg_32 |= (1L &amp;lt;&amp;lt; MEINBIT15);             /* andere Schreibweise. */&lt;br /&gt;
reg_64 |= (1LL &amp;lt;&amp;lt; MEINBIT42);            /* Hier wird nur Bit 42 gesetzt,&lt;br /&gt;
                                            andere Schreibweise für 64 Bit (long long). */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei Compilern für 32bit Controller (z.&amp;amp;nbsp;B. ARM7TDMI) sind Integers per default 32-bit und Konstanten sind somit implizit ebenfalls 32-bit. Man sollte aber dennoch die oben gezeigte Vorgehenweise verwenden, um Probleme zu vermeiden die entstehen könnten, wenn Code unter verschiedenen Plattformen/Compilern verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
== Bits löschen ==&lt;br /&gt;
&lt;br /&gt;
Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] auf Null gesetzt werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#UND | UND]]-Verknüpfung erreicht. Alle Bits, welche in der Bitmaske &#039;0&#039; sind, werden auf &#039;0&#039; gesetzt. Alle Bits, die in der Maske auf &#039;1&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR-Assembler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
cbr r16, 0b00001111     ; löscht Bits 0-3 in r16, ist ein Pseudobefehl &lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
andi r16, 0b11110000    ; löscht Bits 0-3 in r16, andi ist identisch mit cbr&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
andi r16, ~0b00001111   ; andere Schreibweise, hier wird die Bitmaske durch ~ invertiert&lt;br /&gt;
                        ; dadurch kann man einfach alle zu löschenden Bit als &#039;1&#039; angeben&lt;br /&gt;
                        ; so wie bei den Bitmasken für das setzen von Bits (positive Logik)&lt;br /&gt;
&lt;br /&gt;
cbi PORTB, 5            ; löscht Bit 5 in PortB&lt;br /&gt;
cbi PORTB, PB5          ; identisch, besser lesbar&lt;br /&gt;
                        ; funktioniert nur für die IO-Register 0..31&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register mit I/O Adresse 0x20..0x3F muss&lt;br /&gt;
                        ; in/out verwendet werden weil dieser Bereich nicht&lt;br /&gt;
                        ; bitadressierbar ist&lt;br /&gt;
in  r16, TIMSK          ; löscht Bit TOIE1 in TIMSK&lt;br /&gt;
cbr r16, 1&amp;lt;&amp;lt;TOIE1    &lt;br /&gt;
out TIMSK, r16&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register oberhalb der I/O Adresse 0x3F muss&lt;br /&gt;
                        ; lds/sts verwednet werden&lt;br /&gt;
                        ; löscht Bit RXCIE0 in UCSR0B&lt;br /&gt;
lds r16, UCSR0B &lt;br /&gt;
cbr r16, 1&amp;lt;&amp;lt;RXCIE0&lt;br /&gt;
sts UCSR0B, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier gilt: Man beachte den Unterschied! Eine &amp;quot;5&amp;quot; würde von cbr als &amp;quot;lösche Bit 2 und 0&amp;quot; gedeutet, während cbi sie als &amp;quot;lösche Bit 5&amp;quot; versteht. Der Befehl &#039;&#039;&#039;cbr&#039;&#039;&#039; erwartet ein Bit&#039;&#039;&#039;muster&#039;&#039;&#039; für eine UND-NOT-Verknüpfung (nicht zu verwechseln mit NAND), während der Befehl &#039;&#039;&#039;cbi&#039;&#039;&#039; die Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; benötigt. Darauf sind auch die Includefiles von Atmel im AVR-Studio (Assembler) als auch [[WinAVR]] ausgelegt. Die Namen der Bits sind als Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; definiert. Das ist wichtig, wenn man Register von grossen AVRs manipuliert, z.&amp;amp;nbsp;B. ATmega48. Hier muss aus der Bitnummer über eine Schiebeoperation &amp;lt;&amp;lt; erst das Bit&#039;&#039;&#039;muster&#039;&#039;&#039; gemacht werden.&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB &amp;amp;= 0xF0;   // entspricht PORTB = PORTB &amp;amp; 0xF0; bitweises UND&lt;br /&gt;
                 // Bits 0-3 (das &amp;quot;niederwertige&amp;quot; Nibble) werden geloescht &lt;br /&gt;
&lt;br /&gt;
/* übersichtlicher mittels Bit-Definitionen */ &lt;br /&gt;
#define MEINBIT0 0&lt;br /&gt;
#define MEINBIT1 1  &lt;br /&gt;
#define MEINBIT2 2  &lt;br /&gt;
&lt;br /&gt;
PORTB &amp;amp;= ~((1 &amp;lt;&amp;lt; MEINBIT0) | (1 &amp;lt;&amp;lt; MEINBIT2)); // löscht Bit 0 und 2 in PORTB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die letzte Zeile entschlüsselt:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;(1 &amp;lt;&amp;lt; n)&#039;&#039;&#039; : Zuerst wird durch die &#039;&amp;lt;&amp;lt;&#039;-Ausdrücke eine &amp;quot;1&amp;quot; n-mal nach links geschoben. Dies ergibt somit (in Binärschreibweise) 0b00000001 für (1 &amp;lt;&amp;lt; MEINBIT0) und 0b00000100 für (1 &amp;lt;&amp;lt; MEINBIT2).&lt;br /&gt;
# &#039;&#039;&#039;|&#039;&#039;&#039; : Das Ergebnis wird bitweise ODER-verknüpft also 0b00000001 &#039;&#039;or&#039;&#039; 0b00000100 wird zu 0b00000101.&lt;br /&gt;
# &#039;&#039;&#039;~&#039;&#039;&#039; : Der Wert in der Klammer wird bitweise invertiert, aus 0b00000101 wird 0b11111010.&lt;br /&gt;
# &#039;&#039;&#039;&amp;amp;=&#039;&#039;&#039; : PORTB wird mit der berechneten Maske UND-verknüpft und das Ergebnis wieder PORTB zugewiesen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB &amp;amp;= variable;          // Kurzschreibweise&lt;br /&gt;
PORTB  = PORTB &amp;amp; variable;  // lange Schreibweise&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Ist PORTB vorher z.&amp;amp;nbsp;B. 0b01111111, dann ist der Inhalt nach der Operation 0b01111111 &#039;&#039;and&#039;&#039; 0b11111010 = 0b01111010, die gewünschten Bits 0 und 2 sind somit gelöscht.&lt;br /&gt;
&lt;br /&gt;
Die C-Ausdrücke mittels Definitionen von Bitnummern und Schieboperator (&amp;lt;&amp;lt;) sehen auf den ersten Blick etwas &amp;quot;erschreckend&amp;quot; aus und sind mehr &amp;quot;Tipparbeit&amp;quot;, funktionieren aber universell und sind deutlicher und nachvollziehbarer als &amp;quot;handoptimierte&amp;quot; Konstanten. Bei eingeschalteter Optimierung löst der Compiler die Ausdücke mit konstanten Werten bereits zur Compilierungszeit auf und es entsteht kein zusätzlicher Maschinencode. Bei AVR sind die Definitionen meist Teil der Entwicklungsumgebungen (bei avr-libc z.&amp;amp;nbsp;B. implizit durch #include &amp;lt;avr/io.h&amp;gt;). Sie entsprechen den Angaben und Beispielen in den Datenblättern und sind damit de-facto ein Standard beim Zugriff auf Bits in Hardware-Registern.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Wichtiger Hinweis&#039;&#039;&#039;: Die ODER-Verknüpfung und die anschliessende Invertierung kann man nicht vertauschen! (Theorem von DeMorgan) Folgendes Beispiel soll die Richtigkeit der Aussage zeigen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 ~(0b0001 | 0b0010) == 0b1100&lt;br /&gt;
  ~0b0001 | ~0b0010 == 0b1111&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Noch ein wichtiger Hinweis&#039;&#039;&#039;: Der operator ~ mit einem Operanden vom Typ int negiert nur so viele bits, wie der Typ int hat.&lt;br /&gt;
Will man ein bit in einer breiteren Variablen löschen, dann sollte die nach links zu shiftende 1 den Typ dieser Variablen haben.&lt;br /&gt;
&lt;br /&gt;
Ein Programm, welches das verdeutlicht:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, const char* argv[])&lt;br /&gt;
{&lt;br /&gt;
    int bit = 60;&lt;br /&gt;
    uint64_t ui64;&lt;br /&gt;
    printf(&amp;quot;sizeof(int)=%d\n&amp;quot;, (int)sizeof(int));&lt;br /&gt;
    &lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;    &lt;br /&gt;
    ui64 &amp;amp;= ~(1&amp;lt;&amp;lt;60); /* Keine Wirkung bei sizeof(int) &amp;lt; 8 */&lt;br /&gt;
    /* gcc warnt sogar:    &lt;br /&gt;
     * gcc -Wall bit_clear.c -o bit_clear&lt;br /&gt;
     * bit_clear.c: In function ‘main’:&lt;br /&gt;
     * bit_clear.c:11:5: warning: left shift count &amp;gt;= width of type [enabled by default]&lt;br /&gt;
     */    &lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;    &lt;br /&gt;
    ui64 &amp;amp;= ~((uint64_t)1&amp;lt;&amp;lt;60); /* ok */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;&lt;br /&gt;
    ui64 &amp;amp;= ~(1LL&amp;lt;&amp;lt;60); /* auch ok, und kürzer. */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;&lt;br /&gt;
    ui64 &amp;amp;= ~(1&amp;lt;&amp;lt;bit); /* Ohne Warnung, und funktioniert manchmal, je nach Optimierung */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
/* Ausgabe auf meinem PC ohne Optimierung:&lt;br /&gt;
 * sizeof(int)=4&lt;br /&gt;
 * 0&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * Ausgabe auf meinem PC mit -O2&lt;br /&gt;
 * 0&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * 0&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Niederwertigstes gesetztes Bit löschen (Standard C) ===&lt;br /&gt;
&lt;br /&gt;
Folgender Code löscht von allen 1-Bits in einer Integer-Variable das niederwertigste, unabhängig von der Position desselben.&lt;br /&gt;
&lt;br /&gt;
Beispiel: 01101000 -&amp;gt; 01100000&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t byte;&lt;br /&gt;
&lt;br /&gt;
byte = irgendwas();&lt;br /&gt;
&lt;br /&gt;
byte = byte &amp;amp; (byte - 1); /* Diese seltsame Operation löscht das&lt;br /&gt;
                             niederwertigste 1-Bit */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Byte  :  01101000 &lt;br /&gt;
Byte-1:  01100111&lt;br /&gt;
Ergebnis:01100000&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Das funktioniert also mit jeder beliebigen Zahl.&lt;br /&gt;
&lt;br /&gt;
Dies kann bspw. zur schnellen Paritätsgenerierung eingesetzt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t pareven(uint8_t byte) {&lt;br /&gt;
  uint8_t par = 0;&lt;br /&gt;
&lt;br /&gt;
  while(byte) {&lt;br /&gt;
    byte = byte &amp;amp; (byte - 1);&lt;br /&gt;
    par = ~par;&lt;br /&gt;
  }&lt;br /&gt;
  return par;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das genannte gilt natürlich nicht nur für 8-Bit-Integers, sondern für beliebige, vom Compiler unterstützte Wortlängen.&lt;br /&gt;
&lt;br /&gt;
== Bits invertieren ==&lt;br /&gt;
&lt;br /&gt;
Im allgemeinen Sprachgebrauch oft Toggeln genannt (aus dem Englischen). Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] invertiert (getoggelt) werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#XOR_.28Exlusives_Oder.29 | XOR]]-Verknüpfung erreicht. Alle Bits, welche in der Bitmaske &#039;1&#039; sind, werden invertiert. Alle Bits, die in der Maske auf &#039;0&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR Assembler ===&lt;br /&gt;
&lt;br /&gt;
Bei [[AVR]]s erlaubt dies folgender Assemblercode. Hier wird ein Ausgangspin invertiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
  sbic  PortB, 0    ; Überspringe den nächsten Befehl, wenn das Bit 0 im Port gelöscht ist&lt;br /&gt;
  rjmp  ClrBitNow   ; Springe zu ClrBitNow   &lt;br /&gt;
  sbi   PortB, 0    ; Setze Bit 0 in PortB&lt;br /&gt;
  rjmp  BitReady    ; Springe BitReady&lt;br /&gt;
ClrBitNow:&lt;br /&gt;
   cbi  PortB, 0    ; Lösche Bit 0 in PortB&lt;br /&gt;
BitReady:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Noch kürzer gehts so:&amp;lt;br&amp;gt;&lt;br /&gt;
Die zweite Zeile mit dem Befehl &#039;&#039;&#039;ldi&#039;&#039;&#039; lädt die Bitmaske, in welcher die zu toggelnden Bits auf &#039;1&#039; gesetzt sind. In diesem Beispiel wird das dritte Bit invertiert. Der Vorteil dieser Methode ist neben der Kürze und Übersichtlichkeit auch die Möglichkeit, bis zu 8 Bit gleichzeitig zu toggeln. Diese Methode ist natürlich auch auf normale Daten anwendbar, nicht nur auf IO-Ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
 in     R24, PORTE   ; Daten lesen&lt;br /&gt;
 ldi    R25, 0x04    ; Bitmaske laden, hier Bit #2&lt;br /&gt;
 eor    R24, R25     ; Exklusiv ODER&lt;br /&gt;
 out    PORTE, R24   ; Daten zurückschreiben&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine andere Möglichkeit gibt es, wenn man nur das 8. Bit kippen will:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
 in      r16, PORTB&lt;br /&gt;
 subi    r16, 0x80&lt;br /&gt;
 out     PORTB, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 PORTB ^= (1&amp;lt;&amp;lt;PB0);    /* XOR, Kurzschreibweise, PORTB = PORTB ^ (1&amp;lt;&amp;lt;PB0) */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Neuere ATmegas ===&lt;br /&gt;
&lt;br /&gt;
Bei den neueren ATmegas (z.&amp;amp;nbsp;B. ATmega48) kann man IO-Pins direkt ohne den Umweg über Register togglen, indem man das entsprechende Bit im PINx-Register &#039;&#039;&#039;setzt&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
sbi PIND, 2       ; Bit 2 von Port D togglen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 8051er ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
cpl bitadresse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bits prüfen ==&lt;br /&gt;
&lt;br /&gt;
Will man prüfen ob ein oder mehrere Bits in einer Variable gesetzt oder gelöscht sind, muss man sie mit einer Bitmaske UND verknüpfen. Die Bitmaske muss an den Stellen der zu prüfenden Bits eine &#039;1&#039; haben, an allen anderen eine &#039;0&#039;.&lt;br /&gt;
&lt;br /&gt;
* Ist das Ergebnis gleich Null, sind alle geprüften Bits gelöscht.&lt;br /&gt;
* Ist das Ergebnis ungleich Null, ist mindestens ein geprüftes Bit gesetzt.&lt;br /&gt;
* Ist das Ergebnis gleich der Bitmaske, sind alle geprüften Bits gesetzt.&lt;br /&gt;
&lt;br /&gt;
=== AVR Assembler ===&lt;br /&gt;
&lt;br /&gt;
Der AVR hat spezielle Befehle um direkt einzelne Bits in den CPU-Registern r0..r31 sowie den IO-Registern 0..0x1F zu prüfen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
; Befehle zur Prüfung von einzelnen Bits&lt;br /&gt;
&lt;br /&gt;
    sbrs    r16,3       ; überspringe den nächsten Befehl, wenn in r16 Bit #3 gesetzt ist&lt;br /&gt;
    rjmp    bit_ist_nicht_gesetzt&lt;br /&gt;
&lt;br /&gt;
    sbrc    r16,5       ; überspringe den nächsten Befehl, wenn in r16 Bit #5 gelöscht ist&lt;br /&gt;
    rjmp    bit_ist_nicht_geloescht&lt;br /&gt;
&lt;br /&gt;
    sbis    timsk,3     ; überspringe den nächsten Befehl, wenn in timsk Bit #3 gesetzt ist&lt;br /&gt;
    rjmp    bit_ist_nicht_gesetzt&lt;br /&gt;
&lt;br /&gt;
    sbic    timsk,5     ; überspringe den nächsten Befehl, wenn in timsk Bit #5 gelöscht ist&lt;br /&gt;
    rjmp    bit_ist_nicht_geloescht&lt;br /&gt;
&lt;br /&gt;
; Befehle zur Prüfung von mehreren Bits&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    breq    alle_bits_sind_geloescht&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    brne    mind_ein_bit_ist_gesetzt&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    cpi     r16,0b1010&lt;br /&gt;
    breq    alle_bits_sind_gesetzt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    // prüfe ob Bit 4 in der Variable tmp gelöscht ist&lt;br /&gt;
    // die Klammer ist wichtig &lt;br /&gt;
    if (!(tmp &amp;amp; 0x10)) {        &lt;br /&gt;
       // hier die Anweisungen, wenn das Bit gelöscht ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 und Bit 4 in der Variable tmp gelöscht sind&lt;br /&gt;
    // die Klammer ist wichtig! &lt;br /&gt;
    if ((tmp &amp;amp; 0x11) == 0) {        &lt;br /&gt;
       // hier die Anweisungen, wenn beide Bits gelöscht sind&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 oder Bit 4 in der Variable tmp gesetzt ist&lt;br /&gt;
    if (tmp &amp;amp; 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn mindestens ein Bit gesetzt ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 oder Bit 4 in der Variable tmp gelöscht sind&lt;br /&gt;
    if (~tmp &amp;amp; 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn mindestens ein Bit gelöscht ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 4 in der Variable tmp gesetzt ist &lt;br /&gt;
    if (tmp &amp;amp; 0x10) {        &lt;br /&gt;
       // hier die Anweisungen, wenn das Bit gesetzt ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 und Bit 4 in der Variable tmp gesetzt sind&lt;br /&gt;
    // die Klammer ist wichtig! &lt;br /&gt;
    if ((tmp &amp;amp; 0x11) == 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn beide Bits gesetzt sind&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hilfsfunktionen zur Bitmanipulation in C/C++ ==&lt;br /&gt;
Um &amp;quot;einfacher&amp;quot; elementare Bitmanipulationen durchzuführen bietet es sich an einige Hilfsfunktionen zu definieren. Dabei gibt es zwei verschiedene Möglichkeiten diese zu realiseren:&lt;br /&gt;
* Als C-Makro [[C_Makros]]&lt;br /&gt;
* Als Inline-Funktion&lt;br /&gt;
In beiden Fällen wird bei eingeschalteter Optimierung letztendlich vom Compiler ein sehr kompakter (und identischer!) Code erzeugt, jedoch ist dringend von der Verwendung von Makros abzuraten (siehe [[Makro]] )!&lt;br /&gt;
Im Fehlerfall zeigt der Compiler bei der Verwendung vom Makros keine eindeutigen Fehlermeldungen an, da es sich um simple Ersetzungen handelt - bei der Verwendung von Inline-Funktionen hingegen gibt es eine &amp;quot;brauchbare&amp;quot; Fehlermeldung!&lt;br /&gt;
&lt;br /&gt;
=== Beispiele - Inline Variante ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Achtung: Zugriffe erfolgen über Pointer&lt;br /&gt;
// PORTA, PB2 setzen&lt;br /&gt;
BIT_SET(&amp;amp;PORTA, PB2);&lt;br /&gt;
&lt;br /&gt;
// PORTC, PB0 löschen&lt;br /&gt;
BIT_CLEAR(&amp;amp;PORTC, PB0);&lt;br /&gt;
&lt;br /&gt;
// PORTA, PB2 direkt setzen&lt;br /&gt;
// HIGH&lt;br /&gt;
BIT_BOOL_SET(&amp;amp;PORTA, PB2, 1);&lt;br /&gt;
&lt;br /&gt;
// LOW&lt;br /&gt;
BIT_BOOL_SET(&amp;amp;PORTA, PB2, 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beispiele - MakroVariante ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Achtung: Zugriffe erfolgen direkt über die Variablen/Portnamen&lt;br /&gt;
// PORTA, PB2 setzen&lt;br /&gt;
BIT_SET(PORTA, PB2);&lt;br /&gt;
&lt;br /&gt;
// PORTC, PB0 löschen&lt;br /&gt;
BIT_CLEAR(PORTC, PB0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um die Hilfsfunktionen verwenden zu können einfach folgenden Code in eine neue Header-Datei (z.B. BitIO.h) kopieren:&lt;br /&gt;
&lt;br /&gt;
=== Hilfsfunktionen als Inline-Methoden ===&lt;br /&gt;
Achtung: Wenn nur ein C Compiler verwendet wird, kennt dieser den Typ &amp;quot;bool&amp;quot; nicht, dieser muss dann vorher definiert werden!&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *  BitIO.h&lt;br /&gt;
 *	@author 	Andi Dittrich &amp;lt;http://andidittrich.de&amp;gt;&lt;br /&gt;
 *	@version	1.0&lt;br /&gt;
 *	@license	MIT Style X11 License&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;inttypes.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef BITIO_H_&lt;br /&gt;
#define BITIO_H_&lt;br /&gt;
&lt;br /&gt;
// set bit&lt;br /&gt;
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target |= (1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// set clear&lt;br /&gt;
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target &amp;amp;= ~(1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// bit toogle&lt;br /&gt;
static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target ^= (1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// set bit by boolean&lt;br /&gt;
static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable){&lt;br /&gt;
	if (enable){&lt;br /&gt;
		BIT_SET(target, bit);&lt;br /&gt;
	}else{&lt;br /&gt;
		BIT_CLEAR(target, bit);&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif /* BITIO_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hilfsfunktionen als C-Makro (nicht empfohlen) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* Bit setzen */&lt;br /&gt;
#define set_bit(var, bit) ((var) |= (1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
 &lt;br /&gt;
/* Bit löschen */&lt;br /&gt;
#define clear_bit(var, bit) ((var) &amp;amp;= (unsigned)~(1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
 &lt;br /&gt;
/* Bit togglen */&lt;br /&gt;
#define toggle_bit(var,bit) ((var) ^= (1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bitmanipulation beim MSP430 ==&lt;br /&gt;
&lt;br /&gt;
Beim MSP430 und dessen Compilern sind die Bitnamen meist anders definiert. Und zwar nicht als Bitnummer, sondern als Bitmuster. Darum schreibt man dort die Bitzugriffe in C anders. Das kann auch bei anderen Mikrocontrollern bzw. C-Compilern so sein. Wichtig ist, dass man seine eignen Definitionen in der gleichen Weise wie der Compiler anlegt, um Verwirrung zu vermeiden, siehe [[Strukturierte Programmierung auf Mikrocontrollern]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Definition von Bitnamen in den Headerfiles des Compilers&lt;br /&gt;
&lt;br /&gt;
#define PD4 4               // Definition im AVR GCC als Bitnummer&lt;br /&gt;
#define PD5 5&lt;br /&gt;
&lt;br /&gt;
#define P14 (1&amp;lt;&amp;lt;4)          // Definition im MSP430 GCC als Bitmuster&lt;br /&gt;
#define P15 (1&amp;lt;&amp;lt;5)&lt;br /&gt;
&lt;br /&gt;
// Bitmanipulation im Programm&lt;br /&gt;
 &lt;br /&gt;
   DDRD = (1&amp;lt;&amp;lt;PD5) | (1&amp;lt;&amp;lt;PD4);   // AVR GCC&lt;br /&gt;
   P1DIR = P15 | P14;            // MSP430 GCC&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/179566#1729219 Forumsbeitrag:] Bits aus einem Array extrahieren&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/169509#1631439 Forumsbeitrag:] Bits für ein Schieberegister zusammenstellen, TLC5941&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/353071?goto=3947567#3947567 Forumsbeitrag:] TLC5947 und ATmega16 Bitmanipulation&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/15466?goto=107726#107720 Forumsbeitrag:] Bitreihenfolge ändern&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/23866?goto=new#177674 Forumsbeitrag:] Wie drehe ich eine Bitreihenfolge um?&lt;br /&gt;
* [http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/AVR-Built_002din-Functions.html AVR Build-in Functions], spezielle Funktion im avr-gcc zur schnellen Bitvertauschung, engl.&lt;br /&gt;
&lt;br /&gt;
[[Category:8051]]&lt;br /&gt;
[[Category:AVR-Arithmetik]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Bitmanipulation&amp;diff=89409</id>
		<title>Bitmanipulation</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Bitmanipulation&amp;diff=89409"/>
		<updated>2015-07-27T19:39:08Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* AVR Assembler */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Bitoperatoren ==&lt;br /&gt;
&lt;br /&gt;
Bitoperatoren stammen ursprünglich aus dem Bereich des Maschinen-Codes und Assembler, existieren aber auch in den meisten Hochsprachen, wie C.&lt;br /&gt;
&lt;br /&gt;
* &amp;gt;&amp;gt; = Rechts schieben&lt;br /&gt;
* &amp;lt;&amp;lt; = Links schieben (Bsp: &#039;&#039;a&amp;lt;&amp;lt;b&#039;&#039; ist das gleiche wie &#039;&#039;a * 2^b&#039;&#039;; bzw. bei 1&amp;lt;&amp;lt;3 wird die 1 um drei Stellen nach links geschoben)&lt;br /&gt;
* |  = binäres ODER&lt;br /&gt;
* &amp;amp;  = binäres UND&lt;br /&gt;
* ^  = binäres Exklusives ODER&lt;br /&gt;
* usw.&lt;br /&gt;
&lt;br /&gt;
Bitoperatoren in dieser Schreibweise können in Assemblercode für&lt;br /&gt;
konstante Ausdrücke benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, (1&amp;lt;&amp;lt;3) | (1&amp;lt;&amp;lt;1) | (1&amp;lt;&amp;lt;2) | (1&amp;lt;&amp;lt;0)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
wird zu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, 8 | 2 | 4 | 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
wird zu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, 15&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bitmaske ==&lt;br /&gt;
&lt;br /&gt;
Im Folgenden ist häufiger von dem Begriff &#039;&#039;Bitmaske&#039;&#039; die Rede. Damit wird eine Folge von einzelnen Bit bezeichnet, die den Zustand Null (&#039;0&#039;) oder Eins (&#039;1&#039;) darstellen können.&lt;br /&gt;
&lt;br /&gt;
Bitmasken werden im allgemeinen dazu verwendet, um unter Anwendung eines Operators (z.&amp;amp;nbsp;B. UND, ODER, XOR), eine Eingabe zu manipulieren. Das Ergebnis ist dann die Anwendung des Operators auf die Eingabe und der Bitmaske.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Operator eine Funktion mit zwei Argumenten ist, dann lässt sich dessen Anwendung wie folgt schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Ergebnis = Operator( Eingabe, Bitmaske )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Bitmaske ist häufig eine Konstante, da diese z.&amp;amp;nbsp;B. die Information über die Position einer Information in einem Register darstellt. Das kann z.&amp;amp;nbsp;B. ein Überlaufflag in einem Timer Statusregister sein.&lt;br /&gt;
&lt;br /&gt;
== Bits setzen ==&lt;br /&gt;
&lt;br /&gt;
Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] auf Eins gesetzt werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#ODER | ODER]]-Verknüpfung erreicht.  Alle Bits, welche in der Bitmaske &#039;1&#039; sind, werden auf &#039;1&#039; gesetzt. Alle Bits, die in der Maske auf &#039;0&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR-Assembler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
sbr r16, 0b11110000     ; setzt Bits 4-7 in r16, ist ein Pseudobefehl&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
ori r16, 0b11110000     ; setzt Bits 4-7 in r16, ori ist identisch mit sbr&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
sbi PORTB, 5            ; setzt Bit 5 in PortB&lt;br /&gt;
sbi PORTB, PB5          ; identisch, besser lesbar&lt;br /&gt;
                        ; funktioniert nur für die IO-Register 0..0x1F&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register mit I/O Adresse 0x20..0x3F muss&lt;br /&gt;
                        ; in/out verwendet werden&lt;br /&gt;
in  r16, TIMSK          ; setzt Bit TOIE1 in TIMSK&lt;br /&gt;
sbr r16, (1&amp;lt;&amp;lt;TOIE1)    &lt;br /&gt;
out TIMSK, r16&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register oberhalb der I/O Adresse 0x3F muss&lt;br /&gt;
                        ; lds/sts verwednet werden&lt;br /&gt;
                        ; setzt Bit RXCIE0 in UCSR0B&lt;br /&gt;
lds r16, UCSR0B &lt;br /&gt;
sbr r16, (1&amp;lt;&amp;lt;RXCIE0)    &lt;br /&gt;
sts UCSR0B, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Man beachte den Unterschied! Eine &amp;quot;5&amp;quot; würde von sbr als &amp;quot;setze Bit 2 und 0&amp;quot; gedeutet (=0b00000101), während sbi sie als &amp;quot;setze Bit 5&amp;quot; versteht. Der Befehl &#039;&#039;&#039;sbr&#039;&#039;&#039; erwartet ein Bit&#039;&#039;&#039;muster&#039;&#039;&#039; für eine ODER-Verknüpfung, während der Befehlt &#039;&#039;&#039;sbi&#039;&#039;&#039; die Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; benötigt. Darauf sind auch die Includefiles von Atmel im AVR-Studio (Assembler) als auch [[WinAVR]] (C) ausgelegt. Die Namen der Bits sind als Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; definiert. Das ist wichtig, wenn man Register von grossen AVRs manipuliert, z.&amp;amp;nbsp;B. ATmega48. Hier muss aus der Bitnummer über eine Schiebeoperation erst das Bit&#039;&#039;&#039;muster&#039;&#039;&#039; gemacht werden.&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB |= 0xF0;   // Kurzschreibweise, entspricht PORTB = PORTB | 0xF0; bitweises ODER&lt;br /&gt;
&lt;br /&gt;
/* übersichtlicher mittels Bit-Definitionen */&lt;br /&gt;
#define MEINBIT0 0&lt;br /&gt;
#define MEINBIT1 1&lt;br /&gt;
#define MEINBIT2 2&lt;br /&gt;
&lt;br /&gt;
PORTB |= ((1 &amp;lt;&amp;lt; MEINBIT0) | (1 &amp;lt;&amp;lt; MEINBIT2)); // setzt Bit 0 und 2 in PORTB auf &amp;quot;1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die letzte Zeile &amp;quot;entschlüsselt&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;(1 &amp;lt;&amp;lt; n)&#039;&#039;&#039; : Zuerst wird durch die &#039;&amp;lt;&amp;lt;&#039;-Ausdrücke eine &amp;quot;1&amp;quot; n-mal nach links geschoben.  Dies ergibt somit (in Binärschreibweise) 0b00000001 für (1 &amp;lt;&amp;lt; MEINBIT0) und 0b00000100 für (1 &amp;lt;&amp;lt; MEINBIT2).&lt;br /&gt;
# &#039;&#039;&#039;|&#039;&#039;&#039; : Das Ergebnis wird bitweise ODER-verknüpft, also 0b00000001 &#039;&#039;or&#039;&#039; 0b00000100 wird zu 0b00000101.&lt;br /&gt;
# &#039;&#039;&#039;|=&#039;&#039;&#039; : Diese Maske wird mit dem aktuellen Inhalt von PORTB bitweise ODER-verknüpft und das Ergebnis PORTB wieder zugewiesen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB |= variable;         // Kurzschreibweise&lt;br /&gt;
PORTB  = PORTB | variable; // lange Schreibweise&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Ist PORTB vorher z.&amp;amp;nbsp;B. 0b01111010, dann ist der Inhalt nach der Operation 0b01111010 &#039;&#039;or&#039;&#039; 0b00000101 = 0b01111111, die gewünschten Bits sind somit gesetzt!&lt;br /&gt;
&lt;br /&gt;
Anmerkung: Will man das gezeigte Beispiel der Bitmanipulation auf größere Datentypen anwenden, ist zu beachten, dass der Compiler in der Operation (1 &amp;lt;&amp;lt; MEINBIT1) stillschweigend gemäss, den C-Regeln, die 1 als Integer Typ ansieht. Beim AVR-GCC bedeutet das 16-Bit/signed und die folgende Operation bringt ggf. nicht das gewünschte Ergebnis. (Stichwort: &amp;quot;Integer Promotion&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Angenommen Bit 15 soll in einer 32-Bit weiten Variable gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define MEINBIT15 15&lt;br /&gt;
#define MEINBIT42 42&lt;br /&gt;
&lt;br /&gt;
uint32_t reg_32; /* uint32_t definiert per typedef z.&amp;amp;nbsp;B. in stdint.h */&lt;br /&gt;
uint64_t reg_64; /* uint64_t definiert per typedef z.&amp;amp;nbsp;B. in stdint.h */&lt;br /&gt;
&lt;br /&gt;
reg_32 |= (1 &amp;lt;&amp;lt; MEINBIT15);              /* FEHLER: Setzt die Bits 31 - 15, da ((int)1 &amp;lt;&amp;lt; 15) == 0xFFFF8000 */&lt;br /&gt;
&lt;br /&gt;
reg_32 |= ((uint32_t)1 &amp;lt;&amp;lt; MEINBIT15);    /* Hier wird nur Bit 15 gesetzt. */&lt;br /&gt;
reg_32 |= (1U &amp;lt;&amp;lt; MEINBIT15);             /* */&lt;br /&gt;
reg_32 |= (1L &amp;lt;&amp;lt; MEINBIT15);             /* andere Schreibweise. */&lt;br /&gt;
reg_64 |= (1LL &amp;lt;&amp;lt; MEINBIT42);            /* Hier wird nur Bit 42 gesetzt,&lt;br /&gt;
                                            andere Schreibweise für 64 Bit (long long). */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei Compilern für 32bit Controller (z.&amp;amp;nbsp;B. ARM7TDMI) sind Integers per default 32-bit und Konstanten sind somit implizit ebenfalls 32-bit. Man sollte aber dennoch die oben gezeigte Vorgehenweise verwenden, um Probleme zu vermeiden die entstehen könnten, wenn Code unter verschiedenen Plattformen/Compilern verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
== Bits löschen ==&lt;br /&gt;
&lt;br /&gt;
Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] auf Null gesetzt werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#UND | UND]]-Verknüpfung erreicht. Alle Bits, welche in der Bitmaske &#039;0&#039; sind, werden auf &#039;0&#039; gesetzt. Alle Bits, die in der Maske auf &#039;1&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR-Assembler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
cbr r16, 0b00001111     ; löscht Bits 0-3 in r16, ist ein Pseudobefehl &lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
andi r16, 0b11110000    ; löscht Bits 0-3 in r16, andi ist identisch mit cbr&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
andi r16, ~0b00001111   ; andere Schreibweise, hier wird die Bitmaske durch ~ invertiert&lt;br /&gt;
                        ; dadurch kann man einfach alle zu löschenden Bit als &#039;1&#039; angeben&lt;br /&gt;
                        ; so wie bei den Bitmasken für das setzen von Bits (positive Logik)&lt;br /&gt;
&lt;br /&gt;
cbi PORTB, 5            ; löscht Bit 5 in PortB&lt;br /&gt;
cbi PORTB, PB5          ; identisch, besser lesbar&lt;br /&gt;
                        ; funktioniert nur für die IO-Register 0..31&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register mit I/O Adresse 0x20..0x3F muss&lt;br /&gt;
                        ; in/out verwendet werden weil dieser Bereich nicht&lt;br /&gt;
                        ; bitadressierbar ist&lt;br /&gt;
in  r16, TIMSK          ; löscht Bit TOIE1 in TIMSK&lt;br /&gt;
cbr r16, 1&amp;lt;&amp;lt;TOIE1    &lt;br /&gt;
out TIMSK, r16&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register oberhalb der I/O Adresse 0x3F muss&lt;br /&gt;
                        ; lds/sts verwednet werden&lt;br /&gt;
                        ; löscht Bit RXCIE0 in UCSR0B&lt;br /&gt;
lds r16, UCSR0B &lt;br /&gt;
cbr r16, 1&amp;lt;&amp;lt;RXCIE0&lt;br /&gt;
sts UCSR0B, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier gilt: Man beachte den Unterschied! Eine &amp;quot;5&amp;quot; würde von cbr als &amp;quot;lösche Bit 2 und 0&amp;quot; gedeutet, während cbi sie als &amp;quot;lösche Bit 5&amp;quot; versteht. Der Befehl &#039;&#039;&#039;cbr&#039;&#039;&#039; erwartet ein Bit&#039;&#039;&#039;muster&#039;&#039;&#039; für eine UND-NOT-Verknüpfung (nicht zu verwechseln mit NAND), während der Befehl &#039;&#039;&#039;cbi&#039;&#039;&#039; die Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; benötigt. Darauf sind auch die Includefiles von Atmel im AVR-Studio (Assembler) als auch [[WinAVR]] ausgelegt. Die Namen der Bits sind als Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; definiert. Das ist wichtig, wenn man Register von grossen AVRs manipuliert, z.&amp;amp;nbsp;B. ATmega48. Hier muss aus der Bitnummer über eine Schiebeoperation &amp;lt;&amp;lt; erst das Bit&#039;&#039;&#039;muster&#039;&#039;&#039; gemacht werden.&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB &amp;amp;= 0xF0;   // entspricht PORTB = PORTB &amp;amp; 0xF0; bitweises UND&lt;br /&gt;
                 // Bits 0-3 (das &amp;quot;niederwertige&amp;quot; Nibble) werden geloescht &lt;br /&gt;
&lt;br /&gt;
/* übersichtlicher mittels Bit-Definitionen */ &lt;br /&gt;
#define MEINBIT0 0&lt;br /&gt;
#define MEINBIT1 1  &lt;br /&gt;
#define MEINBIT2 2  &lt;br /&gt;
&lt;br /&gt;
PORTB &amp;amp;= ~((1 &amp;lt;&amp;lt; MEINBIT0) | (1 &amp;lt;&amp;lt; MEINBIT2)); // löscht Bit 0 und 2 in PORTB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die letzte Zeile entschlüsselt:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;(1 &amp;lt;&amp;lt; n)&#039;&#039;&#039; : Zuerst wird durch die &#039;&amp;lt;&amp;lt;&#039;-Ausdrücke eine &amp;quot;1&amp;quot; n-mal nach links geschoben. Dies ergibt somit (in Binärschreibweise) 0b00000001 für (1 &amp;lt;&amp;lt; MEINBIT0) und 0b00000100 für (1 &amp;lt;&amp;lt; MEINBIT2).&lt;br /&gt;
# &#039;&#039;&#039;|&#039;&#039;&#039; : Das Ergebnis wird bitweise ODER-verknüpft also 0b00000001 &#039;&#039;or&#039;&#039; 0b00000100 wird zu 0b00000101.&lt;br /&gt;
# &#039;&#039;&#039;~&#039;&#039;&#039; : Der Wert in der Klammer wird bitweise invertiert, aus 0b00000101 wird 0b11111010.&lt;br /&gt;
# &#039;&#039;&#039;&amp;amp;=&#039;&#039;&#039; : PORTB wird mit der berechneten Maske UND-verknüpft und das Ergebnis wieder PORTB zugewiesen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB &amp;amp;= variable;          // Kurzschreibweise&lt;br /&gt;
PORTB  = PORTB &amp;amp; variable;  // lange Schreibweise&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Ist PORTB vorher z.&amp;amp;nbsp;B. 0b01111111, dann ist der Inhalt nach der Operation 0b01111111 &#039;&#039;and&#039;&#039; 0b11111010 = 0b01111010, die gewünschten Bits 0 und 2 sind somit gelöscht.&lt;br /&gt;
&lt;br /&gt;
Die C-Ausdrücke mittels Definitionen von Bitnummern und Schieboperator (&amp;lt;&amp;lt;) sehen auf den ersten Blick etwas &amp;quot;erschreckend&amp;quot; aus und sind mehr &amp;quot;Tipparbeit&amp;quot;, funktionieren aber universell und sind deutlicher und nachvollziehbarer als &amp;quot;handoptimierte&amp;quot; Konstanten. Bei eingeschalteter Optimierung löst der Compiler die Ausdücke mit konstanten Werten bereits zur Compilierungszeit auf und es entsteht kein zusätzlicher Maschinencode. Bei AVR sind die Definitionen meist Teil der Entwicklungsumgebungen (bei avr-libc z.&amp;amp;nbsp;B. implizit durch #include &amp;lt;avr/io.h&amp;gt;). Sie entsprechen den Angaben und Beispielen in den Datenblättern und sind damit de-facto ein Standard beim Zugriff auf Bits in Hardware-Registern.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Wichtiger Hinweis&#039;&#039;&#039;: Die ODER-Verknüpfung und die anschliessende Invertierung kann man nicht vertauschen! (Theorem von DeMorgan) Folgendes Beispiel soll die Richtigkeit der Aussage zeigen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 ~(0b0001 | 0b0010) == 0b1100&lt;br /&gt;
  ~0b0001 | ~0b0010 == 0b1111&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Noch ein wichtiger Hinweis&#039;&#039;&#039;: Der operator ~ mit einem Operanden vom Typ int negiert nur so viele bits, wie der Typ int hat.&lt;br /&gt;
Will man ein bit in einer breiteren Variablen löschen, dann sollte die nach links zu shiftende 1 den Typ dieser Variablen haben.&lt;br /&gt;
&lt;br /&gt;
Ein Programm, welches das verdeutlicht:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, const char* argv[])&lt;br /&gt;
{&lt;br /&gt;
    int bit = 60;&lt;br /&gt;
    uint64_t ui64;&lt;br /&gt;
    printf(&amp;quot;sizeof(int)=%d\n&amp;quot;, (int)sizeof(int));&lt;br /&gt;
    &lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;    &lt;br /&gt;
    ui64 &amp;amp;= ~(1&amp;lt;&amp;lt;60); /* Keine Wirkung bei sizeof(int) &amp;lt; 8 */&lt;br /&gt;
    /* gcc warnt sogar:    &lt;br /&gt;
     * gcc -Wall bit_clear.c -o bit_clear&lt;br /&gt;
     * bit_clear.c: In function ‘main’:&lt;br /&gt;
     * bit_clear.c:11:5: warning: left shift count &amp;gt;= width of type [enabled by default]&lt;br /&gt;
     */    &lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;    &lt;br /&gt;
    ui64 &amp;amp;= ~((uint64_t)1&amp;lt;&amp;lt;60); /* ok */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;&lt;br /&gt;
    ui64 &amp;amp;= ~(1LL&amp;lt;&amp;lt;60); /* auch ok, und kürzer. */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;&lt;br /&gt;
    ui64 &amp;amp;= ~(1&amp;lt;&amp;lt;bit); /* Ohne Warnung, und funktioniert manchmal, je nach Optimierung */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
/* Ausgabe auf meinem PC ohne Optimierung:&lt;br /&gt;
 * sizeof(int)=4&lt;br /&gt;
 * 0&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * Ausgabe auf meinem PC mit -O2&lt;br /&gt;
 * 0&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * 0&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Niederwertigstes gesetztes Bit löschen (Standard C) ===&lt;br /&gt;
&lt;br /&gt;
Folgender Code löscht von allen 1-Bits in einer Integer-Variable das niederwertigste, unabhängig von der Position desselben.&lt;br /&gt;
&lt;br /&gt;
Beispiel: 01101000 -&amp;gt; 01100000&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t byte;&lt;br /&gt;
&lt;br /&gt;
byte = irgendwas();&lt;br /&gt;
&lt;br /&gt;
byte = byte &amp;amp; (byte - 1); /* Diese seltsame Operation löscht das&lt;br /&gt;
                             niederwertigste 1-Bit */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Byte  :  01101000 &lt;br /&gt;
Byte-1:  01100111&lt;br /&gt;
Ergebnis:01100000&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Das funktioniert also mit jeder beliebigen Zahl.&lt;br /&gt;
&lt;br /&gt;
Dies kann bspw. zur schnellen Paritätsgenerierung eingesetzt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t pareven(uint8_t byte) {&lt;br /&gt;
  uint8_t par = 0;&lt;br /&gt;
&lt;br /&gt;
  while(byte) {&lt;br /&gt;
    byte = byte &amp;amp; (byte - 1);&lt;br /&gt;
    par = ~par;&lt;br /&gt;
  }&lt;br /&gt;
  return par;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das genannte gilt natürlich nicht nur für 8-Bit-Integers, sondern für beliebige, vom Compiler unterstützte Wortlängen.&lt;br /&gt;
&lt;br /&gt;
== Bits invertieren ==&lt;br /&gt;
&lt;br /&gt;
Im allgemeinen Sprachgebrauch oft Toggeln genannt (aus dem Englischen). Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] invertiert (getoggelt) werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#XOR_.28Exlusives_Oder.29 | XOR]]-Verknüpfung erreicht. Alle Bits, welche in der Bitmaske &#039;1&#039; sind, werden invertiert. Alle Bits, die in der Maske auf &#039;0&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR Assembler ===&lt;br /&gt;
&lt;br /&gt;
Bei [[AVR]]s erlaubt dies folgender Assemblercode. Hier wird ein Ausgangspin invertiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
  sbic  PortB, 0    ; Überspringe den nächsten Befehl, wenn das Bit 0 im Port gelöscht ist&lt;br /&gt;
  rjmp  ClrBitNow   ; Springe zu ClrBitNow   &lt;br /&gt;
  sbi   PortB, 0    ; Setze Bit 0 in PortB&lt;br /&gt;
  rjmp  BitReady    ; Springe BitReady&lt;br /&gt;
ClrBitNow:&lt;br /&gt;
   cbi  PortB, 0    ; Lösche Bit 0 in PortB&lt;br /&gt;
BitReady:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Noch kürzer gehts so:&amp;lt;br&amp;gt;&lt;br /&gt;
Die zweite Zeile mit dem Befehl &#039;&#039;&#039;ldi&#039;&#039;&#039; lädt die Bitmaske, in welcher die zu toggelnden Bits auf &#039;1&#039; gesetzt sind. In diesem Beispiel wird das dritte Bit invertiert. Der Vorteil dieser Methode ist neben der Kürze und Übersichtlichkeit auch die Möglichkeit, bis zu 8 Bit gleichzeitig zu toggeln. Diese Methode ist natürlich auch auf normale Daten anwendbar, nicht nur auf IO-Ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
 in     R24, PORTE   ; Daten lesen&lt;br /&gt;
 ldi    R25, 0x04    ; Bitmaske laden, hier Bit #2&lt;br /&gt;
 eor    R24, R25     ; Exklusiv ODER&lt;br /&gt;
 out    PORTE, R24   ; Daten zurückschreiben&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine andere Möglichkeit gibt es, wenn man nur das 8. Bit kippen will:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
 in      r16, PORTB&lt;br /&gt;
 subi    r16, 0x80&lt;br /&gt;
 out     PORTB, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 PORTB ^= (1&amp;lt;&amp;lt;PB0);    /* XOR, Kurzschreibweise, PORTB = PORTB ^ (1&amp;lt;&amp;lt;PB0) */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Neuere ATmegas ===&lt;br /&gt;
&lt;br /&gt;
Bei den neueren ATmegas (z.&amp;amp;nbsp;B. ATmega48) kann man IO-Pins direkt ohne den Umweg über Register togglen, indem man das entsprechende Bit im PINx-Register &#039;&#039;&#039;setzt&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
sbi PIND, 2       ; Bit 2 von Port D togglen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 8051er ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
cpl bitadresse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bits prüfen ==&lt;br /&gt;
&lt;br /&gt;
Will man prüfen ob ein oder mehrere Bits in einer Variable gesetzt oder gelöscht sind, muss man sie mit einer Bitmaske UND verknüpfen. Die Bitmaske muss an den Stellen der zu prüfenden Bits eine &#039;1&#039; haben, an allen anderen eine &#039;0&#039;.&lt;br /&gt;
&lt;br /&gt;
* Ist das Ergebnis gleich Null, sind alle geprüften Bits gelöscht.&lt;br /&gt;
* Ist das Ergebnis ungleich Null, ist mindestens ein geprüftes Bit gesetzt.&lt;br /&gt;
* Ist das Ergebnis gleich der Bitmaske, sind alle geprüften Bits gesetzt.&lt;br /&gt;
&lt;br /&gt;
=== AVR Assembler ===&lt;br /&gt;
&lt;br /&gt;
Der AVR hat spezielle Befehle um direkt einzelne Bits in den CPU-Registern r0..r31 sowie den IO-Registern 0..0x1F zu prüfen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
; Befehle zur Prüfung von einzelnen Bits&lt;br /&gt;
&lt;br /&gt;
    sbrs    r16,3       ; überspringe den nächsten Befehl, wenn in r16 Bit #3 gesetzt ist&lt;br /&gt;
    rjmp    bit_ist_nicht_gesetzt&lt;br /&gt;
&lt;br /&gt;
    sbrc    r16,5       ; überspringe den nächsten Befehl, wenn in r16 Bit #5 gelöscht ist&lt;br /&gt;
    rjmp    bit_ist_nicht_geloescht&lt;br /&gt;
&lt;br /&gt;
    sbis    timsk,3     ; überspringe den nächsten Befehl, wenn in timsk Bit #3 gesetzt ist&lt;br /&gt;
    rjmp    bit_ist_nicht_gesetzt&lt;br /&gt;
&lt;br /&gt;
    sbic    timsk,5     ; überspringe den nächsten Befehl, wenn in timsk Bit #5 gelöscht ist&lt;br /&gt;
    rjmp    bit_ist_nicht_geloescht&lt;br /&gt;
&lt;br /&gt;
; Befehle zur Prüfung von mehreren Bits&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    breq    alle_bits_sind_geloescht&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    brne    mind_ein_bit_ist_gesetzt&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    cpi     r16,0b1010&lt;br /&gt;
    breq    alle_bits_sind_gesetzt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    // prüfe ob Bit 4 in der Variable tmp gelöscht ist&lt;br /&gt;
    // die Klammer ist wichtig &lt;br /&gt;
    if (!(tmp &amp;amp; 0x10)) {        &lt;br /&gt;
       // hier die Anweisungen, wenn das Bit gelöscht ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 und Bit 4 in der Variable tmp gelöscht sind&lt;br /&gt;
    // die Klammer ist wichtig! &lt;br /&gt;
    if ((tmp &amp;amp; 0x11) == 0) {        &lt;br /&gt;
       // hier die Anweisungen, wenn beide Bits gelöscht sind&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 oder Bit 4 in der Variable tmp gesetzt ist&lt;br /&gt;
    if (tmp &amp;amp; 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn mindestens ein Bit gesetzt ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 oder Bit 4 in der Variable tmp gelöscht sind&lt;br /&gt;
    if (~tmp &amp;amp; 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn mindestens ein Bit gelöscht ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 4 in der Variable tmp gesetzt ist &lt;br /&gt;
    if (tmp &amp;amp; 0x10) {        &lt;br /&gt;
       // hier die Anweisungen, wenn das Bit gesetzt ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 und Bit 4 in der Variable tmp gesetzt sind&lt;br /&gt;
    // die Klammer ist wichtig! &lt;br /&gt;
    if ((tmp &amp;amp; 0x11) == 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn beide Bits gesetzt sind&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hilfsfunktionen zur Bitmanipulation in C/C++ ==&lt;br /&gt;
Um &amp;quot;einfacher&amp;quot; elementare Bitmanipulationen durchzuführen bietet es sich an einige Hilfsfunktionen zu definieren. Dabei gibt es zwei verschiedene Möglichkeiten diese zu realiseren:&lt;br /&gt;
* Als C-Makro [[C_Makros]]&lt;br /&gt;
* Als Inline-Funktion&lt;br /&gt;
In beiden Fällen wird bei eingeschalteter Optimierung letztendlich vom Compiler ein sehr kompakter (und identischer!) Code erzeugt, jedoch ist dringend von der Verwendung von Makros abzuraten (siehe [[Makro]] )!&lt;br /&gt;
Im Fehlerfall zeigt der Compiler bei der Verwendung vom Makros keine eindeutigen Fehlermeldungen an, da es sich um simple Ersetzungen handelt - bei der Verwendung von Inline-Funktionen hingegen gibt es eine &amp;quot;brauchbare&amp;quot; Fehlermeldung!&lt;br /&gt;
&lt;br /&gt;
=== Beispiele - Inline Variante ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Achtung: Zugriffe erfolgen über Pointer&lt;br /&gt;
// PORTA, PB2 setzen&lt;br /&gt;
BIT_SET(&amp;amp;PORTA, PB2);&lt;br /&gt;
&lt;br /&gt;
// PORTC, PB0 löschen&lt;br /&gt;
BIT_CLEAR(&amp;amp;PORTC, PB0);&lt;br /&gt;
&lt;br /&gt;
// PORTA, PB2 direkt setzen&lt;br /&gt;
// HIGH&lt;br /&gt;
BIT_BOOL_SET(&amp;amp;PORTA, PB2, 1);&lt;br /&gt;
&lt;br /&gt;
// LOW&lt;br /&gt;
BIT_BOOL_SET(&amp;amp;PORTA, PB2, 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beispiele - MakroVariante ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Achtung: Zugriffe erfolgen direkt über die Variablen/Portnamen&lt;br /&gt;
// PORTA, PB2 setzen&lt;br /&gt;
BIT_SET(PORTA, PB2);&lt;br /&gt;
&lt;br /&gt;
// PORTC, PB0 löschen&lt;br /&gt;
BIT_CLEAR(PORTC, PB0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um die Hilfsfunktionen verwenden zu können einfach folgenden Code in eine neue Header-Datei (z.B. BitIO.h) kopieren:&lt;br /&gt;
&lt;br /&gt;
=== Hilfsfunktionen als Inline-Methoden ===&lt;br /&gt;
Achtung: Wenn nur ein C Compiler verwendet wird, kennt dieser den Typ &amp;quot;bool&amp;quot; nicht, dieser muss dann vorher definiert werden!&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *  BitIO.h&lt;br /&gt;
 *	@author 	Andi Dittrich &amp;lt;http://andidittrich.de&amp;gt;&lt;br /&gt;
 *	@version	1.0&lt;br /&gt;
 *	@license	MIT Style X11 License&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;inttypes.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef BITIO_H_&lt;br /&gt;
#define BITIO_H_&lt;br /&gt;
&lt;br /&gt;
// set bit&lt;br /&gt;
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target |= (1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// set clear&lt;br /&gt;
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target &amp;amp;= ~(1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// bit toogle&lt;br /&gt;
static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target ^= (1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// set bit by boolean&lt;br /&gt;
static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable){&lt;br /&gt;
	if (enable){&lt;br /&gt;
		BIT_SET(target, bit);&lt;br /&gt;
	}else{&lt;br /&gt;
		BIT_CLEAR(target, bit);&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif /* BITIO_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hilfsfunktionen als C-Makro (nicht empfohlen) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* Bit setzen */&lt;br /&gt;
#define set_bit(var, bit) ((var) |= (1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
 &lt;br /&gt;
/* Bit löschen */&lt;br /&gt;
#define clear_bit(var, bit) ((var) &amp;amp;= (unsigned)~(1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
 &lt;br /&gt;
/* Bit togglen */&lt;br /&gt;
#define toggle_bit(var,bit) ((var) ^= (1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bitmanipulation beim MSP430 ==&lt;br /&gt;
&lt;br /&gt;
Beim MSP430 und dessen Compilern sind die Bitnamen meist anders definiert. Und zwar nicht als Bitnummer, sondern als Bitmuster. Darum schreibt man dort die Bitzugriffe in C anders. Das kann auch bei anderen Mikrocontrollern bzw. C-Compilern so sein. Wichtig ist, dass man seine eignen Definitionen in der gleichen Weise wie der Compiler anlegt, um Verwirrung zu vermeiden, siehe [[Strukturierte Programmierung auf Mikrocontrollern]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Definition von Bitnamen in den Headerfiles des Compilers&lt;br /&gt;
&lt;br /&gt;
#define PD4 4               // Definition im AVR GCC als Bitnummer&lt;br /&gt;
#define PD5 5&lt;br /&gt;
&lt;br /&gt;
#define P14 (1&amp;lt;&amp;lt;4)          // Definition im MSP430 GCC als Bitmuster&lt;br /&gt;
#define P15 (1&amp;lt;&amp;lt;5)&lt;br /&gt;
&lt;br /&gt;
// Bitmanipulation im Programm&lt;br /&gt;
 &lt;br /&gt;
   DDRD = (1&amp;lt;&amp;lt;PD5) | (1&amp;lt;&amp;lt;PD4);   // AVR GCC&lt;br /&gt;
   P1DIR = P15 | P14;            // MSP430 GCC&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/179566#1729219 Forumsbeitrag:] Bits aus einem Array extrahieren&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/169509#1631439 Forumsbeitrag:] Bits für ein Schieberegister zusammenstellen, TLC5941&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/353071?goto=3947567#3947567 Forumsbeitrag:] TLC5947 und ATmega16 Bitmanipulation&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/15466?goto=107726#107720 Forumsbeitrag:] Bitreihenfolge ändern&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/23866?goto=new#177674 Forumsbeitrag:] Wie drehe ich eine Bitreihenfolge um?&lt;br /&gt;
* [http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/AVR-Built_002din-Functions.html AVR Build-in Functions], spezielle Funktion im avr-gcc zur schnellen Bitvertauschung, engl.&lt;br /&gt;
&lt;br /&gt;
[[Category:8051]]&lt;br /&gt;
[[Category:AVR-Arithmetik]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Bitmanipulation&amp;diff=89408</id>
		<title>Bitmanipulation</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Bitmanipulation&amp;diff=89408"/>
		<updated>2015-07-27T19:38:13Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* Bitoperatoren */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Bitoperatoren ==&lt;br /&gt;
&lt;br /&gt;
Bitoperatoren stammen ursprünglich aus dem Bereich des Maschinen-Codes und Assembler, existieren aber auch in den meisten Hochsprachen, wie C.&lt;br /&gt;
&lt;br /&gt;
* &amp;gt;&amp;gt; = Rechts schieben&lt;br /&gt;
* &amp;lt;&amp;lt; = Links schieben (Bsp: &#039;&#039;a&amp;lt;&amp;lt;b&#039;&#039; ist das gleiche wie &#039;&#039;a * 2^b&#039;&#039;; bzw. bei 1&amp;lt;&amp;lt;3 wird die 1 um drei Stellen nach links geschoben)&lt;br /&gt;
* |  = binäres ODER&lt;br /&gt;
* &amp;amp;  = binäres UND&lt;br /&gt;
* ^  = binäres Exklusives ODER&lt;br /&gt;
* usw.&lt;br /&gt;
&lt;br /&gt;
Bitoperatoren in dieser Schreibweise können in Assemblercode für&lt;br /&gt;
konstante Ausdrücke benutzt werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, (1&amp;lt;&amp;lt;3) | (1&amp;lt;&amp;lt;1) | (1&amp;lt;&amp;lt;2) | (1&amp;lt;&amp;lt;0)&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
wird zu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, 8 | 2 | 4 | 1&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
wird zu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;asm&amp;quot;&amp;gt; &lt;br /&gt;
ldi temp, 15&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bitmaske ==&lt;br /&gt;
&lt;br /&gt;
Im Folgenden ist häufiger von dem Begriff &#039;&#039;Bitmaske&#039;&#039; die Rede. Damit wird eine Folge von einzelnen Bit bezeichnet, die den Zustand Null (&#039;0&#039;) oder Eins (&#039;1&#039;) darstellen können.&lt;br /&gt;
&lt;br /&gt;
Bitmasken werden im allgemeinen dazu verwendet, um unter Anwendung eines Operators (z.&amp;amp;nbsp;B. UND, ODER, XOR), eine Eingabe zu manipulieren. Das Ergebnis ist dann die Anwendung des Operators auf die Eingabe und der Bitmaske.&lt;br /&gt;
&lt;br /&gt;
Wenn ein Operator eine Funktion mit zwei Argumenten ist, dann lässt sich dessen Anwendung wie folgt schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Ergebnis = Operator( Eingabe, Bitmaske )&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Bitmaske ist häufig eine Konstante, da diese z.&amp;amp;nbsp;B. die Information über die Position einer Information in einem Register darstellt. Das kann z.&amp;amp;nbsp;B. ein Überlaufflag in einem Timer Statusregister sein.&lt;br /&gt;
&lt;br /&gt;
== Bits setzen ==&lt;br /&gt;
&lt;br /&gt;
Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] auf Eins gesetzt werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#ODER | ODER]]-Verknüpfung erreicht.  Alle Bits, welche in der Bitmaske &#039;1&#039; sind, werden auf &#039;1&#039; gesetzt. Alle Bits, die in der Maske auf &#039;0&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR-Assembler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
sbr r16, 0b11110000     ; setzt Bits 4-7 in r16, ist ein Pseudobefehl&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
ori r16, 0b11110000     ; setzt Bits 4-7 in r16, ori ist identisch mit sbr&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
sbi PORTB, 5            ; setzt Bit 5 in PortB&lt;br /&gt;
sbi PORTB, PB5          ; identisch, besser lesbar&lt;br /&gt;
                        ; funktioniert nur für die IO-Register 0..0x1F&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register mit I/O Adresse 0x20..0x3F muss&lt;br /&gt;
                        ; in/out verwendet werden&lt;br /&gt;
in  r16, TIMSK          ; setzt Bit TOIE1 in TIMSK&lt;br /&gt;
sbr r16, (1&amp;lt;&amp;lt;TOIE1)    &lt;br /&gt;
out TIMSK, r16&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register oberhalb der I/O Adresse 0x3F muss&lt;br /&gt;
                        ; lds/sts verwednet werden&lt;br /&gt;
                        ; setzt Bit RXCIE0 in UCSR0B&lt;br /&gt;
lds r16, UCSR0B &lt;br /&gt;
sbr r16, (1&amp;lt;&amp;lt;RXCIE0)    &lt;br /&gt;
sts UCSR0B, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Man beachte den Unterschied! Eine &amp;quot;5&amp;quot; würde von sbr als &amp;quot;setze Bit 2 und 0&amp;quot; gedeutet (=0b00000101), während sbi sie als &amp;quot;setze Bit 5&amp;quot; versteht. Der Befehl &#039;&#039;&#039;sbr&#039;&#039;&#039; erwartet ein Bit&#039;&#039;&#039;muster&#039;&#039;&#039; für eine ODER-Verknüpfung, während der Befehlt &#039;&#039;&#039;sbi&#039;&#039;&#039; die Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; benötigt. Darauf sind auch die Includefiles von Atmel im AVR-Studio (Assembler) als auch [[WinAVR]] (C) ausgelegt. Die Namen der Bits sind als Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; definiert. Das ist wichtig, wenn man Register von grossen AVRs manipuliert, z.&amp;amp;nbsp;B. ATmega48. Hier muss aus der Bitnummer über eine Schiebeoperation erst das Bit&#039;&#039;&#039;muster&#039;&#039;&#039; gemacht werden.&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB |= 0xF0;   // Kurzschreibweise, entspricht PORTB = PORTB | 0xF0; bitweises ODER&lt;br /&gt;
&lt;br /&gt;
/* übersichtlicher mittels Bit-Definitionen */&lt;br /&gt;
#define MEINBIT0 0&lt;br /&gt;
#define MEINBIT1 1&lt;br /&gt;
#define MEINBIT2 2&lt;br /&gt;
&lt;br /&gt;
PORTB |= ((1 &amp;lt;&amp;lt; MEINBIT0) | (1 &amp;lt;&amp;lt; MEINBIT2)); // setzt Bit 0 und 2 in PORTB auf &amp;quot;1&amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die letzte Zeile &amp;quot;entschlüsselt&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;(1 &amp;lt;&amp;lt; n)&#039;&#039;&#039; : Zuerst wird durch die &#039;&amp;lt;&amp;lt;&#039;-Ausdrücke eine &amp;quot;1&amp;quot; n-mal nach links geschoben.  Dies ergibt somit (in Binärschreibweise) 0b00000001 für (1 &amp;lt;&amp;lt; MEINBIT0) und 0b00000100 für (1 &amp;lt;&amp;lt; MEINBIT2).&lt;br /&gt;
# &#039;&#039;&#039;|&#039;&#039;&#039; : Das Ergebnis wird bitweise ODER-verknüpft, also 0b00000001 &#039;&#039;or&#039;&#039; 0b00000100 wird zu 0b00000101.&lt;br /&gt;
# &#039;&#039;&#039;|=&#039;&#039;&#039; : Diese Maske wird mit dem aktuellen Inhalt von PORTB bitweise ODER-verknüpft und das Ergebnis PORTB wieder zugewiesen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB |= variable;         // Kurzschreibweise&lt;br /&gt;
PORTB  = PORTB | variable; // lange Schreibweise&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Ist PORTB vorher z.&amp;amp;nbsp;B. 0b01111010, dann ist der Inhalt nach der Operation 0b01111010 &#039;&#039;or&#039;&#039; 0b00000101 = 0b01111111, die gewünschten Bits sind somit gesetzt!&lt;br /&gt;
&lt;br /&gt;
Anmerkung: Will man das gezeigte Beispiel der Bitmanipulation auf größere Datentypen anwenden, ist zu beachten, dass der Compiler in der Operation (1 &amp;lt;&amp;lt; MEINBIT1) stillschweigend gemäss, den C-Regeln, die 1 als Integer Typ ansieht. Beim AVR-GCC bedeutet das 16-Bit/signed und die folgende Operation bringt ggf. nicht das gewünschte Ergebnis. (Stichwort: &amp;quot;Integer Promotion&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Angenommen Bit 15 soll in einer 32-Bit weiten Variable gesetzt werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#define MEINBIT15 15&lt;br /&gt;
#define MEINBIT42 42&lt;br /&gt;
&lt;br /&gt;
uint32_t reg_32; /* uint32_t definiert per typedef z.&amp;amp;nbsp;B. in stdint.h */&lt;br /&gt;
uint64_t reg_64; /* uint64_t definiert per typedef z.&amp;amp;nbsp;B. in stdint.h */&lt;br /&gt;
&lt;br /&gt;
reg_32 |= (1 &amp;lt;&amp;lt; MEINBIT15);              /* FEHLER: Setzt die Bits 31 - 15, da ((int)1 &amp;lt;&amp;lt; 15) == 0xFFFF8000 */&lt;br /&gt;
&lt;br /&gt;
reg_32 |= ((uint32_t)1 &amp;lt;&amp;lt; MEINBIT15);    /* Hier wird nur Bit 15 gesetzt. */&lt;br /&gt;
reg_32 |= (1U &amp;lt;&amp;lt; MEINBIT15);             /* */&lt;br /&gt;
reg_32 |= (1L &amp;lt;&amp;lt; MEINBIT15);             /* andere Schreibweise. */&lt;br /&gt;
reg_64 |= (1LL &amp;lt;&amp;lt; MEINBIT42);            /* Hier wird nur Bit 42 gesetzt,&lt;br /&gt;
                                            andere Schreibweise für 64 Bit (long long). */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei Compilern für 32bit Controller (z.&amp;amp;nbsp;B. ARM7TDMI) sind Integers per default 32-bit und Konstanten sind somit implizit ebenfalls 32-bit. Man sollte aber dennoch die oben gezeigte Vorgehenweise verwenden, um Probleme zu vermeiden die entstehen könnten, wenn Code unter verschiedenen Plattformen/Compilern verwendet werden soll.&lt;br /&gt;
&lt;br /&gt;
== Bits löschen ==&lt;br /&gt;
&lt;br /&gt;
Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] auf Null gesetzt werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#UND | UND]]-Verknüpfung erreicht. Alle Bits, welche in der Bitmaske &#039;0&#039; sind, werden auf &#039;0&#039; gesetzt. Alle Bits, die in der Maske auf &#039;1&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR-Assembler ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
cbr r16, 0b00001111     ; löscht Bits 0-3 in r16, ist ein Pseudobefehl &lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
andi r16, 0b11110000    ; löscht Bits 0-3 in r16, andi ist identisch mit cbr&lt;br /&gt;
                        ; funktioniert nur für die Arbeitsregister r16-r31&lt;br /&gt;
&lt;br /&gt;
andi r16, ~0b00001111   ; andere Schreibweise, hier wird die Bitmaske durch ~ invertiert&lt;br /&gt;
                        ; dadurch kann man einfach alle zu löschenden Bit als &#039;1&#039; angeben&lt;br /&gt;
                        ; so wie bei den Bitmasken für das setzen von Bits (positive Logik)&lt;br /&gt;
&lt;br /&gt;
cbi PORTB, 5            ; löscht Bit 5 in PortB&lt;br /&gt;
cbi PORTB, PB5          ; identisch, besser lesbar&lt;br /&gt;
                        ; funktioniert nur für die IO-Register 0..31&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register mit I/O Adresse 0x20..0x3F muss&lt;br /&gt;
                        ; in/out verwendet werden weil dieser Bereich nicht&lt;br /&gt;
                        ; bitadressierbar ist&lt;br /&gt;
in  r16, TIMSK          ; löscht Bit TOIE1 in TIMSK&lt;br /&gt;
cbr r16, 1&amp;lt;&amp;lt;TOIE1    &lt;br /&gt;
out TIMSK, r16&lt;br /&gt;
&lt;br /&gt;
                        ; für I/O Register oberhalb der I/O Adresse 0x3F muss&lt;br /&gt;
                        ; lds/sts verwednet werden&lt;br /&gt;
                        ; löscht Bit RXCIE0 in UCSR0B&lt;br /&gt;
lds r16, UCSR0B &lt;br /&gt;
cbr r16, 1&amp;lt;&amp;lt;RXCIE0&lt;br /&gt;
sts UCSR0B, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auch hier gilt: Man beachte den Unterschied! Eine &amp;quot;5&amp;quot; würde von cbr als &amp;quot;lösche Bit 2 und 0&amp;quot; gedeutet, während cbi sie als &amp;quot;lösche Bit 5&amp;quot; versteht. Der Befehl &#039;&#039;&#039;cbr&#039;&#039;&#039; erwartet ein Bit&#039;&#039;&#039;muster&#039;&#039;&#039; für eine UND-NOT-Verknüpfung (nicht zu verwechseln mit NAND), während der Befehl &#039;&#039;&#039;cbi&#039;&#039;&#039; die Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; benötigt. Darauf sind auch die Includefiles von Atmel im AVR-Studio (Assembler) als auch [[WinAVR]] ausgelegt. Die Namen der Bits sind als Bit&#039;&#039;&#039;nummer&#039;&#039;&#039; definiert. Das ist wichtig, wenn man Register von grossen AVRs manipuliert, z.&amp;amp;nbsp;B. ATmega48. Hier muss aus der Bitnummer über eine Schiebeoperation &amp;lt;&amp;lt; erst das Bit&#039;&#039;&#039;muster&#039;&#039;&#039; gemacht werden.&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB &amp;amp;= 0xF0;   // entspricht PORTB = PORTB &amp;amp; 0xF0; bitweises UND&lt;br /&gt;
                 // Bits 0-3 (das &amp;quot;niederwertige&amp;quot; Nibble) werden geloescht &lt;br /&gt;
&lt;br /&gt;
/* übersichtlicher mittels Bit-Definitionen */ &lt;br /&gt;
#define MEINBIT0 0&lt;br /&gt;
#define MEINBIT1 1  &lt;br /&gt;
#define MEINBIT2 2  &lt;br /&gt;
&lt;br /&gt;
PORTB &amp;amp;= ~((1 &amp;lt;&amp;lt; MEINBIT0) | (1 &amp;lt;&amp;lt; MEINBIT2)); // löscht Bit 0 und 2 in PORTB&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die letzte Zeile entschlüsselt:&lt;br /&gt;
&lt;br /&gt;
# &#039;&#039;&#039;(1 &amp;lt;&amp;lt; n)&#039;&#039;&#039; : Zuerst wird durch die &#039;&amp;lt;&amp;lt;&#039;-Ausdrücke eine &amp;quot;1&amp;quot; n-mal nach links geschoben. Dies ergibt somit (in Binärschreibweise) 0b00000001 für (1 &amp;lt;&amp;lt; MEINBIT0) und 0b00000100 für (1 &amp;lt;&amp;lt; MEINBIT2).&lt;br /&gt;
# &#039;&#039;&#039;|&#039;&#039;&#039; : Das Ergebnis wird bitweise ODER-verknüpft also 0b00000001 &#039;&#039;or&#039;&#039; 0b00000100 wird zu 0b00000101.&lt;br /&gt;
# &#039;&#039;&#039;~&#039;&#039;&#039; : Der Wert in der Klammer wird bitweise invertiert, aus 0b00000101 wird 0b11111010.&lt;br /&gt;
# &#039;&#039;&#039;&amp;amp;=&#039;&#039;&#039; : PORTB wird mit der berechneten Maske UND-verknüpft und das Ergebnis wieder PORTB zugewiesen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
PORTB &amp;amp;= variable;          // Kurzschreibweise&lt;br /&gt;
PORTB  = PORTB &amp;amp; variable;  // lange Schreibweise&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
: Ist PORTB vorher z.&amp;amp;nbsp;B. 0b01111111, dann ist der Inhalt nach der Operation 0b01111111 &#039;&#039;and&#039;&#039; 0b11111010 = 0b01111010, die gewünschten Bits 0 und 2 sind somit gelöscht.&lt;br /&gt;
&lt;br /&gt;
Die C-Ausdrücke mittels Definitionen von Bitnummern und Schieboperator (&amp;lt;&amp;lt;) sehen auf den ersten Blick etwas &amp;quot;erschreckend&amp;quot; aus und sind mehr &amp;quot;Tipparbeit&amp;quot;, funktionieren aber universell und sind deutlicher und nachvollziehbarer als &amp;quot;handoptimierte&amp;quot; Konstanten. Bei eingeschalteter Optimierung löst der Compiler die Ausdücke mit konstanten Werten bereits zur Compilierungszeit auf und es entsteht kein zusätzlicher Maschinencode. Bei AVR sind die Definitionen meist Teil der Entwicklungsumgebungen (bei avr-libc z.&amp;amp;nbsp;B. implizit durch #include &amp;lt;avr/io.h&amp;gt;). Sie entsprechen den Angaben und Beispielen in den Datenblättern und sind damit de-facto ein Standard beim Zugriff auf Bits in Hardware-Registern.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Wichtiger Hinweis&#039;&#039;&#039;: Die ODER-Verknüpfung und die anschliessende Invertierung kann man nicht vertauschen! (Theorem von DeMorgan) Folgendes Beispiel soll die Richtigkeit der Aussage zeigen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 ~(0b0001 | 0b0010) == 0b1100&lt;br /&gt;
  ~0b0001 | ~0b0010 == 0b1111&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Noch ein wichtiger Hinweis&#039;&#039;&#039;: Der operator ~ mit einem Operanden vom Typ int negiert nur so viele bits, wie der Typ int hat.&lt;br /&gt;
Will man ein bit in einer breiteren Variablen löschen, dann sollte die nach links zu shiftende 1 den Typ dieser Variablen haben.&lt;br /&gt;
&lt;br /&gt;
Ein Programm, welches das verdeutlicht:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(int argc, const char* argv[])&lt;br /&gt;
{&lt;br /&gt;
    int bit = 60;&lt;br /&gt;
    uint64_t ui64;&lt;br /&gt;
    printf(&amp;quot;sizeof(int)=%d\n&amp;quot;, (int)sizeof(int));&lt;br /&gt;
    &lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;    &lt;br /&gt;
    ui64 &amp;amp;= ~(1&amp;lt;&amp;lt;60); /* Keine Wirkung bei sizeof(int) &amp;lt; 8 */&lt;br /&gt;
    /* gcc warnt sogar:    &lt;br /&gt;
     * gcc -Wall bit_clear.c -o bit_clear&lt;br /&gt;
     * bit_clear.c: In function ‘main’:&lt;br /&gt;
     * bit_clear.c:11:5: warning: left shift count &amp;gt;= width of type [enabled by default]&lt;br /&gt;
     */    &lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;    &lt;br /&gt;
    ui64 &amp;amp;= ~((uint64_t)1&amp;lt;&amp;lt;60); /* ok */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;&lt;br /&gt;
    ui64 &amp;amp;= ~(1LL&amp;lt;&amp;lt;60); /* auch ok, und kürzer. */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    ui64 = 0xFFFFFFFFFFFFFFFF;&lt;br /&gt;
    ui64 &amp;amp;= ~(1&amp;lt;&amp;lt;bit); /* Ohne Warnung, und funktioniert manchmal, je nach Optimierung */&lt;br /&gt;
    printf(&amp;quot;%d\n&amp;quot;, ui64!=0xFFFFFFFFFFFFFFFF);&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
/* Ausgabe auf meinem PC ohne Optimierung:&lt;br /&gt;
 * sizeof(int)=4&lt;br /&gt;
 * 0&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * Ausgabe auf meinem PC mit -O2&lt;br /&gt;
 * 0&lt;br /&gt;
 * 1&lt;br /&gt;
 * 1&lt;br /&gt;
 * 0&lt;br /&gt;
 */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Niederwertigstes gesetztes Bit löschen (Standard C) ===&lt;br /&gt;
&lt;br /&gt;
Folgender Code löscht von allen 1-Bits in einer Integer-Variable das niederwertigste, unabhängig von der Position desselben.&lt;br /&gt;
&lt;br /&gt;
Beispiel: 01101000 -&amp;gt; 01100000&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t byte;&lt;br /&gt;
&lt;br /&gt;
byte = irgendwas();&lt;br /&gt;
&lt;br /&gt;
byte = byte &amp;amp; (byte - 1); /* Diese seltsame Operation löscht das&lt;br /&gt;
                             niederwertigste 1-Bit */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
Byte  :  01101000 &lt;br /&gt;
Byte-1:  01100111&lt;br /&gt;
Ergebnis:01100000&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Das funktioniert also mit jeder beliebigen Zahl.&lt;br /&gt;
&lt;br /&gt;
Dies kann bspw. zur schnellen Paritätsgenerierung eingesetzt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
uint8_t pareven(uint8_t byte) {&lt;br /&gt;
  uint8_t par = 0;&lt;br /&gt;
&lt;br /&gt;
  while(byte) {&lt;br /&gt;
    byte = byte &amp;amp; (byte - 1);&lt;br /&gt;
    par = ~par;&lt;br /&gt;
  }&lt;br /&gt;
  return par;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das genannte gilt natürlich nicht nur für 8-Bit-Integers, sondern für beliebige, vom Compiler unterstützte Wortlängen.&lt;br /&gt;
&lt;br /&gt;
== Bits invertieren ==&lt;br /&gt;
&lt;br /&gt;
Im allgemeinen Sprachgebrauch oft Toggeln genannt (aus dem Englischen). Wenn in einem Byte mehrere [[Digitaltechnik|Bits]] invertiert (getoggelt) werden sollen, wird dies durch eine [[AVR-Tutorial:_Logik#XOR_.28Exlusives_Oder.29 | XOR]]-Verknüpfung erreicht. Alle Bits, welche in der Bitmaske &#039;1&#039; sind, werden invertiert. Alle Bits, die in der Maske auf &#039;0&#039; gesetzt sind, bleiben unverändert.&lt;br /&gt;
&lt;br /&gt;
=== AVR Assembler ===&lt;br /&gt;
&lt;br /&gt;
Bei [[AVR]]s erlaubt dies folgender Assemblercode. Hier wird ein Ausgangspin invertiert.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
  sbic  PortB, 0    ; Überspringe den nächsten Befehl, wenn das Bit 0 im Port gelöscht ist&lt;br /&gt;
  rjmp  ClrBitNow   ; Springe zu ClrBitNow   &lt;br /&gt;
  sbi   PortB, 0    ; Setze Bit 0 in PortB&lt;br /&gt;
  rjmp  BitReady    ; Springe BitReady&lt;br /&gt;
ClrBitNow:&lt;br /&gt;
   cbi  PortB, 0    ; Lösche Bit 0 in PortB&lt;br /&gt;
BitReady:&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Noch kürzer gehts so:&amp;lt;br&amp;gt;&lt;br /&gt;
Die zweite Zeile mit dem Befehl &#039;&#039;&#039;ldi&#039;&#039;&#039; lädt die Bitmaske, in welcher die zu toggelnden Bits auf &#039;1&#039; gesetzt sind. In diesem Beispiel wird das dritte Bit invertiert. Der Vorteil dieser Methode ist neben der Kürze und Übersichtlichkeit auch die Möglichkeit, bis zu 8 Bit gleichzeitig zu toggeln. Diese Methode ist natürlich auch auf normale Daten anwendbar, nicht nur auf IO-Ports.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
 in     R24, PORTE   ; Daten lesen&lt;br /&gt;
 ldi    R25, 0x04    ; Bitmaske laden, hier Bit #2&lt;br /&gt;
 eor    R24, R25     ; Exklusiv ODER&lt;br /&gt;
 out    PORTE, R24   ; Daten zurückschreiben&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine andere Möglichkeit gibt es, wenn man nur das 8. Bit kippen will:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
 in      r16, PORTB&lt;br /&gt;
 subi    r16, 0x80&lt;br /&gt;
 out     PORTB, r16&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
 PORTB ^= (1&amp;lt;&amp;lt;PB0);    /* XOR, Kurzschreibweise, PORTB = PORTB ^ (1&amp;lt;&amp;lt;PB0) */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Neuere ATmegas ===&lt;br /&gt;
&lt;br /&gt;
Bei den neueren ATmegas (z.&amp;amp;nbsp;B. ATmega48) kann man IO-Pins direkt ohne den Umweg über Register togglen, indem man das entsprechende Bit im PINx-Register &#039;&#039;&#039;setzt&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
sbi PIND, 2       ; Bit 2 von Port D togglen&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== 8051er ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
cpl bitadresse&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bits prüfen ==&lt;br /&gt;
&lt;br /&gt;
Will man prüfen ob ein oder mehrere Bits in einer Variable gesetzt oder gelöscht sind, muss man sie mit einer Bitmaske UND verknüpfen. Die Bitmaske muss an den Stellen der zu prüfenden Bits eine &#039;1&#039; haben, an allen anderen eine &#039;0&#039;.&lt;br /&gt;
&lt;br /&gt;
* Ist das Ergebnis gleich Null, sind alle geprüften Bits gelöscht.&lt;br /&gt;
* Ist das Ergebnis ungleich Null, ist mindestens ein geprüftes Bit gesetzt.&lt;br /&gt;
* Ist das Ergebnis gleich der Bitmaske, sind alle geprüften Bits gesetzt.&lt;br /&gt;
&lt;br /&gt;
=== AVR Assembler ===&lt;br /&gt;
&lt;br /&gt;
Der AVR hat spezielle Befehle um direkt einzelne Bits in den CPU-Registern r0..r31 sowie den IO-Registern 0..0x1F zu prüfen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;avrasm&amp;quot;&amp;gt; &lt;br /&gt;
; Befehle zur Prüfung von einzelnen Bits&lt;br /&gt;
&lt;br /&gt;
    sbrs    r16,3       ; überspringe den nächsten Befehl, wenn in r16 Bit #3 gesetzt ist&lt;br /&gt;
    rjmp    bit_ist_nicht_gesetzt&lt;br /&gt;
&lt;br /&gt;
    sbrc    r16,5       ; überspringe den nächsten Befehl, wenn in r16 Bit #5 gelöscht ist&lt;br /&gt;
    rjmp    bit_ist_nicht_geloescht&lt;br /&gt;
&lt;br /&gt;
    sbis    timsk,3     ; überspringe den nächsten Befehl, wenn in timsk Bit #3 gesetzt ist&lt;br /&gt;
    rjmp    bit_ist_nicht_gesetzt&lt;br /&gt;
&lt;br /&gt;
    sbic    timsk,5     ; überspringe den nächsten Befehl, wenn in timsk Bit #5 gelöscht ist&lt;br /&gt;
    rjmp    bit_ist_nicht_geloescht&lt;br /&gt;
&lt;br /&gt;
; Befehle zur Prüfung von mehreren Bits&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    breq    alle_bits_sind_geloescht&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    brne    mind_ein_bit_ist_gesetzt&lt;br /&gt;
&lt;br /&gt;
    andi    r16,0b1010  ; prüfe Bit #1 und #3 in r16&lt;br /&gt;
    cpi     r16,0b1010&lt;br /&gt;
    breq    alle_bits_sind_gesetzt&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Standard C ===&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    // prüfe ob Bit 4 in der Variable tmp gelöscht ist&lt;br /&gt;
    // die Klammer ist wichtig &lt;br /&gt;
    if (!(tmp &amp;amp; 0x10)) {        &lt;br /&gt;
       // hier die Anweisungen, wenn das Bit gelöscht ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 und Bit 4 in der Variable tmp gelöscht sind&lt;br /&gt;
    // die Klammer ist wichtig! &lt;br /&gt;
    if ((tmp &amp;amp; 0x11) == 0) {        &lt;br /&gt;
       // hier die Anweisungen, wenn beide Bits gelöscht sind&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 oder Bit 4 in der Variable tmp gesetzt ist&lt;br /&gt;
    if (tmp &amp;amp; 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn mindestens ein Bit gesetzt ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 oder Bit 4 in der Variable tmp gelöscht sind&lt;br /&gt;
    if (~tmp &amp;amp; 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn mindestens ein Bit gelöscht ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 4 in der Variable tmp gesetzt ist &lt;br /&gt;
    if (tmp &amp;amp; 0x10) {        &lt;br /&gt;
       // hier die Anweisungen, wenn das Bit gesetzt ist&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    // prüfe ob Bit 0 und Bit 4 in der Variable tmp gesetzt sind&lt;br /&gt;
    // die Klammer ist wichtig! &lt;br /&gt;
    if ((tmp &amp;amp; 0x11) == 0x11) {        &lt;br /&gt;
       // hier die Anweisungen, wenn beide Bits gesetzt sind&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Hilfsfunktionen zur Bitmanipulation in C/C++ ==&lt;br /&gt;
Um &amp;quot;einfacher&amp;quot; elementare Bitmanipulationen durchzuführen bietet es sich an einige Hilfsfunktionen zu definieren. Dabei gibt es zwei verschiedene Möglichkeiten diese zu realiseren:&lt;br /&gt;
* Als C-Makro [[C_Makros]]&lt;br /&gt;
* Als Inline-Funktion&lt;br /&gt;
In beiden Fällen wird bei eingeschalteter Optimierung letztendlich vom Compiler ein sehr kompakter (und identischer!) Code erzeugt, jedoch ist dringend von der Verwendung von Makros abzuraten (siehe [[Makro]] )!&lt;br /&gt;
Im Fehlerfall zeigt der Compiler bei der Verwendung vom Makros keine eindeutigen Fehlermeldungen an, da es sich um simple Ersetzungen handelt - bei der Verwendung von Inline-Funktionen hingegen gibt es eine &amp;quot;brauchbare&amp;quot; Fehlermeldung!&lt;br /&gt;
&lt;br /&gt;
=== Beispiele - Inline Variante ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Achtung: Zugriffe erfolgen über Pointer&lt;br /&gt;
// PORTA, PB2 setzen&lt;br /&gt;
BIT_SET(&amp;amp;PORTA, PB2);&lt;br /&gt;
&lt;br /&gt;
// PORTC, PB0 löschen&lt;br /&gt;
BIT_CLEAR(&amp;amp;PORTC, PB0);&lt;br /&gt;
&lt;br /&gt;
// PORTA, PB2 direkt setzen&lt;br /&gt;
// HIGH&lt;br /&gt;
BIT_BOOL_SET(&amp;amp;PORTA, PB2, 1);&lt;br /&gt;
&lt;br /&gt;
// LOW&lt;br /&gt;
BIT_BOOL_SET(&amp;amp;PORTA, PB2, 0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Beispiele - MakroVariante ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Achtung: Zugriffe erfolgen direkt über die Variablen/Portnamen&lt;br /&gt;
// PORTA, PB2 setzen&lt;br /&gt;
BIT_SET(PORTA, PB2);&lt;br /&gt;
&lt;br /&gt;
// PORTC, PB0 löschen&lt;br /&gt;
BIT_CLEAR(PORTC, PB0);&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Um die Hilfsfunktionen verwenden zu können einfach folgenden Code in eine neue Header-Datei (z.B. BitIO.h) kopieren:&lt;br /&gt;
&lt;br /&gt;
=== Hilfsfunktionen als Inline-Methoden ===&lt;br /&gt;
Achtung: Wenn nur ein C Compiler verwendet wird, kennt dieser den Typ &amp;quot;bool&amp;quot; nicht, dieser muss dann vorher definiert werden!&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/**&lt;br /&gt;
 *  BitIO.h&lt;br /&gt;
 *	@author 	Andi Dittrich &amp;lt;http://andidittrich.de&amp;gt;&lt;br /&gt;
 *	@version	1.0&lt;br /&gt;
 *	@license	MIT Style X11 License&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;inttypes.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef BITIO_H_&lt;br /&gt;
#define BITIO_H_&lt;br /&gt;
&lt;br /&gt;
// set bit&lt;br /&gt;
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_SET(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target |= (1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// set clear&lt;br /&gt;
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_CLEAR(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target &amp;amp;= ~(1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// bit toogle&lt;br /&gt;
static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_TOGGLE(volatile uint8_t *target, uint8_t bit){&lt;br /&gt;
	*target ^= (1&amp;lt;&amp;lt;bit);&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
// set bit by boolean&lt;br /&gt;
static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable) __attribute__((always_inline));&lt;br /&gt;
static inline void BIT_BOOL_SET(volatile uint8_t *target, uint8_t bit, bool enable){&lt;br /&gt;
	if (enable){&lt;br /&gt;
		BIT_SET(target, bit);&lt;br /&gt;
	}else{&lt;br /&gt;
		BIT_CLEAR(target, bit);&lt;br /&gt;
	}&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif /* BITIO_H_ */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Hilfsfunktionen als C-Makro (nicht empfohlen) ===&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
/* Bit setzen */&lt;br /&gt;
#define set_bit(var, bit) ((var) |= (1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
 &lt;br /&gt;
/* Bit löschen */&lt;br /&gt;
#define clear_bit(var, bit) ((var) &amp;amp;= (unsigned)~(1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
 &lt;br /&gt;
/* Bit togglen */&lt;br /&gt;
#define toggle_bit(var,bit) ((var) ^= (1 &amp;lt;&amp;lt; (bit)))&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Bitmanipulation beim MSP430 ==&lt;br /&gt;
&lt;br /&gt;
Beim MSP430 und dessen Compilern sind die Bitnamen meist anders definiert. Und zwar nicht als Bitnummer, sondern als Bitmuster. Darum schreibt man dort die Bitzugriffe in C anders. Das kann auch bei anderen Mikrocontrollern bzw. C-Compilern so sein. Wichtig ist, dass man seine eignen Definitionen in der gleichen Weise wie der Compiler anlegt, um Verwirrung zu vermeiden, siehe [[Strukturierte Programmierung auf Mikrocontrollern]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Definition von Bitnamen in den Headerfiles des Compilers&lt;br /&gt;
&lt;br /&gt;
#define PD4 4               // Definition im AVR GCC als Bitnummer&lt;br /&gt;
#define PD5 5&lt;br /&gt;
&lt;br /&gt;
#define P14 (1&amp;lt;&amp;lt;4)          // Definition im MSP430 GCC als Bitmuster&lt;br /&gt;
#define P15 (1&amp;lt;&amp;lt;5)&lt;br /&gt;
&lt;br /&gt;
// Bitmanipulation im Programm&lt;br /&gt;
 &lt;br /&gt;
   DDRD = (1&amp;lt;&amp;lt;PD5) | (1&amp;lt;&amp;lt;PD4);   // AVR GCC&lt;br /&gt;
   P1DIR = P15 | P14;            // MSP430 GCC&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Siehe auch==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/179566#1729219 Forumsbeitrag:] Bits aus einem Array extrahieren&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/169509#1631439 Forumsbeitrag:] Bits für ein Schieberegister zusammenstellen, TLC5941&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/353071?goto=3947567#3947567 Forumsbeitrag:] TLC5947 und ATmega16 Bitmanipulation&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/15466?goto=107726#107720 Forumsbeitrag:] Bitreihenfolge ändern&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/23866?goto=new#177674 Forumsbeitrag:] Wie drehe ich eine Bitreihenfolge um?&lt;br /&gt;
* [http://gcc.gnu.org/onlinedocs/gcc-4.7.1/gcc/AVR-Built_002din-Functions.html AVR Build-in Functions], spezielle Funktion im avr-gcc zur schnellen Bitvertauschung, engl.&lt;br /&gt;
&lt;br /&gt;
[[Category:8051]]&lt;br /&gt;
[[Category:AVR-Arithmetik]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=MMC-_und_SD-Karten&amp;diff=81696</id>
		<title>MMC- und SD-Karten</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=MMC-_und_SD-Karten&amp;diff=81696"/>
		<updated>2014-02-19T21:18:36Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* DOs und DON&amp;#039;Ts bei der Ansteuerung */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;MMC- und SD-Speicherkarten lassen sich im [[SPI]]-Modus relativ einfach mit einem Mikrocontroller ansteuern. Prinzipiell gibt es zwischen SD-Card und MMC nicht viele Unterschiede, allerdings sind SD-Karten weiter verbreitet, in der Regel schneller als MMCs, und haben ein besser implementiertes SPI-Interface. Es existieren diverse Varianten (miniSD, microSD), die zur normalen SD-Card weitgehend kompatibel sind.&lt;br /&gt;
&lt;br /&gt;
Die Karte liest das anliegende Datenbit mit der steigenden Taktflanke ein, als SPI-Modi eignen sich somit Mode 0 (CPOL=0, CPHA=0) und Mode 3 (CPOL=1, CPHA=1) (siehe auch [[Serial Peripheral Interface]]). Bei MMCs ist der SPI-Modus nicht genau spezifiziert, somit kommt es durchaus mal vor dass der SPI-Modus je nach Karte unterschiedlich gewählt werden muss, oder dass die Karte überhaupt nicht zuverlässig funktioniert (siehe [http://www.mikrocontroller.net/forum/read-1-343528.html Beitrag im Forum]).&lt;br /&gt;
&lt;br /&gt;
== DOs und DON&#039;Ts bei der Ansteuerung ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Lasst euch nicht verrückt machen&#039;&#039;&#039; wenn es einfach nicht funktioniert, sondern probiert zu allererst mal eine SD-Karte eines anderen Herstellers aus. Die MMC-Implementierung für AVR von Elm Chan z.&amp;amp;nbsp;B. funktioniert mit SanDisk problemlos hat aber mit Platinum Karten ein Problem.&lt;br /&gt;
* Taktfrequenz bei der Initialisierung nicht höher als 400kHz&lt;br /&gt;
* Ein Pullup-Widerstand am Ausgang der MMC/SD Karte (DO) ist für eine saubere Initialisierung per SPI notwendig! [http://www.mikrocontroller.net/topic/112421#1001693 (Thread mit Erklärung dazu)]&lt;br /&gt;
* Ein Pullup-Widerstand an der Select-Leitung (/CS) schadet nicht und stellt sicher, dass die Karte erst mit Absicht selektiert wird.&lt;br /&gt;
* Nachdem die Karte deselektiert wurde (/CS auf high), die Taktleitung noch einige Male pulsen, damit die Karte DO hochohmig/tri-state schaltet (vgl. Chans Erläuterungen).&lt;br /&gt;
* Im SPI-Mode die nicht benutzten SD-Datenleitungen mit Pull-Ups versehen ([http://www.mikrocontroller.net/topic/86311#763460])&lt;br /&gt;
* Saubere Versorgung: Kein Dioden-Pfusch, mit dem eine vorhandene 5V Versorgung mittels in Reihe geschalteter Dioden auf irgendwas im Bereich 3V &amp;quot;geregelt&amp;quot; wird. Stattdessen einen guten 3,3V-Regler verwenden. Die Karte mag es nicht, wenn mehr als 60mV Ripple auf Vcc ist. LM317 oder LM1117-ADJ/-3.3 mit entspechenden Kondensatoren reicht zumindest bei Basteleien allemal.&lt;br /&gt;
* Sauberer Anschluss der Digitalschnittstelle: Spannungsteiler &amp;quot;verschleifen&amp;quot; die Signale bei hohen Frequenzen und die Übertragungsrate muss dann begrenzt werden. Also entweder ein [http://www.mikrocontroller.net/articles/Pegelwandler Pegelwandler] oder gleich an ein 3,3V I/O anschließen.&lt;br /&gt;
* Die Karten verfügen weder über einen Reset- noch einen Sleep-Anschluss. Moderne Karten reduzieren bei Nichtbenutzung ihren Stromverbrauch, einen vollständigen Reset kann man jedoch nicht per Software auslösen. Daher sollten die Karten per P-Channel-FET oder Spannungsregler/-wandler mit Enable-Funktion so angeschlossen werden, dass über Versorgung an/aus ein (Power-On-)Reset ausgelöst werden kann. Dabei darauf achten, dass vorhandene Pull-Up-Widerstände bei abgeschalteter Versorgung ebenfalls deaktiviert werden (vgl. z.&amp;amp;nbsp;B. Schaltplan für den Anschluss von SD-Card/MMC per SPI an AVR in Chans Beispielen. Link unten).&lt;br /&gt;
* Ist beabsichtigt die Speicherkarte im Betrieb auszutauschen, sollte darauf geachtet werden, dass einige Karten beim Einstecken einen relativ hohen Strombedarf haben. Dies kann einen kurzzeitigen Zusammenbruch der Spannungsversorgung verursachen, der zu undefinierten Zuständen führt (z.&amp;amp;nbsp;B. Reset eines Mikrocontrollers durch Ansprechen des Unterspannungsschutzes/Brown-Out-Detection). Abhilfe schafft eine Spule in Reihe zum Versorgungsanschluss (VDD) der Karte. In vielen Boards von Olimex werden dazu 470&amp;amp;nbsp;nH Festinduktivitäten verwandt.&lt;br /&gt;
* Guter Kontakt im Steckplatz, sehr gut eignen sich mit der Zange verbogene Stiftleisten, oft sieht es aus als ob es &amp;quot;passt&amp;quot;, aber es gibt doch keinen Kontakt, daher bei Fehlern: Immer Durchmessen! Auch zu erwähnen wären da alte ISA-Bus Buchsen, die auf jedem alten PC Mainboard drauf sind. Um sicher zu gehen, dass der Kontakt wirklich gut ist, sollte man aber trotzdem SD-Slots benutzen. Diese bekommt man u.a. bei CSD (günstig), Reichelt (teuer) oder aus alten Kartenlesern.&lt;br /&gt;
* Guter Kontakt #2: Was sich im übrigen auch sehr gut eignet sind Adapter von MiniSD auf normales SD-Format, um dann MiniSD zu benutzen. Wenn man eine Stiftleiste im 2.54mm-Format oder Lötnägel im selben Format auf der Platine hat, kann man daran wunderbar den SD-Kartenadapter anlöten. Das ist mechanisch recht stabil. Ein kleines Manko ist allerdings, daß dann eine Gold-Lötzinn-Legierung durch die vergoldeten Kontakte entsteht und das soll ja dem Lötzinn langfristig nicht sehr zuträglich sein. Aber für&#039;s Hobby funktioniert das wunderbar.&lt;br /&gt;
* &#039;&#039;&#039;Speziell PIC&#039;&#039;&#039;: Wird der C18 Compiler benutzt, so hat man in der Bibliothek die Funktion ReadSPI(). Diese darf nicht benutzt werden, da sie SSPBUF vor dem Lesevorgang mit 0x00 initialisiert. Die SD-Karte erwartet aber 0xff !! Man kann die Funktion aus der Bibliothek kopieren und SSPBUF = 0xff schreiben, dann gehts.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
||[[Bild:SD Steck Stift.jpg]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;sup&amp;gt;(Liefere Bild in besserer Qualität nach!)&amp;lt;/sup&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Bibliotheken zur Ansteuerung ==&lt;br /&gt;
&lt;br /&gt;
* [http://elm-chan.org/fsw/ff/00index_e.html ELM ChaN FatFs]  FAT(12,16,32)-Dateisystem. Klein und übersichtlich, hochoptimiert, frei auch für kommerzielle Anwendung. Beispiele für AVR, H8, LPC2k mit MCI u.a. enthalten (&amp;quot;samples&amp;quot;), neuere Versionen mit LFN-Unterstützung. Beispiel für AT91SAM7 inkl. DMA im Projekt [[ARM MP3/AAC Player]]. (siehe auch [http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/ M. Thomas&#039; ARM+SD/MMC Seite])&lt;br /&gt;
* [http://elm-chan.org/fsw/ff/00index_p.html ELM ChaN Petit FatFS] FAT(12,16,32)-Dateisystem. Sehr klein. Beispiele für AVR.&lt;br /&gt;
* [http://sourceforge.net/projects/efsl EFSL] FAT16/32-Dateisystem, unterstützt Partitionen und Superfloppys, Beispielcode für AVR, LPC2000 und AT91SAM7 enthalten (siehe auch [http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/ M. Thomas&#039; ARM+SD/MMC Seite])&lt;br /&gt;
* [http://www.holger-klabunde.de/avr/avrboard.htm#cf Holger Klabundes FAT16/32] mit Beispielen für AVR MMC/SD und CF, LPC2k mit SPI&lt;br /&gt;
* libfat aus dem [http://sourceforge.net/projects/devkitpro devkitpro-Projekt] u.a. LFN-Unterstützung.&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-4-125350.html MMC-Ansteuerung mit FAT16 von Ulrich Radig]&lt;br /&gt;
* [http://www.zws.com/products/dosfs/index.html DOSFS Free FAT12/FAT16/FAT32 Filesystem] &amp;quot;DOSFS is a free FAT-compatible filesystem intended for fairly low-end embedded applications. Intended target systems would be in the ballpark of 1K RAM, 4K ROM or more&amp;quot;.&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/48481 MMC/SD-Karte mit FAT16 an AVR] von Roland Riegel&lt;br /&gt;
* [ftp://ftp.circuitcellar.com/pub/Circuit_Cellar/2005/176/Sham176.zip Circuit Cellar FAT16 MMC/SD] mit MMC/SD Hardwaretreiber für MSP430&lt;br /&gt;
* [http://www.analog.com &amp;quot;Implementing FAT32 File Systems on ADSP-BF533 Blackfin Processors&amp;quot;] Application Note und Code von ADI&lt;br /&gt;
* [http://www.atmel.com/dyn/products/tools.asp?family_id=682 FAT-Code in Atmel&#039;s AVR32 UC3 Software-Library]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/FAT32 AVR FAT16/32] Bibliothek mit Wiki. Unterstützt LFN und Ordner Rekursiv löschen. SVN für neuste Version.&lt;br /&gt;
* [http://www.embedded-os.de/index.html?pcfat_port.htm pC/FAT driver] &amp;quot;using SPI for sector read/write to MMC/MMCplus/HD-MMC/M-Bridge/SD/SDHC-cards on different platforms&amp;quot;&lt;br /&gt;
* [http://www.dharmanitech.com/2009/01/sd-card-interfacing-with-atmega8-fat32.html SD Card Interfacing with ATmega8] (FAT32 implementation) by CC Dharmani&lt;br /&gt;
* [http://www.blacksphere.co.nz/main/openfat OpenFAT]: &amp;quot;OpenFAT is a FAT filesystem implementation intended for use with embedded microcontrollers in small systems. (...) OpenFAT is licensed under the GPL, version 3.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Allgemeine Informationen ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.digitalspirit.org/file/index.php/obj/docs/sd/ Datenblätter] ( [http://www.digitalspirit.org/file/index.php/obj-download/docs/sd/ProductManualSDCardv2.2final.pdf SD Card Product Manual 2.2] )&lt;br /&gt;
* [http://elm-chan.org/docs/mmc/mmc_e.html ELM ChaN - How to Use an MMC]&lt;br /&gt;
* [http://elm-chan.org/fsw/ff/00index_e.html ELM ChaN - FatFs Generic FAT File System Module]&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/list-1-1.html?filter=MMC*+SD Beiträge zum Thema MMC/SD im Forum (ca. 200 Threads)]&lt;br /&gt;
* [http://www.shop.display3000.com/elektronikmodule/sd-speicherkartenplatine.html Weiter unten im Text (runterscrollen) gibt es interessante Oszi-Bilder zu den oft genannten Spannungsteilern oder Transistorlösungen als Pegelwandler]&lt;br /&gt;
* [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=2680&amp;amp;dDocName=en547784 Microchip Memory Disk Drive System mit FAT32 und SDHC Unterstützung]&lt;br /&gt;
* [http://www.ifas.htwk-leipzig.de/easytoweb/download/D&amp;amp;E_11_2006_Anbindung_von_SD-Karten.pdf Gute Beschreibung der SDIO-Architektur und wie man eine SD-Karte mit ARM bzw. AVR benutzt]&lt;br /&gt;
&lt;br /&gt;
== Bauteile ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.instructables.com/id/EZD6Q18LYGES1762SJ/ DIY SD-Card Fassung aus einem alten Floppy Kabel]&lt;br /&gt;
* [http://www.watterott.com/index.php?page=search&amp;amp;page_action=query&amp;amp;desc=on&amp;amp;sdesc=on&amp;amp;keywords=multicomp&amp;amp;x=0&amp;amp;y=0 Halter für SD-Karten]&lt;br /&gt;
* [http://www.shop.display3000.com/elektronikmodule/sd-speicherkartenplatine.html günstige Komplettlösung mit bidirektionalem Pegelwandler, Spannungsregler, Kartenhalter]&lt;br /&gt;
&lt;br /&gt;
== Projekte ==&lt;br /&gt;
&lt;br /&gt;
* [http://retromaster.wordpress.com/ufe/ Ultimate Floppy Emulator] von Retromaster (PIC32 @ 80 Mhz, 16 Mb SDRAM)&lt;br /&gt;
&lt;br /&gt;
[[Category:Bauteile]]&lt;br /&gt;
[[Category:Datenübertragung]]&lt;br /&gt;
[[Kategorie:Speicher und Dateisysteme]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=ARM_Cortex_Mikrocontroller&amp;diff=79920</id>
		<title>ARM Cortex Mikrocontroller</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=ARM_Cortex_Mikrocontroller&amp;diff=79920"/>
		<updated>2013-12-08T23:15:30Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* IDEs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Firma ARM stellt selbst keine Prozessoren/Controller her, sondern entwickelt nur sogenannte &amp;quot;IP-Cores&amp;quot;, die von Herstellern wie Atmel, Infineon, NXP, TI und vielen anderen lizenziert werden. Diese Hersteller ergänzen den Core um Speicher und Peripherie. Der Vorteil dieses Modells ist, dass dadurch sehr viele Prozessoren mit unterschiedlichster Ausstattung verfügbar sind, die alle mit dem selben Befehlssatz (und damit dem selben Compiler) programmierbar sind.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;In diesem Artikel geht es NUR um die ARM Cortex-M Microcontroller, nicht jedoch um ARM [https://www.mikrocontroller.net/articles/Cortex-A Cortex-A] Prozessoren.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Befehlssatz ===&lt;br /&gt;
Allen ARM-Cores gemeinsam ist die 32 Bit RISC-Architektur. Manche ARM-Cores besitzen neben dem 32 Bit ARM-Befehlssatz noch einen zusätzlichen, kleineren 16 Bit-Befehlssatz (&#039;&#039;&#039;Thumb&#039;&#039;&#039;-Modus, erkennbar am &#039;&#039;&#039;T&#039;&#039;&#039; in der Bezeichnung, z.&amp;amp;nbsp;B. ARM7&#039;&#039;&#039;T&#039;&#039;&#039;DMI). Der Vorteil des Thumb-Befehlssatzes ist der geringere Platzbedarf des Codes; der Nachteil ist die etwas niedrigere Geschwindigkeit. Die ARMv7M-Architektur (man beachtet das &#039;&#039;&#039;v&#039;&#039;&#039;), also z.&amp;amp;nbsp;B. Controller mit Cortex-M3-Kern, unterstützen ausschließlich den Thumb2-Befehlssatz.&lt;br /&gt;
&lt;br /&gt;
== ARM Cortex M ==&lt;br /&gt;
&lt;br /&gt;
Seit wenigen Jahren sind ARM-basierte Mikrocontroller erhältlich, die Aufgrund der vergleichbar einfachen Beschaltung und mit einer &#039;&#039;&#039;deutlich&#039;&#039;&#039; größeren Power eine echte Alternative zu 8-Bit-Controllern darstellen. &lt;br /&gt;
&lt;br /&gt;
Es gibt folgende Varianten dieses Mikrocontroller &amp;quot;Kerns&amp;quot;,&lt;br /&gt;
aufgeführt vom Energieeffizientesten zum Leistungsfähigsten:&lt;br /&gt;
&lt;br /&gt;
=== ARM Cortex M0 ===&lt;br /&gt;
Als günstigere Variante gibt es die Cortex-M0 Cores mit deutlich kleinerem Befehlssatz, wie z.B. den &#039;&#039;&#039;[[LPC1xxx]]&#039;&#039;&#039;. Diese&lt;br /&gt;
werden beispielsweise in folgenden Controllern eingesetzt:&lt;br /&gt;
&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1588.jsp?WT.ac=fp_may12_stm32f0 STM32F0] von [http://www.st.com STMicro], siehe &#039;&#039;&#039;[[STM32|STM32 hier im Wiki]]&#039;&#039;&#039;&lt;br /&gt;
* [http://ics.nxp.com/products/lpc1000/lpc11xx/ LPC11xx] von [http://www.nxp.com NXP], siehe &#039;&#039;&#039;[[LPC1xxx|LPC1xxx hier im Wiki]]&#039;&#039;&#039;&lt;br /&gt;
* [http://www.infineon.com/XMC1000 XMC1000] von [http://www.infineon.com Infineon], siehe &#039;&#039;&#039;[[XMCxxxx|XMCxxxx hier im Wiki]]&#039;&#039;&#039;&lt;br /&gt;
* [http://www.nuvoton.com/NuvotonMOSS/Community/ProductInfo.aspx?tp_GUID=5dbf7d7a-b6df-4fe1-91c9-063449500ce7 NuMicro-Controller] von nuvoton (ex Winbond), laut Datenblatt mit 2.5-5.5V Betriebssspannung!!!&lt;br /&gt;
Für die M0-Familie ist für den LPC1xxx bereits eine &#039;&#039;&#039;[http://www.mikrocontroller.net/articles/Codebase_f%C3%BCr_LPC1xxx#Allgemeine_Informationen_zum_Aufbau_der_Code_Base Code-Base]&#039;&#039;&#039;  und ein preisgünstiges &#039;&#039;&#039;[http://www.mikrocontroller.net/wikisoftware/index.php?title=LPC1xxx_Entwicklungskit_LPCXpresso Entwicklungskit]&#039;&#039;&#039; vorhanden.&lt;br /&gt;
&lt;br /&gt;
=== ARM Cortex M0+ ===&lt;br /&gt;
Inzwischen gibt es auch eine optimierte Version des Cortex-M0 - die Cortex-M0+ Cores. Diese können (optional) einige Features der Cortex-M3 Serie beeinhalten, wie z.B eine MPU:&lt;br /&gt;
&lt;br /&gt;
* [http://www.energymicro.com/products/efm32-zero-gecko-microcontroller-family EFM32 Zero Gecko] von [http://www.energymicro.com Silicon Labs (ehemals Energy Micro)], siehe &#039;&#039;&#039;[[EFM32|EFM32 hier im Wiki]]&#039;&#039;&#039;&lt;br /&gt;
* [http://www.nxp.com/products/microcontrollers/cortex_m0plus/lpc800/ LPC8xx] von [http://www.nxp.com NXP]&lt;br /&gt;
* [http://www.freescale.com/webapp/sps/site/taxonomy.jsp?code=KINETIS_L_SERIES Kinetis L-Serie] und [http://www.freescale.com/webapp/sps/site/taxonomy.jsp?code=KINETIS_M_SERIES Kinetis M-Serie] von [http://www.freescale.com/ Freescale]&lt;br /&gt;
* [http://www.fujitsu-fm-family.com/products/fm0.html angekündigte FM0+ Familie] von [http://www.fujitsu.com/emea/services/microelectronics Fujitsu]&lt;br /&gt;
&lt;br /&gt;
=== ARM Cortex M3 ===&lt;br /&gt;
Eine sehr aktuelle Variante des ARM ist die Cortex-M3 Familie die &#039;&#039;&#039;[[LPC1xxx]]&#039;&#039;&#039;, als eine echte Konkurrenz zu 8- und 16-Bit Mikrocontrollern wie dem [[AVR]] und [[MSP430]] gedacht ist. Der Cortex-M3 enthält einige Verbesserungen gegenüber dem ARM7TDMI-Kern und ist bereits dabei diesen zu ersetzen. &lt;br /&gt;
Controllerfamilien dieser Klasse sind:&lt;br /&gt;
&lt;br /&gt;
* [http://www.energymicro.com/products/efm32-tiny-gecko-microcontroller-family EFM32 Tiny Gecko],[http://www.energymicro.com/products/efm32-gecko-microcontroller-family EFM32 Gecko] sowie [http://www.energymicro.com/products/efm32-leopard-gecko-microcontroller-family EFM32 Leopard Gecko] von [http://www.energymicro.com Silicon Labs (ehemals Energy Micro)] , siehe &#039;&#039;&#039;[[EFM32|EFM32 hier im Wiki]]&#039;&#039;&#039;&lt;br /&gt;
* [http://www.nxp.com LPC13xx/LPC17xx/LPC18xx] von NXP oder die inzwischen schon sehr ausführliche, siehe &#039;&#039;&#039;[[LPC1xxx|LPC1xxx hier im Wiki]]&#039;&#039;&#039;&lt;br /&gt;
* [http://www.ti.com/lsds/ti/microcontroller/tiva_arm_cortex/c_series/tm4c_arm_cortex-m4/overview.page TIVA] von [http://www.ti.com Texas Instruments] (vormals Stellaris, vormals Luminary Micro)&lt;br /&gt;
* [http://www.atmel.com/products/at91/sam3landing.asp?family_id=605 AT91SAM3] von Atmel&lt;br /&gt;
* [http://www.st.com/internet/mcu/family/141.jsp STM32] Baureihen [http://www.st.com/internet/mcu/subclass/1169.jsp F1]/[http://www.st.com/internet/mcu/subclass/1520.jsp F2]/[http://www.st.com/internet/mcu/subclass/1376.jsp L1]/[http://www.st.com/internet/mcu/subclass/1377.jsp W] von STMicroelectronics , siehe &#039;&#039;&#039;[[STM32|STM32 hier im Wiki]]&#039;&#039;&#039;&lt;br /&gt;
* [http://www.toshiba-components.com/microcontroller/TMPM330.html TMPM330] von Toshiba&lt;br /&gt;
* [http://www.spansion.com/Products/microcontrollers/32-bit-ARM-Core/fm3/Pages/FM3-family.aspx FM3] von [http://www.spansion.com Spansion] (vormals Fujitsu)&lt;br /&gt;
* [http://www.infineon.com/XMC4000 XMC4000] von Infineon, siehe &#039;&#039;&#039;[[XMCxxxx | XMC hier im Wiki]]&#039;&#039;&#039;&lt;br /&gt;
* [https://www.silabs.com/products/mcu/Pages/ARM-32bit-microcontroller.aspx SiM3U1xx] von Silabs&lt;br /&gt;
* [http://www.holtek.com.tw/english/products/32bit_flashmcu.htm HT32] von Holtek Semiconductor&lt;br /&gt;
&lt;br /&gt;
Für den LPC1xxx ist bereits eine &#039;&#039;&#039;[http://www.mikrocontroller.net/articles/Codebase_f%C3%BCr_LPC1xxx#Allgemeine_Informationen_zum_Aufbau_der_Code_Base Code-Base]&#039;&#039;&#039;  und ein preisgünstiges &#039;&#039;&#039;[[LPC1xxx_Entwicklungskit_LPCXpresso]]&#039;&#039;&#039; vorhanden.&lt;br /&gt;
&lt;br /&gt;
=== ARM Cortex M4 ===&lt;br /&gt;
Als hoch performante Variante gibt es dann noch die Cortex-M4 Cores welche teilweise mit einer FPU ausgestattet sind. &lt;br /&gt;
&lt;br /&gt;
Diese werden beispielsweise in folgenden Controllern eingesetzt:&lt;br /&gt;
&lt;br /&gt;
* [http://www.energymicro.com/products/efm32-wonder-gecko-microcontroller-family EFM32-Wonder Gecko] von [http://www.energymicro.com Silicon Labs (ehemals Energy Micro)], siehe &#039;&#039;&#039;[[EFM32|EFM32 hier im Wiki]]&#039;&#039;&#039;&lt;br /&gt;
* [http://www.nxp.com LPC43xx] von NXP (Dual Core)&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1605.jsp STM32F3] von [http://www.st.com STMicro], siehe &#039;&#039;&#039;[[STM32|STM32 hier im Wiki]]&#039;&#039;&#039;&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1521.jsp?WT.ac=p2_bn_jun12_stm32f4series STM32F4] von [http://www.st.com STMicro], siehe &#039;&#039;&#039;[[STM32|STM32 hier im Wiki]]&#039;&#039;&#039;&lt;br /&gt;
* [http://www.ti.com/lsds/ti/microcontroller/tiva_arm_cortex/c_series/tm4c_arm_cortex-m4/overview.page Tiva C Series, TM4C] von [http://www.ti.com Texas Instruments]. Früher nannte Texas Instruments diese Controller &#039;&#039;Stellaris LM4F Series&#039;&#039;. 2013 begann TI mit einer große Umbenennung, bei der sogar neue Typenbezeichnung vergeben wurden. So wurde zum Beispiel aus dem LM4F230H5QR der TM4C123GH6PM. Gleichzeitig begann TI die Bezeichnung &#039;&#039;Stellaris&#039;&#039; aus Datenblättern, Software-Bibliotheken und Ähnlichem zu entfernen und durch &#039;&#039;Tiva&#039;&#039; zu ersetzen. Siehe auch [http://www.ti.com/lit/an/spma050a/spma050a.pdf].&lt;br /&gt;
* [http://www.infineon.com/XMC4000 XMC4000] von [http://www.infineon.com Infineon],  siehe &#039;&#039;&#039;[[XMCxxxx|XMCxxxx hier im Wiki]]&#039;&#039;&#039;, [https://www.mikrocontroller.net/articles/XMC4500 Artikel zum XMC4500]&lt;br /&gt;
* [http://www.spansion.com/Products/microcontrollers/32-bit-ARM-Core/fm4/Pages/default.aspx FM4] von [http://www.spansion.com Spansion] (vormals Fujitsu)&lt;br /&gt;
* [http://www.atmel.com/products/at91/sam4landing.asp?family_id=605 AT91SAM4] von Atmel&lt;br /&gt;
&lt;br /&gt;
== ARM7 ==&lt;br /&gt;
Eine schon etwas ältere Controller-Familie ist der &#039;&#039;&#039;ARM7&#039;&#039;&#039;TDMI.  Core. Controllerfamilien dieser Klasse sind:&lt;br /&gt;
* NXP (ehemals Philips) [[LPC2000]] &lt;br /&gt;
* Atmel [[AT91SAM]]7&lt;br /&gt;
* Analog Devices [[ADuC7xxx]]&lt;br /&gt;
* [http://focus.ti.com/mcu/docs/mcuprodoverview.tsp?sectionId=95&amp;amp;tabId=203&amp;amp;familyId=454 Texas Instruments TMS470]&lt;br /&gt;
* SAMSUNG S3C24x0 [http://www.samsung.com/global/business/semiconductor/productInfo.do?fmly_id=229&amp;amp;partnum=S3C2410]&lt;br /&gt;
* STR7xx von ST Microelectronics [http://www.st.com/mcu/inchtml-pages-str7.html]&lt;br /&gt;
* und viele weitere&lt;br /&gt;
&lt;br /&gt;
Mehr Informationen zur ARM-Architektur finden sich in der [http://de.wikipedia.org/wiki/ARM-Architektur Wikipedia], weiterführende Links in der [[Linksammlung#ARM|Linksammlung]].&lt;br /&gt;
&lt;br /&gt;
== Compiler ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Basic ===&lt;br /&gt;
Von Mikroe gibt es Basic&lt;br /&gt;
http://www.mikroe.com/mikrobasic/arm/&lt;br /&gt;
&lt;br /&gt;
=== Pascal ===&lt;br /&gt;
Von Mikroe gibt es Pascal&lt;br /&gt;
http://www.mikroe.com/mikropascal/arm/&lt;br /&gt;
&lt;br /&gt;
=== [[ARM_GCC|GCC]] ===&lt;br /&gt;
&lt;br /&gt;
Einer der beliebtesten Compiler für ARM-Prozessoren ist der GCC. Er kann sowohl ARM- als auch Thumb-Code erzeugen. Mehr dazu unter [[ARM GCC]].&lt;br /&gt;
&lt;br /&gt;
=== IDEs ===&lt;br /&gt;
&lt;br /&gt;
Kostenlose Entwicklungsumgebungen:&lt;br /&gt;
* [http://www.coocox.org/CooCox_CoIDE.htm CooCox IDE] (Eclipse basierend)&lt;br /&gt;
* Für das MBED Board (mbed NXP LPC1768) ist ein kostenloser Onlinecompiler verfügbar (ARM Realview), der sich durch die Bereitstellung von sehr leistungsfähigen Funktionen (API&#039;s) auszeichnet. Den praktischen Nutzen für eine professionelle Anwendung mag man zu Recht in Frage stellen. Um mal schnell was zu programmieren ist das Ding unschlagbar, es ist faktisch keine Installation oder Einarbeitung in eine IDE nötig.&lt;br /&gt;
* [http://www.emide.org/ emIDE] Windows, komplette Visual Studio artige Entwicklungsumgebung (basierend auf Code::Blocks) mit GCC und Debugger (Unterstützung für Adapter von Segger) &amp;lt;!-- Projekt eines Segger Mitarbeiters --&amp;gt;&lt;br /&gt;
* [http://www.isystem.com/products/software/winidea-open winIDEAOpen]&lt;br /&gt;
* Die Fa. iSystem stellt mit der winIDEAOpen nun eine kostenlose Entwicklungsumgebung für alle Cortex-M Bauteile zur Verfügung. Als Compiler wird der GNU GCC verwendet und auch gleich mitinstalliert. Die IDE ist recht intuitiv und mit einer umfangreichen Hilfe ausgestattet. Das Ganze funktioniert mit dem &amp;lt;u&amp;gt;GCC ohne Codesize Limit&amp;lt;/u&amp;gt; und auch ein Testwerkzeug (testIDEA) ist mit integriert. Hardwareseitig werden neben dem iSystem iTag50 [http://www.isystem.com/products/hardware/cortex-debugger/itag] auch die Segger J-Link Debug Probes sowie der ST-Link von ST unterstützt. Auf der Webseite von iSystem sind auch einige schöne Beispielprojekte für diverse Boards zu finden [http://www.isystem.com/download/winideaopen]. Demnächst soll noch die Unterstützung für die ARM und IAR Compiler hinzuzkommen. Hier gehts zum &#039;&#039;[http://www.isystem.com/download/winideaopen Download]&#039;&#039;&#039;&lt;br /&gt;
* Für die LPC Prozessorfamilie ist eine &amp;lt;u&amp;gt;kostenlose&amp;lt;/u&amp;gt; C/C++ Entwicklungsumgebung  von &#039;&#039;&#039;[http://www.code-red-tech.com/lpcxpresso.php  code-red]&#039;&#039;&#039; erhältlich. Die auf Eclipse basierende Entwicklungsumgebung ist nach der Installation bis 8k freigeschaltet und nach einer einfachen und kostenlosen Registrierung für 128kB. Die IDE ist auch für &#039;&#039;&#039;[http://support.code-red-tech.com/CodeRedWiki/redlib_v2_notes Linux]&#039;&#039;&#039; verfügbar. Hier die &#039;&#039;&#039;[http://www.mikrocontroller.net/articles/Installationsanleitung_C-Entwicklungsumgebung_f%C3%BCr_LPC1xxx_von_Code_Red Installationsanleitung]&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Kommerzielle Entwicklungsumgebungen (zum Teil kostenlos mit Einschränkungen) für ARM-basierte Mikrocontroller sind z.&amp;amp;nbsp;B. :&lt;br /&gt;
*[http://www.code-red-tech.com/red-suite-4-nxp.php Code-Red (Eclipse basierend für mehr als 128k)]&lt;br /&gt;
*[http://rowley.co.uk/arm/ Crossworks ARM] (GCC-basiert, Windows, Mac OS und Linux)&lt;br /&gt;
* [http://www.cosmicsoftware.com/download_cortex_64k.php Cosmic Software] 64k free (Windows)&lt;br /&gt;
* [http://www.iar.com/ewarm/ IAR Embedded Workbench for ARM] (Windows)&lt;br /&gt;
* [http://www.keil.com/arm/ MDK-ARM von Keil/ARM] (Windows).&lt;br /&gt;
&lt;br /&gt;
== JTAG/SWD ==&lt;br /&gt;
&lt;br /&gt;
Alle ARM-basierten Prozessoren verwenden ein einheitliches [[JTAG]]-Interface, über das Debugging und Speicherzugriff erfolgen kann. Nicht standardisiert sind allerdings die Verfahren zum Beschreiben des Flash-ROMs, deshalb muss man beachten ob die verwendete JTAG-Software Programmierroutinen für den jeweiligen Controller besitzt.&lt;br /&gt;
&lt;br /&gt;
Es gibt Mikrocontroller (z.B. [[EFM32]] von [https://www.energymicro.com Energy Micro]) welche NUR über SWD (Serial Wire Debugg) programmiert werden können.&lt;br /&gt;
&lt;br /&gt;
=== Günstige Beispiele zum Starten ===&lt;br /&gt;
Ein einfacher JTAG-Adapter für den Parallelport ist der &amp;quot;Wiggler&amp;quot;-kompatible, den man selbst bauen kann oder z.&amp;amp;nbsp;B. im [http://shop.embedded-projects.net/index.php?module=artikel&amp;amp;action=artikel&amp;amp;id=48 Embedded Projects Shop] für &amp;amp;euro; 10,00 bestellen kann. Als Software lässt sich unter Windows und Linux [http://openocd.berlios.de/ OpenOCD] (zusammen mit [[GDB]]) oder [http://rowley.co.uk Crossworks ARM] verwenden. &lt;br /&gt;
&lt;br /&gt;
Für USB gibt es [http://shop.embedded-projects.net/index.php?module=artikel&amp;amp;action=artikel&amp;amp;id=436 hier] einen ebenfalls OpenOCD-kompatiblen JTAG-Adapter zum Preis von ca 45€.&lt;br /&gt;
&lt;br /&gt;
Von NXP sind preiswerte Entwicklungskits (ca. 25€ für Evaluation-Board incl. USB-JTAG-/-SWD-Programer und Debugger) erhältlich z.B. &#039;&#039;&#039;[http://www.watterott.com/index.php?page=search&amp;amp;keywords=LPCXpresso&amp;amp;cat=&amp;amp;mnf=&amp;amp;x=0&amp;amp;y=0 Watterott]&#039;&#039;&#039;. Siehe dazu auch die Dokumentation von NXP zu den &#039;&#039;&#039;[http://www.nxp.com/documents/leaflet/75016842.pdf LPCXpresso-Entwicklungskits]&#039;&#039;&#039; (PDF), oder diese &#039;&#039;&#039;[http://www.mikrocontroller.net/wikisoftware/index.php?title=LPC1xxx_Entwicklungskit_LPCXpresso Beschreibung]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Von ST gibt es günstige Entwicklungskits (ca. 20€), mit integriertem ST-Link (Debugger). Zum Beispiel das [http://www.st.com/stm32f4-discovery STM32F4 Discovery Board].&lt;br /&gt;
&lt;br /&gt;
Von Energymicro gibt es [http://www.energymicro.com/tools/efm32-starter-kits Starter Kits] mit integriertem J-Link (Debugger) ab ca. 50 € z.B. das [http://www.energymicro.com/tools/efm32-tiny-gecko-starter-kit EFM32 Tiny Gecko Starter Kit] bei [http://de.mouser.com/ProductDetail/Energy-Micro/EFM32-TG-STK3300/?Energy-Micro/EFM32-TG-STK3300/&amp;amp;qs=sGAEpiMZZMvFPGEOwQcrYyZeaSbmjQvRx7NKUweLQtQ= Mouser]&lt;br /&gt;
&lt;br /&gt;
Der [http://www.segger.com/cms/jlink.html J-Link]-&amp;quot;Emulator&amp;quot; von Segger wird von vielen Softwarepaketen unterstützt und ist für den &amp;quot;nicht-kommerziellen&amp;quot; Einsatz von Studenten, Funkamateuren und Hobby-Bastler für ca. €50.- erhältlich (J-Link-Edu). Sein Umfang ist dabei auf das Flashen des Speichers und das Debuggen beschränkt. Die Trace-Option wie sie bei der PRO-Variante zur Verfügung steht, ist nicht vorhanden. Für den Preis (05/2013) bekommt man jedoch ein ausgewachsenes Werkzeug mit breiter Unterstützung und der Möglichkeit sowohl SWD als auch JTAG in einem Gerät vereint zu haben.&lt;br /&gt;
&lt;br /&gt;
Der ULINK2 von Keil/ARM ist ebenfalls ein wirklich gutes Gerät. Leider ist er nicht ganz so günstig und seine Zusammenarbeit beschränkt sich auf die Arm/Keil IDE µVision. Er benötigt jedoch keine speziellen USB-Treiber sondern nutzt geschickt die Funktionalität der HID-Treiber des Betriebssystems. Das macht ihn sofort auf jedem Windows-Betriebssystem einsatzbereit.&lt;br /&gt;
&lt;br /&gt;
Als Alternative zum Beschreiben des Flash über JTAG ist oft ein serieller [[Bootloader]] im Controller enthalten. Bei ST werden sie über einen speziellen Pin der MPU aktiviert und sind dank Kompression und das intelligente entfernen redundanter Information, bei der Übertragung genauso schnell wie JTAG/SWD Adapter.&lt;br /&gt;
&lt;br /&gt;
== CMSIS - ARM Cortex Software Libraries  ==&lt;br /&gt;
&lt;br /&gt;
CMSIS - Cortex Microcontroller Software Interface Standard&lt;br /&gt;
 &lt;br /&gt;
Der ARM Cortex Microcontroller Software Interface Standard (CMSIS) ist ein herstellerunabhängiger Hardware Abstraction Layer für die Cortex-M-Prozessor -Serie. Die CMSIS ermöglicht konsistente und einfache Software-Schnittstellen für den Prozessor und die Peripherie, und vereinfacht damit die Software-Wiederverwendung. &lt;br /&gt;
&lt;br /&gt;
Die CMSIS besteht aus folgenden Komponenten:&lt;br /&gt;
&lt;br /&gt;
* CMSIS-CORE: Bietet eine Schnittstelle zum Cortex-M0, Cortex-M3, Cortex-M4, SC000 und SC300-Prozessoren und Peripherie-Register&lt;br /&gt;
* CMSIS-DSP: DSP-Bibliothek mit über 60 Funktionen in Festkomma-(fractional q7, q15, q31) und single precision floating-point (32-bit)-Implementierung&lt;br /&gt;
* CMSIS-RTOS API: Standardisierte Programmierschnittstelle für Echtzeit-Betriebssysteme für Thread-Steuerung, Ressourcen-und Zeitmanagement&lt;br /&gt;
* CMSIS-SVD: System View Beschreibung -  XML-Dateien, die die Programmiereransicht des kompletten Mikrocontroller-Systems einschließlich Peripheriegeräte enthalten&lt;br /&gt;
&lt;br /&gt;
Der Standard ist für Cortex-M-Mikrocontroller skalierbar: Von der  kleinsten 4 KB MCU bis zu MCUs mit anspruchsvoller Kommunikations-Peripherie wie Ethernet oder USB. Der Speicherbedarf für die Core Peripheral Funktionen bedarf weniger als 1 KB-Code und weniger als 10 Bytes RAM.&lt;br /&gt;
&lt;br /&gt;
Beispiele:&lt;br /&gt;
&lt;br /&gt;
* Software Beispiele von [http://www.energymicro.com/downloads/application-notes Energy Micro] basierend auf CMSIS&lt;br /&gt;
&lt;br /&gt;
Mehr Informationen unter:&lt;br /&gt;
&lt;br /&gt;
* [http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php ARM CMSIS Webseite]&lt;br /&gt;
&lt;br /&gt;
== Freie Software ==&lt;br /&gt;
&lt;br /&gt;
=== ARM/XSCALE/CORTEX Instruction Set Simulator ===&lt;br /&gt;
&lt;br /&gt;
Die Firma Lauterbach bietet unter der Artikelnummer LA-8809 einen Instruction Set Simulator für ARM Cores an. Die Demoversion ist zur Evaluierung kostenlos. Einschränkungen bestehen in der Anzahl der zu ladenen Debugsymbole. Der Simulator unterstützt alle gängigen ARM Derivate und lädt alle üblichen Debugformate, wie die des RealView,  IAR und TI Compilers, oder der freien GCC Tools.&lt;br /&gt;
&lt;br /&gt;
Zum Simulator gibt es entsprechende zugehörige Debugtools, die allerdings käuflich zu erwerben sind.&lt;br /&gt;
&lt;br /&gt;
Weblinks: &lt;br /&gt;
[[http://www.lauterbach.com/frames.html?dwnload.html Download area mit ARM/XSCALE/CORTEX Simulator]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [[Linksammlung#ARM|Linksammlung (Abschnitt ARM)]]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/LPC1xxx Beschreibung der LPC1xxx-Familie]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/LPC1xxx_Entwicklungskit_LPCXpresso LPCXpresso-Entwicklungskit]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/Installationsanleitung_C-Entwicklungsumgebung_f%C3%BCr_LPC1xxx_von_Code_Red Installationsanleitung zur IDE von Code-Red]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/Codebase_f%C3%BCr_LPC1xxx LPC1xxx Codebase]&lt;br /&gt;
* [[ARM-elf-GCC-Tutorial]]&lt;br /&gt;
* [[AVR32]]&lt;br /&gt;
* [[Blackfin]]&lt;br /&gt;
* [[AT91SAM9260]]&lt;br /&gt;
* [[STM32]]&lt;br /&gt;
* [[JTAG]]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/EFM32 EFM32]&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://embdev.net/forum/arm-gcc ARM-GCC Forum] im englischsprachigen &amp;quot;Ableger&amp;quot; von microcontroller.net embdev.net u.a. für WinARM, Yagarto, CS Codebench&lt;br /&gt;
* [http://infocenter.arm.com/help/index.jsp Infocenter von ARM Ltd.]&lt;br /&gt;
* [http://www.open-research.org.uk/ARMuC/ ARMuC ARM microcontroller Wiki]&lt;br /&gt;
* [http://chaosradio.ccc.de/cre151.html Chaosradio Express - Die ARM-Architektur]&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
*ARM Systems Developer&#039;s Guide (2004) ISBN 1558608745 [http://books.google.de/books?id=HKKUkDQE17QC&amp;amp;output=html Im Buch blättern] [http://www.mkp.com/companions/defaultindividual.asp?isbn=9781558608740 Programmbeispiele aus dem Buch, u.a. FFT, FIR/IIR-Filter, Division, Wurzel]&lt;br /&gt;
*ARM Assembly Language - an Introduction (2007) ISBN 1847536964 [http://books.google.de/books?id=8KJX5R8mMvsC&amp;amp;output=html Im Buch blättern]   [http://www.lulu.com/content/1172076 Verlagsseite &amp;quot;Book on demand&amp;quot;]&lt;br /&gt;
*ARM Rechnerarchitekturen für System-on-Chip-Design (2002) ISBN 3826608542&lt;br /&gt;
*Co-Verification of Hardware and Software for Arm Soc Design (2004) ISBN 0750677309&lt;br /&gt;
*ARM System-on-Chip Architecture (2000) ISBN 0201675196 [http://books.google.de/books?id=J_Fu_YTVD9gC&amp;amp;printsec=frontcover&amp;amp;output=html&amp;amp;source=gbs_summary_r&amp;amp;cad=0 Im Buch blättern]&lt;br /&gt;
*ARM Architecture Reference Manual ISBN 0201737191 [http://books.google.de/books?id=O5G-6WX1xWsC&amp;amp;printsec=frontcover&amp;amp;output=html&amp;amp;source=gbs_summary_r&amp;amp;cad=0 Im Buch blättern]&lt;br /&gt;
*Messen, Steuern und Regeln mit ARM-Mikrocontrollern ISBN 3772340172 [http://books.google.de/books?id=TKs4kN-zNYQC&amp;amp;output=html im Buch blättern]&lt;br /&gt;
*Programming Arm Microcontrollers: Using C and the Lpc2100 Family (2005? /ab 1. Dezember 2008) ISBN 0321263359&lt;br /&gt;
*Arm Assembly: Fundamentals and Techniques (ab 1. März 2009) ISBN 1439806101&lt;br /&gt;
*Reliable Embedded Systems: Using 8051 and ARM Microcontrollers (2007) ISBN 0321252918 600 Seiten mit CD [http://vig.pearsoned.co.uk/catalog/academic/product/0,1144,0321252918-TOC,00.html Inhaltsverzeichnis]&lt;br /&gt;
* C und C++ für Embedded Systems (u.a. ARM Cortex-M3) mitp-Verlag 2008 ISBN 382665949X&lt;br /&gt;
* The Definitive Guide to the Arm Cortex-M0 (Joseph Yiu) Newnes Verlag ISBN 0123854776&lt;br /&gt;
* The Definitive Guide to the Arm Cortex-M3 (Joseph Yiu) Newnes Verlag ISBN 185617963X&lt;br /&gt;
&lt;br /&gt;
== Artikel aus der Kategorie ARM ==&lt;br /&gt;
&amp;lt;ncl style=compact maxdepth=2 headings=bullet headstart=2&lt;br /&gt;
      showcats=1 showarts=1&amp;gt;ARM&amp;lt;/ncl&amp;gt;&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/EFM32 &#039;&#039;&#039;EFM32&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/EFM32 &#039;&#039;&#039;XMCxxxx&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
* [https://www.mikrocontroller.net/articles/Cortex-A ARM Cortex A]&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM| ]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=ARM_GCC&amp;diff=79919</id>
		<title>ARM GCC</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=ARM_GCC&amp;diff=79919"/>
		<updated>2013-12-08T23:05:34Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* GCC Binärdistributionen */  cut&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Category:ARM]][[Category:Compiler]]Der [[GCC]] kann auch für [[ARM]] konfiguriert werden. Es gibt diverse fertige Binärdistributionen die für verschiedene Controller mit ARM-Kern verwendet werden können.&lt;br /&gt;
== GCC Binärdistributionen ==&lt;br /&gt;
* [http://www.mentor.com/embedded-software/codesourcery Mentor Graphics Sourcery Tools (vormals CodeSourcery CodeBench Lite)] Windows, Linux&lt;br /&gt;
* [https://launchpad.net/gcc-arm-embedded GCC-ARM-Embedded] für Cortex-R4/R5/M0/M3/M4(F)/M0+. Windows, Linux, Mac, bereitgestellt von ARM selbst,  vollständiger Support für FPU&#039;s, C++11, kein Code-Size-Limit&lt;br /&gt;
* [http://sourceforge.net/projects/devkitpro/ devkitPro]&lt;br /&gt;
* [[ARM GCC toolchain for Linux and Mac OS X]]&lt;br /&gt;
* [http://www.yagarto.de/ Yagarto] (Windows, mit Eclipse-Integration), &lt;br /&gt;
* [http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/#winarm WinARM] (wird derzeit nicht gepflegt)&lt;br /&gt;
* [http://gnuarm.com/ GNUARM] (Linux, Windows, wird derzeit nicht gepflegt)&lt;br /&gt;
&lt;br /&gt;
Bei der Auswahl der Toolchain sollte beachtet werden, dass es größere Unterschiede bei den bereitgestellten C-Bibliotheken gibt. Die Sourcery Codebench Lite-Edition stellt z.B. keine Bibliotheken mit FPU-Unterstützung bereit, so dass trotz vorhandener FPU beim Cortex-M4 nur suboptimaler Code erzegt werden kann. Siehe [http://wiki.debian.org/ArmHardFloatPort/VfpComparison] für ein kleines Beispiel und eine Erklärung.&lt;br /&gt;
&lt;br /&gt;
Die im Netz häufig anzutreffende summon-arm Toolchain hat einen der seltenen Compiler-Bugs [http://www.mail-archive.com/gcc-bugs@gcc.gnu.org/msg353473.html] und sollte daher nicht verwendet werden, wenn man floatingpoint-Typen einsetzen möchte. Egal ob mit oder ohne FPU.&lt;br /&gt;
&lt;br /&gt;
Beim Einsatz des gcc in Verbindung mit in C geschriebenem startup-Code bei den Optimierungslevels &amp;quot;-O2&amp;quot; und &amp;quot;-O3&amp;quot; muss zusätzlich &amp;quot;-fno-gcse&amp;quot; gesetzt werden, da ansonsten die von der CPU benötigte NVIC-Tabelle(n) und zugehörige Funktionen u.U. nicht so aussehen wie sie sollten.&lt;br /&gt;
&lt;br /&gt;
Siehe auch [http://embdev.net/topic/129986#1175214 ARM-GCC development resources] im Forum.&lt;br /&gt;
&lt;br /&gt;
== Nutzung mit eigener Umgebung/Kommandozeile ==&lt;br /&gt;
Hier einige Hinweise wie man den GCC direkt verwenden kann (zB. mit selbstgebautem makefile), falls man das nicht von einer Entwicklungsumgebung machen lässt.&lt;br /&gt;
=== Compiler &amp;amp; Linker Flags ===&lt;br /&gt;
Für Eilige, zum Copy&amp;amp;Pasten. Detailinformationen gibt es in der [http://gcc.gnu.org/onlinedocs/gcc/Option-Summary.html#Option-Summary GCC Dokumentation], auch [http://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html#ARM-Options speziell für ARM].&lt;br /&gt;
* Mit Optimierungen:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Tool/Sprache                                          !! Cortex-M3                       !! Cortex-M4F&lt;br /&gt;
|-&lt;br /&gt;
| C-Compiler (gcc) || -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -Os -flto || -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -ffunction-sections -fdata-sections -Os -flto&lt;br /&gt;
|-&lt;br /&gt;
| C++ Compiler (g++) || -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -Os -flto -fno-rtti -fno-exceptions || -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -ffunction-sections -fdata-sections -Os -flto -fno-rtti -fno-exceptions&lt;br /&gt;
|-&lt;br /&gt;
| Assembler (as) || -mcpu=cortex-m3 -mfloat-abi=soft -mthumb || -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb&lt;br /&gt;
|-&lt;br /&gt;
| Linken von C Code (mit gcc-Befehl) || -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -Os -flto -Wl,--gc-sections -static || -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -ffunction-sections -fdata-sections -Os -flto -Wl,--gc-sections -static&lt;br /&gt;
|-&lt;br /&gt;
| Linken von C++ (und C) Code (mit g++-Befehl) || -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -Os -flto -fno-rtti -fno-exceptions -Wl,--gc-sections -static || -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -ffunction-sections -fdata-sections -Os -flto -fno-rtti -fno-exceptions -Wl,--gc-sections -static&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
* Ohne Optimierungen, mit Debug-Informationen:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Tool/Sprache                                          !! Cortex-M3                       !! Cortex-M4F&lt;br /&gt;
|-&lt;br /&gt;
| C-Compiler (gcc) || -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -g || -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -ffunction-sections -fdata-sections -g&lt;br /&gt;
|-&lt;br /&gt;
| C++ Compiler (g++) || -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -g -fno-rtti -fno-exceptions || -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -ffunction-sections -fdata-sections -g -fno-rtti -fno-exceptions&lt;br /&gt;
|-&lt;br /&gt;
| Assembler (as) || -mcpu=cortex-m3 -mfloat-abi=soft -mthumb || -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb&lt;br /&gt;
|-&lt;br /&gt;
| Linken von C Code (mit gcc-Befehl) || -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -g -Wl,--gc-sections -static || -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -ffunction-sections -fdata-sections -g -Wl,--gc-sections -static&lt;br /&gt;
|-&lt;br /&gt;
| Linken von C++ (und C) Code (mit g++-Befehl) || -mcpu=cortex-m3 -mfloat-abi=soft -mthumb -ffunction-sections -fdata-sections -g -fno-rtti -fno-exceptions -Wl,--gc-sections -static || -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -ffunction-sections -fdata-sections -g -fno-rtti -fno-exceptions -Wl,--gc-sections -static&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
* Siehe auch das [https://launchpadlibrarian.net/135588846/readme.txt Readme vom GCC-ARM-Embedded]&lt;br /&gt;
* Um das -flto -Flag verwenden zu können, muss der GCC [http://gcc.gnu.org/onlinedocs/gccint/LTO.html LTO] unterstützen. Beim GCC-ARM-Embedded ist dies ab Version 4.7-2013-q2-update  der Fall.&lt;br /&gt;
* Die LTO erkennt die ISR&#039;s und den Interrupt Vector möglicherweise als &amp;quot;unbenutzt&amp;quot; und optimiert sie daher weg. Dies kann durch Markierung der Funktionen &amp;amp; Variablen mit  &amp;quot;__attribute__ ((used))&amp;quot; verhindert werden.&lt;br /&gt;
* Alle Compileroptionen müssen auch beim Linken mit angegeben werden (ist in obiger Tabelle berücksichtigt), da auch dann u.U. Code generiert werden kann.&lt;br /&gt;
=== Startupcode &amp;amp; Linkerscript ===&lt;br /&gt;
* Damit der compilierte Code an den richtigen Stellen im Controller landet (d.h. dem Flash) muss man dem Linker ein Linkerscript mitgeben. Dies geht per &amp;quot;-T &#039;&#039;pfad_zum_linkerscript.ld&#039;&#039;&amp;quot; an den Linker-Befehl. Das Script ist praktisch Controller-spezifisch, es gibt Beispiel-Scripte der Controller-Hersteller.&lt;br /&gt;
* Damit beim Starten die richtigen Initialisierungen vorgenommen werden (wie globale Variablen und bei C++ Konstruktoren globaler Objekt-Instanzen) muss als erstes ein Startupcode laufen, der dann die main()-Funktion aufruft. Der Startupcode ist meistens in Assembler geschrieben, C/C++-Code ist aber auch möglich. Assemblercode kann per arm-none-eabi-as (Flags s.o.) assemblisiert werden, die resultierende .o -Datei normal mitgelinkt. Auch für den Startupcode gibt es Beispiele der Controller-Hersteller.&lt;br /&gt;
&lt;br /&gt;
Zusammen bieten die beiden Dateien der Anwendung ein Standard-C-Interface, d.h. man kann wie gewohnt globale Variablen verwenden und seinen Code in die main()-Funktion schreiben.&lt;br /&gt;
=== FPU der Cortex-M4F nutzen ===&lt;br /&gt;
Um die FPU zu nutzen, muss dem Compiler per [[#Compiler_.26_Linker_Flags|Flag]] dazu gebracht werden, FPU-Instruktionen zu generieren.&lt;br /&gt;
&lt;br /&gt;
Außerdem muss vor Benutzung der FPU-Befehle die FPU aktiviert werden, dies geschieht typischerweise im Startupcode, bevor die main() -Funktion aufgerufen wird. Hier die entsprechenden Befehle, falls sie im verwendeten Startupcode nicht onehin schon enthalten sind:&lt;br /&gt;
&amp;lt;pre&amp;gt;/*FPU settings*/&lt;br /&gt;
 ldr     r0, =0xE000ED88           /* Enable CP10,CP11 */&lt;br /&gt;
 ldr     r1,[r0]&lt;br /&gt;
 orr     r1,r1,#(0xF &amp;lt;&amp;lt; 20)&lt;br /&gt;
 str     r1,[r0]&amp;lt;/pre&amp;gt;&lt;br /&gt;
In C/C++ unter Verwendung der CMSIS geht es so:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2)); /* set CP10 and CP11 Full Access */&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weiterhin sollte die GCC-Distribution auch Laufzeitbibliotheken mit FPU-Unterstützung mitbringen (CodeBench lite und Yagarto werden ohne ausgeleifert, GCC-ARM-Embedded mit).&lt;br /&gt;
&lt;br /&gt;
Am Beispiel der STM32F4 mehr dazu in diesem Thread: [http://www.mikrocontroller.net/topic/261021 Floating Pointing Unit STM32F4]&lt;br /&gt;
=== Disassemblieren mit GCC ===&lt;br /&gt;
arm-none-eabi-objdump -d -t -C pfad_zum_binary.elf&lt;br /&gt;
&lt;br /&gt;
=== Konvertieren zwischen Binary-Formaten beim GCC ===&lt;br /&gt;
arm-none-eabi-objcopy -O &#039;&#039;ausgabeformat&#039;&#039; &#039;&#039;eingabe_binary.elf&#039;&#039; &#039;&#039;ausgabe_binary&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Nützlich als Ausgabeformat sind z.B. &amp;quot;ihex&amp;quot; oder &amp;quot;binary&amp;quot;.&lt;br /&gt;
=== Code-Größe optimieren ===&lt;br /&gt;
Obige Flags (insbesondere -flto -Os -ffunction-sections -fdata-sections -Wl,--gc-sections ) verwenden. [http://www.mikrocontroller.net/topic/298976#3197418 Hier] finden sich noch ein par Tips, für den 1. kann aber mittlerweile der GCC-ARM-Embedded direkt verwendet werden, da er jetzt LTO unterstützt (s.o.).&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Platinenhersteller&amp;diff=79854</id>
		<title>Platinenhersteller</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Platinenhersteller&amp;diff=79854"/>
		<updated>2013-12-02T20:44:10Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* Deutschland */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
Die Vor- und Nachteile von Platinenherstellern/-lieferanten werden relativ häufig im [http://www.mikrocontroller.net/forum/platinen Forum] diskutiert (und führen ab und zu zu Flamewars :-). Damit man schnell einen Überblick über die verschiedenen Möglichkeiten erhält, soll hier eine Liste zusammengetragen werden.&lt;br /&gt;
&lt;br /&gt;
Jeder kann/soll seinen Beitrag leisten, d.h. wenn man einen Platinenlieferanten kennt, der noch nicht erwähnt ist, einfach hinzufügen. Falls man den Hersteller nicht so gut kennt, einfach mal den Namen und die URL hinzufügen, es gibt sicherlich andere, die den Hersteller so gut kennen, dass sie sich zutrauen, ein Urteil über die Leistung zu fällen.&lt;br /&gt;
&lt;br /&gt;
Eigentümer oder Mitarbeiter der gelisteten Firmen mögen bitte der Versuchung widerstehen, die Einträge mit werbeähnlichen Texten oder Werbung zu ergänzen. Zufriedene Kunden mögen bitte darauf achten, ihre Zufriedenheit so zu formulieren, dass nicht der Eindruck entsteht, der Eintrag sei von einem Hersteller zur &amp;quot;Verschönerung&amp;quot; gemacht worden.&lt;br /&gt;
&lt;br /&gt;
PS.: Das Ganze soll so ähnlich werden wie [[Elektronik-Versender]], da hat das auch sehr gut geklappt!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Diese Seite kann nur von angemeldeten Benutzern bearbeitet werden!&#039;&#039;&#039; Bei neuen Einträgen bitte die Sortierung beachten.&lt;br /&gt;
&lt;br /&gt;
Einige Hinweise, Hilfestellungen zur Platinenfertigung und Auftragsvergabe gibt es auch in der [http://www.dse-faq.elektronik-kompendium.de/dse-faq.htm#F.6 de.sci.electronics-FAQ].&lt;br /&gt;
&lt;br /&gt;
===Preise===&lt;br /&gt;
Zur besseren Vergleichbarkeit bei jedem Hersteller dazu schreiben, was &#039;&#039;&#039;eine doppelseitige durchkontaktierte Eurokarte (160mm x 100mm) mit deutscher MwSt.&#039;&#039;&#039; ohne Versand kostet.&lt;br /&gt;
Dazu noch die Lieferzeit und ob Lötstopplack und Bestückungsdruck dabei ist.&lt;br /&gt;
&#039;&#039;Zusätzlich&#039;&#039; kann man noch die Preise für andere Formate, Stückzahlen etc. dazu schreiben.&lt;br /&gt;
&lt;br /&gt;
== Liste der Hersteller ==&lt;br /&gt;
&lt;br /&gt;
=== Deutschland ===&lt;br /&gt;
&lt;br /&gt;
==== Accent PCB GmbH ====&lt;br /&gt;
Homepage: http://www.accentpcb.com/duitsland-home.html&lt;br /&gt;
&lt;br /&gt;
Eigendarstellung (vgl. auch [http://www.mikrocontroller.net/topic/316646 Forenthread]):&lt;br /&gt;
* Leiterplatten &amp;quot;ab 75€ - €99€&amp;quot; &lt;br /&gt;
* erfahrene Techniker&lt;br /&gt;
* Beratung gratis&lt;br /&gt;
* Produktion in Asien und Europa&lt;br /&gt;
* auch flexible und &amp;quot;starr-flexible&amp;quot; Platinen&lt;br /&gt;
&lt;br /&gt;
==== Ätzwerk GmbH ====&lt;br /&gt;
Homepage: http://www.aetzwerk.de&lt;br /&gt;
&lt;br /&gt;
Eigendarstellung:&lt;br /&gt;
* 100x160mm, Lötstopp doppelseitig, Bestückungsdruck einseitig, Stuktur&amp;gt;0,15mm, Bohrungen&amp;gt;0,3mm, 7AT, 59€&lt;br /&gt;
* scheint auch an privat zu liefern&lt;br /&gt;
* SMD-Schablonen&lt;br /&gt;
* Expressfertigung&lt;br /&gt;
&lt;br /&gt;
Erfahrungen:&lt;br /&gt;
* verschicken unaufgeforderte Newsletter&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/246385 Diskussionsfaden &amp;quot;Ätzwerk GmbH&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
==== am2s ====&lt;br /&gt;
Homepage: http://www.am2s.de&lt;br /&gt;
* Leiterplatten (Prototypen und Kleinserien, bis hin zur Großserie)&lt;br /&gt;
* Eildienst möglich&lt;br /&gt;
* Ein- und doppelseitige Leiterplatten, Multilayer. &lt;br /&gt;
* Layoutservice&lt;br /&gt;
* günstige Preise&lt;br /&gt;
* sehr gute Qualität&lt;br /&gt;
* Lieferzeit ab 3 AT&lt;br /&gt;
* KEINE eigene Leiterplattenfertigung - nur Vertrieb&lt;br /&gt;
&lt;br /&gt;
==== andus electronic ====&lt;br /&gt;
Homepage: http://www.andus.de&lt;br /&gt;
* Prototypen Fertigung&lt;br /&gt;
* Top Qualität&lt;br /&gt;
* Top Service&lt;br /&gt;
* Vergleichsweise Teuer&lt;br /&gt;
&lt;br /&gt;
==== ANTtronic ====&lt;br /&gt;
Homepage: http://www.anttronic.de/pcb/&lt;br /&gt;
&amp;lt;!-- früher http://www.gsel.de --&amp;gt;&lt;br /&gt;
* gute Preise, aber Lieferzeit beachten!&lt;br /&gt;
* 1 Europlatine einseitig kein Lötstoplack 17€ inkl. MwSt +7€ Versand&lt;br /&gt;
* 1 Europlatine doppelseitig &#039;&#039;nicht durchkontaktiert&#039;&#039; kein Lötstoplack 23€ inkl. MwSt +7€ Versand; 2Stück 37€&lt;br /&gt;
&lt;br /&gt;
==== Basista Leiterplatten ====&lt;br /&gt;
Homepage: http://www.basista.de&lt;br /&gt;
* Eurokarte doppelseitig für 52€ inkl. MwSt / mit Stopplack + Best.Druck 94€ inkl. MwSt&lt;br /&gt;
* Prototypen standardmäßig chemisch zinnbehandelt&lt;br /&gt;
* Preise OK&lt;br /&gt;
* Früher geliefert ohne Aufpreis (7 statt 10 AT)&lt;br /&gt;
* Qualität OK&lt;br /&gt;
* &#039;&#039;Onlinekalkulator&#039;&#039;&lt;br /&gt;
* 100x160mm, zweiseitig, durchkontaktiert, mit Lötstop, 8AT, 82€&lt;br /&gt;
&lt;br /&gt;
==== Bauer-Elektronik ====&lt;br /&gt;
Homepage: http://www.bauer-leiterplatten.de/&lt;br /&gt;
* Eurokarte doppelseitig für 61€ inkl. MwSt 8AT Lieferzeit / Stopplack +10% / Best.Druck +10%&lt;br /&gt;
* Prototypen aktivzinnbehandelt, dieses lässt sich laut Firmenangaben noch nach Jahren löten&lt;br /&gt;
* Eildienst 2h: Versand am selben Tag bei Einsendung bis 13:00 400€ für 2dm²&lt;br /&gt;
==== Britze ====&lt;br /&gt;
Homepage: http://www.britze.de&lt;br /&gt;
* Leiterplatten in kleinen und mittlere Serien&lt;br /&gt;
* Musterleiterplatten / Prototypen&lt;br /&gt;
* 1- und 2-lagige Leiterplatten&lt;br /&gt;
* Multilayer bis 10 Lagen&lt;br /&gt;
* Aluminiumträgerleiterplatten&lt;br /&gt;
* &#039;&#039;Online-Kalkulator&#039;&#039; für Multinutzen und Leiterplatten&lt;br /&gt;
* Beratung/Layout/Entflechtung von Leiterplatten&lt;br /&gt;
* 100x160mm, zweiseitig, durchkontaktiert, mit Lötstop, 10AT, 73€&lt;br /&gt;
* scheint auch an privat zu liefern&lt;br /&gt;
&lt;br /&gt;
==== B&amp;amp;B Gruppe ====&lt;br /&gt;
&lt;br /&gt;
Homepage: http://www.bb-gruppe.de&lt;br /&gt;
&lt;br /&gt;
Hersteller aus Mittweida/Sachsen &amp;lt;br&amp;gt;&lt;br /&gt;
Klein- und Musterserien, Spezialist Sondertechniken&amp;lt;br&amp;gt;&lt;br /&gt;
Zusätzliche Partner für Großserien in Asien mit eigenen Mitarbeitern &lt;br /&gt;
&lt;br /&gt;
* Ein- und Doppelseitige Leiterplatten&lt;br /&gt;
* Multilayer&lt;br /&gt;
* Schleifringe&lt;br /&gt;
* Starrflex&lt;br /&gt;
* Hochstromleiterplatte&lt;br /&gt;
* Dickkupfer&lt;br /&gt;
* Flexlam&lt;br /&gt;
* Dünnstleiterplatte&lt;br /&gt;
* IMS&lt;br /&gt;
* HDI Leiterplatte&lt;br /&gt;
* E-Test inklusive&lt;br /&gt;
* Datenformate: Ger­ber, Eagle, Excel­lon, Sieb &amp;amp; Meier&lt;br /&gt;
* Eildienst möglich&lt;br /&gt;
* Abrufeinteilung und Konsignationslager möglich&lt;br /&gt;
&lt;br /&gt;
B&amp;amp;B Sachsenelektronik GmbH&amp;lt;br&amp;gt;&lt;br /&gt;
Leipziger Straße 40&amp;lt;br&amp;gt;&lt;br /&gt;
09648 Mittweida&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Tel: 03727/62 97 0&amp;lt;br&amp;gt;&lt;br /&gt;
Fax: 03727/ 62 97 24&amp;lt;br&amp;gt;&lt;br /&gt;
Email: info@bb-gruppe.de&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Contag====&lt;br /&gt;
&lt;br /&gt;
Homepage: http://www.contag.de&lt;br /&gt;
* SAUSCHNELL- ab 4 STUNDEN(!)&lt;br /&gt;
* Aber auch sehr teuer&lt;br /&gt;
* Qualität sehr gut&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Christian Enzmann Gmbh ====&lt;br /&gt;
&lt;br /&gt;
Hompage: http://www.enzmann.de/&amp;lt;br&amp;gt;&lt;br /&gt;
E-Mail: info@enzmann.de&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Angebot:&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Prototypen&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
- Schnelle Reaktion auf individuelle Kundenwünsche&amp;lt;br&amp;gt;&lt;br /&gt;
- Liefertermine werden eingehalten&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;Serienfertigung&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
- gefertigten Prototypen sollen später in Produktion von Großserien gehen&amp;lt;br&amp;gt;&lt;br /&gt;
- Kunden können mit großen Stückzahlen versorgt werden&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Deutschlaender Electronic GmbH ====&lt;br /&gt;
&lt;br /&gt;
Homepage: http://www.deutschlaender.net&amp;lt;br&amp;gt;&lt;br /&gt;
E-Mail: vertrieb@deutschlaender.net&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ausführung:&amp;lt;br&amp;gt;&lt;br /&gt;
• Leiterbahnbreite und -abstand ab 100 µm&amp;lt;br&amp;gt;&lt;br /&gt;
• Bohrdurchmesser (Endmaß) ab 0,2 mm&amp;lt;br&amp;gt;&lt;br /&gt;
• Sacklöcher&amp;lt;br&amp;gt;&lt;br /&gt;
• Halblöcher&amp;lt;br&amp;gt;&lt;br /&gt;
• Tiefenfräsung&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Materialien:&amp;lt;br&amp;gt;&lt;br /&gt;
• Materialstärke ab 0,5 mm bis 2,4mm&amp;lt;br&amp;gt;&lt;br /&gt;
• Kupferauflagen: 35 µm, 70 µm, 105 µm,145 µm und 235 µm&amp;lt;br&amp;gt;&lt;br /&gt;
• Hoch-Tg oder Aluminiummaterial&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Servicedrucke:&amp;lt;br&amp;gt;&lt;br /&gt;
• Fotosensitiver Lötstoplack (grün,schwarz,rot und weiß)&amp;lt;br&amp;gt;&lt;br /&gt;
• Bestückungsdruck (weiß,gelb,schwarz und rot)&amp;lt;br&amp;gt;&lt;br /&gt;
• Carbondruck (Kontaktflächen)&amp;lt;br&amp;gt;&lt;br /&gt;
• Abziehlack&amp;lt;br&amp;gt;&lt;br /&gt;
• Viadruck&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mechanische Bearbeitung:&amp;lt;br&amp;gt;&lt;br /&gt;
CNC-Fräsen für:&amp;lt;br&amp;gt;&lt;br /&gt;
• Kontur&amp;lt;br&amp;gt;&lt;br /&gt;
• Schlitze - auch durchkontaktiert&amp;lt;br&amp;gt;&lt;br /&gt;
• Kerb Ritzen für Kontur, Sollbruchstellen, Sprungritzen&amp;lt;br&amp;gt;&lt;br /&gt;
• Kontur anfasen, z.B. für Steckerkamm&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oberflächenveredelung:&amp;lt;br&amp;gt;&lt;br /&gt;
• HAL bleifrei / PbSn&amp;lt;br&amp;gt;&lt;br /&gt;
• Chemisch Nickel/Gold(Ni/Au)&amp;lt;br&amp;gt;&lt;br /&gt;
• Chemisch Zinn (Sn)&amp;lt;br&amp;gt;&lt;br /&gt;
• Galvanisch Nickel/Gold (Ni/Au, Hartgold)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Datenformate: Ger­ber, Eagle, Target, Autocad, Excel­lon, Sieb &amp;amp; Meier&amp;lt;br&amp;gt;&lt;br /&gt;
* Eildienst möglich (3AT/5AT/7AT)&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== EPN Electroprint GmbH ====&lt;br /&gt;
&lt;br /&gt;
Homepage: http://www.epn.de&lt;br /&gt;
* Hersteller aus Neustadt an der Orla/Thüringen&lt;br /&gt;
* 8 Tage Lieferzeit, Eilservice 24h auch möglich&lt;br /&gt;
* Single-Layer, Multi-Layer (bis 22 Lagen als Spezialanfertigung!), Dickkupfer&lt;br /&gt;
* Verzinnung: Hot-Air-Leveling oder chemisch Zinn&lt;br /&gt;
* Lötstopplack verschiedene Farben nach Absprache möglich&lt;br /&gt;
* Stencil-Fertigung&lt;br /&gt;
* Thüringer Staatspreis für Qualität&lt;br /&gt;
&lt;br /&gt;
==== Elischer Leiterplatten ====&lt;br /&gt;
e-mail: aurel-elischer@t-online.de&lt;br /&gt;
* Firmensitz / Post-Adresse: Dipl.-Ing. Aurel Elischer, Leiterplatten, Am Forst 7, 72574 Bad Urach, Tel. 07125/4498, Ust.Id.-Nr.: DE 223 09 4959&lt;br /&gt;
* Layoutentwurf, LP Entwicklung, herstellen, bestücken, löten, prüfen&lt;br /&gt;
* 3 KW Lieferzeit (nach Vereinbarung auch kürzer)&lt;br /&gt;
* sehr gute Preise, Qual.1A&lt;br /&gt;
* einen Preis zu nennen, wäre Unfair. Es ist abhängig davon ob:&lt;br /&gt;
** 1 oder 2-seitig&lt;br /&gt;
** Leiterbahnenabstand und Lötflächenanstände kleiner oder größer als 0,3 mm&lt;br /&gt;
** Cu 30, 70, 110 µm&lt;br /&gt;
** Stärke der LP 1,0; 1,6; 2,0; ... mm&lt;br /&gt;
** mit (1- oder 2-seitig, grün, blau, weiß, schwarz,...)oder ohne Beschriftung&lt;br /&gt;
** mit oder ohne Stoplack&lt;br /&gt;
** gefräst oder nur geritzt&lt;br /&gt;
** einzeln oder X-Fach-Montage&lt;br /&gt;
* BITTE BEACHTEN: unter 10 St lohnt es sich für Sie nicht: für die erste Lieferung müssen wir einmalig ca 65€ berechnen (Film, Maske, Bohrdatei, ...)&lt;br /&gt;
* ab 10 St unbedingt Gerber 274X und Exellon für das Angebot (Angebot kostenlos) beifügen; keine Angst: Gerber 274X und Exellon kann man aus jedem Programm generieren&lt;br /&gt;
&lt;br /&gt;
==== Elk Tronic ====&lt;br /&gt;
&lt;br /&gt;
Homepage [http://www.elk-tronic.de/ http://www.elk-tronic.de]&lt;br /&gt;
*Entwicklung und Fertigung von Kleingeräten und Kleinserien&lt;br /&gt;
*Verkauf von IC-Adaptern und Bauteilen&lt;br /&gt;
&lt;br /&gt;
==== Fischer Leiterplatten GmbH ====&lt;br /&gt;
Homepage: http://www.fischer-leiterplatten.de&lt;br /&gt;
* 1 Europlatine inkl. Lack, E-Test, ohne Bestückungsdruck für 46,41€ inkl. MwSt in 10 Tagen + Versand&lt;br /&gt;
* 1 Europlatine inkl. Lack, E-Test, Best.-Druck top oder bottom für 58,31€ inkl. MwSt in 10 Tagen + Versand&lt;br /&gt;
* 1 Europlatine inkl. Lack, E-Test, Best.-Druck doppelseitig für 117,81€ inkl. MwSt in 10 Tagen + Versand&lt;br /&gt;
* max. 4 lagig&lt;br /&gt;
* Bestückungsdruck doppelseitig&lt;br /&gt;
* Bohrungen no limit&lt;br /&gt;
* min Clearance 0,15mm (Standard)&lt;br /&gt;
* min Bohrdurchmesser 0,3mm (Standard)&lt;br /&gt;
* Gerber/Eagle/Protel/Target&lt;br /&gt;
* mehrere Leiterplatten können auf einer Europakarte, zum Preis einer Europakarte, zusammengefasst werden und werden automatisch vereinzelt.&lt;br /&gt;
* Überlieferung wird kostenlos beigelegt. (Sprich: in der Regel werden mehr Leiterplatten geliefert als bestellt.)&lt;br /&gt;
* Verkauf nur an Gewerbetreibende (aber es wird kein Gewerbenachweis verlangt ;) )&lt;br /&gt;
* Erfahrungen: [http://www.mikrocontroller.net/topic/209947#2078731]&lt;br /&gt;
&lt;br /&gt;
==== GLS Leiterplatten-Service GmbH ====&lt;br /&gt;
Homepage: http://www.leiterplattenprototypen.de&lt;br /&gt;
* Prototypenfertigung bei Chemnitz&lt;br /&gt;
* Top Qualität (mittleres Preisniveau)&lt;br /&gt;
* Top Service&lt;br /&gt;
* Prüfung der Layoutdaten in der CAM&lt;br /&gt;
* Standardlieferzeit: 10 Arbeitstage&lt;br /&gt;
* Eilservice bis 3 Arbeitstage (mit Aufpreis)&lt;br /&gt;
* Oberfläche Standard: HAL bleifrei; aber auch z.&amp;amp;nbsp;B. chem. Gold, chem. Zinn und HAL bleihaltig&lt;br /&gt;
* einseitige, nichtdurchkontaktierte Leiterplatten &lt;br /&gt;
* durchkontaktierte Leiterplatten&lt;br /&gt;
* Multilayer: bis 8-Lagen&lt;br /&gt;
* bietet zusätzlichen Service rund um die Leiterplatte: Erstellung von Leiterplattenlayouts und Digitalisierung/Scannen von alten Fertigungsfilmen, Papierausdrucken oder vorhandenen Musterleiterplatten&lt;br /&gt;
* SMD Schablonen&lt;br /&gt;
&lt;br /&gt;
==== HAKA Elektronik-Leiterplatten GmbH ====&lt;br /&gt;
Homepage: http://www.haka-lp.de/&lt;br /&gt;
* Zwillingsangebot: 2 identische Europakarten für 50€ (durchkontaktiert, Lötstop, kein Bestückungsdruck, nur Eagle- oder Target-Dateien), auch hierbei kostenlose Duplizierung kleinerer Layouts&lt;br /&gt;
* Zwillingsangebot: 2 identische Doppel-Eurokarten (200x160) für 90€, gleiche Bedingungen wie oben&lt;br /&gt;
* Prototypenangebot (min. Abstand 0,15 mm, min. Leiterbahnbreite 0,15 mm, kleinste Bohrung 0,3 mm, durchkontaktiert, Lötstop), 160x100mm in 2AT = 260EUR .. 8AT = 72 EUR .. 15AT = 63 EUR&lt;br /&gt;
* bei Platinen kleiner 1 qdm gibt es entsprechend mehr ohne Aufpreis&lt;br /&gt;
* Lieferzeit ab 3 Werktage; Achtung: Lieferzeit sind nur Circa-Werte und nicht verbindlich. Auch bei Aufpreis (AGB)!&lt;br /&gt;
* sehr gute Qualität&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Auf der Homepage ist von Platinen nichts mehr zu sehen --Esko&lt;br /&gt;
==== LED-Hobby ====&lt;br /&gt;
Homepage: http://www.led-hobby.de/&lt;br /&gt;
* Kleinster Leiterbahnabstand: 0,2mm&lt;br /&gt;
* Kleinste Leiterbahnbreite: 0,2mm&lt;br /&gt;
* Kleinste Bohrung: 0,3mm&lt;br /&gt;
* Preis 0,35 EUR pro 1 x 1 cm (folglich 56,- EUR für eine doppelseitige Europakarte)&lt;br /&gt;
* RoHS-konform, made in Germany.&lt;br /&gt;
* Es sind alle Konturen, durchkontaktierte Bohrungen, Verzinnung (bleifrei) und beidseitiger grüner Lötstopplack enthalten. Kein Aufpreis, kein Grundpreis, keine Nacharbeit. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== IBR Leiterplatten GmbH &amp;amp; Co. KG ====&lt;br /&gt;
Homepage: http://www.ringler.de&lt;br /&gt;
* sehr freundlicher und kompetenter Service&lt;br /&gt;
* reagiert sehr schnell&lt;br /&gt;
* Qualität TOP&lt;br /&gt;
* Preise TOP - günstige Einmalkosten/Setup&lt;br /&gt;
* kann auch Dinge wie Alu, Starrflex, fine pitch oder 0,1 er vias&lt;br /&gt;
* Lieferzeit ab 2 Tage&lt;br /&gt;
* 2 Lagen in 10 Tagen - 10 Lagen Multilayer ohne besondere Nachfrage binnen 18 Tagen geliefert&lt;br /&gt;
* liefert generell schneller als bestätigt / macht auch Rahmenaufträge&lt;br /&gt;
* Mehrmengen bei Prototypen werden kostenlos geliefert&lt;br /&gt;
* SMD-Schablonen&lt;br /&gt;
&lt;br /&gt;
==== ILFA Feinstleitertechnik GmbH ====&lt;br /&gt;
Homepage: http://www.ilfa.de&lt;br /&gt;
&lt;br /&gt;
==== Eurocircuits GmbH&lt;br /&gt;
&lt;br /&gt;
Hompage: http://www.eurocircuits.de&lt;br /&gt;
&lt;br /&gt;
* ideal für kleine Stückzahlen ab 1 Stück&lt;br /&gt;
* Lieferzeit ab 2 AT&lt;br /&gt;
* gute Preise bei Prototypen aber auch bei mittleren Stückzahlen&lt;br /&gt;
* Online Datenvisualisierung und DRC Check&lt;br /&gt;
* SMD - Schablonen&lt;br /&gt;
* Preisberechnung eindeutig ohne versteckte Kosten&lt;br /&gt;
&lt;br /&gt;
==== Julian Hüsing CNC Leiterplattenprototypen (Privat) ====&lt;br /&gt;
* Europlatine 100x160 1 bis 2 Seitig ca. 20-40€ (Berechnung Maschinenzeit)&lt;br /&gt;
* Isolationsbreiten abhängig vom Stichel: minimale Isolationsbreite ca. 0,15 mm&lt;br /&gt;
* Bohr und Fräsarbeiten, auch aufwändige Konturen realisierbar&lt;br /&gt;
* Lieferzeit 8AT, ansonsten Aufpreis bei schnellerer Lieferung&lt;br /&gt;
mailto:julian.huesing85@googlemail.com&lt;br /&gt;
&lt;br /&gt;
==== kessler systems GmbH ====&lt;br /&gt;
Homepage: http://www.kesslersystems.de&lt;br /&gt;
* Leiterplatten und Bestückung (Prototypen und Kleinserien, bis hin zur Großserie)&lt;br /&gt;
* Sehr schnell&lt;br /&gt;
* Ein- und doppelseitige Leiterplatten, Multilayer. &lt;br /&gt;
* Layoutservice&lt;br /&gt;
* SMD- und THT Bestückung&lt;br /&gt;
* Gerätebau&lt;br /&gt;
* günstige Preise&lt;br /&gt;
* sehr gute Qualität&lt;br /&gt;
* Lieferzeit an 3 AT&lt;br /&gt;
* Bauelementebeschaffung auch schon bei 1 Stück (super funktioniert)&lt;br /&gt;
&lt;br /&gt;
==== LEITON ====&lt;br /&gt;
Homepage: [http://www.leiton.de/ leiterplatten-online.de]&lt;br /&gt;
* Flexible Leiterplatten online kalkulieren&lt;br /&gt;
* Alle Layouts werden in der CAM eingehend geprüft&lt;br /&gt;
* Schnellste Bearbeitung von Anfragen &lt;br /&gt;
* Diverse Spezialfertigungen (Aluminiumkern, HF, hoch-Tg etc.)&lt;br /&gt;
* Fließender Übergang vom Prototyp in die Serie möglich&lt;br /&gt;
* Niederlassungen in Hongkong &amp;amp; China für Großserien (LeitOn HK Ltd.)&lt;br /&gt;
* Relativ günstig&lt;br /&gt;
* bei mehreren kleinen Leiterplatten wird nach Gesamtfläche berechnet, nicht nach Mindestfläche x Mindestpreis x Stückzahl&lt;br /&gt;
* Doppelseitige Europlatine mit Lötstop in 8 Tagen 61,25 Eur&lt;br /&gt;
* In 15 Tagen 49 Eur&lt;br /&gt;
* Gute Qualität&lt;br /&gt;
* Bis 8-lagig und ab 12 Std.&lt;br /&gt;
&lt;br /&gt;
==== Leiterplatten-Express-Service GmbH ====&lt;br /&gt;
Homepage: http://www.les-gmbh.com&lt;br /&gt;
&lt;br /&gt;
==== Microcirtec  ====&lt;br /&gt;
Homepage: http://www.microcirtec.de&lt;br /&gt;
* Direct - Online - Shop — zum Kalkulieren-Bestellen und Kaufen&lt;br /&gt;
* Mit Auftragsverfolgung per Online&lt;br /&gt;
* Vom Rapid Prototyping bis zur Rapid Mass-Production&lt;br /&gt;
* Qualität betrachten wir als selbstverständlich&lt;br /&gt;
* Allerdings ist die Anmelde-Prozedur ein Drama&lt;br /&gt;
* Preiswert&lt;br /&gt;
&lt;br /&gt;
==== MME-Leiterplatten ====&lt;br /&gt;
Homepage: http://mme-pcb.de&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/73790 Thread &#039;MME-PCB, Erfahrungen&#039;](bereits 4 Jahre alt)&lt;br /&gt;
* Verkauft über seine Homepage (Onlinekalkulator)&lt;br /&gt;
* Europakarte: ES: 20,60 EUR, DSDK: 41,50 EUR&lt;br /&gt;
* Durchkontaktierung bei zweiseitigen Leiterplatten ist im Preis inbegriffen&lt;br /&gt;
* Trennen und Bohren inklusive&lt;br /&gt;
* Stopplack inklusive&lt;br /&gt;
* Bestückungsdruck (16€) kosten extra&lt;br /&gt;
* min. Abstand 0,20 mm,  min. Leiterbahnbreite 0,20 mm, kleinste Bohrung 0,4 mm&lt;br /&gt;
&amp;lt;!-- * sehr gute Qualität --&amp;gt;&lt;br /&gt;
* Lieferzeit 8-12 Arbeitstage (bei mir waren es nur 5 Werktage)&lt;br /&gt;
* Überlieferung kostet nichts (häufig wird eine Leiterplatte mehr geliefert, bei mir waren es bei vier bestellten Platinen zwei mehr)&lt;br /&gt;
* Mit einer bestellten einseitigen Platine (DIL Bauteile) bin ich sehr zufrieden&lt;br /&gt;
* Die auf der Seite beworbene Lierferzeit wird meist eingehalten.&lt;br /&gt;
* Bis zu zehn unterschiedliche Karten können in einem Auftrag gepoolt werden -&amp;gt; preiswerter weil dm² kosten über alle gerechnet werden.&lt;br /&gt;
* Antwortet bei mir nicht auf emails, telefonisch kaum zu erreichen.&lt;br /&gt;
*Kommunikation hat sich erheblich verbesssert.&lt;br /&gt;
* Kommunikation wieder schleppend ( stand: August 2013 )&lt;br /&gt;
&lt;br /&gt;
==== Multi Printed Circuit Boards Ltd. ====&lt;br /&gt;
Homepage: http://www.multi-circuit-boards.eu&lt;br /&gt;
* nur für Gewerbetreibende&lt;br /&gt;
* Eurokarte doppelseitig mit Lötstopplack, Bestückungsdruck und E-Test in 6AT:  68,54€ inkl. MwSt&lt;br /&gt;
* Online Kalkulator&lt;br /&gt;
&amp;lt;!-- (wurde von &amp;quot;ordentlich&amp;quot; auf &amp;quot;hervorragend&amp;quot; vom einem sehr zufriedenen Kunden umgeändert oder vom Anbieter? Anbieter finden ihre Produkte hoffentlich alle hervorragend. &amp;quot;Sehr gute Qualität&amp;quot; nun ohnehin schon unten) * hervoragende Qualität bei gutem Preis  * interessant für Serien; neuer günstiger Service für Prototypen --&amp;gt;&lt;br /&gt;
* farbiger Lötstopplack und Bestückungsdruck möglich&lt;br /&gt;
* 48 Stunden Express&lt;br /&gt;
* Kompletter Design-Rule-Check der CAM-Daten&lt;br /&gt;
* Diverse Spezialfertigungen (Flex, Starrflex, Metallkern, HF, hoch-Tg, etc.)&lt;br /&gt;
* Sehr gute Qualität&lt;br /&gt;
* Liefertermine werden gerne etwas überschritten( auch bei Eilservice)&lt;br /&gt;
&lt;br /&gt;
==== M &amp;amp; V Leiterplatten - Vertriebs GmbH ====&lt;br /&gt;
Homepage: &amp;lt;!-- http://www.mvpcb.de/ alte Adresse--&amp;gt; http://pcb-center.de/&lt;br /&gt;
* Bin sehr zufrieden, gute Preise, 10 - 14 Tage&lt;br /&gt;
* Top Qualität, nichts auszusetzen&lt;br /&gt;
* Qualität sehr gut, hohe Auflösung, auch SMD fine pitch möglich&lt;br /&gt;
* Eurokarte doppelseitig 2xStopplack FR4 bleifrei konturgefräst  63€ inkl. MwSt zzgl. Versand&lt;br /&gt;
* Eurokarte einseitig    1xStopplack FR4 bleifrei konturgefräst  44€ inkl. MwSt zzgl. Versand&lt;br /&gt;
&lt;br /&gt;
* Freundlicher Kontakt, Leiterplatten sehen gut aus, lieferten 6 Tage zu frueh!&lt;br /&gt;
* Biszu fünf unterschiedliche Karten können in einem Auftrag gepoolt werden -&amp;gt; preiswerter weil dm² kosten über alle gerechnet werden.&lt;br /&gt;
&lt;br /&gt;
==== PCB Joker ====&lt;br /&gt;
Homepage: http://www.pcb-joker.com/&lt;br /&gt;
* Poolkonzept extrem! &lt;br /&gt;
* 1- bis 4 Lagen Multilayer&lt;br /&gt;
* Allgemein schnell und geringe Terminzuschläge&lt;br /&gt;
* Leiterplatten werden bei verschiedenen deutschen Herstellern platziert&lt;br /&gt;
* Sehr günstig , sehr übersichtliche Onlinekalkulation&lt;br /&gt;
* Bezahlung per PayPal oder Vorkasse&lt;br /&gt;
* Farbe, Dicke, Kupferauflage und Oberfläche können nicht festgelegt werden, sondern sind &amp;quot;Joker&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== PCB Pool ====&lt;br /&gt;
Homepage: http://www.pcb-pool.de/ &lt;br /&gt;
Alternativname: BETA Layout&lt;br /&gt;
* Standort: Im Aartal 14, 65326 Aarbergen, [http://www.openstreetmap.de/karte.html?zoom=17&amp;amp;lat=50.23705&amp;amp;lon=8.06361&amp;amp;layers=B000TT Link zur Openstreetmap Karte]&lt;br /&gt;
* ideal für einzelne Boards und Klein(st)serien&lt;br /&gt;
* Preise im üblichen Rahmen&lt;br /&gt;
* Günstigere Preise für 10er oder 20er Auflage&lt;br /&gt;
* sehr gute Qualität&lt;br /&gt;
* Lieferzeit ab 2 AT&lt;br /&gt;
* SMD-Schablonen&lt;br /&gt;
* Aktzeptieren von den gängigsten Layoutprogrammen die Boarddaten direkt. AUCH von KiCAD. Siehe http://www.pcb-pool.com/ppde/info_dataformat.html&lt;br /&gt;
&lt;br /&gt;
==== Precoplat ====&lt;br /&gt;
&lt;br /&gt;
Homepage: http://www.precoplat.de/&lt;br /&gt;
&lt;br /&gt;
* Standort: Krefeld, Oberdiessemer Str. 15, 47805 Krefeld, [http://www.openstreetmap.de/karte.html?zoom=17&amp;amp;lat=51.32818&amp;amp;lon=6.58062&amp;amp;layers=B000TT Link zur Openstreetmap Karte]&lt;br /&gt;
* Prototypen, Großserien und alles dazwischen.&lt;br /&gt;
* Extrem flexibel im Angebot (Fläche/Lieferzeit, Blitz-Prototyping, Rapid-Mass-Produktion) &lt;br /&gt;
* Online Bestellung&lt;br /&gt;
* sehr gute Qualität&lt;br /&gt;
* bis 24 Lagen&lt;br /&gt;
* Mikro-Vias 100-200u&lt;br /&gt;
* Carbonlack&lt;br /&gt;
* Elektrischer Test (Flying probe + Nadelbett)&lt;br /&gt;
&lt;br /&gt;
==== Q-print/Q-PCB ====&lt;br /&gt;
Homepage: http://www.Q-PCB.de&lt;br /&gt;
* ideal für einzelne Boards und Klein(st)serien&lt;br /&gt;
* supergünstige Preise &lt;br /&gt;
* gute Qualität (u.U. Lötstop etwas unsauber)&lt;br /&gt;
* keine Zusatzpreise für 2x Lötstoplack o.ä.&lt;br /&gt;
* 150 µm kleinste Strukturbreite&lt;br /&gt;
* ohne Aufpreis bekommt man entweder HAL oder Ni/Au, gegen Aufpreis kann man aus einem von beiden wählen&lt;br /&gt;
* SMD-Schablonen&lt;br /&gt;
* Lieferzeit ab 4 AT&lt;br /&gt;
* Platine 50mm x 60mm, doppelseitig: ~45€ incl. Versand und ~5€ Nachnahme&lt;br /&gt;
* Platine 85mm x 58mm, doppelseitig: 33€ zzgl 6,80 Versand&lt;br /&gt;
* Platine 100mm x 160mm, doppelseitig: 49€ +7€ für Lötstopp +6,80€ Versand&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Ruwel ====&lt;br /&gt;
&lt;br /&gt;
Homepage: http://www.ruwel.com/&lt;br /&gt;
&lt;br /&gt;
* Standort: Am Holländer See 70, 47608 Geldern, [http://www.openstreetmap.de/karte.html?zoom=17&amp;amp;lat=51.50451&amp;amp;lon=6.32046&amp;amp;layers=B000TT Link zur Openstreetmap Karte]&lt;br /&gt;
* Werke in Deutschland und China&lt;br /&gt;
* Überwiegend Großserien.&lt;br /&gt;
* Hochtemperatur, Dickkupfer, Kupferinlays, Semiflex, Sacklochbohren.&lt;br /&gt;
&lt;br /&gt;
==== SMTstencil (Großbritannien) ====&lt;br /&gt;
SMD-Schablonen aus Polyester gelasert, preiswert, kleinste Strukturen 0,25 x 0,25 mm², kleinster Abstand 0,3 mm&lt;br /&gt;
&lt;br /&gt;
Homepage: http://smtstencil.co.uk/&lt;br /&gt;
&lt;br /&gt;
==== Steimer Leiterplatten GmbH ====&lt;br /&gt;
Homepage: http://www.steimer.de&lt;br /&gt;
&lt;br /&gt;
==== The PCB-Shop / Europrint Deutschland GmbH ====&lt;br /&gt;
Homepage: http://www.thepcbshop.com&lt;br /&gt;
* Punktabzug, da der Preisrechner nur mit Internet Explorer funktioniert&lt;br /&gt;
* gute Qualität&lt;br /&gt;
* guter Preis (inkl. gratis Überlieferungen - 30 kleine Platinen bestellt, 35 bekommen)&lt;br /&gt;
* wenig Statusinformationen (Link zur Statusseite kommt per Mail, dort ändert sich der Status und der Empfänger eigentlich täglich - ist aber trotzdem fristgerecht angekommen)&lt;br /&gt;
&lt;br /&gt;
==== Würth Elektronik GmbH &amp;amp; Co. KG ====&lt;br /&gt;
Homepage: http://www.we-online.de&lt;br /&gt;
* gehört sicherlich nicht zu den preisgünstigsten&lt;br /&gt;
* kann Bauteile in der Leiterplatte fertigen (R, C, Potis u.a.)&lt;br /&gt;
* beherrscht Microvias in allen erdenklichen Varianten&lt;br /&gt;
* sehr kompetentes Ansprechpersonal&lt;br /&gt;
&lt;br /&gt;
==== Onlineshop WEdirekt ====&lt;br /&gt;
&amp;lt;!-- Benutzer:Bede hat diese Beitrag eingefügt und sonst nie etwas im Wiki geschrieben, daher höchstwahrscheinlich Spam. Daher positive Meinung entfernt --&amp;gt;&lt;br /&gt;
Homepage: http://www.wedirekt.de&lt;br /&gt;
* PCB&#039;s in Basistechnologie, 2-8 Lagen&lt;br /&gt;
* SMD Schablonen in allen Ausführungen&lt;br /&gt;
* Europlatine doppelseitig mit Lötstopplack 67€ inkl. MwSt&lt;br /&gt;
* Design- und Applikationsfachbücher rund um EMV&lt;br /&gt;
&amp;lt;!-- * online kalkulieren und bestellen&lt;br /&gt;
* günstig, super Qualität  --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Deutschland sehr günstige===&lt;br /&gt;
Diese Hersteller zeichnen sich durch einen sehr günstigen Preis von &#039;&#039;&#039;unter 30€ pro doppelseitiger Eurokarte&#039;&#039;&#039; aus und können (bis auf pcb-devboards) &#039;&#039;&#039;keine Durchkontaktierungen&#039;&#039;&#039; herstellen.&lt;br /&gt;
&lt;br /&gt;
==== EBC Utz Kohl ====&lt;br /&gt;
Homepage: [http://www.e-b-c-elektronik.de http://www.e-b-c-elektronik.de]&lt;br /&gt;
* recht einfach gehalten, daher wirklich günstig&lt;br /&gt;
* Ideal für den Bastler, denen es auf den Preis ankommt&lt;br /&gt;
* Geätzt einseitig Euroformat 160 x 100mm 16,- EUR (zzgl 1,- EUR  Entsorgungspauschale pro Platine)&lt;br /&gt;
* Geätzt doppelseitig Euroformat 160 x 100mm 26,20 (zzgl 2,- EUR  Entsorgungspauschale pro Platine)&lt;br /&gt;
* Geometrie: Leiterbahnabstand/-breite &amp;gt;0.3/0.3mm; Bohrdurchmesser &amp;gt;0.8mm?; Bohrrestring &amp;gt;? = D-d; Leiterplattengröße &amp;lt;160x100mm?; ein- und doppelseitig&lt;br /&gt;
* doppelseitige Platinen sind nicht durchkontaktiert !&lt;br /&gt;
* eigentlich ein Ladengeschäft, versendet jedoch auch&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Platinenbelichter ====&lt;br /&gt;
&lt;br /&gt;
Homepage: http://www.platinenbelichter.de&lt;br /&gt;
* eine doppelseitige Europlatine kostet 14,90 EUR Grundpreis + 2,6 Cent je Bohrung&lt;br /&gt;
* Geometrie: Leiterbahnabstand/-breite &amp;gt;0.18/0.18mm; Bohrdurchmesser &amp;gt;0.4mm; Bohrrestring &amp;gt;0.25mm = D-d; Leiterplattengröße &amp;lt;300x200mm; ein- und doppelseitig&lt;br /&gt;
* Lötstopplack grün auf anfrage möglich&lt;br /&gt;
* Express Service möglich&lt;br /&gt;
* Scannservice&lt;br /&gt;
* Layoutherstellung vom Schaltplan bis zur fertigen Platine&lt;br /&gt;
* Macht auch Bestückungsarbeiten in Top Qualität&lt;br /&gt;
* Qualität ist mehr als ausreichend für TQFP&lt;br /&gt;
* gute Lötbarkeit der Platinen&lt;br /&gt;
&lt;br /&gt;
Nachteile&lt;br /&gt;
* Keine Durchkontaktierungen möglich&lt;br /&gt;
* Zum Teil lange Lieferzeit (Bis zu 2 Monate)&lt;br /&gt;
* Bei Nachfrage spärliche oder gar keine Antwort&lt;br /&gt;
&lt;br /&gt;
==== Platinendesign ====&lt;br /&gt;
Homepage: http://www.platinendesign.de/&lt;br /&gt;
* Geometrie: Leiterbahnabstand/-breite &amp;gt; 0.25/0.25mm; Bohrdurchmesser &amp;gt;?; Bohrrestring &amp;gt; 0.3mm = D-d; Leiterplattengröße &amp;lt; 300×200mm; ein- und doppelseitig&lt;br /&gt;
* eine doppelseitige Europlatine kostet 14 EUR Grundpreis + Bohrung 2cent + Optionen&lt;br /&gt;
* keine Durchkontaktierungen möglich&lt;br /&gt;
* Lötstopplack grün&lt;br /&gt;
* Lieferzeit von bis zu 8 Arbeitstagen nach Geldeingang&lt;br /&gt;
* Zeitweise geschlossen, Neueröffnung am 31.3.2013&lt;br /&gt;
&lt;br /&gt;
==== Ertürk Electronic ====&lt;br /&gt;
Website: http://www.erturk.de&lt;br /&gt;
&lt;br /&gt;
e-mail: [mailto:info@erturk.de info@erturk.de]&lt;br /&gt;
* Wir rechnen nach dm², in unserem Homepage können Sie selber sehen was Ihre Platine kostet (zur Zeit noch in Aufbau)&lt;br /&gt;
* Platine 1seitig FR4, 8€/dm²&lt;br /&gt;
* Chemische Verzinnung optional erhältlich&lt;br /&gt;
* Geometrie: Leiterbahnabstand/-breite &amp;gt; 0.2/0.2mm; Bohrdurchmesser &amp;gt; 0.4mm; Bohrrestring &amp;gt;0.3mm, Leiterplattengröße &amp;lt; 200×300mm; ein- und doppelseitig &lt;br /&gt;
* Sehr hohe Qualität&lt;br /&gt;
* Bohrung möglich (ab 10 dm² CNC gesteuert), 0,03 Euro pro Bohrung&lt;br /&gt;
* Lieferzeit meistens nach Geldeingang oder bis 3 Arbeitstage&lt;br /&gt;
* Ab 15 Platinen sind Durchkontaktierungen, Lötstoplack, Bohrungen und Positionsdruck möglich (Lieferzeit bis zu 2 Wochen). Anfrage und Auftragsannahme nur mit Gerberdaten oder Eagle Daten möglich.&lt;br /&gt;
* Für ein Prototyp-Angebot reicht eine Eagle, Sprintlayout- Target3001 oder PDF-Datei schon aus. PDF muss im Maßstab 1:1 und schwarz/weiß sein&lt;br /&gt;
* Verpackung und Versand von 2,50 bis 5,90 Euro innerhalb Deutschland egal wieviel Sie bestellen&lt;br /&gt;
* Mindestauftragsannahme ab 10,50,-- Euro Inklusiver Verpackung/Versand.&lt;br /&gt;
* Stand: Juli 2013&lt;br /&gt;
&lt;br /&gt;
==== Cadgrafik Bauriedl (nur Filme) ====&lt;br /&gt;
Homepage: [http://cadgrafik-bauriedl.de/leiterplattenfilme.htm]&lt;br /&gt;
* Überträgt Layouts auf hochwertige Folie/Film zum Selberätzen&lt;br /&gt;
* 1,15 € / 100 cm² Film, 2,50 € Mindestbestellwert (Stand März 2009)&lt;br /&gt;
* 2 € Porto (Stand März 2009)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== pcb-devboards.de (Leiterplatten, HF- und Mikrowellen-Prototypen inkl. Durchkontaktierung)====&lt;br /&gt;
&lt;br /&gt;
++++++ FR4-Standard 0,5-3,20mm, 35/70µmCu, Farbe(FR4): Standard, Schwarz ++++++&lt;br /&gt;
&lt;br /&gt;
Homepage: http://www.pcb-devboards.de/catalog/index.php?cPath=38_55_157&lt;br /&gt;
&lt;br /&gt;
* Einseitige und doppelseitige &amp;lt;b&amp;gt;durchkontaktierte&amp;lt;/b&amp;gt; Leiterplatten&lt;br /&gt;
* Oberfläche: chemisch Zinn&lt;br /&gt;
* Basismaterial FR4 Farbe: Standard, Schwarz.&lt;br /&gt;
* Kupfer-Endstärke; 35µmCU und 70µmCU.&lt;br /&gt;
* Fertigung im Nutzen, folgende Rohling-Größen verfügbar:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;b&amp;gt;FR4 1.60mm&amp;lt;/b&amp;gt;:&lt;br /&gt;
* 45x90mm (0,41dm²) - doppelseitig DK = 8,99 €.&lt;br /&gt;
* 100x80mm (0.80dm²) - doppelseitig DK = 13,99 €.&lt;br /&gt;
* 95x90mm (0,85dm²) - doppelseitig DK = 13,99 €.&lt;br /&gt;
* 160x100mm (1,60dm²) - doppelseitig DK =  23,49 €.&lt;br /&gt;
* 195x90mm (1,75dm²) - doppelseitig DK = 23,49 €.&lt;br /&gt;
* 195x140mm (2,7dm²) - doppelseitig DK = 29,99 €.&lt;br /&gt;
* 290x90mm (2,7dm²) - doppelseitig DK = 29,99 €.&lt;br /&gt;
* 290x195mm (5,65dm²) - doppelseitig DK = 49,99 €. &lt;br /&gt;
&lt;br /&gt;
* 45x90mm (0,41dm²) - einseitig = 5,99 €.&lt;br /&gt;
* 100x80mm (0.80dm²) - einseitig = 9,99 €.&lt;br /&gt;
* 95x90mm (0,85dm²) - einseitig = 9,99 €.&lt;br /&gt;
* 160x100mm (1,60dm²) - einseitig = 16,49 €.&lt;br /&gt;
* 200x90mm (1,80dm²) - einseitig = 16,49 €.&lt;br /&gt;
* 290x95mm (2,75dm²) - einseitig = 22,99 €.&lt;br /&gt;
* 200x140mm (2,80dm²) - einseitig = 22,99 €.&lt;br /&gt;
* 290x200mm (5,80dm²) - einseitig = 39,99 €.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;FR4 0.5mm/0.8mm/1.0mm&amp;lt;/b&amp;gt;:&lt;br /&gt;
* 290x195mm (5,65dm²) - doppelseitig DK = 49,99 €.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;FR4 2.0mm&amp;lt;/b&amp;gt;:&lt;br /&gt;
* 290x195mm (5,65dm²) - doppelseitig DK = 54,99 €.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;FR4 3.2mm&amp;lt;/b&amp;gt;:&lt;br /&gt;
* 290x195mm (5,65dm²) - doppelseitig DK = 59,99 €.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Fertigungsvorgaben, Standard Leiterplatten:&amp;lt;/b&amp;gt;:&lt;br /&gt;
* Geometrie: Leiterbahnabstand/-breite =&amp;gt;0.2/0.2mm; &lt;br /&gt;
* Kleinster Restring umlaufend: 0.20mm = (PAD - Bohrung)/2; &lt;br /&gt;
* max. Leiterplattengröße &amp;lt;290x195mm (5,65dm²); &lt;br /&gt;
* Unlimitierte Bohrungen ab 0,3mm (von der LP-Dicke abhängig) bis 6,3mm, ab 6,3mm werden die Bohrungen gefräst.&lt;br /&gt;
* LP-Dicke (0,50mm - 1,60mm): ab 0,3mm bis 6,3mm &lt;br /&gt;
* LP-Dicke 2,00mm: ab 0,4mm bis 6,3mm &lt;br /&gt;
* LP-Dicke 3,20mm: ab 0,5mm bis 6,3mm &lt;br /&gt;
* Optional Lötstoppmaske (70µm Laminat in grün) und ohne Bestückungsdruck&lt;br /&gt;
&lt;br /&gt;
++++++ ENDE FR4-Standard ++++++&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
++++++ HF-Leiterplatten, Basismaterial RO4003C, 0,51mm/0,81mm/1.52mm, 35µmCU ++++++&lt;br /&gt;
&lt;br /&gt;
Homepage: http://www.pcb-devboards.de/catalog/index.php?cPath=38_55_181_165&lt;br /&gt;
&lt;br /&gt;
* Doppelseitige &amp;lt;b&amp;gt;durchkontaktierte&amp;lt;/b&amp;gt; HF-Leiterplatten&lt;br /&gt;
* Oberfläche: chemisch Silber/Zinn&lt;br /&gt;
* Basismaterial RO4003C, Farbe: Weiß&lt;br /&gt;
* Kupfer-Endstärke; 35µmCU&lt;br /&gt;
* Fertigung im Nutzen, folgende Rohling-Größen verfügbar:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RO4003C 0.51mm&amp;lt;/b&amp;gt;:&lt;br /&gt;
* 195x90mm (1,75dm²) - doppelseitig DK = 39,99 €.&lt;br /&gt;
* 195x140mm (2,7dm²) - doppelseitig DK = 51,99 €.&lt;br /&gt;
* 290x195mm (5,65dm²) - doppelseitig DK = 87,49 €. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RO4003C 0.81mm&amp;lt;/b&amp;gt;:&lt;br /&gt;
* 195x90mm (1,75dm²) - doppelseitig DK = 39,99 €.&lt;br /&gt;
* 195x140mm (2,7dm²) - doppelseitig DK = 51,99 €.&lt;br /&gt;
* 290x195mm (5,65dm²) - doppelseitig DK = 87,49 €. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;RO4003C 1.52mm&amp;lt;/b&amp;gt;:&lt;br /&gt;
* 195x90mm (1,75dm²) - doppelseitig DK = 53,49 €.&lt;br /&gt;
* 195x140mm (2,7dm²) - doppelseitig DK = 69,00 €.&lt;br /&gt;
* 290x195mm (5,65dm²) - doppelseitig DK = 117,49 €.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Fertigungsvorgaben, HF-Leiterplatten:&amp;lt;/b&amp;gt;:&lt;br /&gt;
* Geometrie: Leiterbahnabstand/-breite =&amp;gt;150/150µm; &lt;br /&gt;
* Kleinster Restring umlaufend: 150µm = (PAD - Bohrung)/2; &lt;br /&gt;
* max. Leiterplattengröße &amp;lt;290x195mm (5,65dm²); &lt;br /&gt;
* Unlimitierte Bohrungen ab 0,3mm bis 6,3mm, ab 6,3mm werden die Bohrungen gefräst.&lt;br /&gt;
* ohne Lötstoppmaske und Bestückungsdruck&lt;br /&gt;
&lt;br /&gt;
++++++ ENDE HF-Leiterplatten ++++++&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Allgemeine Informationen:&amp;lt;/b&amp;gt;:&lt;br /&gt;
* Beliebige Stückzahlen von Einzelplatinen, auch im Nutzen, der Abstand von Platinen muss mindesten 4mm betragen&lt;br /&gt;
* Lieferzeit, Fertigung alle 10-15 Arbeitstage, die Fertigungstermine werden auf der Webseite angegeben.&lt;br /&gt;
* Anfrage und Auftragsannahme mit Eagle, Target (freeware), Design Spark oder extended Gerberdaten möglich.&lt;br /&gt;
* Verpackung und Versand ab 4,75 Euro (für Stammkunden ab 2,75EUR) innerhalb Deutschland&lt;br /&gt;
&lt;br /&gt;
++++++ ENDE ++++++&lt;br /&gt;
&lt;br /&gt;
=== Ausland ===&lt;br /&gt;
&lt;br /&gt;
==== BatchPCB ====&lt;br /&gt;
Homepage: http://www.batchpcb.com (USA)&lt;br /&gt;
* Vermittler und keine eigene Herstellung (&amp;quot;PCB pooling service&amp;quot;), Hersteller vermutlich meist [[Platinenhersteller#Gold Phoenix|Gold Phoenix]]&lt;br /&gt;
* verbandelt mit Sparkfun (&amp;quot;off shoot of Spark Fun Electronics&amp;quot;)&lt;br /&gt;
* &amp;quot;We only offer one service at this time: 2 layer PCBs with soldermask both sides and silkscreen both sides. The minimum trace width is 8mil with 8 mil spacing.&amp;quot;&lt;br /&gt;
* relativ günstig, lange Lieferzeiten, weiteres siehe Homepage und [http://batchpcb.com/index.php/Faq BatchPCB FAQ]&lt;br /&gt;
&lt;br /&gt;
==== BILEX-LP ====&lt;br /&gt;
Homepage http://www.bilex-lp.com/ (Bulgarien)&lt;br /&gt;
* deutschsprechender Ansprechpartner&lt;br /&gt;
* liefern bleifreie Platinen(RoHs konform)&lt;br /&gt;
* 31€ für eine doppelseitige Eurokarte ohne Lack und Druck&lt;br /&gt;
* SMD- und THT Bestückung &lt;br /&gt;
* Layoutservice &lt;br /&gt;
* Lieferzeit ab 3-4 AT &lt;br /&gt;
* insgesamt von 5 bis 7 AT Anlieferung bei Airmail (Porto ab 4,-Euro)&lt;br /&gt;
* FedEx wollte von Bulgarien aus ab 27,-Euro, 1-2AT)&lt;br /&gt;
* Löcher größer 6 mm wurden nicht gebohrt, sondern gefräst(gegen Anfrage)&lt;br /&gt;
* Berichtete Qualitätsmängel (in Einzelfällen): ausgefranste Platinenfräsung, Lötstoplack hebt ab(nur bei Sn-Pb beschichtung, nicht bei Ni-Au).&lt;br /&gt;
* Fräsungen müssen extra bestellt werden! Aber trotzdem günstig&lt;br /&gt;
&lt;br /&gt;
==== CUBE CZ s.r.o. ====&lt;br /&gt;
Homepage http://www.cube.cz/ (Tschechische Republik)&lt;br /&gt;
&lt;br /&gt;
* kein Termineinhaltung bei Eilservice - Lieferung hat sich durch wiederholte DRC Checks (dauern jeweils einen Tag) und Vorauskassa statt Zahlungsziel 20 Tage wie auf der Rechnung angegeben von 4AT auf 10AT verzögert&lt;br /&gt;
* Keine Design Rules auf der Homepage verfügbar&lt;br /&gt;
* UL Zertifikat aus 2001 für nur 6 Mil Traces&lt;br /&gt;
* für Deutsche Verhältnisse günstig&lt;br /&gt;
&lt;br /&gt;
==== dfrobot ====&lt;br /&gt;
Homepage http://www.dfrobot.com/ (China)&lt;br /&gt;
&lt;br /&gt;
* Mindestens 10Stk&lt;br /&gt;
* Größe in 5cm Preisrasterung&lt;br /&gt;
* 10Stk 5x5 cm 9.9USD =&amp;gt; 1USD/Stk&lt;br /&gt;
* 200Stk 5x5 cm 69.5USD =&amp;gt; 0.35USD/Stk&lt;br /&gt;
* 4 Lagig 10Stk 5x5 cm 64.90USD =&amp;gt; 6.49USD/Stk&lt;br /&gt;
&lt;br /&gt;
==== Euro PCB Ltd. ====&lt;br /&gt;
Homepage http://www.europcb.com/ (Großbritannien)&lt;br /&gt;
* Günstige Leiterplatten&lt;br /&gt;
* Schnelle Lieferung&lt;br /&gt;
* Qualitativ OK&lt;br /&gt;
&lt;br /&gt;
12.02.2012: Webseite ist leer; Firma terminiert?&lt;br /&gt;
&lt;br /&gt;
==== Gold Phoenix ====&lt;br /&gt;
Homepage http://www.goldphoenixpcb.biz/ (VR China)&lt;br /&gt;
&lt;br /&gt;
==== ITead Studio PCB prototyping service ====&lt;br /&gt;
Homepage http://iteadstudio.com/store/index.php?main_page=index&amp;amp;cPath=19_20 (VR China)&lt;br /&gt;
* Sehr günstige Leiterplatten&lt;br /&gt;
* Relativ günstige Lieferung&lt;br /&gt;
* 10 Stück mit jeweils 5x5cm für 9,90€&lt;br /&gt;
* Qulität relativ gut&lt;br /&gt;
* 100% E-Test&lt;br /&gt;
* Teilweise Probleme mit Gerberdateien, die knapp am Limit (6 mil) sind&lt;br /&gt;
* Testvideo: [http://www.eevblog.com/2011/03/11/eevblog-155-itead-studio-pcb-prototype-goof/ EEVBlog #155]&lt;br /&gt;
&lt;br /&gt;
==== LNAFIN ====&lt;br /&gt;
Homepage: http://electronics-pcb.com (Finland)&lt;br /&gt;
Produkte: http://electronics-pcb.com/shop (Finland)&lt;br /&gt;
Email   : pcb@lnafin.com&lt;br /&gt;
&lt;br /&gt;
* PCB Vertrieb mit Mikrowellenbereich und Multilagig HDI Kompetenz&lt;br /&gt;
* Leiterplatten fuer Industrie und auch als Kleinserien (kein MOQ)&lt;br /&gt;
* Elektronik und Layout Design Hilfe (bitte siehe Produkte)&lt;br /&gt;
* Auch ASIC design und PCBA (14 ASIC Erfahrung)&lt;br /&gt;
* Sicher Service auf Deutsch.&lt;br /&gt;
&lt;br /&gt;
==== MakePCB ====&lt;br /&gt;
Homepage http://www.makepcb.com/ (Shanghai, VR China)&lt;br /&gt;
* Ich habe bei MakePCB Platinen geordert und als Zahlungsart Paypal angegeben. Die automatische Bestaetigung kam, es stand nochmal explizit drin dass ich Paypal als Zahlungsart gewaehlt habe und die Bemerkung, dass bei Zahlungsart Paypal in 2 Tagen eine Mail an die gleiche Adresse kaeme mit den Daten für Paypal. Naja, nach 4 Tagen war immernoch nichts da, ich habe denen eine Mail geschrieben und nochmal nach den &amp;quot;versprochenen&amp;quot; Paypaldaten gefragt. Drei Tage spaeter war immernoch nichts da, also habe ich die Bestellung abgebrochen. Am 8. Tag kam die Zahlungsforderung über Paypal, kein Wort der Erklaerung. Am 10. Tag kamen zwei identische Mails, die sagten man haette die PayPal-Zahlungsaufforderung schon geschickt. Irgendwas laeuft in dem Laden also schief.&lt;br /&gt;
* Weiterer Erfahrungsbericht zu MakePCB: Nach einiger Überlegung habe ich mich entschieden, es zu wagen, bei MakePCB Platinen zu bestellen. Meine Platine hatte halbes Euro-Format, aus Kostengründen habe ich gleich 5 Stück bestellt. Der gesamte Preis betrug ca. 45 €, Zahlung per PayPal funktionierte ohne Probleme. Auf der Internetseite von MakePCB wurde für die Produktion 14 Tage, für Shipment 10-14 Tage veranschlagt. Nach der Bestellung konnte ich den Status der Bestellung online in einer Tabelle einsehen. Nach etwas mehr als den veranschlagten 4 Wochen kamen heute die Platinen am. Die Verpackung wirkte nicht sehr professionell (gepolsterter Umschlag, auf den mit Filzstift meine Anschrift geschrieben war), nach dem Aufreissen des Umschlags hielt ich ein mehrfach mit gepolsterter Folie und Klebeband umklebtes Päckchen in der Hand. Erst als ich die Folie entfernt hatte kam eine professionell mit Luftpolsterfolie verschweisste Packung zum Vorschein. Die Platinen sehen, so weit ich bisher beurteilen kann, gut aus, lediglich der Bestückungsdruck ist ein wenig versetzt. Ein kurzer exemplarischer Test mit dem Multimeter sah auch in Ordnung aus. Alles in allem macht das Angebot, insbesondere zu dem Preis, einen echt guten Eindruck. Ich kann es nur empfehlen. &lt;br /&gt;
&lt;br /&gt;
==== OLIMEX Ltd. ====&lt;br /&gt;
Homepage http://www.olimex.com (Bulgarien)&lt;br /&gt;
&lt;br /&gt;
Habe mehrere Jahre bei Olimex meine Prototypen herstellen lassen. Stets saubere Arbeit erhalten. Bis ich denen mal falsche Gerber-Dateien zusandte. Als ich einige Stunden spaeter den Fehler bemerkt hatte, bat ich um Stornierung und Neuzusendung. Gegen ein zusaetzliches Entgelt wurde dies akzeptiert.&lt;br /&gt;
Die angesagten Zusatzkosten wurden zwar von mir nicht abgebucht, aber ich erhielt  1 Woche spaeter die anfaenglich falsch zugesandten PCB&#039;s.&lt;br /&gt;
Die Zusammenfassung des darauffolgenden Email-Verkehrs: Ein Schulterzucken seitens Olimex und die Bitte, eine neue, kostenpflichte Bestellung zu taetigen.&lt;br /&gt;
&lt;br /&gt;
==== PAD2PAD ====&lt;br /&gt;
Homepage http://www.pad2pad.com/ (USA)&lt;br /&gt;
* Bestücken die Platinen auch mit Digikey-Bauteilen.&lt;br /&gt;
&lt;br /&gt;
==== PCBCart ====&lt;br /&gt;
Homepage http://www.pcbcart.com/ (China)&lt;br /&gt;
* auch kompliziertere Designs&lt;br /&gt;
* schnell und zuverlässig&lt;br /&gt;
* Eurokarte doppelseitig mit Lötstopp beidseitig und Bestückungsdruck kostet 60€ ohne MwSt +15€ Versand&lt;br /&gt;
* 2Stück 64€ ohne MwSt +15€ Versand&lt;br /&gt;
* 10Stück 90€ ohne MwSt +15€ Versand&lt;br /&gt;
* Eurokarte einseitig ohne Lötstopp und ohne Bestückungsdruck kosten 10Stück 71€ ohne MwSt +19€ Versand&lt;br /&gt;
&lt;br /&gt;
==== PCBPro ====&lt;br /&gt;
Homepage http://www.pcbpro.com/ (USA)&lt;br /&gt;
* Bei größeren Mengen (z.&amp;amp;nbsp;B. 100 Stück) sehr niedrige Preise&lt;br /&gt;
&lt;br /&gt;
==== Top-Tec-PCB ====&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Geschäftsbetrieb eingestellt&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Homepage http://www.top-tec-pcb.com/ (Großbritannien)&lt;br /&gt;
* Günstig für Klein- bis Großserien&lt;br /&gt;
* Discount bei Nachbestellung&lt;br /&gt;
* sehr gute Technik (z.&amp;amp;nbsp;B. 100µm Bohren oder 75µm Leiterbahn)&lt;br /&gt;
* deutschsprechender Ansprechpartner&lt;br /&gt;
* liefern bleifreie Platinen (HAL, chem. Gold, Silber u. Zinn)&lt;br /&gt;
* 48h Eildienst&lt;br /&gt;
&lt;br /&gt;
==== The PCB Shop ====&lt;br /&gt;
Homepage http://www.thepcbshop.com/ (Belgien)&lt;br /&gt;
* Für einfache Sachen&lt;br /&gt;
* Preisrechner funktioniert nur mit IE&lt;br /&gt;
&lt;br /&gt;
==== PIU-Printex ====&lt;br /&gt;
Homepage http://www.piu-printex.at/ (Österreich)&lt;br /&gt;
* Bei größeren Mengen (&amp;gt; 20 Stück, einseitig, viele Bohrungen) günstig&lt;br /&gt;
* Bearbeitung innerhalb 6 AT&lt;br /&gt;
* Telefonische Kontaktaufnahme bei Rückfragen&lt;br /&gt;
* Ich war sehr positiv überrascht.&lt;br /&gt;
&lt;br /&gt;
==== Seeed ====&lt;br /&gt;
Homepage http://www.seeedstudio.com (China)&lt;br /&gt;
* Mindestens 10Stk&lt;br /&gt;
* Größe in 5cm Preisrasterung&lt;br /&gt;
* 10Stk 5x5 cm 9.9USD =&amp;gt; 1USD/Stk&lt;br /&gt;
* 4 Lagig  5Stk 5x5 cm 39.90USD =&amp;gt; 8USD/Stk&lt;br /&gt;
* 4 Lagig 10Stk 5x5 cm 49.90USD =&amp;gt; 5USD/Stk&lt;br /&gt;
* Blaue, weiße, rote, gelbe, schwarze platinen für 10USD Aufpreis&lt;br /&gt;
* Überproduktion wird mit geliefert, bei einer 2cmx1cm Platine wurden 24Stk anstatt 10Stk geliefert.&lt;br /&gt;
* Kostenloser Standardversand bei Bestellungen über 50USD&lt;br /&gt;
&lt;br /&gt;
==== smart prototyping ====&lt;br /&gt;
Homepage http://smart-prototyping.com/ (China)&lt;br /&gt;
&lt;br /&gt;
* Mindestens 10Stk&lt;br /&gt;
* Größe in 5cm Preisrasterung&lt;br /&gt;
* Auch 6 lagige boards&lt;br /&gt;
* Maximal 30x30cm&lt;br /&gt;
* 10Stk 5x5 cm 8.9USD =&amp;gt; 0.9USD/Stk&lt;br /&gt;
* 500Stk 5x5 cm 132.92USD =&amp;gt; 0.27USD/Stk&lt;br /&gt;
* 4 Lagig 10Stk 5x5 cm 39.9USD =&amp;gt; 4USD/Stk&lt;br /&gt;
* 6 Lagig 10Stk 5x5 cm 239.9USD =&amp;gt; 24USD/Stk&lt;br /&gt;
&lt;br /&gt;
==== Vi&amp;amp;Rus International ====&lt;br /&gt;
Euro 160x100 für Euro 58,- incl. Express-Versand&lt;br /&gt;
&lt;br /&gt;
http://www.vrint-pcb.com (Bulgarien)&lt;br /&gt;
&lt;br /&gt;
* 3 (!) Arbeitstage&lt;br /&gt;
* RoHS, ENIG&lt;br /&gt;
* 2 Lagen, durchkontaktiert&lt;br /&gt;
* Lötstop beideitig&lt;br /&gt;
* Bestückungsdruck&lt;br /&gt;
* E-Test&lt;br /&gt;
* incl. Vereinzelungen (gefräst)&lt;br /&gt;
* incl. Versand (1 AT), also am 4. AT geliefert&lt;br /&gt;
* Erstklassige Qualität, auch bei Fine-Pitch; schneller, freundlicher Support.&lt;br /&gt;
&lt;br /&gt;
==== PRIONIK ( Österreich ) ====&lt;br /&gt;
Homepage: noch in Arbeit&lt;br /&gt;
&lt;br /&gt;
* Erstellung von hochwertigen Folien/Filmen zum selberätzen&lt;br /&gt;
* 1,25 € / 1dm² Film, 2,50 € Mindestbestellwert (Stand September 2013)&lt;br /&gt;
* 2 € Porto Österreich (Stand September 2013)&lt;br /&gt;
* 4 € Porto Deutschland (Stand September 2013) &lt;br /&gt;
* Leiterplattenfertigung auf Anfrage&lt;br /&gt;
Kontakt: office@prionik.at&lt;br /&gt;
&lt;br /&gt;
== Preisvergleichstabellen (Stand Februar 2010) ==&lt;br /&gt;
&lt;br /&gt;
Preise für 1, 2 Europlatinen (160x100), FR4 1.6mm, HAL bleifrei, 150µm Leiter, 0.3mm Bohren, doppelseitig, 8AT, kein Bestückungsdruck, inkl. MwSt, ohne Versand.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!style=&amp;quot;text-align:left&amp;quot; |Hersteller !!Preis (€) 1x !!Preis (€) 2x&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; colspan=&amp;quot;3&amp;quot; |&#039;&#039;ohne Lötstopp, ohne E-Test&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;Basista Leiterplatten&#039;&#039;&#039;|| 43,66 || 81,61&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;Fischer Leiterplatten GmbH&#039;&#039;&#039; (10AT, immer mit LS.+E-T.)|| 46,41 || 73,07&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;HAKA Elektronik-Leiterplatten GmbH&#039;&#039;&#039;|| 64,54 || 106,13&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;LEITON&#039;&#039;&#039;|| 54,98 || 104,51&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;MME-Leiterplatten&#039;&#039;&#039; (200µm Leiter)|| 41,44 || ?&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;PCB Pool&#039;&#039;&#039;|| 50,27 || 100,54&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;Q-print/Q-PCB&#039;&#039;&#039;|| 55,62 || 95,89&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; colspan=&amp;quot;3&amp;quot; |&#039;&#039;mit Lötstopp, mit E-Test&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;Basista Leiterplatten&#039;&#039;&#039;|| 77,66 || 115,61&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;Fischer Leiterplatten GmbH&#039;&#039;&#039; (10AT)|| 46,41 || 73,07&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;LEITON&#039;&#039;&#039;|| 88,79 || 147,39&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;Multi PCB Ltd. Leiterplatten&#039;&#039;&#039; (6AT)|| 78,06 || 156,13&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;M &amp;amp; V Leiterplatten - Vertriebs GmbH&#039;&#039;&#039;|| 62,83 || 125,66 &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;Onlineshop WEdirekt&#039;&#039;&#039;|| 128,75 || 172,38&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Preise für 1, 2, 10 Europlatinen (160x100), FR4 1.6mm, HAL bleifrei, 150µm Leiter, 0.3mm Bohren, doppelseitig, 8AT, 1x Bestückungsdruck, 2x Lötstopp, E-Test, inkl. MwSt, ohne Versand.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Hersteller !! Preis (€) 1x !!Preis (€) 2x !!Preis (€) 10x !! Nachbest. (€) 10x&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; colspan=&amp;quot;5&amp;quot; |&#039;&#039;mit Lötstopp, mit Bestückungsdruck, mit E-Test&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;Fischer Leiterplatten GmbH&#039;&#039;&#039; (10AT)|| 58,31 || 84,97 || 337,72 || 219,91 &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;HAKA Elektronik-Leiterplatten GmbH&#039;&#039;&#039;|| 82,54 || 124,13 || 302,08 || 284,08 &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;LEITON&#039;&#039;&#039;|| 124,37 || 187,15 || 389,84 || x &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;Multi PCB Ltd. Leiterplatten&#039;&#039;&#039;|| 78,06 || 156,13 || 272,27 || 180,64&lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;M &amp;amp; V Leiterplatten - Vertriebs GmbH&#039;&#039;&#039;|| 110,43 || 173,26 || ? || ? &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;PCB Pool&#039;&#039;&#039;|| 122,29 || 129,26 || 407,58 || x &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;Q-print/Q-PCB&#039;&#039;&#039;|| 96,80 || 166,90 || 834,48 || x &lt;br /&gt;
|-&lt;br /&gt;
|style=&amp;quot;text-align:left&amp;quot; |&#039;&#039;&#039;Onlineshop WEdirekt&#039;&#039;&#039;|| 145,18 || 190,64 || 379,49 || x&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://www.jackaltac.com/faq --&amp;gt; grafischer Vergleich der Platinenkosten]&lt;br /&gt;
&lt;br /&gt;
== Lohnbestücker - Kleinserien ==&lt;br /&gt;
&lt;br /&gt;
==== kessler systems GmbH ====&lt;br /&gt;
Homepage: http://www.kesslersystems.de&lt;br /&gt;
* SMD bis 0201, THT&lt;br /&gt;
* BGAs&lt;br /&gt;
* macht auch Großserien&lt;br /&gt;
* 5 Tage ab Eingang aller Bauteile, Express möglich&lt;br /&gt;
&lt;br /&gt;
==== PCB Pool ====&lt;br /&gt;
Homepage: http://www.pcb-pool.com/ppde/info_pcb_assembling.html&lt;br /&gt;
* Prototyp &amp;amp; Kleinserien, Größere Stückzahlen auf Anfrage&lt;br /&gt;
* SMD bis 0402, THT&lt;br /&gt;
* 5 Tage ab Eingang aller Bauteile &lt;br /&gt;
&lt;br /&gt;
==== REDER Domotic GmbH ====&lt;br /&gt;
Homepage: http://reder.eu&lt;br /&gt;
* Prototypen, Kleinserie, Serie&lt;br /&gt;
* THT, SMD ab 0201 Baugröße&lt;br /&gt;
* Komplette Materialbeschaffung&lt;br /&gt;
* Prototypen über Nacht möglich&lt;br /&gt;
* riesen Vorteil: der Mann an der Maschine ist selbst Entwickler&lt;br /&gt;
  &lt;br /&gt;
==== riese electronic GmbH ====&lt;br /&gt;
Homepage: http://www.riese-electronic.de/leistungen_prototype.html&lt;br /&gt;
* SMD bis 0201, THT&lt;br /&gt;
* BGAs inkl Röntgen&lt;br /&gt;
* macht auch Großserien&lt;br /&gt;
* 5 Tage ab Eingang aller Bauteile, Express möglich&lt;br /&gt;
&lt;br /&gt;
==== D-E-K Dischereit GmbH &amp;amp; Co. KG ====&lt;br /&gt;
Homepage: http://www.dischereit.de&lt;br /&gt;
* Prototyp, Kleinserien, Serie&lt;br /&gt;
* SMD bis 0402, THT&lt;br /&gt;
* Bauteilbeschaffung&lt;br /&gt;
&lt;br /&gt;
==== PBS-Electronic ====&lt;br /&gt;
Homepage: http://www.pbs-electronic.de&lt;br /&gt;
* Prototyp, Kleinserien, Serie&lt;br /&gt;
* BGA, QFN, TQPF, Fine Pitch, SMD bis 0402, THT&lt;br /&gt;
* Einzel IC Bestückung möglich&lt;br /&gt;
* Spezialist für LED Technik&lt;br /&gt;
&lt;br /&gt;
==== Traffitec ====&lt;br /&gt;
Homepage:http://www.traffitec.de/&lt;br /&gt;
* Standort: Hervorster Str. 175, 47574 Goch [http://www.openstreetmap.de/karte.html?zoom=17&amp;amp;lat=51.6904&amp;amp;lon=6.14378&amp;amp;layers=B000TT Link zur Openstreetmap Karte]&lt;br /&gt;
* Bestückt Prototypen, Kleinserien, Normalserien&lt;br /&gt;
* In THT, SMD und gemischt.&lt;br /&gt;
* und von allen Seiten&lt;br /&gt;
* Einpresstechnik&lt;br /&gt;
* Starrflex&lt;br /&gt;
* Komponentenbau&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [http://www.cadsoft.de/services/board-houses/?language=de Übersicht von Cadsoft, sortiert nach PLZ]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/245590 Forum: Platinensammler - Leiterkarten für 30ct/cm²]&lt;br /&gt;
&lt;br /&gt;
[[Category:Platinen| ]]&lt;br /&gt;
[[Kategorie:Lieferanten]]&lt;br /&gt;
[[Kategorie:Listen]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Olimex_AT91SAM7X256-Board_SAM7-EX256&amp;diff=78672</id>
		<title>Olimex AT91SAM7X256-Board SAM7-EX256</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Olimex_AT91SAM7X256-Board_SAM7-EX256&amp;diff=78672"/>
		<updated>2013-09-28T00:32:00Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: Schützte „Olimex AT91SAM7X256-Board SAM7-EX256“: Wiederholtes Einstellen von Werbung ([Bearbeiten=Nur automatisch bestätigten Benutzern erlauben] (bis 28. März 2014, 01:32 Uhr (UTC)) [Verschieben=Nur automatisch bestätigten Benutzern erlauben]&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[http://shop.mikrocontroller.net/csc_article_details.php?saArticle%5BID%5D=80 Olimex AT91SAM7X256-Board (SAM7-EX256)]&lt;br /&gt;
&lt;br /&gt;
[http://shop.mikrocontroller.net/csc_article_details.php?saArticle%5BID%5D=80 http://shop.mikrocontroller.net/images/sam7-ex256-small.jpg]&lt;br /&gt;
&lt;br /&gt;
== Softwarevoraussetzungen ==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Anleitungen setzen das Vorhandensein einer [[ARM#Compiler|ARM-GCC-Toolchain]] voraus.&lt;br /&gt;
&lt;br /&gt;
== Minimalbeispiel ==&lt;br /&gt;
&lt;br /&gt;
Dieses einfache Beispielprojekt mit Makefile basiert auf dem GCC-Tutorial von Atmel. Enthalten ist kein OS, nur ein paar Funktionen für UART-Kommunikation.&lt;br /&gt;
&lt;br /&gt;
Download: http://www.mikrocontroller.net/attachment/25724/Olimex_SAM7_EX256_StartupMinimal_2007.08.17.zip&lt;br /&gt;
&lt;br /&gt;
== Installation von FreeRTOS ==&lt;br /&gt;
&lt;br /&gt;
Merkmale von FreeRTOS:&lt;br /&gt;
* präemptives Multitasking&lt;br /&gt;
* Unterstützung für viele Prozessoren und Controller&lt;br /&gt;
* Demos für viele verschiedene Boards enthalten&lt;br /&gt;
* Beispiele für die Anbindung verschiedener IP-Stacks enthalten (lwIP, uIP)&lt;br /&gt;
* Codequalität der Demos durchwachsen&lt;br /&gt;
&lt;br /&gt;
Funktionsumfang des Beispielprojekts:&lt;br /&gt;
* TCP/IP-Stack lwIP&lt;br /&gt;
* Webserver&lt;br /&gt;
* virtueller serieller Port über USB realisiert (CDC, Windows-Treiber enthalten)&lt;br /&gt;
&lt;br /&gt;
Als Ausgangspunkt dient das Beispiel &amp;quot;lwIP_Demo_Rowley_ARM7&amp;quot; aus [http://www.freertos.org FreeRTOS] 4.4.0. Die für das Olimex-Board angepasste (und ein bisschen aufgeräumte) Version kann man [http://www.mikrocontroller.net/attachment/25551/lwIP_Demo_olimex.zip hier] herunterladen. Die Datei muss in den Demo-Ordner von FreeRTOS entpackt werden. Die Änderungen gegenüber der Originalversion sind in der Datei changes.txt dokumentiert.&lt;br /&gt;
&lt;br /&gt;
Die IP-Adresse ist standardmäßig auf 192.168.0.111 gesetzt und lässt sich in der Datei BasicWEB.c ändern.&lt;br /&gt;
&lt;br /&gt;
Kompiliert wird das Projekt wie üblich durch Eingabe von &amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Installation von Ethernut ==&lt;br /&gt;
&lt;br /&gt;
Ethernut bzw. Nut/OS ist ein Betriebssystem mit TCP/IP-Stack, das ursprünglich für AVR-Controller entwickelt wurde, später aber u.a. auf ARM portiert wurde.&lt;br /&gt;
&lt;br /&gt;
Merkmale von Nut/OS:&lt;br /&gt;
* sehr sauberer und gut kommentierter Code&lt;br /&gt;
* Buildsystem mit Konfigurations-GUI; Vorteil: einfacher Einstieg, Nachteil: Gesamtsystem manchmal etwas undurchsichtig&lt;br /&gt;
* nur kooperatives Multitasking&lt;br /&gt;
* zielt hauptsächlich auf AVR ab, ARM-Unterstützung noch nicht weit fortgeschritten&lt;br /&gt;
* im Vergleich zu lwIP spartanischer IP-Stack&lt;br /&gt;
&lt;br /&gt;
Funktionsumfang des Beispielprojekts:&lt;br /&gt;
* verschiedene Netzwerk-Beispielanwendungen (HTTP, FTP, DHCP)&lt;br /&gt;
* serieller Port&lt;br /&gt;
&lt;br /&gt;
Getestet wurde diese Anleitung mit der Ethernut-Version 4.2.1.&lt;br /&gt;
&lt;br /&gt;
Als Ausgangspunkt dient die Konfiguration at91sam7x-ek.conf. Für das Olimex-Board sind ein paar kleine Änderungen nötig.&lt;br /&gt;
&lt;br /&gt;
=== PHY-Konfiguration ändern ===&lt;br /&gt;
&lt;br /&gt;
Unter Architecture/ARM/AT91 EMAC Driver: &amp;lt;br /&amp;gt; [[Bild:olimex-sam7x-ethernut-phy-conf.png]]&lt;br /&gt;
&lt;br /&gt;
=== PHY-Initialisierung patchen ===&lt;br /&gt;
&lt;br /&gt;
In der Funktion EmacReset in der Datei at91_emac.c den Block mit dem Kommentar &amp;lt;code&amp;gt;/* For some unknown reason...&amp;lt;/code&amp;gt; durch folgenden Code ersetzen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
     /* PHY ID */&lt;br /&gt;
     #define MII_DM9161_ID_H 0x0181&lt;br /&gt;
     #define MII_DM9161_ID_L 0xb8a0&lt;br /&gt;
&lt;br /&gt;
     #define MII_AM79C875_ID_H 0x0022&lt;br /&gt;
     #define MII_AM79C875_ID_L 0x5540&lt;br /&gt;
&lt;br /&gt;
     #define MII_MICREL_ID_H 0x0022&lt;br /&gt;
     #define MII_MICREL_ID_L 0x1610 &lt;br /&gt;
&lt;br /&gt;
     /* For some unknown reason it seems to be required to read the ID registers first. */&lt;br /&gt;
     // Check for DM PHY (as used on the ATMEL EK)&lt;br /&gt;
     if (phy_inw(NIC_PHY_ID1) != MII_DM9161_ID_H ||&lt;br /&gt;
        (phy_inw(NIC_PHY_ID2) &amp;amp; 0xFFF0) != MII_DM9161_ID_L) {&lt;br /&gt;
     // Check for MICREL PHY (as used on the Olimex SAM7-EX256)   	&lt;br /&gt;
         if (phy_inw(NIC_PHY_ID1) != MII_MICREL_ID_H ||&lt;br /&gt;
            (phy_inw(NIC_PHY_ID2) &amp;amp; 0xFFF0) != MII_MICREL_ID_L) {&lt;br /&gt;
            outr(EMAC_NCR, inr(EMAC_NCR) &amp;amp; ~EMAC_MPE);&lt;br /&gt;
            return -1;&lt;br /&gt;
         }&lt;br /&gt;
     }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Fehlende Definition ergänzen ===&lt;br /&gt;
Falls eine Fehlermeldung auftritt dass EMAC_PIO_SODR nicht definiert ist, folgenden Code in der Datei at91_emac.c vor &amp;lt;code&amp;gt;#ifdef PHY_PWRDN_BIT\n /* Disable PHY power down. */&amp;lt;/code&amp;gt; einfügen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#ifndef EMAC_PIO_SODR&lt;br /&gt;
#define EMAC_PIO_SODR PIOB_SODR&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ausprobieren ===&lt;br /&gt;
&lt;br /&gt;
Wenn man das Beispielprogramm httpserv kompiliert (&amp;lt;code&amp;gt;make&amp;lt;/code&amp;gt; eingeben) und in den Controller geladen hat sollte man über das UART (115.2 kBaud) die erfolgreiche Initialisierung bestätigt bekommen:&lt;br /&gt;
 Nut/OS 4.2.1 HTTP Daemon...Configure eth0...OK&lt;br /&gt;
 192.168.0.21 ready&lt;br /&gt;
&lt;br /&gt;
Jetzt kann man die angezeigte IP-Adresse im Browser eingeben und sollte die Testseite zu sehen bekommen.&lt;br /&gt;
&lt;br /&gt;
== Forum ==&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/75721#new Diskussion zum Thema]&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* http://www.sparkfun.com/tutorial/Nokia%206100%20LCD%20Display%20Driver.pdf&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM-Boards]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=PHILIPS_VP5500_VoIP_Telefon&amp;diff=77869</id>
		<title>PHILIPS VP5500 VoIP Telefon</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=PHILIPS_VP5500_VoIP_Telefon&amp;diff=77869"/>
		<updated>2013-08-03T09:21:50Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: Schützte „PHILIPS VP5500 VoIP Telefon“: Wiederkehrender Vandalismus ([Bearbeiten=Nur automatisch bestätigten Benutzern erlauben] (bis 3. Februar 2014, 10:21 Uhr (UTC)) [Verschieben=Nur automatisch bestätigten Benutzern erlauben] (bis 3. Februar&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Verwandte Artikel =&lt;br /&gt;
* Konfiguration: http://www.mikrocontroller.net/topic/170483#new&lt;br /&gt;
* Kernel/GUI Entwicklung: http://www.mikrocontroller.net/topic/172616#new&lt;br /&gt;
* http://das-labor.org/wiki/VP5500&lt;br /&gt;
* (Hack) http://spritesmods.com/?art=vpx500&lt;br /&gt;
* http://vp6500.bd8.nl/&lt;br /&gt;
 &lt;br /&gt;
= Allgemeines =&lt;br /&gt;
 &lt;br /&gt;
Bei den diesem Text zugrundeliegenden Geräten handelt es sich um videofähige VoIP-Phones des Herstellers Philips, die vom früheren holländischen Anbieter KPN vertrieben wurden und nach dessen Ausscheiden aus dem Markt nun günstig erhältlich sind.&lt;br /&gt;
Ihr geringer Preis, die SoC-Architektur und das darauf laufende OS macht sie dabei für all jene interessant, die ihre eigenen Ideen und Projekte auf der Basis eines solchen Gerätes verwirklichen wollen, und gibt den oft fabrikneuen Exemplaren eine Art zweite Chance.&lt;br /&gt;
 &lt;br /&gt;
== Features ==&lt;br /&gt;
 &lt;br /&gt;
=== VP5500 ===&lt;br /&gt;
* Kamera-Auflösung 640x480 Pixel&lt;br /&gt;
* 30 Bilder pro Sekunde&lt;br /&gt;
* Kamera um 240° drehbar&lt;br /&gt;
* 5,6 cm (2,2&amp;quot;) TFT-Display, 176x220 Pixel, 65000 Farben&lt;br /&gt;
* Audio-/Video-Ausgang - 4fach 2,5mm Klinke-Cinch&lt;br /&gt;
* integrierter Li-Ion Akku, 3,7 V-/1100 mAh&lt;br /&gt;
* englische und niederländische Menüsprache&lt;br /&gt;
* Software Qtopia Version 2.1.0&lt;br /&gt;
* Maße (LxBxH): 134x49x24 mm.&lt;br /&gt;
 &lt;br /&gt;
[[Datei:Philips_VP5500.jpg]]&lt;br /&gt;
 &lt;br /&gt;
=== VP6500 ===&lt;br /&gt;
 &lt;br /&gt;
* Kamera-Auflösung 640x480 Pixel&lt;br /&gt;
* 30 Bilder pro Sekunde&lt;br /&gt;
* Kamera um 240° drehbar&lt;br /&gt;
* 5,6 cm (2,2&amp;quot;) TFT-Display, 176x220 Pixel, 65000 Farben&lt;br /&gt;
* Audio-/Video-Ausgang - 4fach 3,5mm Klinke-Cinch&lt;br /&gt;
* 2x Philips Multilife AA/R6NM 1800mAh NiMH-Akkus, je 1,2V, Ladeempfehlung: 15h mit 180mAh&lt;br /&gt;
* englische, deutsche und niederländische Menüsprache&lt;br /&gt;
* Software Qtopia Version 2.1.0&lt;br /&gt;
* Maße (LxBxH): 134x49x24 mm.&lt;br /&gt;
* Gewicht Mobilteil: 170 g (inkl. 2 NiMH-Akkus AA)&lt;br /&gt;
[[Bild:VP6500_kl.jpg]]&lt;br /&gt;
 &lt;br /&gt;
= Das VPx500 &#039;rooten&#039; =&lt;br /&gt;
 &lt;br /&gt;
Um vollen Zugang zum System auf dem Gerät zu erhalten gibt es mehrere Möglichkeiten.&lt;br /&gt;
 &lt;br /&gt;
== per telnet ==&lt;br /&gt;
Sobald das Telefon im Netzwerk angemeldet ist (egal ob DHCP oder statisch) kann über irgendein Terminal vom Netzwerk aus via telnet und der Telefon-IP auf das Gerät zugegriffen werden.&lt;br /&gt;
User: root / PW: toor&lt;br /&gt;
 &lt;br /&gt;
== per serieller Schnittstelle ==&lt;br /&gt;
Dazu muß der [[#UART]] angeschlossen werden. Während des Bootvorgangs drückt man immer wieder ziellos irgendwelche Tasten bis man am Prompt des [http://www.lartmaker.nl/lartware/blob/ blob-Bootloaders] ist.&lt;br /&gt;
Dann kann man&lt;br /&gt;
boot root=/dev/mtdblock2 init=/bin/sh&lt;br /&gt;
eingeben, um an eine minimale Shell zu kommen.&lt;br /&gt;
 &lt;br /&gt;
In dieser setzt man dann mit&lt;br /&gt;
passwd&lt;br /&gt;
das Passwort für &#039;&#039;root&#039;&#039;. Danach kann man sich als &#039;&#039;root&#039;&#039; mit dem gesetzten Passwort einloggen.&lt;br /&gt;
 &lt;br /&gt;
== per DNS-Hack ==&lt;br /&gt;
Um den Rootzugriff zu aktivieren, wird dem Telefon ein Softwareupdate vorgegaukelt. Es versucht, auf den Updateserver von KPN zuzugreifen (den es nicht mehr gibt). Glücklicherweise geschieht dies nicht über eine feste IP, sondern über einen Hostnamen, so dass man an dieser Stelle sich durch einen eigenen DNS den Domainname auf einen eigenen Server umleiten kann. Daher ist im eigenen Netzwerk eine Umleitung des DNS erforderlich (oder ein DHCP-Server, der die Adresse des DNS bekanntgibt. Stichworte &#039;Static DNS&#039;, ..).&lt;br /&gt;
Das Gerät holt sich dann ein Updatepaket, das den Telnet-Zugang aktiviert.&lt;br /&gt;
 &lt;br /&gt;
Dann lässt sich per Terminal (Linux. Windows: ....) die Kommandozeile des Geräts aufrufen:&lt;br /&gt;
 &lt;br /&gt;
telnet 123.456.789.012&lt;br /&gt;
 &lt;br /&gt;
Passwort ist &amp;quot;toor&amp;quot;.&lt;br /&gt;
Das Ändern des root-Passwortes erfolgt mit dem Befehl passwd.&lt;br /&gt;
 &lt;br /&gt;
Unter Applications&amp;gt;Registration sind Netzwerk- und VoIP-Einstellungen zu finden.&lt;br /&gt;
 &lt;br /&gt;
=== Anleitung für Fritz-Box-Benutzer ===&lt;br /&gt;
Die Fritzboxen bieten bisher leider keine Möglichkeit, den verwendeten DNS&lt;br /&gt;
direkt im Webinterface zu ändern, über Umwege geht es aber doch:&lt;br /&gt;
* Über das Webinterface der Fritzbox die Einstellungen sichern&lt;br /&gt;
* Exportdatei im Texteditor öffnen (am besten nicht Notepad, da der die Unix-Zeilenumbrüche nicht versteht - zur Not geht auch Wordpad)&lt;br /&gt;
* nach overwrite_dns1 suchen (gibt es zwei mal) und da den DNS 84.38.68.30 (von blooza http://www.mikrocontroller.net/topic/170483#1651124 bereitgestellt) oder 188.40.123.50 (von sprites http://spritesmods.com/?art=vpx500 bereitgestellt) eintragen&lt;br /&gt;
* am Anfang der Exportdatei VOR &amp;quot;**** CFGFILE:ar7.cfg&amp;quot; eine Zeile &#039;NoChecks = yes&#039; einfügen, damit die Fritzbox die nun nicht mehr passende Checksumme ignoriert.&lt;br /&gt;
* Einstellungen zurück in die Fritzbox übertragen.&lt;br /&gt;
 &lt;br /&gt;
Wenn die Telefone entsperrt sind, den DNS wieder entfernen (Es ist&lt;br /&gt;
vielleicht eine ganz gute Idee, wenn man da zwei unabhängige DNS-Server&lt;br /&gt;
einträgt, so umgeht man auch gleich providerseitige DNS-Sperren)&lt;br /&gt;
 &lt;br /&gt;
==== Alternative ====&lt;br /&gt;
Wer sich den nicht ganz ungefährlichen Weg mit den anpassungen an der Fritzbox erspahren will, wechselt seine Fritzbox in den Expertenmodus. Danach kann man unter System - Netzwerk bei dem Punkt &amp;quot;IP adresse der Fritzbox ändern&amp;quot; bei vielen modellen den internen DHCP abschalten. Dann unter windows z.B. tftpd32 (http://tftpd32.jounin.net/) starten, in dessen DHCP-Server die Fritzbox als Gateway und den entsprechenden &amp;quot;modding-dns&amp;quot; eintragen und das Telefon neustarten.&lt;br /&gt;
 &lt;br /&gt;
War das Telefon schonmal angemeldet, versucht es die selbe IP vom neuen DHCP zu erzwingen, was tftpd32 nicht wirklich mag. Daher im tftpd32 die lease-ip bei 2 beginnen lassen und eine range von 250 eintragen, damit die vom Telefon verlangte IP auch im Adresspool des dhcp servers vorhanden ist.&lt;br /&gt;
 &lt;br /&gt;
=== Anleitung fli4l ===&lt;br /&gt;
Mit dem [http://www.fli4l.de fli4l] ist das ganze ganz einfach.&lt;br /&gt;
 &lt;br /&gt;
In der Datei config/dns_dhcp.txt den DNS  Redirect für die zwei DNS-Name Konfigurieren.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;file&amp;gt;&lt;br /&gt;
    DNS_REDIRECT_N=&#039;2&#039;                # number of redirected domains&lt;br /&gt;
    DNS_REDIRECT_1=&#039;ntp.xs4all.nl&#039;    # 1st redirected domain&lt;br /&gt;
    DNS_REDIRECT_1_IP=&#039;188.40.123.50&#039; # IP of redirected domain&lt;br /&gt;
 &lt;br /&gt;
    DNS_REDIRECT_2=&#039;vpcm-001.cust.kpn.net&#039;&lt;br /&gt;
    DNS_REDIRECT_2_IP=&#039;188.40.123.50&#039;&lt;br /&gt;
&amp;lt;/file&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
= Hardware =&lt;br /&gt;
 &lt;br /&gt;
== verwendete Komponenten ==&lt;br /&gt;
 &lt;br /&gt;
* MCU: [http://www.mikrocontroller.net/attachment/72258/datasheet.pdf Freescale MC9328MX21] (ARM9) @ 266MHz ([http://en.wikipedia.org/wiki/I.MX21 Wikipedia_englisch])&lt;br /&gt;
** gehört zur ARM9E-Familie: ARMv5TEJ -&amp;quot;IntructionSet&amp;quot; (ARM926EJ-S)&lt;br /&gt;
** [http://www.freescale.com/files/32bit/doc/ref_manual/MC9328MX21RM.pdf MC9328MX21 Applications Processor Reference Manual]&lt;br /&gt;
* PC-to-TV-Konverter-Chip: [http://www.mikrocontroller.net/attachment/73579/Data_Sheets.zip FS455LF]&lt;br /&gt;
* WLAN: Marvell 88w8385, als Modul von [http://www.mikrocontroller.net/attachment/72802/WM-G-MR-01-v27__01192006.pdf WM-G-MR-01] (VP5500) / Philips [http://www.mikrocontroller.net/attachment/73812/BGW211_Preliminary_Datasheet_v1.1.pdf BGW211], on-board (VP6500)&lt;br /&gt;
* SDRAM: 2 x [http://www.mikrocontroller.net/attachment/72461/K4S56163LF.pdf K4S56163LF] - 4M x 16Bit x 4 Banks im VP5500&lt;br /&gt;
* SDRAM: 1 x [http://www.mikrocontroller.net/attachment/73520/Samsung_64MB_K4M51323PC_1_8V.pdf K4M51323PC_1_8V] - 4M x 32Bit x 4 Banks im VP6500&lt;br /&gt;
* Flash: 2 x ws128j0pbfw00 [http://www.mikrocontroller.net/attachment/72462/S29WS064J.pdf S29WS128J/064J] 128/64 Megabit (8/4 M x 16-Bit) CMOS 1.8 Volt-only Simultaneous Read/Write, Burst Mode Flash Memory im VP5500&lt;br /&gt;
* Flash: 1 x [http://www.mikrocontroller.net/attachment/73521/S29GL512N.pdf S29GL512N] - 512 Megabit, 3.0 Volt-only Page Mode Flash Memory im VP6500&lt;br /&gt;
* Kamera: dc-4626.a5 by chicony&lt;br /&gt;
* Display: Samsung LTS220QC (HD66772 Controller)&lt;br /&gt;
 &lt;br /&gt;
== Messungen ==&lt;br /&gt;
 &lt;br /&gt;
=== Stromaufnahme ===&lt;br /&gt;
 &lt;br /&gt;
==== VP5500 ====&lt;br /&gt;
FIXME&lt;br /&gt;
 &lt;br /&gt;
==== VP6500 ====&lt;br /&gt;
   &lt;br /&gt;
Konfiguration: VP6500 mit aktivierter serieller Konsole an Labornetzteil, Spannung 3.67V (Bei weniger bootet es anscheinend aufgrund von Stromspitzen nicht richtig und vermeldet auf der seriellen Konsole ein &#039;battery low&#039; und schaltet sich danach selbst ab. Diese Spannung sollte noch so gerade &#039;safe&#039; sein, geht man davon aus, daß da ein Step-Up im Innern am werkeln ist und noch ein geringer Abfall über die Schottky-Diode einzurechnen ist).&lt;br /&gt;
 &lt;br /&gt;
===== Telefon =====&lt;br /&gt;
* Booten: bis zu 420mA&lt;br /&gt;
* Einbuchen: ca. 400mA&lt;br /&gt;
* mit abgeschaltetem Display, aber eingebucht und laufend (idle): ca. 80mA&lt;br /&gt;
* mit angeschaltetem Display, eingebucht und idle: ca. 190mA&lt;br /&gt;
* mit 100% Prozessor-Last (von serieller Konsole ausgeführt: &amp;quot;while true; do true; done&amp;quot;): ca. 60mA mehr als idle (Scheint aber auch größere Sprünge für andere CPU-Last zu geben)&lt;br /&gt;
* im &#039;Deep Sleep&#039; (wird ein paar Minuten nach Einschalten erreicht): &amp;lt;10mA (!), mit kurzen Wachphasen mit erheblichem Stromverbrauch (&amp;gt;100mA). Beachte: Die serielle Konsole ist in diesem Modus auch nicht mehr aktiv, das Telefon ist aber nicht abgestürzt (Tastendruck aktiviert die Konsole wieder).&lt;br /&gt;
* Telefonieren ca 500mA&lt;br /&gt;
* Telefonieren mit Webcam ca 550mA&lt;br /&gt;
 &lt;br /&gt;
===== Ladegerät =====&lt;br /&gt;
* Phone nicht in der Ladeschale: &amp;lt; 0.2W&lt;br /&gt;
* Phone wird geladen: ca 4W&lt;br /&gt;
 &lt;br /&gt;
== System-Takte ==&lt;br /&gt;
# cat /proc/systclk&lt;br /&gt;
System clocks state:&lt;br /&gt;
    Ref clock :      32768Hz  (int, premult by 512)&lt;br /&gt;
    MPLL clock:  263999905Hz  (computed: 264000000Hz)&lt;br /&gt;
    SPLL clock:  163840000Hz  (computed: 163840000Hz)&lt;br /&gt;
    CPU clock :  263999905Hz  (PERSC  = 0)&lt;br /&gt;
    Bus clock :  132000000Hz  (BCLKDIV = 1, computed: 131999952Hz)&lt;br /&gt;
    CSI clock :  unknown      (cannot read register CSICR1)&lt;br /&gt;
    USB clock :  20480000Hz  (USB_DIV = 7)&lt;br /&gt;
    Wait State:  CS0U[WSC] = 10, CS0U[WSC] = 48&lt;br /&gt;
    loops_per_jiffy = 665058&lt;br /&gt;
 &lt;br /&gt;
== Innenleben ==&lt;br /&gt;
 &lt;br /&gt;
=== Zerlegen des VP5500 ===&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
Datei:01_offen_von_Hinten.JPG|1. Geöffnetes Akkufach&lt;br /&gt;
Datei:02_Blende_entfernt.JPG|2. hintere Schwarze Blende entfernt&lt;br /&gt;
Datei:03_Rückseite_entfernt.JPG|3. Schalenrückteil entfernt&lt;br /&gt;
Datei:04_aufhebeln_Vorderteil.JPG|4. Druck nach außen&lt;br /&gt;
Datei:05_vorderteil_entfernt.JPG|5. entferntes Vorderteil&lt;br /&gt;
Datei:06_Elektronik_entfernt.JPG|6. entfernte Elektronik&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
# das Akkufach muss geöffnet und die Schrauben entfernt werden&lt;br /&gt;
# hinter der rückseitigen schwarzen Blende befinden sich zwei Schrauben, die entfernt werden müssen&lt;br /&gt;
#* Hierzu am besten mit einem schmalen kleinen Schraubendreher von der Stirnseite aus zwischen die Plastikteile fahren und vorsichtig aufhebeln und den Schraubendreher dabei weiter unter die Blende bewegen.&lt;br /&gt;
# Nun kann einfach das rückseitige Schalenteil abgeschaubt werden&lt;br /&gt;
# das Entfernen des Frontschalenteils ist etwas tricky:&lt;br /&gt;
#* von oben und unten lässt sich ganz gut ein Spalt zur Seite aufweiten&lt;br /&gt;
#* etwas unter der Mitte hängt es aber auf beiden Seiten. Dort befinden sich kleine Plastikbügel, die recht leicht zerbrechen.&lt;br /&gt;
#* Mit einem sehr schmalen Schraubendreher in eine der Lücken fahren (anfangen auf der Seite ohne Tasten) und den Schraubendreher nach innen drücken, so das der Druck in der Seite nach außen wirkt.&lt;br /&gt;
#* Mit etwas Geschick bekommt man das so ohne Bruch ab, es ist aber auch nicht kritisch, wenn der Bügel ein wenig anbricht)&lt;br /&gt;
# Die Platine zu entfernen ist nicht ganz so schwierig.&lt;br /&gt;
#* Zuerst die Seite auf der keine Knöpfe sind:&lt;br /&gt;
#* vorsichtig diese Seite leicht anheben. Am unteren Ende ist auf die Kontakte zu achten&lt;br /&gt;
#* dann versuchen die Platine seitlich nach oben aus dem Gehäuse zu ziehen&lt;br /&gt;
#* dabei auf das Lautsprecherkabel und den Kamerakonnektor achten&lt;br /&gt;
# Zusammenbau genauso, nur umgedreht ;)&lt;br /&gt;
#* nicht die Lautsprecher- und Kamera-Stecker vergessen&lt;br /&gt;
 &lt;br /&gt;
=== Bilder vom VP5500 Innenleben ===&lt;br /&gt;
&amp;lt;gallery widths=&amp;quot;240&amp;quot; &amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Datei:Oberseite.jpg | Ansicht der Oberseite&lt;br /&gt;
Datei:Oberseite_beschriftet.jpg | Oberseite mit Beschriftung der Bauteile&lt;br /&gt;
Datei:Drumherum.jpg | Übersicht über die Komponenten&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;gallery widths=&amp;quot;240&amp;quot; &amp;gt;&lt;br /&gt;
Datei:Kontakte_Oberseite.jpg | UART-Schnittstelle Oberseite&lt;br /&gt;
Datei:Kontakte_Unterseite.jpg | JTAG-Schnittstelle Unterseite&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
=== Testpins am VP5500 ===&lt;br /&gt;
Original Liste von [http://www.mikrocontroller.net/topic/170483#1646514 Tino] [[Media:Philips vp5500 Liste Testpins.pdf|herrunterladen]].&lt;br /&gt;
 &lt;br /&gt;
[[Bild:Philips vp5500 testpins 1.jpg|thumb| Testpins auf der Rückseite]]&lt;br /&gt;
[[Bild:Philips vp5500 testpins 2.jpg|thumb| Frontseite: Die ICs wurden zum Messen ausgelötet.]]&lt;br /&gt;
 &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Testpin Nr.  !!    verbunden zu !! Funktion&lt;br /&gt;
|-&lt;br /&gt;
|  1      ||                  LED || unbekannt&lt;br /&gt;
|-&lt;br /&gt;
|    2    ||            Kamera Pin 8 an CN1 || unbekannt&lt;br /&gt;
|-&lt;br /&gt;
|    3    ||                  Pin 4 an IC1 || unbekannt&lt;br /&gt;
|-&lt;br /&gt;
|    4    ||                z.B. IC5 Pin V 18 || VDDA&lt;br /&gt;
|-&lt;br /&gt;
|    5    ||                      GND || GND&lt;br /&gt;
|-&lt;br /&gt;
|    6    ||                      NC || NC&lt;br /&gt;
|-&lt;br /&gt;
|    7    ||                Pin E 16 an IC5 || SAP_CLK&lt;br /&gt;
|-&lt;br /&gt;
|    8    ||                Pin 1 an CN 3 || Lautsprecher&lt;br /&gt;
|-&lt;br /&gt;
|    9    ||                Pin 2 an CN 3 || Lautsprecher&lt;br /&gt;
|-&lt;br /&gt;
|    10    ||                  Pin an CN 4 || ?&lt;br /&gt;
|-&lt;br /&gt;
|    11    ||                Pin an CN 4 || ?&lt;br /&gt;
|-&lt;br /&gt;
|    12    ||                  Pin an CN 4 || ?&lt;br /&gt;
|-&lt;br /&gt;
|    13    ||                Pin L 16 an IC5 || UART2_TXD&lt;br /&gt;
|-&lt;br /&gt;
|    14    ||              Pin C 12 an IC5 || USBH1_RXDM&lt;br /&gt;
|-&lt;br /&gt;
|    15  ||                Pin H 12 an IC5 || USBH1_TXDP&lt;br /&gt;
|-&lt;br /&gt;
|    16    ||              Pin B 19 an IC5 || CSPI2_SS2&lt;br /&gt;
|-&lt;br /&gt;
|    17  ||                Pin B16 an IC5 || SSI2_FS&lt;br /&gt;
|-&lt;br /&gt;
|    18    ||              Pin F 18 an IC5 || KP_ROW0&lt;br /&gt;
|-&lt;br /&gt;
|    19    ||                Pin K 18 an IC5 || KP_COL4&lt;br /&gt;
|-&lt;br /&gt;
|    20    ||                Pin L 19 an IC5 || UART3_TXD&lt;br /&gt;
|-&lt;br /&gt;
|    21    ||              Pin T 14 an IC5 || RESET_IN&lt;br /&gt;
|-&lt;br /&gt;
|    22    ||    geht an + des Kondensators neben IC6 || unbekannt&lt;br /&gt;
|-&lt;br /&gt;
|    23  ||                Pin D 13 an IC 9 || CLKOUT&lt;br /&gt;
|-&lt;br /&gt;
|    24      ||            Pin E 13 an IC 9 || CLKIN_P&lt;br /&gt;
|-&lt;br /&gt;
|    25    ||                Pin A 9 an IC 9 || DAC_D&lt;br /&gt;
|-&lt;br /&gt;
|    26    ||                Pin A 8 an IC 9 || DAC_A&lt;br /&gt;
|-&lt;br /&gt;
|    27    ||                Pin A 7 an IC 9 || DAC_B&lt;br /&gt;
|-&lt;br /&gt;
|    28    ||              Pin A 6 an IC 9 || DAC_C&lt;br /&gt;
|-&lt;br /&gt;
|    29      ||            Pin L 13 an IC 5 || UART1_TXD&lt;br /&gt;
|-&lt;br /&gt;
|    30    ||              Pin T 16 an IC 5 || BOOT1&lt;br /&gt;
|-&lt;br /&gt;
|    31  ||                Pin K 10 an IC 5 || UART1_RXD&lt;br /&gt;
|-&lt;br /&gt;
|    32    ||              Pin U 17 an IC 5 || BOOT2&lt;br /&gt;
|-&lt;br /&gt;
|    33    ||                Pin 9 an IC 23 || unbekannt&lt;br /&gt;
|-&lt;br /&gt;
|    34    ||                Pin D 19 an IC5 || CSPI2_SCLK&lt;br /&gt;
|-&lt;br /&gt;
|    35    ||              Pin C 14 an IC5 || TIN&lt;br /&gt;
|-&lt;br /&gt;
|    36    ||                Pin C 19 an IC5 || CSPI2_SS1&lt;br /&gt;
|-&lt;br /&gt;
|    37  ||                Pin D 18 an IC5 || CSPI2_SS0&lt;br /&gt;
|-&lt;br /&gt;
|    38    ||              Pin E 19 an IC5 || CSPI2_MOSI&lt;br /&gt;
|-&lt;br /&gt;
|    39    ||              Pin H 19 an IC5 || PWMO&lt;br /&gt;
|-&lt;br /&gt;
|    40  ||            Pin J 9 an IC 7 und IC 8 || VDD&lt;br /&gt;
|-&lt;br /&gt;
|    41  ||                Pin J 19 an IC 5 || KP_COL2&lt;br /&gt;
|-&lt;br /&gt;
|    42  ||                Pin K 16 an IC 5 || KP_COL3&lt;br /&gt;
|-&lt;br /&gt;
|    43  ||                Pin J 11 an IC 5 || KP_ROW2&lt;br /&gt;
|-&lt;br /&gt;
|44      ||    Pin J 17 an IC 5 || KP_COL1&lt;br /&gt;
|-&lt;br /&gt;
|45  ||        Pin G 19 an IC 5 || KP_ROW4&lt;br /&gt;
|-&lt;br /&gt;
|46  ||        Pin G 17 an IC 5 || KP_ROW3&lt;br /&gt;
|-&lt;br /&gt;
|47  ||    Pin D 5 an IC 10 und IC 11 || ACC&lt;br /&gt;
|-&lt;br /&gt;
|48 ||          Pin G 16 an IC 5 || KP_ROW1&lt;br /&gt;
|-&lt;br /&gt;
|49  ||        Pin J 18 an IC 5 || KP_COL0&lt;br /&gt;
|-&lt;br /&gt;
|50  ||        Pin V 18 an IC 5 || VDDA&lt;br /&gt;
|-&lt;br /&gt;
|51 ||      Pin 2 an CN KB-Stecker || ?&lt;br /&gt;
|-&lt;br /&gt;
|52 ||          Pin 2 an IC 15 ||  ?&lt;br /&gt;
|-&lt;br /&gt;
|53  ||      Pin 4 am LCD Stecker || ?&lt;br /&gt;
|-&lt;br /&gt;
|54  ||        Pin E 17 an IC 5 || CSPI2_MISO&lt;br /&gt;
|-&lt;br /&gt;
|55 ||  Pin 1,2,3,10,13 am LCD Stecker || ?&lt;br /&gt;
|-&lt;br /&gt;
|56  ||          Pin 3 an IC 16 ||  ?&lt;br /&gt;
|-&lt;br /&gt;
|57  ||        Pin U 10 an IC 5 || PC_PWRON&lt;br /&gt;
|-&lt;br /&gt;
|58  ||            Pin 1 IC 18 || ?&lt;br /&gt;
|-&lt;br /&gt;
|59  ||      an Diode über IC 16 || ?&lt;br /&gt;
|-&lt;br /&gt;
|60  ||          Pin 3 an IC 25 || ?&lt;br /&gt;
|-&lt;br /&gt;
|61 ||        Ladekontakt positiv || Ladegerät +&lt;br /&gt;
|-&lt;br /&gt;
|62  ||              GND || GND&lt;br /&gt;
|-&lt;br /&gt;
|63  ||        Akku Mittelkontakt || Akkustand? Temperatur?&lt;br /&gt;
|-&lt;br /&gt;
|64 ||      Transistor unter IC 16 || ?&lt;br /&gt;
|-&lt;br /&gt;
|65  ||          Pin 2 an IC 22 || ?&lt;br /&gt;
|-&lt;br /&gt;
|66  ||      Pin 1,12,30 an IC 24 || VSS&lt;br /&gt;
|-&lt;br /&gt;
|67  ||    Kondensator + unter IC 20 || ?&lt;br /&gt;
|-&lt;br /&gt;
|68  ||        Pin 5 an IC 21 || ?&lt;br /&gt;
|-&lt;br /&gt;
|69  ||          Pin 2 an IC 4 || ?&lt;br /&gt;
|-&lt;br /&gt;
|70    ||        Pin 25 an IC24 || MCLK&lt;br /&gt;
|-&lt;br /&gt;
|71  ||      Prozessor Pin W 14 || QVDD&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
=== Testpins am VP6500 ===&lt;br /&gt;
Original Listen von [http://www.mikrocontroller.net/topic/170483#1658720 Tino] herunterladen. [[Media:V6500_Back.xls|Rückseite]], [[Media:V6500_Front.xls|Vorderseite]].&lt;br /&gt;
 &lt;br /&gt;
[[Bild:V6500_Back.jpg|thumb| Testpins auf der Rückseite]]&lt;br /&gt;
 &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Testpin Nr.  !!    verbunden zu !! Funktion&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Pin 21 an BGW211EG || POR_N&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Pin A 14 an i.MX21 || TOUT&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Pin 46 an BGW211EG || JTAG_TDI&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Pin 44 an BGW211EG || JTAG_TCLK&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Pin 42 an BGW211EG || JTAG_TDO&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Pin 47 an BGW211EG || JTAG_TRST_N&lt;br /&gt;
|-&lt;br /&gt;
| 7 || PIN 45 an BGW211EG || JTAG_TMS&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Pin 43 an BGW211EG || JTAG_RTCLK&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Pin C 14 an i.MX21 || TIN&lt;br /&gt;
|-&lt;br /&gt;
| 10 || VDD || VDD&lt;br /&gt;
|-&lt;br /&gt;
| 11 || Pin K 10 an i.MX21 || UART1_RXD&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Pin L 13 an i.MX21 || UART1_TXD&lt;br /&gt;
|-&lt;br /&gt;
| 13 || GND || GND&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Pin U 17 an i.MX21 || BOOT2&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Pin V 16 an i.MX21 || BOOT0&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
[[Bild:V6500_Front.jpg|thumb| Frontseite: Die ICs wurden zum Messen ausgelötet.]]&lt;br /&gt;
 &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
! Testpin Nr.  !!    verbunden zu !! Funktion&lt;br /&gt;
|-&lt;br /&gt;
| 1 || Pin 29 von BGW211EG &amp;amp; F 16 an i.MX21 || RESET_N / CSPI1_SS1&lt;br /&gt;
|-&lt;br /&gt;
| 2 || Pin 28 an BGW211EG &amp;amp; J 12 an i.MX21 || SPI_DAT_MOSI / CSPI1_MOSI&lt;br /&gt;
|-&lt;br /&gt;
| 3 || Pin 27 an BGW211EG &amp;amp; F 19 an i.MX21 || SPI_SS_N / CSPI1_SS0&lt;br /&gt;
|-&lt;br /&gt;
| 4 || Pin 26 an BGW21EG &amp;amp; F 17 an i.MX21 || SPI_DAT_MISO / CSPI1_MISO&lt;br /&gt;
|-&lt;br /&gt;
| 5 || Pin 25 an BGW211EG &amp;amp; H 10 an i.MX21 || SPI_CLK / CSPI1_SCLK&lt;br /&gt;
|-&lt;br /&gt;
| 6 || Pin 24 an BGW211EG &amp;amp; H 11 an i.MX21 || SPI_EXT_INT / CSPI1_RDY&lt;br /&gt;
|-&lt;br /&gt;
| 7 || Pin 41 an BGW211EG || UART_TX&lt;br /&gt;
|-&lt;br /&gt;
| 8 || Pin 40 an BGW211EG || UART_RX&lt;br /&gt;
|-&lt;br /&gt;
| 9 || Transistor unter Testpunkt || ?&lt;br /&gt;
|-&lt;br /&gt;
| 10 || GND || GND&lt;br /&gt;
|-&lt;br /&gt;
| 11 || LED || ?&lt;br /&gt;
|-&lt;br /&gt;
| 12 || Pin 8 am Kamerastecker || ?&lt;br /&gt;
|-&lt;br /&gt;
| 13 || Pin 18 am Kamerastecker || ?&lt;br /&gt;
|-&lt;br /&gt;
| 14 || Pin E 13 &amp;amp; H12 an FS455 || CLKIN / PREF&lt;br /&gt;
|-&lt;br /&gt;
| 15 || Pin D 13 an FS455 || CLKOUT&lt;br /&gt;
|-&lt;br /&gt;
| 16 || Pin A 11 an FS455 || XTAL_OUT&lt;br /&gt;
|-&lt;br /&gt;
| 17 || VDD von FS455 || VDD&lt;br /&gt;
|-&lt;br /&gt;
| 18 || Pin 15 &amp;amp; 16 am Displayconnector || ?&lt;br /&gt;
|-&lt;br /&gt;
| 19 || geht an 2 Dioden links daneben || ?&lt;br /&gt;
|-&lt;br /&gt;
| 20 || Pin M 19 an i.MX21 || UART1_CTS&lt;br /&gt;
|-&lt;br /&gt;
| 21 || Pin M 18 an i.MX21 || UART1_RTS &amp;amp; GND ??&lt;br /&gt;
|-&lt;br /&gt;
| 22 || VDDan i,MX21 || VDD&lt;br /&gt;
|-&lt;br /&gt;
| 23 || Pin G 10 an i.MX21 || USB_BYP&lt;br /&gt;
|-&lt;br /&gt;
| 24 || Pin A 19 an i.MX21 || SSI3_FS&lt;br /&gt;
|-&lt;br /&gt;
| 25 || Pin D 17 an i.MX21 || SSI2_CLK&lt;br /&gt;
|-&lt;br /&gt;
| 26 || VDD an i.MX21 || VDD&lt;br /&gt;
|-&lt;br /&gt;
| 27 || Pin T 17 an i.MX21 || SD1_D3&lt;br /&gt;
|-&lt;br /&gt;
| 28 || Pin A 15 an i.MX21 || SAP_TXDAT&lt;br /&gt;
|-&lt;br /&gt;
| 29 || GND || GND&lt;br /&gt;
|-&lt;br /&gt;
| 30 || Pin T 14 an i.MX21 || RESET_IN&lt;br /&gt;
|-&lt;br /&gt;
| 31 || Pin R 19 an i.MX21 || TRST&lt;br /&gt;
|-&lt;br /&gt;
| 32 || Pin P 19 an i.MX21 || TMS&lt;br /&gt;
|-&lt;br /&gt;
| 33 || Pin N 17 an i.MX21 || TCK&lt;br /&gt;
|-&lt;br /&gt;
| 34 || Pin K 11 an i.MX21 || TDO&lt;br /&gt;
|-&lt;br /&gt;
| 35 || Pin P 18 an i.MX21 || TDI&lt;br /&gt;
|-&lt;br /&gt;
| 36 || Pin 13 an TLV320 || OUTP2&lt;br /&gt;
|-&lt;br /&gt;
| 37 || Pin 14 an TLV320 || OUTMV&lt;br /&gt;
|-&lt;br /&gt;
| 38 || Pin 15 an BGW211EG || VDD&lt;br /&gt;
|-&lt;br /&gt;
| 39 || Pin an Klinkenbuchse || ?&lt;br /&gt;
|-&lt;br /&gt;
| 40 || Pin an Klinkenbuchse || ?&lt;br /&gt;
|-&lt;br /&gt;
| 41 || ? || ?&lt;br /&gt;
|-&lt;br /&gt;
| 42 || LED Tastatur || ?&lt;br /&gt;
|-&lt;br /&gt;
| 43 || LED Tastatur || ?&lt;br /&gt;
|-&lt;br /&gt;
| 44 || Pin 1,8 an 20XN2512 &amp;amp; Key ON || PowerON&lt;br /&gt;
|-&lt;br /&gt;
| 45 || Pin 7 an BDR72K || ?&lt;br /&gt;
|-&lt;br /&gt;
| 46 || Pin 2 an BDR72K || ?&lt;br /&gt;
|-&lt;br /&gt;
| 47 || Pin 6 an MRRBGB3 || ?&lt;br /&gt;
|-&lt;br /&gt;
| 48 || LED Tastatur ||  ?&lt;br /&gt;
|-&lt;br /&gt;
| 49 || Pin 10 an MRRBG3 || ?&lt;br /&gt;
|-&lt;br /&gt;
| 50 || LED Tastatur || ?&lt;br /&gt;
|-&lt;br /&gt;
| 51 || geht an Widerstand auf Rückseite ? || ?&lt;br /&gt;
|-&lt;br /&gt;
| 52 || Pin L 13 an i.MX21 || UART1_TXD&lt;br /&gt;
|-&lt;br /&gt;
| 53 || geht an Diode und Kondensator auf der Rückseite || ?&lt;br /&gt;
|-&lt;br /&gt;
| 54 || Pin C 14 an i.MX21 || TIN&lt;br /&gt;
|-&lt;br /&gt;
| 55 || geht an Widerstand auf der Rückseite || ?&lt;br /&gt;
|-&lt;br /&gt;
| 56 || Pin 7 an BDR72K || ?&lt;br /&gt;
|-&lt;br /&gt;
| 57 || Pin K 10 an i.MX21 || UART1_RDX&lt;br /&gt;
|-&lt;br /&gt;
| 58 || Pin U 17 an i.MX21 || BOOT2&lt;br /&gt;
|-&lt;br /&gt;
| 59 || Pin T 16 an i.MX21 || BOOT1&lt;br /&gt;
|-&lt;br /&gt;
| 60 || geht an Widerstand auf der Rückseite || ?&lt;br /&gt;
|-&lt;br /&gt;
| 61 || Pin V 16 an i.MX21 || BOOT0&lt;br /&gt;
|-&lt;br /&gt;
| 62 || LED Tastatur || ?&lt;br /&gt;
|-&lt;br /&gt;
| 63 || LED Tastatur || ?&lt;br /&gt;
|-&lt;br /&gt;
| 64 || Pin 25 an TLV320 || MLCK&lt;br /&gt;
|-&lt;br /&gt;
| 65 || Pin4 an 69W2440D || ?&lt;br /&gt;
|-&lt;br /&gt;
| 66 || VDD von TLV320 || VDD&lt;br /&gt;
|-&lt;br /&gt;
| 67 || geht an Widerstand auf der Rückseite ||  ?&lt;br /&gt;
|-&lt;br /&gt;
| 68 || geht an Widerstand auf der Rückseite || ?&lt;br /&gt;
|-&lt;br /&gt;
| 69 || Pin 65 an MRRBG3 || ?&lt;br /&gt;
|-&lt;br /&gt;
| 70 || GND || GND&lt;br /&gt;
|-&lt;br /&gt;
| 71 || LED Tastatur || ?&lt;br /&gt;
|-&lt;br /&gt;
| 72 || LED Tastatur || ?&lt;br /&gt;
|-&lt;br /&gt;
| 73 || Akku positiv || Plus Akku&lt;br /&gt;
|-&lt;br /&gt;
| 74 || Ladekontakt positiv || Ladekontakt positiv&lt;br /&gt;
|-&lt;br /&gt;
| 75 || Akku positiv || Plus Akku&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
== UART ==&lt;br /&gt;
TIN muss auf low gezogen werden, um die Schnittstelle zu aktivieren.&lt;br /&gt;
Jedoch startet dann das Telefon nicht vollständig (Fix siehe [[#Betrieb mit aktivierter serieller Schnittstelle]], zum rooten langt es jedoch, siehe [[#per serieller Schnittstelle]])&lt;br /&gt;
 &lt;br /&gt;
* Spannungs-Pegel: 3.3V&lt;br /&gt;
* Baudrate: 115200 bps&lt;br /&gt;
* Stopbits: 1&lt;br /&gt;
* Flussteuerung: keine&lt;br /&gt;
=== VP5500 ===&lt;br /&gt;
[[Bild:VP5500_seriell_highlight.svg|100px|UART-Pins VP5500(Frontseite der Platine)]]&lt;br /&gt;
 &lt;br /&gt;
Die serielle Schnittstelle ist unten vom Akkufach aus zugänglich.&lt;br /&gt;
Obiges Bild kennzeichnet die für die serielle Kommunikation benötigten Pins.&lt;br /&gt;
 &lt;br /&gt;
=== VP6500 ===&lt;br /&gt;
[[Bild:VP5600-Serialport-Preliminary.jpg|100px|UART-Pins VP6500]]&lt;br /&gt;
 &lt;br /&gt;
Die serielle Schnittstelle ist unten vom Akkufach aus zugänglich.&lt;br /&gt;
Obiges Bild kennzeichnet die für die serielle Kommunikation benötigten Pins.&amp;lt;br&amp;gt;&lt;br /&gt;
VCC liefert anscheinend die ungeregelte Akkuspannung, Boot-Pins nicht verifiziert.&lt;br /&gt;
 &lt;br /&gt;
== JTAG ==&lt;br /&gt;
[[Bild:jtag.jpg Belegung der JTAG-Pins (Rückseite der Platine)]]&lt;br /&gt;
 &lt;br /&gt;
== Hardware Modifikationen ==&lt;br /&gt;
 &lt;br /&gt;
Nachdem wir ja bereits wissen wie das [[#Zerlegen_des_Telefons]] geht, steht der Nachrüstung von Bauelementen und Schnittstellen generell nichts mehr im Wege.&lt;br /&gt;
 &lt;br /&gt;
=== Buchse für UART ins VP5500 einbauen ===&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
Datei:10_Pins.JPG|1. unbearbeitete Pinreihe&lt;br /&gt;
Datei:11_Pins_bearbeitet.JPG|2. präperierte Pinreihe&lt;br /&gt;
Datei:09_Pads.JPG|3. präperierte Pads&lt;br /&gt;
Datei:12_Pins_ausrichten.JPG|4. Pinreiheausrichten&lt;br /&gt;
Datei:13_Pins_angelötet_1.JPG|5. angelötete Pinreihe&lt;br /&gt;
Datei:14_Pins_angelötet_2.JPG|6. angelötete Pinreihen&lt;br /&gt;
Datei:08_Mittelteil.JPG|7. Mittelteil mit ausgefeiltem Loch&lt;br /&gt;
Datei:15_Mittelteil_zusammengebaut.JPG|8. wieder zusammengesteckt&lt;br /&gt;
Datei:16_in_Aktion.JPG|9.verbundene serielle Schnittstelle&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Zunächst muss das Telefon zerlegt werden ([[#Zerlegen des Telefons]])&lt;br /&gt;
Um das Gehäuse nicht zu beeinträchtigen, habe ich mich dazu entschieden, alles so zu lassen wie es ist und nur kleine Buchsen einzubauen.&lt;br /&gt;
 &lt;br /&gt;
# Hierfür habe ich einreihige gedrehte IC-Sockel genutzt&lt;br /&gt;
# deren Beine abgezwickt, und etwas Lötzinn aufgetragen (mit der langen Reihe kann man die kurzen, schmalen Teile super handhaben)&lt;br /&gt;
# ebendso auf die Pads ein wenig eingezinnt&lt;br /&gt;
# ausrichten und festlöten&lt;br /&gt;
# eine Reihe&lt;br /&gt;
# die zweite Reihe&lt;br /&gt;
# bei der Gehäuseöffnung über den Pins habe ich mit einer feinen Schlüsselfeile den Rand wenig aufgeweitet. An der Gummimatte hab ich nix geändert.&lt;br /&gt;
# fertig&lt;br /&gt;
# und im Einsatz&lt;br /&gt;
 &lt;br /&gt;
=== Anschluss für UART des VP6500 zugänglich machen ===&lt;br /&gt;
Vorteil beim VP6500: es muss dazu nicht zerlegt werden, da sich die Kupferpads unter den Akkus im Akkufach verstecken. Dies ermöglicht eine lötfreie Variante des seriellen Anschlusses. Die Pinbelegung ist unter [[#VP6500_2|UART]] beschrieben.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
Datei:01_Kuli-Molex.jpg|1. Benötigte Teile: Stück Plastik + Molex Stecker&lt;br /&gt;
Datei:02_gefeiltes_Plastik_18_mm.jpg|2. Länge der Aussparung im Batteriefach: 18 mm&lt;br /&gt;
Datei:03_gefeiltes_Plastik_4_mm.jpg|3. Breite der Aussparung im Batteriefach: 4 mm&lt;br /&gt;
Datei:04_gefeiltes_Plastik_passt.jpg|4. Solange feilen bis es passt&lt;br /&gt;
Datei:05_gefeiltes_Plastik_Kerben.jpg|5. Padabstand markiert&lt;br /&gt;
Datei:06_gekerbtes_Plastik_Molex.jpg|6. So bekommt man die Federn aus den Steckern&lt;br /&gt;
Datei:07_Federelement_roh.jpg|7. Frisch aus dem Stecker&lt;br /&gt;
Datei:08_Federelement_offen.jpg|8. Aufgebogen&lt;br /&gt;
Datei:10_Federelement_unter_Plastik.jpg|9. In Plastikführung&lt;br /&gt;
Datei:09_Federelement_umgebogen.jpg|10. Umgebogen&lt;br /&gt;
Datei:11_halbfertig_passt.jpg|11. Kerbung angepasst?&lt;br /&gt;
Datei:12_ganz_fertig1.jpg|12. Mit Heißkleber sichern&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
*1. Da wir 4 Pole anschließen wollen, benötigen wir 4 federnde Teile aus &amp;quot;Molex&amp;quot;-Steckern, wie man sie aus CPU-Lüftern kennt. (Entweder hat man einen 4-poligen für die modernen PWM geregeltn zur Hand den man ausschlachten kann, oder man nimmt zwei dreipolige alte auseinander.)&lt;br /&gt;
*2./3. Ferner braucht man ein Stück Plastik mit den Maßen 4 mm mal 18 mm, welches als Träger für die Federkontakte dienen soll. Die Höhe ist nicht so entscheidend. Man kann z.B. den Clip eines Kugelschreibes passend zuschneiden und feilen.&lt;br /&gt;
*4. Plastikträger so weit zufeilen, dass er in die Aussparung passt (Tip: Bindfaden darum knoten um ihn wieder entfernen zu können)&lt;br /&gt;
*5. Abstände zwischen den Kontakten die kontaktiert werden müssen (TIN, GND, RX, TX : siehe [[#UART|UART]]) markieren und in die Unterseite des Trägers Führungskerben für die Federn sägen. Ebenso braucht man kleine Aussparungen um die Metallzungen von der Platine in das Batteriefach zu führen.&lt;br /&gt;
*6./7. Aus den Molex-Steckern bekommt man die Federn sehr einfach raus, indem man mit einem kleinen flachen Schraubenzieher vorsichtig in die Aussparungen sticht und hinten am Kabel zieht.&lt;br /&gt;
*8. Die einzelnen Metallzungen nun noch auf 90° aufbiegen.&lt;br /&gt;
*9. In die Führungskerbe einschieben.&lt;br /&gt;
*10. Metallzunge umbiegen. (Zange)&lt;br /&gt;
*11. Sind alle Kerbungen und Aussparungen richtig abgemessen und gut zugefeilt, dann passt alles in die Lücke im Batteriefach, ohne dass sich die verschiedenen Metallteile berühren.&lt;br /&gt;
*12. Mit etwas Schrumpfschlauch und Heißkleiber kann man dem Verrutschen der Metallzungen vorbeugen und die Kurzschlußwahrscheinlichkeit senken. Ferner dient der Heißkleber als Kraftüberträger, damit die Batterien die leicht federnden Metallzungen fest auf die Kontakte auf der Platine drücken können.&lt;br /&gt;
*13. Batterien einsetzen. Ohne diese wird das ganze irgendwann doch wieder rausfallen und die Verbindung von Anfang an unzuverlässig sein.&lt;br /&gt;
 &lt;br /&gt;
Problembehandlung:&lt;br /&gt;
* Kein Kontakt: (Man kann z.B. die Masse auf Durchgang prüfen.)&lt;br /&gt;
** Träger nicht tief genug in die Lücke gedrückt: Mit schmalem Schraubenzieher nachdrücken. Meistens auf der Seite notwendig wo die Metallzungen nach oben kommen.&lt;br /&gt;
** Träger wird nach aussen gedrückt (Metallzungen federn ja): Mehr Heißkleber um mehr Druck durch die Batterien zu bekommen.&lt;br /&gt;
** Träger tief drin, aber trotzdem keine oder unzuverlässige Verbindung: Die Metallzungen auf der Unterseite haben verschiedene &amp;quot;Dicken&amp;quot;, oder die Kerben sind unterschiedlich tief. Ein Tropfen Lötzinn auf die zu niedrigen Metallzungen erledigt dies. (Anmerkung: Der Autor musste überall ein wenig Lötzinn auftragen um die notwendige Dicke und sichere Verbindung zu erreichen.)&lt;br /&gt;
 &lt;br /&gt;
= Nutzung für Voice over IP (VoIP, SIP) =&lt;br /&gt;
 &lt;br /&gt;
== weiterführende Links ==&lt;br /&gt;
 &lt;br /&gt;
*http://de.wikipedia.org/wiki/IP-Telefonie&lt;br /&gt;
*http://de.wikipedia.org/wiki/Session_Initiation_Protocol&lt;br /&gt;
*http://de.wikipedia.org/wiki/H.323&lt;br /&gt;
*http://de.wikipedia.org/wiki/Softphone&lt;br /&gt;
 &lt;br /&gt;
Benutzer ist 103&lt;br /&gt;
 &lt;br /&gt;
Mit [http://ekiga.org Ekiga] konnte so per 103@xxx.xxx.xxx.xxx bei ersten Tests eine Sprachverbindung zum Telefon aufgebaut werden.&lt;br /&gt;
 &lt;br /&gt;
== SIP Einstellungen ==&lt;br /&gt;
 &lt;br /&gt;
Die SIP Einstellungen können alternativ auch direkt in der Datei&lt;br /&gt;
/user_data/data/hpr0userparam.cfg&lt;br /&gt;
vorgenommen werden.&lt;br /&gt;
 &lt;br /&gt;
=== Einstellung für 1und1 ===&lt;br /&gt;
 &lt;br /&gt;
* SIP1:&lt;br /&gt;
** Display Name: ...&lt;br /&gt;
** Username: 49#VORWAHLOHNE0#NUMMER#&lt;br /&gt;
** Telephone Number: 0#VORWAHLOHNE0#NUMMER#&lt;br /&gt;
* Auth:&lt;br /&gt;
** Auth Username: 49#VORWAHLOHNE0#NUMMER#&lt;br /&gt;
** Password: *********&lt;br /&gt;
* Server:&lt;br /&gt;
** sip.1und1.de:5060&lt;br /&gt;
* Proxy:&lt;br /&gt;
** sip.1und1.de:5060&lt;br /&gt;
* RTP:&lt;br /&gt;
** 30000 und 30019&lt;br /&gt;
* STUN:&lt;br /&gt;
** stun.1und1.de&lt;br /&gt;
* STUN Server Port:&lt;br /&gt;
** 3478&lt;br /&gt;
* SIP2:&lt;br /&gt;
** UDP: 5060&lt;br /&gt;
** TCP: 5060&lt;br /&gt;
 &lt;br /&gt;
=== Einstellung für Vodafone NGN (Arcor NGN) ===&lt;br /&gt;
 &lt;br /&gt;
* SIP1:&lt;br /&gt;
** Display Name: ...&lt;br /&gt;
** Username: VORWAHLUNDRUFNUMMER&lt;br /&gt;
** Telephone Number: (leer lassen)&lt;br /&gt;
* Auth:&lt;br /&gt;
** Auth Username: VORWAHLUNDRUFNUMMER&lt;br /&gt;
** Password: *********&lt;br /&gt;
* Server:&lt;br /&gt;
** arcor.de:5060&lt;br /&gt;
* Proxy:&lt;br /&gt;
** VORWAHL.sip.arcor.de:5060&lt;br /&gt;
* RTP:&lt;br /&gt;
** 10000 und 10001&lt;br /&gt;
* STUN:&lt;br /&gt;
** (X) use rport&lt;br /&gt;
* SIP2:&lt;br /&gt;
** UDP: 5060&lt;br /&gt;
** TCP: 5060&lt;br /&gt;
(getestet von Micha mit EasyBox 802; an EasyBox n-WLAN ausschalten)&lt;br /&gt;
 &lt;br /&gt;
=== Einstellung für Sipgate ===&lt;br /&gt;
 &lt;br /&gt;
*SIP1&lt;br /&gt;
**Display Name: Sipgate Username&lt;br /&gt;
**User Name: your SIPgate-ID&lt;br /&gt;
**Telephone Number:  Sipgate-Telefonnummer&lt;br /&gt;
*Auth&lt;br /&gt;
**Authentification UserName: your SIPgate-ID&lt;br /&gt;
**Password: Sipgate Passwort&lt;br /&gt;
*Server&lt;br /&gt;
**SIP register address:port: sipgate.de:5060&lt;br /&gt;
*Proxy&lt;br /&gt;
**SIP proxy1 address:port: sipgate.de:5060&lt;br /&gt;
*RTP Audio Channel&lt;br /&gt;
**RTP: 22800&lt;br /&gt;
**RTCP: 22801&lt;br /&gt;
*RTP Video Channel&lt;br /&gt;
**RTP: 22804&lt;br /&gt;
**RTCP: 22805&lt;br /&gt;
*STUN: [X] use rport&lt;br /&gt;
*SIP2&lt;br /&gt;
**SIP Port Listen&lt;br /&gt;
**for UDP: 5062&lt;br /&gt;
**for TCP: 5062&lt;br /&gt;
**for TCP TLS: 5053&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
SIP Outbound muss leer sein.&lt;br /&gt;
 &lt;br /&gt;
=== Alternative Einstellung für Sipgate ===&lt;br /&gt;
 &lt;br /&gt;
Hinter meiner Freetzbox hat die obige Einstellung nix gebracht - incoming calls wurden nicht signalisiert. Folgendes tut dagegen:&lt;br /&gt;
 &lt;br /&gt;
*SIP1&lt;br /&gt;
**Display Name: Sipgate Username&lt;br /&gt;
**User Name: your SIPgate-ID&lt;br /&gt;
**Telephone Number:  Sipgate-Telefonnummer&lt;br /&gt;
*Auth&lt;br /&gt;
**Authentification UserName: your SIPgate-ID&lt;br /&gt;
**Password: Sipgate Passwort&lt;br /&gt;
*Server&lt;br /&gt;
**SIP register address:port: sipgate.de:5060&lt;br /&gt;
*Proxy&lt;br /&gt;
** leer&lt;br /&gt;
*SIP2&lt;br /&gt;
**Symmetric Mode [X]&lt;br /&gt;
**SIP Port Listen&lt;br /&gt;
**for UDP: 5062&lt;br /&gt;
**for TCP: 5062&lt;br /&gt;
**for TCP TLS: 5053&lt;br /&gt;
*STUN: [x] use rport&lt;br /&gt;
 &lt;br /&gt;
SIP Outbound muss leer sein.&lt;br /&gt;
 &lt;br /&gt;
Ein Videotelefonat von Sipgate zu Sipgate zwischen zwei VP6500 wurde erfolgreich getestet. Gegebenenfalls muss die eigene Videoübertragung noch durch Drücken der Taste &#039;&#039;&#039;Video&#039;&#039;&#039; gestartet werden.&lt;br /&gt;
 &lt;br /&gt;
Bei mir hat es nur per UDP funktioniert, aber mit starken Delays (&amp;gt;1s)&lt;br /&gt;
 &lt;br /&gt;
=== Einstellung für Ekiga.net ===&lt;br /&gt;
 &lt;br /&gt;
*SIP1&lt;br /&gt;
**Display Name: Irgendwas&lt;br /&gt;
**User Name: username&lt;br /&gt;
**Telephone Number: leer&lt;br /&gt;
*Auth&lt;br /&gt;
**Authentication User Name: username&lt;br /&gt;
**Password: password&lt;br /&gt;
*Server&lt;br /&gt;
**SIP register: ekiga.net:5060&lt;br /&gt;
**Protocol: ( ) TCP (*) UDP&lt;br /&gt;
**Expire Timer: 3600&lt;br /&gt;
**Keep Alive: 0&lt;br /&gt;
*Proxy&lt;br /&gt;
**alle leer&lt;br /&gt;
*STUN&lt;br /&gt;
**( ) use rport&lt;br /&gt;
**STUN Server IP address: stun.ekiga.net&lt;br /&gt;
**STUN Server port: 3478&lt;br /&gt;
*SIP2&lt;br /&gt;
**(*) Symmetric Mode&lt;br /&gt;
**UDP: 5060&lt;br /&gt;
**TCP: 5060&lt;br /&gt;
**TCP TLS: 5061&lt;br /&gt;
*OBproxy&lt;br /&gt;
**alle leer&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
Nach der (kostenlosen) Registrierung bei ekiga.net und der Anmeldung des Telefons kann man unter der 500 einen Audio und Video(!) Test machen.&amp;lt;br&amp;gt;&lt;br /&gt;
Weitere features: https://www.ekiga.net/index.php?page=services&amp;lt;br&amp;gt;&lt;br /&gt;
Ekiga teilt keine Festnetz Rufnummern zu, daher ist ein Anruf von/zu Festnetz Telefonen nicht möglich.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Bei Ekiga.net angemeldete Geräte können aber problemlos untereinander telefonieren, sogar mit Video. Da man vom Mainscreen des VP5500/6500 aus direkt nur numerische Kontakte (herkömmliche Telefonnumern) wählen kann, Ekiga.net Telefonnummern aber aus [Benutzername]@ekiga.net bestehen, legt man über das Menü des VP5500/6500 einfach &amp;lt;b&amp;gt;einen neuen Kontakt&amp;lt;/b&amp;gt; (Telefonbuch) an. Als Video-Rufnummer trägt man einfach [Benutzername]@ekiga.net ein, wobei [Benutzername] der Name des Ekiga-Accounts ist, den man erreichen will. Zwischen der Eingabe von Buchstaben, Zahlen und Sonderzeichen kann man dabei mit der &amp;lt;b&amp;gt;[#]&amp;lt;/b&amp;gt;-Taste des VP5500/6500 umschalten.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Sollte bei einem Telefonat über Ekiga Video einmal nicht funktionieren, hilft eventuell die manuelle Aktivierung der Videofunktion mittels der &amp;lt;b&amp;gt;Video-Taste&amp;lt;/b&amp;gt; auf der Tastatur des VP6500&amp;lt;/p&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
=== Einstellung für Fritzbox 7170/7270 und andere mit SIP-Registrar ===&lt;br /&gt;
Die Anmeldung eines Telefons auf der Fritzbox starten (System/Ansicht/&amp;quot;Expertenansicht aktivieren&amp;quot;, dann Telefonie/Telefoniegeräte/&amp;quot;Neues Gerät einrichten&amp;quot;, &amp;quot;Telefon&amp;quot;, &amp;quot;Bitte auswählen&amp;quot;/&amp;quot;LAN/WLAN (IP-Telefon)&amp;quot;) und sich eine Nummer geben lassen,&amp;lt;br&amp;gt; dann in Registration auf dem VPx500 wechseln und die Einstellungen wie unten vornehmen.&amp;lt;br&amp;gt; Anschließend will das Telefon diese Einstellungen aktivieren, vorher noch auf der FB die Anmeldung starten.&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
Im Beispiel will die FB die Nummer 621 vergeben:&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Reiter SIP1&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Display Name: egal &amp;lt;leer lassen&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
User Name: 621&amp;lt;br&amp;gt;&lt;br /&gt;
Telephone Number: 621&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Reiter Auth&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Authentication UserName: 621&amp;lt;br&amp;gt;&lt;br /&gt;
Password: [hier das gleiche, wie auf der FB eingeben]&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Reiter Server&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
SIP register address:port&amp;lt;br&amp;gt;&lt;br /&gt;
192.168.2.1:5060 (IP Bitte auf Euer Netz anpassen) oder alternativ: fritz.box:5060&amp;lt;br&amp;gt;&lt;br /&gt;
Protocol: UDP&amp;lt;br&amp;gt;&lt;br /&gt;
ExpireTime: 3600&amp;lt;br&amp;gt;&lt;br /&gt;
Keep Alive: 300&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Reiter SIP2&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
[ ] Symmetric Mode&amp;lt;br&amp;gt;&lt;br /&gt;
SIP Port Listen&amp;lt;br&amp;gt;&lt;br /&gt;
for UDP: 5060&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;br&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Anmerkungen dazu:&#039;&#039;&#039;&amp;lt;br&amp;gt;&lt;br /&gt;
Protokoll: UDP&amp;lt;br&amp;gt;&lt;br /&gt;
Bei TCP hat das VP6500 nach Minuten oder Stunden immer wieder die Verbindung zur FB verloren.&amp;lt;br&amp;gt;&lt;br /&gt;
Keep Alive: 300&amp;lt;br&amp;gt;&lt;br /&gt;
Die Keep Alive Time habe ich eingestellt, weil ich die TCP Probleme umgehen &amp;lt;br&amp;gt;wollte. Ich denke nicht, dass es zu Problemen bzgl. Akku kommt. Da es so &amp;lt;br&amp;gt;aber perfekt funktioniert, habe ich es gelassen. Das UDP Protokoll kommt zudem mit weniger Netzwerk-Traffic aus.&amp;lt;br&amp;gt;&lt;br /&gt;
Anmeldung:&amp;lt;br&amp;gt;&lt;br /&gt;
Die Anmeldung wurde von der Fritz!Box nicht immer erfolgreich bestätigt. Einfach Weiter klicken und die restlichen Einstellungen vornehmen.&amp;lt;br&amp;gt; Spätestens nach einem Reboot des VPx500 funktioniert alles einwandfrei.&amp;lt;br&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Falls eure Fritz!Box keine Möglichkeit bietet, ein IP-Telefon anzumelden, empfehle ich euch mal in das http://wiki.ip-phone-forum.de/skript:speedport2fritz einzulesen.&amp;lt;br&amp;gt;&lt;br /&gt;
Bzw. mal im IP-Phone-Forum nach SIP-Registrar suchen.&amp;lt;br&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Der SIP Listen Port 5060 hat mich viel Zeit gekostet - stand noch von sipgate direkt auf 5062 und das VP5500 hat sich dann zwar an der fritzbox registriert aber keine eingehenden Anrufe empfangen...&lt;br /&gt;
 &lt;br /&gt;
=== Fritz!Box Hinweis ===&lt;br /&gt;
Hinter meiner Fritz!Box konnte ich auf dem Port 5060 keine Incoming Calls bekommen, da die Box auf diesen Port für ihre eigenes System hört.&lt;br /&gt;
Geholfen hat mit dann ein Wechsel auf Port 5061 im Reiter SIP2&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
== Eigener VoIP Server mit Asterisk ==&lt;br /&gt;
 &lt;br /&gt;
*http://www.das-asterisk-buch.de&lt;br /&gt;
 &lt;br /&gt;
===Asterisk auf einer Fritz!Box===&lt;br /&gt;
 &lt;br /&gt;
*http://www.asterisk-kompakt.de/artikel/45-asterisk-auf-fritzbox-phone.html&lt;br /&gt;
 &lt;br /&gt;
== Videogespräche zu anderen Clients / Softphones ==&lt;br /&gt;
=== Ekiga Softphone ===&lt;br /&gt;
 &lt;br /&gt;
Damit Videos klappen, müssen Ekiga und VP6500 über mindestens einen übereinstimmenden Videocodec verfügen, klar. Im Falle des VP6500 ist es wohl so, daß ausschließlich H.263 in verschiedenen Ausprägungen zur Verfügung steht.&lt;br /&gt;
 &lt;br /&gt;
Ekiga kommt jedoch zunächst unter Ubuntu 9.10 nur mit H.261 und Theora Codec. Wir müssen daher den H.263-Codec in Ekiga zusätzlich einhängen.&lt;br /&gt;
 &lt;br /&gt;
Leider ist der H.263-Codec nicht ganz frei zugänglich, sodaß wir eine Fremdquelle benötigen, um den Codec mit dem Paketmanager installieren zu können. Daher muß Bojos Ekiga-Plugin-PPA wie in&lt;br /&gt;
 &lt;br /&gt;
https://launchpad.net/~bojo42/+archive/ekiga&lt;br /&gt;
 &lt;br /&gt;
beschrieben als Paketquelle hinzugefügt werden. Den zugehörigen Schlüssel nicht vergessen!&lt;br /&gt;
Wenn die neue Quelle bekannt gemacht ist, können im Paketmanager nun die&lt;br /&gt;
 &lt;br /&gt;
; Pakete&lt;br /&gt;
: libopal3.6.1-plugins-h263-1998&lt;br /&gt;
: libopal3.6.1-plugins-ilbc&lt;br /&gt;
: libavcodec-dev&lt;br /&gt;
 &lt;br /&gt;
installiert werden. Darauf achten, daß alle Abhängigkeiten sauber erfüllt sind.&lt;br /&gt;
Das H.263-Plugin läßt sich nur installieren, wenn libstdc++6 &amp;gt;= 4.4.0 vorhanden ist, was meines Wissens erst ab Ubuntu 9.10 der Fall ist.&lt;br /&gt;
Nach der Installation dieser Komponenten kann Ekiga neu gestartet werden. Es sollte nun unter Bearbeiten-&amp;gt;Einstellungen-&amp;gt;Video-&amp;gt;Codecs zusätzlich den H.263-Codec anbieten. Durch Verschieben nach oben kann man diesen beim Handshake priorisieren.&lt;br /&gt;
Nach Integration des H.263-Codecs in Ekiga konnte ich mit zwei Sipgate-Accounts störungsfrei, sogar über den gleichen DSL-Anschluß, videofonieren.&lt;br /&gt;
 &lt;br /&gt;
== DEMO MODE ==&lt;br /&gt;
 &lt;br /&gt;
Um den DEMO MODE zwischen einem VP55 und VP65 herzustellen muss man die Dateien&lt;br /&gt;
mit den Einstellungen vom VP55 auf das VP65 übertragen. Diese liegen in&lt;br /&gt;
/usr/local/data/demo/ und es sind vier Dateien. Danach ist die SSID und der KEY&lt;br /&gt;
bei beiden gleich eingerichtet und die beiden Geräte verbinden sich miteinander.&lt;br /&gt;
 &lt;br /&gt;
= Software =&lt;br /&gt;
 &lt;br /&gt;
== Vorsicht Fallen! ==&lt;br /&gt;
Es ist nicht schwer, sich den Zugang zum Telefon abzuschneiden, wenn man nicht aufpasst.&lt;br /&gt;
 &lt;br /&gt;
== Betrieb mit aktivierter serieller Schnittstelle ==&lt;br /&gt;
 &lt;br /&gt;
Das 5500 und das 6500 scheint nicht komplett zu starten wenn man TIN auf low hat&lt;br /&gt;
und die serielle Schnittstelle benutzt. Man kann das Gerät dann nicht normal bedienen. Dies lässt sich ändern indem man in der Datei&lt;br /&gt;
 &lt;br /&gt;
/usr/local/startup/daemon.sh&lt;br /&gt;
 &lt;br /&gt;
ziemlich am Anfang das TINDETECT=&amp;quot;TRUE&amp;quot; ändert auf TINDETECT=&amp;quot;FALSE&amp;quot;&lt;br /&gt;
 &lt;br /&gt;
Danach startet er auch mit aktiver serieller Verbindung komplett durch&lt;br /&gt;
und das Gerät ist ganz normal bedienbar.&lt;br /&gt;
 &lt;br /&gt;
== Grundlagen ==&lt;br /&gt;
Bestimmte Aktionen werden immer wieder benötigt.&lt;br /&gt;
Diese sollen hier kurz beschrieben werden.&lt;br /&gt;
 &lt;br /&gt;
Es werden dennoch grundlegende Kenntnisse von Kommandozeilen vorausgesetzt.&lt;br /&gt;
 &lt;br /&gt;
==== Dateien bearbeiten mit vi ====&lt;br /&gt;
Auf dem Telefon ist der minimalistische Editor vi installiert mit dem Dateien über Telnet bearbeitet werden können.&lt;br /&gt;
Für eine genaue Bedienung bitte Google benutzen.&lt;br /&gt;
Die wichtigsten Bedienelemente werden hier kurz erläutert.&lt;br /&gt;
 &lt;br /&gt;
Datei Öffnen mit &#039;vi Dateipfad&#039;&lt;br /&gt;
vi kennt zwei Modi: Kommando- und Einfüge-Modus.&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;i&#039;&#039;&#039; - wechselt in den Einfüge-Modus, in dem geschrieben werden kann&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;a&#039;&#039;&#039; - anhängen (hinter dem aktuellem Zeichen in den Einfüge-Modus)&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;[Esc]&#039;&#039;&#039; wechselt zurück in den Kommandomodus.&lt;br /&gt;
In diesem kann mittels Pfeil- und Bildlauftasten navigiert werden.&lt;br /&gt;
:x - löscht das Zeichen an Cursor position&lt;br /&gt;
:d&#039;&#039;n&#039;&#039;d - löscht &#039;&#039;n&#039;&#039; Zeile(n) in den Zeilenbuffer (ohne &#039;&#039;n&#039;&#039; = eine Zeile)&lt;br /&gt;
:y&#039;&#039;n&#039;&#039;y - kopiert &#039;&#039;n&#039;&#039; Zeile(n) in den Zeilenbuffer (ohne &#039;&#039;n&#039;&#039; = eine Zeile)&lt;br /&gt;
:p - fügt Inhalt des Zeilenbuffer &#039;&#039;&#039;unter&#039;&#039;&#039; der aktuellen Zeile ein&lt;br /&gt;
:&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;q! - schließt ohne zu speichern&lt;br /&gt;
:&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;w - speichert&lt;br /&gt;
:&amp;lt;nowiki&amp;gt;:&amp;lt;/nowiki&amp;gt;wq - speichert und beenden&lt;br /&gt;
 &lt;br /&gt;
==== Dateien auf das Telefon laden ====&lt;br /&gt;
Um Daten von einem http-Server zu laden, benutzt man&lt;br /&gt;
wget url&lt;br /&gt;
Die Datei wird dann in das aktuelle Verzeichnis geladen, weswegen vorher in das Zielverzeichnis wechseln.&lt;br /&gt;
 &lt;br /&gt;
Um Daten von einem ftp-Server zu laden, benutzt man ftp.&lt;br /&gt;
Auch hier muss vorher in das zielverzeichnis gewechselt werden.&lt;br /&gt;
ftp hostname&lt;br /&gt;
dann gegebenenfalls die Zugangsdaten eingeben und mittels &#039;cd&#039; und &#039;ls&#039; in das Entsprechende Verzeichnis auf dem FTP-Server wechseln&lt;br /&gt;
und anschließend mittels&lt;br /&gt;
get dateiname&lt;br /&gt;
die Datei herunterladen.&lt;br /&gt;
==== Dateien vom Telefon herunterladen ====&lt;br /&gt;
Auch hier bietet sich ein FTP an.&lt;br /&gt;
Mittels &#039;ftp hostname&#039; verbinden, Benutzerdaten eingeben, in das entsprechende FTP-Server-Verzeischnis wechseln und mittels&lt;br /&gt;
put localeDatei&lt;br /&gt;
eine Lokale Datei hochladen.&lt;br /&gt;
 &lt;br /&gt;
==== Alternative: Dropbear ====&lt;br /&gt;
 &lt;br /&gt;
Wurde der dropbear-ssh server installiert [[#Dropbear (SSH-Server) installieren]] können mittels eines Programms mit SCP-Unterstützung (zB. [http://winscp.net/eng/docs/lang:de WinSCP] für Windows) sehr komfortabel Dateien ausgetauscht werden.&lt;br /&gt;
 &lt;br /&gt;
Mit WinSCP können auch Dateien direkt bearbeitet werden.&lt;br /&gt;
Der Client lädt die Datei herunter, öffnet einen Editor und lädt die Datei wieder herauf, wenn diese geändert wurde.&lt;br /&gt;
 &lt;br /&gt;
== Grundkonfiguration, die das Leben erleichtert ==&lt;br /&gt;
=== .bashrc ===&lt;br /&gt;
Die installierte Shell ist die bash. Einstellungen bezieht sie aus der (versteckten) Datei &amp;quot;.bashrc&amp;quot;. Hier kann man sinnvolle Ergänzungen vornehmen, damit sich das Telefon ein bißchen mehr wie ein gewohntes Linux-System verhält:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
alias vim=vi&lt;br /&gt;
PS1=&amp;quot;[\u@\h] \w $ &amp;quot;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
== Backup ==&lt;br /&gt;
=== Backup des Flash ===&lt;br /&gt;
If you want to make a backup of your root partition, you can do as&lt;br /&gt;
follows:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;#!/bin/sh&#039; &amp;gt; /tmp/backup.sh&lt;br /&gt;
echo &#039;cat /dev/mtdb2 2&amp;gt;/dev/null&#039; &amp;gt;&amp;gt; /tmp/backup.sh&lt;br /&gt;
chmod 700 /tmp/backup.sh&lt;br /&gt;
micro_inetd 31337 /tmp/backup.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
This&#039;ll make your device listen for incoming connections on port 31337.&lt;br /&gt;
On your host system you may then simply run&lt;br /&gt;
nc ip.of.your.phone 31337 &amp;gt; fon_rootfs&lt;br /&gt;
et voilà, you got your rootfs packed into a file.&lt;br /&gt;
 &lt;br /&gt;
Note that the backed up file is not ext2, but a jffs2 formatted&lt;br /&gt;
filesystem. These can&#039;t be handled by a simple &amp;quot;mount -o loop&amp;quot; as you&#039;d&lt;br /&gt;
have thought... so here&#039;s how you mount it:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
modprobe jffs2&lt;br /&gt;
modprobe mtdram total_size=65536 erase_size=128&lt;br /&gt;
modprobe mtdblock&lt;br /&gt;
mkdir /tmp/phone-root&lt;br /&gt;
mknod /tmp/phone-mtdb2 b 31 0&lt;br /&gt;
dd if=/your/backup/file of=/tmp/phone-mtdb2&lt;br /&gt;
mount -t jffs2 /tmp/phone-mtdb2 /tmp/phone-root&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
[[#Dateisystem herunterladen]] describes another way to dump the filesystem for closer examination.&lt;br /&gt;
 &lt;br /&gt;
=== Komplettes Backup ===&lt;br /&gt;
Die Datei http://www.mikrocontroller.net/attachment/73323/S91backup_pipe auf das Gerät laden und als ausführbar markieren.&lt;br /&gt;
 &lt;br /&gt;
cd /etc/rc.d/init.d&lt;br /&gt;
wget http://www.mikrocontroller.net/attachment/73323/S91backup_pipe&lt;br /&gt;
chmod +x /etc/rc.d/init.d/S91backup_pipe&lt;br /&gt;
 &lt;br /&gt;
Damit wird eine Art Backup-Server mit dem Boot gestartet.&lt;br /&gt;
wenn man dies nicht möchte kann man das Skript natürlich auch an jeden beliebigen anderen Ort legen und per Hand starten.&lt;br /&gt;
 &lt;br /&gt;
Nun kann man von einem Rechner aus mittels nc (netcat) die Bereiche sichern:&lt;br /&gt;
 &lt;br /&gt;
nc 192.168.1.3 31337 &amp;gt; fon_rootfs&lt;br /&gt;
nc 192.168.1.3 31338 &amp;gt; fon_udata&lt;br /&gt;
nc 192.168.1.3 31339 &amp;gt; fon_usettings&lt;br /&gt;
nc 192.168.1.3 31340 &amp;gt; fon_bootld&lt;br /&gt;
nc 192.168.1.3 31341 &amp;gt; fon_kernel&lt;br /&gt;
 &lt;br /&gt;
Die 192.168.1.3 natürlich mit der IP des Gerätes austauschen, die fon_*&lt;br /&gt;
Dateinamen könnt ihr natürlich auch frei vergeben.&lt;br /&gt;
 &lt;br /&gt;
fon_udata ist die /user_data Partition, fon_usertings dementsprechend&lt;br /&gt;
die /user_settings Partition.&lt;br /&gt;
 &lt;br /&gt;
Der bootld Bereich enthält auch die Parameter. Um das später (falls&lt;br /&gt;
überhaupt nötig) mittels blob zu restaurieren müsste die Datei noch in&lt;br /&gt;
zwei Teile aufgeteilt werden. Der erste enthält dann den reinen&lt;br /&gt;
Bootloader-Bereich, der zweite die Parameter. Wer&#039;s wirklich braucht für&lt;br /&gt;
den kann ich noch ne Anleitung zum Aufteilen geben. Wirklich Sinnvoll&lt;br /&gt;
ist das aber nicht, hat man den Bootloader erstmal mit was anderem&lt;br /&gt;
überschrieben kann man ihn ja auch nicht mehr zum Wiederherstellen&lt;br /&gt;
benutzen....&lt;br /&gt;
 &lt;br /&gt;
=== Zurückspielen der Backups ===&lt;br /&gt;
 &lt;br /&gt;
1) Man braucht ein (die) Backup-Image(s).&lt;br /&gt;
 &lt;br /&gt;
2) Serielle Verbindung zum Telefon&lt;br /&gt;
 &lt;br /&gt;
3) Akku abstecken, wieder anstecken.&lt;br /&gt;
 &lt;br /&gt;
4) Telefon einschalten und im Terminalprogram auf die Tasten kloppen, so&lt;br /&gt;
das man im Bootloader landet. Dabei muss man recht schnell sein. Es&lt;br /&gt;
sollte dann ein Prompt kommen:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
blob&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
5) Nun gibt man ein&lt;br /&gt;
  xdownload param&lt;br /&gt;
Wobei &#039;param&#039; der Teil ist, den man wiederherstellen will:&lt;br /&gt;
* blob - Bootloader (fon_bootld)&lt;br /&gt;
* param - Parameter Bereich (Bootloader oder Kernel?) (fon_bootld)&lt;br /&gt;
* kernel - Der Kernel (fon_kernel)&lt;br /&gt;
* ramdisk - Das Root-Filesystem / (fon_rootfs)&lt;br /&gt;
* ramdisk2 - Das /user_data Filesystem (fon_udata)&lt;br /&gt;
* ramdisk3 - Das /user_settings Filesystem (fon_usettings)&lt;br /&gt;
 &lt;br /&gt;
Beim Backup ist blob + param in einer Datei, müsste man also ggf.&lt;br /&gt;
erstmal aufsplitten.&lt;br /&gt;
 &lt;br /&gt;
6) Er wartet dann auf den Upload. Nun startet man im Terminalprogram den&lt;br /&gt;
Upload des Backup-Images, dazu verwendet man das X-Modem Protokoll.&lt;br /&gt;
 &lt;br /&gt;
7) Kaffee trinken, auf&#039;s Klo gehen, mit Frau/Freundin/Mutter ein Gespräch&lt;br /&gt;
anfangen.&lt;br /&gt;
 &lt;br /&gt;
8) Irgendwann ist der Upload fertig. Dauert halt lange. Man landet&lt;br /&gt;
wieder am &amp;quot;blob&amp;gt;&amp;quot; prompt. Nun gibt man&lt;br /&gt;
flash param&lt;br /&gt;
ein.&lt;br /&gt;
 &lt;br /&gt;
9) Er schreibt nun das, was man hochgeladen hat, in das Flash.&lt;br /&gt;
 &lt;br /&gt;
10) &amp;quot;boot&amp;quot; eingeben. Da Telefon bootet nun normal.&lt;br /&gt;
 &lt;br /&gt;
Achtung: Wenn im Backup nicht die Änderung gemacht wurde damit das&lt;br /&gt;
Telefon auch bei angeschlossener serieller Schnittstelle startet, kommt&lt;br /&gt;
man nicht weiter als wie bis zur Sanduhr. Dann einfach die serielle&lt;br /&gt;
abstecken (Also den TIN pin wieder freigeben) und das Telefon neustarten&lt;br /&gt;
(Akku kurz ab- und wieder anstöpseln)&lt;br /&gt;
 &lt;br /&gt;
=== Dateisystem herunterladen ===&lt;br /&gt;
Zum unkomplizierten Durchsuchen des Dateisystems kann es nützlich sein, dieses vom Gerät zu kopieren.&lt;br /&gt;
 &lt;br /&gt;
Folgende Befehle erzeugen wie beim Backup des Flash einen kleinen Server, dessen Output auf anderer Seite mittels mittels nc abgeholt werden kann:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
echo &#039;#! /bin/sh&#039; &amp;gt; /tmp/backup.sh&lt;br /&gt;
echo &#039;cd /&#039; &amp;gt;&amp;gt; /tmp/backup.sh&lt;br /&gt;
chmod 700 /tmp/backup.sh&lt;br /&gt;
echo &#039;tar cf - bin boot dev etc home lib mnt opt root sbin tmp trace upgrade user_data user_settings usr var 2&amp;gt;/dev/null&#039; &amp;gt;&amp;gt; /tmp/backup.sh&lt;br /&gt;
micro_inetd 31340 /tmp/backup.sh&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Die lange Liste mit Unterverzeichnissen ist notwendig um /proc zu überspringen, was Probleme mit tar verursachen würde.&lt;br /&gt;
 &lt;br /&gt;
Auf einem anderen Linux system (oder cygwin) kann mittels&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
  nc telefon-Ip 31340 &amp;gt; file.tar&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
die Datei abgerufen werden.&lt;br /&gt;
 &lt;br /&gt;
Der Vorgang dauert aber ein ganz paar Minuten.&lt;br /&gt;
 &lt;br /&gt;
Heraus kommt ein Tar-Archiv, was alle Dateien des Gerätes enthält - inclusive der temporären Dateien der Ram-Disks.&lt;br /&gt;
 &lt;br /&gt;
== Erkunden des Systems mit Bordmitteln ==&lt;br /&gt;
 &lt;br /&gt;
=== Ausgabe von &amp;lt;b&amp;gt;&amp;lt;tt&amp;gt;dmesg&amp;lt;/tt&amp;gt;&amp;lt;/b&amp;gt; auf einem VP6500 ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
6&amp;gt;NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.&lt;br /&gt;
NetWinder Floating Point Emulator V0.95 (c) 1998-1999 Rebel.com&lt;br /&gt;
VFS: Mounted root (jffs2 filesystem).&lt;br /&gt;
Freeing init memory: 68K&lt;br /&gt;
PCB version: ind3 v2&lt;br /&gt;
Driver SYSTCLK: SYSTCLK-1.12 (REFERENCED)&lt;br /&gt;
Driver GPIO-1.59 (REFERENCED)&lt;br /&gt;
****p_gpio_init_low_bat****&lt;br /&gt;
GPIO: p_gpio_it_init at 762&lt;br /&gt;
Driver FRAMEBUF-1.12 (REFERENCED)&lt;br /&gt;
Driver SPI-1.20 (REFERENCED) Debug level 3&lt;br /&gt;
 &lt;br /&gt;
u32_spi1_MinLenghtForDMAInTX set to 300&lt;br /&gt;
 &lt;br /&gt;
u32_spi1_MinLenghtForDMAInRX set to 300&lt;br /&gt;
Driver LCD-1.20 (REFERENCED)&lt;br /&gt;
Driver TVLINK-1.45 (REFERENCED)&lt;br /&gt;
Reset from Software Reset.&lt;br /&gt;
Motorola PostProcessor Linux driver ver 0.64 - Copyright (C) 2003 Motorola Inc&lt;br /&gt;
pp: hw ver = 2&lt;br /&gt;
prp_dbg=0&lt;br /&gt;
Motorola PreProcessor Linux driver ver 0.0 - Copyright (C) 2003 Motorola Inc&lt;br /&gt;
hmp4d: base_port=0x10026800 irq=50&lt;br /&gt;
hmp4d: module inserted&lt;br /&gt;
hmp4e: base_port=0x10026c00 irq=49&lt;br /&gt;
hmp4e: Compatble HW found with ID: 0x004c1882&lt;br /&gt;
hmp4e: module inserted. Major = 249&lt;br /&gt;
SPI2:: drv_Init :PID of driver: 134&lt;br /&gt;
SPI2:: drv_Init :ScanList not provided. Will use the default scan list.&lt;br /&gt;
SPI2:: drv_Init :ScanChannelList :1 6 11 14 2 7 12 3 8 13 4 9 5 10&lt;br /&gt;
SPI2:: drv_Init :setting PhyType to: Rf-to-Rf&lt;br /&gt;
SPI2:: drv_Init :Ref.Clock parameter not provided&lt;br /&gt;
SPI2:: drv_Init :Configure target for a reference clock of &#039;default=40&#039; Mhz.&lt;br /&gt;
SPI2:: drvRegEtherDev :Interface Name is: eth%d&lt;br /&gt;
SPI2:: drv_Init :HEOCSIWPOWON: Powering on...&lt;br /&gt;
SPI2:: drvPhase2Init :Protocol Firmware will be loaded by driver ...&lt;br /&gt;
SPI2:: drvPhase2Init :Initializing HHAL (PhgHhalInitialize)...&lt;br /&gt;
Divider : 8&lt;br /&gt;
 &lt;br /&gt;
OCR2 : e4015308 (12582912)&lt;br /&gt;
Reset : 3 / 27 (c497cc00 / e401531c)&lt;br /&gt;
 &lt;br /&gt;
Reset : 3 / 27 (c497cc00 / e401531c)&lt;br /&gt;
GPIO: p_gpio_init_gpio_status at 1262&lt;br /&gt;
GPIO: POWER_FAIL signal NOT detected at GPIO driver init carry on !!!&lt;br /&gt;
GPIO: CHARGE_IN at init&lt;br /&gt;
GPIO: LOW_BAT_OUT at init&lt;br /&gt;
GPIO: No accessory plugged at init.  - Set Video on jack&lt;br /&gt;
GPIO: camera to front at init&lt;br /&gt;
**ChargeStatusPmb=========gpio_Read_ChargeStatus_Ready=1&lt;br /&gt;
SPI2:: PhgOsal_linux_init_thread :assigning thread name and deamonize() ..&lt;br /&gt;
SPI2:: drvPhase2Init :Success&lt;br /&gt;
SPI2:: drvPhase2Init : registering callbacks with HHAL..&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :PHGHHAL_EVNT_INIT_COMPLETE; setting CARRIER_ON&lt;br /&gt;
SPI2:: drvPhase2Init :calling PhgHhalQueueMgmtReq()!&lt;br /&gt;
PhgHhalQueueMgmtReq:1172:HHAL got Init message&lt;br /&gt;
PhgHhalQueueMgmtReq:1217:HHAL done Init message&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :PS wake (0) in Drvmain&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :PHGHHAL_EVENT_DISCONNECT; setting CARRIER_OFF&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :netdev-&amp;gt;flags=0x00001002, IFF_UP=0&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :device was already closed&lt;br /&gt;
SPI2:: drvMgmtCfmHndler :Using MAC Address: 00:08:c6:86:8b:99&lt;br /&gt;
SPI2:: drvPhase2Init :init etherdev; stopping queue, setting CARRIER_OFF&lt;br /&gt;
SPI2:: drv_Init :Philips WLAN Drv - loaded - in state: 1&lt;br /&gt;
SPI2:: drvInit :Philips WLAN Drv - loaded&lt;br /&gt;
SPI2:: drvOpen :opening net device&lt;br /&gt;
SPI2:: drvOpen :Device is not associated!&lt;br /&gt;
SPI2:: drvOpen :Carrier flag is already set to CARRIER_OFF&lt;br /&gt;
SPI2:: drvOpen :Disabling again netqueue&lt;br /&gt;
requested reg.domain code setting = 3&lt;br /&gt;
SPI2:: drvIoctl :set u8LinkAdaptation  : 1 Result=[0]&lt;br /&gt;
SPI2:: drvIoctl :changed HEOCSIWLNADPALLOWRATES: 8 allowed rate codes&lt;br /&gt;
SPI2:: drvInitConnect :Req to connect to new WLAN network&lt;br /&gt;
SPI2:: drvInitConnect :Disabling TX queue and setting CARRIER_OFF&lt;br /&gt;
SPI2:: drvInitConnect :Connecting To AP...&lt;br /&gt;
SPI2:: drvInitConnect :step2&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :PHGHHAL_EVENT_DISCONNECT; setting CARRIER_OFF&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :netdev-&amp;gt;flags=0x00001003, IFF_UP=1&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :device was already opened; stopping queue&lt;br /&gt;
SPI2:: drvInitConnect :step3 : u8Status 255&lt;br /&gt;
SPI2:: drvInitConnect :step5&lt;br /&gt;
SPI2:: drvInitConnect :TIMEDOUT&lt;br /&gt;
SPI2:: drvInitConnect :step6&lt;br /&gt;
SPI2:: drvInitParamsAndPowerOnAndConnect :Connect failed!&lt;br /&gt;
Motorola CSI Linux driver ver 0.1&lt;br /&gt;
- Copyright (C) 2004 Motorola Inc&lt;br /&gt;
 &lt;br /&gt;
Driver SENSOR-1.29 (REFERENCED)&lt;br /&gt;
i2c-client version : 1.9&lt;br /&gt;
Initialize i2c-client-aic14 module&lt;br /&gt;
Module i2c-client-aic14 initialized&lt;br /&gt;
Insert module aic14 (AIC14-1.0)&lt;br /&gt;
Module AIC14 assumes CODEC MCLK already configured for 20480000Hz&lt;br /&gt;
Driver KPP-1.36 (REFERENCED)&lt;br /&gt;
Driver DOZE-1.27 (REFERENCED)&lt;br /&gt;
SPI2:: drvDoScan :Buero (bittorf)&lt;br /&gt;
SPI2:: drvProcessScanCfm :Scan Confirm: Success 1 APs&lt;br /&gt;
SPI2:: drvInitConnect :Req to connect to new WLAN network&lt;br /&gt;
SPI2:: drvInitConnect :Disabling TX queue and setting CARRIER_OFF&lt;br /&gt;
SPI2:: drvInitConnect :Connecting To AP...&lt;br /&gt;
SPI2:: drvInitConnect :step2&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :PHGHHAL_EVNT_INIT_CONNECT; setting CARRIER_ON&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :netdev-&amp;gt;flags=0x00001003, IFF_UP=1&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :device was already opened; enabling queue&lt;br /&gt;
SPI2:: drvInitConnect :step3 : u8Status 8&lt;br /&gt;
SPI2:: drvInitConnect :step4&lt;br /&gt;
SPI2:: drvInitConnect :Successful&lt;br /&gt;
SPI2:: drvInitConnect :step6&lt;br /&gt;
SPI2:: drvIoctl :dot11LongRetryLimitAC0 = 8&lt;br /&gt;
SPI2:: drvIoctl :dot11LongRetryLimitAC1 = 8&lt;br /&gt;
SPI2:: drvIoctl :dot11LongRetryLimitAC2 = 8&lt;br /&gt;
SPI2:: drvIoctl :dot11LongRetryLimitAC3 = 8&lt;br /&gt;
SPI2:: drvIoctl :dot11ShortRetryLimitAC0 = 8&lt;br /&gt;
SPI2:: drvIoctl :dot11ShortRetryLimitAC1 = 8&lt;br /&gt;
SPI2:: drvIoctl :dot11ShortRetryLimitAC2 = 8&lt;br /&gt;
SPI2:: drvIoctl :dot11ShortRetryLimitAC3 = 8&lt;br /&gt;
SPI2:: drvIoctl :PA Request&lt;br /&gt;
SPI2:: drvIoctl :No state change!&lt;br /&gt;
SPI2:: drvIoctl :Fast PS Request&lt;br /&gt;
PhgHhalDoM2SDMA:1661:--&amp;gt;P1&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :PS Ind (1) in Drvmain&lt;br /&gt;
SPI2:: drvStop :Driver Stop: disable TX queue! (usage: 2)&lt;br /&gt;
SPI2:: drvIoctl :Deauth BSSID: 00:1d:7e:18:e3:89&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :PHGHHAL_EVENT_DISCONNECT; setting CARRIER_OFF&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :netdev-&amp;gt;flags=0x00000002, IFF_UP=0&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :device was already closed&lt;br /&gt;
SPI2:: drvOpen :opening net device&lt;br /&gt;
SPI2:: drvOpen :ERROR: Associated, but Carrier flag is set to CARRIER_OFF&lt;br /&gt;
SPI2:: drvDoScan :Buero (bittorf)&lt;br /&gt;
SPI2:: drvProcessScanCfm :Scan Confirm: Success 1 APs&lt;br /&gt;
SPI2:: drvInitConnect :Req to connect to new WLAN network&lt;br /&gt;
SPI2:: drvInitConnect :Disabling TX queue and setting CARRIER_OFF&lt;br /&gt;
SPI2:: drvInitConnect :Connecting To AP...&lt;br /&gt;
SPI2:: drvInitConnect :step2&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :PHGHHAL_EVNT_INIT_CONNECT; setting CARRIER_ON&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :netdev-&amp;gt;flags=0x00000003, IFF_UP=1&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :device was already opened; enabling queue&lt;br /&gt;
SPI2:: drvInitConnect :step3 : u8Status 8&lt;br /&gt;
SPI2:: drvInitConnect :step4&lt;br /&gt;
SPI2:: drvInitConnect :Successful&lt;br /&gt;
SPI2:: drvInitConnect :step6&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :PS Ind (1) in Drvmain&lt;br /&gt;
SPI2:: drvIoctl :PA Request&lt;br /&gt;
PhgHhalDoM2SDMA:1661:--&amp;gt;P0&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :PS wake (0) in Drvmain&lt;br /&gt;
drvSetWOWFilter: Enable UNICAST: Disable ARP: Enable&lt;br /&gt;
Ip addr = 10.63.17.5. LMP=2&lt;br /&gt;
SPI2:: drvIoctl :PA Request&lt;br /&gt;
SPI2:: drvIoctl :No state change!&lt;br /&gt;
SPI2:: drvIoctl :Fast PS Request&lt;br /&gt;
PhgHhalDoM2SDMA:1661:--&amp;gt;P1&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :PS Ind (1) in Drvmain&lt;br /&gt;
Sensor driver: initialize device OV7660&lt;br /&gt;
Warning: Remapping obsolete /dev/fb* minor 32 to 1&lt;br /&gt;
SPI2:: drvIoctl :dot11LongRetryLimitAC0 = 4&lt;br /&gt;
SPI2:: drvIoctl :dot11LongRetryLimitAC1 = 4&lt;br /&gt;
SPI2:: drvIoctl :dot11LongRetryLimitAC2 = 4&lt;br /&gt;
SPI2:: drvIoctl :dot11LongRetryLimitAC3 = 4&lt;br /&gt;
SPI2:: drvIoctl :dot11ShortRetryLimitAC0 = 4&lt;br /&gt;
SPI2:: drvIoctl :dot11ShortRetryLimitAC1 = 4&lt;br /&gt;
SPI2:: drvIoctl :dot11ShortRetryLimitAC2 = 4&lt;br /&gt;
SPI2:: drvIoctl :dot11ShortRetryLimitAC3 = 4&lt;br /&gt;
SPI2:: drvIoctl :PA Request&lt;br /&gt;
PhgHhalDoM2SDMA:1661:--&amp;gt;P0&lt;br /&gt;
SPI2:: drvHhalEventIndicationHandler :PS wake (0) in Drvmain&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
=== Ausgabe von &amp;lt;b&amp;gt;&amp;lt;tt&amp;gt;logread&amp;lt;/tt&amp;gt;&amp;lt;/b&amp;gt; auf einem VP6500 ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Jan  1 00:00:00 imx21 syslog.info syslogd started: BusyBox v0.60.0 (2007.02.28-13:39+0000)&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.emerg klogd: klogd started: BusyBox v0.60.0 (2007.02.28-13:39+0000)&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: Linux version 2.4.20-celf3 (root@wbul04) (gcc version 3.3.2) #1 Wed Feb 28 13:30:26 UTC 2007&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: CPU: ARM926EJ-Sid(wb) [41069264] revision 4 (ARMv?(8))&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: CPU: D undefined 14 cache&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: CPU: I cache: 16384 bytes, associativity 4, 32 byte lines, 128 sets&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: CPU: D cache: 16384 bytes, associativity 4, 32 byte lines, 128 sets&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: Machine: Freescale i.MX2 ADS&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: FCLK=266000 kHz  HCLK=133000 kHz  IPGCLK=66500 kHz&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: PERCLKs: 1=44333 KHz  2=33250 kHz  3=44333 kHz  4=88666 kHz&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: On node 0 totalpages: 16384&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: zone(0): 16384 pages.&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: zone(1): 0 pages.&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: zone(2): 0 pages.&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: Kernel command line: root=/dev/mtdblock2 noinitrd ip=none mtdparts=s29gl512n:256k@0x00000000&lt;br /&gt;
(bootloader)ro,896k@0x00040000(kernel)ro,50432k@0x00120000(fs#1),12800k@0x03260000(fs#2),1152k@0x03EE0000(fs#3)&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.debug klogd: Relocating machine vectors to 0xffff0000&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: Console: colour dummy device 80x30&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: Calibrating delay loop (skipped)... 132.71 BogoMIPS&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: Memory: 64MB = 64MB total&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.notice klogd: Memory: 63052KB available (1366K code, 299K data, 68K init)&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: Dentry cache hash table entries: 8192 (order: 4, 65536 bytes)&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: Inode cache hash table entries: 4096 (order: 3, 32768 bytes)&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: Mount-cache hash table entries: 1024 (order: 1, 8192 bytes)&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: Buffer-cache hash table entries: 4096 (order: 2, 16384 bytes)&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: Page-cache hash table entries: 16384 (order: 4, 65536 bytes)&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: POSIX conformance testing by UNIFIX&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: Linux NET4.0 for Linux 2.4&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: Based upon Swansea University Computer Society NET3.039&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: Initializing RT netlink socket&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: apm: Simulating APM BIOS version 1.2 (Driver version 1.0)&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: i.MX21 Dynamic Power Management&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: Starting kswapd&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: Disabling the Out Of Memory Killer&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.notice klogd: JFFS2 version 2.1. (C) 2001, 2002 Red Hat, Inc., designed by Axis Communications AB.&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: i2c-core.o: i2c core module version 2.6.2 (20011118)&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: pty: 256 Unix98 ptys configured&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: Serial driver version 5.05c (2001-07-08) with no serial options enabled&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: UART driver version 0.3.6&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: I2C driver Feb 28 2007 / 13:31:04&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: Initialize i2c-client-dbmx-codec module&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.notice klogd: s29gl512n: probing 16-bit flash bus&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.notice klogd:  Amd/Fujitsu Extended Query Table v1.3 at 0x0040&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.notice klogd: number of CFI chips: 1&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.notice klogd: cfi_cmdset_0002: Using Write Buffer method.&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.notice klogd: cfi_cmdset_0002: buffer_Write_Time = 128&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.notice klogd: cfi_cmdset_0002: Disabling fast programming due to code brokenness.&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.notice klogd: Using static partition definition&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.notice klogd: Creating 5 MTD partitions on &amp;quot;s29gl512n&amp;quot;:&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.notice klogd: 0x00000000-0x00040000 : &amp;quot;bootloader&amp;quot;&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.notice klogd: 0x00040000-0x00120000 : &amp;quot;kernel&amp;quot;&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.notice klogd: 0x00120000-0x03260000 : &amp;quot;fs #1&amp;quot;&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.notice klogd: 0x03260000-0x03ee0000 : &amp;quot;fs #2&amp;quot;&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.notice klogd: 0x03ee0000-0x04000000 : &amp;quot;fs #3&amp;quot;&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: NET4: Linux TCP/IP 1.0 for NET4.0&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: IP Protocols: ICMP, UDP, TCP&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: IP: routing cache hash table of 512 buckets, 4Kbytes&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: TCP: Hash tables configured (established 4096 bind 8192)&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: NET4: Unix domain sockets 1.0/SMP for Linux NET4.0.&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: NetWinder Floating Point Emulator V0.95 (c) 1998-1999 Rebel.com&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: VFS: Mounted root (jffs2 filesystem).&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: Freeing init memory: 68K&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: PCB version: ind3 v2&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: Driver SYSTCLK: SYSTCLK-1.12 (REFERENCED)&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: Driver GPIO-1.59 (REFERENCED)&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: ****p_gpio_init_low_bat****&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: GPIO: p_gpio_it_init at 762&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: Driver FRAMEBUF-1.12 (REFERENCED)&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: Driver SPI-1.20 (REFERENCED) Debug level 3&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd:&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: u32_spi1_MinLenghtForDMAInTX set to 300&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd:&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: u32_spi1_MinLenghtForDMAInRX set to 300&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: Driver LCD-1.20 (REFERENCED)&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.info klogd: Driver TVLINK-1.45 (REFERENCED)&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: Reset from Software Reset.&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: Motorola PostProcessor Linux driver ver 0.64 - Copyright (C) 2003 Motorola Inc&lt;br /&gt;
Jan  1 00:00:02 imx21 daemon.warn klogd: pp: hw ver = 2&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.warn klogd: prp_dbg=0&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.warn klogd: Motorola PreProcessor Linux driver ver 0.0 - Copyright (C) 2003 Motorola Inc&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.info klogd: hmp4d: base_port=0x10026800 irq=50&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.info klogd: hmp4d: module inserted&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.info klogd: hmp4e: base_port=0x10026c00 irq=49&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.info klogd: hmp4e: Compatble HW found with ID: 0x004c1882&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.info klogd: hmp4e: module inserted. Major = 249&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.err klogd: SPI2:: drv_Init :PID of driver: 134&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.err klogd: SPI2:: drv_Init :ScanList not provided. Will use the default scan list.&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.err klogd: SPI2:: drv_Init :ScanChannelList :1 6 11 14 2 7 12 3 8 13 4 9 5 10&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.err klogd: SPI2:: drv_Init :setting PhyType to: Rf-to-Rf&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.err klogd: SPI2:: drv_Init :Ref.Clock parameter not provided&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.err klogd: SPI2:: drv_Init :Configure target for a reference clock of &#039;default=40&#039; Mhz.&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.err klogd: SPI2:: drvRegEtherDev :Interface Name is: eth%d&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.err klogd: SPI2:: drv_Init :HEOCSIWPOWON: Powering on...&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.err klogd: SPI2:: drvPhase2Init :Protocol Firmware will be loaded by driver ...&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.err klogd: SPI2:: drvPhase2Init :Initializing HHAL (PhgHhalInitialize)...&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.warn klogd: Divider : 8&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.warn klogd:&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.warn klogd:  OCR2 : e4015308 (12582912)&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.warn klogd: Reset : 3 / 27 (c497cc00 / e401531c)&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.warn klogd:&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.warn klogd: Reset : 3 / 27 (c497cc00 / e401531c)&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.warn klogd: GPIO: p_gpio_init_gpio_status at 1262&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.warn klogd: GPIO: POWER_FAIL signal NOT detected at GPIO driver init carry on !!!&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.warn klogd: GPIO: CHARGE_IN at init&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.warn klogd: GPIO: LOW_BAT_OUT at init&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.warn klogd: GPIO: No accessory plugged at init.  - Set Video on jack&lt;br /&gt;
Jan  1 00:00:03 imx21 daemon.warn klogd: GPIO: camera to front at init&lt;br /&gt;
Jan  1 00:00:04 imx21 daemon.warn klogd: **ChargeStatusPmb=========gpio_Read_ChargeStatus_Ready=1&lt;br /&gt;
Jan  1 00:00:06 imx21 daemon.err klogd: SPI2:: PhgOsal_linux_init_thread :assigning thread name and deamonize() ..&lt;br /&gt;
Jan  1 00:00:06 imx21 daemon.err klogd: SPI2:: drvPhase2Init :Success&lt;br /&gt;
Jan  1 00:00:06 imx21 daemon.err klogd: SPI2:: drvPhase2Init : registering callbacks with HHAL..&lt;br /&gt;
Jan  1 00:00:06 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :&lt;br /&gt;
Jan  1 00:00:06 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :PHGHHAL_EVNT_INIT_COMPLETE; setting CARRIER_ON&lt;br /&gt;
Jan  1 00:00:06 imx21 daemon.err klogd: SPI2:: drvPhase2Init :calling PhgHhalQueueMgmtReq()!&lt;br /&gt;
Jan  1 00:00:06 imx21 daemon.info klogd: PhgHhalQueueMgmtReq:1172:HHAL got Init message&lt;br /&gt;
Jan  1 00:00:06 imx21 daemon.info klogd: PhgHhalQueueMgmtReq:1217:HHAL done Init message&lt;br /&gt;
Jan  1 00:00:06 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :PS wake (0) in Drvmain&lt;br /&gt;
Jan  1 00:00:06 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :&lt;br /&gt;
Jan  1 00:00:06 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :PHGHHAL_EVENT_DISCONNECT; setting CARRIER_OFF&lt;br /&gt;
Jan  1 00:00:06 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :netdev-&amp;gt;flags=0x00001002, IFF_UP=0&lt;br /&gt;
Jan  1 00:00:06 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :device was already closed&lt;br /&gt;
Jan  1 00:00:06 imx21 daemon.err klogd: SPI2:: drvMgmtCfmHndler :Using MAC Address: 00:08:c6:86:8b:99&lt;br /&gt;
Jan  1 00:00:06 imx21 daemon.err klogd: SPI2:: drvPhase2Init :init etherdev; stopping queue, setting CARRIER_OFF&lt;br /&gt;
Jan  1 00:00:06 imx21 daemon.err klogd: SPI2:: drv_Init :Philips WLAN Drv - loaded - in state: 1&lt;br /&gt;
Jan  1 00:00:06 imx21 daemon.err klogd: SPI2:: drvInit :Philips WLAN Drv - loaded&lt;br /&gt;
Jan  1 00:00:07 imx21 daemon.err klogd: SPI2:: drvOpen :opening net device&lt;br /&gt;
Jan  1 00:00:07 imx21 daemon.err klogd: SPI2:: drvOpen :Device is not associated!&lt;br /&gt;
Jan  1 00:00:07 imx21 daemon.err klogd: SPI2:: drvOpen :Carrier flag is already set to CARRIER_OFF&lt;br /&gt;
Jan  1 00:00:07 imx21 daemon.err klogd: SPI2:: drvOpen :Disabling again netqueue&lt;br /&gt;
Jan  1 00:00:07 imx21 daemon.warn klogd: requested reg.domain code setting = 3&lt;br /&gt;
Jan  1 00:00:07 imx21 daemon.err klogd: SPI2:: drvIoctl :set u8LinkAdaptation  : 1 Result=[0]&lt;br /&gt;
Jan  1 00:00:07 imx21 daemon.err klogd: SPI2:: drvIoctl :changed HEOCSIWLNADPALLOWRATES: 8 allowed rate codes&lt;br /&gt;
Jan  1 00:00:07 imx21 daemon.err klogd: SPI2:: drvInitConnect :Req to connect to new WLAN network&lt;br /&gt;
Jan  1 00:00:07 imx21 daemon.err klogd: SPI2:: drvInitConnect :Disabling TX queue and setting CARRIER_OFF&lt;br /&gt;
Jan  1 00:00:07 imx21 daemon.err klogd: SPI2:: drvInitConnect :Connecting To AP...&lt;br /&gt;
Jan  1 00:00:07 imx21 daemon.err klogd: SPI2:: drvInitConnect :step2&lt;br /&gt;
Jan  1 00:00:10 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :&lt;br /&gt;
Jan  1 00:00:10 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :PHGHHAL_EVENT_DISCONNECT; setting CARRIER_OFF&lt;br /&gt;
Jan  1 00:00:10 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :netdev-&amp;gt;flags=0x00001003, IFF_UP=1&lt;br /&gt;
Jan  1 00:00:10 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :device was already opened; stopping queue&lt;br /&gt;
Jan  1 00:00:11 imx21 daemon.err klogd: SPI2:: drvInitConnect :step3 : u8Status 255&lt;br /&gt;
Jan  1 00:00:11 imx21 daemon.err klogd: SPI2:: drvInitConnect :step5&lt;br /&gt;
Jan  1 00:00:11 imx21 daemon.err klogd: SPI2:: drvInitConnect :TIMEDOUT&lt;br /&gt;
Jan  1 00:00:11 imx21 daemon.err klogd: SPI2:: drvInitConnect :step6&lt;br /&gt;
Jan  1 00:00:11 imx21 daemon.err klogd: SPI2:: drvInitParamsAndPowerOnAndConnect :Connect failed!&lt;br /&gt;
Jan  1 00:00:12 imx21 daemon.warn klogd: Motorola CSI Linux driver ver 0.1&lt;br /&gt;
Jan  1 00:00:12 imx21 daemon.warn klogd:  - Copyright (C) 2004 Motorola Inc&lt;br /&gt;
Jan  1 00:00:12 imx21 daemon.warn klogd:&lt;br /&gt;
Jan  1 00:00:12 imx21 daemon.info klogd: Driver SENSOR-1.29 (REFERENCED)&lt;br /&gt;
Jan  1 00:00:12 imx21 daemon.info klogd: i2c-client version : 1.9&lt;br /&gt;
Jan  1 00:00:12 imx21 daemon.info klogd: Initialize i2c-client-aic14 module&lt;br /&gt;
Jan  1 00:00:12 imx21 daemon.info klogd: Module i2c-client-aic14 initialized&lt;br /&gt;
Jan  1 00:00:12 imx21 daemon.alert klogd: Insert module aic14 (AIC14-1.0)&lt;br /&gt;
Jan  1 00:00:12 imx21 daemon.warn klogd: Module AIC14 assumes CODEC MCLK already configured for 20480000Hz&lt;br /&gt;
Jan  1 00:00:12 imx21 daemon.info klogd: Driver KPP-1.36 (REFERENCED)&lt;br /&gt;
Jan  1 00:00:13 imx21 daemon.info klogd: Driver DOZE-1.27 (REFERENCED)&lt;br /&gt;
Jan  1 00:00:14 imx21 daemon.err klogd: SPI2:: drvDoScan :Buero (bittorf)&lt;br /&gt;
Jan  1 00:00:15 imx21 daemon.err klogd: SPI2:: drvProcessScanCfm :Scan Confirm: Success 1 APs&lt;br /&gt;
Jan  1 00:00:15 imx21 daemon.info netsyncd[315]: creating FIFO_NETSYNC_HMON_NAME...&lt;br /&gt;
Jan  1 00:00:15 imx21 daemon.info netsyncd[315]: creating FIFO_HMON_NETSYNC_NAME...&lt;br /&gt;
Jan  1 00:00:18 imx21 daemon.err klogd: SPI2:: drvInitConnect :Req to connect to new WLAN network&lt;br /&gt;
Jan  1 00:00:18 imx21 daemon.err klogd: SPI2:: drvInitConnect :Disabling TX queue and setting CARRIER_OFF&lt;br /&gt;
Jan  1 00:00:18 imx21 daemon.err klogd: SPI2:: drvInitConnect :Connecting To AP...&lt;br /&gt;
Jan  1 00:00:18 imx21 daemon.err klogd: SPI2:: drvInitConnect :step2&lt;br /&gt;
Jan  1 00:00:19 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :&lt;br /&gt;
Jan  1 00:00:19 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :PHGHHAL_EVNT_INIT_CONNECT; setting CARRIER_ON&lt;br /&gt;
Jan  1 00:00:19 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :netdev-&amp;gt;flags=0x00001003, IFF_UP=1&lt;br /&gt;
Jan  1 00:00:19 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :device was already opened; enabling queue&lt;br /&gt;
Jan  1 00:00:19 imx21 daemon.err klogd: SPI2:: drvInitConnect :step3 : u8Status 8&lt;br /&gt;
Jan  1 00:00:19 imx21 daemon.err klogd: SPI2:: drvInitConnect :step4&lt;br /&gt;
Jan  1 00:00:19 imx21 daemon.err klogd: SPI2:: drvInitConnect :Successful&lt;br /&gt;
Jan  1 00:00:19 imx21 daemon.err klogd: SPI2:: drvInitConnect :step6&lt;br /&gt;
Jan  1 00:00:19 imx21 daemon.err modprobe: modprobe: Can&#039;t locate module sound-slot-0&lt;br /&gt;
Jan  1 00:00:19 imx21 daemon.err modprobe: modprobe: Can&#039;t locate module sound-service-0-0&lt;br /&gt;
Jan  1 00:00:20 imx21 local0.debug dhcpcd[337]: broadcasting DHCP_DISCOVER&lt;br /&gt;
Jan  1 00:00:23 imx21 local0.debug dhcpcd[337]: DHCP_OFFER received from  (10.63.17.1)&lt;br /&gt;
Jan  1 00:00:23 imx21 local0.debug dhcpcd[337]: DHCP_ACK received from  (10.63.17.1)&lt;br /&gt;
Jan  1 00:00:23 imx21 daemon.err netsyncd[314]: father received(10) eth0 up!&lt;br /&gt;
Jan  1 00:00:23 imx21 daemon.info netsyncd[314]: Dhcp_start 337 return : 0 &lt;br /&gt;
Jan  1 00:00:26 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11LongRetryLimitAC0 = 8&lt;br /&gt;
Jan  1 00:00:26 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11LongRetryLimitAC1 = 8&lt;br /&gt;
Jan  1 00:00:26 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11LongRetryLimitAC2 = 8&lt;br /&gt;
Jan  1 00:00:26 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11LongRetryLimitAC3 = 8&lt;br /&gt;
Jan  1 00:00:26 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11ShortRetryLimitAC0 = 8&lt;br /&gt;
Jan  1 00:00:26 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11ShortRetryLimitAC1 = 8&lt;br /&gt;
Jan  1 00:00:26 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11ShortRetryLimitAC2 = 8&lt;br /&gt;
Jan  1 00:00:26 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11ShortRetryLimitAC3 = 8&lt;br /&gt;
Jan  1 00:00:26 imx21 daemon.err klogd: SPI2:: drvIoctl :PA Request&lt;br /&gt;
Jan  1 00:00:26 imx21 daemon.err klogd: SPI2:: drvIoctl :No state change!&lt;br /&gt;
Jan  1 00:00:26 imx21 daemon.err klogd: SPI2:: drvIoctl :Fast PS Request&lt;br /&gt;
Jan  1 00:00:26 imx21 daemon.info klogd: PhgHhalDoM2SDMA:1661:--&amp;gt;P1&lt;br /&gt;
Jan  1 00:00:26 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :PS Ind (1) in Drvmain&lt;br /&gt;
Jan  1 00:00:28 imx21 daemon.info netsyncd[314]: Dhcp_stop 359 return : 0 &lt;br /&gt;
Jan  1 00:00:28 imx21 local0.debug dhcpcd[347]: sending DHCP_RELEASE for 10.63.17.5 to 10.63.17.1&lt;br /&gt;
Jan  1 00:00:29 imx21 local0.err dhcpcd[347]: terminating on signal 1&lt;br /&gt;
Jan  1 00:00:29 imx21 daemon.err netsyncd[314]: father received(12) eth0 down!&lt;br /&gt;
Jan  1 00:00:29 imx21 daemon.err klogd: SPI2:: drvStop :Driver Stop: disable TX queue! (usage: 2)&lt;br /&gt;
Jan  1 00:00:41 imx21 daemon.err klogd: SPI2:: drvIoctl :Deauth BSSID: 00:1d:7e:18:e3:89&lt;br /&gt;
Jan  1 00:00:41 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :&lt;br /&gt;
Jan  1 00:00:41 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :PHGHHAL_EVENT_DISCONNECT; setting CARRIER_OFF&lt;br /&gt;
Jan  1 00:00:41 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :netdev-&amp;gt;flags=0x00000002, IFF_UP=0&lt;br /&gt;
Jan  1 00:00:41 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :device was already closed&lt;br /&gt;
Jan  1 00:00:41 imx21 daemon.err klogd: SPI2:: drvOpen :opening net device&lt;br /&gt;
Jan  1 00:00:41 imx21 daemon.err klogd: SPI2:: drvOpen :ERROR: Associated, but Carrier flag is set to CARRIER_OFF&lt;br /&gt;
Jan  1 00:00:41 imx21 daemon.err klogd: SPI2:: drvDoScan :Buero (bittorf)&lt;br /&gt;
Jan  1 00:00:42 imx21 daemon.err klogd: SPI2:: drvProcessScanCfm :Scan Confirm: Success 1 APs&lt;br /&gt;
Jan  1 00:00:45 imx21 daemon.err klogd: SPI2:: drvInitConnect :Req to connect to new WLAN network&lt;br /&gt;
Jan  1 00:00:45 imx21 daemon.err klogd: SPI2:: drvInitConnect :Disabling TX queue and setting CARRIER_OFF&lt;br /&gt;
Jan  1 00:00:45 imx21 daemon.err klogd: SPI2:: drvInitConnect :Connecting To AP...&lt;br /&gt;
Jan  1 00:00:45 imx21 daemon.err klogd: SPI2:: drvInitConnect :step2&lt;br /&gt;
Jan  1 00:00:46 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :&lt;br /&gt;
Jan  1 00:00:46 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :PHGHHAL_EVNT_INIT_CONNECT; setting CARRIER_ON&lt;br /&gt;
Jan  1 00:00:46 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :netdev-&amp;gt;flags=0x00000003, IFF_UP=1&lt;br /&gt;
Jan  1 00:00:46 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :device was already opened; enabling queue&lt;br /&gt;
Jan  1 00:00:46 imx21 daemon.err klogd: SPI2:: drvInitConnect :step3 : u8Status 8&lt;br /&gt;
Jan  1 00:00:46 imx21 daemon.err klogd: SPI2:: drvInitConnect :step4&lt;br /&gt;
Jan  1 00:00:46 imx21 daemon.err klogd: SPI2:: drvInitConnect :Successful&lt;br /&gt;
Jan  1 00:00:46 imx21 daemon.err klogd: SPI2:: drvInitConnect :step6&lt;br /&gt;
Jan  1 00:00:46 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :PS Ind (1) in Drvmain&lt;br /&gt;
Jan  1 00:00:54 imx21 local0.debug dhcpcd[386]: broadcasting DHCP_DISCOVER&lt;br /&gt;
Jan  1 00:00:57 imx21 local0.debug dhcpcd[386]: DHCP_OFFER received from  (10.63.17.1)&lt;br /&gt;
Jan  1 00:00:57 imx21 local0.debug dhcpcd[386]: DHCP_ACK received from  (10.63.17.1)&lt;br /&gt;
Jan  1 00:00:57 imx21 daemon.info netsyncd[314]: Dhcp_start 386 return : 0 &lt;br /&gt;
Jan  1 00:00:57 imx21 daemon.info netsyncd[314]: NTP server request on : ntp.xs4all.nl&lt;br /&gt;
Jan  1 00:00:57 imx21 daemon.err klogd: SPI2:: drvIoctl :PA Request&lt;br /&gt;
Jan  1 00:00:57 imx21 daemon.info klogd: PhgHhalDoM2SDMA:1661:--&amp;gt;P0&lt;br /&gt;
Jan  1 00:00:57 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :PS wake (0) in Drvmain&lt;br /&gt;
Jan  1 00:00:57 imx21 daemon.warn klogd: drvSetWOWFilter: Enable UNICAST: Disable ARP: Enable&lt;br /&gt;
Jan  1 00:00:57 imx21 daemon.warn klogd: Ip addr = 10.63.17.5. LMP=2&lt;br /&gt;
Jan  1 00:00:57 imx21 daemon.err klogd: SPI2:: drvIoctl :PA Request&lt;br /&gt;
Jan  1 00:00:57 imx21 daemon.err klogd: SPI2:: drvIoctl :No state change!&lt;br /&gt;
Jan  1 00:00:57 imx21 daemon.err klogd: SPI2:: drvIoctl :Fast PS Request&lt;br /&gt;
Jan  1 00:00:57 imx21 daemon.info klogd: PhgHhalDoM2SDMA:1661:--&amp;gt;P1&lt;br /&gt;
Jan  1 00:00:57 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :PS Ind (1) in Drvmain&lt;br /&gt;
Jan  1 00:00:57 imx21 daemon.warn klogd: Sensor driver: initialize device OV7660&lt;br /&gt;
Jan  1 00:00:57 imx21 daemon.warn klogd: Warning: Remapping obsolete /dev/fb* minor 32 to 1&lt;br /&gt;
Apr  7 09:58:16 imx21 daemon.info netsyncd[314]: NTP process return code : 0 &lt;br /&gt;
Apr  7 09:58:19 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11LongRetryLimitAC0 = 4&lt;br /&gt;
Apr  7 09:58:19 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11LongRetryLimitAC1 = 4&lt;br /&gt;
Apr  7 09:58:19 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11LongRetryLimitAC2 = 4&lt;br /&gt;
Apr  7 09:58:19 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11LongRetryLimitAC3 = 4&lt;br /&gt;
Apr  7 09:58:19 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11ShortRetryLimitAC0 = 4&lt;br /&gt;
Apr  7 09:58:19 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11ShortRetryLimitAC1 = 4&lt;br /&gt;
Apr  7 09:58:19 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11ShortRetryLimitAC2 = 4&lt;br /&gt;
Apr  7 09:58:19 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11ShortRetryLimitAC3 = 4&lt;br /&gt;
Apr  7 09:58:19 imx21 daemon.err klogd: SPI2:: drvIoctl :PA Request&lt;br /&gt;
Apr  7 09:58:19 imx21 daemon.info klogd: PhgHhalDoM2SDMA:1661:--&amp;gt;P0&lt;br /&gt;
Apr  7 09:58:19 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :PS wake (0) in Drvmain&lt;br /&gt;
Apr  7 09:58:19 imx21 daemon.info upgraded[312]: K_SW0_DWNLD_ACK&lt;br /&gt;
Apr  7 09:58:27 imx21 auth.info login[393]: root login  on `ttyp0&#039; from `bittorf-AP.olsr&#039;&lt;br /&gt;
Apr  7 09:59:50 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11LongRetryLimitAC0 = 8&lt;br /&gt;
Apr  7 09:59:50 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11LongRetryLimitAC1 = 8&lt;br /&gt;
Apr  7 09:59:50 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11LongRetryLimitAC2 = 8&lt;br /&gt;
Apr  7 09:59:50 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11LongRetryLimitAC3 = 8&lt;br /&gt;
Apr  7 09:59:50 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11ShortRetryLimitAC0 = 8&lt;br /&gt;
Apr  7 09:59:50 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11ShortRetryLimitAC1 = 8&lt;br /&gt;
Apr  7 09:59:50 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11ShortRetryLimitAC2 = 8&lt;br /&gt;
Apr  7 09:59:50 imx21 daemon.err klogd: SPI2:: drvIoctl :dot11ShortRetryLimitAC3 = 8&lt;br /&gt;
Apr  7 09:59:50 imx21 daemon.err klogd: SPI2:: drvIoctl :PA Request&lt;br /&gt;
Apr  7 09:59:50 imx21 daemon.err klogd: SPI2:: drvIoctl :No state change!&lt;br /&gt;
Apr  7 09:59:50 imx21 daemon.err klogd: SPI2:: drvIoctl :Fast PS Request&lt;br /&gt;
Apr  7 09:59:50 imx21 daemon.info klogd: PhgHhalDoM2SDMA:1661:--&amp;gt;P1&lt;br /&gt;
Apr  7 09:59:50 imx21 daemon.err klogd: SPI2:: drvHhalEventIndicationHandler :PS Ind (1) in Drvmain&lt;br /&gt;
Apr  7 10:14:53 imx21 auth.info login[408]: root login  on `ttyp1&#039; from `bittorf-AP.olsr&#039;&lt;br /&gt;
Apr  7 10:17:18 imx21 syslog.info -- MARK --&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
=== Ausgabe von &amp;lt;b&amp;gt;&amp;lt;tt&amp;gt;/proc/cpuinfo&amp;lt;/tt&amp;gt;&amp;lt;/b&amp;gt; auf einem VP6500 ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# cat /proc/cpuinfo&lt;br /&gt;
Processor      : ARM926EJ-Sid(wb) rev 4 (v5EJl)&lt;br /&gt;
BogoMIPS        : 133.01&lt;br /&gt;
Features        : swp half thumb fastmult&lt;br /&gt;
CPU implementer : 0x41&lt;br /&gt;
CPU architecture: ?(8)&lt;br /&gt;
CPU variant    : 0x0&lt;br /&gt;
CPU part        : 0x926&lt;br /&gt;
CPU revision    : 4&lt;br /&gt;
Cache type      : undefined 14&lt;br /&gt;
Cache clean    : undefined 14&lt;br /&gt;
Cache lockdown  : undefined 14&lt;br /&gt;
Cache unified  : Harvard&lt;br /&gt;
I size          : 16384&lt;br /&gt;
I assoc        : 4&lt;br /&gt;
I line length  : 32&lt;br /&gt;
I sets          : 128&lt;br /&gt;
D size          : 16384&lt;br /&gt;
D assoc        : 4&lt;br /&gt;
D line length  : 32&lt;br /&gt;
D sets          : 128&lt;br /&gt;
 &lt;br /&gt;
Hardware        : Freescale i.MX2 ADS&lt;br /&gt;
Revision        : 0000&lt;br /&gt;
Serial          : 0000000000000000&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
== Software Modifikationen ==&lt;br /&gt;
 &lt;br /&gt;
=== Startscripts ===&lt;br /&gt;
Die Scripts in /etc/rc.d/&amp;quot; müssen im Hintergrund laufen. Tut ein Script das nicht, ist an dieser Stelle Schluß mit dem Bootvorgang.&lt;br /&gt;
 &lt;br /&gt;
Dann darf man als nächstes den Lötkolben anheizen und die serielle Schnittstelle ([[#UART]]) zugänglich machen.&lt;br /&gt;
 &lt;br /&gt;
=== Aktivierung WPA2 Unterstützung ===&lt;br /&gt;
&amp;lt;p&amp;gt;Standardmäßig kann das Telefon nur WPA, dabei unterstützt es allerdings auch &amp;lt;b&amp;gt;WPA mit AES&amp;lt;/b&amp;gt; Verschlüsselung.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;Es gibt zwei verschiedene Tricks mit denen auch WPA2 aktiviert werden kann.&lt;br /&gt;
Allerdings wurde von einigen ein Einbruch der Verbindungsgeschwindigkeit festgestellt (scheint jedoch nur bei geringem Akkuladestand aufzutreten).&amp;lt;/p&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
==== Trick1 ====&lt;br /&gt;
Mittels&lt;br /&gt;
vi /etc/marvell/wpa_supplicant.conf&lt;br /&gt;
den Texteditor starten.&lt;br /&gt;
Mit PageDown (Bild runter) bis zum Ende des Files gehen.&lt;br /&gt;
Die Zeilen&lt;br /&gt;
proto=WPA&lt;br /&gt;
pairwise=TKIP&lt;br /&gt;
group=TKIP&lt;br /&gt;
auskommentieren, indem ein # vorangestellt wird:&lt;br /&gt;
* cursor auf Beginn einer Zeile&lt;br /&gt;
* i drücken zum Einfügen&lt;br /&gt;
* # eintippen&lt;br /&gt;
* [Esc]&lt;br /&gt;
Sind alle Zeilen auskommentiert, dann mittels&lt;br /&gt;
:wq[enter]&lt;br /&gt;
abspeichern und Editor verlassen.&lt;br /&gt;
 &lt;br /&gt;
Danach neu booten.&lt;br /&gt;
 &lt;br /&gt;
Anmerkung: Will man sich mit dieser Änderung in einem reinen WPA2 Netz anmelden (registrieren), kann man als Verschlüsselung nur noch WEP auswählen - der Verbindungsversuch scheitert natürlich! (Hardware: Fritz!Box 7270, PHILIPS VP5500)&lt;br /&gt;
 &lt;br /&gt;
Also am Accesspoint WPA2 + WPA einstellen, Telefon registrieren, dann Accesspoint auf WPA2 konfigurieren.&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;u&amp;gt;&#039;&#039;&#039;Achtung!&#039;&#039;&#039;&amp;lt;/u&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;Das Herumspielen an der wpa_supplicant.conf endet sehr schnell damit das man sich ausperrt&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;Um sich eine Wiederbelebung per serieller Konsole zu ersparen, ist es günstig, immer nur Einträge an die wpa_supplicant.conf &amp;lt;u&amp;gt;hinten anzuhängen&amp;lt;/u&amp;gt;, niemals aber vorne einzufügen!&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
==== Trick2 ====&lt;br /&gt;
Dieser Trick funktioniert mit Accesspoints, bei denen man auch WPA Verbindungen mit AES verschlüsseln kann. Vorteil dieses Tricks ist, dass man die wpa_supplicant.conf nicht manuell editieren muss. Allerdings unterstützt nicht jeder Accesspoint WPA mit AES (aber dd-wrt kann das).&lt;br /&gt;
 &lt;br /&gt;
Man konfiguriert den Accesspoint zunächst mit WPA PSK und wählt AES als Verschlüsselungsalgorithmus. Jetzt meldet man das Telefon an, das Telefon erkennt richtig, dass eine WPA Verbindung vorliegt und verbindet sich per WPA und AES mit dem Accesspoint. Anschliessend konfiguriert man den Accesspoint von WPA PSK AES nach WPA2 PSK AES. Jetzt schaltet man das VP5500/6500 aus und wieder ein. Nachdem es fertig gebootet hat, verbindet es sich automisch per WPA2 PSK und mit AES Verschlüsselung. Fertig.&lt;br /&gt;
 &lt;br /&gt;
==== Versehentliche Aussperrung nach WPA2 Einstellversuch beheben ====&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;1. DON&#039;T PANIC!&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
Für den Fall das man sich den Zugangsweg per wireless abgeschnitten hat, gibt es, neben dem Bau eines seriellen Adapters und der Notwendigkeit zu löten, noch eine Variante um wieder auf das Telefon zu kommen:&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;den Demo-Modus!&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
Dieser Modus war dazu gedacht die Funktionalität der VPs ohne SIP-Server ausprobieren zu können. 2 Geräte starten dazu im WLAN-AdHoc-Modus mit unterschiedlichen IP&#039;s (192.168.10.1 + 192.168.10.2 , jeweils /24 = 255.255.255.0) und machen ein IBSS-Netzwerk mit WEP-Verschlüsselung auf (Key: VP6500 = 5648751265 beim VP5500 = 7295569793).&lt;br /&gt;
 &lt;br /&gt;
Nun kann man auch ein einzelnes Telefon in den Demo-Modus versetzen (vorhandener neuer Menüeintrag nach dem rooten, oder per Tastenkombination &amp;quot;*#3 &amp;quot;), gibt sich eine passende WLAN und IP-Einstellungen auf dem Rechner und schon kann man wieder darauf connecten und Fehleinstellungen wieder beheben. Dummerweise wird eine zufällige IBSS-Cell-ID verwendet, aber neuere Betriebssysteme können der Zelle trotzdem beitreten. Als ESSID kann man &#039;&#039;demo_mode_obiwan&#039;&#039; verwenden.&lt;br /&gt;
 &lt;br /&gt;
===== Schritt für Schritt Anleitung für Linux =====&lt;br /&gt;
 &lt;br /&gt;
Einstellungen&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;am Telefon&#039;&#039;&#039;&lt;br /&gt;
* Telefon anschalten und per Menüeintrag oder Tastenkombination &amp;quot;*#3&amp;quot; in Demomodus versetzen (z.B. als Einstellung Handset 1)&lt;br /&gt;
-&amp;gt; IP des Telefons wird danach zu 192.168.10.1&lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;am Computer&#039;&#039;&#039;&lt;br /&gt;
* Konsole öffnen&lt;br /&gt;
per ifconfig checken welches das WLAN-Gerät am Rechner ist (im weiteren &amp;quot;wlan0&amp;quot; genannt)&lt;br /&gt;
ifconfig wlan0 down&lt;br /&gt;
iwconfig wlan0 mode ad-hoc (ad-hoc Modus aktivieren)&lt;br /&gt;
iwconfig wlan0 essid &#039;demo_mode_obiwan&#039; (Passende essid-Kennung setzen)&lt;br /&gt;
iwconfig wlan0 key 5648751265 (Key für das VP6500)&lt;br /&gt;
ifconfig wlan0 up&lt;br /&gt;
ifconfig wlan0 192.168.10.2 (setzen der IP)&lt;br /&gt;
 &lt;br /&gt;
man kann nun mittels:&lt;br /&gt;
 &lt;br /&gt;
ping 192.168.10.1&lt;br /&gt;
 &lt;br /&gt;
testen ob alles korrekt verlaufen ist und man eine Antwort bekommt - sollte das der Fall sein ist man &#039;&#039;&#039;fertig!&#039;&#039;&#039;&lt;br /&gt;
 &lt;br /&gt;
Nun kann man per telnet oder ssh, mit den üblichen Benutzerkennung und dem Passwort, auf die IP 192.168.10.1 connecten und die Probleme beheben.&lt;br /&gt;
 &lt;br /&gt;
=== Menüs ===&lt;br /&gt;
==== Hauptmenu ====&lt;br /&gt;
 &lt;br /&gt;
Das File&lt;br /&gt;
/usr/local/etc/defaultbuttons.conf&lt;br /&gt;
enthält unter anderm die definition des Hauptmenus.&lt;br /&gt;
 &lt;br /&gt;
Hierfür ist der Abschnitt Menu besonders interessant.&lt;br /&gt;
  [Menu]&lt;br /&gt;
  1 = Applications/camera.desktop&lt;br /&gt;
  2 = Applications/callhistory.desktop&lt;br /&gt;
  3 = Applications&lt;br /&gt;
  4 = Settings&lt;br /&gt;
  5 = Applications/addressbook.desktop&lt;br /&gt;
  6 = Settings/RingProfiles.desktop&lt;br /&gt;
  Columns = 3&lt;br /&gt;
  Default = 5&lt;br /&gt;
  Map = 123456789*0#&lt;br /&gt;
  Rows = 2&lt;br /&gt;
 &lt;br /&gt;
&#039;Rows&#039; und &#039;Columns&#039; geben an, wieviel Reihen und Spalten das Hauptmenu hat.&lt;br /&gt;
Über die Zuweisungen 1 bis (Columns * Rows) kann man dann den Menüpositionen die Menüpunkte zuweisen.&lt;br /&gt;
Die Menupunkte sind definiert in den Verzeichnissen unter&lt;br /&gt;
/usr/local/apps&lt;br /&gt;
gibt man nur ein Verzeichnis an, dann erscheint ein Submenü, dessen Icon und Name in der .directory -Datei des entsprechenden Ordner definiert ist.&lt;br /&gt;
direkte Menupunkte haben Dateinamen mit der Endung .desktop&lt;br /&gt;
&#039;Default&#039; bestimmten vorselektierten Eintrag.&lt;br /&gt;
 &lt;br /&gt;
Hier ein weiteres Beispiel für ein angepasstes Menu:&lt;br /&gt;
  [Menu]&lt;br /&gt;
  1 = Applications/addressbook.desktop&lt;br /&gt;
  2 = Applications/callhistory.desktop&lt;br /&gt;
  3 = Applications/sysinfo.desktop&lt;br /&gt;
  4 = Applications&lt;br /&gt;
  5 = Settings&lt;br /&gt;
  6 = Games&lt;br /&gt;
  7 = Applications/camera.desktop&lt;br /&gt;
  8 = Applications/photoedit.desktop&lt;br /&gt;
  9 = Applications/manualsub.desktop&lt;br /&gt;
  Columns = 3&lt;br /&gt;
  Default = 5&lt;br /&gt;
  Map = 123456789*0#&lt;br /&gt;
  Rows = 3&lt;br /&gt;
 &lt;br /&gt;
Der Ordner Games ist (momentan ;) leer.&lt;br /&gt;
 &lt;br /&gt;
==== Genereller Aufbau Menü-Einträge ====&lt;br /&gt;
Die Einträge für die Menüs sind im Filesystem abgelegt:&lt;br /&gt;
 &lt;br /&gt;
* Settings: /usr/local/apps/Settings&lt;br /&gt;
* Applications: /usr/local/apps/Applications&lt;br /&gt;
* Klingeltöne: /usr/local/etc/SystemRingTones/&lt;br /&gt;
 &lt;br /&gt;
Die Dateien haben die Endung &amp;quot;.desktop&amp;quot; und sind normale Textdateien, die die relevanten Infos enthalten.&lt;br /&gt;
 &lt;br /&gt;
Ein Beispiel aus dem Settingsordner:&lt;br /&gt;
  [Translation]&lt;br /&gt;
  File=QtopiaSettings&lt;br /&gt;
  Context=Sound&lt;br /&gt;
  [Desktop Entry]&lt;br /&gt;
  Type=Application&lt;br /&gt;
  Exec=sound&lt;br /&gt;
  Icon=Sound&lt;br /&gt;
  Name[]=Sound&lt;br /&gt;
  CanFastload=0&lt;br /&gt;
 &lt;br /&gt;
Der Abschnitt &#039;Translation&#039; gibt an in welchem File, die Lokalisationsdaten stehen.&lt;br /&gt;
 &lt;br /&gt;
Der Abschnitt &#039;Desktop Entry&#039;:&lt;br /&gt;
* Type: Typ des Eintrages&lt;br /&gt;
** Application für Anwendungen&lt;br /&gt;
** audio/x-wav für Klingeltöne&lt;br /&gt;
* Exec: Anwendung, die ausgeführt werden soll&lt;br /&gt;
* Icon: Icon, das im Menü benutzt wird.&lt;br /&gt;
** Pfad ist meist: /usr/local/pics/[Exex]/[Icon].png&lt;br /&gt;
** manchmal aber auch: /usr/local/pics/icons/[14x14|16x16|22x22]/[Icon].png&lt;br /&gt;
* Name[]: Name im Menü, wird über das in Translation angegebe File und Context aufgelöst. Dies wird verhindert, wenn die Klammern wegelassen werden, was das Einfügen eigener Einträge ermöglicht&lt;br /&gt;
 &lt;br /&gt;
Hier ein Textfile mit allen desktop-Files als Referenz: [[File:alleDesktopFiles.txt]]&lt;br /&gt;
 &lt;br /&gt;
==== Versteckte Menüeinträge ====&lt;br /&gt;
in den oben genannten Ordnern existieren ein paar Dateien mit der Endung &#039;.desktopMASK&#039;.&lt;br /&gt;
Benennt man diese um, werden die Einträge nach einem Neustart im Menü freigeschaltet.&lt;br /&gt;
 &lt;br /&gt;
folgendes an der Kommandozeile eingeben:&lt;br /&gt;
cd /usr/local/apps/Settings&lt;br /&gt;
mv datetime.desktopMASK datetime.desktop&lt;br /&gt;
mv callforward.desktopMASK callforward.desktop&lt;br /&gt;
mv calloptions.desktopMASK calloptions.desktop&lt;br /&gt;
mv resetparam.desktopMASK resetparam.desktop&lt;br /&gt;
mv subkpncode.desktopMASK subkpncode.desktop&lt;br /&gt;
 &lt;br /&gt;
Dies aktiviert folgende Optionen:&lt;br /&gt;
* Datums/Zeit-Einstellung&lt;br /&gt;
* Anrufweiterleitung&lt;br /&gt;
* Anrufoptionen&lt;br /&gt;
* Parameter zurücksetzen&lt;br /&gt;
* Number Switch&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
Die nützlichsten sind wohl die ersten Einträge.&lt;br /&gt;
Bei dem &amp;quot;Number Switch&amp;quot; ist unklar, was er bewirken soll. Beim Start wird ein Code abgefragt.&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
Weiterhin kann im Verzeichnis /usr/local/apps/Applications eine [[File:demomode.desktop]] anlegen.&lt;br /&gt;
 &lt;br /&gt;
Hierfür ist folgende Prozedur nötig:&lt;br /&gt;
* im Terminal&lt;br /&gt;
                cd /usr/local/apps/Applications&lt;br /&gt;
                vi demomode.desktop&lt;br /&gt;
 &lt;br /&gt;
* i drücken&lt;br /&gt;
* folgendes Textfragment einfügen&lt;br /&gt;
                [Translation]&lt;br /&gt;
                File=QtopiaApplications&lt;br /&gt;
                Context=DemoMode&lt;br /&gt;
                [Desktop Entry]&lt;br /&gt;
                Exec=demomode&lt;br /&gt;
                Icon=Camera&lt;br /&gt;
                Type=Application&lt;br /&gt;
                Name[]=DemoMode&lt;br /&gt;
* [Esc]&lt;br /&gt;
* :wq [Enter]&lt;br /&gt;
 &lt;br /&gt;
Dies schaltet einen Demo-Modus frei.&lt;br /&gt;
 &lt;br /&gt;
===== Französisch =====&lt;br /&gt;
Es gab die Geräte wohl auch in Frankreich von der France Telekom.&lt;br /&gt;
Zumindest sind entsprechende monitor und upgrade Referenz-Dateien&lt;br /&gt;
vorhanden in denen das steht. Daher wohl auch die Französischen&lt;br /&gt;
Sprachdateien, die zwar auf dem Gerät sind, allerdings in einem&lt;br /&gt;
Unterverzeichnis, so das sie nicht auswählbar sind.&lt;br /&gt;
 &lt;br /&gt;
Um diese Dateien zu aktivieren:&lt;br /&gt;
 &lt;br /&gt;
cd /usr/local/i18n&lt;br /&gt;
mv NOTUSED/fr .&lt;br /&gt;
 &lt;br /&gt;
Nun ist auch noch französisch als Sprache verfügbar.&lt;br /&gt;
 &lt;br /&gt;
==== Eigene Menüeinträge ====&lt;br /&gt;
 &lt;br /&gt;
Es besteht die Möglichkeit Menüeinträge anzulegen, durch die Shellskripte ausgeführt werden. Im Folgenden ist dieses Vorgehen am Beispiel des ein- und ausschaltens von SSH beschrieben.&lt;br /&gt;
 &lt;br /&gt;
===== SSH aktivieren &amp;amp; deaktivieren =====&lt;br /&gt;
 &lt;br /&gt;
*&#039;&#039;&#039;Achtung! Folgendes Vorgehen kann das Gerät bricken, falls Telnet deaktiviert ist und irgendwas mit SSH schief läuft!&#039;&#039;&#039;&lt;br /&gt;
*Die folgenden beiden Dateien repräsentieren die Menüeinträge und rufen &#039;&#039;enablessh&#039;&#039; bzw. &#039;&#039;disablessh&#039;&#039; auf.&lt;br /&gt;
:*&#039;&#039;/usr/local/apps/Applications/enablessh.desktop&#039;&#039;:&lt;br /&gt;
[Translation]&lt;br /&gt;
File=QtopiaApplications&lt;br /&gt;
Context=enablessh&lt;br /&gt;
[Desktop Entry]&lt;br /&gt;
Exec=enablessh&lt;br /&gt;
Icon=Camera&lt;br /&gt;
Type=Application&lt;br /&gt;
Name[]=Enable SSH&lt;br /&gt;
:*&#039;&#039;/usr/local/apps/Applications/disablessh.desktop&#039;&#039;:&lt;br /&gt;
[Translation]&lt;br /&gt;
File=QtopiaApplications&lt;br /&gt;
Context=disablessh&lt;br /&gt;
[Desktop Entry]&lt;br /&gt;
Exec=disablessh&lt;br /&gt;
Icon=Camera&lt;br /&gt;
Type=Application&lt;br /&gt;
Name[]=Disable SSH&lt;br /&gt;
*&#039;&#039;enablessh&#039;&#039; und &#039;&#039;disablessh&#039;&#039; sind Shellskripte, die in &#039;&#039;/usr/local/bin/&#039;&#039; liegen und folgendes enthalten:&lt;br /&gt;
:*&#039;&#039;/usr/local/bin/enablessh&#039;&#039;:&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
touch /var/log/lastlog&lt;br /&gt;
/etc/rc.d/init.d/S99dropbear restart&lt;br /&gt;
exit(0)&lt;br /&gt;
:*&#039;&#039;/usr/local/bin/disablessh&#039;&#039;:&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
/etc/rc.d/init.d/S99dropbear stop&lt;br /&gt;
exit(0)&lt;br /&gt;
*Nach einem Neustart des Telefons sollten im Menü &#039;&#039;Anwendungen&#039;&#039; die zwei neuen Menüpunkte auftauchen.&lt;br /&gt;
 &lt;br /&gt;
=== Grafische Anpassungen ===&lt;br /&gt;
So gut wie alle Grafiken liegen im Verzeichnis /usr/local/pics und können beliebig ausgetauscht werden (gleicher Dateityp, gleiche Größe).&lt;br /&gt;
 &lt;br /&gt;
Einige besonders interessante werden hier aufgeführt:&lt;br /&gt;
 &lt;br /&gt;
===== Eigene Startup/Shutdown-Animation =====&lt;br /&gt;
 &lt;br /&gt;
Die Animation beim Starten oder Herunterfahren sind normale (animierte) GIFs. Diese findet man in&lt;br /&gt;
 &lt;br /&gt;
/usr/local/pics/qpe&lt;br /&gt;
 &lt;br /&gt;
Die Links &amp;quot;splash.gif&amp;quot; und &amp;quot;goodbye.gif&amp;quot; zeigen auf die tasächlich zu verwendenen Dateien (&amp;quot;splash-chuck.gif&amp;quot;, &amp;quot;goodby-chuck.gif&amp;quot;).&lt;br /&gt;
Man kann sein eigenes animiertes GIF im Format 176x220 Pixel raufladen und die&lt;br /&gt;
splash.gif entsprechend neu verlinken. Dazu löscht man zuerst die alte&lt;br /&gt;
mit:&lt;br /&gt;
 &lt;br /&gt;
rm /usr/local/pics/qpe/splash.gif&lt;br /&gt;
 &lt;br /&gt;
Anschliessend erzeugt man den Link neu, dabei zeigt er dann auf die&lt;br /&gt;
eigene Datei:&lt;br /&gt;
 &lt;br /&gt;
ln -s /pfad/zur/eigenedatei.gif /usr/local/pics/qpe/splash.gif&lt;br /&gt;
 &lt;br /&gt;
Danach wird dann bei jedem Neustart die eigene Animation angezeigt.&lt;br /&gt;
Analog hierzu mit der goodbye.gif.&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
Also, man packe das Bild auf einen Webserver. Dann am Gerät über telnet&lt;br /&gt;
anmelden und:&lt;br /&gt;
 &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
cd /usr/local/pics/qpe/&lt;br /&gt;
wget http://dein.server/woauchimmer/Matrix5.gif&lt;br /&gt;
rm /usr/local/pics/qpe/splash.gif&lt;br /&gt;
ln -s Matrix5.gif splash.gif&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Die GIF Animation kann bis zu 176x220 Pixel groß sein.&lt;br /&gt;
Kleinere (möglicherweise auch größere) Bilder werden zentriert.&lt;br /&gt;
&amp;lt;gallery&amp;gt;&lt;br /&gt;
Bild:walking_baby_tux.gif&lt;br /&gt;
Bild:custwakeup2.gif&lt;br /&gt;
Bild:custgoodbye2.gif&lt;br /&gt;
Bild:94vw4.gif&lt;br /&gt;
Bild:1_Matrix--16984.gif&lt;br /&gt;
Bild:1_Matrix--16985.gif&lt;br /&gt;
Bild:3.gif&lt;br /&gt;
Bild:ClanSpider2.gif&lt;br /&gt;
Bild:TS12.gif&lt;br /&gt;
Bild:Matrix5.gif&lt;br /&gt;
Bild:qtopia3.gif&lt;br /&gt;
Bild:qtopia0.gif&lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
===== Eigener Boot/Update-Screen =====&lt;br /&gt;
 &lt;br /&gt;
Der Boot-Screen, oder der Update-Screen liegen als Rohdaten vor.&lt;br /&gt;
/user_data/data/welcome.rgb565&lt;br /&gt;
/usr/local/startup_V4.20/update.bin&lt;br /&gt;
 &lt;br /&gt;
Weitere Beispielbilder:&lt;br /&gt;
/user_data/prod/data/lcd_test_card1.bin&lt;br /&gt;
/user_data/prod/data/lcd_test_card2.bin&lt;br /&gt;
 &lt;br /&gt;
Diese werden direkt in den Framebuffer geschrieben.&lt;br /&gt;
Daher müssen sich diese genau ein bestimmtes Format halten:&lt;br /&gt;
* Größe 240 x 220 (Das Display ist 176 x 220, der Rest ist also nicht zu sehen)&lt;br /&gt;
* 16bit pro Pixel RGB565&lt;br /&gt;
 &lt;br /&gt;
Um solch ein Bild zu erstellen sind folgende Schritte notwendig:&lt;br /&gt;
# Ein Bild in Gimp mit 176x220 erstellen&lt;br /&gt;
# das Bild vertikal spiegeln&lt;br /&gt;
# Bild-&amp;gt;Leinwandgröße auf 240x220 erweitern (Bilddaten ganz nach links)&lt;br /&gt;
# Datei-&amp;gt;Kopie speichern...&lt;br /&gt;
# Als Windowsbitmap -&amp;gt; erweiterete Optionen -&amp;gt; 16bit R5G6B5&lt;br /&gt;
# BMP-Header entfernen (dies kann auch auf dem Telefon gemacht werden)&lt;br /&gt;
        tail -c 105600 input.bmp &amp;gt; output.raw&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
Von der Kommandozeile kann auch manuell das Bild in den Framebuffer geschrieben werden.&lt;br /&gt;
cat /user_data/prod/data/lcd_test_card1.bin &amp;gt; /dev/fb0&lt;br /&gt;
 &lt;br /&gt;
=== Wichtige Verzeichnisse ===&lt;br /&gt;
 &lt;br /&gt;
==== Adressdaten ====&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# cat /user_data/home/Applications/addressbook/addressbook.xml&lt;br /&gt;
  &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&amp;lt;!DOCTYPE Addressbook &amp;gt;&amp;lt;AddressBook&amp;gt;&lt;br /&gt;
  &amp;lt;Groups&amp;gt;&lt;br /&gt;
  &amp;lt;/Groups&amp;gt;&lt;br /&gt;
  &amp;lt;Contacts&amp;gt;&lt;br /&gt;
    &amp;lt;Contact&lt;br /&gt;
                                Uid=&amp;quot;-1269720893&amp;quot;&lt;br /&gt;
                        Categories=&amp;quot;-1269431263;-1266109093;-1266109094&amp;quot;&lt;br /&gt;
                          FirstName=&amp;quot;ich&amp;quot;&lt;br /&gt;
                            FileAs=&amp;quot;ich&amp;quot;&lt;br /&gt;
                          JobTitle=&amp;quot;cc&amp;quot;&lt;br /&gt;
                        Department=&amp;quot;dep&amp;quot;&lt;br /&gt;
                            Company=&amp;quot;aa&amp;quot;&lt;br /&gt;
                      BusinessPhone=&amp;quot;55&amp;quot;&lt;br /&gt;
                        BusinessFax=&amp;quot;77&amp;quot;&lt;br /&gt;
                    BusinessMobile=&amp;quot;66&amp;quot;&lt;br /&gt;
                          HomePhone=&amp;quot;55&amp;quot;&lt;br /&gt;
                        HomeMobile=&amp;quot;11&amp;quot;&lt;br /&gt;
                            HomePc=&amp;quot;12&amp;quot;&lt;br /&gt;
                          HomeData=&amp;quot;13&amp;quot;&lt;br /&gt;
                            HomeFax=&amp;quot;14&amp;quot;&lt;br /&gt;
                    BusinessStreet=&amp;quot;street&amp;quot;&lt;br /&gt;
                      BusinessCity=&amp;quot;city&amp;quot;&lt;br /&gt;
                      BusinessState=&amp;quot;state&amp;quot;&lt;br /&gt;
                        BusinessZip=&amp;quot;zip&amp;quot;&lt;br /&gt;
                    BusinessCountry=&amp;quot;country&amp;quot;&lt;br /&gt;
                      BusinessPager=&amp;quot;88&amp;quot;&lt;br /&gt;
                            Office=&amp;quot;office&amp;quot;&lt;br /&gt;
                        Profession=&amp;quot;prof&amp;quot;&lt;br /&gt;
                          Assistant=&amp;quot;ass&amp;quot;&lt;br /&gt;
                            Manager=&amp;quot;man&amp;quot;&lt;br /&gt;
                        HomeStreet=&amp;quot;ptjml&amp;quot;&lt;br /&gt;
                          HomeCity=&amp;quot;cit&amp;quot;&lt;br /&gt;
                          HomeState=&amp;quot;stat&amp;quot;&lt;br /&gt;
                            HomeZip=&amp;quot;zi&amp;quot;&lt;br /&gt;
                        HomeCountry=&amp;quot;coun&amp;quot;&lt;br /&gt;
                            Spouse=&amp;quot;spouse&amp;quot;&lt;br /&gt;
                            Gender=&amp;quot;1&amp;quot;&lt;br /&gt;
                          Birthday=&amp;quot;20100322&amp;quot;&lt;br /&gt;
                        Anniversary=&amp;quot;20100429&amp;quot;&lt;br /&gt;
                          Children=&amp;quot;child&amp;quot;&lt;br /&gt;
                              Notes=&amp;quot;gakm&amp;quot;&lt;br /&gt;
              CompanyPronunciation=&amp;quot;bb&amp;quot;&lt;br /&gt;
                  BUSINESS_CONTACT=&amp;quot;&amp;quot;&lt;br /&gt;
                          photofile=&amp;quot;ci-1269721575-0.jpg&amp;quot;&lt;br /&gt;
                  qdl-private-data=&amp;quot;&amp;quot;&lt;br /&gt;
                              tone=&amp;quot;/usr/local/etc/SystemRingTones/16-Tetris.desktop&amp;quot;&lt;br /&gt;
        /&amp;gt;&lt;br /&gt;
    &amp;lt;Contact Uid=&amp;quot;-1269554029&amp;quot;&lt;br /&gt;
            FirstName=&amp;quot;VoIP&amp;quot;&lt;br /&gt;
            LastName=&amp;quot;Phone1&amp;quot;&lt;br /&gt;
            FileAs=&amp;quot;VoIP Phone1&amp;quot;&lt;br /&gt;
            HomeMobile=&amp;quot;**621&amp;quot; &lt;br /&gt;
            tone=&amp;quot;/usr/local/etc/SystemRingTones/15-Techno2.desktop&amp;quot;  /&amp;gt;&lt;br /&gt;
    &amp;lt;Contact Uid=&amp;quot;-1269554032&amp;quot;&lt;br /&gt;
            Categories=&amp;quot;-1269431263&amp;quot;&lt;br /&gt;
            FirstName=&amp;quot;VoIP&amp;quot;&lt;br /&gt;
            LastName=&amp;quot;Phone3&amp;quot;&lt;br /&gt;
            FileAs=&amp;quot;VoIP Phone3&amp;quot;&lt;br /&gt;
            HomeMobile=&amp;quot;**623&amp;quot; &lt;br /&gt;
            BUSINESS_CONTACT=&amp;quot;&amp;quot;&lt;br /&gt;
            qdl-private-data=&amp;quot;&amp;quot;&lt;br /&gt;
            tone=&amp;quot;/usr/local/etc/SystemRingTones/08-Celtrelax.desktop&amp;quot;  /&amp;gt;&lt;br /&gt;
  &amp;lt;/Contacts&amp;gt;&lt;br /&gt;
  &amp;lt;/AddressBook&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
UID ist wohl egal, solange sie nicht zweimal vorkommen.&lt;br /&gt;
 &lt;br /&gt;
Die Beschränkung auf 500 Adressbucheinträge kann man auch aufheben: &lt;br /&gt;
&amp;lt;pre&amp;gt;maxEntries = 500&amp;lt;/pre&amp;gt; in der &amp;lt;pre&amp;gt;Contacts.conf&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Kategorien stehen in &amp;lt;pre&amp;gt;/user_settings/Categories.xml&amp;lt;/pre&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;xml&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&amp;lt;!DOCTYPE CategoryList&amp;gt;&lt;br /&gt;
  &amp;lt;Categories&amp;gt;&lt;br /&gt;
    &amp;lt;Category id=&amp;quot;-1269431263&amp;quot; name=&amp;quot;_Personal&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;Category id=&amp;quot;-1269431262&amp;quot; name=&amp;quot;_Business&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/Categories&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Wenn man einem Kontakt eine bestimmte Kategorie zuordnet, dann wird die ID dieser Kategorie im Attribut &amp;quot;Categories&amp;quot; des Kontakts eingetragen (s.o.). Wenn die Kategorie BUSINESS gewählt wird, steht im Attribut &amp;quot;BUSINESS_CONTACT&amp;quot; eine &amp;quot;1&amp;quot;.&lt;br /&gt;
 &lt;br /&gt;
Ein Einrücken der Attribute mit TABs in den Dateien ist übrigens nicht erlaubt!&lt;br /&gt;
 &lt;br /&gt;
Die Software des Telefons wertet die XML Datei bei jedem Zugriff neu aus. Es ist also möglich, die Datei im laufendem Betrieb zu ändern (z.B. per Script).&lt;br /&gt;
 &lt;br /&gt;
Um VCards in das XML Format zu konvertieren gibts es im Forum folgendes kleines C-Programm: [http://www.mikrocontroller.net/attachment/74583/VCardsToXML.c] [http://www.mikrocontroller.net/attachment/highlight/74583]&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
==== Fotos &amp;amp; Videoschnappschüsse ====&lt;br /&gt;
 &lt;br /&gt;
Alle Bilder die mit der Kamera aufgenommen werden, sowie Schnappschüsse die während eines Videocalls aufgenommen wurden, befinden sich in folgendem Verzeichnis:&lt;br /&gt;
      /user_data/home/Documents&lt;br /&gt;
 &lt;br /&gt;
Die Bilder sind dabei nach folgendem Namensschema benannt:&lt;br /&gt;
 &lt;br /&gt;
      DD-MM-YYYY-hh:mm:ss.jpg&lt;br /&gt;
 &lt;br /&gt;
Tag (DD) und Monat (MM) können auch einstellig sein.&lt;br /&gt;
 &lt;br /&gt;
=== Klingeltöne ===&lt;br /&gt;
 &lt;br /&gt;
Die Klingeltöne liegen, wie oben beschrieben unter:&lt;br /&gt;
 &lt;br /&gt;
/usr/local/etc/SystemRingTones/&lt;br /&gt;
 &lt;br /&gt;
Es sind .wav Dateien mit (16Khz, 16Bit, Mono), welche sich z.B. mit MhWaveEdit (Linux/GTK) oder auch Audacity recht komfortabel erzeugen lassen.&lt;br /&gt;
 &lt;br /&gt;
Auch .wav Dateien mit 22050Hz werden problemlos abgespielt (ein wenig bessere Qualität als 16000hz) und sind als Klingeltöne nutzbar. Dateien mit 44100Hz spielt es leider nur &#039;ruckelnd&#039; ab (32000Hhz nicht getestet).&lt;br /&gt;
 &lt;br /&gt;
Zusätzlich zu den Audio Dateien müssen noch im selben Verzeichnis entsprechende *.desktop dateien angelegt werden, damit alles korrekt ins Menü integriert wird.&lt;br /&gt;
Eine für den fiktiven 16. Klingelton erzeugte Datei &amp;quot;16-Tetris.desktop&amp;quot; könnte den folgenden Inhalt haben:&lt;br /&gt;
 &lt;br /&gt;
                [Desktop Entry]&lt;br /&gt;
                Categories =&lt;br /&gt;
                File =16-Tetris.wav&lt;br /&gt;
                Name[] =16-Tetris&lt;br /&gt;
                Type = audio/x-wav&lt;br /&gt;
                [Translation]&lt;br /&gt;
                File=QtopiaRingTones&lt;br /&gt;
                Context=16-Tetris&lt;br /&gt;
 &lt;br /&gt;
Nach dem Anlegen der Dateien sollte sie dann im Menü auftauchen und auswählbar sein.&lt;br /&gt;
 &lt;br /&gt;
=== Systemtöne ===&lt;br /&gt;
 &lt;br /&gt;
*Sämtliche Systemtöne liegen unter &#039;&#039;/usr/local/sounds/&#039;&#039; und lassen sich problemlos durch andere Dateien ersetzen.&lt;br /&gt;
*z.B.:&lt;br /&gt;
**&#039;&#039;charge.wav&#039;&#039; - Ton, wenn Gerät in die Basisstation gesetzt wird&lt;br /&gt;
 &lt;br /&gt;
=== Timeserver ===&lt;br /&gt;
 &lt;br /&gt;
http://www.mikrocontroller.net/topic/170483#1645101&lt;br /&gt;
Unter /usr/local/data steht in der monitor.cfg und monitor_ref_KPN.cfg&lt;br /&gt;
die Adressen der Zeitserver &amp;quot;ntp.xs4all.nl&amp;quot; und &amp;quot;130.142.110.71&amp;quot;. Diese&lt;br /&gt;
könnte man z.B. auf &amp;quot;ptbtime1.ptb.de&amp;quot; und &amp;quot;ptbtime2.ptb.de&amp;quot; ändern.&lt;br /&gt;
 &lt;br /&gt;
(http://www.mikrocontroller.net/topic/170483#1649594)&lt;br /&gt;
das telefon benutzt *nicht ntp* sondern das time-protokoll auf port 37 -&lt;br /&gt;
time.fu-berlin.de (bzw. chronos.zedat.fu-berlin.de) kann man als server nehmen.&lt;br /&gt;
 &lt;br /&gt;
vi Tipp hilfe:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
vi /usr/local/data/monitor.cfg&lt;br /&gt;
:%s/ntp.xs4all.nl/time.fu-berlin.de/g&lt;br /&gt;
:%s/130.142.110.71/130.133.1.10/g&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Aufgefallen ist, dass sich Telefone mit fest eingestellter IP nicht automatisch&lt;br /&gt;
die Uhrzeit abrufen. Stellt man das Telefon auf DHCP, stellt sich die Uhr&lt;br /&gt;
auch ohne Timeserver Modifikation auf die richtige Uhrzeit ein.&lt;br /&gt;
 &lt;br /&gt;
Wer lieber einen NTP-Client einsetzen möchte findet unter dem Link für [[#Weitere_Konsolenkommandos]] ein Paket mit ntpd oder auch ntpdate für den schnellen Zeitabgleich via Konsole:&lt;br /&gt;
    ntpdate pool.ntp.org&lt;br /&gt;
 &lt;br /&gt;
=== Zusätzliche Software ===&lt;br /&gt;
==== Dropbear (SSH-Server) installieren ====&lt;br /&gt;
 &lt;br /&gt;
# Mit telnet auf dem Gerät einloggen&lt;br /&gt;
# folgendes in die Kommandozeile kopieren&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      cd /&lt;br /&gt;
      wget http://www.mikrocontroller.net/attachment/74656/dropbear.tgz&lt;br /&gt;
      tar -xzf dropbear.tgz&lt;br /&gt;
      rm dropbear.tgz&lt;br /&gt;
      cd /etc/rc.d/init.d&lt;br /&gt;
      mv dropbear S90dropbear&lt;br /&gt;
      ./S90dropbear start&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Kommando in Zeile 6 (mv ...) ist notwendig damit dropbear bei jedem Reboot automatisch gestartet wird.&lt;br /&gt;
 &lt;br /&gt;
Prüfen ob dropbear gestartet ist und läuft:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
  # ps&lt;br /&gt;
  PID  Uid    Stat Command&lt;br /&gt;
  136 root    S    /usr/sbin/dropbear&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
Bei jedem Login sucht dropbear nach der /var/log/lastlog, daher sollte man abschließend noch ein&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
      touch /var/log/lastlog&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
machen, um diese Datei anzulegen. Damit verschwinden auch die entsprechenden Fehlermeldungen im logread.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
==== Nano 2.2.3 installieren ====&lt;br /&gt;
 &lt;br /&gt;
* Mit telnet auf dem Gerät einloggen&lt;br /&gt;
* folgendes in die Kommandozeile kopieren&lt;br /&gt;
      cd /usr/bin&lt;br /&gt;
      wget http://www.mikrocontroller.net/attachment/74023/nano&lt;br /&gt;
* Mit folgendem Befehl den Editor ausführbar machen:&lt;br /&gt;
      chmod +x /usr/bin/nano&lt;br /&gt;
* Nun ist vi Geschichte ;-)&lt;br /&gt;
 &lt;br /&gt;
Ggf. kann der Fehler &amp;quot;Error opening terminal: xterm-color&amp;quot; auftreten wenn nano gestartet wird, in diesem Fall hilft folgendes:&lt;br /&gt;
 &lt;br /&gt;
* /root/.bashrc öffnen (mit vi :-)&lt;br /&gt;
* &amp;quot;export TERM=xterm&amp;quot; in die Datei schreiben&lt;br /&gt;
* ausloggen / einloggen&lt;br /&gt;
 &lt;br /&gt;
==== OpenVPN 2.0.9 installieren ====&lt;br /&gt;
 &lt;br /&gt;
* Mit telnet auf dem Gerät einloggen&lt;br /&gt;
* folgendes in die Kommandozeile kopieren&lt;br /&gt;
      cd /&lt;br /&gt;
      wget http://www.mikrocontroller.net/attachment/74380/openvpn.tar.gz&lt;br /&gt;
      tar -xzf openvpn.tar.gz&lt;br /&gt;
      depmod&lt;br /&gt;
      mknod /dev/net/tun c 10 200&lt;br /&gt;
 &lt;br /&gt;
==== OpenVPN 2.1.1 installieren ====&lt;br /&gt;
 &lt;br /&gt;
* Mit telnet auf dem Gerät einloggen&lt;br /&gt;
* folgendes in die Kommandozeile kopieren&lt;br /&gt;
      cd /&lt;br /&gt;
      wget http://www.mikrocontroller.net/attachment/74395/openvpn-2.1.1.tar.gz&lt;br /&gt;
      tar -xzf openvpn-2.1.1.tar.gz&lt;br /&gt;
      depmod&lt;br /&gt;
      mknod /dev/net/tun c 10 200&lt;br /&gt;
 &lt;br /&gt;
==== Tinc 1.0.12 installieren ====&lt;br /&gt;
 &lt;br /&gt;
* Mit telnet auf dem Gerät einloggen&lt;br /&gt;
* folgendes in die Kommandozeile kopieren&lt;br /&gt;
      cd /&lt;br /&gt;
      wget http://www.mikrocontroller.net/attachment/74396/tinc-1.0.12.tar.gz&lt;br /&gt;
      tar -xzf tinc-1.0.12.tar.gz&lt;br /&gt;
      depmod&lt;br /&gt;
      mknod /dev/net/tun c 10 200&lt;br /&gt;
 &lt;br /&gt;
==== Weitere Konsolenkommandos ====&lt;br /&gt;
 &lt;br /&gt;
Auf http://thinksilicon.de/57/Hacking-the-VP6500.html finden sich einige nützliche Konsolentools. Darunter sind bc, lsof, file, curl, mc (bzw. mcedit), hexedit, mktemp, rsync, tcpdump, crond (mit crontab) und ntpd.&lt;br /&gt;
* Hinweis zu tcpdump; muss folgendermaßen ausgeführt werden:&lt;br /&gt;
      tcpdump -U root&lt;br /&gt;
 &lt;br /&gt;
=== simpler WLAN-Switcher ===&lt;br /&gt;
 &lt;br /&gt;
Ohne tiefer gehende GUI-Programmiererfahrungen bei Qtopia zu haben, kann man sich mit folgendem WLAN-Switcher behelfen:&lt;br /&gt;
 &lt;br /&gt;
Im Script /user_data/prod/config_ats.sh stehen viele Befehle, wie man mittels &#039;&#039;config code&#039;&#039; Einstellungen vorschreiben kann. Dies habe ich mir mit folgenden eigenen Scripten zu nutze gemacht:&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;/root/switch_wlan.sh&#039;&#039;&#039;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
#================================================&lt;br /&gt;
# WLAN-Switcher&lt;br /&gt;
#================================================&lt;br /&gt;
CONFIG_CODE=`cat /user_data/config_code.txt`&lt;br /&gt;
cp -f /usr/local/data/wpa_supplicant_ref_${CONFIG_CODE}.conf /user_data/wifi/wpa_supplicant.conf&lt;br /&gt;
 &lt;br /&gt;
* kopiert Anhand des &#039;&#039;config code&#039;&#039;s die wpa_supplicant.conf&lt;br /&gt;
* es muss für jeden &#039;&#039;config code&#039;&#039; eine wpa_supplicant_ref_&amp;lt;&#039;&#039;config code&#039;&#039;&amp;gt;.conf vorhanden sein, am besten dazu die aktuelle /user_data/wifi/wpa_supplicant.conf dorthin kopieren&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;/root/set_config_code.sh&#039;&#039;&#039;&lt;br /&gt;
#!/bin/bash&lt;br /&gt;
echo &amp;quot;$1&amp;quot; &amp;gt; /user_data/config_code.txt&lt;br /&gt;
 &lt;br /&gt;
* schreibt den ersten übergebenen Parameter in die Datei /user_data/config_code.txt&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;/usr/local/bin/set2XXX&#039;&#039;&#039;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
/root/set_config_code.sh XXX&lt;br /&gt;
/root/switch_wlan.sh&lt;br /&gt;
reboot&lt;br /&gt;
 &lt;br /&gt;
* XXX durch den &#039;&#039;config code&#039;&#039; ersetzen&lt;br /&gt;
* Script, welches als Applikation gestartet wird&lt;br /&gt;
* derzeit leider keine &amp;quot;on-the-fly&amp;quot;-Eingabe des &#039;&#039;config code&#039;&#039;s möglich, daher muss für jedes WLAN ein Script vorhanden sein&lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
 &lt;br /&gt;
&#039;&#039;&#039;/usr/local/apps/Applications/set2YYY.desktop&#039;&#039;&#039;&lt;br /&gt;
[Translation]&lt;br /&gt;
File=QtopiaApplications&lt;br /&gt;
Context=set2XXX&lt;br /&gt;
[Desktop Entry]&lt;br /&gt;
Exec=set2XXX&lt;br /&gt;
Icon=Camera&lt;br /&gt;
Type=Application&lt;br /&gt;
Name[]=Enable YYY&lt;br /&gt;
 &lt;br /&gt;
* XXX durch den &#039;&#039;config code&#039;&#039; ersetzen (gleicher Scriptname wie oben)&lt;br /&gt;
* YYY durch einmaligen Namen ersetzen&lt;br /&gt;
* Diese Datei erscheint unter dem Name[] im Applications-Menü&lt;br /&gt;
 &lt;br /&gt;
Theoretisch kann man mit dieser Methode auch problemlos zwischen mehreren SIP-Einstellungen und vielen weiteren Telefoneinstellungen umschalten (siehe Dateien in /usr/local/data) - der DemoMode funktioniert nach dem gleichen Prinzip.&lt;br /&gt;
 &lt;br /&gt;
== Buildumgebung erstellen ==&lt;br /&gt;
 &lt;br /&gt;
Bislang ist die Erstellung von GUI-Applikationen (QTopia) noch nicht auf einfache Weise möglich. Das größte Problem ist, dass der Quellcode der Video-Telefon-Anwendung zum größten Teil zur Verfügung steht. Das Erstellen von Kommandozeilen-Anwendungen geht aber schon problemlos.&lt;br /&gt;
 &lt;br /&gt;
=== Windows ===&lt;br /&gt;
Die verwendete ARM-Entwicklungsumgebung basiert auf gcc. Mittels cygwin kann diese zwar auch als Win32-Anwendungen gebaut werden, dies ist aber in hohem Maß unüblich.&lt;br /&gt;
 &lt;br /&gt;
Am besten eine aktuelle Version von Debian oder Ubuntu in &amp;quot;vmware player&amp;quot; oder &amp;quot;virtual box&amp;quot; installieren. Wenn man die virtuelle Maschine nur zum Compilieren verwendet, reicht eine kompakte Kommandozeilen-Version (z.B. Ubuntu Server 9.10). Fertige virtuelle Machinen, im vmware-Marketing-Sprech gerne auch &amp;quot;virtual appliances&amp;quot; genannt, sind reichlich verfügbar (z.B. http://www.vmware.com/appliances/directory/70918).&lt;br /&gt;
 &lt;br /&gt;
=== Freetz-Linux ===&lt;br /&gt;
Für Fritzbox-Besitzer besonders geeignet ist das Freetz-linux, welches man im IP-Phone-Forum finden kann (-&amp;gt; http://www.ip-phone-forum.de/showpost.php?p=1400234&amp;amp;postcount=1).&lt;br /&gt;
Dieses kann zum Erstellen von Freetz-Images einerseits und andererseits als Buildumgebung benutzt werden. So spart man sich eine zweite VM.&lt;br /&gt;
 &lt;br /&gt;
Die VM selbst braucht nur gestartet werden, den Rest macht man am Besten von seiner gewohnten Umgebung aus.&lt;br /&gt;
Mittels Samba kann einfach per Windowsnetzwerk auf das Home-Verzeichnis zugriffen werden und per SSH kann einfach eine Shell (UTF als Codierung einstellen, dann stimmen auch die Sonderrzeichen) geöffnet werden.&lt;br /&gt;
Es muss sichergestellt werden sein, dass die VM zugriff auf das lokale Netzwerk, sowie das Internet hat (am besten mit einem &#039;ping google.com&#039; überprüfen). Bei mir ging es eigenartiger weise erst, als ich die virtuelle Netzwerkkarte in den VM-Settings auf NAT gestellt habe.&lt;br /&gt;
 &lt;br /&gt;
Benutzername und alle Kennwörter sind &#039;freetz&#039;&lt;br /&gt;
 &lt;br /&gt;
==== Installation und Test der VP5500 Toolchain ====&lt;br /&gt;
Installation der Buildumgebung:&lt;br /&gt;
  sudo mkdir -p /opt/VP5500/toolchain&lt;br /&gt;
  cd /opt/VP5500/toolchain&lt;br /&gt;
  sudo wget http://www.handhelds.org/download/projects/toolchain/arm-linux-gcc-3.3.2.tar.bz2&lt;br /&gt;
  sudo tar xjf arm-linux-gcc-3.3.2.tar.bz2&lt;br /&gt;
  sudo rm arm-linux-gcc-3.3.2.tar.bz2&lt;br /&gt;
  sudo ln -s /opt/VP5500/toolchain/usr/local/arm /usr/local/arm&lt;br /&gt;
 &lt;br /&gt;
Nach einem sudo-Kommando muss eventuell das Passwort eingegeben werden, weswegen die Befehle einzeln eingegeben werden sollten (oder man öffnet am Anfang eine sudo shell, dann kann man das auch weglassen.&lt;br /&gt;
 &lt;br /&gt;
Test der Buildumgebung:&lt;br /&gt;
  cd ~&lt;br /&gt;
  wget http://www.mikrocontroller.net/attachment/73161/helloworld.tgz&lt;br /&gt;
  tar -xzf helloworld.tgz&lt;br /&gt;
  rm helloworld.tgz&lt;br /&gt;
  cd helloworld&lt;br /&gt;
  make&lt;br /&gt;
Dannach sollte im ~/helloworld verzeichnis ein neues executable liegen, was vom Hostrechner einfach via Netzwerkfreigabe (\\freetz-linux\helloworld) und via WinSCP auf das Telefon kopiert werden kann.&lt;br /&gt;
 &lt;br /&gt;
==== Freetz-Linux eigentlicher Anwendungszweck ====&lt;br /&gt;
wer das Ding auch zum Bauen von Freetz-Images zum Erweitern seiner Fritz-box benutzen will muss sich zuerst ein Freetz runterladen.&lt;br /&gt;
Folgende Schritte machen dies:&lt;br /&gt;
cd ~&lt;br /&gt;
svn checkout  http://svn.freetz.org/trunk  freetz-trunk&lt;br /&gt;
Dannach gibts im Home-Verzeichnis das aktuelle Freetz im Verzeichnis &#039;freetz-trunk&#039;.&lt;br /&gt;
Konfigurieren mit &#039;make menuconfig&#039; und Image erstellen mit &#039;make&#039;.&lt;br /&gt;
Wenn alles gut geht kann man das image dann vom Hostrechner aus der Windowsfreigabe &#039;\\freetz-linux\freetz-trunk\images&#039; rausholen und auf die Box spielen.&lt;br /&gt;
 &lt;br /&gt;
Für detailiertere Infos bitte direkt bei Freetz nachschlagen:&lt;br /&gt;
http://trac.freetz.org/&lt;br /&gt;
 &lt;br /&gt;
=== Linux ===&lt;br /&gt;
Die bisher bekannten, mit VP5500 und VP6500 ausgelieferten Software-Versionen, basieren auf einer etwas älteren &amp;quot;gcc 3.3.2-ARM-Toolchain&amp;quot;. Eine passende Toolchain für ein x86-basiertes Entwicklungssystem ist unter http://www.handhelds.org/download/projects/toolchain/arm-linux-gcc-3.3.2.tar.bz2 zu finden.&lt;br /&gt;
 &lt;br /&gt;
Unter Debian-basierten Linux-Distros kann dieses Archiv z.B. nach /opt/VP5500/toolchain entpackt werden (einige der Makefiles im Forum setzen diesen Speicherort voraus). Es ist jedoch zu beachten, dass diese Version der Toolchain auch über den Pfad /usr/local zugänglich sein sollte. Dazu kann mittels &amp;quot;ln -s /opt/VP5500/toolchain/usr/local/arm arm&amp;quot; in /usr/local ein Symlink auf den eigentlichen Speicherort gesetzt werden.&lt;br /&gt;
 &lt;br /&gt;
==== Hello World ====&lt;br /&gt;
Christian Klippel (ChrisK) hat unter http://www.mikrocontroller.net/attachment/73161/helloworld.tgz ein &amp;quot;Hello World&amp;quot; bereitgestellt, mit dem sich die Toolchain testen lässt und dessen &amp;quot;Makefile&amp;quot; und &amp;quot;Makefile.local&amp;quot; als Grundlage für eigene Versuche dienen kann.&lt;br /&gt;
 &lt;br /&gt;
Das Archiv wird in ein lokals Verzeichnis (z.b. ~/helloworld) entpackt und dort durch Eingabe von &amp;quot;make&amp;quot; compiliert.&lt;br /&gt;
   &lt;br /&gt;
Zum Testen muss das Binary natürlich auf das Zielsystem übertragen werden. Wenn auf dem Entwicklungssystem ein http-Server oder ein ssh-Server läuft, kann man das Binary einfach in ein darüber zugängliches Verzeichnis kopieren es anschließend in einer telnet-Sitzung vom Verzeichnis /tmp aus mittels wget oder scp laden. Zum Test muss die Datei mittels &amp;quot;chmod +x helloworld&amp;quot; ausführbar gemacht werden, bevor sie mit &amp;quot;./helloworld&amp;quot; ausgeführt werden kann.&lt;br /&gt;
 &lt;br /&gt;
Mittels eines ftpd (z.B. http://www.mikrocontroller.net/attachment/73780/troll-ftpd_1.28-cg2_arm.tgz) oder sshd (z.B. Dropbear von http://vp6500.bd8.nl/) auf dem Zielsystem, kann man das Kopieren auch vom Entwicklungssystem aus durchführen.&lt;br /&gt;
 &lt;br /&gt;
==== Anpassen kleinerer Konsolen-Tools auf Cross-Compilierung ====&lt;br /&gt;
Die Makefiles von kleineren Projekten sind häufig nicht so sauber aufgebaut wie das helloworld-Beispiel, so dass man sie leichter ersetzt, als ändert. Am Beispiel von micro_httpd (http://www.acme.com/software/micro_httpd/ , http://www.mikrocontroller.net/attachment/73175/micro_httpd.tar.gz) kann leicht nachvollzogen werden, wie man den modularen Ansatz vom &amp;quot;Hello World&amp;quot;-Beispiel übernehmen kann (Makefile -&amp;gt; Makefile + Makefile.local).&lt;br /&gt;
 &lt;br /&gt;
= Sonstiges =&lt;br /&gt;
 &lt;br /&gt;
== Hardware  + Software Versionen ==&lt;br /&gt;
 &lt;br /&gt;
Listet mal eure Hardware- und Softwareversion aus dem &#039;&#039;&#039;Applications&#039;&#039;&#039; =&amp;gt; &#039;&#039;&#039;System Info&#039;&#039;&#039; Menü auf, wenn sie hier noch nicht stehen!&lt;br /&gt;
 &lt;br /&gt;
=== VP5500 ===&lt;br /&gt;
 &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Hardware Version            !! Date    !! Software Version &lt;br /&gt;
|-&lt;br /&gt;
| ind5                        ||0645      || 4.20&lt;br /&gt;
|-&lt;br /&gt;
| ind5                        ||0647      || 4.20&lt;br /&gt;
|-&lt;br /&gt;
| ind5                        ||0648      || 4.20&lt;br /&gt;
|-&lt;br /&gt;
| ind5                        ||0649      || 4.20&lt;br /&gt;
|-&lt;br /&gt;
| ind5                        ||0702      || 4.20&lt;br /&gt;
|-&lt;br /&gt;
| ind5                        ||0703      || 4.20&lt;br /&gt;
|}&lt;br /&gt;
 &lt;br /&gt;
=== VP6500 ===&lt;br /&gt;
 &lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Hardware Version            !! Date    !! Software Version &lt;br /&gt;
|-&lt;br /&gt;
| ind3-v2                      || 0711    || 3.22&lt;br /&gt;
|-&lt;br /&gt;
| ind3-v2                      || 0713    || 3.22&lt;br /&gt;
|-&lt;br /&gt;
| ind3-v2                      || 0716    || 3.22&lt;br /&gt;
|}&lt;br /&gt;
= Wünsche und Nutzungsideen =&lt;br /&gt;
&lt;br /&gt;
Wer was äußern möchte, kann das hier reintippeln, zwecks Bündelung Interessen und Kräfte. Muss ja keiner das Rad 3x erfinden und man kann schaun was der ein oder andere macht.&lt;br /&gt;
Eine Status und Kontaktangabe bei Sachen die in Arbeit sind wäre toll.&lt;br /&gt;
 &lt;br /&gt;
== Software ==&lt;br /&gt;
 &lt;br /&gt;
* Audiostream-Player&lt;br /&gt;
* MP3&lt;br /&gt;
** madplay gibt es [http://www.mikrocontroller.net/topic/172616#1704777 hier], der automatische Stromsparmodus stört aber noch&lt;br /&gt;
* Browser und sei es nur für Wikipedia und Google&lt;br /&gt;
* Mailclient&lt;br /&gt;
* T9 Unterstützung bei Texteingabe&lt;br /&gt;
* Skypebenutzung&lt;br /&gt;
* Nutzungsmöglichkeit als Wireless-Webcam&lt;br /&gt;
* WLAN-Repeater&lt;br /&gt;
** besser: [http://freifunk.net Freifunk-] bzw. [http://www.olsr.org OLSR-Daemon]&lt;br /&gt;
* Wecker&lt;br /&gt;
* Voice-Crypto&lt;br /&gt;
* Unterstützung von mehreren WLAN Profilen, damit man das Gerät an mehreren APs betreiben kann ohne jedesmal SSID / Key neu eingeben zu müssen. (Sollte durch mehrere Einträge in der wpa_supplicant.conf möglich sein. Diese wird aber bei Änderungen über&#039;s Menü komplett überschrieben. Alternative: [[#simpler WLAN-Switcher]])&lt;br /&gt;
* Unterstützung von mehreren SIP Profilen, um z.b. von einem SIP-Anbieter auf den anderen zu wechseln. Ideal wäre, wenn man 2 SIP Profile gleichzeitig nutzen könnte&lt;br /&gt;
* YouTube Client, vgl. mit &amp;quot;MiniTube Linux&amp;quot;&lt;br /&gt;
* &#039;ne aktuelle Firmware? z.B: mit 2.6er Kernel und Android?&lt;br /&gt;
* Unterstützung für WLANs mit 802.1x die WPA2 verschlüsselt sind reparieren bzw. passende Konfig finden (unverschlüsselt geht schon)&lt;br /&gt;
 &lt;br /&gt;
== Hardwarerweiterungen ==&lt;br /&gt;
 &lt;br /&gt;
* Speichererweiterung&lt;br /&gt;
* USB Anschluss&lt;br /&gt;
* Blauzahn&lt;br /&gt;
* zusätzlicher Anschluss um eine andere Videokamera anzuschließen mit CINCH&lt;br /&gt;
 &lt;br /&gt;
== Nutzungsideen ==&lt;br /&gt;
 &lt;br /&gt;
* VoIP Phone und Webcam (nahliegend)&lt;br /&gt;
* WLAN-Finder&lt;br /&gt;
* Repeater&lt;br /&gt;
* mobiles Infogerät mit Wikizugriff und Mailpush in der Wireless-Bubble&lt;br /&gt;
* Türöffner, Ferncontroller&lt;br /&gt;
* Robohirn&lt;br /&gt;
* WLAN-Radio&lt;br /&gt;
* Video(Streaming)-Client in Verbindung mit VDR&lt;br /&gt;
* Barcode-Reader&lt;br /&gt;
* als Fernbedienung für PC (Winamp/Mediaplayer/VLC...&lt;br /&gt;
* Streamclient und Fernbedienung für DBOX2 mit Linux&lt;br /&gt;
 &lt;br /&gt;
[[Kategorie:Projekte]]&lt;br /&gt;
[[Kategorie:Datenübertragung]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Entwicklungsboard_mit_PIC&amp;diff=75790</id>
		<title>Entwicklungsboard mit PIC</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Entwicklungsboard_mit_PIC&amp;diff=75790"/>
		<updated>2013-05-22T16:16:02Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: Schützte „Entwicklungsboard mit PIC“: Weblink-Spam ([edit=autoconfirmed] (bis 22. Juni 2013, 16:16 Uhr (UTC)) [move=autoconfirmed] (bis 22. Juni 2013, 16:16 Uhr (UTC)))&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Kategorie:Wettbewerb]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;von Denys Maiier&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
{{Wettbewerb Header}}&lt;br /&gt;
&lt;br /&gt;
      [[Datei:brd mini.jpg]]  [[Datei:Entwicklungsboard_gefräst.JPG]]&lt;br /&gt;
&lt;br /&gt;
== Vorwort ==&lt;br /&gt;
&lt;br /&gt;
Dieses Kit dient als Lehrmittel  für Studenten, Schüler und diejenigen, die Grundlagen und Funktionalität der Mikroprozessortechnik, am Beispiel des Microcontrollers der PIC18 Familie von der Firma Microchip, beherrschen möchten.  Mit Hilfe der im Kit erhaltenen Modulen  können folgende Programmieraufgaben gelöst werden:&lt;br /&gt;
&lt;br /&gt;
•	Ein- und Ausgabe über I/O Ports und Kontrolle  der Ausgabe über 16 LED’s&lt;br /&gt;
&lt;br /&gt;
•	Externe Programmunterbrechung über 3 Interruptquellen(3 Buttons)&lt;br /&gt;
&lt;br /&gt;
•	Verbindung mit dem PC über UART &lt;br /&gt;
&lt;br /&gt;
•	Datenübertragung über IR&lt;br /&gt;
&lt;br /&gt;
•	Tonausgabe (Buzzer)&lt;br /&gt;
&lt;br /&gt;
•	Datenübertragung über SPI und I²C  im Halb-Duplex-Mode&lt;br /&gt;
&lt;br /&gt;
•	Schrittmotorensteuerung&lt;br /&gt;
&lt;br /&gt;
•	Dynamische Tastatureingabe&lt;br /&gt;
&lt;br /&gt;
•	AD- Umwandlung&lt;br /&gt;
&lt;br /&gt;
•	Datenausgabe auf dem HD44780 Display&lt;br /&gt;
&lt;br /&gt;
== Projektinhalt ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
     a.	Mainboard&lt;br /&gt;
     b.	SPI-Board&lt;br /&gt;
     c.	I²C-Board&lt;br /&gt;
     d.	Com-Board&lt;br /&gt;
     e.	Hitachi LCD Board&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hardware ==&lt;br /&gt;
&lt;br /&gt;
Projekt der Entwicklungsplatine basiert sich auf dem PIC 18F4520 Microcontroller und besteht aus dem Main-board und Peripherie-Modulen , die mit Hilfe der Kabelverbindungen mit Main-board verbunden werden. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Mainboard ==&lt;br /&gt;
&lt;br /&gt;
Mainboard verfügt über 33 I/O Ports, die allerdings spezifisch benutzt werden können. Die PORTB I/O Pins können softwaremäßig an die innere Pull-Up Widerstände angeschlossen werden. Das MCU wird über Quarz/Keramik Oszillator taktversorgt.Die Kapazität der Kondensatoren liegt im Bereich 15-25pF und von den Quartzeigenschaften abhängig.Die empfohlene Größe steht üblicherweise im Datenblatt. Buzzer SG1  kann anhand dem Jumper JP2 an Port RE2 angeschlossen werden. Drei Tasten (INT1-INT3) zusammen mit Widerständen R69 bis R71 und R20 bis R23 ermöglichen die externe Programmunterbrechung. Mikrocontroller PIC18 verfügt über ICSP Modul und kann über ICSP Input direkt im Board programmiert werden.  16 separat gesteuerte LED sind  über JP5 und JP10 an die Output-Pins von PIC18 anzuschließen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Mainboard Modul&#039;&#039;&lt;br /&gt;
[[Datei:Mainboard V1.0.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
PIC 18 verfügt über Master Synchronous Serial Port und kann im SPI oder I²C Modus arbeiten. Dieses Entwicklungsboard hat zwei Module womit die  Grundlagen der  seriellen Übertragung  geübt werden können.&lt;br /&gt;
&lt;br /&gt;
== SPI-Interface Board ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;SPI Modul&#039;&#039;&lt;br /&gt;
[[Datei:SPI Modul.png]]&lt;br /&gt;
&lt;br /&gt;
Wenn MSSP als SPI eingestellt ist, sollen die Pins RC3-RC5 des PIC18 entsprechend softwaremäßig eingestellt und mit ISP – Modul verbunden werden. Benötigt wird auch noch ein Port-Pin des MCU um den Chip Select Eingänge der MCP23S17  zu steuern.&lt;br /&gt;
SPI Interface Modul – Platine ermöglicht separate Steuerung von zwei MCP23S17 Bausteinen, die allerdings mit dem gemeinsamen Chip Select Signal  und unterschiedlichen HW-Adressen (000 und 111) als I/ O  Serial – zu –Parallel Treiber funktionieren. &lt;br /&gt;
IC2 ist mit 4 Binär zu Dezimal Wandler ausgestattet und  wird zur Ausgabe der 16 Bit Daten benutzt.  &lt;br /&gt;
Die ersten 8 Bit vom IC3 können über JP15 mit zwei L293D Schritt-Motoren –Treiber beschaltet werden. &lt;br /&gt;
Die Bits 9 bis 16 dienen als Inputs und können mit externer Tastatur  4x4 angeschlossen werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== I²C Interface Board ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;I²C Modul&#039;&#039; [[Datei:I2C Interface.jpg]]&lt;br /&gt;
&lt;br /&gt;
Wenn MSSP im I²C Modus ist, wird die I²C Interface Platine benötigt.  Entsprechende MCU Pins RC3 und RC4 sollen dann mit I2C-Input beschaltet werden. &lt;br /&gt;
Über I²C Protokoll können  folgende Peripherie-Bauteile angesteuert werden: Real Clock Modul, EEProm, ADU Umwander mit 4 über Potis beschalteten  Analog- Eingängen, Serial-to-Parallel Wandler mit 8 LED , Serial-to-Parallel Wandler mit 4x4 Tastatur und ein Temperatursensor.&lt;br /&gt;
Zugang zu den einzelnen Bauelementen erfolgt über  verschiedene Adressen der Peripherie. Damit werden die Kollisionen vermieden. &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;HW-Adressen der I²C Peripherie&#039;&#039;&lt;br /&gt;
[[Datei:HW-Adresse.bmp]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Comm-Modul ==&lt;br /&gt;
RS-232&amp;amp; USB Modul [[Datei:USB&amp;amp;RS-232&amp;amp;Keyboard.jpg]]&lt;br /&gt;
&lt;br /&gt;
Peripherie- Com-Modul ermöglicht die Datenübertragung zwischen dem PC und MCU über eine UART Schnittstelle. Dafür müssen gewisse Änderungen im Software vorgenommen werden. Außerdem sollen die Port-Pins RC6 und RC7 mit den entsprechenden Kontakten der JP18 JP17 verbunden sein(Siehe Videobeispiel &amp;quot;Anschluß mit PC über USB&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
== LCD-Modul ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;PVC200403P&#039;&#039;[[Datei:PVC200403P.JPG]]&lt;br /&gt;
&lt;br /&gt;
Über  die Pin-Heads JP8(JP6 oder JP7) und JP19 kann die parallele Steuerung des LCD-Moduls organisiert werden. In meinem Fall habe ich ein Display PVC200403P von PICVUE  genommen.  Das ist ein Hitachi HD44780 Standard- Display, und verfügt über 8–bit Daten-Bus + 3 Steuerung-Wires.  Erlaubt ist auch die Datenübertragung über 4-bit Daten-Bus+3 Steuerung-Wires. D.h. benötigt werden mindestens 7 Adern des MCU + Stromversorgung. Im Beispiel 3 und 4 (Siehe Anhang &amp;quot;Videobeispiele&amp;quot;), habe ich mein Display mit insgesamt 8 Adern gesteuert(-,+ -Stromversorgung, E-Enable, RS-Register Select, 4-bit Datenbus). Alle anderen Eingänge wurden mit &amp;quot;-&amp;quot; verbunden.  Diese Lösung spart Euch I/O, benötigt allerdings bisschen komplexere LCD-Initialisierung. Die im Datenblatt&amp;quot;PVC200403P&amp;quot; angegebene Zeitverzögerungen zwischen den Initialisierungsbefehlen habe ich mit Timer1 realisiert und damit die Abfrage des Busy-Flags gespart.&lt;br /&gt;
&lt;br /&gt;
== ICSP Programmierung ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;ICSP I/O  Beschaltung&#039;&#039; [[Datei:ICSP.png]]&lt;br /&gt;
&lt;br /&gt;
Ein ICSP I/O ermöglicht die interne Programmierung des Microcontrollers, &lt;br /&gt;
Z.b. via PicKit2 oder PicKit3. In meinem Fall habe ich ein EEPRom Programmiergerät mit ZIF-Socket zu ICSP Adapter genommen(Siehe Anhang).&lt;br /&gt;
&lt;br /&gt;
[http://www.mikrocontroller.net/wikifiles/2/2f/ICSP_Programmierung.JPG EEPROM_Programmer + ICSP Adapter]&lt;br /&gt;
&lt;br /&gt;
== Leiterplatte ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A4 Größe Design&#039;&#039; [[Datei:Brd Entwicklungsboard.png]]&lt;br /&gt;
&lt;br /&gt;
Schaltplandesign und Leiterplattenentwurf wurde im Eagle realisiert. Der Prototyp wurde auf der doppelseitigen Leiterplatte gefräst und bestückt. Das MCU wurde im Sockel befestigt. Hiermit können die weitere Erweiterungen und MCU-Wechsel ohne Löten durchgeführt werden.&lt;br /&gt;
Der Spannungsregler wurde auf die Leiterplatte gelegt und übers Wärmeleitpad mit dem Lötzinn befestigt. Somit spielt die Plattenfläche auch die Rolle des Kühlkörpers. &lt;br /&gt;
&lt;br /&gt;
[[Datei:7805T.JPG]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Praktische Anwendung ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Real Time Clock &#039;&#039; [[Datei:Realtime_Clock.BMP]]&lt;br /&gt;
&lt;br /&gt;
Eine der möglichen Anwendungen der Entwicklungsplatine ist ein Real-Clock mit der Ausgabe auf dem LCD-Display (siehe Bild). Hiermit werden die Prinzipien der I2C-, Parallel Datenübertragung und der dynamischen Tastenabfrage geübt. In dem Fall benötigen wir ein HD44780 Modul, Mainboard- Modul und ein I2C Modul. &lt;br /&gt;
Die 4x4 Tastatur wird direkt an PortB des MCU angeschlossen. Die ersten 4 Bits sind als Ausgange konfiguriert und die letzten 4 Bits dienen als Eingange mit den inneren Pull-Up Widerständen. Die parallele Datenübertragung zwischen dem MCU und LCD-Modul erfolgt über Port D und Port E des Microcontrollers. Die beiden Peripherie – Bausteine PCF8574 und PCF8583 benötigen serielle Datenübertragung  im I²C Mode mit Taktfrequenz &amp;lt;100kHz. Damit es nicht zu Kollisionen führt, haben die beiden Bausteine verschiedene Adressen. Achten Sie auch darauf, dass alle Bausteine der I²C Peripherie eigene Protokollspezifik haben. Z.B.:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;PCF8574_Read_Mode&#039;&#039;  [[Datei:8574_Read_Mode.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;PCF8574_Write_Mode&#039;&#039;  [[Datei:8574 Write Mode.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;PCF8583_Read_Mode&#039;&#039;  [[Datei:Clock_Read_Mode.png]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;PCF8583_Write_Mode&#039;&#039;  [[Datei:Clock_Write_Mode.png]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Fazit ==&lt;br /&gt;
Der Einstieg in die moderne Mikroprozessor- und Mikrocontroller-welt ist praktisch ohne Evaluations-Kits nicht möglich. An manchen Stellen ist die Simulationsprogramm ungenau, insbesondere ist sehr von der Prozessorbelastung abhängig,und lässt die äußere Einflüsse nicht simulieren.In dem Fall ist der Einsatz der Entwicklungsplatine unvermeidlich. Mehrere auf dem Markt vorgestellte Platten sind wegen ihren hohen Preisen nicht an einen durchschnittlichen Käufer(Studenten oder Schüler) gedacht und beziehen sich auf den konkreten Mikroprozessor, der nicht auszutauschen ist. In diesem Zusammenhang , bietet die angebotene Entwicklungsplatine die Universalität, kann leicht nachgebaut und erweitert werden. Der IC-Sockel ermöglicht den unkomplizierten MCU-Tausch, Upgrade oder Übergang zu dem MCU anderer Hersteller.  &lt;br /&gt;
&lt;br /&gt;
== Kontakt ==&lt;br /&gt;
Nach Anfrage kann ich auch die Quellcode, sowie PCB-Design und Programmierbeispiele zur Verfügung stellen.&lt;br /&gt;
Ihre Fragen bitte an : maiierok@t-online.de&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Videobeispiele ==&lt;br /&gt;
&#039;&#039;Video &amp;quot;Anwendung Real-Time Clock&amp;quot;&#039;&#039;&lt;br /&gt;
[http://www.youtube.com/watch?v=9R3alJx_ldA Simulation im Proteus]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Video &amp;quot;Versuch #1 LED&amp;amp; Buzzer- Steuerung&amp;quot;&#039;&#039;&lt;br /&gt;
[http://youtu.be/Yn8-Ny-1He0  LED&amp;amp;Buzzer TEST#1 ]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Beispiel 3 &amp;quot;Liebeserklärung&#039;&#039;&lt;br /&gt;
[http://youtu.be/26qt7u2WQ8s Mainboard + HD44780]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Beispiel 4 &amp;quot;Anschluß mit PC über USB&#039;&#039;&lt;br /&gt;
[http://www.youtube.com/watch?v=nqvd8O5QHOQ Mainboard+ Comm-Board+ HD44780]&lt;br /&gt;
&lt;br /&gt;
== Link ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;PIC18 Datasheet&#039;&#039;  [[Datei:Pic18f2420-2520-4420-4520.pdf]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;A200_ua7805&#039;&#039;  [[Datei:A200_ua7805.pdf]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;PCF8583&#039;&#039;  [[Datei:Clock and Calendar.pdf]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;PCF8574&#039;&#039;  [[Datei:PCF8574.pdf]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;I²C_ Temperature Sensor&#039;&#039;  [[Datei:Thermo_I²C.pdf]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Mcp23s17 SPI Expander&#039;&#039;  [[Datei:Mcp23s17.pdf]]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;HD44780 Display&#039;&#039;  [http://www.adafruit.com/datasheets/HD44780.pdf  Datasheet]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=P89626&amp;diff=75789</id>
		<title>P89626</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=P89626&amp;diff=75789"/>
		<updated>2013-05-22T16:15:14Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: Schützte „P89626“: Weblink-Spam ([edit=autoconfirmed] (bis 22. Juni 2013, 16:15 Uhr (UTC)) [move=autoconfirmed] (bis 22. Juni 2013, 16:15 Uhr (UTC)))&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Alles über den [http://www.medion.com/au/service/start/_product.php?msn=50039627 MEDION LIFE P89626 (MD 86407) NAS] den es im Dez.2011 bei Aldi-Süd für 99€ gab &lt;br /&gt;
&lt;br /&gt;
Nummern von Medion: MD 86407 - MSN: 50039627&lt;br /&gt;
&lt;br /&gt;
Desweiteren kann dies größtenteils auch auf den P89630 NAS von Medion angewandt werden, welcher lediglich eine größere Festplatte besitzt (2TB). Sämtliche andere Eigenschaften sind exakt gleich.&lt;br /&gt;
&lt;br /&gt;
= Beitrag im Forum =&lt;br /&gt;
&lt;br /&gt;
* [https://www.mikrocontroller.net/topic/240238 Alles rund um den MEDION LIFE P89626 NAS]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/187115#new 20Euro Embedded System mit ARM, 128MB RAM und 256MB Flash ]&lt;br /&gt;
&lt;br /&gt;
extern:&lt;br /&gt;
* http://forum.nas-portal.org/forumdisplay.php?135-Medion&lt;br /&gt;
* http://forums.whirlpool.net.au/archive/1817691&lt;br /&gt;
&lt;br /&gt;
= Unterseiten =&lt;br /&gt;
&lt;br /&gt;
Es gibt noch eine Reihe Unterseiten:&lt;br /&gt;
&lt;br /&gt;
* [[P89626/UART]] - Alles rund um die UART-Schnittstelle&lt;br /&gt;
* [[P89626/debootstrap]] - NAS mit Debian betreiben&lt;br /&gt;
* [[P89626/ArchLinuxARM]] - NAS mit ArchLinuxARM betreiben&lt;br /&gt;
* [[P89626/dropbear]] - SSH Server mit dropbear einrichten&lt;br /&gt;
* [[P89626/usb key func]] - In den Boot-Prozess reinhacken&lt;br /&gt;
&lt;br /&gt;
(Alle Seiten sollten in der [http://www.mikrocontroller.net/articles/Kategorie:P89626 Kategorie &amp;quot;P89626&amp;quot;] sein!)&lt;br /&gt;
&lt;br /&gt;
= Technische Daten =&lt;br /&gt;
&lt;br /&gt;
* Dual Core ARM [http://www.plxtech.com/products/consumer/nas7820 PLX-NAS7820] 750 MHz (&#039;&#039;&#039;Achtung:&#039;&#039;&#039; Offizielle Firmware bis Version 1.01 nutzt nur einen CPU-Kern! Siehe [[P89626#Single_Core_Problem]])&lt;br /&gt;
* 128 MB RAM&lt;br /&gt;
* 1.50 TB (1.36 TiB) Seagate Barracuda Green ST1500DL003-9VT1 SATA-HD&lt;br /&gt;
* 2 x USB 2.0&lt;br /&gt;
* 1 x Gigabit LAN (Realtek RTL8211E)&lt;br /&gt;
&lt;br /&gt;
Netzteil:&lt;br /&gt;
* Eingang: 100-240 V, 50/60 Hz,  0,4 A&lt;br /&gt;
* Ausgang: 12 V,  1,5 A Gleichspannung&lt;br /&gt;
&lt;br /&gt;
== Single-Core-Problem ==&lt;br /&gt;
&lt;br /&gt;
!Die aktuelle Firmware 1.02 nutzt nun beide Kerne der CPU!&lt;br /&gt;
&lt;br /&gt;
In der Box steckt zwar ein Dual-Core, doch entgegen der Werbeaussage wird bei der aktuellen Firmware &#039;&#039;&#039;1.00(UZD.2)&#039;&#039;&#039; (&#039;&#039;cat /zyxel/mnt/info/fwversion&#039;&#039;) nur &#039;&#039;&#039;ein CPU-Kern genutzt!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Hier ein paar Indizien, die das belegen sollen (Bitte ergänzen):&lt;br /&gt;
&lt;br /&gt;
Dateien/Unterverzeichnisse existieren in &#039;&#039;/sys/devices/system/cpu/&#039;&#039;&#039;cpu0&#039;&#039;&#039;&#039;&#039;, aber &#039;&#039;/sys/devices/system/cpu/&#039;&#039;&#039;cpu1&#039;&#039;&#039;&#039;&#039; ist leer (siehe http://www.mikrocontroller.net/topic/240238?page=2#2448859 )&lt;br /&gt;
&lt;br /&gt;
Außerdem, zeigt es der Inhalt dieser Dateien an (siehe http://www.mikrocontroller.net/topic/240238?goto=2469569#2469802 ):&lt;br /&gt;
&amp;lt;pre&amp;gt;/sys/devices/system/cpu/kernel_max -&amp;gt; 1&lt;br /&gt;
/sys/devices/system/cpu/offline -&amp;gt; 1&lt;br /&gt;
/sys/devices/system/cpu/online -&amp;gt; 0&lt;br /&gt;
/sys/devices/system/cpu/possible -&amp;gt; 0-1&lt;br /&gt;
/sys/devices/system/cpu/present -&amp;gt; 0-1&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;offline:&#039;&#039;&#039; cpus that are not online because they have been&lt;br /&gt;
HOTPLUGGED off or exceed the limit of cpus allowed by the&lt;br /&gt;
kernel configuration (kernel_max above).&lt;br /&gt;
Quelle: http://www.kernel.org/doc/Documentation/ABI/testing/sysfs-devices-system-cpu&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Original-System zeit per [[#dmesg]]:&lt;br /&gt;
&amp;lt;pre&amp;gt;Brought up 1 CPUs&lt;br /&gt;
SMP: Total of 1 processors activated (299.00 BogoMIPS).&amp;lt;/pre&amp;gt;&lt;br /&gt;
ArchLinuxARM zeigt das an:&lt;br /&gt;
&amp;lt;pre&amp;gt;[    0.630000] Brought up 2 CPUs&lt;br /&gt;
[    0.640000] SMP: Total of 2 processors activated (598.83 BogoMIPS).&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn du das NAS P89626 oder P89630 hast, schreib Aldi an und mache sie auf das Problem aufmerksam. Vielleicht erstellt Medion dann eine neue Firmware, wobei sie z.Z. das Problem abstreiten (siehe: http://www.mikrocontroller.net/topic/240238?goto=2468866#2468866 )&lt;br /&gt;
Kontakt zu Aldi:&lt;br /&gt;
* https://www.aldi-sued.de/de/html/contact.php&lt;br /&gt;
* https://www.aldi-nord.de/kontakt_form.php&lt;br /&gt;
&lt;br /&gt;
&amp;lt;u&amp;gt;Anmerkung:&amp;lt;/u&amp;gt;&lt;br /&gt;
Das Sourcecode-Archiv ist der eindeutigste Hinweis, da hier eben der Startup des zweiten Kerns unterbunden worden ist.&lt;br /&gt;
&lt;br /&gt;
hier die Infos zu den Stellen der Deaktivierung:&lt;br /&gt;
* http://www.mikrocontroller.net/topic/240238?goto=2470122#2470122&lt;br /&gt;
* http://www.mikrocontroller.net/topic/240238?goto=2470148#2470148&lt;br /&gt;
&lt;br /&gt;
und hier das Ergebnis beim Entfernen dieser Zeilen.&lt;br /&gt;
* http://www.mikrocontroller.net/topic/240238?goto=2470241#2470241&lt;br /&gt;
&lt;br /&gt;
== Festplattentemperatur ==&lt;br /&gt;
&lt;br /&gt;
Die Box neigt mit ihrem lüfterlosen Design dazu, sich unter Last stark aufzuheizen. Forennutzer berichten von Festplattentemperaturen über 55°C (auslesbar mit smartmontools) [http://www.mikrocontroller.net/topic/240238#2443707]. Seagate spezifiziert für die Platte eine Betriebstemperatur bis 60°C und eine maximale Temperaturänderung im Betrieb von 20°C pro Stunde [http://www.seagate.com/ww/v/index.jsp?name=st1500dl003-bcuda-green-sata-6gb-1.5tb-hd&amp;amp;vgnextoid=2035439d45c0b210VgnVCM1000001a48090aRCRD&amp;amp;locale=en-US&amp;amp;pf=1#tTabContentSpecifications]. Um die Einhaltung dieser Vorgaben zu garantieren, bieten sich zwei Möglichkeiten an:&lt;br /&gt;
* Verwendung eines Lüfters mit externer Stromversorgung. Anbringung an Ober-/Unterseite des Gehäuses oder Montage eines Radiallüfters im Gehäuseinnern.&lt;br /&gt;
* Entfernen des schwarzen Kunststoffgehäuses (senkt die Temperatur der Festplatte unter Last auf etwa 40°C).&lt;br /&gt;
&lt;br /&gt;
Eine Anleitung zur Lüftermontage findet sich in:  [http://www.mikrocontroller.net/attachment/132515/Installation_ArchLinuxArm.pdf]&lt;br /&gt;
&lt;br /&gt;
== Ähnliche Geräte ==&lt;br /&gt;
&lt;br /&gt;
Systeme, die den gleichen SoC-&amp;quot;NAS 7820&amp;quot;-Prozessor nutzen:&lt;br /&gt;
* MEDION LIFE P89630 (MD 86587) (gleiche Box, nur mit 2-TB-Laufwerk)&lt;br /&gt;
* MEDION LIFE [[P89636]] (gleiche Box, nur mit 1-TB-Laufwerk)&lt;br /&gt;
* [http://archlinuxarm.org/platforms/armv6/pogoplug-provideov3 Pogoplug Pro/Video/v3]&lt;br /&gt;
* [http://iomega.nas-central.org/wiki/Category:Home_Media_CE Iomega Home Media Network Hard Drive, Cloud Edition]&lt;br /&gt;
** Open Source Paket: https://iomega-eu-en.custhelp.com/app/answers/detail/a_id/26776&lt;br /&gt;
* [http://www.heise.de/preisvergleich/692728 Level One GNS-1001]&lt;br /&gt;
** Firmware Download: http://www.level1.tw/level1/firmware/GNS-1001(GNS-1001_v3.6.6_HW-1)_2011-07-22.zip&lt;br /&gt;
&lt;br /&gt;
= Demontage =&lt;br /&gt;
&lt;br /&gt;
Die Demontage und das Wechseln der S-ATA-Festplatte sind sehr einfach für Schrauber möglich: Unter den Gummifußflächen sind zwei Schrauben zu lösen, dann kann man das Gehäuse aus zwei Schalen recht einfach auseinandernehmen. Festplatte und Elektronik sind mit weiteren zwei Schrauben vom Gehäusedeckel zu lösen. Festplatte ist mit drei Schrauben an dem Platinenteil befestigt. Alles ohne große Probleme zu lösen und wieder zusammenzubauen...&lt;br /&gt;
&lt;br /&gt;
Bilder der Platine gibt es u.a. hier:&lt;br /&gt;
* http://flickr.com/photos/jensdiemer/tags/p89626/&lt;br /&gt;
&lt;br /&gt;
sowie hier: [http://i41.tinypic.com/5leazs.jpg], [http://i43.tinypic.com/11qjvgh.jpg], [http://i44.tinypic.com/2nurcr8.jpg], [http://i42.tinypic.com/25tc576.jpg]&lt;br /&gt;
&lt;br /&gt;
== cpuinfo ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
~ # cat /proc/cpuinfo &lt;br /&gt;
Processor       : ARMv6-compatible processor rev 5 (v6l)&lt;br /&gt;
processor       : 0&lt;br /&gt;
BogoMIPS        : 299.00&lt;br /&gt;
&lt;br /&gt;
Features        : swp half thumb fastmult edsp java &lt;br /&gt;
CPU implementer : 0x41&lt;br /&gt;
CPU architecture: 7&lt;br /&gt;
CPU variant     : 0x0&lt;br /&gt;
CPU part        : 0xb02&lt;br /&gt;
CPU revision    : 5&lt;br /&gt;
&lt;br /&gt;
Hardware        : Oxsemi NAS&lt;br /&gt;
Revision        : 0000&lt;br /&gt;
Serial          : 0000000000000000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== /proc/modules ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ntfs 106132 0 - Live 0xbf015000&lt;br /&gt;
gmac 47336 0 - Live 0xbf004000&lt;br /&gt;
mii 6764 1 gmac, Live 0xbf000000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== lsmod ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/ # lsmod&lt;br /&gt;
gmac 47336 0 - Live 0xbf004000&lt;br /&gt;
mii 6764 1 gmac, Live 0xbf000000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== mtd ==&lt;br /&gt;
&amp;lt;pre&amp;gt;~ # cat /proc/mtd &lt;br /&gt;
dev:    size   erasesize  name&lt;br /&gt;
mtd0: 08000000 00020000 &amp;quot;NAND 128MiB 3,3V 8-bit&amp;quot;&lt;br /&gt;
mtd1: 00040000 00020000 &amp;quot;stage1&amp;quot;&lt;br /&gt;
mtd2: 00380000 00020000 &amp;quot;uboot&amp;quot;&lt;br /&gt;
mtd3: 00080000 00020000 &amp;quot;uboot_env&amp;quot;&lt;br /&gt;
mtd4: 00a00000 00020000 &amp;quot;kernel&amp;quot;&lt;br /&gt;
mtd5: 00a00000 00020000 &amp;quot;etc&amp;quot;&lt;br /&gt;
mtd6: 00a00000 00020000 &amp;quot;info&amp;quot;&lt;br /&gt;
mtd7: 05dc0000 00020000 &amp;quot;sysdisk&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weitere Details dazu: http://www.mikrocontroller.net/topic/240238?goto=2471725#2471733&lt;br /&gt;
&lt;br /&gt;
== Speicherinformationen ==&lt;br /&gt;
&lt;br /&gt;
=== mount-Punkte ===&lt;br /&gt;
&amp;lt;pre&amp;gt;~ # mount&lt;br /&gt;
rootfs on / type rootfs (rw)&lt;br /&gt;
/proc on /proc type proc (rw,relatime)&lt;br /&gt;
/sys on /sys type sysfs (rw,relatime)&lt;br /&gt;
none on /proc/bus/usb type usbfs (rw,relatime)&lt;br /&gt;
devpts on /dev/pts type devpts (rw,relatime,mode=600)&lt;br /&gt;
/dev/mtdblock6 on /zyxel/mnt/info type yaffs2 (ro,relatime)&lt;br /&gt;
/dev/mtdblock7 on /zyxel/mnt/sysdisk type yaffs2 (ro,relatime)&lt;br /&gt;
/dev/loop0 on /ram_bin type ext2 (ro,relatime,errors=continue)&lt;br /&gt;
/dev/loop0 on /usr type ext2 (ro,relatime,errors=continue)&lt;br /&gt;
/dev/loop0 on /lib/security type ext2 (ro,relatime,errors=continue)&lt;br /&gt;
/dev/loop0 on /lib/modules type ext2 (ro,relatime,errors=continue)&lt;br /&gt;
/dev/ram0 on /tmp/tmpfs type tmpfs (rw,relatime,size=5120k)&lt;br /&gt;
/dev/ram0 on /usr/local/etc type tmpfs (rw,relatime,size=5120k)&lt;br /&gt;
/dev/ram0 on /usr/local/var type tmpfs (rw,relatime,size=5120k)&lt;br /&gt;
/dev/mtdblock5 on /etc/zyxel type yaffs2 (rw,relatime)&lt;br /&gt;
/dev/md4 on /i-data/6764ac2f type xfs (rw,relatime,nouuid,attr2,nobarrier,usrquota)&lt;br /&gt;
/dev/md4 on /usr/local/zy-pkgs type xfs (rw,relatime,nouuid,attr2,nobarrier,usrquota)&lt;br /&gt;
/dev/md4 on /etc/zyxel/zy-pkgs type xfs (rw,relatime,nouuid,attr2,nobarrier,usrquota)&lt;br /&gt;
/dev/md4 on /usr/local/apache/htdocs/adv,/pkg type xfs (rw,relatime,nouuid,attr2,nobarrier,usrquota)&lt;br /&gt;
/dev/md4 on /usr/local/apache/web_framework/data/cache type xfs (rw,relatime,nouuid,attr2,nobarrier,usrquota)&lt;br /&gt;
/dev/mtdblock5 on /usr/local/apache/web_framework/data/config type yaffs2 (rw,relatime)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Freier Plattenplatz ===&lt;br /&gt;
Ursprungszustand:&lt;br /&gt;
&amp;lt;pre&amp;gt;~ # df -h&lt;br /&gt;
Filesystem                Size      Used Available Use% Mounted on&lt;br /&gt;
/dev/mtdblock6           10.0M    804.0K      9.2M   8% /zyxel/mnt/info&lt;br /&gt;
/dev/mtdblock7           93.8M     86.8M      7.0M  93% /zyxel/mnt/sysdisk&lt;br /&gt;
/dev/loop0               83.3M     75.5M      7.8M  91% /ram_bin&lt;br /&gt;
/dev/loop0               83.3M     75.5M      7.8M  91% /usr&lt;br /&gt;
/dev/loop0               83.3M     75.5M      7.8M  91% /lib/security&lt;br /&gt;
/dev/loop0               83.3M     75.5M      7.8M  91% /lib/modules&lt;br /&gt;
/dev/ram0                 5.0M      4.0K      5.0M   0% /tmp/tmpfs&lt;br /&gt;
/dev/ram0                 5.0M      4.0K      5.0M   0% /usr/local/etc&lt;br /&gt;
/dev/ram0                 5.0M      4.0K      5.0M   0% /usr/local/var&lt;br /&gt;
/dev/mtdblock5           10.0M      1.4M      8.6M  14% /etc/zyxel&lt;br /&gt;
/dev/md4                  1.4T    519.0M      1.4T   0% /i-data/6764ac2f&lt;br /&gt;
/dev/md4                  1.4T    519.0M      1.4T   0% /usr/local/zy-pkgs&lt;br /&gt;
/dev/md4                  1.4T    519.0M      1.4T   0% /etc/zyxel/zy-pkgs&lt;br /&gt;
/dev/md4                  1.4T    519.0M      1.4T   0% /usr/local/apache/htdocs/adv,/pkg&lt;br /&gt;
/dev/md4                  1.4T    519.0M      1.4T   0% /usr/local/apache/web_framework/data/cache&lt;br /&gt;
/dev/mtdblock5           10.0M      1.4M      8.6M  14% /usr/local/apache/web_framework/data/config&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== hdparm ===&lt;br /&gt;
hdparm (siehe http://www.mikrocontroller.net/topic/240238?page=2#2453618 ):&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
Configuration:&lt;br /&gt;
        Logical         max     current&lt;br /&gt;
        cylinders       16383   16383&lt;br /&gt;
        heads           16      16&lt;br /&gt;
        sectors/track   63      63&lt;br /&gt;
        --&lt;br /&gt;
        CHS current addressable sectors:   16514064&lt;br /&gt;
        LBA    user addressable sectors:  268435455&lt;br /&gt;
        LBA48  user addressable sectors: 2930277168&lt;br /&gt;
        Logical  Sector size:                   512 bytes (*)&lt;br /&gt;
        Physical Sector size:                  4096 bytes (*)&lt;br /&gt;
        Logical Sector-0 offset:                  0 bytes&lt;br /&gt;
        device size with M = 1024*1024:     1430799 MBytes&lt;br /&gt;
        device size with M = 1000*1000:     1500301 MBytes (1500 GB)&lt;br /&gt;
        cache/buffer size  = unknown&lt;br /&gt;
        Nominal Media Rotation Rate: 5900&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== fdisk ===&lt;br /&gt;
&amp;lt;pre&amp;gt;/ # fdisk /dev/sda -l&lt;br /&gt;
&lt;br /&gt;
Disk /dev/sda: 1500.3 GB, 1500301910016 bytes&lt;br /&gt;
255 heads, 63 sectors/track, 182401 cylinders&lt;br /&gt;
Units = cylinders of 16065 * 512 = 8225280 bytes&lt;br /&gt;
&lt;br /&gt;
   Device Boot      Start         End      Blocks   Id  System&lt;br /&gt;
/dev/sda1               1          64      514048+  83  Linux&lt;br /&gt;
/dev/sda2              65      182401  1464621952+   9  AIX bootable&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
~ # fdisk -lu /dev/sda&lt;br /&gt;
&lt;br /&gt;
Disk /dev/sda: 2000.3 GB, 2000398934016 bytes&lt;br /&gt;
255 heads, 63 sectors/track, 243201 cylinders, total 3907029168 sectors&lt;br /&gt;
Units = sectors of 1 * 512 = 512 bytes&lt;br /&gt;
&lt;br /&gt;
   Device Boot      Start         End      Blocks   Id  System&lt;br /&gt;
/dev/sda1              63     1028159      514048+  83  Linux&lt;br /&gt;
/dev/sda2         1028160  3907024064  1952997952+   9  AIX bootable&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== uBoot ==&lt;br /&gt;
&lt;br /&gt;
=== uBoot help ===&lt;br /&gt;
&amp;lt;pre&amp;gt;$ help&lt;br /&gt;
?       - alias for &#039;help&#039;&lt;br /&gt;
base    - print or set address offset&lt;br /&gt;
bdinfo  - print Board Info structure&lt;br /&gt;
bootm   - boot application image from memory&lt;br /&gt;
bootp   - boot image via network using BootP/TFTP protocol&lt;br /&gt;
cmp     - memory compare&lt;br /&gt;
cp      - memory copy&lt;br /&gt;
crc32   - checksum calculation&lt;br /&gt;
echo    - echo args to console&lt;br /&gt;
exit    - exit script&lt;br /&gt;
go      - start application at address &#039;addr&#039;&lt;br /&gt;
help    - print online help&lt;br /&gt;
iminfo  - print header information for application image&lt;br /&gt;
ledfail - Extinguish (0) or light (1) failure LED&lt;br /&gt;
loop    - infinite loop on address range&lt;br /&gt;
md      - memory display&lt;br /&gt;
mm      - memory modify (auto-incrementing)&lt;br /&gt;
mtest   - simple RAM test&lt;br /&gt;
mw      - memory write (fill)&lt;br /&gt;
nand    - NAND sub-system&lt;br /&gt;
nboot   - boot from NAND device&lt;br /&gt;
nm      - memory modify (constant address)&lt;br /&gt;
nwboot          - NAND Write boot information&lt;br /&gt;
ping    - send ICMP ECHO_REQUEST to network host&lt;br /&gt;
printenv- print environment variables&lt;br /&gt;
rarpboot- boot image via network using RARP/TFTP protocol&lt;br /&gt;
reset   - Perform RESET of the CPU&lt;br /&gt;
run     - run commands in an environment variable&lt;br /&gt;
saveenv - save environment variables to persistent storage&lt;br /&gt;
setenv  - set environment variables&lt;br /&gt;
test    - minimal test like /bin/sh&lt;br /&gt;
tftpboot- boot image via network using TFTP protocol&lt;br /&gt;
version - print monitor version&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== uBoot-boot-Ausgaben ===&lt;br /&gt;
&lt;br /&gt;
Ausgaben über UART (mehr Info dazu auf [[P89626/UART]]), bis Ausgaben per dmesg einsehbar sind:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Stage-1 Bootloader Tue Aug  9 16:44:00 CST 2011&lt;br /&gt;
Attempting to set PLLA to 750MHz ...&lt;br /&gt;
  plla_ctrl0 : 0x0000000A&lt;br /&gt;
  plla_ctrl1 : 0x000F0000&lt;br /&gt;
  plla_ctrl2 : 0x001D01A0&lt;br /&gt;
  plla_ctrl3 : 0x00000017&lt;br /&gt;
PLLA Set&lt;br /&gt;
&lt;br /&gt;
Setup memory, testing&lt;br /&gt;
Reading NAND, Image 0&lt;br /&gt;
  Hdr len: 0x0001A94C&lt;br /&gt;
  Hdr CRC: 0xF0019DAC&lt;br /&gt;
 OK&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
U-Boot 1.1.2 (Jun 24 2011 - 09:41:57)&lt;br /&gt;
&lt;br /&gt;
U-Boot code: 60D00000 -&amp;gt; 60D1A94C  BSS: -&amp;gt; 60D1F004&lt;br /&gt;
RAM Configuration:&lt;br /&gt;
        Bank #0: 60000000 128 MB&lt;br /&gt;
SRAM Configuration:&lt;br /&gt;
        64KB at 0x50000000&lt;br /&gt;
NAND:128 MiB&lt;br /&gt;
In:    serial&lt;br /&gt;
Out:   serial&lt;br /&gt;
Err:   serial&lt;br /&gt;
Setting Linux mem= boot arg value&lt;br /&gt;
Hit any key to stop autoboot:  0 &lt;br /&gt;
&lt;br /&gt;
Loading from device 0: 128MiB 3,3V 8-bit (offset 0x440000)&lt;br /&gt;
   Image Name:   Linux-2.6.31.14_SMP_820&lt;br /&gt;
   Image Type:   ARM Linux Kernel Image (uncompressed)&lt;br /&gt;
   Data Size:    5241420 Bytes =  5 MB&lt;br /&gt;
   Load Address: 60008000&lt;br /&gt;
   Entry Point:  60008000&lt;br /&gt;
## Booting image at 61000000 ...&lt;br /&gt;
   Image Name:   Linux-2.6.31.14_SMP_820&lt;br /&gt;
   Image Type:   ARM Linux Kernel Image (uncompressed)&lt;br /&gt;
   Data Size:    5241420 Bytes =  5 MB&lt;br /&gt;
   Load Address: 60008000&lt;br /&gt;
   Entry Point:  60008000&lt;br /&gt;
   Verifying Checksum ... OK&lt;br /&gt;
OK&lt;br /&gt;
&lt;br /&gt;
Starting kernel ...&lt;br /&gt;
&lt;br /&gt;
Uncompressing Linux... .......................... ... done, booting the kernel.&lt;br /&gt;
Linux version 2.6.31.14_SMP_820 (root@Neo) (gcc version 4.3.2 (crosstool-NG-1.8.0) ) #2 SMP Wed Oct 5 21:54:14 CST 2011&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== dmesg ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
~ # dmesg&lt;br /&gt;
Linux version 2.6.31.14_SMP_820 (root@Neo) (gcc version 4.3.2 (crosstool-NG-1.8.0) ) #2 SMP Wed Oct 5 21:54:14 CST 2011&lt;br /&gt;
CPU: ARMv6-compatible processor [410fb025] revision 5 (ARMv7), cr=00c5387f&lt;br /&gt;
CPU: VIPT nonaliasing data cache, VIPT nonaliasing instruction cache&lt;br /&gt;
Machine: Oxsemi NAS&lt;br /&gt;
1 memory region&lt;br /&gt;
Ignoring unrecognised tag 0x00000000&lt;br /&gt;
Memory policy: ECC disabled, Data cache writealloc&lt;br /&gt;
On node 0 totalpages: 32768&lt;br /&gt;
free_area_init_node: node 0, pgdat c07be3a0, node_mem_map c07e6000&lt;br /&gt;
  Normal zone: 256 pages used for memmap&lt;br /&gt;
  Normal zone: 0 pages reserved&lt;br /&gt;
  Normal zone: 32512 pages, LIFO batch:7&lt;br /&gt;
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 32512&lt;br /&gt;
Kernel command line: console=ttyS0,115200 elevator=cfq mac_adr=0x00,0x30,0xe0,0x00,0x00,0x01 mem=128M poweroutage=yes&lt;br /&gt;
PID hash table entries: 512 (order: 9, 2048 bytes)&lt;br /&gt;
Dentry cache hash table entries: 16384 (order: 4, 65536 bytes)&lt;br /&gt;
Inode-cache hash table entries: 8192 (order: 3, 32768 bytes)&lt;br /&gt;
Memory: 128MB = 128MB total&lt;br /&gt;
Memory: 121656KB available (5340K code, 338K data, 2264K init, 0K highmem)&lt;br /&gt;
Hierarchical RCU implementation.&lt;br /&gt;
NR_IRQS:96&lt;br /&gt;
OX820_RPS_init_irq: interrupts 64 to 96&lt;br /&gt;
ox820_clocksource_init() Timer 2 running at 390625 Hz&lt;br /&gt;
Console: colour dummy device 80x30&lt;br /&gt;
console [ttyS0] enabled&lt;br /&gt;
Calibrating delay loop... 299.00 BogoMIPS (lpj=1495040)&lt;br /&gt;
Mount-cache hash table entries: 512&lt;br /&gt;
CPU: Testing write buffer coherency: ok&lt;br /&gt;
Calibrating local timer... 374.49MHz.&lt;br /&gt;
Brought up 1 CPUs&lt;br /&gt;
SMP: Total of 1 processors activated (299.00 BogoMIPS).&lt;br /&gt;
NET: Registered protocol family 16&lt;br /&gt;
Number of DMA channels = 4, version = 4&lt;br /&gt;
Allocating 303 SRAM generic DMA descriptors&lt;br /&gt;
bio: create slab &amp;lt;bio-0&amp;gt; at 0&lt;br /&gt;
SCSI subsystem initialized&lt;br /&gt;
libata version 3.00 loaded.&lt;br /&gt;
usbcore: registered new interface driver usbfs&lt;br /&gt;
usbcore: registered new interface driver hub&lt;br /&gt;
usbcore: registered new device driver usb&lt;br /&gt;
NET: Registered protocol family 2&lt;br /&gt;
IP route cache hash table entries: 1024 (order: 0, 4096 bytes)&lt;br /&gt;
Switched to NOHz mode on CPU #0&lt;br /&gt;
TCP established hash table entries: 4096 (order: 3, 32768 bytes)&lt;br /&gt;
TCP bind hash table entries: 4096 (order: 3, 32768 bytes)&lt;br /&gt;
TCP: Hash tables configured (established 4096 bind 4096)&lt;br /&gt;
TCP reno registered&lt;br /&gt;
NET: Registered protocol family 1&lt;br /&gt;
Create fragment cache&lt;br /&gt;
MitraStar NAS GPIO driver/controller 1.00&lt;br /&gt;
Initialize LEDs&lt;br /&gt;
 o SYS LED&lt;br /&gt;
 o COPY LED&lt;br /&gt;
 o Quota 4 LED&lt;br /&gt;
Initialize buzzer&lt;br /&gt;
Initialize buttons&lt;br /&gt;
 o Copy Button&lt;br /&gt;
 o Reset Button&lt;br /&gt;
nas_gpio: Register a char device 254:0&lt;br /&gt;
audit: initializing netlink socket (disabled)&lt;br /&gt;
type=2000 audit(0.880:1): initialized&lt;br /&gt;
VFS: Disk quotas dquot_6.5.2&lt;br /&gt;
Dquot-cache hash table entries: 1024 (order 0, 4096 bytes)&lt;br /&gt;
Installing knfsd (copyright (C) 1996 okir@monad.swb.de).&lt;br /&gt;
fuse init (API version 7.12)&lt;br /&gt;
SGI XFS with security attributes, large block/inode numbers, no debug enabled&lt;br /&gt;
SGI XFS Quota Management subsystem&lt;br /&gt;
yaffs built Oct  5 2011 21:42:41 Installing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
YAFFS-WARNING CONFIG_YAFFS_ALWAYS_CHECK_CHUNK_ERASED selected.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
msgmni has been set to 237&lt;br /&gt;
alg: No test for stdrng (krng)&lt;br /&gt;
io scheduler noop registered&lt;br /&gt;
io scheduler anticipatory registered&lt;br /&gt;
io scheduler deadline registered&lt;br /&gt;
io scheduler cfq registered (default)&lt;br /&gt;
Serial: 8250/16550 driver, 2 ports, IRQ sharing disabled&lt;br /&gt;
serial8250: ttyS0 at MMIO 0x44200000 (irq = 55) is a 16550A&lt;br /&gt;
brd: module loaded&lt;br /&gt;
loop: module loaded&lt;br /&gt;
ox820sata: OX820 sata core.&lt;br /&gt;
scsi0 : oxnassata&lt;br /&gt;
scsi1 : oxnassata&lt;br /&gt;
ata1: SATA max UDMA/133 irq 50&lt;br /&gt;
ata2: SATA max UDMA/133 irq 50&lt;br /&gt;
ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300)&lt;br /&gt;
ox820sata_qc_issue: Core busy, returning an error.&lt;br /&gt;
ata1.00: failed to IDENTIFY (I/O error, err_mask=0x100)&lt;br /&gt;
ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300)&lt;br /&gt;
ox820sata_qc_issue: Core busy, returning an error.&lt;br /&gt;
ata1.00: failed to IDENTIFY (I/O error, err_mask=0x100)&lt;br /&gt;
ata1: limiting SATA link speed to 1.5 Gbps&lt;br /&gt;
ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 310)&lt;br /&gt;
ox820sata_qc_issue: Core busy, returning an error.&lt;br /&gt;
ata1.00: failed to IDENTIFY (I/O error, err_mask=0x100)&lt;br /&gt;
ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 310)&lt;br /&gt;
ata1: exception Emask 0x10 SAct 0x0 SErr 0x0 action 0x9 t4&lt;br /&gt;
ata1: hard resetting link&lt;br /&gt;
ata1: SATA link up 1.5 Gbps (SStatus 113 SControl 300)&lt;br /&gt;
ata1.00: ATA-8: ST1500DL003-9VT16L, CC4A, max UDMA/133&lt;br /&gt;
ata1.00: 2930277168 sectors, multi 0: LBA48 NCQ (depth 0/32)&lt;br /&gt;
ata1.00: configured for UDMA/133&lt;br /&gt;
ata1: exception Emask 0x10 SAct 0x0 SErr 0x0 action 0x9 t3&lt;br /&gt;
ata1.00: configured for UDMA/133&lt;br /&gt;
ata1: EH complete&lt;br /&gt;
ata2: SATA link down (SStatus 0 SControl 300)&lt;br /&gt;
scsi 0:0:0:0: Direct-Access     ATA      ST1500DL003-9VT1 CC4A PQ: 0 ANSI: 5&lt;br /&gt;
sd 0:0:0:0: [sda] 2930277168 512-byte logical blocks: (1.50 TB/1.36 TiB)&lt;br /&gt;
sd 0:0:0:0: [sda] 4096-byte physical blocks&lt;br /&gt;
sd 0:0:0:0: [sda] Write Protect is off&lt;br /&gt;
sd 0:0:0:0: [sda] Mode Sense: 00 3a 00 00&lt;br /&gt;
sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn&#039;t support DPO or FUA&lt;br /&gt;
 sda:&lt;br /&gt;
sd 0:0:0:0: Attached scsi generic sg0 type 0&lt;br /&gt;
 sda1 sda2&lt;br /&gt;
PPP generic driver version 2.4.2&lt;br /&gt;
PPP Deflate Compression module registered&lt;br /&gt;
PPP BSD Compression module registered&lt;br /&gt;
sd 0:0:0:0: [sda] Attached SCSI disk&lt;br /&gt;
PPP MPPE Compression module registered&lt;br /&gt;
NET: Registered protocol family 24&lt;br /&gt;
PPPoL2TP kernel driver, V1.0&lt;br /&gt;
NAND device: Manufacturer ID: 0xad, Chip ID: 0xf1 (Hynix NAND 128MiB 3,3V 8-bit)&lt;br /&gt;
Scanning device for bad blocks&lt;br /&gt;
Bad eraseblock 17 at 0x000000220000&lt;br /&gt;
Bad eraseblock 282 at 0x000002340000&lt;br /&gt;
Creating 7 MTD partitions on &amp;quot;NAND 128MiB 3,3V 8-bit&amp;quot;:&lt;br /&gt;
0x000000000000-0x000000040000 : &amp;quot;stage1&amp;quot;&lt;br /&gt;
0x000000040000-0x0000003c0000 : &amp;quot;uboot&amp;quot;&lt;br /&gt;
0x0000003c0000-0x000000440000 : &amp;quot;uboot_env&amp;quot;&lt;br /&gt;
0x000000440000-0x000000e40000 : &amp;quot;kernel&amp;quot;&lt;br /&gt;
0x000000e40000-0x000001840000 : &amp;quot;etc&amp;quot;&lt;br /&gt;
0x000001840000-0x000002240000 : &amp;quot;info&amp;quot;&lt;br /&gt;
0x000002240000-0x000008000000 : &amp;quot;sysdisk&amp;quot;&lt;br /&gt;
ehci_hcd: USB 2.0 &#039;Enhanced&#039; Host Controller (EHCI) Driver&lt;br /&gt;
Start USB clocks&lt;br /&gt;
oxnas-ehci oxnas-ehci.0: OXNAS EHCI Host Controller&lt;br /&gt;
oxnas-ehci oxnas-ehci.0: new USB bus registered, assigned bus number 1&lt;br /&gt;
oxnas-ehci oxnas-ehci.0: irq 39, io mem 0x00000000&lt;br /&gt;
oxnas-ehci oxnas-ehci.0: USB 0.0 started, EHCI 1.00&lt;br /&gt;
usb usb1: configuration #1 chosen from 1 choice&lt;br /&gt;
hub 1-0:1.0: USB hub found&lt;br /&gt;
hub 1-0:1.0: 2 ports detected&lt;br /&gt;
usbcore: registered new interface driver usblp&lt;br /&gt;
Initializing USB Mass Storage driver...&lt;br /&gt;
usbcore: registered new interface driver usb-storage&lt;br /&gt;
USB Mass Storage support registered.&lt;br /&gt;
usbcore: registered new interface driver ums-datafab&lt;br /&gt;
usbcore: registered new interface driver ums-freecom&lt;br /&gt;
usbcore: registered new interface driver ums-isd200&lt;br /&gt;
usbcore: registered new interface driver ums-jumpshot&lt;br /&gt;
usbcore: registered new interface driver ums-sddr09&lt;br /&gt;
usbcore: registered new interface driver ums-sddr55&lt;br /&gt;
usbcore: registered new interface driver ums-usbat&lt;br /&gt;
mice: PS/2 mouse device common for all mice&lt;br /&gt;
md: linear personality registered for level -1&lt;br /&gt;
md: raid0 personality registered for level 0&lt;br /&gt;
md: raid1 personality registered for level 1&lt;br /&gt;
usbcore: registered new interface driver hiddev&lt;br /&gt;
usbcore: registered new interface driver usbhid&lt;br /&gt;
usbhid: v2.6:USB HID core driver&lt;br /&gt;
TCP cubic registered&lt;br /&gt;
NET: Registered protocol family 10&lt;br /&gt;
NET: Registered protocol family 17&lt;br /&gt;
RPC: Registered udp transport module.&lt;br /&gt;
RPC: Registered tcp transport module.&lt;br /&gt;
registered taskstats version 1&lt;br /&gt;
Freeing init memory: 2264K&lt;br /&gt;
Probing for Synopsis GMAC, unit 0&lt;br /&gt;
eth0: Tuning GMAC 0 RGMII timings&lt;br /&gt;
eth0: PHY is Realtek RTL8211E, type 0x001cc915&lt;br /&gt;
eth0: Disable EEE (Energy Efficient Ethernet 802.3az)&lt;br /&gt;
eth0: Set SSC&lt;br /&gt;
eth0: GMAC ver = 53, vendor ver = 18 at 0xed400000, IRQ 40&lt;br /&gt;
eth0: Found PHY at address 7, type 0x001cc915 -&amp;gt; 10/100/1000&lt;br /&gt;
eth0: Ethernet addr: 00:30:e0:00:00:00&lt;br /&gt;
probe() eth0: Leon x2 clock&lt;br /&gt;
hw_set_mac_address() Storing port0 mac_adr in global array&lt;br /&gt;
CoPro offload is active on egiga0&lt;br /&gt;
Alloc&#039;ing ARM descs 8192 bytes&lt;br /&gt;
Alloc&#039;ing CoPro parameters 40 bytes&lt;br /&gt;
gmac gmac.0: firmware: requesting gmac_copro_firmware&lt;br /&gt;
CoPro: Programming start address as 0xd000e000&lt;br /&gt;
egiga0: Resetting GMAC&lt;br /&gt;
egiga0: GMAC reset complete&lt;br /&gt;
workaround step1&lt;br /&gt;
workaround step2&lt;br /&gt;
workaround finish&lt;br /&gt;
hw_set_mac_address() Storing port0 mac_adr in global array&lt;br /&gt;
egiga0: Setting Rx flow control thresholds for LAN port&lt;br /&gt;
CoPro available SRAM end 0x00000001&lt;br /&gt;
Copro offload started&lt;br /&gt;
Waiting for auto-negotiation to complete&lt;br /&gt;
Waiting for auto-negotiation to complete&lt;br /&gt;
egiga0: PHY is Realtek RTL8211E, type 0x001cc915&lt;br /&gt;
egiga0: Disable EEE (Energy Efficient Ethernet 802.3az)&lt;br /&gt;
egiga0: Set SSC&lt;br /&gt;
egiga0: link down&lt;br /&gt;
egiga0: link up, 100Mbps, full-duplex, using pause, lpa 0x45E1&lt;br /&gt;
yaffs: dev is 32505862 name is &amp;quot;mtdblock6&amp;quot; ro&lt;br /&gt;
yaffs: passed flags &amp;quot;&amp;quot;&lt;br /&gt;
yaffs: Attempting MTD mount of 31.6,&amp;quot;mtdblock6&amp;quot;&lt;br /&gt;
uncorrectable error :&lt;br /&gt;
yaffs_read_super: isCheckpointed 0&lt;br /&gt;
yaffs: dev is 32505863 name is &amp;quot;mtdblock7&amp;quot; ro&lt;br /&gt;
yaffs: passed flags &amp;quot;&amp;quot;&lt;br /&gt;
yaffs: Attempting MTD mount of 31.7,&amp;quot;mtdblock7&amp;quot;&lt;br /&gt;
block 9 is bad&lt;br /&gt;
yaffs_read_super: isCheckpointed 0&lt;br /&gt;
REISERFS warning (device sda1): super-6502 reiserfs_getopt: unknown mount option &amp;quot;iocharset=utf8&amp;quot;&lt;br /&gt;
FAT: utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!&lt;br /&gt;
hfs: unable to parse mount options&lt;br /&gt;
udf: bad mount option &amp;quot;shortname=mixed&amp;quot; or missing value&lt;br /&gt;
XFS: unknown mount option [iocharset].&lt;br /&gt;
yaffs: dev is 8388609 name is &amp;quot;sda1&amp;quot; ro&lt;br /&gt;
yaffs: passed flags &amp;quot;iocharset=utf8,shortname=mixed&amp;quot;&lt;br /&gt;
yaffs: Bad mount option &amp;quot;iocharset=utf8&amp;quot;&lt;br /&gt;
yaffs: dev is 8388609 name is &amp;quot;sda1&amp;quot; ro&lt;br /&gt;
yaffs: passed flags &amp;quot;iocharset=utf8,shortname=mixed&amp;quot;&lt;br /&gt;
yaffs: Bad mount option &amp;quot;iocharset=utf8&amp;quot;&lt;br /&gt;
REISERFS warning (device sda1): super-6502 reiserfs_getopt: unknown mount option &amp;quot;iocharset=utf8&amp;quot;&lt;br /&gt;
FAT: utf8 is not a recommended IO charset for FAT filesystems, filesystem will be case sensitive!&lt;br /&gt;
hfs: unable to parse mount options&lt;br /&gt;
udf: bad mount option &amp;quot;shortname=mixed&amp;quot; or missing value&lt;br /&gt;
XFS: unknown mount option [iocharset].&lt;br /&gt;
yaffs: dev is 8388609 name is &amp;quot;sda1&amp;quot; ro&lt;br /&gt;
yaffs: passed flags &amp;quot;iocharset=utf8,shortname=mixed&amp;quot;&lt;br /&gt;
yaffs: Bad mount option &amp;quot;iocharset=utf8&amp;quot;&lt;br /&gt;
yaffs: dev is 8388609 name is &amp;quot;sda1&amp;quot; ro&lt;br /&gt;
yaffs: passed flags &amp;quot;iocharset=utf8,shortname=mixed&amp;quot;&lt;br /&gt;
yaffs: Bad mount option &amp;quot;iocharset=utf8&amp;quot;&lt;br /&gt;
yaffs: dev is 32505861 name is &amp;quot;mtdblock5&amp;quot; rw&lt;br /&gt;
yaffs: passed flags &amp;quot;&amp;quot;&lt;br /&gt;
yaffs: Attempting MTD mount of 31.5,&amp;quot;mtdblock5&amp;quot;&lt;br /&gt;
yaffs: restored from checkpoint&lt;br /&gt;
yaffs_read_super: isCheckpointed 1&lt;br /&gt;
NTFS driver 2.1.29 [Flags: R/O MODULE].&lt;br /&gt;
egiga0: no IPv6 routers present&lt;br /&gt;
md: md4 stopped.&lt;br /&gt;
md: bind&amp;lt;sda2&amp;gt;&lt;br /&gt;
raid1: raid set md4 active with 1 out of 2 mirrors&lt;br /&gt;
md4 using HW RAID-1&lt;br /&gt;
HW-RAID1 sda2, is read/write.&lt;br /&gt;
HW-RAID1 using disk sda2 on port 0 mirror 0&lt;br /&gt;
md4: detected capacity change from 0 to 1499772813312&lt;br /&gt;
 md4: unknown partition table&lt;br /&gt;
Filesystem &amp;quot;md4&amp;quot;: Disabling barriers, trial barrier write failed&lt;br /&gt;
XFS mounting filesystem md4&lt;br /&gt;
Starting XFS recovery on filesystem: md4 (logdev: internal)&lt;br /&gt;
Ending XFS recovery on filesystem: md4 (logdev: internal)&lt;br /&gt;
Adding 524280k swap on /i-data/.system/swap_ul6545p.  Priority:-1 extents:1 across:524280k&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Software =&lt;br /&gt;
&lt;br /&gt;
Installiert ist die Firmware &#039;&#039;&#039;1.00(UZD.2)&#039;&#039;&#039;. Sie basiert offensichtlich auf der Firmware vom &#039;&#039;&#039;Zyxel NSA-210&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;~ # cat /zyxel/mnt/info/fwversion &lt;br /&gt;
1.00(UZD.2)&lt;br /&gt;
~ # cat /zyxel/mnt/info/modelid &lt;br /&gt;
AB03&lt;br /&gt;
~ # cat /zyxel/mnt/info/revision &lt;br /&gt;
32694&lt;br /&gt;
~ # zysh --version&lt;br /&gt;
zysh: version 2.0.0&lt;br /&gt;
Build: 21:37:19 Oct  5 2011&lt;br /&gt;
# cat /etc/Zy_Private &lt;br /&gt;
52103jeenajevol8290i&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;modelid&#039;&#039; &#039;&#039;&#039;AB03&#039;&#039;&#039; steht für &#039;&#039;&#039;STG212&#039;&#039;&#039; (siehe /etc/init.d/rcS)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Linux nas-server 2.6.31.14_SMP_820 #2 SMP Wed Oct 5 21:54:14 CST 2011 armv6l GNU/Linux&lt;br /&gt;
* cat /proc/version: Linux version 2.6.31.14_SMP_820 (root@Neo) (gcc version 4.3.2 (crosstool-NG-1.8.0) ) #2 SMP Wed Oct 5 21:54:14 CST 2011&lt;br /&gt;
* BusyBox v1.17.2&lt;br /&gt;
&lt;br /&gt;
== Paketverwaltung ==&lt;br /&gt;
Pakete und Updates der Firmware werden von &#039;&#039;&#039;download.medion.de&#039;&#039;&#039; gezogen. Genauen Link zu Firmware erhält man mit &#039;&#039;&#039;cat /etc/firmware_src_url&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Pakete werden per &#039;&#039;&#039;ipkg v0.99.163&#039;&#039;&#039; (/usr/bin/ipkg-cl) installiert und landen auf der Festplatte unter &#039;&#039;&#039;/i-data/md0/admin/package/&#039;&#039;&#039; Dies ist anscheinend in der Datei &#039;&#039;&#039;/etc/zyxel/zy-pkg.conf&#039;&#039;&#039; festgelegt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
~ # ipkg-cl print_architecture&lt;br /&gt;
arch all 1&lt;br /&gt;
arch noarch 1&lt;br /&gt;
arch arm 10&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Konfiguration ==&lt;br /&gt;
&lt;br /&gt;
Die meiste Konfigurationen (u.a. Name des NAS, existierende User und Freigaben) findet hier wieder:&lt;br /&gt;
* &#039;&#039;&#039;/etc/zyxel/conf/startup-config.conf&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== environment ==&lt;br /&gt;
&amp;lt;pre&amp;gt;/ # env&lt;br /&gt;
USER=root&lt;br /&gt;
LD_LIBRARY_PATH=/usr/local/zy-pkgs/lib&lt;br /&gt;
OLDPWD=/usr/local/apache/cgi-bin&lt;br /&gt;
HOME=/root&lt;br /&gt;
LOGNAME=root&lt;br /&gt;
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/zyxel/sbin:/usr/local/zy-pkgs/bin:/zyxel/htp&lt;br /&gt;
SHELL=/bin/sh&lt;br /&gt;
PWD=/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== uboot env ==&lt;br /&gt;
&amp;lt;pre&amp;gt;/ # fw_printenv &lt;br /&gt;
bootargs= console=ttyS0,115200 elevator=cfq mac_adr=0x00,0x30,0xe0,0x00,0x00,0x01&lt;br /&gt;
bootcmd=run boot_nand&lt;br /&gt;
bootdelay=2&lt;br /&gt;
baudrate=115200&lt;br /&gt;
ipaddr=192.168.50.100&lt;br /&gt;
serverip=192.168.50.59&lt;br /&gt;
autoload=n&lt;br /&gt;
netmask=255.255.0.0&lt;br /&gt;
bootfile=&amp;quot;uImage&amp;quot;&lt;br /&gt;
load_nand=nboot 61000000 0 440000&lt;br /&gt;
boot=bootm 61000000&lt;br /&gt;
boot_nand=run load_nand boot&lt;br /&gt;
MODEL_ID=AB03&lt;br /&gt;
PRODUCT_NAME=STG-212&lt;br /&gt;
VENDOR_NAME=MitraStar Technology Corp.&lt;br /&gt;
ethaddr=00:11:41:xx:xx:xx&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== interessante Dateien/Pfade ==&lt;br /&gt;
&lt;br /&gt;
NAS Speicher:&lt;br /&gt;
* &#039;&#039;&#039;/i-data/md0/&#039;&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;/i-data/md0/public&#039;&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;/i-data/md0/photo&#039;&#039;&#039;&lt;br /&gt;
** &#039;&#039;&#039;/i-data/md0/music&#039;&#039;&#039;&lt;br /&gt;
** usw.&lt;br /&gt;
&lt;br /&gt;
Allgemeine Konfiguration:&lt;br /&gt;
* /etc/init.d/rcS - System-Start-Skript&lt;br /&gt;
* &#039;&#039;&#039;/usr/local/btn/&#039;&#039;&#039; Spezielle Steuerungs-Skripte&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Apache:&#039;&#039;&#039;&lt;br /&gt;
* /etc/service_conf/httpd.conf&lt;br /&gt;
* /etc/service_conf/httpd_zld.conf&lt;br /&gt;
* /etc/service_conf/httpd_special.conf&lt;br /&gt;
* /usr/local/apache/htdocs&lt;br /&gt;
* /usr/local/apache/cgi-bin&lt;br /&gt;
&lt;br /&gt;
= Aufspüren =&lt;br /&gt;
&lt;br /&gt;
Die Box bezieht sich vom vorhandenen DHCP Server eine IP. Meldet sich mit dem Namen &#039;&#039;&#039;nas-server&#039;&#039;&#039;. Somit sollte ein &#039;&#039;&#039;ping nas-server&#039;&#039;&#039; gehen und die IP ausspucken.&lt;br /&gt;
&lt;br /&gt;
Zum Aufspüren kann man auch nmap benutzten. z.B. das ganze Subnetz scannen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;~$ sudo nmap -e eth1 -sP 169.254.xxx.0/24&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Dienste =&lt;br /&gt;
&lt;br /&gt;
Auf der Box laufen einige Dienste im Ursprungszustand:&lt;br /&gt;
&amp;lt;pre&amp;gt;~$ nmap -sT nas-server&lt;br /&gt;
&lt;br /&gt;
PORT      STATE SERVICE&lt;br /&gt;
21/tcp   open  ftp&lt;br /&gt;
80/tcp   open  http&lt;br /&gt;
139/tcp  open  netbios-ssn&lt;br /&gt;
443/tcp  open  https&lt;br /&gt;
631/tcp  open  ipp&lt;br /&gt;
3689/tcp open  rendezvous&lt;br /&gt;
8082/tcp open  blackice-alerts&lt;br /&gt;
9001/tcp open  tor-orport&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dienste:&lt;br /&gt;
* Port 21 - &#039;&#039;&#039;pure-ftpd v1.0.21&#039;&#039;&#039;&lt;br /&gt;
* Port 80 und 8082 - &#039;&#039;&#039;Apache/2.2.9 (Unix) mod_ssl/2.2.9 OpenSSL/0.9.8o mod_wsgi/2.4 Python/2.6.2&#039;&#039;&#039;&lt;br /&gt;
* Port 139 - &#039;&#039;&#039;Samba v3.0.32&#039;&#039;&#039;&lt;br /&gt;
* Port 3689 - &#039;&#039;&#039;mt-daapd: 0.2.4.2&#039;&#039;&#039; &lt;br /&gt;
* Port 9001 - DLNA-Server &#039;&#039;&#039;Twonky Media 5.1.13&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
= Einfacher Web Server =&lt;br /&gt;
Html-Dateien, die man im Verzeichnis &amp;lt;pre&amp;gt;/usr/local/apache/htdocs/adv,/pkg&amp;lt;/pre&amp;gt; ablegt, können im Browser über &amp;lt;pre&amp;gt;http://nas-server/r32694,/adv,/pkg/&amp;lt;/pre&amp;gt; angezeigt werden. Geht auch secure mit https. Mit entsprechender Port-Freigabe kann man zumindest eine statische Website aufbauen.&lt;br /&gt;
&lt;br /&gt;
seit FW-Version 1.01 lautet der Link&lt;br /&gt;
http://nas-server/r34814,/adv,/pkg/&lt;br /&gt;
&lt;br /&gt;
Die Verzeichnisse unter &amp;lt;pre&amp;gt;/usr/local/apache&amp;lt;/pre&amp;gt; scheinen im nicht beschreibbaren Bereich zu liegen. &amp;lt;pre&amp;gt;/usr/local/apache/htdocs/adv,/pkg&amp;lt;/pre&amp;gt; ist  auf einen beschreibbaren Bereich gemappt.&lt;br /&gt;
&lt;br /&gt;
= Zugang =&lt;br /&gt;
&lt;br /&gt;
Wie bei vielen NAS läuft auch hier ein WebServer. Es gibt den Benutzer &#039;&#039;&#039;admin&#039;&#039;&#039; mit Passwort &#039;&#039;&#039;1234&#039;&#039;&#039;, mit dem man sich anmelden kann.&lt;br /&gt;
&lt;br /&gt;
== Telnet ==&lt;br /&gt;
&lt;br /&gt;
Telnet kann man mit dieser URL starten (wichtig ist, dass man sich vorher normal angemldet hat!):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;http://nas-server/r32694,/adv,/cgi-bin/remote_help-cgi?type=backdoor&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
bzw.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;http://192.168.xxx.yyy/r32694,/adv,/cgi-bin/remote_help-cgi?type=backdoor&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
seit FW-Version 1.01 lautet der Link&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;http://nas-server/r34814,/adv,/cgi-bin/remote_help-cgi?type=backdoor&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
bzw.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;http://192.168.xxx.yyy/r34814,/adv,/cgi-bin/remote_help-cgi?type=backdoor&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Für FW 1.01(UZD.2) lautet der Link: ...r36258...&lt;br /&gt;
&lt;br /&gt;
Per Telnet kann man sich mit &#039;&#039;&#039;root&#039;&#039;&#039; Passwort &#039;&#039;&#039;1234&#039;&#039;&#039; (bzw. das Passwort vom User &#039;&#039;&#039;admin&#039;&#039;&#039;) verbinden.&lt;br /&gt;
&lt;br /&gt;
Nach einem Reboot ist Telnet allerdings wieder aus!&lt;br /&gt;
&lt;br /&gt;
Für das Starten von Telnet sind diese Dateien zuständig:&lt;br /&gt;
* /usr/local/apache/cgi-bin/remote_help-cgi&lt;br /&gt;
* /usr/local/btn/open_back_door.sh&lt;br /&gt;
&lt;br /&gt;
=== Telnet-Zugang dauerhaft aktivieren ===&lt;br /&gt;
&lt;br /&gt;
Eine Möglichkeit, den Telnet-Zugang bei jedem Booten des NAS automatisch zu starten, ist, ein neues Start-Skript anzulegen, z.B. so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;echo &amp;quot;/usr/local/btn/open_back_door.sh&amp;quot; &amp;gt; /usr/local/zy-pkgs/etc/init.d/starttelnet.sh&lt;br /&gt;
chmod +x /usr/local/zy-pkgs/etc/init.d/starttelnet.sh&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Siehe: http://www.mikrocontroller.net/topic/240238?goto=2457264#2457390&lt;br /&gt;
&lt;br /&gt;
== SSH-Server aktivieren ==&lt;br /&gt;
&lt;br /&gt;
Es ist möglich, einen SSH-Server mit &amp;quot;dropbear&amp;quot; zu realisieren und direkt nach dem Booten zu starten. Siehe Beschreibung auf http://www.mikrocontroller.net/articles/P89626/dropbear&lt;br /&gt;
&lt;br /&gt;
= Dateien editieren =&lt;br /&gt;
&lt;br /&gt;
Auf der Box gibt es VI als Editor. Möchte man Dateien bequemer editieren, kann man dies über &#039;&#039;&#039;SMB&#039;&#039;&#039;, &#039;&#039;&#039;FTP&#039;&#039;&#039; oder &#039;&#039;&#039;NFS&#039;&#039;&#039; erledigen.&lt;br /&gt;
&lt;br /&gt;
Einige Konfigurationsdateien scheinen eh auf der Platte im versteckten Verzeichnis &#039;&#039;&#039;.system&#039;&#039;&#039; gespeichert zu sein (z.B. &#039;&#039;&#039;.system/zy-pkgs/etc/exports&#039;&#039;&#039;) Wenn man &#039;&#039;&#039;/i-data/6764ac2f/&#039;&#039;&#039; von außen erreichbar macht, kann man diese Dateien bequem editieren.&lt;br /&gt;
&lt;br /&gt;
Eine Lösung wäre es, Dateien temporär in einen Share kopieren und wieder zurück, z.B.:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /etc/exports /i-data/6764ac2f/admin/&amp;lt;/pre&amp;gt;&lt;br /&gt;
auf Client editieren und zurück:&lt;br /&gt;
&amp;lt;pre&amp;gt;cp /i-data/6764ac2f/admin/exports /etc/exports&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine andere Lösung wäre, via telnet im admin share mit ln -s ../.system/ einen softlink auf das schreibbare Systemverzeichnis zu setzen, dann kann man das verzeichnis aus dem Samba-Share direkt erreichen.&lt;br /&gt;
&lt;br /&gt;
= NFS =&lt;br /&gt;
&lt;br /&gt;
Einen NFS-Server kann man über die Web-Oberfläche unter Admin/Applications/Package nachinstallieren.&lt;br /&gt;
&lt;br /&gt;
Leider kann man über die Web-Oberfläche nur Exporte unterhalb von &#039;&#039;&#039;/i-data/6764ac2f/nfs/&#039;&#039;&#039; freigeben. Jedoch liegt die Datei &#039;&#039;&#039;/etc/exports&#039;&#039;&#039; im beschreibbaren Bereich. Somit kann man sie nach Belieben anpassen, ohne daß es beim Neustart &amp;quot;zurückgesetzt&amp;quot; wird.&lt;br /&gt;
&lt;br /&gt;
In der &#039;&#039;&#039;/etc/exports&#039;&#039;&#039; z.B. das eintragen:&lt;br /&gt;
&amp;lt;pre&amp;gt;/i-data/6764ac2f/ 192.168.1.0/24(rw,sync,no_subtree_check,wdelay,no_root_squash)&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mounten geht das z.B. so:&lt;br /&gt;
&amp;lt;pre&amp;gt;~$ sudo mkdir /media/nas-server&lt;br /&gt;
~$ sudo mount 192.168.xxx.yyy:/i-data/6764ac2f/ /media/nas-server&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(IP-Bereich natürlich anpassen)&lt;br /&gt;
&lt;br /&gt;
= Backup des Flashspeichers =&lt;br /&gt;
&lt;br /&gt;
Mit diesen Skripten kann man den Flash-Speicher sichern. Dazu die Skripte z.B. im admin-share speichern und per Telnet ausführen.&lt;br /&gt;
&lt;br /&gt;
Ruft man das Skript ein weiteres Mal auf, werden die MD5-Daten angezeigt.&lt;br /&gt;
&lt;br /&gt;
Welcher mtd-Teil was speichert, erfährt man durch ein &#039;&#039;&#039;cat /proc/mtd&#039;&#039;&#039; ([http://www.mikrocontroller.net/articles/P89626#mtd siehe oben])&lt;br /&gt;
&lt;br /&gt;
== raw dd ==&lt;br /&gt;
Sicherung mittels dd.&lt;br /&gt;
&lt;br /&gt;
Zu beachten ist:&lt;br /&gt;
&amp;lt;pre&amp;gt;To create an image of mtd0, you need to dump the nand without ecc. using&lt;br /&gt;
&amp;quot;dd if=/dev/mtd0 of=mtd0.DOESNOTWORK&amp;quot; will automatically do ecc for you&lt;br /&gt;
and will result in a corrupt image.&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
(Hinweis von http://jeff.doozan.com/debian/uboot/build_uboot.htm unter &amp;quot;Backup&lt;br /&gt;
/dev/mtd0&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
dest=/i-data/6764ac2f/admin&lt;br /&gt;
&lt;br /&gt;
for mtd in `cd /dev &amp;amp;&amp;amp; ls mtd?`&lt;br /&gt;
do&lt;br /&gt;
    echo &amp;quot;____________________________________________________________________&amp;quot;&lt;br /&gt;
    echo &amp;quot;Backup von ${mtd}&amp;quot;&lt;br /&gt;
    outfile=${dest}/${mtd}.img&lt;br /&gt;
    if [ -f ${outfile} ]; then&lt;br /&gt;
        echo &amp;quot;Skip backup, outfile ${outfile} exist!&amp;quot;&lt;br /&gt;
        if [ -f ${outfile}.md5 ]; then&lt;br /&gt;
            echo &amp;quot;MD5 info:&amp;quot;&lt;br /&gt;
            (&lt;br /&gt;
                set -x&lt;br /&gt;
                cat ${outfile}.md5&lt;br /&gt;
                md5sum ${outfile}&lt;br /&gt;
                md5sum /dev/${mtd}&lt;br /&gt;
            )&lt;br /&gt;
        fi&lt;br /&gt;
    else&lt;br /&gt;
        (&lt;br /&gt;
            set -x&lt;br /&gt;
            dd if=/dev/${mtd} of=${outfile}&lt;br /&gt;
        )&lt;br /&gt;
        if [ $? == 0 ]; then&lt;br /&gt;
            (&lt;br /&gt;
                set -x&lt;br /&gt;
                md5sum ${outfile} &amp;gt; ${outfile}.md5&lt;br /&gt;
                cat ${outfile}.md5&lt;br /&gt;
            )&lt;br /&gt;
        fi&lt;br /&gt;
&lt;br /&gt;
    fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== nanddump ==&lt;br /&gt;
Hier ein Script, welches nanddump von Jeff Doozan benutzt (siehe: http://jeff.doozan.com/debian/uboot/build_uboot.htm )&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#!/bin/sh&lt;br /&gt;
&lt;br /&gt;
dest=/i-data/6764ac2f/admin&lt;br /&gt;
&lt;br /&gt;
if [ -f nanddump ]; then&lt;br /&gt;
    echo &amp;quot;nanddump found, ok.&amp;quot;&lt;br /&gt;
else&lt;br /&gt;
    (&lt;br /&gt;
        set -x&lt;br /&gt;
        wget http://jeff.doozan.com/debian/uboot/nanddump&lt;br /&gt;
        chmod +x nanddump&lt;br /&gt;
    )&lt;br /&gt;
fi&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
for mtd in `cd /dev &amp;amp;&amp;amp; ls mtd?`&lt;br /&gt;
do&lt;br /&gt;
    echo &amp;quot;____________________________________________________________________&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    mtd_info=`cat /proc/mtd | grep ${mtd}`&lt;br /&gt;
&lt;br /&gt;
    if [ -z &amp;quot;${mtd_info}&amp;quot; ]; then&lt;br /&gt;
        echo &amp;quot;Skip ${mtd} because it&#039;s not in /proc/mtd&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
        echo &amp;quot;Backup ${mtd_info}&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        prefix=${dest}/${mtd}&lt;br /&gt;
        backup=${prefix}.backup&lt;br /&gt;
        oob=${backup}.oob&lt;br /&gt;
&lt;br /&gt;
        if [ -f ${backup} ]; then&lt;br /&gt;
            echo &amp;quot;Skip backup: File ${backup} exist!&amp;quot;&lt;br /&gt;
            (&lt;br /&gt;
                set -x&lt;br /&gt;
                cat ${backup}.md5&lt;br /&gt;
                md5sum ${backup}&lt;br /&gt;
&lt;br /&gt;
                cat ${oob}.md5&lt;br /&gt;
                md5sum ${oob}&lt;br /&gt;
            )&lt;br /&gt;
        else&lt;br /&gt;
            (&lt;br /&gt;
                set -x&lt;br /&gt;
                ./nanddump -nof ${backup} /dev/${mtd}&lt;br /&gt;
                md5sum ${backup} &amp;gt; ${backup}.md5&lt;br /&gt;
                cat ${backup}.md5&lt;br /&gt;
&lt;br /&gt;
                ./nanddump -nf ${oob} /dev/${mtd}&lt;br /&gt;
                md5sum ${oob} &amp;gt; ${oob}.md5&lt;br /&gt;
                cat ${oob}.md5&lt;br /&gt;
            )&lt;br /&gt;
        fi&lt;br /&gt;
    fi&lt;br /&gt;
done&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Cross-Compiler =&lt;br /&gt;
==crosstool-ng==&lt;br /&gt;
Auf dem Medion-Server ist die Original-Cross-Compiler-Umgebung für das NAS verfügbar. Mit der folgenden Anleitung wird die Toolchain unter Ubuntu 11.10 nach /opt installiert:&lt;br /&gt;
&lt;br /&gt;
  wget -c download2.medion.com/downloads/software/gpl_source_md86407.exe&lt;br /&gt;
  wine gpl_source_md86407.exe&lt;br /&gt;
  cd ~/.wine/drive_c/Medion/&lt;br /&gt;
  tar -xvf x-tools.armv5v6.tar.gz&lt;br /&gt;
  sudo mv x-tools /opt&lt;br /&gt;
  export CC=/opt/x-tools/armv6_le/arm-none-linux-gnueabi/bin/arm-none-linux-gnueabi-gcc&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;hello.c&#039;&#039;&#039;:&lt;br /&gt;
&amp;lt;c&amp;gt;#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
        printf(&amp;quot;Hello world\n&amp;quot;);&lt;br /&gt;
        return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
  arm-none-linux-gnueabi-gcc -Wall -g -o hello hello-c&lt;br /&gt;
&lt;br /&gt;
==ELDK==&lt;br /&gt;
Da das ELDK nicht immer lauffähige Binaries erzeugt, sollte die crosstool-ng Toolchain eingesetzt werden.&lt;br /&gt;
&lt;br /&gt;
(von http://www.mikrocontroller.net/topic/240238?goto=2446372#2442210 )&lt;br /&gt;
&lt;br /&gt;
hier eine kleine Anleitung zur Installation eines Cross-Compilers unter&lt;br /&gt;
Ubuntu 10.04/11.10:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
$ sudo aptitude install ia32-libs # Nur für 64-Bit-Systeme&lt;br /&gt;
$ sudo mkdir /opt/eldk42&lt;br /&gt;
$ wget http://ftp.denx.de/pub/eldk/4.2/arm-linux-x86/iso/arm-2008-11-24.iso&lt;br /&gt;
$ sudo mount -t iso9660 -o loop -o exec arm-2008-11-24.iso /mnt&lt;br /&gt;
$ cd /mnt&lt;br /&gt;
$ sudo ./install -d /opt/eldk42/ armVFP&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;$ /opt/eldk42/usr/bin/armVFP-linux-gcc -Wall -g -o hello hello.c&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;.bashrc&#039;&#039;&#039;&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
# ELDK 4.2 ARM 11 (i.MX35)&lt;br /&gt;
export ARCH=armVFP&lt;br /&gt;
export CROSS_COMPILE=armVFP-linux-&lt;br /&gt;
export CC=armVFP-linux-gcc&lt;br /&gt;
export PATH=$PATH:/opt/eldk42/usr/bin:/opt/eldk42/bin&lt;br /&gt;
export ROOT=/opt/eldk42/armVFP/&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beispiel dropbear compilieren:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
wget http://matt.ucc.asn.au/dropbear/dropbear-2011.54.tar.gz&lt;br /&gt;
tar -xvf dropbear-2011.54.tar.gz&lt;br /&gt;
cd dropbear-2011.54/&lt;br /&gt;
./configure --host=arm-linux&lt;br /&gt;
make&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= SATA Boot =&lt;br /&gt;
&lt;br /&gt;
PLX7820-basierte Geräte können von SATA, SPI und NAND booten. Das SATA-Interface ist - dem Verwendungszweck des SoC entsprechend - immer vorhanden. Die beiden anderen Interfaces sind nicht in jedem Gerät implementiert. Die angegebene Reihenfolge stellt gleichzeitig die Priorität dar, mit der an den einzelnen Interfaces nach dem Bootloader gesucht wird.&lt;br /&gt;
&lt;br /&gt;
Deshalb ist es möglich, durch spezielles Präparieren der angeschlossenen Festplatte von dieser zu booten. Der Inhalt des NAND braucht dafür nicht verändert zu werden. Nach Überschreiben der entsprechenden Stellen auf der Festplatte erfolgt der Boot-Vorgang wieder von NAND, wie in der Ausgangskonfiguration.&lt;br /&gt;
&lt;br /&gt;
Die ersten 32 MB einer bootfähigen Festplatte können nicht für Partitionen genutzt werden, sondern enthalten folgende Daten (basiert auf [http://iomega.nas-central.org/wiki/Stock_Configuration_%28Home_Media_CE%29#.27Unused_space.27_.28first_32_MiB.29 der Tabbelle von iomega.nas-central.org]):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background:#BBBBBB; color:black&amp;quot;&lt;br /&gt;
|Startblock (Blockgröße: 512 Bytes)||Größe (Bytes)||Inhalt||Kommentar&lt;br /&gt;
|- &lt;br /&gt;
|0||512||MBR||Die ersten 446 Bytes enthalten eine Art &#039;&#039;Startsequenz&#039;&#039;, in der unter anderem die Nummer des Startblocks des Stage-1-Bootloaders vorkommt (siehe [http://www.mikrocontroller.net/topic/240238?goto=2486646#2477637 forum] und [https://de.wikipedia.org/wiki/Master_Boot_Record#Aufbau_des_MBR Wikipedia]). Danach folgt die MBR-Partitionstabelle.&lt;br /&gt;
|-&lt;br /&gt;
|1||1536||GUID-Partitionstabelle||&lt;br /&gt;
|-&lt;br /&gt;
|34||8736||Stage-1-Bootloader||&lt;br /&gt;
|-&lt;br /&gt;
|154||103552||U-Boot||&lt;br /&gt;
|-&lt;br /&gt;
|558||At least 608||U-Boot environment||&lt;br /&gt;
|-&lt;br /&gt;
|1290||2189216||uImage kernel||&lt;br /&gt;
|-&lt;br /&gt;
|16674||2787216||uImage initrd||&lt;br /&gt;
|-&lt;br /&gt;
|57080||5||0x69 0xD3 0xAB 0x52 0x31||Dies stellt möglicherweise eine Seriennummer dar. Die MAC-Adresse ist es nicht.&lt;br /&gt;
|-&lt;br /&gt;
|57088||4640||Stage-1-Bootloader||Kopie&lt;br /&gt;
|-&lt;br /&gt;
|57208||103568||U-Boot||Kopie&lt;br /&gt;
|-&lt;br /&gt;
|58344||2189216||uImage kernel||Kopie&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
= Twonky Media Server: Versteckte Konfigurationsseite =&lt;br /&gt;
&lt;br /&gt;
Der eingebaute Twonky Media Server hat eine versteckte Konfigurationsseite: http://nas-server:9001/config&lt;br /&gt;
&lt;br /&gt;
Dort kann z.B. den Typen des Media-Receivers (TV) einstellen, um Videos zuverlässiger, mit mehr unterstützten Formaten abzuspielen.&lt;br /&gt;
&lt;br /&gt;
Dazu einfach in der Liste der Media Receivers den Fernseher von &amp;quot;Generic Media Receiver&amp;quot; auf z.B. &amp;quot;Samsung TV&amp;quot; stellen.&lt;br /&gt;
&lt;br /&gt;
Leider ist kein Knopf zum Speichern sichtbar. Dazu besser auf http://nas-server:9001/configpage/config-content.html gehen, da sind dann ganz oben Knöpfe zum Speichern etc.&lt;br /&gt;
&lt;br /&gt;
= Links =&lt;br /&gt;
&lt;br /&gt;
* http://forums.whirlpool.net.au/archive/1817691&lt;br /&gt;
* http://zyxel.nas-central.org/wiki/Category:NSA-212&lt;br /&gt;
* http://zyxel.nas-central.org/wiki/NZBGet&lt;br /&gt;
* http://zyxel.nas-central.org/wiki/SABnzdb&lt;br /&gt;
&lt;br /&gt;
Test der 2TB Version&lt;br /&gt;
* http://www.heise.de/ct/artikel/Luefterloses-Aldi-NAS-im-Kurztest-1757975.html&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:P89626| ]]&lt;br /&gt;
[[Kategorie:ARM-Boards]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Diskussion:Elektronikversender&amp;diff=69892</id>
		<title>Diskussion:Elektronikversender</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Diskussion:Elektronikversender&amp;diff=69892"/>
		<updated>2012-12-16T19:30:26Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* PayPal */ Vorschlag übernommen, Hauptseite ergänzt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Warum wurde Shortec von Eurotronik gelöscht ?&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Elektronikversender&amp;diff=69891</id>
		<title>Elektronikversender</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Elektronikversender&amp;diff=69891"/>
		<updated>2012-12-16T19:29:28Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* Pollin Electronic */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Vor- und Nachteile von verschiedenen Elektronik-Versand-Händlern werden relativ häufig im Forum diskutiert. Diese Diskussionen führen nicht selten zu weitestgehend gleichen Ergebnissen. In diesem Artikel sollen daher die Argumente, die für oder gegen einen bestimmten Elektronik-Versender sprechen, zusammengetragen werden. Sobald diese Liste einigermaßen vollständig ist, würde dies sicher einige Diskussions-Threads und/oder Flame-Wars überflüssig machen.&lt;br /&gt;
&lt;br /&gt;
Diese Liste erhebt keinerlei Anspruch auf Vollständigkeit, d.h. wenn ihr einen Versender kennt, der hier noch nicht aufgeführt ist, dann nennt wenigstens die URL und den Namen. Den Rest können auch andere besorgen, die den Versender ebenfalls kennen!&lt;br /&gt;
&lt;br /&gt;
Bitte ergänzt nur allgemeine Sachen (z.&amp;amp;nbsp;B. &amp;quot;liefert immer vollständig&amp;quot;, &amp;quot;günstig&amp;quot; oder &amp;quot;große Auswahl&amp;quot;), aber nicht Sachen wie &amp;quot;mein ATMega 128 hatte verbogene Beine&amp;quot;! Bitte auch die alphabetische Sortierung beibehalten!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Diese Seite kann nur von angemeldeten Benutzern bearbeitet werden!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Liste der Versender ==&lt;br /&gt;
&lt;br /&gt;
=== AATiS ===&lt;br /&gt;
Homepage: http://www.aatis.de&lt;br /&gt;
&lt;br /&gt;
* Arbeitskreis Amateurfunk und Technik in der Schule e.V.&lt;br /&gt;
* Bausätze speziell auch für Elektronik-Anfänger, Schüler&lt;br /&gt;
* Literatur, Seminare für Lehrer &lt;br /&gt;
&lt;br /&gt;
=== Actron ===&lt;br /&gt;
Homepage: http://www.actron.de&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;kein&#039;&#039;&#039; Online-Shop!&lt;br /&gt;
* alphanumerische LCDs und Graphikdisplays in großer Auswahl, auch mit Touchscreens&lt;br /&gt;
* für gewerbliche Kunden: etwas verhandeln schadet nie&lt;br /&gt;
* bei kleinen Stückzahlen nicht ganz billig&lt;br /&gt;
* liefern sehr schnell und stets zuverlässig&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=== Adapterprofi ===&lt;br /&gt;
Homepage: http://www.adapterprofi.de&lt;br /&gt;
&lt;br /&gt;
* Bauteile, Gehäuse, Netzteile&lt;br /&gt;
* Viele unterschiedliche HF-Adapter&lt;br /&gt;
* Seite aktuell nicht erreichbar (10.12.2011) ist wohl tot&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== AK Modul Bus Computer GmbH ===&lt;br /&gt;
Homepage: http://www.ak-modul-bus.com/stat/produkte.html&lt;br /&gt;
&lt;br /&gt;
* Interfaces, Messmodule, Funktionsmodelle, Experimentiersysteme&lt;br /&gt;
* Entwicklungssysteme, Baugruppen, Elektor, Zubehör, Bauelemente&lt;br /&gt;
* Software, Lernpakete, Bücher, Sonderposten&lt;br /&gt;
&lt;br /&gt;
=== Allpax ===&lt;br /&gt;
Homepage: http://www.allpax.de&lt;br /&gt;
&lt;br /&gt;
* Liefert auch an Privathaushalte&lt;br /&gt;
* Keine Elektronik an sich, aber ggf. nützliches Zubehör: Größeres, übersichtliches Sortiment an ESD-Beuteln und -Folien, offen und mit Zippverschluss, Pink Poly und Metallisiert (High Shield). Preislich über Farnell, dafür findet man sofort, was man sucht...&lt;br /&gt;
* außerdem Ultraschallreiniger, Waagen und Folienschweißgeräte, sowie viel Fachfremdes&lt;br /&gt;
* Versandkosten: 8,33€ nach Deutschland, diverse EU-Länder 17,85€, Schweiz 34,51€; Versandkostenfrei in D ab 178,50€&lt;br /&gt;
* Gewährt scheinbar auch Privatkunden die Zahlung per Rechnung; bei Bankeinzug 2% Rabatt, bei Vorkasse und Abholung 3%&lt;br /&gt;
&lt;br /&gt;
=== AME-Engineering ===&lt;br /&gt;
Homepage: http://www.ame-engineering.de&lt;br /&gt;
&lt;br /&gt;
* Hochfrequenz-Spezialitäten, Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Amidon ===&lt;br /&gt;
Homepage: http://www.amidon.de&lt;br /&gt;
&lt;br /&gt;
* Sehr großes Sortiment, vorallem für seltene Bauteile, z.&amp;amp;nbsp;B. Dioden&lt;br /&gt;
&lt;br /&gt;
=== Andy&#039;s Funkladen ===&lt;br /&gt;
Homepage: http://www.andyfunk.de&lt;br /&gt;
&lt;br /&gt;
* Alles für Amateur- und CB-Funk&lt;br /&gt;
* Bauteile und Gehäuse&lt;br /&gt;
&lt;br /&gt;
=== Anvilex ===&lt;br /&gt;
Homepage: http://shop.anvilex.com/index.html&lt;br /&gt;
&lt;br /&gt;
* Liefert sehr günstige Break-Out Boards für diverse Packages&lt;br /&gt;
* Hat einige einfache und günstige Programmer auch für FPGAs etc&lt;br /&gt;
&lt;br /&gt;
=== Atlantis Shop 24 ===&lt;br /&gt;
Homepage: http://www.atlantis-shop24.de&lt;br /&gt;
&lt;br /&gt;
* Elektronik nur ein kleiner Teil des Angebotes. Ansonsten eher Drogerie bzw. Haushaltsbedarf&lt;br /&gt;
&lt;br /&gt;
=== Atzert-Elektronik Versand ===&lt;br /&gt;
Homepage: http://www.atzert-elektronik.de&lt;br /&gt;
&lt;br /&gt;
Früher &#039;&#039;EFB-Electronic Versand&#039;&#039;, davor &#039;&#039;MEGAKICK Electronic Stores&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* Mindestens schon der dritte Name und die dritte Webseite für den Endkunden-Versand von [[Elektronikversender#ETT|ETT]]. ETT liefert sonst nur an gewerbliche Kunden.&lt;br /&gt;
* Ladengeschäfte in Bielefeld, Braunschweig, Bremen, Hamburg und Berlin. &lt;br /&gt;
* Die Preise schwanken im Vergleich zu anderen Anbietern, welche ebenfalls ETT-importierte Produkte führen, mal nach oben, mal nach unten.&lt;br /&gt;
&lt;br /&gt;
=== Bassenberg Elektronik ===&lt;br /&gt;
Homepage: http://www.bassenberg.de&lt;br /&gt;
&lt;br /&gt;
* Ladengeschäfte in Braunschweig und Neumünster&lt;br /&gt;
* Beschafft auch nicht mehr gelistete und abgekündigte Bauteile&lt;br /&gt;
* Liefert auch an Privat&lt;br /&gt;
&lt;br /&gt;
=== Batronix ===&lt;br /&gt;
Homepage: http://www.batronix.com&lt;br /&gt;
* Grosses Sortiment an Geräten&lt;br /&gt;
* Bausätze für Microcontroller-Applikationen&lt;br /&gt;
* Liefert auch an Privat&lt;br /&gt;
&lt;br /&gt;
=== BAZ Spezialantennen ===&lt;br /&gt;
Homepage: http://www.spezialantennen.de&lt;br /&gt;
&lt;br /&gt;
* Antennen für Amateurfunk, ISM, WLAN usw.&lt;br /&gt;
&lt;br /&gt;
=== bed - elektronik ===&lt;br /&gt;
Homepage: http://www.bed-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Restposten aktive und passive Bauelemente&lt;br /&gt;
* sehr günstige Preise&lt;br /&gt;
* alles ab Lager lieferbar&lt;br /&gt;
* Versand an Privat&lt;br /&gt;
* ab 60 EUR versandkostenfrei&lt;br /&gt;
&lt;br /&gt;
=== Bfi-Optilas ===&lt;br /&gt;
Homepage: http://www.bfioptilas.de&lt;br /&gt;
&lt;br /&gt;
* Kein Onlineshop&lt;br /&gt;
* spezialisierter Distributor für Hochfrequenzhalbleiter und Optik&lt;br /&gt;
&lt;br /&gt;
=== BG-Electronics.de ===&lt;br /&gt;
Homepage: http://www.bg-electronics.de&lt;br /&gt;
&lt;br /&gt;
* Online Shop für aktive und passive elektronische Bauelememte&lt;br /&gt;
* günstige Preise&lt;br /&gt;
* alle Artikel ab Lager lieferbar, daher kurze Wartezeiten&lt;br /&gt;
* weltweiter Versand&lt;br /&gt;
* zahlreiche Mengenrabatte&lt;br /&gt;
* viele Ersatzteile aus dem Audio-, CarHiFi und TV-Bereich&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=== B &amp;amp; M electronics ===&lt;br /&gt;
Homepage: http://www.bmelectronics.de&lt;br /&gt;
&lt;br /&gt;
* Bauteile, Platinen und Baugruppen für Amateurfunk&lt;br /&gt;
Seite nicht erreichbar am 22.7.2012 --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Box73 ===&lt;br /&gt;
Homepage: http://www.box73.de&lt;br /&gt;
&lt;br /&gt;
Onlineshop des Funkamateur.&lt;br /&gt;
&lt;br /&gt;
* Bauteile, Bausätze, Literatur aus dem Amateurfunkbereich&lt;br /&gt;
* Preise sind O.K.&lt;br /&gt;
* Bestellungen werden nur Di und Do bearbeitet&lt;br /&gt;
* Ab 50 EUR bei Bankeinzug portofrei.&lt;br /&gt;
&lt;br /&gt;
=== Bürklin OHG ===&lt;br /&gt;
Homepage: http://www.buerklin.com&lt;br /&gt;
&lt;br /&gt;
* große Auswahl, hohe Verfügbarkeit&lt;br /&gt;
* sehr schneller Versand&lt;br /&gt;
* Ladengeschäft in Oberhaching (südlicher Landkreis München)&lt;br /&gt;
* &amp;lt;s&amp;gt;nur an gewerbliche Abnehmer (lt. AGB), private Abnehmer können dennoch im Ladengeschäft einkaufen&amp;lt;br&amp;gt;Angeblich versendet Bürklin seit November 2010 auch an Privatpersonen. Allerdings verlangt Bürklin weiterhin in Adressformularen die Eingabe eines Firmennamens &amp;lt;br&amp;gt;Geben Sie einen Wert in das Feld &amp;quot;Firma&amp;quot; ein.&amp;lt;br&amp;gt;Daher ist diese Information eher mit Vorsicht zu genießen.&amp;lt;/s&amp;gt;&amp;lt;br&amp;gt;Mittlerweile muss man auch keinen Firmennamen mehr eingeben. Die AGB wurde ebenfalls angepasst.&lt;br /&gt;
&lt;br /&gt;
=== CBsoft, s.r.o. (ltd.) ===&lt;br /&gt;
*Homepage: http://www.jjtubes.eu/&lt;br /&gt;
* Firma in der Slowakei&lt;br /&gt;
* Verkauft Röhren der Firma JJ&lt;br /&gt;
* englischsprachig&lt;br /&gt;
* Zahlungsmöglichkeiten in € mit Paypal und Kreditkarte&lt;br /&gt;
&lt;br /&gt;
=== chiptrade.com ===&lt;br /&gt;
siehe [[#SE Spezial-Electronic AG|SE Spezial-Electronic AG]]&lt;br /&gt;
&lt;br /&gt;
=== ConeleK Electronic ===&lt;br /&gt;
Homepage: http://www.conelek.com&lt;br /&gt;
&lt;br /&gt;
* Sehr kleines Bauteileangebot (Röhren, Röhrensockel)&lt;br /&gt;
* Elektronik-Laborbedarf, insbesondere Nachfüllpackungen mit Steckbrett-Drahtbrücken&lt;br /&gt;
* Werkzeug für Elektronik&lt;br /&gt;
* Stromversorgungen&lt;br /&gt;
* Versand an Privat&lt;br /&gt;
* Versandkosten bis 25kg, Vorkasse 5,90€ (Stand 04/2008)&lt;br /&gt;
&lt;br /&gt;
=== Conrad ===&lt;br /&gt;
Homepage: http://www.conrad.de und http://www.business.conrad.de&lt;br /&gt;
&lt;br /&gt;
* großes Angebot (für Bauteile den &amp;quot;Business&amp;quot;-Katalog beachten, der Hauptkatalog ist dahingehend etwas &amp;quot;dünn&amp;quot;) (Anm.: Bauteile, die nur im Business-Katalog aufgeführt sind, sind in Ladengeschäften nur über Sonderbestellung zu bekommen, d.h. dort in aller Regel nicht vorrätig.)&lt;br /&gt;
* Positiv: Wirklich jedes Bauteil kann einzeln gekauft werden und wird nicht in dämlichen Verpackungseinheiten verkauft, so wie es bei den meisten anderen Elektronik-Lieferanten der Fall ist. Dies ist vor Allem für den Prototypenbau sehr hilfreich.&lt;br /&gt;
* relativ teuer jedoch bis zu 10% Rabatt für Schulen (bei genügend Umsatz)&lt;br /&gt;
* 21 Ladengeschäfte in Deutschland, fünf in Österreich&lt;br /&gt;
* positiv: Bei Business-Kunden wird der Rechnungsbetrag erst nach 14 Tagen abgebucht.&lt;br /&gt;
* haben einen (teuren) 24 Std. Lieferservice für Notfälle - Conrad garantiert aber nicht 100%ig für die Einhaltung der 24 Stunden. Bei Nichteinhaltung gibt es kein Geld zurück.&lt;br /&gt;
* Verfügbarkeit in Filialen kann Online überprüft werden.&lt;br /&gt;
* Verfügbarkeit in Filialen kann über zentale Rufnummer erfragt werden. Abholung bestellter Ware in Filialen möglich, aber trotzdem gleiche Versandkosten.&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
Vorerst Auskommentiert - Subjektiv/Einzelerfahrung, veraltete Informationen (Filialen)&lt;br /&gt;
* Mit jeder Bestellung erhält man zusätzlich Werbung von unseriösen Firmen, wo Gewinne versprochen werden und man sich in Wirklichkeit für irgendwelche Abos verpflichtet. Wenn man bei Conrad anruft und sie zur Rede stellt, erhält man die Antwort, dass diese Werbung anscheinend aus Versehen hineingerutscht ist. So ein Zufall.&lt;br /&gt;
* sehr kulant bei Umtäuschen&lt;br /&gt;
* versuchen bei Rückgaben einen Teil oder den gesamten Betrag einzubehalten (schon mehrfach vorgekommen)&lt;br /&gt;
* Schlampig verpackte Artikel. ICs sind nicht Antistatik-Konform verpackt.&lt;br /&gt;
* Die Filiale München / Tal hat keine Telefonnummer mehr in den Verzeichnissen, anscheinend sind Kundenanfragen dort zu &amp;quot;lästig&amp;quot;. (Kommentar: andere Filialen auch nicht, wird nur noch über eine Sammelnummer über ein Callcenter abgewickelt. Die Ladenbestellung wird dann vom Callcenter per eMail an die Filiale weitergeleitet.)&lt;br /&gt;
* die Ladengeschäfte haben nicht das gesamte Programm vor Ort, man kann jedoch in den Geschäften anrufen und die Verfügbarkeit anfragen, evtl. sogar Teile für ein paar Stunden &amp;quot;zurücklegen lassen&amp;quot; (von Geschäft zu Geschäft verschieden).&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== csd-electronics ===&lt;br /&gt;
Homepage: [http://www.csd-electronics.de csd-electronics.de]&lt;br /&gt;
&lt;br /&gt;
* schnelle Lieferung, sofern die Artikel auf Lager sind, versandkostenfreie Nachlieferung, &#039;&#039;&#039;teilweise sehr lange Lieferzeiten bei Ware die nicht ab Lager lieferbar ist&#039;&#039;&#039;. Bitte selbst abwägen ob dies für einen selbst akzeptabel ist. (Diskussion siehe hier [http://www.mikrocontroller.net/topic/273508] und hier [http://www.mikrocontroller.net/topic/249395].)&lt;br /&gt;
* ATMEL, ICs, Passive und Mechanische Bauteile, Platinen- und Lötzubehör, u.a.&lt;br /&gt;
* ca. 4000 Bauteile lagernd&lt;br /&gt;
* günstig&lt;br /&gt;
* Mengenrabatte für fast jedes Produkt&lt;br /&gt;
* Versand innerhalb Deutschlands: &lt;br /&gt;
* DPD: 3,75€ (ab 50 EUR versandkostenfrei)&lt;br /&gt;
* DHL: 4,50€ (ab 100 EUR versandkostenfrei)&lt;br /&gt;
* Versand EU-weit ab 5,95 EUR&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* Bauelemente, die nicht im Shop angeboten werden, können auf Anfrage beschafft werden.&lt;br /&gt;
* Zahlung per Vorkasse (2% Skonto), PayPal, Nachnahme. 1 EUR Aufschlag bei PayPal-Zahlung&lt;br /&gt;
* Zahlung per Bankabbuchung, Kreditkarte oder Rechnung nur für Stammkunden (ab 4 bis 5 Bestellung), Für Institute/Firmen direkt auf Rechnung möglich&lt;br /&gt;
&lt;br /&gt;
=== dad24 ===&lt;br /&gt;
Homepage, Shop: http://dad24.eu&lt;br /&gt;
E-Bay Shop:     http://stores.ebay.de/Shop-dad24&lt;br /&gt;
&lt;br /&gt;
* Unterschiedliche Preise in den beiden Shops&lt;br /&gt;
* Kleiner, nicht sonderlich schöner Onlineshop (dad24.eu)&lt;br /&gt;
* Kleines Angebot. Lupenleuchten, Lötstationen, Labornetzgeräte, Messgeräte, etc. aus dem unteren Preissegment&lt;br /&gt;
* Jede Woche eine neue &amp;quot;Kategorie der Woche&amp;quot; auf dad24.eu. Produkte aus der Kategorie werden erst im Warenkorb mit einem Rabatt angezeigt, der auch gewährt wird.&lt;br /&gt;
&lt;br /&gt;
=== Darisus ===&lt;br /&gt;
Homepage: http://www.darisus.de&lt;br /&gt;
&lt;br /&gt;
* kompetente Beratung&lt;br /&gt;
* liefert sehr zuverlässig, in Notfällen auch Express&lt;br /&gt;
* Versand innerhalb Deutschlands ab 4,50 EUR&lt;br /&gt;
* Hat auch eine gute Auswahl an CPLDs und einige FPGAs diverser Hersteller&lt;br /&gt;
&lt;br /&gt;
=== Daschke LTD ===&lt;br /&gt;
PDF-Katalog (Achtung, grosse Datei): http://www.daschke-ltd.de/Catalog/&lt;br /&gt;
&lt;br /&gt;
* Prompte Antwort und Hilfe via info ät obige adresse&lt;br /&gt;
* Bezahlung per Paypal und Rechnung möglich. Ist auch Ebay-Händler.&lt;br /&gt;
* sehr faire Preise für Bauteile und Versand&lt;br /&gt;
* Führt eine Vielzahl an unüblichen Steckern und Buchsen&lt;br /&gt;
* Nicht verfügbare Bauteile wurden proaktiv nachbestellt, trotz geringer Bestellmenge. Prima!&lt;br /&gt;
&lt;br /&gt;
=== DES - Der Elektroniker-Shop ===&lt;br /&gt;
Homepage: http://www.DerElektronikerShop.de&lt;br /&gt;
&lt;br /&gt;
* Bauteile&lt;br /&gt;
* Bauteilsätze der [http://www.DieElektronikerseite.de Elektronikerseite]&lt;br /&gt;
* Verkauf des BasicBeetle von [http://www.DieProjektseite.de der Projektseite]&lt;br /&gt;
* Ständig wachsendes Angebot&lt;br /&gt;
* Auch einige SMD-Bauteile verfügbar&lt;br /&gt;
* Kein Mindestbestellwert&lt;br /&gt;
* Versandkosten ab 3,50 EUR (Ab 1.1.13 3,70€) (Österreich/Europa ab 4,00 Eur)&lt;br /&gt;
* *** Versandkostenfrei an den Adventsonntagen bei einem Bestellwert ab 10,- € ***&lt;br /&gt;
* Versand auch nach Österreich (Europa auf Anfrage)&lt;br /&gt;
* Zahlung per Vorkasse&lt;br /&gt;
* Lieferzeit 1-3 Tage bei Verfügbarkeit&lt;br /&gt;
* PrePaid-Konto möglich&lt;br /&gt;
* Lieferungen auch an Privat&lt;br /&gt;
&lt;br /&gt;
=== Digi-Key ===&lt;br /&gt;
(tlw.) deutsche Homepage: http://de.digikey.com&lt;br /&gt;
&lt;br /&gt;
* optisch nicht besonders ansprechende, aber durchaus sehr funktionelle Website&lt;br /&gt;
* beheimatet in den USA, ein Logistikbüro gibt es in den Niederlanden&lt;br /&gt;
* kostenloser Versand ab 65&amp;amp;#8364;, darunter 18&amp;amp;#8364; Versandkosten&lt;br /&gt;
* macht merkwürdige Plausibilitäts-Checks: wenn man privat über ihrem Dollar Limit (z.B. 400 Dollar bestellt) kommt sofort die Rückfrage nach Firmenname und Firmenadresse&lt;br /&gt;
* Rückfragen nach dem Verwendungszweck kommen ebenfalls schon bei der Bestellung bei bestimmten Bauteilen die der Exportkontrolle unterliegen&lt;br /&gt;
* Versand direkt aus den USA, dafür sehr flott mit UPS Express (in rund zwei bis drei Tagen da)&lt;br /&gt;
* riesiges Angebot, gewissermaßen ein Distributor der auch Kleinmengen an Privatpersonen liefert, entscheidend ist, dass der Hersteller des Produkts geführt wird&lt;br /&gt;
* kein anderer Anbieter, bietet so viele verschiedene passive Bauteile in kleinen Stückzahlen, z.&amp;amp;nbsp;B. SMD Widerstände in Bauform 01005 bis 2512 meist in verschiedenen Toleranzklassen und von verschiedenen Herstellern&lt;br /&gt;
* alle Bauteile mit Herstellerangabe, Digikey kauft ausschließlich direkt vom Hersteller&lt;br /&gt;
* Preise sind auf der deutschen Website in Euro inklusive etwaigem Zoll angegeben, allerdings ohne Mehrwertsteuer, die korrekt abgerechnet wird (d.h. man zahlt bei Versand nach Österreich 20% Mwst., nach Deutschland m.W.n. 19%)&lt;br /&gt;
* Meistens deutlich teurer als Reichelt, doch häufig die beste Anlaufstelle für Privatkunden wenn es um Spezialbauteile geht, und der Hersteller sich im Programm von Digikey befindet&lt;br /&gt;
&amp;lt;!-- * wesentlich teurer als Reichelt, dafür jeder Artikel mit Herstellerangabe&lt;br /&gt;
=&amp;gt; &amp;quot;wesentlich&amp;quot; etwas zu pauschal (vgl. STK500 etc. selbst bei den verglw. hohen Versandkosten) - mt --&amp;gt;&lt;br /&gt;
* Zu beachten ist auch noch folgendes, um unliebsame zusatzkosten zu vermeiden: http://www.mikrocontroller.net/topic/90943#new. &#039;&#039;Anmerkung dazu: Digikey hat wohl zum 1.4.2011 den Versand umgestellt und importiert nun selbst. Zusatzkosten durch Verzollung sollten dann nicht mehr anfallen.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Display Electronics ===&lt;br /&gt;
&lt;br /&gt;
Homepage: http://www.distel.co.uk&lt;br /&gt;
&lt;br /&gt;
* In England&lt;br /&gt;
* Webseite = Augenkrebs &lt;br /&gt;
* Online-Shop versteckt hinter dem Search-Button auf der Homepage&lt;br /&gt;
* Restposten aller Art&lt;br /&gt;
* Mindestbestellwert 10 GBP&lt;br /&gt;
&lt;br /&gt;
=== eHaJo ===&lt;br /&gt;
Homepage: http://www.eHaJo.de&lt;br /&gt;
&lt;br /&gt;
* Bausätze &lt;br /&gt;
* Lötübungen&lt;br /&gt;
* AVR-ISP-Stick&lt;br /&gt;
&lt;br /&gt;
=== EIBTron.com ===&lt;br /&gt;
Homepage: http://www.eibtron.com&lt;br /&gt;
&lt;br /&gt;
* Riesige Auswahl an Produkten (~300000)&lt;br /&gt;
* SMD-Bauteile bis 0402!&lt;br /&gt;
* auch spezielle Sachen wie Xilinx-Configuration PROMs, AD9740-DACs oder SMD-Quarze (z.B. Abracon ABM7) im Angebot&lt;br /&gt;
* Alternative zum HBE-Shop für Privatanwender!&lt;br /&gt;
&lt;br /&gt;
=== Eisch-Kafka-Electronic ===&lt;br /&gt;
Homepage: http://www.eisch-electronic.de&lt;br /&gt;
 &lt;br /&gt;
* Hochfrequenz Bausätze und Bauteile für Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== EleConT ===&lt;br /&gt;
Homepage: http://www.elecont.de/shop/&lt;br /&gt;
&lt;br /&gt;
* Carrierboards für gebräuchliche AVR&lt;br /&gt;
&lt;br /&gt;
=== Electropuces ===&lt;br /&gt;
Homepage: http://perso.wanadoo.fr/electropuces/&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte aus Nantes, Frankreich  (teilweise engl. Menü)&lt;br /&gt;
&lt;br /&gt;
=== Electronic Search ===&lt;br /&gt;
&lt;br /&gt;
Homepage: http://www.electronic-search.de&lt;br /&gt;
&lt;br /&gt;
* Keine Mindestbestellmenge&lt;br /&gt;
* Verkauf auch an Privat/Bastler&lt;br /&gt;
* Fast alle Preise im Online-Shop nur &amp;quot;auf Anfrage&amp;quot;, und nicht im Shop angegeben.&lt;br /&gt;
&lt;br /&gt;
=== electronicpool Rheinstetten ===&lt;br /&gt;
Homepage: http://www.electronicpool.de&lt;br /&gt;
&lt;br /&gt;
* abgekündigte oder schwer beschaffbare elektronische Bauteile&lt;br /&gt;
&lt;br /&gt;
=== Elektronikladen ===&lt;br /&gt;
Homepage: http://www.elektronikladen.de&lt;br /&gt;
&lt;br /&gt;
* Spezialist für Mikrokontroller&lt;br /&gt;
* Entwicklungssysteme, keine Einzelbauteile&lt;br /&gt;
* entsprechende Literatur und Software&lt;br /&gt;
* &amp;quot;Kein Verkauf an Endverbraucher i.S.d. §13 BGB&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Elektronik-Kompendium ===&lt;br /&gt;
Homepage: http://www.elektronik-kompendium.de&lt;br /&gt;
&lt;br /&gt;
* Bausätze diverser Schaltungen (mit Anleitung und Funktionsbeschreibung)&lt;br /&gt;
* erspart lästiges Suchen in anderen Shops&lt;br /&gt;
* kurze Lieferzeiten&lt;br /&gt;
* günstiger Versand&lt;br /&gt;
&lt;br /&gt;
=== Elk Tronic ===&lt;br /&gt;
Homepage: http://www.elk-tronic.de&lt;br /&gt;
&lt;br /&gt;
* kleines Lieferprogramm Adapterplatinen (SMD -&amp;gt; 2,54mm-Raster) und Programmieradapter&lt;br /&gt;
* günstige Preise und Versandspesen&lt;br /&gt;
&lt;br /&gt;
=== Elko-Verkauf ===&lt;br /&gt;
Homepage: http://www.elko-verkauf.de&lt;br /&gt;
&lt;br /&gt;
* Nur Low-ESR-Elkos&lt;br /&gt;
* Elko-Sets für ein Gerät&lt;br /&gt;
&lt;br /&gt;
=== Ellmitron ===&lt;br /&gt;
Homepage: http://www.ellmitron.de/&lt;br /&gt;
Katalog: http://www.ellmitron.de/katalog.pdf&lt;br /&gt;
&lt;br /&gt;
Lehrmittel, Kleinbausätze vor allem für Schüler, Experimentierkästen&lt;br /&gt;
&lt;br /&gt;
=== Elpro Darmstadt ===&lt;br /&gt;
Homepage: http://www.elpro.org&lt;br /&gt;
&lt;br /&gt;
* Kein Mindestbestellwert, aber hohe Versandkosten für kleine Bestellungen. Stand September 2008:&lt;br /&gt;
** Bis 15€: 9,95€ Versandkosten&lt;br /&gt;
** Von €15 bis €75: 5,95€ Versandkosten&lt;br /&gt;
** Von €75 bis €200: 4,49€ Versandkosten&lt;br /&gt;
** Ab €200: Versandkostenfrei&lt;br /&gt;
* Große Auswahl an Mikrocontrollern&lt;br /&gt;
* Sehr große Auswahl an Schaltnetzteilen von Meanwell (geschlossen, offen, auf PCB lötbar, DIN-Schiene)&lt;br /&gt;
* Merkwürdig zu bedienende Shopsoftware, ständig klappt was auf und zu und wird irgendwas nachgeladen. Braucht JavaScript&lt;br /&gt;
* Keine AGBs online. Da Preisangaben ohne MwSt. richtet sich das Angebot vermutlich nicht an Endverbraucher (werden aber beliefert)&lt;br /&gt;
* Bearbeitungszeit (bis Warenausgang) 2-3 Tage.&lt;br /&gt;
* Versand bisher mit DHL&lt;br /&gt;
* gute bis sehr gute Verpackung&lt;br /&gt;
&lt;br /&gt;
=== Eltrix ===&lt;br /&gt;
Homepage: http://eltrix.de/Starteltrix.htm&lt;br /&gt;
&lt;br /&gt;
*  Verbrauchsmaterial, Tipps und Tricks fürs Leiterplattenherstellen und Löten&lt;br /&gt;
&lt;br /&gt;
=== ELV ===&lt;br /&gt;
Homepage: http://www.elv.de&lt;br /&gt;
&lt;br /&gt;
* nicht sehr große Auswahl an Einzelteilen&lt;br /&gt;
* riesiges Angebot an Zubehör für Hobbyisten&lt;br /&gt;
* viele z.T. pfiffige Eigenentwicklungen, Bausätze (auch zum Download auf der Website verfügbar)&lt;br /&gt;
* sonst Sortiment ähnlich Conrad, nicht billig&lt;br /&gt;
* im Allgemeinen nicht billig, merkwürdigerweise sind manche Artikel aber die günstigsten auf dem Markt&lt;br /&gt;
* mühsamer Onlinekatalog&lt;br /&gt;
* Immer mal wieder Fehllieferungen und Wartezeiten (zumindest in die Schweiz). Service erreichte in 3 Fällen nicht das inserierte Niveau.&lt;br /&gt;
* Versandkosten innerhalb Deutschland 4,5&amp;amp;#8364;, ab 150&amp;amp;#8364; Bestellwert versandkostenfrei&lt;br /&gt;
* nicht abwählbare Versandversicherung, die 0,85% des Bestellwertes kostet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Erklärte am 31. August 2010 &amp;quot;... den Betrieb bis auf weiteres zu schließen.&amp;quot; &lt;br /&gt;
=== Embedit Mikrocontrollertechnik ===&lt;br /&gt;
Online Shop: http://shop.embedit.de&lt;br /&gt;
&lt;br /&gt;
* Gute Auswahl an AVR Controllern, aber nur aktuelle Typen, keine AT90Sxxxx. Teilweise exotische Typen wie MLF Gehäuse&lt;br /&gt;
* Atmel und Philips SmartARM Controller&lt;br /&gt;
* Module und Boards mit AVR Controllern&lt;br /&gt;
* Zubehör von Atmel wie STK500 oder AVRISP mkII&lt;br /&gt;
* Diverse aktive und passive Elektronikteile, ständig neue Teile&lt;br /&gt;
* Mechanikteile wie Zahnräder, Steckverbinder usw.&lt;br /&gt;
* Lieferzeit 1-4 Tage, je nachdem wie man zahlt (hab aber auch schon ne Vorauskasse innerhalb eines Tages per Expressbrief bekommen, zuvorkommender Service)&lt;br /&gt;
* Versandkosten ab 3,95 &amp;amp;#8364;, versicherter Versand, Vorauskasse und Nachnahme&lt;br /&gt;
* Keine Versandkosten ab 50 &amp;amp;#8364; Warenwert innerhalb Deutschlands, bei Zahlung per Vorauskasse und Lieferung per Hermes&lt;br /&gt;
* Lieferung in viele EU-Länder&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ETT - Electronic Toys Trading  ===&lt;br /&gt;
Homepage: http://www.ett-online.de&lt;br /&gt;
&lt;br /&gt;
* Großhandel nur für Gewerbekunden.&lt;br /&gt;
* Zweitshop [[Elektronikversender#Atzert-Elektronik_Versand|Atzert-Elektronik Versand]] (früher EFB-Electronic Versand, davor Megakick Electronic-Stores) für Endkunden.&lt;br /&gt;
* Ladengeschäft in Braunschweig für jedermann. Weitere Atzert Ladengeschäfte in Bielefeld, Bremen, Hamburg und Berlin.&lt;br /&gt;
* Eigentümer der Marken McCHECK®, McPower®, McVoice® und anderer, unter denen ETT importierte Messgeräte, Labornetzteile, usw. an Großkunden und Händler vertreibt. Diese sind unter oben genannten Marken dann in vielen Shops anderer Firmen für Endkunden zu finden, nicht nur bei Atzert. Preisvergleiche lohnen.&lt;br /&gt;
&lt;br /&gt;
=== Ettinger GmbH ===&lt;br /&gt;
Homepage: http://www.ettinger.de&lt;br /&gt;
&lt;br /&gt;
* Für gewerbliche Kunden&lt;br /&gt;
* Mechanische Komponenten (Gehäuse, Abstandshalter, Drehknöpfe, usw.)&lt;br /&gt;
* LEDs&lt;br /&gt;
* Gewöhnungsbedürftiger Online-Shop&lt;br /&gt;
&lt;br /&gt;
=== Eurotronik GmbH ===&lt;br /&gt;
Homepage: http://www.eurotronik.com&lt;br /&gt;
&lt;br /&gt;
* Für gewerbliche Kunden&lt;br /&gt;
* Mindestbestellwert 100.00 Euro&lt;br /&gt;
* Individuelle Suche für alle möglichen Bauelemente&lt;br /&gt;
* Abgekündigte und allokierte BE finden&lt;br /&gt;
* Besonders Stark mit Altera, Microchip, Texas Instruments&lt;br /&gt;
&lt;br /&gt;
=== EVE ===&lt;br /&gt;
Homepage: http://www.eve.de&lt;br /&gt;
&lt;br /&gt;
* Zitat aus den AGBs:&lt;br /&gt;
::&#039;&#039;&amp;quot;Zu Bestellungen im Rahmen des Online-Handels sind nur durch uns autorisierte, d. h. zugelassene Käufer berechtigt. Wir gewähren nach erfolgreicher Zertifizierung – ohne hierzu verpflichtet zu sein – dem jeweiligen Käufer das nicht übertragbare, nicht exklusive Recht im Rahmen des Online-Handels Bestellungen uns gegenüber “auszubringen”.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:Dies darf man wohl getrost als Hinweis ansehen, dass Endverbraucher als Kunden nicht gewünscht sind.&lt;br /&gt;
* Versandhaus für elektronische Artikel in Emsdetten&lt;br /&gt;
* machen auch Kabelkonfektion&lt;br /&gt;
* Pb-freie Artikel markiert&lt;br /&gt;
&lt;br /&gt;
=== Farnell ===&lt;br /&gt;
Homepage: http://de.farnell.com&lt;br /&gt;
&lt;br /&gt;
* liefert nur an gewerbliche Abnehmer, Ausnahme sind Studenten und HTL-Schüler (Österreich, Farnell.at). Nachweis wird verlangt (Gewerbeschein oder Immatrikulation).&lt;br /&gt;
* Lieferungen an Privat:&lt;br /&gt;
:* Schweiz: Farnell Schweiz beliefert auch Privatkunden.&lt;br /&gt;
:* Deutschland: Über den Reseller [[#HBE_-_Heinz_B.C3.BCchner_Elektronik.2C_Messtechnik.2C_med._Elektronik_e.K.|HBE]] kann man Produkte aus dem Farnell-Sortiment zu bestellen.&lt;br /&gt;
:* Österreich: [[#Technik-Welt / Industrieshop.at|Technik-Welt / Industrieshop.at]]&lt;br /&gt;
* große Auswahl&lt;br /&gt;
* 12% Rabatt für Studenten und Lehreinrichtungen&lt;br /&gt;
* sehr schneller Versand, Ware ist in 99% aller Fälle am nächsten Tag da (UPS), fehlende Positionen werden relativ rasch versandkostenfrei nachgeliefert&lt;br /&gt;
* Versandkosten: Bestellung bis 49,99&amp;amp;#8364;: 7,95&amp;amp;#8364;;   50,- bis 149,99&amp;amp;#8364;: 5,95&amp;amp;#8364;;   ab EUR 150,- versandkostenfrei&lt;br /&gt;
* hat nach eigenen Aussagen umfangreichstes Sortiment an RoHS-konformen Bauteilen mit Suchfunktion im WWW&lt;br /&gt;
* leistungsfähige parametrische Suchfunktion / teils aber völlig nutzlos, da den Artikeln massenweise Tags fehlen, weswegen die Suchergebnisse unnötig eingeschränkt werden&lt;br /&gt;
* Datenblätter für die meisten Bauteile online&lt;br /&gt;
* Internetpräsenz fällt nachts oft aus (Hinweis auf angebliche geplante Wartungsarbeiten)&lt;br /&gt;
* Sortierfunktion wird bei der Suche ständig zurückgesetzt, im Warenkorb ist überhaupt keine sinnvolle Sortierung möglich&lt;br /&gt;
* Eigenwillige Preispolitik: Einiges sehr günstig, Anderes total überteuert&lt;br /&gt;
&lt;br /&gt;
=== Fibra-Brandt Zweibrücken ===&lt;br /&gt;
Homepage: http://www.fibra-brandt.com&lt;br /&gt;
&lt;br /&gt;
* lagert tausende veraltete und schwer zu findende elektronische Bauteile&lt;br /&gt;
* Halbleiter, IC&#039;s, Transistoren, Spulen und Kondensatoren.&lt;br /&gt;
* Sonderbeschaffung von abgekündigten Halbleitern.&lt;br /&gt;
&lt;br /&gt;
=== Fischer DK2FD ===&lt;br /&gt;
Homepage: http://www.dfe-online.de für das Ingenieurbüro,&lt;br /&gt;
Homepage: http://www.dk2fd.de für Amateurfunkprodukte&lt;br /&gt;
&lt;br /&gt;
* Baugruppen für Hochfrequenzmesstechnik und Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Funkamateur Online-Shop ===&lt;br /&gt;
&lt;br /&gt;
Siehe [[Elektronikversender#Box73]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Futurelec ===&lt;br /&gt;
Homepage: http://www.futurlec.com&lt;br /&gt;
&lt;br /&gt;
* günstiger Versender aus Übersee&lt;br /&gt;
* viele Stamp-Boards&lt;br /&gt;
* LED Matrix-Module&lt;br /&gt;
&lt;br /&gt;
=== Future Electronics ===&lt;br /&gt;
Homepage: http://de.futureelectronics.com&lt;br /&gt;
&lt;br /&gt;
* große Auswahl an Teilen&lt;br /&gt;
* Versand auch an Privatpersonen&lt;br /&gt;
* Preisangaben ohne MwSt.&lt;br /&gt;
* Zahlung nur mit Kreditkarte&lt;br /&gt;
* Versandkosten 7,14€ (Brutto)&lt;br /&gt;
* Versand aus den USA mit FedEx, Lieferzeit meist unter 5AT&lt;br /&gt;
* Verzollung usw. wird von FutureElectronics gemacht, keine Nachzahlungen etc.&lt;br /&gt;
&lt;br /&gt;
=== Geist Electronic-Versand GmbH ===&lt;br /&gt;
Homepage: http://www.geist-electronic.de&lt;br /&gt;
&lt;br /&gt;
* Liefern Bauteile für Elektor-Projekte&lt;br /&gt;
* D-78054 Villingen-Schwenningen&lt;br /&gt;
* Versandkosten: 5.40€&lt;br /&gt;
&lt;br /&gt;
=== Giga-Tech ===&lt;br /&gt;
Homepage: http://www.giga-tech.de&lt;br /&gt;
&lt;br /&gt;
* Spezialitäten für Hochfrequenz / Amateurfunk&lt;br /&gt;
* Scheinbar nur noch Abverkauf, da viele Artikel nicht mehr lieferbar&lt;br /&gt;
* Antworten auf Anfragen und Lieferungen dauern sehr lange&lt;br /&gt;
* 68542 Heddesheim&lt;br /&gt;
&lt;br /&gt;
=== Grummes Elektronik ===&lt;br /&gt;
Homepage: http://www.grummes.de&lt;br /&gt;
&lt;br /&gt;
* Elektronikversender /CNC-Fräsmaschinen / Schrittmotorsteuerungen / Bauteile&lt;br /&gt;
* Homepage nicht aufrufbar (10.12.2011)&lt;br /&gt;
&lt;br /&gt;
=== Glyn (GLYNshop) ===&lt;br /&gt;
Homepage: https://www.glynshop.com/erp/welcome.do&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;B2B Shop&amp;quot; = nicht für Privatkunden&lt;br /&gt;
* Microcontroller, Evaluation Boards, TFT-Displays, LC-Displays, Memory Cards u.a.&lt;br /&gt;
&lt;br /&gt;
=== guloshop.de ===&lt;br /&gt;
Homepage: http://guloshop.de&lt;br /&gt;
&lt;br /&gt;
* kleiner Shop, konzentriert sich auf Standard-AVRs im DIP-Gehäuse, ist dabei aber meist der billigste Versender in Deutschland&lt;br /&gt;
* ATtiny, ATmega, Breakout-Boards, Programmer, Adapterkabel, IC-Fassungen&lt;br /&gt;
* AVR mit geflashtem Arduino-Bootloader&lt;br /&gt;
* äußerst niedrige Preise&lt;br /&gt;
* liefert schnell und zuverlässig, jedoch nur gegen Vorkasse&lt;br /&gt;
* kein Mindestbestellwert, Versandkosten für kleine Bestellungen: 2,40 EUR, darüber 4,40 EUR&lt;br /&gt;
* ansässig in 90489 Nürnberg&lt;br /&gt;
&lt;br /&gt;
=== H-Tronic ===&lt;br /&gt;
Homepage: http://www.h-tronic.eu/index.php&lt;br /&gt;
&lt;br /&gt;
* Online-Shop einer Entwicklungsfirma, in dem neben Baugruppen und Geräten auch einige Bauelemente und Elektronikzubehör angeboten werden&lt;br /&gt;
* kleines Angebot&lt;br /&gt;
&lt;br /&gt;
=== Hallmanns Elektronik ===&lt;br /&gt;
Homepage: http://www.hallmanns.com &amp;lt;br&amp;gt;&lt;br /&gt;
Adresse: Bruno Hallmanns, Weierstraße 41, 52349 Düren&lt;br /&gt;
&lt;br /&gt;
* Elektronikhändler mit Ladenlokal und Versand&lt;br /&gt;
* Ladentypisches Sortiment (Bauteile, Geräte, PC, Funk, Hifi...)&lt;br /&gt;
&lt;br /&gt;
=== Hari Seligenstadt ===&lt;br /&gt;
Homepage: http://www.hari-ham.com&lt;br /&gt;
&lt;br /&gt;
* Bausätze, Ringkerne, Geräte für Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== HBE - Heinz Büchner Elektronik, Messtechnik, med. Elektronik e.K. ===&lt;br /&gt;
Homepage: http://www.hbe-shop.de/katalog/&lt;br /&gt;
&lt;br /&gt;
* Bezeichnet sich als &#039;&#039;[[#Farnell|Farnell]] Fachhändler&#039;&#039;, bei dem nichtgewerbliche Kunden aus dem Farnell-Sortiment bestellen können.&lt;br /&gt;
* Preise für Farnell-Produkte normalerweise Farnell Netto-Preis + MwSt.&lt;br /&gt;
* Mindestbestellwert 25,- € (netto), Mindermengenzuschlag 5,- € (Stand 06/2010)&lt;br /&gt;
* Versandkosten 4,75 € (netto), ab 75,- € (netto) versandkostenfrei (Stand 06/2010)&lt;br /&gt;
&lt;br /&gt;
=== Heho-Elektronik ===&lt;br /&gt;
Homepage: http://www.heho-elektronik.de&lt;br /&gt;
* Halbleiter / Bauteile, Sortimente, Handy - Akkus, VELLEMAN - Bausätze&lt;br /&gt;
* Aktuelles Angebot, Ladegeräte / Akkuladegeräte, Blei - Akkus&lt;br /&gt;
* Spannungswandler, Audio / Video / USB - Kabel, Netzwerk - Kabel&lt;br /&gt;
* 1-2 Arbeitstage für Waren ab Lager&lt;br /&gt;
* Porto + Verpackung pauschal Euro 4,50&lt;br /&gt;
* Mindestbestellwert von &amp;amp;#8364; 10,00&lt;br /&gt;
&lt;br /&gt;
=== Hinkel ===&lt;br /&gt;
Homepage: http://www.hinkel-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Von der Webseite &amp;quot;Unser Angebot richtet sich an Schulen, Behörden, Handel, Handwerk und Industrie.&amp;quot;&lt;br /&gt;
* Batterien&lt;br /&gt;
* Knopfzellen, spezielle KZH, die man sonst lang sucht, findet man hier&lt;br /&gt;
* Mindestbestellwert von 20&amp;amp;#8364;&lt;br /&gt;
* Standardversand innerhalb Deutschlands 5,80&amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== HN Electronic Components GmbH &amp;amp; Co. KG / Netzteilshop ===&lt;br /&gt;
Homepage gewerbliche Kunden: http://www.hn-electronic.de/&lt;br /&gt;
* Netzteile aller Art&lt;br /&gt;
* Es gibt keinen Onlineshop mehr, wahrscheinlich werden Endkunden nicht beliefert&lt;br /&gt;
** Homepage Endkunden: http://www.netzteilshop.com/hnshop.html&lt;br /&gt;
** Lieferung an Endkunden nur per UPS Nachnahme.&lt;br /&gt;
** Mindestbestellmenge für Endkunden 25 €&lt;br /&gt;
&lt;br /&gt;
=== Home-Electronic24 ===&lt;br /&gt;
Homepage: http://www.home-electronic24.de/&lt;br /&gt;
&lt;br /&gt;
=== HW-Electronics ===&lt;br /&gt;
Homepage: http://www.hw-electronics.de &amp;lt;br&amp;gt;&lt;br /&gt;
Homepage EU: http://hw-electronics.eu/&lt;br /&gt;
&lt;br /&gt;
* Tauch- und Sprühätzanlagen&lt;br /&gt;
* Entwicklungsgeräte&lt;br /&gt;
* Belichtungsgeräte, Materialsätze zum Selbstbau von Belichtungsgeräten&lt;br /&gt;
&lt;br /&gt;
=== ID-Elektronik ===&lt;br /&gt;
Homepage: http://www.id-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Amateurfunk-Baugruppen&lt;br /&gt;
&lt;br /&gt;
=== IT-WNS ===&lt;br /&gt;
Homepage: http://www.it-wns.de&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Bauteile, Platinen, Bausätze&amp;quot; insbesondere mit ATMEGA und ENC28J60&lt;br /&gt;
* Bausätze zu Projekten aus dem Forum, z.&amp;amp;nbsp;B. USBprog, ChipBasic, Mikro-Webserver, Transistortester u.v.a.m.&lt;br /&gt;
* Atmega32/644 Experimentiersystem als Bausatz mit vielen Zusatzmodul-Bausätzen&lt;br /&gt;
* SD-Slots, RFID, Bluetooth-Module, AVR Mikrocontroller uvam.&lt;br /&gt;
* Bauelemente, die nicht im Shop angeboten werden, können auf Anfrage (Kontaktformular) beschafft werden &lt;br /&gt;
* günstige Preise und Versandkosten ab 1,90EUR, kein Mindestbestellwert&lt;br /&gt;
* schneller Versand, sofern die Artikel auf Lager sind, versandkostenfreie Nachlieferung&lt;br /&gt;
&lt;br /&gt;
=== Kabelscheune ===&lt;br /&gt;
Homepage: http://www.kabelscheune.de&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Direktversand von Elektromaterial und Multimediaprodukten&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Kelemen ===&lt;br /&gt;
Homepage: http://www.kelemenantennen.de/Kelemen-Shop/&lt;br /&gt;
&lt;br /&gt;
* Messgeräte, Antennen und Zubehör für den Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Kessler ===&lt;br /&gt;
Homepage: http://www.kessler-electronic.de&lt;br /&gt;
&lt;br /&gt;
* im Preis-Leistungsverhältnis mit Reichelt zu vergleichen (sprich: günstig)&lt;br /&gt;
* Sortiment kleiner als Reichelt und mit gewissen Abweichungen (z. B. andere FPGA und RAMs)&lt;br /&gt;
* oft lange Lieferzeiten&lt;br /&gt;
* Versandkosten innerhalb Deutschlands 4€ (Brief), 5€ (DHL-Paket), 10€ (DHL-Express-Paket)&lt;br /&gt;
&lt;br /&gt;
=== Klein-Electronic ===&lt;br /&gt;
Homepage: http://www.klein-electronic.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen zur Video- und 2,4GHz-Sendetechnik&lt;br /&gt;
&lt;br /&gt;
=== Konni-Antennen ===&lt;br /&gt;
Homepage: http://www.konni-antennen.de&lt;br /&gt;
&lt;br /&gt;
* Antennen für TV, Amateurfunk&lt;br /&gt;
* Zubehör, Einzelteile&lt;br /&gt;
* sehr netter kompetenter Service&lt;br /&gt;
&lt;br /&gt;
=== Köditz Nachrichtentechnik ===&lt;br /&gt;
Homepage: http://www.koeditz-nachrichtentechnik.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen und Bauteile für Amateurfunk und TV-Satellitenempfang&lt;br /&gt;
&lt;br /&gt;
=== Kuhne DB6NT ===&lt;br /&gt;
Homepage: http://www.kuhne-electronic.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen und Bausätze für Mikrowellenamateure&lt;br /&gt;
&lt;br /&gt;
=== LEDSEE Electronics ===&lt;br /&gt;
Homepage: http://www.ledsee.com&lt;br /&gt;
&lt;br /&gt;
* LEDs, LCDs, diverses&lt;br /&gt;
* Lieferung direkt aus China, daher sehr günstig und lange Lieferzeiten&lt;br /&gt;
&lt;br /&gt;
=== LED Microtechnics LTD ===&lt;br /&gt;
Homepage: http://www.ledmeile.de&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;LED Shop und Lampentechnik&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== LED-Tech LED-Shop ===&lt;br /&gt;
Homepage: http://www.led-tech.de&lt;br /&gt;
&lt;br /&gt;
* viele verschiedene LEDs zu sehr guten (meist den günstigsten) Preisen&lt;br /&gt;
* vor allem auf High-Power-LEDs spezialisiert&lt;br /&gt;
* viele verschiedene Treiber für High-Power-LEDs&lt;br /&gt;
* kostenloser Versand&lt;br /&gt;
* haben ein eigenes, sehr umfangreiches Forum&lt;br /&gt;
&lt;br /&gt;
=== Lieske Elektronik ===&lt;br /&gt;
Homepage: http://www.lieske-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* liefert nur an Geschäftskunden&lt;br /&gt;
&lt;br /&gt;
=== Lüdeke Elektronic ===&lt;br /&gt;
Homepage: http://www.luedeke-elektronic.de/&lt;br /&gt;
&lt;br /&gt;
* großes Sortiment, bietet unter anderem auch viele selbst entwickelte Bausätze an&lt;br /&gt;
&lt;br /&gt;
=== LUMITRONIX LEDs-Shop ===&lt;br /&gt;
Homepage: http://www.leds.de&lt;br /&gt;
&lt;br /&gt;
* alles rund um LEDs (auch Zubehör und Lektüre)&lt;br /&gt;
* neben Standard-LEDs auch SMD- und SuperFlux-LEDs&lt;br /&gt;
&lt;br /&gt;
=== Marsch Elektronik, M. Schlimper ===&lt;br /&gt;
Homepage: http://www.marsch-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Online Shop für aktive und passive Bauelemente&lt;br /&gt;
* Versandkosten ab Euro 1,60&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* bietet auch Einsteigersortimente und Widerstandsortimente (auch SMD)&lt;br /&gt;
* liefert nur innerhalb Deutschlands&lt;br /&gt;
* nicht gelistete Artikel können angefragt werden und werden meist auch beschafft&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mauritz Communication &amp;amp; Electronics ===&lt;br /&gt;
Homepage: http://www.mauritz-shop.eu&lt;br /&gt;
&lt;br /&gt;
* Online Shop für HF-Stecker und Kabel&lt;br /&gt;
* bietet HF-Stecker/Buchsen und Koaxkabel an&lt;br /&gt;
* große Auswahl, auch exotische Teile&lt;br /&gt;
* Kabelkonfektionierung nach Wunsch&lt;br /&gt;
* vernünftige Preise&lt;br /&gt;
* liefert nach Rücksprache auch weltweit&lt;br /&gt;
* Keine Mindestbestellwert, aber 5 € Aufschlag unter 15 €&lt;br /&gt;
* Versand bis 40 kg pauschal 5,95 € per GLS innerhalb DE&lt;br /&gt;
* schneller Versand&lt;br /&gt;
* Paypal oder Vorkasse&lt;br /&gt;
&lt;br /&gt;
=== Mein-Daarle ===&lt;br /&gt;
Homepage: http://www.mein-st-arnual.de/shop/saarbruecken/artikellisteL.html&lt;br /&gt;
&lt;br /&gt;
* Teileliste eines &amp;quot;Händlers aus Saarbrücken&amp;quot; (wahrscheinl.: Frank Skowronek ESS Elektronik Service), &amp;quot;bis sein Onlineshop ans Netz gehen kann&amp;quot;&lt;br /&gt;
* derzeit (4/2011) kein Onlineshop, Kontakt über Formular&lt;br /&gt;
&lt;br /&gt;
=== Micromaus ===&lt;br /&gt;
Homepage: http://www.micromaus.de&lt;br /&gt;
&lt;br /&gt;
* Sensoren&lt;br /&gt;
* Mikrokontroller&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* 22.7.2012: Totalausverkauf wegen Geschäftsaufgabe, 10% auf alle Artikel&lt;br /&gt;
&lt;br /&gt;
=== Microcontroller-Starterkits ===&lt;br /&gt;
Homepage: http://www.microcontroller-starterkits.de&lt;br /&gt;
&lt;br /&gt;
* 22.7.2012: Seite nicht erreichbar&lt;br /&gt;
* Bauteile: CAN, Ethernet, Mikrokontroller AVR und ARM, Linearregler 1,8V 3,3V 5V in SOT223&lt;br /&gt;
* Leerplatinen, Bausätze&lt;br /&gt;
* günstig&lt;br /&gt;
* Abholung in Hattingen möglich&lt;br /&gt;
* Versandkosten innerhalb Deutschlands ab 2,50&amp;amp;#8364;&lt;br /&gt;
* keine Kreditkartenzahlung möglich&lt;br /&gt;
&lt;br /&gt;
=== Mikrocontroller.net ===&lt;br /&gt;
Homepage: http://shop.mikrocontroller.net&lt;br /&gt;
&lt;br /&gt;
* Starterkits, Development Boards und Zubehör für AVR, AVR32, ARM und MSP430&lt;br /&gt;
&lt;br /&gt;
=== Mira Nürnberg ===&lt;br /&gt;
Homepage: http://www.mira-electronic.de&lt;br /&gt;
&lt;br /&gt;
* SMD-Bauteile, SMD-Sortimentboxen&lt;br /&gt;
* Verkauf und Preisangaben nur für Gewerbetreibende&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- 22.7.2012 Seite nicht erreichbar, Domain bei einem Domaingrabber&lt;br /&gt;
=== Karl Müller EME Messtechnik ===&lt;br /&gt;
Homepage: http://www.eme-hf-technik.de&lt;br /&gt;
&lt;br /&gt;
* Hochfrequenz-Messtechnik, HF-Komponenten&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mouser ===&lt;br /&gt;
Homepage: http://de.mouser.com&lt;br /&gt;
&lt;br /&gt;
* Liefert an Privat&lt;br /&gt;
* Zügige Lieferung mit FedEx aus den USA&lt;br /&gt;
* Keine Halbleiter von Linear, National und Analog&lt;br /&gt;
&lt;br /&gt;
=== MS-Elektronik ===&lt;br /&gt;
Homepage: http://www.ms-elektronik.info&lt;br /&gt;
&lt;br /&gt;
* Liefert an Privat&lt;br /&gt;
* Zügige Lieferung&lt;br /&gt;
* Gute Qualität&lt;br /&gt;
* Viel in Richtung Audio&lt;br /&gt;
* Große Auswahl an Elkos -&amp;gt; kleine Preise&lt;br /&gt;
* kein allzu großes Sortiment&lt;br /&gt;
&lt;br /&gt;
=== Mütron ===&lt;br /&gt;
Homepage: http://www.muetronshop.de&lt;br /&gt;
&lt;br /&gt;
* Keine Privatkunden&lt;br /&gt;
&lt;br /&gt;
=== myAVR Shop ===&lt;br /&gt;
Hompage http://shop.myavr.de&lt;br /&gt;
&lt;br /&gt;
* Kleine Auswahl, aber die angebotene Ware ist sehr preiswert (meist preiswerter als bei Reichelt)&lt;br /&gt;
* Zügige Lieferung (1-2 Werktage)&lt;br /&gt;
* Diverse Zahlungsmöglichkeiten: Rechnung, Vorkasse, Lastschrift, Kreditkarte, PayPal&lt;br /&gt;
* Kein Mindestbestellwert&lt;br /&gt;
* Sehr günstige Versandkosten ab 1,95 Eur&lt;br /&gt;
* Mengenrabatt ab 10 gleichen Artikeln&lt;br /&gt;
&lt;br /&gt;
=== Neuhold-Elektronik ===&lt;br /&gt;
Homepage: http://www.neuhold-elektronik.at &amp;lt;br&amp;gt;&lt;br /&gt;
Shop: http://www.neuhold-elektronik.at/catshop/default.php?language=de&lt;br /&gt;
&lt;br /&gt;
* preiswerte Schnäppchen&lt;br /&gt;
* regelmäßig aktualisierte Angebotsliste herunterladbar&lt;br /&gt;
* Ab 60,- EUR versandkostenfrei in Österreich&lt;br /&gt;
&lt;br /&gt;
=== Octamex ===&lt;br /&gt;
Homepage: http://www.octamex.de&lt;br /&gt;
&lt;br /&gt;
* Leiterplattenchemie (Entwickler, Ätzmittel, CRC-Sprays)&lt;br /&gt;
* Chemisch Zinn&lt;br /&gt;
* Lötstopp-Laminat, Tentingresist, Bestückungsdruck&lt;br /&gt;
* Bungard Basismaterial in 0,5mm 1,0mm 1,5mm Dicke und 18µm, 35µm, 70µm Kupfer&lt;br /&gt;
* Bungard Alucorex für 19&amp;quot; Frontplatten&lt;br /&gt;
* Bungard Cotherm, Alukernbasismaterial&lt;br /&gt;
* Funkmodule 434MHz, 868MHz, 2.4GHz&lt;br /&gt;
* Löttechnik und Zubehör&lt;br /&gt;
* Gehäuse aller Art&lt;br /&gt;
* Messgeräte und Labornetzteile&lt;br /&gt;
* aktive, passive u. mechanische Bauelemente (Widerstände, Kondensatoren, Transistoren, Logik-ICs etc.)&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* Lieferung auch ins Ausland&lt;br /&gt;
* Versandkosten ab 4,50EUR&lt;br /&gt;
* Liefert nur gegen Vorkasse, ausser für Bestandskunden, die schon häufig bestellt haben&lt;br /&gt;
* Zahlung mit EC-Pay oder Kreditkarte nur gegen Aufschlag (bis zu 5%)&lt;br /&gt;
&lt;br /&gt;
=== Online Batterien ===&lt;br /&gt;
Homepage: http://www.online-batterien.de&lt;br /&gt;
&lt;br /&gt;
* Allerlei günstige Batterien &amp;amp; Akkus vieler Marken&lt;br /&gt;
* z.&amp;amp;nbsp;B. &#039;&#039;&#039;40 Stk.&#039;&#039;&#039; DURACELL PLUS LR6 AA 11,59€ (Jan 2010)&lt;br /&gt;
* Beleuchtungsartikel&lt;br /&gt;
* USV&lt;br /&gt;
* Versand ab 3,90€&lt;br /&gt;
&lt;br /&gt;
=== Oppermann ===&lt;br /&gt;
Homepage: http://www.oppermann-electronic.de&lt;br /&gt;
&lt;br /&gt;
* Restposten, auch HF Bauteile&lt;br /&gt;
* auch Privatkunden&lt;br /&gt;
* Lieferung nach üblicher Zeit&lt;br /&gt;
&lt;br /&gt;
=== PCB-Soldering ===&lt;br /&gt;
&lt;br /&gt;
Homepage, Online-Shop: http://www.pcb-soldering.co.uk&lt;br /&gt;
eBay: http://www.allendale-stores.co.uk&lt;br /&gt;
Firmen-Homepage: http://www.allendale-elec.co.uk&lt;br /&gt;
&lt;br /&gt;
* [http://www.aoyue.com/en/products.asp Aoyue] Lötstationen und preiswertes Zubehör (Lötspitzen) für diese. Bei Aoyue-Zubehör bessere Preise (Stand 10/2008) als [[#WilTec_Wildanger_Technik_GmbH|WilTec]]&lt;br /&gt;
* Schnelle Lieferung&lt;br /&gt;
* Dank [http://www.zoll.de/b0_zoll_und_steuern/a0_zoelle/a1_grundlage_zollrecht/b0_zollgebiet/index.html EU Binnenmarkt] nur britische Mehrwertsteuer (VAT), kein Zoll, keine [http://www.zoll.de/b0_zoll_und_steuern/a3_einfuhrumsatzsteuer/index.html Einfuhrumsatzsteuer] fällig.&lt;br /&gt;
* Zwei von drei E-Mails wurden nicht beantwortet&lt;br /&gt;
* Versandart wurde eigenmächtig von &amp;quot;Standard&amp;quot; auf teureres &amp;quot;Signed for&amp;quot; (Einschreiben) geändert&lt;br /&gt;
&lt;br /&gt;
=== Pollin Electronic ===&lt;br /&gt;
Homepage: http://www.pollin.de&lt;br /&gt;
&lt;br /&gt;
* Günstige Restposten aller Art (z.&amp;amp;nbsp;B. &amp;quot;250 g verschiedene ICs&amp;quot; u.dgl.)&lt;br /&gt;
* Produktkategorien:&lt;br /&gt;
** Computer und Zubehör&lt;br /&gt;
** Telefone und Zubehör&lt;br /&gt;
** Antennentechnik&lt;br /&gt;
** HiFi/Car-HiFi/Video/TV&lt;br /&gt;
** Stromversorgung&lt;br /&gt;
** Lichttechnik&lt;br /&gt;
** Messtechnik / Uhren&lt;br /&gt;
** Haustechnik&lt;br /&gt;
** Werkstatt&lt;br /&gt;
** Bauelemente&lt;br /&gt;
** KFZ- und Zweirad&lt;br /&gt;
** Motoren&lt;br /&gt;
** Bausätze&lt;br /&gt;
** Fundgrube&lt;br /&gt;
* Produkte teils schnell ausverkauft &lt;br /&gt;
* Qualität schwankend. Man kann gute Schnäppchen machen aber auch reinfallen. Umtausch ist dann aber problemlos.&lt;br /&gt;
* Es wird öfters von sorgloser Verpackung berichtet, trotz Verpackungspauschale von 0,85 % des Warenwerts (empfindliche und schwere Produkte besser nicht zusammen bestellen). Reklamationen bei Beschädigungen werden freundlich behandelt.&lt;br /&gt;
* Lieferzeit i.d.r. 2-3 Werktage / knappe Woche bei neuer Sonderliste&lt;br /&gt;
* Ladengeschäft in 85104 Pförring&lt;br /&gt;
* Versandkosten  innerhalb Deutschlands 4,50 &amp;amp;#8364; (ab 150&amp;amp;#8364; versandkostenfrei); dazu 0,85 % Verpackungspauschale&lt;br /&gt;
* Zahlung per Nachnahme (+2,50 €), Bankeinzug, &#039;&#039;SOFORT&#039;&#039;-Überweisung oder PayPal&lt;br /&gt;
&lt;br /&gt;
=== proma / Isel ===&lt;br /&gt;
Homepage: http://www.isel.com/en/proma_systro.php&lt;br /&gt;
&lt;br /&gt;
The proMa systro GmbH has completed its business transactions since the 20th February 2009.&lt;br /&gt;
Nachfolger: http://idimod.iselshop.de/&lt;br /&gt;
&amp;lt;s&amp;gt;&lt;br /&gt;
* fotobeschichtete Leiterplatten Platinenfrästechnik&lt;br /&gt;
* Chemikalien für die Platinenherstellung: Ätzmittel, Flussmittel für Lötanlagen, etc.&lt;br /&gt;
* Profilgehäuse, u.a. von Conrad und Reichelt vertrieben&lt;br /&gt;
&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== QRP-project ===&lt;br /&gt;
Homepage: http://www.qrpshop.de/&lt;br /&gt;
&lt;br /&gt;
* Bausätze vor allem einfache Kurzwellen-Funkgeräte&lt;br /&gt;
&lt;br /&gt;
=== Reichelt ===&lt;br /&gt;
Homepage: http://www.reichelt.de&lt;br /&gt;
&lt;br /&gt;
* relativ große Auswahl, aber nicht viele &amp;quot;brandaktuelle&amp;quot; Bauteile&lt;br /&gt;
* wenn man höflich fragt, liefern sie ganz selten auch Bauteile, die nicht im Katalog stehen zu &amp;quot;normalen&amp;quot; Preisen (vorausgesetzt der Hersteller ist im Sortiment), z.&amp;amp;nbsp;B. Xilinx XC2S50, aber meist erhält man die Antwort, dass der Artikel nicht im Sortiment ist, obwohl auf der Homepage unter Service extra ein Punkt angeführt ist: &amp;quot;Ich benötige einen Artikel, der nicht im Programm ist&amp;quot;&lt;br /&gt;
* reagiert aber teilweise auch auf Anregungen, neue Produkte in das Angebot aufzunehmen; siehe dazu auch den Artikel [[Reichelt-Wishlist]]&lt;br /&gt;
* liefert schnell und vollständig; wenn etwas ausnahmsweise nicht verfügbar ist, dann liefern sie es auf eigene Kosten nach, wenn der Artikel in absehbarer Zeit wieder vorrätig ist (selbst wenn er nur 0,20€ wert ist).&lt;br /&gt;
* lässt einen dennoch manchmal warten, wenn ein Artikel nicht lieferbar ist! Daher bei der Bestellung immer darauf hinweisen, dass man auch eine Teillieferung akzeptiert. (Laut Auskunft dauert das länger, besser nach der Inet-Bestellung anrufen und nicht lieferbare Teile aus der Bestellung streichen lassen)&lt;br /&gt;
* Lieferzeiten normalerweise 2 - 4 Arbeitstage&lt;br /&gt;
* niedrige Preise (aber unbedingt Qualität des Artikel checken)&lt;br /&gt;
* Versandkosten 5,60€ (Deutschland); 10€ Österreich; Schweiz 16€; EU 15 - 19€;&lt;br /&gt;
* 10€ Mindestbestellwert für alle Länder&lt;br /&gt;
* auch in die Schweiz sehr guter Service&lt;br /&gt;
* holt sich auch ohne Erlaubnis Bankauskünfte bei großen Bestellungen ein&lt;br /&gt;
&lt;br /&gt;
=== RF Microwave ===&lt;br /&gt;
Homepage: http://http://www.rfmicrowave.it/&lt;br /&gt;
&lt;br /&gt;
* Ausschliesslich HF Bauelemente&lt;br /&gt;
* riesige Auswahl an Bauteilen für den Mikrowellenbereich&lt;br /&gt;
* Bestellung nur nach Registrierung im Shop&lt;br /&gt;
* Schnelle Lieferung&lt;br /&gt;
* Firmensitz in Italien&lt;br /&gt;
* Teilweise englischer Shop&lt;br /&gt;
&lt;br /&gt;
=== RFW Elektronik ===&lt;br /&gt;
Homepage: http://www.rfw-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* HF Bauelemente&lt;br /&gt;
&lt;br /&gt;
=== Ribu ===&lt;br /&gt;
Homepage: http://www.ribu.at&lt;br /&gt;
&lt;br /&gt;
* Sehr guter Elektronikversand in Österreich mit zahlreichen Entwicklungsboards und zahlreichen Elektroniklösungen.&lt;br /&gt;
* Liefert sehr schnell und hat eine ausgezeichnete Beratung. &lt;br /&gt;
* Online-Shop ist sehr übersichtlich und einfach zu bedienen.&lt;br /&gt;
* Lieferstatusanzeige für alle Artikel. Bei Auslaufartikeln ist sogar die noch verfügbare Stückzahl sichbar.&lt;br /&gt;
* Günstige Sonderangebote&lt;br /&gt;
* innerhalb Österreichs 4,90&amp;amp;#8364; Versandkosten, ab 80,- keine Versandkosten&lt;br /&gt;
* ausserhalb Österreichs 13&amp;amp;#8364; Versandkosten, ab 225&amp;amp;#8364; versandkostenfrei&lt;br /&gt;
* liefert auch an Privatkunden&lt;br /&gt;
* Mindestbestellwert innerhalb Österreichs 10&amp;amp;#8364;, ausserhalb 30&amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== Richardson Electronic ===&lt;br /&gt;
Homepage: http://www.richardsonrfpd.com/&lt;br /&gt;
&lt;br /&gt;
* Hochfrequenz-Halbleiter, HF-Röhren,&lt;br /&gt;
&lt;br /&gt;
=== Riedl Elektronik ===&lt;br /&gt;
Homepage: http://www.riedl-electronic.at&lt;br /&gt;
&lt;br /&gt;
* großes Angebot v.a. ICs und Trafos&lt;br /&gt;
* recht günstig&lt;br /&gt;
* Rabatt für Schüler/Student&lt;br /&gt;
* Versand nach AT: 3,95€ bis 1kg, ab 100€ frei Haus&lt;br /&gt;
* Versand AT über 1kg sowie Ausland: Nach Aufwand (wird nicht direkt angezeigt)&lt;br /&gt;
&lt;br /&gt;
=== RLX COMPONENTS s.r.o. ===&lt;br /&gt;
Homepage: http://www.rlx.sk&lt;br /&gt;
&lt;br /&gt;
* Man spricht Deutsch&lt;br /&gt;
* Messgeräte, Mikrocontroller-Boards, Bauelemente&lt;br /&gt;
&lt;br /&gt;
=== RM Computertechnik GmbH ===&lt;br /&gt;
Homepage: http://www.rm-computertechnik.de&lt;br /&gt;
&lt;br /&gt;
* Kerngeschäft ist PC-Technik, aber auch großes Sortiment an Kabeln, Litzen und Steckverbindern&lt;br /&gt;
* handelt auch mit einigen Bauelementen, wie LED&#039;s&lt;br /&gt;
&lt;br /&gt;
=== Robotikhardware===&lt;br /&gt;
Homepage: http://www.robotikhardware.de&lt;br /&gt;
&lt;br /&gt;
* Microcontroller&lt;br /&gt;
* Entwicklungsboards&lt;br /&gt;
* Sensoren&lt;br /&gt;
* Robotik-Zubehör&lt;br /&gt;
* günstige Angebote für Hobbyelektroniker&lt;br /&gt;
* auch einzelne Platinen&lt;br /&gt;
&lt;br /&gt;
=== Robotik-Teile.de===&lt;br /&gt;
Homepage: http://www.robotik-teile.de&lt;br /&gt;
&lt;br /&gt;
* Große Auswahl an Elektronik Produkten &lt;br /&gt;
* Microcontroller, Sensoren, Zubehör, u.v.m.&lt;br /&gt;
* Versandkosten betragen immer 4,90 €&lt;br /&gt;
* Zahlbar ber PayPal, Sofortüberweisung, Vorkasse und Nachnahme&lt;br /&gt;
&lt;br /&gt;
=== Benno Rößle Elektronik ===&lt;br /&gt;
Homepage: http://www.roessle-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Masten, Antennen, Befestigungsmat.,Zubehör, Geräte, Anpassteile, HF-Stecker&lt;br /&gt;
&lt;br /&gt;
=== RS Components ===&lt;br /&gt;
Homepage: http://de.rs-online.com&lt;br /&gt;
&lt;br /&gt;
* lt. AGB nur an gewerbliche Abnehmer und an Studenten. Bei Internetbestellungen wird per Mail nach Belegen gefragt.&lt;br /&gt;
* gute Auswahl insbesondere an &amp;quot;mechanischen Bauteilen&amp;quot;&lt;br /&gt;
* gute Verfügbarkeit&lt;br /&gt;
* sehr schneller Versand, Ware ist in 99% aller Fälle am nächsten Tag da (GP)&lt;br /&gt;
* Preise wurden angepasst, gute Preis/Leistung&lt;br /&gt;
* Preis im Onlineshop sind ohne MwSt angegeben&lt;br /&gt;
* Bei Onlinekauf ab 50 Euro ist der Versand kostenfrei, ohne Mindesbestellwert.&lt;br /&gt;
* Notify-Me Service für Produktabkündigung&lt;br /&gt;
* Auch größere Stückzahlen über Allied möglich&lt;br /&gt;
* Relativ große Auswahl an Sortimenten (Widerstände, Kondensatoren), Einzelteile können teilweise nachgekauft werden&lt;br /&gt;
* Verfügbarkeitsanzeige im Internet ist ziemlich hilfreich&lt;br /&gt;
* Nützliche Tipps zum Thema RoHS&lt;br /&gt;
* Macht anscheinend Abfragen bei SCHUFA &amp;amp; Co. ohne Einverständnis oder Hinweis in den AGB.&lt;br /&gt;
&lt;br /&gt;
=== Sander Elektronik ===&lt;br /&gt;
Homepage: http://www.sander-electronic.de&lt;br /&gt;
&lt;br /&gt;
* beliefert auch Privatkunden, Bankeinzug möglich&lt;br /&gt;
* ähnlich Segor ein Berliner Versender&lt;br /&gt;
* Hier findet man manche [[MSP430]], die es sonst nicht in kleinen Stückzahlen gibt&lt;br /&gt;
* Herr Sander ist sehr kompetent und selbst Autor von Fachartikeln&lt;br /&gt;
* selbst abgekündigte Halbleiter können noch beschafft werden&lt;br /&gt;
* Bezahlung auch mit Kreditkarte möglich&lt;br /&gt;
* Versandkosten innerhalb Deutschlands ab 3,35&amp;amp;#8364;, innerhalb Europas ab 6&amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== Sasco Holz ===&lt;br /&gt;
Homepage: http://www.sasco.de&lt;br /&gt;
&lt;br /&gt;
* Wie Spoerle eine Tochter von Arrow. &lt;br /&gt;
* Distributor für Analog Devices... &lt;br /&gt;
* Liefert wie Spoerle und Arrow in Deutschland nicht an Privatkunden.&lt;br /&gt;
&lt;br /&gt;
=== Sat-Schneider ===&lt;br /&gt;
Homepage: http://www.sat-schneider.de&lt;br /&gt;
* Bauteile, Ersatzteile  Online-Shop&lt;br /&gt;
* Baugruppen zum Empfang des Digitalen Kurzwellenrundfunks DRM&lt;br /&gt;
&lt;br /&gt;
=== Satistronics ===&lt;br /&gt;
Homepage: http://www.satistronics.com&lt;br /&gt;
&lt;br /&gt;
* typischer &amp;quot;China-Versender&amp;quot;, mit allen Vor- und Nachteilen&lt;br /&gt;
* Lieferzeit bei Standardversand sehr lange (etwa 1 Monat nach D), aber schnellere Lieferung gegen Aufpreis möglich&lt;br /&gt;
* tritt auch bei eBay in Erscheinung ([http://stores.ebay.de/satistronicsstore eBay-Shop]), die Preise dort sind in der Regel aber etwas höher als im Online-Shop&lt;br /&gt;
&lt;br /&gt;
=== Otto Schubert GmbH ===&lt;br /&gt;
Homepage: http://www.schubert-gehaeuse.de&lt;br /&gt;
&lt;br /&gt;
* Kein Online-Shop. Bestellungen nur per Telefon, Fax oder E-Mail &lt;br /&gt;
* Weissblechgehäuse, Gerätegehäuse, wetterfeste Gehäuse&lt;br /&gt;
* Drehkondensatoren&lt;br /&gt;
* Sonderanfertigungen&lt;br /&gt;
* ansässig in 90574 Roßtal&lt;br /&gt;
&lt;br /&gt;
=== Schramm-Software ===&lt;br /&gt;
Homepage: http://www.schramm-software.de/bausatz/&lt;br /&gt;
* Online-Shop, bietet Elektronik-Bausätze mit Mikrocontrollern&lt;br /&gt;
* Bausätze als Lehrmaterial geeignet, da ausführliches Begleitheft mitgeliefert wird (Aufbauanleitung, Schaltung, Controllerprogramm, Experimente...)&lt;br /&gt;
* bisher nur ein relativ kleines Sortiment, soll ergänzt werden&lt;br /&gt;
* Versandkosten innerhalb Deutschlands 2,50 &amp;amp;#8364;, innerhalb der EU 3,50 &amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== Schukat elektronic ===&lt;br /&gt;
Homepage: http://www.schukat.de&lt;br /&gt;
&lt;br /&gt;
* liefert nicht an privaten Endverbraucher&lt;br /&gt;
* einfache und passiver Bauteile oft nur in großen Mindeststückzahlen&lt;br /&gt;
* ICs teilweise recht preiswert (vor allem bei mehr als 1 Stück, z.&amp;amp;nbsp;B. auch AVR)&lt;br /&gt;
* LCDs sehr preiswert und auch als Einzelstücke&lt;br /&gt;
* aktuelle Preise und Verfügbarkeit im Internet (aber nur nach Anmeldung -jetzt nicht mehr bei kleinen Stückzahlen), ebenso Bilder von Gehäusefootprints u.dgl.&lt;br /&gt;
* Abholung in Monheim am Rhein nach Vereinbarung möglich&lt;br /&gt;
* Versandkosten innerhalb Deutschlands ab 5&amp;amp;#8364; (bis 10kg!)&lt;br /&gt;
&lt;br /&gt;
=== Schuricht ===&lt;br /&gt;
Homepage: http://www.schuricht.de&lt;br /&gt;
&lt;br /&gt;
* deutscher Ableger der Distrelec- (Elektronik) und Disdata-Gruppe (Computertechnik)&lt;br /&gt;
* Liefert auch an Privatkunden (getrennte AGBs für gewerbliche und Privatkunden, Lieferung an Privat per Nachnahme: Versandkosten ab 6,54€ plus 4,76€ Nachnahmegebühr).&lt;br /&gt;
** Online-Bestellung von Privatkunde scheiterte daran, dass die  Onlineshop-Bestellformulare nur für gewerbliche Kunden ausgelegt sind und der Onlineshop Bestellungen ohne Firmenangaben nicht annimmt oder gar mit einer internen Fehlermeldung quittierte.&lt;br /&gt;
**Online Bestellung mit &amp;quot;Privat&amp;quot; als Firmenangabe funktionierte einwandfrei.&lt;br /&gt;
**Telefonische Bestellung von Privat funktioniert. Nette, freundliche Behandlung am Telefon, kein Callcenter. Versprochener Rückruf erfolgte mit gewünschten Informationen. Neben Nachnahme wurde für einen relativ teuren Artikel persönliche Abholung angeboten. Angegebene Lieferfrist wurde leicht unterschritten.&lt;br /&gt;
* Papierkatalog über 2000 Seiten, durchgehend farbig, nur für Geschäftskunden erhältlich.&lt;br /&gt;
* Ziemlich teuer&lt;br /&gt;
&lt;br /&gt;
=== Schuro Elektronik GmbH ===&lt;br /&gt;
Homepage: http://www.schuro.de&lt;br /&gt;
&lt;br /&gt;
* Elektronische Bauelemente und Bauteile für den Audio- und Lautsprecherbau (Kondensatoren, Spulen u.dgl.)&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* Versandkosten innerhalb Deutschlands gewichtsabhängig ab 5,75&amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== Segor-electronics ===&lt;br /&gt;
Homepage: http://www.segor.de&lt;br /&gt;
&lt;br /&gt;
* Spezialist für Halbleiter, die ansonsten für nicht-gewerbliche Abnehmer nur schwer erhältlich sind (Preise dahingehend &amp;quot;angemessen&amp;quot;)&lt;br /&gt;
* auch Privatkunden gerne gesehen&lt;br /&gt;
* Ladengeschäft in Berlin&lt;br /&gt;
* kein Mindestbestellwert bei Versand innerhalb der EU&lt;br /&gt;
&lt;br /&gt;
=== SE Spezial-Electronic AG ===&lt;br /&gt;
Homepage: http://www.spezial.de&lt;br /&gt;
&lt;br /&gt;
* Distributor&lt;br /&gt;
* Laut AGB auch Verkauf an Privat.&lt;br /&gt;
* Große Verpackungseinheiten/Mindestbestellmengen pro Bauteil&lt;br /&gt;
* Versandkosten pauschal 9,- €  (Deutschland) (Stand 08/2008)&lt;br /&gt;
&lt;br /&gt;
=== Small Control Shop ===&lt;br /&gt;
Homepage: http://www.small-control.de&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Bernd Walter Computer Technology&amp;quot;&lt;br /&gt;
* kleines Lieferprogramm aber ein paar interessante Produkte&lt;br /&gt;
&lt;br /&gt;
=== SMG Diffusion - F1GE ===&lt;br /&gt;
Homepage: http://www.smgdiffusion.com&lt;br /&gt;
( Seite nur französisch )&lt;br /&gt;
&lt;br /&gt;
* Videotechnik, &lt;br /&gt;
* 1,2 GHz / 2,4GHz Module&lt;br /&gt;
* Gebraucht-Messgeräte HP, Tek, Philips  u.a.&lt;br /&gt;
* GHz-Halbleiter&lt;br /&gt;
* Koax-Adapter&lt;br /&gt;
* Antennen&lt;br /&gt;
&lt;br /&gt;
=== Spoerle ===&lt;br /&gt;
Homepage: http://www.spoerle.de&lt;br /&gt;
&lt;br /&gt;
* Früher eine Tochterfirma von Arror. Mittlerweile komplett in Arrow aufgegangen, Webseite leitet auf Arrow um.&lt;br /&gt;
* Aus dem Webshop: &amp;quot;Unser Angebot richtet sich nur an Kaufleute und nicht an Verbraucher.&amp;quot;&lt;br /&gt;
* Wenn es wirklich über Arrow sein muss, dann kann man es als Privatperson bei Arrow Electronics North American Components http://www.arrownac.com/ versuchen, die sich normalerweise nicht weigern ihre Produkte zu verkaufen. Allerdings muss man mit großen Mindestmengen (z.&amp;amp;nbsp;B. BC547 in Schritten von 2000 Stück) und hohen Kosten rechnen.&lt;br /&gt;
:Zu den Kosten gehören zum Beispiel ein mehrfacher Mindermengenzuschlag (&#039;&#039;$10 handling charge will be added to each line item less than $30&#039;&#039;), eine satte &#039;&#039;handling and energy fee of $10.22&#039;&#039; (mehr als 10x zu hoch wie die vergleichbare Gebühr für amerikanische Besteller), hohe Versandkosten (ab $20 nach Deutschland). Dazu kommen die üblichen Kosten für den Import aus dem Ausland (Einfuhrumsatzsteuer, Kreditkartengebühr, ...)&lt;br /&gt;
&lt;br /&gt;
=== SR-Systems ===&lt;br /&gt;
Homepage: http://www.sr-systems.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen für Digital-TV, Sende- und Empfangstechnik&lt;br /&gt;
* DVB-S, DVB-T&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Strixner&amp;amp;Holzinger ===&lt;br /&gt;
Homepage: http://www.sh-halbleiter.de&lt;br /&gt;
&lt;br /&gt;
* Ladengeschäft in München&lt;br /&gt;
* Versand &lt;br /&gt;
* riesiges Angebot an Halbleiter, auch schwer beschaffbare&lt;br /&gt;
* Online-Shop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== TAUTEC-ELECTRONICS ===&lt;br /&gt;
Homepage: http://www.tautec-electronics.de&lt;br /&gt;
&lt;br /&gt;
* Online Shop für aktive elektronische Bauelemente&lt;br /&gt;
* günstige Preise (Vorsicht, Preisangaben enthalten keine Mehrwertsteuer) aber Mindestbestellwert 100 Euro&lt;br /&gt;
* alle Artikel ab Lager lieferbar, daher kurze Wartezeiten&lt;br /&gt;
* weltweiter Versand&lt;br /&gt;
* zahlreiche Mengenrabatte&lt;br /&gt;
* viele Ersatzteile aus dem Audio-, Car-HiFi und TV-Bereich&lt;br /&gt;
&lt;br /&gt;
=== TCB-Versand ===&lt;br /&gt;
Homepage: http://www.tcb-versand.de&lt;br /&gt;
&lt;br /&gt;
* insbesondere für Modellbauer ein sehr interresantes Sortiment&lt;br /&gt;
* Stecker,Kabel etc. recht günstig und kleine Mengen abnehmbar &lt;br /&gt;
* Lieferung normal zwischen 1 und 3 Tage&lt;br /&gt;
* leider nur Online-Shop&lt;br /&gt;
&lt;br /&gt;
=== TecHome.de Online-Shop ===&lt;br /&gt;
Hompage: http://www.techome.de/index.html&lt;br /&gt;
&lt;br /&gt;
=== Tec-Shop (Wolfgang Rompel Elektronik) ===&lt;br /&gt;
Homepage: http://www.tec-shop.de&lt;br /&gt;
&lt;br /&gt;
* Kleines, aber ausgesuchtes Sortiment&lt;br /&gt;
* Interessantes Angebot an Sensoren&lt;br /&gt;
&lt;br /&gt;
=== Technik-Welt / Industrieshop.at ===&lt;br /&gt;
Homepage: http://www.industrieshop.at&lt;br /&gt;
&lt;br /&gt;
* Laut Homepage richtet man sich &amp;quot;an den industriellen Kunden&amp;quot;. Laut AGB sieht man das jedoch nicht so eng, Zitat:&lt;br /&gt;
:: &#039;&#039;TW schließt online Verträge nur mit Kunden ab, die natürliche oder juristischen Personen sind, die ihren Wohnsitz oder Sitz in Österreich, einem Mitgliedsstaat der Europäischen Union (EU25) oder der Schweiz haben.&#039;&#039;&lt;br /&gt;
* [[#Farnell|Farnell]] Teile&lt;br /&gt;
* In Österreich&lt;br /&gt;
* Schnelle Lieferung (2 Tage)&lt;br /&gt;
&lt;br /&gt;
=== Teske electronics ===&lt;br /&gt;
Homepage: http://www.teske-electronics.de&lt;br /&gt;
&lt;br /&gt;
* Noch relativ übersichtliches Produktsortiment (Dez. 2012) aber schon einige interessante Teile&lt;br /&gt;
* Bisher überwiegend SMD Bauteile&lt;br /&gt;
* Kein Mindestbestellwert&lt;br /&gt;
* Versandkosten ab 2,85€&lt;br /&gt;
* Lieferung nur innerhalb Deutschlands&lt;br /&gt;
* Wunschliste für neue Produkte&lt;br /&gt;
* Beschaffung von Bauteilen möglich, die nicht im Shop angeboten werden&lt;br /&gt;
* Zahlung per Vorkasse, PayPal, Nachnahme oder Rechnung (für Stammkunden) möglich.&lt;br /&gt;
&lt;br /&gt;
=== Thinkembedded.ch ===&lt;br /&gt;
Homepage: http://www.thinkembedded.ch&lt;br /&gt;
&lt;br /&gt;
* in der Schweiz (auch Abholung möglich), Versand CH ab SFr 12.- (bis 5kg)&lt;br /&gt;
* keine Mindestbestellmenge, Bezahlung: Barbezahlung, Rechnung, PayPal &lt;br /&gt;
* Demoboarde von div. Herstellern (Olimex, ST, ARM-Keil, ETT, Conitex)&lt;br /&gt;
* Demoboarde mit ARM (Cortex M)uC von ST, NXP, Energy Micro&lt;br /&gt;
* Demoboarde mit ARM Cortex A uC von Olimex&lt;br /&gt;
* Keil Debugger/Programmer Ulink ME/2/Pro&lt;br /&gt;
* MSP4300 Demoboard&lt;br /&gt;
* PIC Demoboarde und Programmer&lt;br /&gt;
* AVR Demoboarde und Programmer&lt;br /&gt;
* Messgeräte (BMC Messsysteme, Intronix LogicPort)&lt;br /&gt;
* Learning Kits&lt;br /&gt;
* Mehrsprachig (E, D, F), Preise in SFR / Euro&lt;br /&gt;
&lt;br /&gt;
=== TIGAL KG ===&lt;br /&gt;
Homepage: http://www.tigal.com&lt;br /&gt;
&lt;br /&gt;
* Boards und Tools für Embedded-Elektronik&lt;br /&gt;
* In Österreich &lt;br /&gt;
* Versandkosten ab € 7,00 in Österreich, ab € 10,00 nach Deutschland.&lt;br /&gt;
* Preisangaben ohne MWSt. Für Privatkunden kommen 20% österreichische Mehrwertsteuer hinzu.&lt;br /&gt;
* U.a. ZeroLogic Logik-Analysatoren.&lt;br /&gt;
&lt;br /&gt;
=== TME (Transfer Multisort Elektronik) ===&lt;br /&gt;
Homepage: [http://www.tme.eu/de]&lt;br /&gt;
&lt;br /&gt;
* Firmensitz in Łódź, Polen. Dort nimmt man seit dem 4.9.2012 [http://www.tme.eu/de/pages/News:tme-germany-gmbh-beginnt-eine-selbstandige-tatigkeit.html nach eigener Aussage] keine Bestellungen aus Deutschland mehr an und verweist auf die selbstständige deutsche Tochtergesellschaft. Wo/wie man bei dieser Tochtergesellschaft Bestellungen aufgeben kann ist unklar.&lt;br /&gt;
* Ebenso ist unklar, ob die Praxis eines &amp;quot;Strafaufschlags&amp;quot; der polnischen Mutter von 17.6% auf den Bruttopreis für Privatkunden von der deutschen Tochter weitergeführt wird.&lt;br /&gt;
&lt;br /&gt;
=== Trade-Shop / AIR Electronics GmbH ===&lt;br /&gt;
Homepage: http://www.trade-shop.de&lt;br /&gt;
&lt;br /&gt;
* Trotz knackiger Sprüche auf der englischen Version der Webseite (&amp;quot;Electronic Components Superstore&amp;quot;) eher kleines Angebot elektronischer Bauteile&lt;br /&gt;
* 20 Euro Mindestbestellmenge (Stand Februar 2008)&lt;br /&gt;
* ab 6,90 Euro Versandkosten (Deutschland, bis 1kg)  (Stand Februar 2008)&lt;br /&gt;
&lt;br /&gt;
=== Trenkenchu &amp;amp; Stadler GbR ===&lt;br /&gt;
Homepage: http://www.ts-audio.de&lt;br /&gt;
&lt;br /&gt;
* die meisten Artikel sind deutlich teurer als der Marktpreis, es sind jedoch auch Schnäppchen dabei, z.B. HDMI-Kabel&lt;br /&gt;
&lt;br /&gt;
=== TV-Ersatzteile ===&lt;br /&gt;
Homepage: http://www.tversatzteile.de&lt;br /&gt;
&lt;br /&gt;
* TV-, Audio-, Video-Ersatzteile, Aktive / Passive Bauteile&lt;br /&gt;
* Fernbedienungen Haushaltstechnik&lt;br /&gt;
&lt;br /&gt;
=== UKW-Berichte ===&lt;br /&gt;
Homepage: http://www.ukw-berichte.de&lt;br /&gt;
&lt;br /&gt;
* Antennen, Bauteile, Bausätze, Literatur für Amateurfunk&lt;br /&gt;
* ansässig in 91081 Baiersdorf&lt;br /&gt;
&lt;br /&gt;
=== Voelkner ===&lt;br /&gt;
Homepage: Kein Link, entsprechend der Vorgabe des Betreibers der Voelkner Webseite im Impressum:&lt;br /&gt;
&amp;lt;i&amp;gt;&amp;lt;blockquote&amp;gt;voelkner - direkt günstiger&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
wird produziert und betreut von&amp;lt;br/&amp;gt;&lt;br /&gt;
Re-In Retail International GmbH &amp;lt;br/&amp;gt;&lt;br /&gt;
...&amp;lt;br/&amp;gt;&lt;br /&gt;
Eine Verlinkung auf die Website der Firma Re-In Retail International GmbH bedarf einer schriftlichen Genehmigung. &amp;lt;/blockquote&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Großer Teil des Conrad-Programms, identische Nummern, identische Aufkleber auf der Ware, Preise weitgehend identisch oder nur ein paar Cent abweichend, bei bestimmten Artikelgruppen (z.B. Werkzeug) aber auch bis zu 25% billiger&lt;br /&gt;
* Versandkosten Deutschland: 4,95€; ab 25€ Warenwert und Sofortüberweisung.de versandkostenfrei / Versandkosten-Flatrate für 15€ pro Jahr&lt;br /&gt;
* Versandkosten EU: 9,95€&lt;br /&gt;
* Möglichkeit der Versandkostenflatrate (D): Einmalig 14,95€ / gültig für ein Jahr&lt;br /&gt;
* Legt jeder Bestellung gleich wieder einen Gutschein über 5€ bei MBW 25€ bei (Flat nur bei häufigen, kleinen Bestellungen sinnvoll); außerdem kommt etwa alle 2-3 Monate selbiger Gutschein + versandkostenfreie Lieferung per Mail, ebenfalls MBW 25€&lt;br /&gt;
* Verpackungsqualität wechselnd, mal brauchbar, mal eher Pollin-Niveau. Selbst kleine Bestellungen, die gefahrlos per Brief/Großbrief verschickt werden könnten werden in einem großen Paket versendet.&lt;br /&gt;
&lt;br /&gt;
=== VOTI Webshop ===&lt;br /&gt;
Homepage: http://www.voti.nl/shop/catalog.html&lt;br /&gt;
&lt;br /&gt;
* relativ kleines Lieferprogramm&lt;br /&gt;
* einige interessante Restposten (Surplus)&lt;br /&gt;
&amp;lt;!-- nicht mehr: * verkauft auch VID/PID-Paare für USB-Applikationen --&amp;gt;&lt;br /&gt;
* Sitz in Amersfoort, Niederlande&lt;br /&gt;
&lt;br /&gt;
=== Walter elektronik ===&lt;br /&gt;
Homepage: http://www.walter-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Bauteile, Röhren&lt;br /&gt;
&lt;br /&gt;
=== Waschbär Soft 2010 ===&lt;br /&gt;
Homepage: http://www.xn--waschbr-soft-2010-vqb.de&lt;br /&gt;
&lt;br /&gt;
* Onlineversandhaus für Unterhaltungselektronik, &amp;quot;Haushaltselektronik&amp;quot;, Computer und -zubehör&lt;br /&gt;
* keine elektronischen Bauteile&lt;br /&gt;
&lt;br /&gt;
=== Watterott electronic GmbH===&lt;br /&gt;
Homepage: http://www.watterott.com&lt;br /&gt;
&lt;br /&gt;
* Distributor für Adafruit, Arduino, BeagleBoard/PandaBoard, Embedded Artists, GHI, Olimex, Parallax, Pololu, Seeed Studio, Solarbotics, SparkFun... &lt;br /&gt;
* Entwicklungskits von Atmel, Cypress, Freescale, Microchip, NXP, STM, TI...&lt;br /&gt;
* Spezialbauteile von Davicom, FTDI, VLSI, WIZnet...&lt;br /&gt;
* Bungard Basismaterial + Chemie&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* Zahlung: Vorkasse, Sofortüberweisung, PayPal, Nachnahme, Kreditkarte (Visa/Mastercard), Rechnung (nur gewerbliche Kunden)&lt;br /&gt;
* Versandkosten Dtl. (DHL): &lt;br /&gt;
** bis  50 EUR Warenwert: 3,50 Euro&lt;br /&gt;
** bis 100 EUR Warenwert: 3,00 Euro&lt;br /&gt;
** bis 150 EUR Warenwert: 2,00 Euro&lt;br /&gt;
** ab  150 EUR Warenwert: versandkostenfrei&lt;br /&gt;
* Versandkosten EU (DHL): &lt;br /&gt;
** bis 150 EUR Warenwert: 10,00 Euro&lt;br /&gt;
** bis 250 EUR Warenwert:  8,90 Euro&lt;br /&gt;
** bis 500 EUR Warenwert:  5,95 Euro&lt;br /&gt;
** ab  500 EUR Warenwert:  versandkostenfrei&lt;br /&gt;
* Schneller, entgegenkommender Service&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
September 2012 sind bei Westfalia gerade mal zehn Bauteile unter &amp;quot;Elektronische Bauteile&amp;quot; gelistet&lt;br /&gt;
 &lt;br /&gt;
=== Westfalia ===&lt;br /&gt;
Homepage Deutschland: http://www.westfalia.de&lt;br /&gt;
Homepage Österreich: http://www.westfalia-versand.at&lt;br /&gt;
&lt;br /&gt;
* Vor 85 Jahren in Hagen, Westfalen gegründet&lt;br /&gt;
* Elektronik nur ein kleiner Teil des Angebotes. Eher insgesamt Haushalts-, Werkstätten-, Agrar- und Gartenbedarf&lt;br /&gt;
* Elektroniksortiment stark schwankend. Momentan (Juni 2008) wenig Auswahl.&lt;br /&gt;
* Mindestbestellwert 18 €, bei Neukundenbestellungen mit Prämienanforderungen (wenig wertiges Geschenk) sogar 50 €.&lt;br /&gt;
* 4,95&amp;amp;#8364; Versandkosten, ab 150&amp;amp;#8364; Bestellwert versandkostenfrei&lt;br /&gt;
* Transportversicherung wird zusätzlich mit einem Zuschlag von 0,8% des Warenwertes berechnet.&lt;br /&gt;
* Einmalige Bestellung führte zu jahrelanger Zusendung von Werbung für Westfalia-Angeboten mit Gewinnspielen (Glücksnummern, Rubbellose, Glücksschlüssel, etc.)&lt;br /&gt;
* Verpackung ähnlich &amp;quot;sorgfältig&amp;quot; wie bei [[#Pollin_Electronic|Pollin Electronic]]. Übergroße Kartons, wenig Verpackungsmaterial, schweres Teil (Labornetzgerät) flog lose im Karton herum und zertrümmerte andere Ware.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== WilTec Wildanger Technik GmbH ===&lt;br /&gt;
Homepage: http://shop.wiltec.info&lt;br /&gt;
&lt;br /&gt;
* Aoyue Lötgeräte (Heißluft, Löten, Entlöten), Netzteile, Werkzeuge&lt;br /&gt;
* Aoyue Zubehör (Lötspitzen, Heißluftdüsen), Ersatzteile&lt;br /&gt;
* Andere, nicht Elektronik-Angebote, wie KFZ-Tuningteile&lt;br /&gt;
* Versand. Bei Voranmeldung auch Lagerverkauf.&lt;br /&gt;
&lt;br /&gt;
=== Wüstens frag-jan-zuerst ===&lt;br /&gt;
Homepage: http://www.die-wuestens.de/dindex.htm&lt;br /&gt;
&lt;br /&gt;
* Röhrentechnik&lt;br /&gt;
* Hochspannungs-Spezialteile&lt;br /&gt;
&lt;br /&gt;
=== WIMO ===&lt;br /&gt;
Homepage: http://www.wimo.de&lt;br /&gt;
&lt;br /&gt;
* Große Auswahl an Amateurfunktechnik&lt;br /&gt;
&lt;br /&gt;
=== Zech DG0VE ===&lt;br /&gt;
Homepage: http://www.dg0ve.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen für Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Diverse ===&lt;br /&gt;
* http://www.chip-flip.com - Europäisches Bauelementesuchsystem, franchised Lieferantensuche, Datenblätter und viele nützliche Informationen&lt;br /&gt;
* http://www.ecomponents-store.com/ Elektronische Bauelemente kaufen - Hier finden Sie eine große Auswahl an elektronischen und elektromechanischen Bauelementen von über 40 Herstellern.&lt;br /&gt;
* http://www.franchised-distributors.eu/ - Finden Sie Vertragsdistributoren von über 800 Halbleiterherstellern für elektronische und elektromechanische Bauelemente.&lt;br /&gt;
&lt;br /&gt;
TODO: elektronik-fundgrube&lt;br /&gt;
&lt;br /&gt;
==Ebay-Shops==&lt;br /&gt;
&lt;br /&gt;
===Ego-China===&lt;br /&gt;
http://stores.ebay.de/Ego-China-Electronics   TFTs und LCDs &amp;lt;br /&amp;gt; Versand aus China (2-3 Wochen)&lt;br /&gt;
&lt;br /&gt;
===Sure-Electronics===&lt;br /&gt;
http://stores.ebay.de/Sure-Electronics   Highpower LEDs und Verstärker &amp;lt;br /&amp;gt;&lt;br /&gt;
Hat auch einen eigenen Shop: http://www.sureelectronics.net/ &amp;lt;br /&amp;gt;&lt;br /&gt;
Versand aus China&lt;br /&gt;
&lt;br /&gt;
===Ether-Deal===&lt;br /&gt;
http://stores.ebay.de/ether-deal   Unter sonstiges viele versch. Elektronik-teile &amp;lt;br /&amp;gt; Versand aus China&lt;br /&gt;
&lt;br /&gt;
===NooElec===&lt;br /&gt;
http://stores.ebay.de/NooElec USB-AVR Boards (mega32u2) und rgbled-matrizen &amp;lt;br /&amp;gt; Versand aus Kanada&lt;br /&gt;
&lt;br /&gt;
==Messgeräte ==&lt;br /&gt;
=== Neue Messgeräte ===&lt;br /&gt;
&lt;br /&gt;
Viele der oben genannten Elektronikversender verkaufen auch Messgeräte. Darüber hinaus gibt es diverse Versender, die sich hauptsächlich oder ausschließlich auf Messgeräte spezialisiert haben. Allerdings verkaufen viele davon nicht an Privat.&lt;br /&gt;
&lt;br /&gt;
==== CalPlus GmbH ====&lt;br /&gt;
Homepage: http://www.calplus.de &amp;lt;br /&amp;gt;&lt;br /&gt;
Shop: http://www.scopeshop.de&lt;br /&gt;
&lt;br /&gt;
==== Cosinus ComputerMesstechnik ====&lt;br /&gt;
Homepage: http://www.cosinus.de&lt;br /&gt;
&lt;br /&gt;
* Nicht an Privat&lt;br /&gt;
&lt;br /&gt;
==== dataTec ====&lt;br /&gt;
Homepage: http://www.datatec.de&lt;br /&gt;
&lt;br /&gt;
* Große Auswahl&lt;br /&gt;
* &amp;lt;s&amp;gt;(Nicht an Privat)&amp;lt;/s&amp;gt; Bestellung von Privat problemlos möglich, Privatpersonen werden laut ABG per Vorkasse beliefert&lt;br /&gt;
* Studenten bekommen Rabatt, je nach dem, was bestellt wird&lt;br /&gt;
* Umständlicher Bestellvorgang, seitens DataTec teilweise auf dem Postweg -&amp;gt; Es dauert teil sehr lange bis die Ware ankommt&lt;br /&gt;
* Sehr freundlicher und kompetenter Service, per eMail als auch telefonisch&lt;br /&gt;
&lt;br /&gt;
==== Elektronik-Kontor Messtechnik GmbH ====&lt;br /&gt;
Homepage: http://www.ekomess.de&lt;br /&gt;
&lt;br /&gt;
==== Meilhaus Electronic GmbH ====&lt;br /&gt;
Homepage: http://www.meilhaus.de&lt;br /&gt;
&lt;br /&gt;
* Diverse Markenhersteller&lt;br /&gt;
* Eigenmarken&lt;br /&gt;
&lt;br /&gt;
==== PinSonne-Elektronik ====&lt;br /&gt;
Homepage: http://www.pinsonne-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Onlineshop&lt;br /&gt;
* Sehr kleines Sortiment&lt;br /&gt;
* UNI-T, RIGOL und andere asiatische Firmen&lt;br /&gt;
&lt;br /&gt;
==== PK elektronik Poppe GmbH ====&lt;br /&gt;
Homepage: http://www.pk-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* U.a. Fluke Distributor.&lt;br /&gt;
&lt;br /&gt;
====Präzitronic Hennig / Messgeräte Chemnitz====&lt;br /&gt;
Homepage: http://www.messgeraete-chemnitz.de&lt;br /&gt;
&lt;br /&gt;
* Verkauft explizit auch an Privat.&lt;br /&gt;
* Owon&lt;br /&gt;
* Selbst übersetzte deutsche Owon-Handbücher&lt;br /&gt;
* Fluke&lt;br /&gt;
* Extech&lt;br /&gt;
* Zusätzlich kleines Angebot an Gebrauchtgeräten&lt;br /&gt;
&lt;br /&gt;
==== ScopeShop Hamburg ====&lt;br /&gt;
&lt;br /&gt;
* Von CalPlus übernommen, siehe [[#CalPlus_GmbH|CalPlus]]&lt;br /&gt;
&lt;br /&gt;
==== SI Scientific Instruments GmbH ====&lt;br /&gt;
Homepage: http://www.si-scientific.de (Onlineshop) &amp;lt;br /&amp;gt;&lt;br /&gt;
Homepage: http://www.si-gmbh.de (komplettes Programm)&lt;br /&gt;
&lt;br /&gt;
* Onlineshop auf si-scientific.de&lt;br /&gt;
* Akzeptiert PayPal&lt;br /&gt;
 &lt;br /&gt;
==== SKY Messtechnik GmbH ====&lt;br /&gt;
Homepage: http://www.sky-messtechnik.de&lt;br /&gt;
&lt;br /&gt;
* Kein Onlineshop (E-Mail oder Telefon)&lt;br /&gt;
&lt;br /&gt;
==== TESTEC ====&lt;br /&gt;
Homepage: http://www.testec.info&lt;br /&gt;
&lt;br /&gt;
* Tastköpfe-Hersteller&lt;br /&gt;
* Hameg Vertriebspartner&lt;br /&gt;
* B+K Precision Generalimporteur&lt;br /&gt;
&lt;br /&gt;
==== Zeitech ====&lt;br /&gt;
Homepage: http://www.zeitech.de/shop/&lt;br /&gt;
&lt;br /&gt;
* Diverses (Rigol, Owon, etc.)&lt;br /&gt;
&lt;br /&gt;
=== Gebrauchte Messgeräte ===&lt;br /&gt;
&lt;br /&gt;
Dieser Abschnitt enthält Anbieter bei denen gebrauchte Messgeräte erhältlich sind.&lt;br /&gt;
&lt;br /&gt;
==== Astro Electronic ====&lt;br /&gt;
Homepage: http://www.astro-electronic.de&lt;br /&gt;
&lt;br /&gt;
==== HTB-Elektronik ====&lt;br /&gt;
Homepage: http://www.htb-elektronik.com&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
&lt;br /&gt;
==== IX Instrumex ====&lt;br /&gt;
Homepage: http://www.instrumex.de/index.cgi?User:LANGUAGE=de&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
&lt;br /&gt;
==== Christoph Lüders MessTechnik ====&lt;br /&gt;
Homepage: http://www.CLMT.de &amp;lt;br&amp;gt;&lt;br /&gt;
Online-Shop: http://www.shop-016.de/shop-CLMT.html &amp;lt;br&amp;gt;&lt;br /&gt;
eBay: http://myworld.ebay.de/c_h_r/&lt;br /&gt;
&lt;br /&gt;
* Hat 2010 die Restbestände von Förtig übernommen&lt;br /&gt;
&lt;br /&gt;
==== mbmt Messtechnik ====&lt;br /&gt;
Homepage: http://www.mbmt.com&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
* Verkauf nur an Gewerbetreibende&lt;br /&gt;
&lt;br /&gt;
==== Rosenkranz Elektronik ====&lt;br /&gt;
Homepage: http://www.rosenkranz-elektronik.de&amp;lt;br&amp;gt;&lt;br /&gt;
eBay Shop: http://stores.ebay.de/Rosenkranz-Elektronik-GmbH-Shop&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
* Auch auf eBay zu finden&lt;br /&gt;
&lt;br /&gt;
==== Helmut-Singer-Elektronik ====&lt;br /&gt;
Homepage: http://www.helmut-singer.de&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
* Verkauf auch an Privat&lt;br /&gt;
* An den meisten Samstagen im Jahr auch Lagerverkauf, sonst Versand&lt;br /&gt;
&lt;br /&gt;
==== Sphere ====&lt;br /&gt;
Homepage: http://www.sphere.bc.ca&amp;lt;br&amp;gt;&lt;br /&gt;
Messgeräte und Ersatzteile: http://www.sphere.bc.ca/test/index.html&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
* Ersatzteile&lt;br /&gt;
** Besonders bekannt für Tektronix-Ersatzteile&lt;br /&gt;
&lt;br /&gt;
==== Tektronix TekSelect ====&lt;br /&gt;
Homepage: http://www.tek.com/Measurement/tekselect/&lt;br /&gt;
&lt;br /&gt;
* Tektronix verkauft selber gebrauchte und überarbeitete Tektronix-Messgeräte unter dem Label &#039;&#039;TekSelect&#039;&#039;.&lt;br /&gt;
* Original Tektronix-Garantie&lt;br /&gt;
* Der Bestellvorgang nervt, man muss Kontaktaufnahme durch einen &amp;quot;Representative&amp;quot; erbeten.&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [[Platinenhersteller]]&lt;br /&gt;
* [[Lokale Elektroniklieferanten]]&lt;br /&gt;
* [[Eisenwarenversender]]&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://www.xs4all.nl/~ganswijk/chipdir/ Suche nach integrierten Schaltkreisen&lt;br /&gt;
* http://www.alldatasheet.com                Datenblätter&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Lieferanten]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR-GCC-Tutorial&amp;diff=69221</id>
		<title>AVR-GCC-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR-GCC-Tutorial&amp;diff=69221"/>
		<updated>2012-11-18T14:10:15Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* EEPROM */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Voraussetzungen =&lt;br /&gt;
&lt;br /&gt;
Vorausgesetzt werden Grundkenntnisse der Programmiersprache C. Diese Kenntnisse kann man sich online erarbeiten, z. B. mit dem [http://www.schellong.de/c.htm C Tutorial von Helmut Schellong] ([[C|Liste von C-Tutorials]]). Nicht erforderlich sind Vorkenntnisse in der Programmierung von Mikrocontrollern, weder in Assembler noch in einer anderen Sprache.&lt;br /&gt;
&lt;br /&gt;
= Vorwort =&lt;br /&gt;
&lt;br /&gt;
Dieses Tutorial soll den Einstieg in die Programmierung von Atmel [[AVR]]-Mikrocontrollern in der Programmiersprache [[C]] mit dem freien C-Compiler [[AVR-GCC]] aus der [http://gcc.gnu.org/ GNU Compiler Collection] erleichtern.&lt;br /&gt;
&lt;br /&gt;
In diesem Text wird häufig auf die Standardbibliothek avr-libc verwiesen, für die es eine [http://www.nongnu.org/avr-libc/user-manual/index.html Online-Dokumentation] gibt, in der sich auch viele nützliche Informationen zum Compiler und zur Programmierung von AVR Controllern finden (beim Paket WinAVR gehört die avr-libc Dokumentation zum Lieferumfang und wird mitinstalliert).&lt;br /&gt;
&lt;br /&gt;
Der Compiler und die Standardbibliothek avr-libc werden stetig weiterentwickelt. Einige Unterschiede, die sich im Verlauf der Entwicklung ergeben haben, werden im Haupttext und Anhang zwar erläutert, Anfängern sei jedoch empfohlen, die aktuellen Versionen zu nutzen (für MS-Windows: aktuelle Version des [[WinAVR]]-Pakets; für Linux: siehe Artikel [[AVR und Linux]]).&lt;br /&gt;
&lt;br /&gt;
Das ursprüngliche Tutorial stammt von Christian Schifferle, viele neue Abschnitte und aktuelle Anpassungen von Martin Thomas.&lt;br /&gt;
&lt;br /&gt;
Dieses Tutorial ist in PDF-Form hier erhältlich (nicht immer auf aktuellem Stand):&lt;br /&gt;
[[Media:AVR-GCC-Tutorial.pdf]]&lt;br /&gt;
&lt;br /&gt;
== Weiterführende Kapitel ==&lt;br /&gt;
&lt;br /&gt;
Um dieses riesige Tutorial etwas überschaubarer zu gestalten, wurden einige Kapitel ausgelagert, die nicht unmittelbar mit den Grundlagen von avr-gcc in Verbindung stehen. All diese Seiten gehören zur [[:Kategorie:avr-gcc Tutorial]].&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Der UART|Der UART]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Analoge Ein- und Ausgabe|Analoge Ein- und Ausgabe (ADC)]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Die Timer und Zähler des AVR|Die Timer und Zähler des AVR]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/LCD-Ansteuerung|LCD-Ansteuerung]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Der Watchdog|Der Watchdog]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Exkurs Makefiles|Exkurs Makefiles]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Alte Quellen|Alte Quellen anpassen]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Assembler und Inline-Assembler|Assembler und Inline-Assembler]]&lt;br /&gt;
&lt;br /&gt;
= Benötigte Werkzeuge =&lt;br /&gt;
&lt;br /&gt;
Um eigene Programme für AVRs mittels avr-gcc/avr-libc zu erstellen und zu testen, wird folgende Hard- und Software benötigt:&lt;br /&gt;
&lt;br /&gt;
* Platine oder Versuchsaufbau für die Aufnahme eines AVR Controllers, der vom avr-gcc Compiler unterstützt wird (siehe [http://www.nongnu.org/avr-libc/user-manual/index.html#supported_devices Dokumentation der avr-libc] für unterstützte Typen). Dieses Testboard kann durchaus auch selbst gelötet oder auf einem Steckbrett aufgebaut werden. Einige Registerbeschreibungen dieses Tutorials beziehen sich auf den inzwischen veralteten AT90S2313. Der weitaus größte Teil des Textes ist aber für alle Controller der AVR-Familie gültig. Brauchbare Testplattformen sind auch das [[STK500]] und der [[AVR Butterfly]] von Atmel. Weitere Infos findet man in den Artikeln [[AVR#Starterkits|AVR Starterkits]] und [[AVR-Tutorial: Equipment]].&lt;br /&gt;
&lt;br /&gt;
* Der avr-gcc Compiler und die avr-libc. Kostenlos erhältlich für nahezu alle Plattformen und Betriebssysteme. Für MS-Windows im Paket [[WinAVR]]; für Unix/Linux siehe auch Hinweise im Artikel [[AVR-GCC]] und im Artikel [[AVR und Linux]].&lt;br /&gt;
&lt;br /&gt;
* Programmiersoftware und -[[AVR In System Programmer |hardware]] z. B. PonyProg (siehe auch: [[Pony-Prog Tutorial]]) oder [[AVRDUDE]] mit [[STK200]]-Dongle oder die von Atmel verfügbare Hard- und Software ([[STK500]], Atmel AVRISP, [[AVR-Studio]]).&lt;br /&gt;
&lt;br /&gt;
* Nicht unbedingt erforderlich, aber zur Simulation und zum Debuggen unter MS-Windows recht nützlich: [[AVR-Studio]] (siehe Artikel [[AVR-GCC-Tutorial/Exkurs_Makefiles|Exkurs: Makefiles]]).&lt;br /&gt;
&lt;br /&gt;
* Wer unter Windows und Linux gleichermassen entwickeln will, der sollte sich die [http://www.eclipse.org/ IDE Eclipse for C/C++ Developers] und das [http://avr-eclipse.sourceforge.net/wiki/index.php/The_AVR_Eclipse_Plugin AVR-Eclipse Plugin ] ansehen, beide sind unter Windows und Linux einfach zu installieren. Hier gibt es auch einen [[AVR_Eclipse|Artikel AVR Eclipse]] in dieser Wiki. Ebenfalls unter Linux und Windows verfügbar ist die Entwicklungsumgebung [http://www.codeblocks.org/ Code::Blocks] (aktuelle, stabile Versionen sind als Nightly Builds regelmäßig im [http://forums.codeblocks.org/ Forum] verfügbar). Innerhalb dieser Entwicklungsumgebung können ohne die Installation zusätzlicher Plugins &amp;quot;AVR-Projekte&amp;quot; angelegt werden. Für Linux gibt es auch noch das [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=25220&amp;amp;postdays=0&amp;amp;postorder=asc&amp;amp;start=0 KontrollerLab].&lt;br /&gt;
&lt;br /&gt;
= Was tun, wenn&#039;s nicht klappt? =&lt;br /&gt;
&lt;br /&gt;
* Herausfinden, ob es tatsächlich ein avr(-gcc) spezifisches Problem ist oder nur die eigenen C-Kenntnisse einer Auffrischung bedürfen. Allgemeine C-Fragen kann man eventuell &amp;quot;beim freundlichen Programmierer zwei Büro-, Zimmer- oder Haustüren weiter&amp;quot; loswerden. Ansonsten: [[C]]-Buch (gibt&#039;s auch &amp;quot;gratis&amp;quot; online) lesen.&lt;br /&gt;
&lt;br /&gt;
* Die [[AVR Checkliste]] durcharbeiten.&lt;br /&gt;
&lt;br /&gt;
* Die &#039;&#039;&#039;[http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc]&#039;&#039;&#039; lesen, vor allem (aber nicht nur) den Abschnitt Related Pages/&#039;&#039;&#039;Frequently Asked Questions&#039;&#039;&#039; = Oft gestellte Fragen (und Antworten dazu). Z.Zt leider nur in englischer Sprache verfügbar.&lt;br /&gt;
&lt;br /&gt;
* Den Artikel [[AVR-GCC]] in diesem Wiki lesen.&lt;br /&gt;
&lt;br /&gt;
* Das [http://www.mikrocontroller.net/forum/gcc GCC-Forum auf  www.mikrocontroller.net] nach vergleichbaren Problemen absuchen.&lt;br /&gt;
&lt;br /&gt;
* Das avr-gcc-Forum bei [http://www.avrfreaks.net AVRfreaks] nach vergleichbaren Problemen absuchen.&lt;br /&gt;
&lt;br /&gt;
* Das [http://lists.gnu.org/archive/html/avr-gcc-list/ Archiv der avr-gcc Mailing-Liste] nach vergleichbaren Problemen absuchen.&lt;br /&gt;
&lt;br /&gt;
* Nach Beispielcode suchen. Vor allem im &#039;&#039;Projects&#039;&#039;-Bereich von [http://www.avrfreaks.net AVRfreaks] (anmelden).&lt;br /&gt;
&lt;br /&gt;
* Google oder yahoo befragen schadet nie.&lt;br /&gt;
&lt;br /&gt;
* Bei Problemen mit der Ansteuerung interner AVR-Funktionen mit C-Code: das Datenblatt des Controllers lesen (ganz und am Besten zweimal). Datenblätter sind  auf den [http://www.atmel.com Atmel Webseiten] als pdf-Dateien verfügbar. Das komplette Datenblatt (complete) und nicht die Kurzfassung (summary) verwenden.&lt;br /&gt;
&lt;br /&gt;
* Die Beispielprogramme im [[AVR-Tutorial]] sind zwar in AVR-Assembler verfasst, Erläuterungen und Vorgehensweisen sind aber auch auf C-Programme übertragbar.&lt;br /&gt;
&lt;br /&gt;
* Einen Beitrag in eines der Foren oder eine Mail an die Mailing-Liste schreiben. Dabei möglichst viel Information geben: Controller, Compilerversion, genutzte Bibliotheken, Ausschnitte aus dem Quellcode oder besser ein [http://www.mikrocontroller.net/topic/72767#598986 Testprojekt] mit allen notwendigen Dateien, um das Problem nachzuvollziehen, sowie genaue Fehlermeldungen bzw. Beschreibung des Fehlverhaltens. Bei Ansteuerung externer Geräte die Beschaltung beschreiben oder skizzieren (z. B. mit [http://www.tech-chat.de/ Andys ASCII Circuit]). Siehe dazu auch: &#039;&#039;&#039;[http://www.tty1.net/smart-questions_de.html &amp;quot;Wie man Fragen richtig stellt&amp;quot;]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= Erzeugen von Maschinencode =&lt;br /&gt;
&lt;br /&gt;
Aus dem C-Quellcode erzeugt der avr-gcc Compiler (zusammen mit Hilfsprogrammen wie z.&amp;amp;nbsp;B. Präprozessor, Assembler und Linker) Maschinencode für den AVR-Controller. Üblicherweise liegt dieser Code dann im Intel Hex-Format vor (&amp;quot;Hex-Datei&amp;quot;). Die Programmiersoftware (z.&amp;amp;nbsp;B. [[AVRDUDE]], PonyProg oder AVRStudio/STK500-plugin) liest diese Datei ein und überträgt die enthaltene Information (den Maschinencode) in den Speicher des Controllers. Im Prinzip sind also &amp;quot;nur&amp;quot; der avr-gcc-Compiler (und wenige Hilfsprogramme) mit den &amp;quot;richtigen&amp;quot; Optionen aufzurufen, um aus C-Code eine &amp;quot;Hex-Datei&amp;quot; zu erzeugen. Grundsätzlich stehen dazu zwei verschiedene Ansätze zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
* Die Verwendung einer integrierten Entwicklungsumgebung (IDE = &#039;&#039;&#039;I&#039;&#039;&#039;ntegrated &#039;&#039;&#039;D&#039;&#039;&#039;evelopment &#039;&#039;&#039;E&#039;&#039;&#039;nvironment), bei der alle Einstellungen z.&amp;amp;nbsp;B. in Dialogboxen durchgeführt werden können. Unter Anderem kann AVRStudio ab Version 4.12 (kostenlos auf [http://www.atmel.com/ atmel.com]) zusammen mit WinAVR als integrierte Entwicklungsumgebung für den Compiler avr-gcc genutzt werden (dazu müssen AVRStudio und WinAVR auf dem Rechner installiert sein). Weitere IDEs (ohne Anspruch auf Vollständigkeit): [http://www.eclipse.org/ Eclipse for C/C++ Developers] (d.h. inkl. CDT) und das [http://avr-eclipse.sourceforge.net/wiki/index.php/The_AVR_Eclipse_Plugin AVR-Eclipse Plugin] (für diverse Plattformen, u.a. Linux und MS Windows, IDE und Plugin kostenlos), [http://sourceforge.net/projects/kontrollerlab KontrollerLab] (Linux/KDE, kostenlos). [http://www.atmanecl.com/EnglishSite/SoftwareEnglish.htm AtmanAvr] (MS Windows, relativ günstig), KamAVR (MS-Windows, kostenlos, wird augenscheinlich nicht mehr weiterentwickelt), [http://www.amctools.com/vmlab.htm VMLab] (MS Windows, ab Version 3.12 ebenfalls kostenlos). Integrierte Entwicklungsumgebungen unterscheiden sich stark in Ihrer Bedienung und stehen auch nicht für alle Plattformen zur Verfügung, auf denen der Compiler  ausführbar ist (z.&amp;amp;nbsp;B. AVRStudio nur für MS-Windows). Zur Anwendung des avr-gcc Compilers mit IDEs sei hier auf deren Dokumentation verwiesen. &lt;br /&gt;
&lt;br /&gt;
* Die Nutzung des Programms make mit passenden Makefiles. In den folgenden Abschnitten wird die Generierung von Maschinencode für einen AVR (&amp;quot;hex-Datei&amp;quot;) aus C-Quellcode (&amp;quot;c-Dateien&amp;quot;) anhand von &amp;quot;make&amp;quot; und den &amp;quot;Makefiles&amp;quot; näher erläutert. Viele der darin beschriebenen Optionen findet man auch im Konfigurationsdialog des avr-gcc-Plugins von AVRStudio (AVRStudio generiert ein makefile in einem Unterverzeichnis des Projektverzeichnisses). &lt;br /&gt;
&lt;br /&gt;
Beim Wechsel vom makefile-Ansatz nach WinAVR-Vorlage zu AVRStudio ist darauf zu achten, dass AVRStudio (Stand: AVRStudio Version 4.13) bei einem neuen Projekt die Optimierungsoption (vgl. Artikel [[AVR-GCC-Tutorial/Exkurs_Makefiles|AVR-GCC-Tutorial/Exkurs: Makefiles]], typisch: -Os) nicht einstellt und die mathematische Bibliothek der avr-libc (libm.a, Linker-Option -lm) nicht einbindet. (Hinweis: Bei Version 4.16 wird beides bereits gesetzt). Beides ist Standard bei Verwendung von makefiles nach WinAVR-Vorlage und sollte daher auch im Konfigurationsdialog des avr-gcc-Plugins von AVRStudio &amp;quot;manuell&amp;quot; eingestellt werden, um auch mit AVRStudio kompakten Code zu erzeugen.&lt;br /&gt;
&lt;br /&gt;
= Einführungsbeispiel =&lt;br /&gt;
&lt;br /&gt;
Zum Einstieg ein kleines Beispiel, an dem die Nutzung des Compilers und der Hilfsprogramme (der sogenannten &#039;&#039;Toolchain&#039;&#039;) demonstriert wird. Detaillierte Erläuterungen folgen in den weiteren Abschnitten dieses Tutorials.&lt;br /&gt;
&lt;br /&gt;
Das Programm soll auf einem AVR Mikrocontroller einige Ausgänge ein- und andere ausschalten. Das Beispiel ist für einen ATmega16 programmiert ([http://www.atmel.com/dyn/resources/prod_documents/doc2466.pdf Datenblatt]), kann aber sinngemäß für andere Controller der AVR-Familie modifiziert werden. &lt;br /&gt;
&lt;br /&gt;
Ein kurzes Wort zur Hardware: Bei diesem Programm werden alle Pins von PORTB auf Ausgang gesetzt, und einige davon werden auf HIGH andere auf LOW gesetzt. Das kann je nach angeschlossener Hardware an diesen Pins kritisch sein. Am ungefährlichsten ist es, wenn nichts an den Pins angeschlossen ist und man die Funktion des Programmes durch eine Spannungsmessung mit einem Multimeter kontrolliert. Die Spannung wird dabei zwischen GND-Pin und den einzelnen Pins von PORTB gemessen.&lt;br /&gt;
&lt;br /&gt;
Zunächst der Quellcode der Anwendung, der in einer Text-Datei mit dem Namen &#039;&#039;main.c&#039;&#039; abgespeichert wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/* Alle Zeichen zwischen Schrägstrich-Stern &lt;br /&gt;
   und Stern-Schrägstrich sind Kommentare */&lt;br /&gt;
&lt;br /&gt;
// Zeilenkommentare sind ebenfalls möglich&lt;br /&gt;
// alle auf die beiden Schrägstriche folgenden&lt;br /&gt;
// Zeichen einer Zeile sind Kommentar&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;          // (1)&lt;br /&gt;
&lt;br /&gt;
int main (void) {            // (2)&lt;br /&gt;
&lt;br /&gt;
   DDRB  = 0xFF;             // (3)&lt;br /&gt;
   PORTB = 0x03;             // (4)&lt;br /&gt;
&lt;br /&gt;
   while(1) {                // (5)&lt;br /&gt;
     /* &amp;quot;leere&amp;quot; Schleife*/   // (6)&lt;br /&gt;
   }                         // (7)&lt;br /&gt;
&lt;br /&gt;
   /* wird nie erreicht */&lt;br /&gt;
   return 0;                 // (8)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# In dieser Zeile wird eine sogenannte Header-Datei eingebunden. In &amp;lt;code&amp;gt;avr/io.h&amp;lt;/code&amp;gt; sind die Registernamen definiert, die im späteren Verlauf genutzt werden. Auch unter Windows wird ein&amp;amp;nbsp;&amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; zur Kennzeichnung von Unterverzeichnissen in Include-Dateinamen verwendet und kein&amp;amp;nbsp;&amp;lt;code&amp;gt;\&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Hier beginnt das eigentliche Programm. Jedes C-Programm beginnt mit den Anweisungen in der Funktion &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Die Anschlüsse eines AVR (Pins) werden zu Blöcken zusammengefasst, einen solchen Block bezeichnet man als Port. Beim ATmega16 hat jeder Port 8 Anschlüsse, bei kleineren AVRs können einem Port auch weniger als 8 Anschlüsse zugeordnet sein. Da per Definition (Datenblatt) alle gesetzten Bits in einem Datenrichtungsregister den entsprechenden Anschluss auf Ausgang schalten, werden mit DDRB=0xff alle Anschlüsse des Ports B als Ausgänge eingestellt.&lt;br /&gt;
# Die den ersten beiden Bits des Ports zugeordneten Anschlüsse (PB0 und PB1) werden 1, alle anderen Anschlüsse des Ports B (PB2-PB7) zu 0. Aktivierte Ausgänge (logisch 1 oder &amp;quot;high&amp;quot;) liegen auf Betriebsspannung (VCC, meist 5 Volt), nicht aktivierte Ausgänge führen 0 Volt (GND, Bezugspotential). Es ist sinnvoll, sich möglichst frühzeitig eine alternative Schreibweise beizubringen, die wegen der leichteren Überprüfbarkeit und Portierbarkeit oft im weiteren Tutorial und in Forenbeiträgen benutzt wird. Die Zuordnung sieht in diesem Fall so aus, Näheres dazu im Artikel [[Bitmanipulation]]:&amp;lt;c&amp;gt;PORTB = (1&amp;lt;&amp;lt;PB1) | (1&amp;lt;&amp;lt;PB0);&amp;lt;/c&amp;gt;&lt;br /&gt;
# ist der Beginn der sogenannte &#039;&#039;Hauptschleife&#039;&#039; (main-loop). Dies ist eine Endlosschleife, welche kontinuierlich wiederkehrende Befehle enthält.&lt;br /&gt;
# In diesem Beispiel ist die Hauptschleife leer. Der Controller durchläuft die Schleife immer wieder, ohne dass etwas passiert. Eine solche Schleife ist notwendig, da es auf dem Controller kein Betriebssystem gibt, das nach Beendigung des Programmes die Kontrolle übernehmen könnte. Ohne diese Schleife kehrt das Programm aus &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; zurück, alle Interrupts werden deaktiviert und eine Endlosschleife betreten.&lt;br /&gt;
# Ende der Hauptschleife und Sprung zur passenden, öffnenden Klammer, also zu 5.&lt;br /&gt;
# ist das Programmende. Die Zeile ist nur aus Gründen der C-Kompatibilität enthalten: &amp;lt;c&amp;gt;int main(void)&amp;lt;/c&amp;gt; besagt, dass die Funktion einen int-Wert zurückgibt. Die Anweisung wird aber nicht erreicht, da das Programm die Hauptschleife nie verlässt.&lt;br /&gt;
&lt;br /&gt;
Um diesen Quellcode in ein lauffähiges Programm zu übersetzen, wird hier ein Makefile genutzt. Das verwendete Makefile findet sich auf der Seite [[Beispiel Makefile]] und basiert auf der Vorlage, die in WinAVR mitgeliefert wird und wurde bereits angepasst (Controllertyp ATmega16). Man kann das Makefile bearbeiten und an andere Controller anpassen oder sich mit dem Programm MFile menügesteuert ein Makefile &amp;quot;zusammenklicken&amp;quot;. Das Makefile speichert man unter dem Namen &amp;lt;code&amp;gt;Makefile&amp;lt;/code&amp;gt; (ohne Endung) im selben Verzeichnis, in dem auch die Datei &amp;lt;code&amp;gt;main.c&amp;lt;/code&amp;gt; mit dem Programmcode abgelegt ist. Detailliertere Erklärungen zur Funktion von Makefiles finden sich im Artikel [[AVR-GCC-Tutorial/Exkurs_Makefiles|Exkurs: Makefiles]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
D:\beispiel&amp;gt;dir&lt;br /&gt;
&lt;br /&gt;
 Verzeichnis von D:\beispiel&lt;br /&gt;
&lt;br /&gt;
28.11.2006  22:53    &amp;lt;DIR&amp;gt;          .&lt;br /&gt;
28.11.2006  22:53    &amp;lt;DIR&amp;gt;          ..&lt;br /&gt;
28.11.2006  20:06               118 main.c&lt;br /&gt;
28.11.2006  20:03            16.810 Makefile&lt;br /&gt;
               2 Datei(en)         16.928 Bytes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun gibt man &#039;&#039;make all&#039;&#039; ein. Falls das mit WinAVR installierte Programmers Notepad genutzt wird, gibt es dazu einen Menüpunkt im Tools Menü. Sind alle Einstellungen korrekt, entsteht eine Datei &amp;lt;code&amp;gt;main.hex&amp;lt;/code&amp;gt;, in welcher der Code für den AVR enthalten ist. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
D:\beispiel&amp;gt;make all&lt;br /&gt;
&lt;br /&gt;
-------- begin --------&lt;br /&gt;
avr-gcc (GCC) 3.4.6&lt;br /&gt;
Copyright (C) 2006 Free Software Foundation, Inc.&lt;br /&gt;
This is free software; see the source for copying conditions.  There is NO&lt;br /&gt;
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&lt;br /&gt;
&lt;br /&gt;
Compiling C: main.c&lt;br /&gt;
avr-gcc -c -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=1000000UL -Os -funsigned-char -f&lt;br /&gt;
unsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wundef&lt;br /&gt;
 -Wa,-adhlns=obj/main.lst  -std=gnu99 -Wundef -MD -MP -MF .dep/main.o.d main.c -&lt;br /&gt;
o obj/main.o&lt;br /&gt;
&lt;br /&gt;
Linking: main.elf&lt;br /&gt;
avr-gcc -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=1000000UL -Os -funsigned-char -funs&lt;br /&gt;
igned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wundef -W&lt;br /&gt;
a,-adhlns=obj/main.o  -std=gnu99 -Wundef -MD -MP -MF .dep/main.elf.d obj/main.o&lt;br /&gt;
--output main.elf -Wl,-Map=main.map,--cref    -lm&lt;br /&gt;
&lt;br /&gt;
Creating load file for Flash: main.hex&lt;br /&gt;
avr-objcopy -O ihex -R .eeprom main.elf main.hex&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Inhalt der hex-Datei kann nun zum Controller übertragen werden. Dies kann z.&amp;amp;nbsp;B. über In-System-Programming ([[ISP]]) erfolgen, das im [[AVR-Tutorial: Equipment]] beschrieben ist. Makefiles nach der WinAVR/MFile-Vorlage sind für die Nutzung des Programms [[AVRDUDE]] vorbereitet. Wenn man den Typ und Anschluss des Programmiergerätes richtig eingestellt hat, kann mit &#039;&#039;make program&#039;&#039; die Übertragung mittels AVRDUDE gestartet werden. Jede andere Software, die hex-Dateien lesen und zu einem AVR übertragen kann&amp;lt;ref&amp;gt;z.&amp;amp;nbsp;B. [[Pony-Prog_Tutorial|Ponyprog]], yapp, AVRStudio&amp;lt;/ref&amp;gt;, kann natürlich ebenfalls genutzt werden.&lt;br /&gt;
&lt;br /&gt;
Startet man nun den Controller (Reset-Taster oder Stromzufuhr aus/an), werden vom Programm die Anschlüsse PB0 und PB1 auf 1 gesetzt. Man kann mit einem Messgerät nun an diesem Anschluss die Betriebsspannung messen oder eine [[LED]] leuchten lassen (Anode an den Pin, Vorwiderstand nicht vergessen). An den Anschlüssen PB2-PB7 misst man 0 Volt. Eine mit der Anode mit einem dieser Anschlüsse verbundene LED leuchtet nicht.&lt;br /&gt;
&lt;br /&gt;
= Ganzzahlige Datentypen (Integer) =&lt;br /&gt;
&lt;br /&gt;
Bei der Programmierung von Mikrokontrollern ist die Definition einiger ganzzahliger Datentypen sinnvoll, an denen eindeutig die Bit-Länge abgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Standardisierte Datentypen werden in der Header-Datei &amp;lt;code&amp;gt;stdint.h&amp;lt;/code&amp;gt; definiert, die folgendermaßen eingebunden werden kann:&lt;br /&gt;
&amp;lt;c&amp;gt;#include &amp;lt;stdint.h&amp;gt;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| {{Tabelle}}&lt;br /&gt;
|+ &#039;&#039;&#039;int-Typen aus &amp;lt;code&amp;gt;stdint.h&amp;lt;/code&amp;gt; (C99)&#039;&#039;&#039;&amp;lt;br/&amp;gt;&amp;amp;nbsp;&lt;br /&gt;
|- bgcolor=&amp;quot;#d0d0ff&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;5&amp;quot;| Vorzeichenbehaftete int-Typen&lt;br /&gt;
|- bgcolor=&amp;quot;#e8e8ff&amp;quot;&lt;br /&gt;
! Typname || Bit-Breite ||colspan=&amp;quot;2&amp;quot;| Wertebereich&lt;br /&gt;
|align=&amp;quot;center| &#039;&#039;&#039;C-Entsprechung&#039;&#039;&#039; (avr-gcc)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;int8_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 8 || −128 ⋯ 127 || −2&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt; ⋯ 2&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;signed char&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;int16_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 16 || −32768 ⋯ 32767 || −2&amp;lt;sup&amp;gt;15&amp;lt;/sup&amp;gt; ⋯ 2&amp;lt;sup&amp;gt;15&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;signed short&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;signed int&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;int32_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 32 || −2147483648 ⋯ 2147483647 || −2&amp;lt;sup&amp;gt;31&amp;lt;/sup&amp;gt; ⋯ 2&amp;lt;sup&amp;gt;31&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;signed long&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;int64_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 64 || −9223372036854775808 ⋯ 9223372036854775807 || −2&amp;lt;sup&amp;gt;63&amp;lt;/sup&amp;gt; ⋯ 2&amp;lt;sup&amp;gt;63&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;signed long long&amp;lt;/code&amp;gt;&lt;br /&gt;
|- bgcolor=&amp;quot;#d0d0ff&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;5&amp;quot;| Vorzeichenlose int-Typen&lt;br /&gt;
|- bgcolor=&amp;quot;#e8e8ff&amp;quot;&lt;br /&gt;
! Typname || Bit-Breite ||colspan=&amp;quot;2&amp;quot;| Wertebereich&lt;br /&gt;
|align=&amp;quot;center| &#039;&#039;&#039;C-Entsprechung&#039;&#039;&#039; (avr-gcc)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 8 || 0 ⋯ 255 || 0 ⋯ 2&amp;lt;sup&amp;gt;8&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;unsigned char&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 16 || 0 ⋯ 65535 || 0 ⋯ 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;unsigned short&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;unsigned int&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;uint32_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 32 || 0 ⋯ 4294967295 || 0 ⋯ 2&amp;lt;sup&amp;gt;32&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;unsigned long&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;uint64_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 64 || 0 ⋯ 18446744073709551615 || 0 ⋯ 2&amp;lt;sup&amp;gt;64&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;unsigned long long&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Neben den Typen gibt es auch Makros für die Bereichsgrenzen wie &amp;lt;code&amp;gt;INT8_MIN&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;UINT16_MAX&amp;lt;/code&amp;gt;. Siehe dazu auch: [http://www.nongnu.org/avr-libc/user-manual/group__avr__stdint.html Dokumentation der avr-libc: Standard Integer Types].&lt;br /&gt;
&lt;br /&gt;
= Bitfelder =&lt;br /&gt;
&lt;br /&gt;
Beim Programmieren von Mikrocontrollern muss auf jedes Byte oder sogar auf&lt;br /&gt;
jedes Bit geachtet werden. Oft müssen wir in einer Variablen lediglich den&lt;br /&gt;
Zustand 0 oder 1 speichern. Wenn wir nun zur Speicherung eines einzelnen Wertes&lt;br /&gt;
den kleinsten bekannten Datentypen, nämlich &#039;&#039;&#039;unsigned char&#039;&#039;&#039;, nehmen, dann&lt;br /&gt;
verschwenden wir 7 Bits, da ein &#039;&#039;&#039;unsigned char&#039;&#039;&#039; ja 8 Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
Hier bietet uns die Programmiersprache C ein mächtiges Werkzeug an, mit dessen&lt;br /&gt;
Hilfe wir 8 Bits in eine einzelne Bytevariable zusammenfassen und (fast) wie&lt;br /&gt;
8 einzelne Variablen ansprechen können. Die Rede ist von sogenannten Bitfeldern. Diese werden als Strukturelemente definiert. Sehen wir uns dazu doch am besten gleich ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
struct {&lt;br /&gt;
   unsigned bStatus_1:1; // 1 Bit für bStatus_1&lt;br /&gt;
   unsigned bStatus_2:1; // 1 Bit für bStatus_2&lt;br /&gt;
   unsigned bNochNBit:1; // Und hier noch mal ein Bit&lt;br /&gt;
   unsigned b2Bits:2;    // Dieses Feld ist 2 Bits breit&lt;br /&gt;
   // All das hat in einer einzigen Byte-Variable Platz.&lt;br /&gt;
   // die 3 verbleibenden Bits bleiben ungenutzt&lt;br /&gt;
} x;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Zugriff auf ein solches Feld erfolgt nun, wie beim Strukturzugriff bekannt,&lt;br /&gt;
über den Punkt- oder den Dereferenzierungs-Operator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
x.bStatus_1 = 1;&lt;br /&gt;
x.bStatus_2 = 0;&lt;br /&gt;
x.b2Bits = 3;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bitfelder sparen Platz im RAM, zu Lasten von Platz im Flash, verschlechtern aber unter Umständen die Les- und Wartbarkeit des Codes. Anfängern wird deshalb geraten, ein &amp;quot;ganzes&amp;quot; Byte (uint8_t) zu nutzen, auch wenn nur ein Bitwert gespeichert werden soll.&lt;br /&gt;
&lt;br /&gt;
= Grundsätzlicher Programmaufbau eines µC-Programms =&lt;br /&gt;
&lt;br /&gt;
Wir unterscheiden zwischen 2 verschiedenen Methoden, um ein&lt;br /&gt;
Mikrocontroller-Programm zu schreiben, und zwar völlig unabhängig davon, in&lt;br /&gt;
welcher Programmiersprache das Programm geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
== Sequentieller Programmablauf ==&lt;br /&gt;
&lt;br /&gt;
[[Image:Sequentielle Programme.gif|left]]&lt;br /&gt;
Bei dieser Programmiertechnik wird eine Endlosschleife programmiert, welche im&lt;br /&gt;
Wesentlichen immer den gleichen Aufbau hat. Es wird hier nach dem sogenannten EVA-Prinzip gehandelt. EVA steht für &amp;quot;Eingabe, Verarbeitung, Ausgabe&amp;quot;.&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
== Interruptgesteuerter Programmablauf ==&lt;br /&gt;
&lt;br /&gt;
[[Image:Interrupt Programme.gif|left]]&lt;br /&gt;
Bei dieser Methode werden beim Programmstart zuerst die gewünschten Interruptquellen aktiviert und dann in eine Endlosschleife gegangen, in welcher Dinge erledigt werden können, welche nicht zeitkritisch sind. Wenn ein Interrupt ausgelöst wird, so wird automatisch die zugeordnete Interruptfunktion ausgeführt.&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
= Zugriff auf Register =&lt;br /&gt;
&lt;br /&gt;
Die AVR-Controller verfügen über eine Vielzahl von Registern. Die meisten&lt;br /&gt;
davon sind sogenannte Schreib-/Leseregister. Das heißt, das Programm kann die&lt;br /&gt;
Inhalte der Register sowohl auslesen als auch beschreiben.&lt;br /&gt;
&lt;br /&gt;
Register haben einen besonderen Stellenwert bei den AVR Controllern. Sie dienen dem Zugriff auf die Ports und die Schnittstellen des Controllers. Wir unterscheiden zwischen 8-Bit und 16-Bit Registern. Vorerst behandeln wir die 8-Bit Register.&lt;br /&gt;
&lt;br /&gt;
Einzelne Register sind bei allen AVRs vorhanden, andere wiederum nur bei bestimmten Typen. So sind beispielsweise die Register, welche für den Zugriff auf den UART notwendig sind, selbstverständlich nur bei denjenigen Modellen vorhanden, welche über einen integrierten Hardware UART bzw. USART verfügen.&lt;br /&gt;
&lt;br /&gt;
Die Namen der Register sind in den Headerdateien zu den entsprechenden AVR-Typen definiert. Dazu muss man den Namen der controllerspezifischen Headerdatei nicht kennen. Es reicht aus, die allgemeine Headerdatei &#039;&#039;avr/io.h&#039;&#039; einzubinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ist im Makefile der MCU-Typ z.&amp;amp;nbsp;B. mit dem Inhalt atmega8 definiert (und wird somit per -mmcu=atmega8 an den Compiler übergeben), wird beim Einlesen der io.h-Datei implizit (&amp;quot;automatisch&amp;quot;) auch die iom8.h-Datei mit den Register-Definitionen für den ATmega8 eingelesen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Wohl besser als Anhang - spaeter... --&amp;gt;&lt;br /&gt;
Intern wird diese &amp;quot;Automatik&amp;quot; wie folgt realisiert: Der Controllertyp wird dem Compiler als Parameter übergeben (vgl. &#039;&#039;avr-gcc -c -mmcu=atmega16 [...]&#039;&#039; im Einführungsbeispiel). Wird ein Makefile nach der WinAVR/mfile-Vorlage verwendet, setzt man die Variable &#039;&#039;MCU&#039;&#039;, der Inhalt dieser Variable wird dann an passender Stelle für die Compilerparameter verwendet. Der Compiler definiert intern eine dem mmcu-Parameter zugeordnete &amp;quot;Variable&amp;quot; (genauer: ein Makro) mit dem Namen des Controllers, vorangestelltem &#039;&#039;__AVR_&#039;&#039; und angehängten Unterstrichen (z.&amp;amp;nbsp;B. wird bei &#039;&#039;-mmcu=atmega16&#039;&#039; das Makro &#039;&#039;__AVR_ATmega16__&#039;&#039; definiert). Beim Einbinden der Header-Datei &#039;&#039;avr/io.h&#039;&#039; wird geprüft, ob das jeweilige Makro definiert ist und die zum Controller passende Definitionsdatei eingelesen. Zur Veranschaulichung einige Ausschnitte aus einem Makefile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[...]&lt;br /&gt;
# MCU Type (&amp;quot;name&amp;quot;) setzen:&lt;br /&gt;
MCU = atmega16&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
## Verwendung des Inhalts von MCU (hier atmega16) fuer die &lt;br /&gt;
## Compiler- und Assembler-Parameter&lt;br /&gt;
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)&lt;br /&gt;
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)&lt;br /&gt;
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
## Aufruf des Compilers:&lt;br /&gt;
## mit den Parametern ($(ALL_CFLAGS) ist -mmcu=$(MCU)[...] = -mmcu=atmega16[...]&lt;br /&gt;
$(OBJDIR)/%.o : %.c&lt;br /&gt;
	@echo&lt;br /&gt;
	@echo $(MSG_COMPILING) $&amp;lt;&lt;br /&gt;
	$(CC) -c $(ALL_CFLAGS) $&amp;lt; -o $@ &lt;br /&gt;
[...]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da --mmcu=atmega16 übergeben wurde, wird __AVR_ATmega16__ definiert und kann in avr/io.h zur Fallunterscheidung genutzt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// avr/io.h &lt;br /&gt;
// (bei WinAVR-Standardinstallation in C:\WinAVR\avr\include\avr)&lt;br /&gt;
[...]&lt;br /&gt;
#if defined (__AVR_AT94K__)&lt;br /&gt;
#  include &amp;lt;avr/ioat94k.h&amp;gt;&lt;br /&gt;
// [...]&lt;br /&gt;
#elif defined (__AVR_ATmega16__)&lt;br /&gt;
// da __AVR_ATmega16__ definiert ist, wird avr/iom16.h eingebunden:&lt;br /&gt;
#  include &amp;lt;avr/iom16.h&amp;gt;&lt;br /&gt;
// [...]&lt;br /&gt;
#else&lt;br /&gt;
#  if !defined(__COMPILING_AVR_LIBC__)&lt;br /&gt;
#    warning &amp;quot;device type not defined&amp;quot;&lt;br /&gt;
#  endif&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Beispiele in den folgenden Abschnitten demonstrieren den Zugriff auf Register anhand der Register für I/O-Ports (PORTx, DDRx, PINx), die Vorgehensweise ist jedoch für alle Register (z.&amp;amp;nbsp;B. die des UART, ADC, SPI) analog.&lt;br /&gt;
&lt;br /&gt;
== Schreiben in Register ==&lt;br /&gt;
&lt;br /&gt;
Zum Schreiben kann man Register einfach wie eine Variable setzen.&amp;lt;ref&amp;gt;In Quellcodes, die für ältere Versionen des avr-gcc/der avr-libc entwickelt wurden, erfolgt der Schreibzugriff über die Funktion outp(). Aktuelle Versionen des Compilers unterstützen den Zugriff nun direkt, outp() ist nicht mehr erforderlich.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    /* Setzt das Richtungsregister des Ports A auf 0xff &lt;br /&gt;
       (alle Pins als Ausgang, vgl. Abschnitt Zugriff auf Ports): */&lt;br /&gt;
    DDRA = 0xff;    &lt;br /&gt;
&lt;br /&gt;
    /* Setzt PortA auf 0x03, Bit 0 und 1 &amp;quot;high&amp;quot;, restliche &amp;quot;low&amp;quot;: */&lt;br /&gt;
    PORTA = 0x03;   &lt;br /&gt;
&lt;br /&gt;
    // Setzen der Bits 0,1,2,3 und 4&lt;br /&gt;
    // Binär 00011111 = Hexadezimal 1F&lt;br /&gt;
    DDRB = 0x1F;    /* direkte Zuweisung - unübersichtlich */&lt;br /&gt;
&lt;br /&gt;
    /* Ausführliche Schreibweise: identische Funktionalität, mehr Tipparbeit&lt;br /&gt;
       aber übersichtlicher und selbsterklärend: */&lt;br /&gt;
    DDRB = (1 &amp;lt;&amp;lt; DDB0) | (1 &amp;lt;&amp;lt; DDB1) | (1 &amp;lt;&amp;lt; DDB2) | (1 &amp;lt;&amp;lt; DDB3) | (1 &amp;lt;&amp;lt; DDB4);&lt;br /&gt;
&lt;br /&gt;
    while (1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die ausführliche Schreibweise sollte bevorzugt verwendet werden, da dadurch die Zuweisungen selbsterklärend sind und somit der Code leichter nachvollzogen werden kann. Atmel verwendet sie auch bei Beispielen in Datenblätten und in den allermeisten Quellcodes zu Application-Notes. Mehr zu der Schreibweise mit &amp;quot;|&amp;quot; und &amp;quot;&amp;lt;&amp;lt;&amp;quot; findet man unter [[Bitmanipulation]].&lt;br /&gt;
&lt;br /&gt;
Der gcc C-Compiler unterstützt ab Version 4.3.0 Konstanten im Binärformat, z.&amp;amp;nbsp;B. DDRB&amp;amp;nbsp;=&amp;amp;nbsp;0b00011111. Diese Schreibweise ist jedoch nur in GNU-C verfügbar und nicht in ISO-C definiert. Man sollte sie daher nicht verwenden, wenn Code mit anderen ausgetauscht oder mit anderen Compilern bzw. älteren Versionen des gcc genutzt werden soll.&lt;br /&gt;
&lt;br /&gt;
== Verändern von Registerinhalten ==&lt;br /&gt;
&lt;br /&gt;
Einzelne Bits setzt und löscht man &amp;quot;Standard-C-konform&amp;quot; mittels logischer (Bit-) Operationen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
 x |= (1 &amp;lt;&amp;lt; Bitnummer);  // Hiermit wird ein Bit in x gesetzt&lt;br /&gt;
 x &amp;amp;= ~(1 &amp;lt;&amp;lt; Bitnummer); // Hiermit wird ein Bit in x geloescht&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es wird jeweils nur der Zustand des angegebenen Bits geändert, der vorherige Zustand der anderen Bits bleibt erhalten. &lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
#define MEINBIT 2&lt;br /&gt;
...&lt;br /&gt;
PORTA |= (1 &amp;lt;&amp;lt; MEINBIT);    /* setzt Bit 2 an PortA auf 1 */&lt;br /&gt;
PORTA &amp;amp;= ~(1 &amp;lt;&amp;lt; MEINBIT);   /* loescht Bit 2 an PortA */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit dieser Methode lassen sich auch mehrere Bits eines Registers gleichzeitig setzen und löschen.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
DDRA &amp;amp;= ~( (1&amp;lt;&amp;lt;PA0) | (1&amp;lt;&amp;lt;PA3) );  /* PA0 und PA3 als Eingaenge */&lt;br /&gt;
PORTA |= ( (1&amp;lt;&amp;lt;PA0) | (1&amp;lt;&amp;lt;PA3) );  /* Interne Pull-Up fuer beide einschalten */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei bestimmten AVR Registern mit Bits, die durch Beschreiben mit einer logischen 1 gelöscht werden, muss eine absolute Zuweisung benutzt werden. Ein ODER löscht in diesen Registern ALLE gesetzten Bits!&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
TIFR2 = (1&amp;lt;&amp;lt;OCF2A); // Nur Bit OCF2A löschen&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Quellcodes, die für ältere Version den des avr-gcc/der avr-libc entwickelt wurden, werden einzelne Bits mittels der Funktionen sbi und cbi gesetzt bzw. gelöscht. Beide Funktionen sind nicht mehr erforderlich.&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* [[Bitmanipulation]]&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/Special Function Registers&lt;br /&gt;
&lt;br /&gt;
== Lesen aus Registern ==&lt;br /&gt;
&lt;br /&gt;
Zum Lesen kann man auf Register einfach wie auf eine Variable zugreifen. In Quellcodes, die für ältere Versionen des avr-gcc/der avr-libc entwickelt wurden, erfolgt der Lesezugriff über die Funktion inp(). Aktuelle Versionen des Compilers unterstützen den Zugriff nun direkt und inp() ist nicht mehr erforderlich.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
uint8_t foo;&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    /* kopiert den Status der Eingabepins an PortB &lt;br /&gt;
       in die Variable foo: */&lt;br /&gt;
    foo = PINB;    &lt;br /&gt;
    //...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Abfrage der Zustände von Bits erfolgt durch Einlesen des gesamten Registerinhalts und ausblenden der Bits deren Zustand nicht von Interesse ist. Einige Beispiele zum Prüfen ob Bits gesetzt oder gelöscht sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#define MEINBIT0 0 &lt;br /&gt;
#define MEINBIT2 2&lt;br /&gt;
&lt;br /&gt;
uint8_t i;&lt;br /&gt;
&lt;br /&gt;
extern test1();&lt;br /&gt;
&lt;br /&gt;
// Funkion test1 aufrufen, wenn Bit 0 in Register PINA gesetzt (1) ist&lt;br /&gt;
i = PINA;         // Inhalt in Arbeitsvariable&lt;br /&gt;
i = i &amp;amp; 0x01;     // alle Bits bis auf Bit 0 ausblenden (bitweise und)&lt;br /&gt;
                  // falls das Bit gesetzt war, hat i den Inhalt 1&lt;br /&gt;
if ( i != 0 ) {   // Ergebnis ungleich 0 (wahr)? &lt;br /&gt;
  test1();         // dann muss Bit 0 in i gesetzt sein -&amp;gt; Funktion aufrufen&lt;br /&gt;
}&lt;br /&gt;
// verkürzt:&lt;br /&gt;
if ( ( PINA &amp;amp; 0x01 ) != 0 ) {&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
// nochmals verkürzt:&lt;br /&gt;
if ( PINA &amp;amp; 0x01 ) {&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
// mit definierter Bitnummer:&lt;br /&gt;
if ( PINA &amp;amp; ( 1 &amp;lt;&amp;lt; MEINBIT0 ) ) {&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Funktion aufrufen, wenn Bit 0 und/oder Bit 2 gesetzt ist. (Bit 0 und 2 also Wert 5) &lt;br /&gt;
// (Bedenke: Bit 0 hat Wert 1, Bit 1 hat Wert 2 und Bit 2 hat Wert 4)&lt;br /&gt;
if ( PINA &amp;amp; 0x05 ) {&lt;br /&gt;
  test1();  // Vergleich &amp;lt;&amp;gt; 0 (wahr), also mindestens eines der Bits gesetzt&lt;br /&gt;
}&lt;br /&gt;
// mit definierten Bitnummern:&lt;br /&gt;
if ( PINA &amp;amp; ( ( 1 &amp;lt;&amp;lt; MEINBIT0 ) | ( 1 &amp;lt;&amp;lt; MEINBIT2 ) ) ) {&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Funktion aufrufen, wenn Bit 0 und Bit 2 gesetzt sind&lt;br /&gt;
if ( ( PINA &amp;amp; 0x05 ) == 0x05 ) {  // nur wahr, wenn beide Bits gesetzt&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Funktion test2() aufrufen, wenn Bit 0 gelöscht (0) ist&lt;br /&gt;
i = PINA;        // einlesen in temporäre Variable&lt;br /&gt;
i = i &amp;amp; 0x01;    // maskieren von Bit 0&lt;br /&gt;
if ( i == 0 ) {  // Vergleich ist wahr, wenn Bit 0 nicht gesetzt ist&lt;br /&gt;
  test2();&lt;br /&gt;
}&lt;br /&gt;
// analog mit not-Operator&lt;br /&gt;
if ( !i ) {&lt;br /&gt;
  test2();&lt;br /&gt;
}&lt;br /&gt;
// nochmals verkürzt:&lt;br /&gt;
if ( !( PINA &amp;amp; 0x01 ) ) {&lt;br /&gt;
  test2();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Warten auf einen bestimmten Zustand ==&lt;br /&gt;
&lt;br /&gt;
Es gibt in der Bibliothek avr-libc Funktionen, die warten, bis ein bestimmter Zustand eines Bits erreicht ist. Es ist allerdings normalerweise eine eher unschöne Programmiertechnik, da in diesen Funktionen &amp;quot;blockierend&amp;quot; gewartet wird. Der Programmablauf bleibt also an dieser Stelle stehen, bis das maskierte Ereignis erfolgt ist. Setzt man den [[Watchdog]] ein, muss man darauf achten, dass dieser auch noch getriggert wird (Zurücksetzen des Watchdogtimers). &lt;br /&gt;
&lt;br /&gt;
Die Funktion &#039;&#039;&#039;loop_until_bit_is_set&#039;&#039;&#039; wartet in einer Schleife, bis das definierte Bit gesetzt ist. Wenn das Bit beim Aufruf der Funktion bereits gesetzt ist, wird die Funktion sofort wieder verlassen. Das niederwertigste Bit hat die Bitnummer 0. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
/* Warten bis Bit Nr. 2 (das dritte Bit) in Register PINA gesetzt (1) ist */&lt;br /&gt;
&lt;br /&gt;
#define WARTEPIN PINA&lt;br /&gt;
#define WARTEBIT PA2&lt;br /&gt;
&lt;br /&gt;
// mit der avr-libc Funktion:&lt;br /&gt;
loop_until_bit_is_set(WARTEPIN, WARTEBIT);&lt;br /&gt;
&lt;br /&gt;
// dito in &amp;quot;C-Standard&amp;quot;:&lt;br /&gt;
// Durchlaufe die (leere) Schleife solange das WARTEBIT in Register WARTEPIN&lt;br /&gt;
// _nicht_ ungleich 0 (also 0) ist.&lt;br /&gt;
while ( !(WARTEPIN &amp;amp; (1 &amp;lt;&amp;lt; WARTEBIT)) ) {}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Funktion &#039;&#039;&#039;loop_until_bit_is_clear&#039;&#039;&#039; wartet in einer Schleife, bis das definierte Bit gelöscht ist. Wenn das Bit beim Aufruf der Funktion bereits gelöscht ist, wird die Funktion sofort wieder verlassen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
/* Warten bis Bit Nr. 4 (das fuenfte Bit) in Register PINB geloescht (0) ist */&lt;br /&gt;
#define WARTEPIN PINB&lt;br /&gt;
#define WARTEBIT PB4&lt;br /&gt;
&lt;br /&gt;
// avr-libc-Funktion:&lt;br /&gt;
loop_until_bit_is_clear(WARTEPIN, WARTEBIT);&lt;br /&gt;
&lt;br /&gt;
// dito in &amp;quot;C-Standard&amp;quot;:&lt;br /&gt;
// Durchlaufe die (leere) Schleife solange das WARTEBIT in Register WARTEPIN&lt;br /&gt;
// gesetzt (1) ist &lt;br /&gt;
while ( WARTEPIN &amp;amp; (1&amp;lt;&amp;lt;WARTEBIT) ) {}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Universeller und auch auf andere Plattformen besser übertragbar ist die Verwendung von C-Standardoperationen.&lt;br /&gt;
&lt;br /&gt;
Siehe auch: &lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/Special Function Registers&lt;br /&gt;
* [[Bitmanipulation]]&lt;br /&gt;
&lt;br /&gt;
== 16-Bit Register (ADC, ICR1, OCR1x, TCNT1, UBRR) ==&lt;br /&gt;
&lt;br /&gt;
Einige der Portregister in den AVR-Controllern sind 16 Bit breit. Im Datenblatt sind diese Register üblicherweise mit dem Suffix &amp;quot;L&amp;quot; (Low-Byte) und &amp;quot;H&amp;quot; (High-Byte) versehen. Die avr-libc definiert zusätzlich die meisten dieser Variablen die Bezeichnung ohne &amp;quot;L&amp;quot; oder &amp;quot;H&amp;quot;. Auf diese Register kann dann direkt zugegriffen werden. Dies ist zum Beispiel der Fall für Register wie ADC oder TCNT1.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
    uint16_t foo;&lt;br /&gt;
&lt;br /&gt;
    /* setzt die Wort-Variable foo auf den Wert der letzten AD-Wandlung */&lt;br /&gt;
    foo = ADC; &lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei anderen Registern, wie zum Beispiel Baudraten-Register, liegen High- und Low-Teil nicht direkt nebeneinander im SFR-Bereich, so dass ein 16-Bit Zugriff nicht möglich ist und der Zugriff zusammengebastelt werden muss:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
#define F_CPU 3686400&lt;br /&gt;
#endif&lt;br /&gt;
#define UART_BAUD_RATE 9600&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
   uint16_t baud = F_CPU / (UART_BAUD_RATE * 16L) -1;&lt;br /&gt;
&lt;br /&gt;
   UBRRH = (uint8_t) (baud &amp;gt;&amp;gt; 8);&lt;br /&gt;
   UBRRL = (uint8_t) baud;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei einigen AVR-Typen wie ATmega8 oder ATmega16 teilen sich UBRRH und UCSRC die gleiche Speicher-Adresse. Damit der AVR trotzdem zwischen den beiden Registern unterscheiden kann, bestimmt das Bit7 (URSEL), welches Register tatsächlich beschrieben werden soll. &#039;&#039;1000 0011&#039;&#039; (0x83) adressiert demnach UCSRC und übergibt den Wert &#039;&#039;3&#039;&#039;. Und &#039;&#039;0000 0011&#039;&#039; (0x3) adressiert UBRRH und übergibt ebenfalls den Wert &#039;&#039;3&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Speziell bei den 16-Bit-Timern und auch beim ADC ist es bei allen Zugriffen auf Datenregister erforderlich, dass diese Daten synchronisiert sind. Wenn z.&amp;amp;nbsp;B. bei einem 16-Bit-Timer das High-Byte des Zählregisters gelesen wurde und vor dem Lesezugriff auf das Low-Byte ein Überlauf des Low-Bytes stattfindet, erhält man einen völlig unsinnigen Wert. Auch die Compare-Register müssen synchron geschrieben werden, da es ansonsten zu unerwünschten Compare-Ereignissen kommen kann. &lt;br /&gt;
&lt;br /&gt;
Beim ADC besteht das Problem darin, dass zwischen den Zugriffen auf die beiden Teilregister eine Wandlung beendet werden kann und der ADC ein neues Ergebnis in ADCL und ADCH schreiben will, wodurch High- und Low-Byte nicht zusammenpassen.&lt;br /&gt;
&lt;br /&gt;
Um diese Datenmüllproduktion zu verhindern, gibt es in beiden Fällen eine Synchronisation, die jeweils durch den Zugriff auf das Low-Byte ausgelöst wird:&lt;br /&gt;
* Bei den Timer-Registern (das gilt für alle TCNT-, OCR- und ICR-Register bei den 16-Bit-Timern) wird bei einem &#039;&#039;Lesezugriff&#039;&#039; auf das Low-Byte automatisch das High-Byte in ein temporäres Register, das ansonsten nach außen nicht sichtbar ist, geschoben. Greift man nun &#039;&#039;anschließend&#039;&#039; auf das High-Byte zu, dann wird eben dieses temporäre Register gelesen.&lt;br /&gt;
* Bei einem &#039;&#039;Schreibzugriff&#039;&#039; auf eines der genannten Register wird das High-Byte in besagtem temporären Register zwischengespeichert und erst beim Schreiben des Low-Bytes werden &#039;&#039;beide&#039;&#039; gleichzeitig in das eigentliche Register übernommen.&lt;br /&gt;
&lt;br /&gt;
Das bedeutet für die Reihenfolge:&lt;br /&gt;
* Lesezugriff: Erst Low-Byte, dann High-Byte&lt;br /&gt;
* Schreibzugriff: Erst High-Byte, dann Low-Byte&lt;br /&gt;
&lt;br /&gt;
Des weiteren ist zu beachten, dass es für all diese 16-Bit-Register nur ein einziges temporäres Register gibt, so dass das Auftreten eines Interrupts, in dessen Handler ein solches Register manipuliert wird, bei einem durch ihn unterbrochenen Zugriff i.d.R. zu Datenmüll führt. 16-Bit-Zugriffe sind generell nicht atomar! Wenn mit Interrupts gearbeitet wird, kann es erforderlich sein, vor einem solchen Zugriff auf ein 16-Bit-Register die Interrupt-Bearbeitung zu deaktivieren.&lt;br /&gt;
&lt;br /&gt;
Beim ADC-Datenregister ADCH/ADCL ist die Synchronisierung anders gelöst. Hier wird beim Lesezugriff (ADCH/ADCL sind logischerweise read-only) auf das Low-Byte ADCL beide Teilregister für Zugriffe seitens des ADC so lange gesperrt, bis das High-Byte ADCH ausgelesen wurde. Dadurch kann der ADC nach einem Zugriff auf ADCL keinen neuen Wert in ADCH/ADCL ablegen, bis ADCH gelesen wurde. Ergebnisse von Wandlungen, die zwischen einem Zugriff auf ADCL und ADCH beendet werden, gehen verloren!&lt;br /&gt;
&lt;br /&gt;
Nach einem Zugriff auf ADCL muss grundsätzlich ADCH gelesen werden!&lt;br /&gt;
&lt;br /&gt;
In beiden Fällen – also sowohl bei den Timern als auch beim ADC – werden vom C-Compiler 16-Bit Pseudo-Register zur Verfügung gestellt (z.&amp;amp;nbsp;B. TCNT1H/TCNT1L → TCNT1, ADCH/ADCL → ADC bzw. ADCW), bei deren Verwendung der Compiler automatisch die richtige Zugriffsreihenfolge regelt. In C-Programmen sollten grundsätzlich diese 16-Bit-Register verwendet werden! Sollte trotzdem ein Zugriff auf ein Teilregister erforderlich sein, sind obige Angaben zu berücksichtigen.&lt;br /&gt;
&lt;br /&gt;
Es ist darauf zu achten, dass auch ein Zugriff auf die 16-Bit-Register vom Compiler in zwei 8-Bit-Zugriffe aufgeteilt wird und dementsprechend genauso nicht-atomar ist wie die Einzelzugriffe. Auch hier gilt, dass u.U. die Interrupt-Bearbeitung gesperrt werden muss, um Datenmüll zu vermeiden.&lt;br /&gt;
&lt;br /&gt;
Beim ADC gibt es für den Fall, dass eine Auflösung von 8 Bit ausreicht, die Möglichkeit, das Ergebnis &amp;quot;linksbündig&amp;quot; in ADCH/ADCL auszurichten, so dass die relevanten 8 MSB in ADCH stehen. In diesem Fall muss bzw. sollte nur ADCH ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
ADC und ADCW sind unterschiedliche Bezeichner für das selbe Registerpaar. Üblicherweise kann man in C-Programmen ADC verwenden, was analog zu den anderen 16-Bit-Registern benannt ist. ADCW (ADC Word) existiert nur deshalb, weil die Headerdateien auch für Assembler vorgesehen sind und es bereits einen Assembler-Befehl namens &#039;&#039;adc&#039;&#039; gibt. &lt;br /&gt;
&lt;br /&gt;
Im Umgang mit 16-Bit Registern siehe auch:&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Related Pages/Frequently Asked Questions/Nr. 8&lt;br /&gt;
* Datenblatt Abschnitt &#039;&#039;Accessing 16-bit Registers&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== IO-Register als Parameter und Variablen ==&lt;br /&gt;
&lt;br /&gt;
Um Register als Parameter für eigene Funktionen übergeben zu können, muss man sie als einen volatile uint8_t Pointer übergeben. Zum Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
uint8_t key_pressed (volatile uint8_t *inputreg, uint8_t inputbit)&lt;br /&gt;
{&lt;br /&gt;
  static uint8_t last_state = 0;&lt;br /&gt;
 &lt;br /&gt;
  if (last_state == (*inputreg &amp;amp; (1&amp;lt;&amp;lt;inputbit)))&lt;br /&gt;
     return 0; /* keine Änderung */&lt;br /&gt;
 &lt;br /&gt;
  /* Wenn doch, warten bis etwaiges Prellen vorbei ist: */&lt;br /&gt;
  _delay_ms(20);&lt;br /&gt;
&lt;br /&gt;
  /* Zustand für nächsten Aufruf merken: */&lt;br /&gt;
  last_state = *inputreg &amp;amp; (1&amp;lt;&amp;lt;inputbit);&lt;br /&gt;
 &lt;br /&gt;
  /* und den entprellten Tastendruck zurückgeben: */&lt;br /&gt;
  return *inputreg &amp;amp; (1&amp;lt;&amp;lt;inputbit);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Beispiel für einen Funktionsaufruf: */&lt;br /&gt;
&lt;br /&gt;
void foo (void)&lt;br /&gt;
{&lt;br /&gt;
   uint8_t i = key_pressed (&amp;amp;PINB, PB1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Aufruf der Funktion mit call by value würde Folgendes bewirken: Beim Funktionseintritt wird nur eine Kopie des momentanen Portzustandes angefertigt, die sich unabhängig vom tatsächlichen Zustand das Ports nicht mehr ändert, womit die Funktion wirkungslos wäre. Die Übergabe eines Zeigers wäre die Lösung, wenn der Compiler nicht optimieren würde. Denn dadurch wird im Programm nicht von der Hardware gelesen, sondern wieder nur von einem Abbild im Speicher. Das Ergebnis wäre das gleiche wie oben. Mit dem Schlüsselwort volatile sagt man nun dem Compiler, dass die entsprechende Variable entweder durch andere Softwareroutinen (Interrupts) oder durch die Hardware verändert werden kann.&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_port_pass avr-libc FAQ: &amp;quot;How do I pass an IO port as a parameter to a function?&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
= Zugriff auf IO-Ports =&lt;br /&gt;
&lt;br /&gt;
Jeder AVR implementiert eine unterschiedliche Menge an GPIO-Registern&lt;br /&gt;
(GPIO - General Purpose Input/Output). Diese Register dienen dazu:&lt;br /&gt;
* einzustellen welche der Anschlüsse (&amp;quot;Beinchen&amp;quot;) des Controllers als Ein- oder Ausgänge dienen&lt;br /&gt;
* bei Ausgängen deren Zustand festzulegen&lt;br /&gt;
* bei Eingängen deren Zustand zu erfassen&lt;br /&gt;
&lt;br /&gt;
Mittels GPIO werden digitale Zustände gesetzt und erfasst, d.h. die Spannung an einem Ausgang wird ein- oder ausgeschaltet und an einem Eingang wird erfasst, ob die anliegende Spannung über oder unter einem bestimmten Schwellwert liegt. Im Datenblatt Abschnitt Electrical Characteristics/DC Characteristics finden sich die Spannungswerte (V_OL, V_OH für Ausgänge, V_IL, V_IH für Eingänge).&lt;br /&gt;
&lt;br /&gt;
Die Verarbeitung von analogen Eingangswerten und die Ausgabe von Analogwerten wird in Kapitel [[AVR-GCC-Tutorial#Analoge_Ein-_und_Ausgabe|Analoge Ein- und Ausgabe]] behandelt.&lt;br /&gt;
&lt;br /&gt;
Die physischen Ein- und Ausgänge werden bei AVR-Controllern zu logischen Ports gruppiert.&lt;br /&gt;
&lt;br /&gt;
Alle Ports werden über Register gesteuert. Dazu sind jedem Port 3 Register zugeordnet:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! DDRx&lt;br /&gt;
| Datenrichtungsregister für Port&#039;&#039;&#039;x&#039;&#039;&#039;. &lt;br /&gt;
&#039;&#039;&#039;x&#039;&#039;&#039; entspricht &#039;&#039;&#039;A&#039;&#039;&#039;, &#039;&#039;&#039;B&#039;&#039;&#039;, &#039;&#039;&#039; C&#039;&#039;&#039;, &#039;&#039;&#039;D&#039;&#039;&#039; usw. (abhängig von der Anzahl der Ports des verwendeten AVR). Bit im Register gesetzt (1) für Ausgang, Bit gelöscht (0) für Eingang.&lt;br /&gt;
|- &lt;br /&gt;
! PINx&lt;br /&gt;
| Eingangsadresse für Port&#039;&#039;&#039;x&#039;&#039;&#039;. &lt;br /&gt;
Zustand des Ports. Die Bits in PINx entsprechen dem Zustand der als Eingang definierten Portpins. Bit 1 wenn Pin &amp;quot;high&amp;quot;, Bit 0 wenn Portpin low.&lt;br /&gt;
|-&lt;br /&gt;
! PORTx&lt;br /&gt;
| Datenregister für Port&#039;&#039;&#039;x&#039;&#039;&#039;. &lt;br /&gt;
Dieses Register wird verwendet, um die Ausgänge eines Ports anzusteuern. Bei Pins, die mittels DDRx auf Eingang geschaltet wurden, können über PORTx&lt;br /&gt;
die internen Pull-Up Widerstände aktiviert oder deaktiviert werden (1 = aktiv).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Beispiele gehen von einem AVR aus, der sowohl Port A als auch Port B besitzt. Sie müssen für andere AVRs (zum Beispiel ATmega8/48/88/168) entsprechend angepasst werden.&lt;br /&gt;
&lt;br /&gt;
== Datenrichtung bestimmen ==&lt;br /&gt;
&lt;br /&gt;
Zuerst muss die Datenrichtung der verwendeten Pins bestimmt werden. Um dies zu erreichen, wird das Datenrichtungsregister des entsprechenden Ports beschrieben.&lt;br /&gt;
&lt;br /&gt;
Für jeden Pin, der als Ausgang verwendet werden soll, muss dabei das&lt;br /&gt;
entsprechende Bit auf dem Port gesetzt werden. Soll der Pin als Eingang&lt;br /&gt;
verwendet werden, muss das entsprechende Bit gelöscht sein.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
Angenommen am Port B sollen die Pins 0 bis 4 als Ausgänge definiert werden, die noch verbleibenden Pins 5 bis 7 sollen als Eingänge fungieren. Dazu ist es daher notwendig, im für das Port B zuständigen Datenrichtungsregister DDRB folgende Bitkonfiguration einzutragen&lt;br /&gt;
&lt;br /&gt;
   +---+---+---+---+---+---+---+---+&lt;br /&gt;
   | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |&lt;br /&gt;
   +---+---+---+---+---+---+---+---+&lt;br /&gt;
   | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |&lt;br /&gt;
&lt;br /&gt;
In C liest sich das dann so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// in io.h wird u.a. DDRB definiert:&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  // Setzen der Bits 0,1,2,3 und 4&lt;br /&gt;
  // Binär 00011111 = Hexadezimal 1F&lt;br /&gt;
  // direkte Zuweisung - standardkonform */&lt;br /&gt;
  DDRB = 0x1F;    /* &lt;br /&gt;
&lt;br /&gt;
  // übersichtliche Alternative - Binärschreibweise, aber kein ISO-C&lt;br /&gt;
  DDRB = 0b00011111;&lt;br /&gt;
&lt;br /&gt;
  // Ausführliche Schreibweise: identische Funktionalität, mehr Tipparbeit&lt;br /&gt;
  // aber übersichtlicher und selbsterklärend:&lt;br /&gt;
  DDRB = (1 &amp;lt;&amp;lt; DDB0) | (1 &amp;lt;&amp;lt; DDB1) | (1 &amp;lt;&amp;lt; DDB2) | (1 &amp;lt;&amp;lt; DDB3) | (1 &amp;lt;&amp;lt; DDB4); &lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Pins 5 bis 7 werden (da 0) als Eingänge geschaltet. Weitere Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  // Alle Pins des Ports B als Ausgang definieren:&lt;br /&gt;
  DDRB = 0xff; &lt;br /&gt;
  // Pin0 wieder auf Eingang und andere im ursprünglichen Zustand belassen:&lt;br /&gt;
  DDRB &amp;amp;= ~(1 &amp;lt;&amp;lt; DDB0);&lt;br /&gt;
  // Pin 3 und 4 auf Eingang und andere im ursprünglichen Zustand belassen:&lt;br /&gt;
  DDRB &amp;amp;= ~((1 &amp;lt;&amp;lt; DDB3) | (1 &amp;lt;&amp;lt; DDB4));&lt;br /&gt;
  // Pin 0 und 3 wieder auf Ausgang und andere im ursprünglichen Zustand belassen:&lt;br /&gt;
  DDRB |= (1 &amp;lt;&amp;lt; DDB0) | (1 &amp;lt;&amp;lt; DDB3);&lt;br /&gt;
  // Alle Pins auf Eingang:&lt;br /&gt;
  DDRB = 0x00;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Vordefinierte Bitnummern für I/O-Register ==&lt;br /&gt;
&lt;br /&gt;
Die Bitnummern (z.&amp;amp;nbsp;B. PCx, PINCx und DDCx für den Port C) sind in den io*.h-Dateien der avr-libc definiert und dienen lediglich der besseren Lesbarkeit. Man muss diese Definitionen nicht verwenden oder kann auch einfach &amp;quot;immer&amp;quot; PAx, PBx, PCx usw. nutzen, auch wenn der Zugriff auf Bits in DDRx- oder PINx-Registern erfolgt. Für den Compiler sind die Ausdrücke (1&amp;lt;&amp;lt;PC7), (1&amp;lt;&amp;lt;DDC7) und (1&amp;lt;&amp;lt;PINC7) identisch zu (1&amp;lt;&amp;lt;7) (genauer: der Präprozessor ersetzt die Ausdrücke (1&amp;lt;&amp;lt;PC7),... zu (1&amp;lt;&amp;lt;7)). Ein Ausschnitt der Definitionen für Port C eines ATmega32 aus der iom32.h-Datei zur Verdeutlichung (analog für die weiteren Ports):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
/* PORTC */&lt;br /&gt;
#define PC7     7&lt;br /&gt;
#define PC6     6&lt;br /&gt;
#define PC5     5&lt;br /&gt;
#define PC4     4&lt;br /&gt;
#define PC3     3&lt;br /&gt;
#define PC2     2&lt;br /&gt;
#define PC1     1&lt;br /&gt;
#define PC0     0&lt;br /&gt;
&lt;br /&gt;
/* DDRC */&lt;br /&gt;
#define DDC7    7&lt;br /&gt;
#define DDC6    6&lt;br /&gt;
#define DDC5    5&lt;br /&gt;
#define DDC4    4&lt;br /&gt;
#define DDC3    3&lt;br /&gt;
#define DDC2    2&lt;br /&gt;
#define DDC1    1&lt;br /&gt;
#define DDC0    0&lt;br /&gt;
&lt;br /&gt;
/* PINC */&lt;br /&gt;
#define PINC7   7&lt;br /&gt;
#define PINC6   6&lt;br /&gt;
#define PINC5   5&lt;br /&gt;
#define PINC4   4&lt;br /&gt;
#define PINC3   3&lt;br /&gt;
#define PINC2   2&lt;br /&gt;
#define PINC1   1&lt;br /&gt;
#define PINC0   0&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Digitale Signale ==&lt;br /&gt;
&lt;br /&gt;
Am einfachsten ist es, digitale Signale mit dem Mikrocontroller zu erfassen bzw. auszugeben.&lt;br /&gt;
&lt;br /&gt;
== Ausgänge ==&lt;br /&gt;
Will man als Ausgang definierte Pins (entsprechende DDRx-Bits = 1) auf Logisch 1 setzen, setzt man die  entsprechenden Bits im Portregister.&lt;br /&gt;
&lt;br /&gt;
Mit dem Befehl&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
    PORTB = 0x04; /* besser PORTB=(1&amp;lt;&amp;lt;PB2) */&lt;br /&gt;
&lt;br /&gt;
    // übersichtliche Alternative - Binärschreibweise&lt;br /&gt;
    PORTB = 0b00000100;    /* direkte Zuweisung - übersichtlich */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
wird also der Ausgang an Pin PB2 gesetzt (Beachte, dass die Bits immer &#039;&#039;von 0 an&#039;&#039; gezählt werden, das niederwertigste Bit ist also Bitnummer 0 und nicht etwa Bitnummer 1).&lt;br /&gt;
&lt;br /&gt;
Man beachte, dass bei der Zuweisung mittels &#039;&#039;&#039;=&#039;&#039;&#039; immer alle Pins gleichzeitig angegeben werden. Man sollte also, wenn nur bestimmte Ausgänge geschaltet werden sollen, zuerst den aktuellen Wert des Ports einlesen und das Bit des gewünschten Ports in diesen Wert einfließen lassen. Will man also nur den dritten Pin (Bit Nr. 2) an Port B auf &amp;quot;high&amp;quot; setzen und den Status der anderen Ausgänge unverändert lassen, nutze man diese Form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
    PORTB = PORTB | 0x04; /* besser: PORTB = PORTB | ( 1&amp;lt;&amp;lt;PB2 ) */&lt;br /&gt;
    /* vereinfacht durch Nutzung des |= Operators : */&lt;br /&gt;
    PORTB |= (1&amp;lt;&amp;lt;PB2);&lt;br /&gt;
&lt;br /&gt;
    /* auch mehrere &amp;quot;gleichzeitig&amp;quot;: */&lt;br /&gt;
    PORTB |= (1&amp;lt;&amp;lt;PB4) | (1&amp;lt;&amp;lt;PB5); /* Pins PB4 und PB5 &amp;quot;high&amp;quot; */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Ausschalten&amp;quot;, also  Ausgänge auf &amp;quot;low&amp;quot; setzen, erfolgt analog:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
    PORTB &amp;amp;= ~(1&amp;lt;&amp;lt;PB2); /* löscht Bit 2 in PORTB und setzt damit Pin PB2 auf low */ &lt;br /&gt;
    PORTB &amp;amp;= ~( (1&amp;lt;&amp;lt;PB4) | (1&amp;lt;&amp;lt;PB5) ); /* Pin PB4 und Pin PB5 &amp;quot;low&amp;quot; */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Siehe auch [[Bitmanipulation]]&lt;br /&gt;
&lt;br /&gt;
In Quellcodes, die für ältere Version den des avr-gcc/der avr-libc entwickelt wurden, werden einzelne Bits mittels der Funktionen sbi und cbi gesetzt bzw. gelöscht. Beide Funktionen sind in aktuellen Versionen der avr-libc nicht mehr enthalten und auch nicht mehr erforderlich.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Falls der Anfangszustand von Ausgängen kritisch ist, muss die Reihenfolge beachtet werden, mit der die Datenrichtung (DDRx) eingestellt und der Ausgabewert (PORTx) gesetzt wird:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Für Ausgangspins, die mit Anfangswert &amp;quot;high&amp;quot; initialisiert werden sollen:&lt;br /&gt;
* zuerst die Bits im PORTx-Register setzen&lt;br /&gt;
* anschließend die Datenrichtung auf Ausgang stellen&lt;br /&gt;
&lt;br /&gt;
Daraus ergibt sich die Abfolge für einen Pin, der bisher als Eingang mit abgeschaltetem Pull-Up konfiguriert war:&lt;br /&gt;
* setze PORTx: interner Pull-Up aktiv&lt;br /&gt;
* setze DDRx: Ausgang (&amp;quot;high&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Bei der Reihenfolge erst DDRx und dann PORTx kann es zu einem kurzen &amp;quot;low-Puls&amp;quot; kommen, der auch externe Pull-Up-Widerstände &amp;quot;überstimmt&amp;quot;. Die (ungünstige) Abfolge: Eingang -&amp;gt; setze DDRx: Ausgang (auf &amp;quot;low&amp;quot;, da PORTx nach Reset 0) -&amp;gt; setze PORTx: Ausgang auf high. Vergleiche dazu auch das Datenblatt Abschnitt &#039;&#039;Configuring the Pin&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Eingänge (Wie kommen Signale in den &amp;amp;micro;C) ==&lt;br /&gt;
&lt;br /&gt;
Die digitalen Eingangssignale können auf verschiedene Arten zu unserer Logik gelangen.&lt;br /&gt;
&lt;br /&gt;
=== Signalkopplung ===&lt;br /&gt;
&lt;br /&gt;
Am einfachsten ist es, wenn die Signale direkt aus einer anderen digitalen Schaltung übernommen werden können. Hat der Ausgang der entsprechenden Schaltung TTL-Pegel dann können wir sogar direkt den Ausgang der Schaltung mit einem Eingangspin von unserem Controller verbinden.&lt;br /&gt;
&lt;br /&gt;
Hat der Ausgang der anderen Schaltung keinen TTL-Pegel so müssen wir den Pegel über entsprechende Hardware (z.&amp;amp;nbsp;B. Optokoppler, [[Widerstand#Spannungsteiler|Spannungsteiler]], &amp;quot;Levelshifter&amp;quot; aka [[Pegelwandler]]) anpassen.&lt;br /&gt;
&lt;br /&gt;
Die Masse der beiden Schaltungen muss selbstverständlich miteinander verbunden werden. Der Software selber ist es natürlich letztendlich egal, wie das Signal eingespeist wird. Wir können ja ohnehin lediglich prüfen, ob an einem Pin unseres Controllers eine logische 1 (Spannung größer ca. 0,7*Vcc) oder eine logische 0 (Spannung kleiner ca. 0,2*Vcc) anliegt. Detaillierte Informationen darüber, ab welcher Spannung ein Eingang als 0 (&amp;quot;low&amp;quot;) bzw. 1 (&amp;quot;high&amp;quot;) erkannt wird, liefert die Tabelle DC Characteristics im Datenblatt des genutzten Controllers.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Spannungstabelle&#039;&#039;&#039; &amp;lt;br /&amp;gt; &amp;lt;small&amp;gt;(ca. Grenzwerte)&amp;lt;/small&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
! Low || High&lt;br /&gt;
|-&lt;br /&gt;
! bei 5 V&lt;br /&gt;
| 1 V || 3,5 V&lt;br /&gt;
|-&lt;br /&gt;
! bei 3,3 V&lt;br /&gt;
| 0,66 V || 2,31 V&lt;br /&gt;
|-&lt;br /&gt;
! bei 1,8 V&lt;br /&gt;
| 0,36 V || 1,26 V&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Abfrage der Zustände der Portpins erfolgt direkt über den Registernamen.&lt;br /&gt;
&lt;br /&gt;
{{Warnung|Dabei ist wichtig, zur Abfrage der Eingänge &#039;&#039;nicht&#039;&#039; etwa Portregister &#039;&#039;&#039;PORTx&#039;&#039;&#039; zu verwenden, sondern Eingangsregister &#039;&#039;&#039;PINx&#039;&#039;&#039;. Ansonsten liest man nicht den Zustand der Eingänge, sondern den Status der internen Pull-Up-Widerstände. Die Abfrage der Pinzustände über PORTx statt PINx ist ein häufiger Fehler beim AVR-&amp;quot;Erstkontakt&amp;quot;.}}&lt;br /&gt;
&lt;br /&gt;
Will man also die aktuellen Signalzustände von Port D abfragen und in eine Variable namens bPortD abspeichern, schreibt man folgende Befehlszeilen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
uint8_t bPortD;&lt;br /&gt;
...&lt;br /&gt;
bPortD = PIND;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit den C-Bitoperationen kann man den Status der Bits abfragen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
/* Fuehre Aktion aus, wenn Bit Nr. 1 (das &amp;quot;zweite&amp;quot; Bit) in PINC gesetzt (1) ist */&lt;br /&gt;
if ( PINC &amp;amp; (1&amp;lt;&amp;lt;PINC1) ) {&lt;br /&gt;
  /* Aktion */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Fuehre Aktion aus, wenn Bit Nr. 2 (das &amp;quot;dritte&amp;quot; Bit) in PINB geloescht (0) ist */&lt;br /&gt;
if ( !(PINB &amp;amp; (1&amp;lt;&amp;lt;PINB2)) ) {&lt;br /&gt;
  /* Aktion */&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Siehe auch [[Bitmanipulation#Bits_prüfen]]&lt;br /&gt;
&lt;br /&gt;
=== Interne Pull-Up Widerstände ===&lt;br /&gt;
&lt;br /&gt;
Portpins für Ein- und Ausgänge (GPIO) eines AVR verfügen über zuschaltbare interne Pull-Up Widerstände (nominal mehrere 10kOhm, z.&amp;amp;nbsp;B. ATmega16 20-50kOhm). Diese können in vielen Fällen statt externer Widerstände genutzt werden.&lt;br /&gt;
&lt;br /&gt;
Die internen Pull-Up Widerstände von Vcc zu den einzelnen Portpins werden über das Register &#039;&#039;&#039; PORTx&#039;&#039;&#039; aktiviert bzw. deaktiviert, wenn ein Pin als &#039;&#039;&#039; Eingang&#039;&#039;&#039; geschaltet ist.&lt;br /&gt;
&lt;br /&gt;
Wird der Wert des entsprechenden Portpins auf 1 gesetzt, so ist der Pull-Up Widerstand aktiviert. Bei einem Wert von 0 ist der Pull-Up Widerstand nicht aktiv. Man sollte jeweils entweder den internen oder einen externen Pull-Up Widerstand verwenden, aber nicht beide zusammen.&lt;br /&gt;
&lt;br /&gt;
Im Beispiel werden alle Pins des Ports D als Eingänge geschaltet und alle Pull-Up Widerstände aktiviert. Weiterhin wird Pin PC7 als Eingang geschaltet und dessen interner Pull-Up Widerstand aktiviert, ohne die Einstellungen für die anderen Portpins (PC0-PC6) zu verändern.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
DDRD  = 0x00; /* alle Pins von Port D als Eingang */&lt;br /&gt;
PORTD = 0xff; /* interne Pull-Ups an allen Port-Pins aktivieren */&lt;br /&gt;
...&lt;br /&gt;
DDRC  &amp;amp;= ~(1&amp;lt;&amp;lt;PC7);  /* Pin PC7 als Eingang */&lt;br /&gt;
PORTC |= (1&amp;lt;&amp;lt;PC7);    /* internen Pull-Up an PC7 aktivieren */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Taster und Schalter ===&lt;br /&gt;
&lt;br /&gt;
Der Anschluss mechanischer Kontakte an den Mikrocontroller, ist zwischen zwei unterschiedliche Methoden zu unterscheiden: &#039;&#039;Active Low&#039;&#039; und &#039;&#039;Active High&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery widths=&amp;quot;300&amp;quot; heights=&amp;quot;300&amp;quot; caption=&amp;quot;Anschluss mechanischer Kontakte an einen µC&amp;quot;&amp;gt;&lt;br /&gt;
Image:Active Low.gif|&#039;&#039;&#039;Active Low:&#039;&#039;&#039; Bei dieser Methode wird der Kontakt zwischen den Eingangspin des Controllers und Masse geschaltet. Damit bei offenem Schalter der Controller kein undefiniertes Signal bekommt, wird zwischen die Versorgungsspannung und den Eingangspin ein sogenannter &#039;&#039;&#039;Pull-Up&#039;&#039;&#039; Widerstand geschaltet. Dieser dient dazu, den Pegel bei geöffnetem Schalter auf logisch 1 zu ziehen.&lt;br /&gt;
Image:Active High.gif|&#039;&#039;&#039;Active High:&#039;&#039;&#039; Hier wird der Kontakt zwischen die Versorgungsspannung und den Eingangspin geschaltet. Damit bei offener Schalterstellung kein undefiniertes Signal am Controller ansteht, wird zwischen den Eingangspin und die Masse ein &#039;&#039;&#039;Pull-Down&#039;&#039;&#039; Widerstand geschaltet. Dieser dient dazu, den Pegel bei geöffneter Schalterstellung auf logisch 0 zu halten. &lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Widerstandswert von Pull-Up- und Pull-Down-Widerständen ist an sich nicht kritisch. Wird er allerdings zu hoch gewählt, ist die Wirkung eventuell nicht gegeben. Als üblicher Wert haben sich 10 kOhm eingebürgert. Die AVRs verfügen an den meisten Pins über zuschaltbare interne Pull-Up Widerstände (vgl. Abschnitt [[AVR-GCC-Tutorial#Interne Pull-Up Widerstände|Interne Pull-Up Widerstände]]), welche insbesondere wie hier bei Tastern und ähnlichen Bauteilen (z.&amp;amp;nbsp;B. Drehgebern) statt externer Bauteile verwendet werden können. Interne Pull-Down-Widerstand sind nicht verfügbar und müssen daher in Form zusätzlicher Bauteile in die Schaltung eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
==== Taster entprellen ====&lt;br /&gt;
&lt;br /&gt;
Siehe: &#039;&#039;[[Entprellung#Warteschleifen-Verfahren|Entprellung: Warteschleifen-Verfahren]]&lt;br /&gt;
&lt;br /&gt;
= Warteschleifen (delay.h) =&lt;br /&gt;
&lt;br /&gt;
Der Programmablauf kann verschiedene Arten von Wartefunktionen erfordern:&lt;br /&gt;
&lt;br /&gt;
* Warten im Sinn von Zeitvertrödeln&lt;br /&gt;
* Warten auf einen bestimmten Zustand an den I/O-Pins&lt;br /&gt;
* Warten auf einen bestimmten Zeitpunkt (siehe Timer)&lt;br /&gt;
* Warten auf einen bestimmten Zählerstand (siehe Counter)&lt;br /&gt;
&lt;br /&gt;
Der einfachste Fall, das Zeitvertrödeln, kann in vielen Fällen und mit großer Genauigkeit anhand der avr-libc Bibliotheksfunktionen _delay_ms() und _delay_us() erledigt werden. Die Bibliotheksfunktionen sind einfachen Zählschleifen (Warteschleifen) vorzuziehen, da leere Zählschleifen ohne besondere Vorkehrungen sonst bei eingeschalteter Optimierung vom avr-gcc-Compiler wegoptimiert werden. Weiterhin sind die Bibliotheksfunktionen bereits darauf vorbereitet, die in F_CPU definierte Taktfrequenz zu verwenden. Außerdem sind die Funktionen der Bibliothek wirklich getestet.&lt;br /&gt;
&lt;br /&gt;
Einfach!? Schon, aber während gewartet wird, macht der µC nichts anderes mehr (abgesehen von möglicherweise auftretenden Interrupts, falls welche aktiviert sind). Die Wartefunktion blockiert den Programmablauf. Möchte man einerseits warten, um z.&amp;amp;nbsp;B. eine LED blinken zu lassen und gleichzeitig andere Aktionen ausführen z.&amp;amp;nbsp;B. weitere LED bedienen, sollten die Timer/Counter des AVR verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Die Bibliotheksfunktionen funktionieren allerdings nur dann korrekt, wenn sie mit zur Übersetzungszeit (beim Compilieren) bekannten konstanten Werten aufgerufen werden. Der Quellcode muss mit eingeschalteter Optimierung übersetzt werden, sonst wird sehr viel Maschinencode erzeugt, und die Wartezeiten stimmen nicht mehr mit dem Parameter überein.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Einschränkung liegt darin, daß sie möglicherweise länger warten, als erwartet, nämlich in dem Fall, daß Interrupts auftreten und die _delay...()-Funktion unterbrechen. Genau genommen warten diese nämlich nicht eine bestimmte Zeit, sondern verbrauchen eine bestimmte Anzahl von Prozessortakten. Die wiederum ist so bemessen, daß ohne Unterbrechung durch Interrupts die gewünschte Wartezeit erreicht wird.&lt;br /&gt;
Wird das Warten aber durch eine oder mehrere ISR unterbrochen, die zusammen 1% Prozessorzeit verbrauchen, dann dauert das Warten etwa 1% länger. Bei 50% Last durch die ISR dauert das Warten doppelt solange wie gewünscht, bei 90% zehnmal solange...&lt;br /&gt;
&lt;br /&gt;
Abhängig von der Version der Bibliothek verhalten sich die Bibliotheksfunktionen etwas unterschiedlich.&lt;br /&gt;
&lt;br /&gt;
== avr-libc Versionen bis 1.6 ==&lt;br /&gt;
&lt;br /&gt;
Die Wartezeit der Funktion _delay_ms() ist auf 262,14ms/F_CPU (in MHz) begrenzt, d.h. bei 20 MHz kann man nur max. 13,1ms warten. Die Wartezeit der Funktion _delay_us() ist auf 768us/F_CPU (in MHz) begrenzt, d.h. bei 20 MHz kann man nur max. 38,4µs warten. Längere Wartezeiten müssen dann über einen mehrfachen Aufruf in einer Schleife gelöst werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Blinken einer LED an PORTB Pin PB0 im ca. 1s Rhythmus&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert &lt;br /&gt;
   (z.&amp;amp;nbsp;B. durch Übergabe als Parameter zum Compiler innerhalb &lt;br /&gt;
   des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die&lt;br /&gt;
   &amp;quot;nachträgliche&amp;quot; Definition hinweist */&lt;br /&gt;
#warning &amp;quot;F_CPU war noch nicht definiert, wird nun mit 3686400 definiert&amp;quot;&lt;br /&gt;
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */&lt;br /&gt;
#endif&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;     /* in älteren avr-libc Versionen &amp;lt;avr/delay.h&amp;gt; */ &lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 lange, variable Verzögerungszeit, Einheit in Millisekunden&lt;br /&gt;
&lt;br /&gt;
Die maximale Zeit pro Funktionsaufruf ist begrenzt auf &lt;br /&gt;
262.14 ms / F_CPU in MHz (im Beispiel: &lt;br /&gt;
262.1 / 3.6864 = max. 71 ms) &lt;br /&gt;
&lt;br /&gt;
Daher wird die kleine Warteschleife mehrfach aufgerufen,&lt;br /&gt;
um auf eine längere Wartezeit zu kommen. Die zusätzliche &lt;br /&gt;
Prüfung der Schleifenbedingung lässt die Wartezeit geringfügig&lt;br /&gt;
ungenau werden (macht hier vielleicht 2-3ms aus).&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
void long_delay(uint16_t ms)&lt;br /&gt;
{&lt;br /&gt;
    for(; ms&amp;gt;0; ms--) _delay_ms(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main( void )&lt;br /&gt;
{&lt;br /&gt;
    DDRB = ( 1 &amp;lt;&amp;lt; PB0 );        // PB0 an PORTB als Ausgang setzen&lt;br /&gt;
&lt;br /&gt;
    while( 1 )                  // Endlosschleife&lt;br /&gt;
    {                &lt;br /&gt;
        PORTB ^= ( 1 &amp;lt;&amp;lt; PB0 );  // Toggle PB0 z.&amp;amp;nbsp;B. angeschlossene LED&lt;br /&gt;
        long_delay(1000);       // Eine Sekunde warten...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== avr-libc Versionen ab 1.7 ==&lt;br /&gt;
&lt;br /&gt;
_delay_ms() kann mit einem Argument bis 6553,5 ms (= 6,5535 Sekunden) benutzt werden. Es ist nicht möglich, eine Variable als Argument zu übergeben. Wird die früher gültige Grenze von 262,14 ms/F_CPU (in MHz) überschritten, so arbeitet _delay_ms() einfach etwas ungenauer und zählt nur noch mit einer Auflösung von 1/10 ms. Eine Verzögerung von 1000,10 ms ließe sich nicht mehr von einer von 1000,19 ms unterscheiden. Ein Verlust, der sich im Allgemeinen verschmerzen lässt. Dem Programmierer wird keine Rückmeldung gegeben, dass die Funktion ggf. gröber arbeitet, d.h. wenn es darauf ankommt, bitte den Parameter wie bisher geschickt wählen.&lt;br /&gt;
&lt;br /&gt;
Die Funktion _delay_us() wurde ebenfalls erweitert. Wenn deren maximal als genau behandelbares Argument überschritten wird, benutzt diese intern _delay_ms(). Damit gelten in diesem Fall die _delay_ms() Einschränkungen.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Blinken einer LED an PORTB Pin PB0 im ca. 1s Rhythmus, avr-libc ab Version 1.6&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert &lt;br /&gt;
   (z.B. durch Übergabe als Parameter zum Compiler innerhalb &lt;br /&gt;
   des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die&lt;br /&gt;
   &amp;quot;nachträgliche&amp;quot; Definition hinweist */&lt;br /&gt;
#warning &amp;quot;F_CPU war noch nicht definiert, wird nun mit 3686400 definiert&amp;quot;&lt;br /&gt;
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */&lt;br /&gt;
#endif&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main( void )&lt;br /&gt;
{&lt;br /&gt;
    DDRB = ( 1 &amp;lt;&amp;lt; PB0 );        // PB0 an PORTB als Ausgang setzen&lt;br /&gt;
&lt;br /&gt;
    while( 1 ) {                // Endlosschleife&lt;br /&gt;
        PORTB ^= ( 1 &amp;lt;&amp;lt; PB0 );  // Toggle PB0 z.B. angeschlossene LED&lt;br /&gt;
        _delay_ms(1000);        // Eine Sekunde +/-1/10000 Sekunde warten...&lt;br /&gt;
                                // funktioniert nicht mit Bibliotheken vor 1.6&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trick zur Übergabe einer Variablen an _delay_ms():&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
#warning &amp;quot;F_CPU war noch nicht definiert, wird nun mit 3686400 definiert&amp;quot;&lt;br /&gt;
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */&lt;br /&gt;
#endif&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void sleep ( uint8_t ms )&lt;br /&gt;
{&lt;br /&gt;
    for(; ms &amp;gt; 0; ms--) _delay_ms(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main( void )&lt;br /&gt;
{&lt;br /&gt;
    int x = 0;                  // Variable als Wartezeit erstellen&lt;br /&gt;
    DDRB = ( 1 &amp;lt;&amp;lt; PB0 );        // PB0 an PORTB als Ausgang setzen&lt;br /&gt;
&lt;br /&gt;
    while( 1 ) {                // Endlosschleife&lt;br /&gt;
        PORTB ^= ( 1 &amp;lt;&amp;lt; PB0 );  // Toggle PB0 z.B. angeschlossene LED&lt;br /&gt;
        sleep(x); &lt;br /&gt;
        x++;       &lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die _delay_ms() und die _delay_us aus &#039;&#039;&#039;avr-libc 1.7.0&#039;&#039;&#039; sind fehlerhaft. _delay_ms () läuft 4x schneller als erwartet. Abhilfe ist eine korrigierte Includedatei: [http://www.mikrocontroller.net/topic/196738#1943039]&lt;br /&gt;
&lt;br /&gt;
= Programmieren mit Interrupts =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:right; margin:2em;&amp;quot;&amp;gt;&lt;br /&gt;
[[Image:Interrupt Programme.gif]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Nachdem wir nun alles Wissenswerte für die serielle Programmerstellung&lt;br /&gt;
gelernt haben nehmen wir jetzt ein völlig anderes Thema in Angriff, nämlich&lt;br /&gt;
die Programmierung unter Zuhilfenahme der Interrupts des AVR.&lt;br /&gt;
&lt;br /&gt;
Tritt ein Interrupt auf, unterbricht (engl. interrupts) der Controller die Verarbeitung des Hauptprogramms und verzweigt zu einer Interruptroutine. Das Hauptprogramm wird also beim Eintreffen eines Interrupts unterbrochen, die Interruptroutine ausgeführt und danach erst wieder das Hauptprogramm an der Unterbrechungsstelle fortgesetzt (vgl. die Abbildung).&lt;br /&gt;
&lt;br /&gt;
Um Interrupts verarbeiten zu können, ist folgendes zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Für jede aktivierte Interruptquelle ist eine Funktion zu programmieren, in der die beim Auftreten des jeweiligen Interrupts erforderlichen Verarbeitungsschritte enthalten sind. Für diese Funktion existieren verschiedene Bezeichnungen. Üblich sind die englischen Begriffe Interrupt-Handler oder Interrupt-Service-Routinen (ISR), man findet aber auch die Bezeichnungen Interruptverarbeitungs- oder -behandlungsroutine oder auch kurz Interuptroutine. Zum Beispiel wird üblicherweise in der ISR zur Verarbeitung des Empfangsinterrupts eines UARTs (UART-RX Interrupt) das empfangene Zeichen in einen Zwischenspeicher (FIFO-Buffer) kopiert, dessen Inhalt später von anderen Programmteilen geleert wird. Sofern der Zwischenspeicher ausreichend groß ist, geht also kein Zeichen verloren, auch wenn im Hauptprogramm zeitintensive Operationen durchgeführt werden.&lt;br /&gt;
* Die benötigten Interrupts sind in den jeweiligen Funktionsbausteinen einzuschalten. Dies erfolgt über das jeweilige Aktivierungsbit (Interrupt Enable) in einem der Hardwareregister (z.B. RX(Complete)Interrupt Enable eines UARTs)&lt;br /&gt;
* Sämtliche Interrupts werden über einen weiteren globalen Schalter aktiviert und deaktiviert. Zur Verarbeitung der Interrupts ist dieser Schalter zu aktivieren (sei(), siehe unten).&lt;br /&gt;
 &lt;br /&gt;
Alle Punkte sind zu beachten. Fehlt z.B. die globale Aktivierung, werden Interruptroutinen auch dann nicht aufgerufen, wenn sie im Funktionsbaustein eingeschaltet sind und eine Behandlungsroutine verhanden ist.&lt;br /&gt;
&lt;br /&gt;
Siehe auch&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-1-235092.html#new Ausführlicher Thread im Forum]&lt;br /&gt;
* Artikel [[Interrupt]]&lt;br /&gt;
* Artikel [[Multitasking]]&lt;br /&gt;
{{Clear}}&lt;br /&gt;
&lt;br /&gt;
== Anforderungen an Interrupt-Routinen ==&lt;br /&gt;
&lt;br /&gt;
Um unliebsamen Überraschungen vorzubeugen, sollten einige Grundregeln bei der Implementierung der Interruptroutinen beachtet werden. Interruptroutinen sollten möglichst kurz und schnell abarbeitbar sein, daraus folgt:&lt;br /&gt;
&lt;br /&gt;
* Keine umfangreichen Berechnungen innerhalb der Interruptroutine. (*)&lt;br /&gt;
* Keine langen Programmschleifen.&lt;br /&gt;
* Obwohl es möglich ist, während der Abarbeitung einer Interruptroutine andere oder sogar den gleichen Interrupt wieder zuzulassen, wird davon ohne genaue Kenntnis der internen Abläufe dringend abgeraten.&lt;br /&gt;
&lt;br /&gt;
Interruptroutinen (ISRs) sollten also möglichst kurz sein und keine Schleifen mit vielen Durchläufen enthalten. Längere Operationen können meist in einen &amp;quot;Interrupt-Teil&amp;quot; in einer ISR und einen &amp;quot;Arbeitsteil&amp;quot; im Hauptprogramm aufgetrennt werden. Z.B. Speichern des Zustands aller Eingänge im EEPROM in bestimmten Zeitabständen: ISR-Teil: Zeitvergleich (Timer,RTC) mit Logzeit/-intervall. Bei Übereinstimmung ein globales Flag setzen (volatile bei Flag-Deklaration nicht vergessen, s.u.). Dann im Hauptprogramm prüfen, ob das Flag gesetzt ist. Wenn ja: die Daten im EEPROM ablegen und Flag löschen.&lt;br /&gt;
&lt;br /&gt;
(*)&lt;br /&gt;
Hinweis: &lt;br /&gt;
Es gibt allerdings die seltene Situation, dass man gerade eingelesene&lt;br /&gt;
ADC-Werte sofort verarbeiten muss. Besonders dann, wenn man mehrere Werte sehr&lt;br /&gt;
schnell hintereinander bekommt. Dann bleibt einem nichts anderes übrig, als die&lt;br /&gt;
Werte noch in der ISR zu verarbeiten. Kommt aber sehr selten vor und sollte&lt;br /&gt;
durch geeignete Wahl des Systemtaktes bzw. Auswahl des Controllers vermieden werden!&lt;br /&gt;
&lt;br /&gt;
== Interrupt-Quellen ==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Ereignisse können einen Interrupt auf einem AVR AT90S2313 auslösen, wobei die Reihenfolge der Auflistung auch die Priorität der Interrupts aufzeigt.&lt;br /&gt;
&lt;br /&gt;
* Reset&lt;br /&gt;
* Externer Interrupt 0&lt;br /&gt;
* Externer Interrupt 1&lt;br /&gt;
* Timer/Counter 1 Capture Ereignis&lt;br /&gt;
* Timer/Counter 1 Compare Match&lt;br /&gt;
* Timer/Counter 1 Überlauf&lt;br /&gt;
* Timer/Counter 0 Überlauf&lt;br /&gt;
* UART Zeichen empfangen&lt;br /&gt;
* UART Datenregister leer&lt;br /&gt;
* UART Zeichen gesendet&lt;br /&gt;
* Analoger Komparator&lt;br /&gt;
&lt;br /&gt;
Die Anzahl der möglichen Interruptquellen variiert zwischen den verschiedenen Microcontroller-Typen. Im Zweifel hilft ein Blick ins Datenblatt (&amp;quot;Interrupt Vectors&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
== Register ==&lt;br /&gt;
&lt;br /&gt;
Der AT90S2313 verfügt über 2 Register die mit den&lt;br /&gt;
Interrupts zusammen hängen.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;GIMSK&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;G&#039;&#039;&#039;eneral &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;M&#039;&#039;&#039;a&#039;&#039;&#039;sk&#039;&#039;&#039; Register.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit &lt;br /&gt;
| 7 || 6|| 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;INT1&#039;&#039;&#039; || &#039;&#039;&#039;INT0&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W || R/W || R || R || R || R || R || R&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;INT1&#039;&#039;&#039; (External &#039;&#039;&#039;Int&#039;&#039;&#039;errupt Request &#039;&#039;&#039;1&#039;&#039;&#039; Enable)&lt;br /&gt;
:Wenn dieses Bit gesetzt ist, wird ein Interrupt ausgelöst, wenn am &#039;&#039;&#039;INT1&#039;&#039;&#039;-Pin eine steigende oder fallende (je nach Konfiguration im &#039;&#039;&#039;MCUCR&#039;&#039;&#039;) Flanke erkannt wird.&lt;br /&gt;
:Das Global Enable Interrupt Flag muss selbstverständlich auch gesetzt sein.&lt;br /&gt;
:Der Interrupt wird auch ausgelöst, wenn der Pin als Ausgang geschaltet ist. Auf diese Weise bietet sich die Möglichkeit, Software-Interrupts zu realisieren.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;INT0&#039;&#039;&#039; (External &#039;&#039;&#039;Int&#039;&#039;&#039;errupt Request &#039;&#039;&#039;0&#039;&#039;&#039; Enable)&lt;br /&gt;
:Wenn dieses Bit gesetzt ist, wird ein Interrupt ausgelöst, wenn am &#039;&#039;&#039;INT0&#039;&#039;&#039;-Pin eine steigende oder fallende (je nach Konfiguration im &#039;&#039;&#039;MCUCR&#039;&#039;&#039;) Flanke erkannt wird.&lt;br /&gt;
:Das Global Enable Interrupt Flag muss selbstverständlich auch gesetzt sein.&lt;br /&gt;
:Der Interrupt wird auch ausgelöst, wenn der Pin als Ausgang geschaltet ist. Auf diese Weise bietet sich die Möglichkeit, Software-Interrupts zu realisieren.&lt;br /&gt;
&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;GIFR&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;G&#039;&#039;&#039;eneral &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;F&#039;&#039;&#039;lag &#039;&#039;&#039;R&#039;&#039;&#039;egister.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;INTF1&#039;&#039;&#039; || &#039;&#039;&#039;INTF0&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W || R/W || R || R || R || R || R || R&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;INTF1&#039;&#039;&#039; (External &#039;&#039;&#039;Int&#039;&#039;&#039;errupt Flag &#039;&#039;&#039;1&#039;&#039;&#039;)&lt;br /&gt;
:Dieses Bit wird gesetzt, wenn am &#039;&#039;&#039;INT1&#039;&#039;&#039;-Pin eine Interrupt-Bedingung, entsprechend der Konfiguration, als eingetreten erkannt wird. Wenn das Global Enable Interrupt Flag gesetzt ist, wird die Interruptroutine angesprungen.&lt;br /&gt;
:Das Flag wird automatisch gelöscht, wenn die Interruptroutine beendet ist. Alternativ kann das Flag gelöscht werden, indem der Wert &#039;&#039;&#039;1(!)&#039;&#039;&#039; eingeschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;INTF0&#039;&#039;&#039; (External &#039;&#039;&#039;Int&#039;&#039;&#039;errupt Flag &#039;&#039;&#039;0&#039;&#039;&#039;)&lt;br /&gt;
:Dieses Bit wird gesetzt, wenn am &#039;&#039;&#039;INT0&#039;&#039;&#039;-Pin eine Interrupt-Bedingung, entsprechend der Konfiguration, als eingetreten erkannt wird. Wenn das Global Enable Interrupt Flag gesetzt ist, wird die Interruptroutine angesprungen.&lt;br /&gt;
:Das Flag wird automatisch gelöscht, wenn die Interruptroutine beendet ist. Alternativ kann das Flag gelöscht werden, indem der Wert &#039;&#039;&#039;1(!)&#039;&#039;&#039; eingeschrieben wird.&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;MCUCR&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;MCU&#039;&#039;&#039; &#039;&#039;&#039;C&#039;&#039;&#039;ontrol &#039;&#039;&#039;R&#039;&#039;&#039;egister.&lt;br /&gt;
&lt;br /&gt;
Das MCU Control Register enthält Kontrollbits für allgemeine MCU-Funktionen.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;SE&#039;&#039;&#039;|| &#039;&#039;&#039;SM&#039;&#039;&#039;|| &#039;&#039;&#039;ISC11&#039;&#039;&#039;|| &#039;&#039;&#039;ISC10&#039;&#039;&#039;|| &#039;&#039;&#039;ISC01&#039;&#039;&#039;|| &#039;&#039;&#039;ISC00&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R || R || R/W || R/W || R/W || R/W || R/W || R/W&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SE&#039;&#039;&#039; (&#039;&#039;&#039;S&#039;&#039;&#039;leep &#039;&#039;&#039;E&#039;&#039;&#039;nable)&lt;br /&gt;
:Dieses Bit muss gesetzt sein, um den Controller mit dem &#039;&#039;&#039;SLEEP&#039;&#039;&#039;-Befehl in den Schlafzustand versetzen zu können.&lt;br /&gt;
:Um den Schlafmodus nicht irrtümlich einzuschalten, wird empfohlen, das Bit erst unmittelbar vor Ausführung des &#039;&#039;&#039;SLEEP&#039;&#039;&#039;-Befehls zu setzen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SM&#039;&#039;&#039; (&#039;&#039;&#039;S&#039;&#039;&#039;leep &#039;&#039;&#039;M&#039;&#039;&#039;ode)&lt;br /&gt;
:Dieses Bit bestimmt über den Schlafmodus.&lt;br /&gt;
:Ist das Bit gelöscht, so wird der &#039;&#039;&#039;Idle&#039;&#039;&#039;-Modus ausgeführt. Ist das Bit gesetzt, so wird der &#039;&#039;&#039;Power-Down&#039;&#039;&#039;-Modus ausgeführt. (für andere AVR Controller siehe Abschnitt &amp;quot;Sleep-Mode&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ISC11&#039;&#039;&#039;, &#039;&#039;&#039;ISC10&#039;&#039;&#039; (&#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;S&#039;&#039;&#039;ense &#039;&#039;&#039;C&#039;&#039;&#039;ontrol &#039;&#039;&#039;1&#039;&#039;&#039; Bits)&lt;br /&gt;
:Diese beiden Bits bestimmen, ob die steigende oder die fallende Flanke für die Interrupterkennung am &#039;&#039;&#039;INT1&#039;&#039;&#039;-Pin ausgewertet wird.&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! ISC11 || ISC10 || Bedeutung&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Low Level an &#039;&#039;&#039;INT1&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
&lt;br /&gt;
Der Interrupt wird getriggert, solange der Pin auf 0 bleibt.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Reserviert&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Die fallende Flanke an &#039;&#039;&#039;INT1&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Die steigende Flanke an &#039;&#039;&#039;INT1&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ISC01&#039;&#039;&#039;, &#039;&#039;&#039;ISC00&#039;&#039;&#039; (&#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;S&#039;&#039;&#039;ense &#039;&#039;&#039;C&#039;&#039;&#039;ontrol &#039;&#039;&#039;0&#039;&#039;&#039; Bits)&lt;br /&gt;
:Diese beiden Bits bestimmen, ob die steigende oder die fallende Flanke für die Interrupterkennung am &#039;&#039;&#039;INT0&#039;&#039;&#039;-Pin ausgewertet wird.&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! ISC01 || ISC00 || Bedeutung&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Low Level an &#039;&#039;&#039;INT0&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
&lt;br /&gt;
Der Interrupt wird getriggert, solange der Pin auf 0 bleibt.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Reserviert&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Die fallende Flanke an &#039;&#039;&#039;INT0&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Die steigende Flanke an &#039;&#039;&#039;INT0&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Allgemeines über die Interrupt-Abarbeitung ==&lt;br /&gt;
&lt;br /&gt;
Wenn ein Interrupt eintrifft, wird automatisch das &#039;&#039;&#039;Global Interrupt Enable&#039;&#039;&#039; Bit im Status Register &#039;&#039;&#039;SREG&#039;&#039;&#039; gelöscht und alle weiteren Interrupts unterbunden. Obwohl es möglich ist, zu diesem Zeitpunkt bereits wieder das GIE-bit zu setzen, wird dringend davon abgeraten. Dieses wird nämlich automatisch gesetzt, wenn die Interruptroutine beendet wird. Wenn in der Zwischenzeit weitere Interrupts eintreffen, werden die zugehörigen Interrupt-Bits gesetzt und die Interrupts bei Beendigung der laufenden Interrupt-Routine in der Reihenfolge ihrer Priorität ausgeführt. Dies kann&lt;br /&gt;
eigentlich nur dann zu Problemen führen, wenn ein hoch priorisierter Interrupt ständig und in kurzer Folge auftritt. Dieser sperrt dann möglicherweise alle anderen Interrupts mit niedrigerer Priorität. Dies ist einer der Gründe, weshalb die Interrupt-Routinen sehr kurz gehalten werden sollen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- === Das Status-Register ===&lt;br /&gt;
&lt;br /&gt;
Es gilt auch zu beachten, dass das Status-Register während der Abarbeitung einer Interruptroutine nicht automatisch gesichert wird. Falls notwendig, muss dies vom Programmierer selber vorgesehen werden. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interrupts mit dem AVR GCC Compiler (WinAVR) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- &#039;&#039;Anmerkung eines Nutzers: Ich habe mir das Thema hier angearbeitet und hatte am Anfang starke Probleme: Jeder Interrupt muss nochmals einzeln aktiviert werden. Es reicht nicht nur per &#039;&#039;sei()&#039;&#039; die Interrupts global zu aktiveren.&#039;&#039; - mthomas: Hoffentlich duch die modifizerte Einleitung etwas offensichtlicher erläutert. Ansonsten bitte per Eintrag auf die Diskussionseite nochmals melden) --&amp;gt; &lt;br /&gt;
&amp;lt;!-- Selbstverständlich können alle interruptspezifischen Registerzugriffe wie gewohnt über I/O-Adressierung vorgenommen werden. Etwas einfacher geht es jedoch, wenn wir die vom Compiler zur Verfügung gestellten Mittel einsetzen.--&amp;gt;&lt;br /&gt;
Funktionen zur Interrupt-Verarbeitung werden in den Includedateien &#039;&#039;interrupt.h&#039;&#039;  der avr-libc zur Verfügung gestellt (bei älterem Quellcode zusätzlich &#039;&#039;signal.h&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// fuer sei(), cli() und ISR():&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Makro &#039;&#039;&#039;sei()&#039;&#039;&#039; schaltet die Interrupts ein. Eigentlich wird nichts anderes gemacht, als das &#039;&#039;&#039;Global Interrupt Enable&#039;&#039;&#039; Bit im Status Register gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    sei();&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Makro &#039;&#039;&#039;cli()&#039;&#039;&#039; schaltet die Interrupts aus, oder anders gesagt, das &#039;&#039;&#039;Global Interrupt Enable&#039;&#039;&#039; Bit im Status Register wird gelöscht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    cli();&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oft steht man vor der Aufgabe, dass eine Codesequenz nicht unterbrochen werden darf. Es liegt dann nahe, zu Beginn dieser Sequenz ein cli() und am Ende ein sei() einzufügen. Dies ist jedoch ungünstig, wenn die Interrupts vor Aufruf der Sequenz deaktiviert waren und danach auch weiterhin deaktiviert bleiben sollen. Ein sei() würde ungeachtet des vorherigen  Zustands die Interrupts aktivieren, was zu unerwünschten Seiteneffekten führen kann. Die aus dem folgenden Beispiel ersichtliche Vorgehensweise ist in solchen Fällen vorzuziehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
#include &amp;lt;inttypes.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
void NichtUnterbrechenBitte(void)&lt;br /&gt;
{&lt;br /&gt;
   uint8_t tmp_sreg;  // temporaerer Speicher fuer das Statusregister&lt;br /&gt;
&lt;br /&gt;
   tmp_sreg = SREG;   // Statusregister (also auch das I-Flag darin) sichern&lt;br /&gt;
   cli();             // Interrupts global deaktivieren&lt;br /&gt;
&lt;br /&gt;
   /* hier &amp;quot;unterbrechnungsfreier&amp;quot; Code */&lt;br /&gt;
&lt;br /&gt;
   /* Beispiel Anfang&lt;br /&gt;
     JTAG-Interface eines ATmega16 per Software deaktivieren &lt;br /&gt;
     und damit die JTAG-Pins an PORTC für &amp;quot;general I/O&amp;quot; nutzbar machen&lt;br /&gt;
     ohne die JTAG-Fuse-Bit zu aendern. Dazu ist eine &amp;quot;timed sequence&amp;quot;&lt;br /&gt;
     einzuhalten (vgl Datenblatt ATmega16, Stand 10/04, S. 229): &lt;br /&gt;
     Das JTD-Bit muss zweimal innerhalb von 4 Taktzyklen geschrieben &lt;br /&gt;
     werden. Ein Interrupt zwischen den beiden Schreibzugriffen wuerde &lt;br /&gt;
     die erforderliche Sequenz &amp;quot;brechen&amp;quot;, das JTAG-Interface bliebe&lt;br /&gt;
     weiterhin aktiv und die IO-Pins weiterhin für JTAG reserviert. */&lt;br /&gt;
&lt;br /&gt;
   MCUCSR |= (1&amp;lt;&amp;lt;JTD);&lt;br /&gt;
   MCUCSR |= (1&amp;lt;&amp;lt;JTD); // 2 mal in Folge ,vgl. Datenblatt fuer mehr Information&lt;br /&gt;
&lt;br /&gt;
   /* Beispiel Ende */&lt;br /&gt;
  &lt;br /&gt;
   SREG = tmp_sreg;     // Status-Register wieder herstellen &lt;br /&gt;
                      // somit auch das I-Flag auf gesicherten Zustand setzen&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NichtSoGut(void)&lt;br /&gt;
{&lt;br /&gt;
   cli();&lt;br /&gt;
   &lt;br /&gt;
   /* hier &amp;quot;unterbrechnungsfreier&amp;quot; Code */&lt;br /&gt;
   &lt;br /&gt;
   sei();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
   //...&lt;br /&gt;
&lt;br /&gt;
   cli();  &lt;br /&gt;
   // Interrupts global deaktiviert &lt;br /&gt;
&lt;br /&gt;
   NichtUnterbrechenBitte();&lt;br /&gt;
   // auch nach Aufruf der Funktion deaktiviert&lt;br /&gt;
&lt;br /&gt;
   sei();&lt;br /&gt;
   // Interrupts global aktiviert &lt;br /&gt;
&lt;br /&gt;
   NichtUnterbrechenBitte();&lt;br /&gt;
   // weiterhin aktiviert&lt;br /&gt;
   //...&lt;br /&gt;
&lt;br /&gt;
   /* Verdeutlichung der unguenstigen Vorgehensweise mit cli/sei: */&lt;br /&gt;
   cli();  &lt;br /&gt;
   // Interrupts jetzt global deaktiviert &lt;br /&gt;
&lt;br /&gt;
   NichtSoGut();&lt;br /&gt;
   // nach Aufruf der Funktion sind Interrupts global aktiviert &lt;br /&gt;
   // dies ist mglw. ungewollt!&lt;br /&gt;
   //...&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- mt: besser so nicht(?), lieber &amp;quot;datenblattkonform&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font face=&amp;quot;Courier New&amp;quot;&amp;gt;&#039;&#039;&#039;timer_enable_int (unsigned char ints);&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;/font&amp;gt;Schaltet Timerbezogene Interrupts ein bzw. aus.&amp;lt;br /&amp;gt;&lt;br /&gt;
Wenn als Argument &#039;&#039;&#039;ints&#039;&#039;&#039; der Wert 0 übergeben wird so werden alle&lt;br /&gt;
Timerinterrupts ausgeschaltet, ansonsten muss in &#039;&#039;&#039;ints&#039;&#039;&#039; angegeben werden,&lt;br /&gt;
welche Interrupts zu aktivieren sind. Dabei müssen einfach die entsprechend zu&lt;br /&gt;
setzenden Bits definiert werden.&amp;lt;br /&amp;gt;&lt;br /&gt;
Beispiel: &#039;&#039;&#039;&amp;lt;font face=&amp;quot;Courier New&amp;quot;&amp;gt;timer_enable_int (1 &amp;lt;&amp;lt; TOIE1));&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;/font&amp;gt;&#039;&#039;&#039;Achtung: Wenn ein Timerinterrupt eingeschaltet wird während ein&lt;br /&gt;
anderer Timerinterrupt bereits läuft, dann müssen beide Bits angegeben werden&lt;br /&gt;
sonst wird der andere Timerinterrupt versehentlich ausgeschaltet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font face=&amp;quot;Courier New&amp;quot;&amp;gt;&#039;&#039;&#039;enable_external_int (unsigned char ints);&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;/font&amp;gt;Schaltet die externen Interrupts ein bzw. aus.&amp;lt;br /&amp;gt;&lt;br /&gt;
Wenn als Argument &#039;&#039;&#039;ints&#039;&#039;&#039; der Wert 0 übergeben wird so werden alle externen&lt;br /&gt;
Interrrups ausgeschaltet, ansonsten muss in &#039;&#039;&#039;ints&#039;&#039;&#039; angegeben werden, welche&lt;br /&gt;
Interrupts zu aktivieren sind. Dabei müssen einfach die entsprechend zu&lt;br /&gt;
setzenden Bits definiert werden.&amp;lt;br /&amp;gt;&lt;br /&gt;
Beispiel: &#039;&#039;&#039;&amp;lt;font face=&amp;quot;Courier New&amp;quot;&amp;gt;enable_external_int ((1&amp;lt;&lt;br /&gt;
&amp;lt;/font&amp;gt;&#039;&#039;&#039;Schaltet die externen Interrupts 0 und 1 ein.&lt;br /&gt;
&lt;br /&gt;
Nachdem nun die Interrupts aktiviert sind, braucht es selbstverständlich noch den auszuführenden Code, der ablaufen soll, wenn ein Interrupt eintrifft.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Zu den aktivierten Interrupts ist eine Funktion zu programmieren, deren Code aufgerufen wird, wenn der betreffende Interrupt auftritt (Interrupt-Handler, Interrupt-Service-Routine). Dazu existiert die Definition (ein Makro) &#039;&#039;&#039;ISR&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== ISR ===&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;ISR()&#039;&#039; ersetzt bei neueren Versionen der avr-libc &#039;&#039;SIGNAL()&#039;&#039;. SIGNAL sollte nicht mehr genutzt werden, zur Portierung von SIGNAL nach ISR siehe den [[AVR-GCC-Tutorial#Anhang|Anhang]].)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
ISR(Vectorname) /* vormals: SIGNAL(siglabel) dabei Vectorname != siglabel ! */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;ISR&#039;&#039; wird eine Funktion für die Bearbeitung eines Interrupts eingeleitet. Als Argument muss dabei die Benennung des entsprechenden Interruptvektors angegeben werden. Diese sind in den jeweiligen Includedateien IOxxxx.h zu finden. Die Bezeichnung entspricht dem Namen aus dem Datenblatt, bei dem die Leerzeichen durch Unterstriche ersetzt sind und ein &#039;&#039;_vect&#039;&#039; angehängt ist.&lt;br /&gt;
&lt;br /&gt;
Als Beispiel ein Ausschnitt aus der Datei für den ATmega8 (bei WinAVR Standardinstallation in C:\WinAVR\avr\include\avr\iom8.h) in der neben den aktuellen Namen für &#039;&#039;ISR&#039;&#039; (*_vect) noch die Bezeichnungen für das inzwischen nicht mehr aktuelle &#039;&#039;SIGNAL&#039;&#039; (SIG_*) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
/* $Id: iom8.h,v 1.13 2005/10/30 22:11:23 joerg_wunsch Exp $ */&lt;br /&gt;
&lt;br /&gt;
/* avr/iom8.h  - definitions for ATmega8 */&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
/* Interrupt vectors */&lt;br /&gt;
&lt;br /&gt;
/* External Interrupt Request 0 */&lt;br /&gt;
#define INT0_vect                       _VECTOR(1)&lt;br /&gt;
#define SIG_INTERRUPT0                  _VECTOR(1)&lt;br /&gt;
&lt;br /&gt;
/* External Interrupt Request 1 */&lt;br /&gt;
#define INT1_vect                       _VECTOR(2)&lt;br /&gt;
#define SIG_INTERRUPT1                  _VECTOR(2)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter2 Compare Match */&lt;br /&gt;
#define TIMER2_COMP_vect                _VECTOR(3)&lt;br /&gt;
#define SIG_OUTPUT_COMPARE2             _VECTOR(3)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter2 Overflow */&lt;br /&gt;
#define TIMER2_OVF_vect                 _VECTOR(4)&lt;br /&gt;
#define SIG_OVERFLOW2                   _VECTOR(4)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter1 Capture Event */&lt;br /&gt;
#define TIMER1_CAPT_vect                _VECTOR(5)&lt;br /&gt;
#define SIG_INPUT_CAPTURE1              _VECTOR(5)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter1 Compare Match A */&lt;br /&gt;
#define TIMER1_COMPA_vect               _VECTOR(6)&lt;br /&gt;
#define SIG_OUTPUT_COMPARE1A            _VECTOR(6)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter1 Compare Match B */&lt;br /&gt;
#define TIMER1_COMPB_vect               _VECTOR(7)&lt;br /&gt;
#define SIG_OUTPUT_COMPARE1B            _VECTOR(7)&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--Vor Nutzung von SIGNAL muss ebenfalls die Header-Datei signal.h eingebunden werden.--&amp;gt; &lt;br /&gt;
Mögliche Funktionsrümpfe für Interruptfunktionen sind zum Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
/* veraltet: #include &amp;lt;avr/signal.h&amp;gt; */&lt;br /&gt;
&lt;br /&gt;
ISR(INT0_vect)       /* veraltet: SIGNAL(SIG_INTERRUPT0) */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER0_OVF_vect) /* veraltet: SIGNAL(SIG_OVERFLOW0) */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ISR(USART_RXC_vect) /* veraltet: SIGNAL(SIG_UART_RECV) */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// und so weiter und so fort...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auf die korrekte Schreibweise der Vektorbezeichnung ist zu achten. Der gcc-Compiler prüft erst ab Version 4.x, ob ein Signal/Interrupt der angegebenen Bezeichnung tatsächlich in der Includedatei definiert ist und gibt andernfalls eine Warnung aus. Bei WinAVR (ab 2/2005) wurde die Überprüfung auch in den mitgelieferten Compiler der Version 3.x integriert. Aus dem gcc-Quellcode Version 3.x selbst erstellte Compiler enthalten die Prüfung nicht (vgl. [[AVR-GCC]]). &lt;br /&gt;
&lt;br /&gt;
Während der Ausführung der Funktion sind alle weiteren Interrupts automatisch gesperrt. Beim Verlassen der Funktion werden die Interrupts wieder zugelassen.&lt;br /&gt;
&lt;br /&gt;
Sollte während der Abarbeitung der Interruptroutine ein weiterer Interrupt (gleiche oder andere Interruptquelle) auftreten, so wird das entsprechende Bit im zugeordneten Interrupt Flag Register gesetzt und die entsprechende Interruptroutine automatisch nach dem Beenden der aktuellen Funktion aufgerufen.&lt;br /&gt;
&lt;br /&gt;
Ein Problem ergibt sich eigentlich nur dann, wenn während der Abarbeitung der aktuellen Interruptroutine mehrere gleichartige Interrupts auftreten. Die entsprechende Interruptroutine wird im Nachhinein zwar aufgerufen jedoch wissen wir nicht, ob nun der entsprechende Interrupt einmal, zweimal oder gar noch öfter aufgetreten ist. Deshalb soll hier noch einmal betont werden, dass Interruptroutinen so schnell wie nur irgend möglich wieder verlassen werden sollten.&lt;br /&gt;
&lt;br /&gt;
=== Unterbrechbare Interruptroutinen ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Faustregel&amp;quot;: im Zweifel &#039;&#039;&#039;ISR&#039;&#039;&#039;. Die nachfolgend beschriebene Methode nur dann verwenden, wenn man sich über die unterschiedliche Funktionsweise im Klaren ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ISR(XXX,ISR_NOBLOCK) /* veraltet: INTERRUPT(SIG_OVERFLOW0) */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt-Code */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei steht XXX für den oben beschriebenen Namen des Vektors (also z.&amp;amp;nbsp;B. &#039;&#039;TIMER0_OVF_vect&#039;&#039;). Der Unterschied im Vergleich zu einer herkömmlichen ISR ist, dass hier beim Aufrufen der Funktion das &#039;&#039;&#039;Global Enable Interrupt&#039;&#039;&#039; Bit durch Einfügen einer SEI-Anweisung direkt wieder gesetzt und somit alle Interrupts zugelassen werden &amp;amp;ndash; auch XXX-Interrupts. &lt;br /&gt;
&lt;br /&gt;
Bei unsachgemässer Handhabung kann dies zu erheblichen Problemen durch Rekursion wie einem Stack-Overflow oder anderen unerwarteten Effekten führen und sollte wirklich nur dann eingesetzt werden, wenn man sich sicher ist, das Ganze auch im Griff zu haben.&lt;br /&gt;
&lt;br /&gt;
Insbesondere sollte möglichst am ISR-Anfang die auslösende IRQ-Quelle deaktiviert und erst am Ende der ISR wieder aktiviert werden. Robuster als die Verwendung einer NOBLOCK-ISR ist daher folgender ISR-Aufbau:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ISR (XXX) &lt;br /&gt;
{&lt;br /&gt;
    // Implementiere die ISR ohne zunaechst weitere IRQs zuzulassen&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;&amp;lt;Dektiviere die XXX-IRQ&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    // Erlaube alle Interrupts (ausser XXX)&lt;br /&gt;
    sei();&lt;br /&gt;
&lt;br /&gt;
    //... Code ...&lt;br /&gt;
&lt;br /&gt;
    // IRQs global deaktivieren um die XXX-IRQ wieder gefahrlos &lt;br /&gt;
    // aktivieren zu koennen&lt;br /&gt;
    cli();&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;&amp;lt;Aktiviere die XXX-IRQ&amp;gt;&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Auf diese Weise kann sich die XXX-IRQ nicht selbst unterbrechen, was zu einer Art Endlosschleife führen würde.&lt;br /&gt;
&lt;br /&gt;
Siehe auch: Hinweise in [[AVR-GCC]]&lt;br /&gt;
&lt;br /&gt;
siehe dazu: http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html&lt;br /&gt;
&lt;br /&gt;
== Datenaustausch mit Interrupt-Routinen ==&lt;br /&gt;
&lt;br /&gt;
Variablen, die sowohl in Interrupt-Routinen (ISR = Interrupt Service Routine(s)) als auch vom übrigen Programmcode geschrieben oder gelesen werden, müssen mit einem &#039;&#039;&#039;volatile&#039;&#039;&#039; deklariert werden. Damit wird dem Compiler mitgeteilt, dass der Inhalt der Variablen vor jedem Lesezugriff aus dem Speicher gelesen und nach jedem Schreibzugriff in den Speicher geschrieben wird. Ansonsten könnte der Compiler den Code so optimieren, dass der Wert der Variablen nur in Prozessorregistern zwischengespeichert wird, die nichts von der Änderung woanders mitbekommen.&lt;br /&gt;
&lt;br /&gt;
Zur Veranschaulichung ein Codefragment für eine Tastenentprellung mit Erkennung einer &amp;quot;lange gedrückten&amp;quot; Taste.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
// Schwellwerte&lt;br /&gt;
// Entprellung: &lt;br /&gt;
#define CNTDEBOUNCE 10&lt;br /&gt;
// &amp;quot;lange gedrueckt:&amp;quot;&lt;br /&gt;
#define CNTREPEAT 200&lt;br /&gt;
&lt;br /&gt;
// hier z.&amp;amp;nbsp;B. Taste an Pin2 PortA &amp;quot;active low&amp;quot; = 0 wenn gedrueckt&lt;br /&gt;
#define KEY_PIN  PINA&lt;br /&gt;
#define KEY_PINNO PA2&lt;br /&gt;
&lt;br /&gt;
// beachte: volatile! &lt;br /&gt;
volatile uint8_t gKeyCounter;&lt;br /&gt;
&lt;br /&gt;
// Timer-Compare Interrupt ISR, wird z.B. alle 10ms ausgefuehrt&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
   // hier wird gKeyCounter veraendert. Die übrigen&lt;br /&gt;
   // Programmteile müssen diese Aenderung &amp;quot;sehen&amp;quot;:&lt;br /&gt;
   // volatile -&amp;gt; aktuellen Wert immer in den Speicher schreiben&lt;br /&gt;
   if ( !(KEY_PIN &amp;amp; (1&amp;lt;&amp;lt;KEY_PINNO)) ) {&lt;br /&gt;
      if (gKeyCounter &amp;lt; CNTREPEAT) gKeyCounter++;&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
      gKeyCounter = 0;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
//...&lt;br /&gt;
    /* hier: Initialisierung der Ports und des Timer-Interrupts */&lt;br /&gt;
//... &lt;br /&gt;
   // hier wird auf gKeyCounter zugegriffen. Dazu muss der in der&lt;br /&gt;
   // ISR geschriebene Wert bekannt sein:&lt;br /&gt;
   // volatile -&amp;gt; aktuellen Wert immer aus dem Speicher lesen&lt;br /&gt;
   if ( gKeyCounter &amp;gt; CNTDEBOUNCE ) { // Taste mind. 10*10 ms &amp;quot;prellfrei&amp;quot;&lt;br /&gt;
       if (gKeyCounter == CNTREPEAT) {&lt;br /&gt;
          /* hier: Code fuer &amp;quot;Taste lange gedrueckt&amp;quot; */&lt;br /&gt;
       }&lt;br /&gt;
       else {&lt;br /&gt;
          /* hier: Code fuer &amp;quot;Taste kurz gedrueckt&amp;quot; */&lt;br /&gt;
       }&lt;br /&gt;
   }&lt;br /&gt;
//...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wird innerhalb einer ISR mehrfach auf eine mit volatile deklarierte Variable zugegriffen, wirkt sich dies ungünstig auf die Verarbeitungsgeschwindigkeit aus, da bei jedem Zugriff mit dem Speicherinhalt abgeglichen wird. Da bei AVR-Controllern &#039;&#039;innerhalb&#039;&#039; einer ISR keine Unterbrechungen zu erwarten sind, bietet es sich an, einen Zwischenspeicher in Form einer lokalen Variable zu verwenden, deren Inhalt zu Beginn und am Ende mit dem der volatile Variable synchronisiert wird. Lokale Variable werden bei eingeschalteter Optimierung mit hoher Wahrscheinlichkeit in Prozessorregistern verwaltet und der Zugriff darauf ist daher nur mit wenigen internen Operationen verbunden. Die ISR aus dem vorherigen Beispiel lässt sich so optimieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
   uint8_t tmp_kc;&lt;br /&gt;
&lt;br /&gt;
   tmp_kc = gKeyCounter; // Uebernahme in lokale Arbeitsvariable&lt;br /&gt;
&lt;br /&gt;
   if ( !(KEY_PIN &amp;amp; (1&amp;lt;&amp;lt;KEY_PINNO)) ) {&lt;br /&gt;
      if (tmp_kc &amp;lt; CNTREPEAT) {&lt;br /&gt;
         tmp_kc++;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
      tmp_kc = 0;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   gKeyCounter = tmp_kc; // Zurueckschreiben&lt;br /&gt;
}&lt;br /&gt;
//...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zum Vergleich die Disassemblies (Ausschnitte der &amp;quot;lss-Dateien&amp;quot;, compiliert für ATmega162) im Anschluss. Man erkennt den viermaligen Zugriff auf die Speicheraddresse von &#039;&#039;gKeyCounter&#039;&#039; (hier 0x032A) in der ISR ohne &amp;quot;Cache&amp;quot;-Variable und den zweimaligen Zugriff in der Variante mit Zwischenspeicher. Im Beispiel ist der Vorteil gering, bei komplexeren Routinen kann die Zwischenspeicherung in lokalen Variablen jedoch zu deutlicheren Verbesserungen führen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
     86a:	1f 92       	push	r1&lt;br /&gt;
     86c:	0f 92       	push	r0&lt;br /&gt;
     86e:	0f b6       	in	r0, 0x3f	; 63&lt;br /&gt;
     870:	0f 92       	push	r0&lt;br /&gt;
     872:	11 24       	eor	r1, r1&lt;br /&gt;
     874:	8f 93       	push	r24&lt;br /&gt;
    if ( !(KEY_PIN &amp;amp; (1&amp;lt;&amp;lt;KEY_PINNO)) ) {&lt;br /&gt;
     876:	ca 99       	sbic	0x19, 2	; 25&lt;br /&gt;
     878:	0a c0       	rjmp	.+20     	; 0x88e &amp;lt;__vector_13+0x24&amp;gt;&lt;br /&gt;
      if (gKeyCounter &amp;lt; CNTREPEAT) gKeyCounter++;&lt;br /&gt;
     87a:	80 91 2a 03 	lds	r24, 0x032A&lt;br /&gt;
     87e:	88 3c       	cpi	r24, 0xC8	; 200 &lt;br /&gt;
     880:	40 f4       	brcc	.+16     	; 0x892 &amp;lt;__vector_13+0x28&amp;gt;&lt;br /&gt;
     882:	80 91 2a 03 	lds	r24, 0x032A&lt;br /&gt;
     886:	8f 5f       	subi	r24, 0xFF	; 255&lt;br /&gt;
     888:	80 93 2a 03 	sts	0x032A, r24&lt;br /&gt;
     88c:	02 c0       	rjmp	.+4      	; 0x892 &amp;lt;__vector_13+0x28&amp;gt;&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
      gKeyCounter = 0;&lt;br /&gt;
     88e:	10 92 2a 03 	sts	0x032A, r1&lt;br /&gt;
     892:	8f 91       	pop	r24&lt;br /&gt;
     894:	0f 90       	pop	r0&lt;br /&gt;
     896:	0f be       	out	0x3f, r0	; 63&lt;br /&gt;
     898:	0f 90       	pop	r0&lt;br /&gt;
     89a:	1f 90       	pop	r1&lt;br /&gt;
     89c:	18 95       	reti&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
     86a:	1f 92       	push	r1&lt;br /&gt;
     86c:	0f 92       	push	r0&lt;br /&gt;
     86e:	0f b6       	in	r0, 0x3f	; 63&lt;br /&gt;
     870:	0f 92       	push	r0&lt;br /&gt;
     872:	11 24       	eor	r1, r1&lt;br /&gt;
     874:	8f 93       	push	r24&lt;br /&gt;
   uint8_t tmp_kc;&lt;br /&gt;
 &lt;br /&gt;
   tmp_kc = gKeyCounter;&lt;br /&gt;
     876:	80 91 2a 03 	lds	r24, 0x032A&lt;br /&gt;
 &lt;br /&gt;
   if ( !(KEY_PIN &amp;amp; (1&amp;lt;&amp;lt;KEY_PINNO)) ) {&lt;br /&gt;
     87a:	ca 9b       	sbis	0x19, 2	; 25&lt;br /&gt;
     87c:	02 c0       	rjmp	.+4      	; 0x882 &amp;lt;__vector_13+0x18&amp;gt;&lt;br /&gt;
     87e:	80 e0       	ldi	r24, 0x00	; 0&lt;br /&gt;
     880:	03 c0       	rjmp	.+6      	; 0x888 &amp;lt;__vector_13+0x1e&amp;gt;&lt;br /&gt;
      if (tmp_kc &amp;lt; CNTREPEAT) {&lt;br /&gt;
     882:	88 3c       	cpi	r24, 0xC8	; 200&lt;br /&gt;
     884:	08 f4       	brcc	.+2      	; 0x888 &amp;lt;__vector_13+0x1e&amp;gt;&lt;br /&gt;
         tmp_kc++;&lt;br /&gt;
     886:	8f 5f       	subi	r24, 0xFF	; 255&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
      tmp_kc = 0;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   gKeyCounter = tmp_kc;&lt;br /&gt;
     888:	80 93 2a 03 	sts	0x032A, r24&lt;br /&gt;
     88c:	8f 91       	pop	r24&lt;br /&gt;
     88e:	0f 90       	pop	r0&lt;br /&gt;
     890:	0f be       	out	0x3f, r0	; 63&lt;br /&gt;
     892:	0f 90       	pop	r0&lt;br /&gt;
     894:	1f 90       	pop	r1&lt;br /&gt;
     896:	18 95       	reti&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== volatile und Pointer ===&lt;br /&gt;
&lt;br /&gt;
Bei &#039;&#039;&#039;volatile&#039;&#039;&#039; in Verbindung mit Pointern ist zu beachten, ob der Pointer selbst oder die Variable, auf die der Pointer zeigt, &#039;&#039;&#039;volatile&#039;&#039;&#039; ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
volatile uint8_t *a;   // das Ziel von a ist volatile&lt;br /&gt;
&lt;br /&gt;
uint8_t *volatile a;   // a selbst ist volatile&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls der Pointer volatile ist (zweiter Fall im Beispiel), ist zu beachten, dass der Wert des Pointers, also eine Speicheradresse, intern in mehr als einem Byte verwaltet wird. Lese- und Schreibzugriffe im Hauptprogramm (außerhalb von Interrupt-Routinen) sind daher so zu implementieren, dass alle Teilbytes der Adresse konsistent bleiben, vgl. dazu den folgenden Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=== Variablen größer 1 Byte ===&lt;br /&gt;
&lt;br /&gt;
Bei Variablen größer ein Byte, auf die in Interrupt-Routinen und im Hauptprogramm zugegriffen wird, muss darauf geachtet werden, dass die Zugriffe auf die einzelnen Bytes außerhalb der ISR nicht durch einen Interrupt unterbrochen werden. (Allgemeinplatz: AVRs sind 8-bit Controller). Zur Veranschaulichung ein Codefragment:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
volatile uint16_t gMyCounter16bit;&lt;br /&gt;
//...&lt;br /&gt;
ISR(...)&lt;br /&gt;
{&lt;br /&gt;
//...&lt;br /&gt;
   gMyCounter16Bit++;&lt;br /&gt;
//...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
   uint16_t tmpCnt;&lt;br /&gt;
//...&lt;br /&gt;
   // nicht gut: Mglw. hier ein Fehler, wenn ein Byte von MyCounter &lt;br /&gt;
   // schon in tmpCnt kopiert ist aber vor dem Kopieren des zweiten Bytes &lt;br /&gt;
   // ein Interrupt auftritt, der den Inhalt von MyCounter verändert.&lt;br /&gt;
   tmpCnt = gMyCounter16bit; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   // besser: Änderungen &amp;quot;außerhalb&amp;quot; verhindern -&amp;gt; alle &amp;quot;Teilbytes&amp;quot;&lt;br /&gt;
   // bleiben konsistent&lt;br /&gt;
   cli();  // Interrupts deaktivieren&lt;br /&gt;
   tmpCnt = gMyCounter16Bit;&lt;br /&gt;
   sei();  // wieder aktivieren&lt;br /&gt;
&lt;br /&gt;
   // oder: vorheriger Status des globalen Interrupt-Flags bleibt erhalten&lt;br /&gt;
   uint8_t sreg_tmp;&lt;br /&gt;
   sreg_tmp = SREG;    /* Sichern */&lt;br /&gt;
   cli()&lt;br /&gt;
   tmpCnt = gMyCounter16Bit;&lt;br /&gt;
   SREG = sreg_tmp;    /* Wiederherstellen */&lt;br /&gt;
&lt;br /&gt;
   // oder: mehrfach lesen, bis man konsistente Daten hat&lt;br /&gt;
   uint16_t count1 = gMyCounter16Bit;&lt;br /&gt;
   uint16_t count2 = gMyCounter16Bit;&lt;br /&gt;
   while (count1 != count2) {&lt;br /&gt;
       count1 = count2;&lt;br /&gt;
       count2 = gMyCounter16Bit;&lt;br /&gt;
   }&lt;br /&gt;
   tmpCnt = count1;&lt;br /&gt;
//...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die avr-libc bietet ab Version 1.6.0(?) einige Hilfsfunktionen/Makros, mit der im Beispiel oben gezeigten Funktionalität, die zusätzlich auch sogenannte [http://en.wikipedia.org/wiki/Memory_barrier memory barriers] beinhalten. Diese stehen nach #include &amp;lt;util/atomic.h&amp;gt; zur Verfügung.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
#include &amp;lt;util/atomic.h&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
    // analog zu cli, Zugriff, sei:&lt;br /&gt;
    ATOMIC_BLOCK(ATOMIC_FORCEON) {&lt;br /&gt;
        tmpCnt = gMyCounter16Bit;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
// oder:&lt;br /&gt;
&lt;br /&gt;
    // analog zu Sicherung des SREG, cli, Zugriff und Zurückschreiben des SREG:&lt;br /&gt;
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {&lt;br /&gt;
        tmpCnt = gMyCounter16Bit;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* siehe auch [http://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html Dokumentation der avr-libc zu atomic.h]&lt;br /&gt;
&lt;br /&gt;
== Interrupt-Routinen und Registerzugriffe ==&lt;br /&gt;
&lt;br /&gt;
Falls Register sowohl im Hauptprogramm als auch in Interrupt-Routinen verändert werden, ist darauf zu achten, dass diese Zugriffe sich nicht überlappen. Nur wenige Anweisungen lassen sich in sogenannte &amp;quot;atomare&amp;quot; Zugriffe übersetzen, die nicht von Interrupt-Routinen unterbrochen werden können. &lt;br /&gt;
&lt;br /&gt;
Zur Veranschaulichung eine Anweisung, bei der ein Bit und im Anschluss drei Bits in einem Register gesetzt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
//...&lt;br /&gt;
	PORTA |= (1&amp;lt;&amp;lt;PA0);&lt;br /&gt;
	&lt;br /&gt;
	PORTA |= (1&amp;lt;&amp;lt;PA2)|(1&amp;lt;&amp;lt;PA3)|(1&amp;lt;&amp;lt;PA4);&lt;br /&gt;
//...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Compiler übersetzt diese Anweisungen für einen ATmega128 bei Optimierungsstufe &amp;quot;S&amp;quot; nach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
        PORTA |= (1&amp;lt;&amp;lt;PA0);&lt;br /&gt;
  d2:	d8 9a       	sbi	0x1b, 0	; 27 (a)&lt;br /&gt;
	&lt;br /&gt;
        PORTA |= (1&amp;lt;&amp;lt;PA2)|(1&amp;lt;&amp;lt;PA3)|(1&amp;lt;&amp;lt;PA4);&lt;br /&gt;
  d4:	8b b3       	in	r24, 0x1b	; 27 (b)&lt;br /&gt;
  d6:	8c 61       	ori	r24, 0x1C	; 28 (c)&lt;br /&gt;
  d8:	8b bb       	out	0x1b, r24	; 27 (d)&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Setzen des einzelnen Bits wird bei eingeschalteter Optimierung für Register im unteren Speicherbereich in eine einzige Assembler-Anweisung (sbi) übersetzt und ist nicht anfällig für Unterbrechungen durch Interrupts. Die Anweisung zum Setzen von drei Bits wird jedoch in drei abhängige Assembler-Anweisungen übersetzt und bietet damit zwei &amp;quot;Angriffspunkte&amp;quot; für Unterbrechungen. Eine Interrupt-Routine könnte nach dem Laden des Ausgangszustands in den Zwischenspeicher (hier Register 24) den Wert des Registers ändern, z.&amp;amp;nbsp;B. ein Bit löschen. Damit würde der Zwischenspeicher nicht mehr mit dem tatsächlichen Zustand übereinstimmen aber dennoch nach der Bitoperation (hier ori) in das Register zurückgeschrieben. &lt;br /&gt;
&lt;br /&gt;
Beispiel: PORTA sei anfangs 0b00000000. Die erste Anweisung (a) setzt Bit 0 auf &#039;&#039;&#039;1&#039;&#039;&#039;, PORTA ist danach 0b0000000&#039;&#039;&#039;1&#039;&#039;&#039;. Nun wird im ersten Teil der zweiten Anweisung der Portzustand in ein Register eingelesen (b). Unmittelbar darauf (vor (c)) &amp;quot;feuert&amp;quot; ein Interrupt, in dessen Interrupt-Routine Bit 0 von PORTA gelöscht wird. Nach Verlassen der Interrupt-Routine hat PORTA den Wert 0b00000000. In den beiden noch folgenden Anweisungen des Hauptprogramms wird nun der zwischengespeicherte &amp;quot;alte&amp;quot; Zustand 0b00000001 mit 0b00011100 logisch-&#039;&#039;&#039;ODER&#039;&#039;&#039;-verknüft (c) und das Ergebnis 0b00011101 in PortA geschrieben (d). Obwohl zwischenzeitlich Bit 0 gelöscht wurde, ist es nach (d) wieder gesetzt. &lt;br /&gt;
&lt;br /&gt;
Lösungsmöglichkeiten:&lt;br /&gt;
* Register ohne besondere Vorkehrungen nicht in Interruptroutinen &#039;&#039;und&#039;&#039; im Hauptprogramm verändern.&lt;br /&gt;
* Interrupts vor Veränderungen in Registern, die auch in ISRs verändert werden, deaktivieren (&amp;quot;cli&amp;quot;).&lt;br /&gt;
* Bits einzeln löschen oder setzen. sbi und cbi können nicht unterbrochen werden. Vorsicht: nur Register im unteren Speicherbereich sind mittels sbi/cbi ansprechbar. Der Compiler kann nur für diese sbi/cbi-Anweisungen generieren. Für Register außerhalb dieses Adressbereichs (&amp;quot;Memory-Mapped&amp;quot;-Register) werden auch zur Manipulation einzelner Bits abhängige Anweisungen erzeugt (lds,...,sts).&lt;br /&gt;
&lt;br /&gt;
* siehe auch: [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Frequently asked Questions/Fragen Nr. 1 und 8. (Stand: avr-libc Vers. 1.0.4)&lt;br /&gt;
&lt;br /&gt;
== Interruptflags löschen ==&lt;br /&gt;
&lt;br /&gt;
Beim Löschen von Interruptflags haben AVRs eine Besonderheit, die auch im Datenblatt beschrieben ist: Es wird zum Löschen eine 1 in das betreffende Bit geschrieben. &lt;br /&gt;
&lt;br /&gt;
Hinweis: Dazu &#039;&#039;&#039;nicht&#039;&#039;&#039; übliche bitweise VerODERung nehmen, sondern eine direkte Zuweisung machen ([http://www.mikrocontroller.net/topic/171148#1640133 Erklärung]).&lt;br /&gt;
&lt;br /&gt;
== Was macht das Hauptprogramm? ==&lt;br /&gt;
&lt;br /&gt;
Im einfachsten (Ausnahme-)Fall gar nichts mehr. Es ist also durchaus denkbar, ein Programm zu schreiben, welches in der main-Funktion lediglich noch die Interrupts aktiviert und dann in einer Endlosschleife verharrt. Sämtliche Funktionen werden dann in den ISRs abgearbeitet. Diese Vorgehensweise ist jedoch bei den meisten Anwendungen schlecht: man verschenkt eine Verarbeitungsebene und hat außerdem möglicherweise Probleme durch Interruptroutinen, die zu viel Verarbeitungszeit benötigen.&lt;br /&gt;
&lt;br /&gt;
Normalerweise wird man in den Interruptroutinen nur die bei Auftreten des jeweiligen Interruptereignisses unbedingt notwendigen Operationen ausführen lassen. Alle weniger kritischen Aufgaben werden dann im Hauptprogramm abgearbeitet.&lt;br /&gt;
&lt;br /&gt;
* siehe auch: [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/Interrupts and Signals&lt;br /&gt;
&lt;br /&gt;
= Sleep-Modes =&lt;br /&gt;
&lt;br /&gt;
AVR Controller verfügen über eine Reihe von sogenannten [[Sleep Mode |&#039;&#039;Sleep-Modes&#039;&#039;]] (&amp;quot;Schlaf-Modi&amp;quot;). Diese ermöglichen es, Teile des Controllers abzuschalten. Zum Einen kann damit besonders bei Batteriebetrieb Strom gespart werden, zum Anderen können Komponenten des Controllers deaktiviert werden, die die Genauigkeit des Analog-Digital-Wandlers bzw. des Analog-Comparators negativ beeinflussen. Der Controller wird durch Interrupts aus dem Schlaf geweckt. Welche Interrupts den jeweiligen Schlafmodus beenden, ist einer Tabelle im Datenblatt des jeweiligen Controllers zu entnehmen.&lt;br /&gt;
Die Funktionen (eigentlich Makros) der avr-libc stehen nach Einbinden der header-Datei &#039;&#039;sleep.h&#039;&#039; zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
;set_sleep_mode (uint8_t mode): Setzt den Schlafmodus, der bei Aufruf von sleep() aktiviert wird. In sleep.h sind einige Konstanten definiert (z.&amp;amp;nbsp;B. SLEEP_MODE_PWR_DOWN). Die definierten Modi werden jedoch nicht alle von sämtlichten AVR-Controllern unterstützt.&lt;br /&gt;
;sleep_enable(): Aktiviert den gesetzten Schlafmodus, versetzt den Controller aber noch nicht in den Schlafmodus&lt;br /&gt;
;sleep_cpu(): Versetzt den Controller in den Schlafmodus .sleep_cpu wird im Prinzip durch die Assembler-Anweisung &#039;&#039;sleep&#039;&#039; ersetzt.&lt;br /&gt;
;sleep_disable(): Deaktiviert den gesetzten Schlafmodus&lt;br /&gt;
;sleep_mode(): Versetzt den Controller in den mit set_sleep_mode gewählten Schlafmodus. Das Makro entspricht sleep_enable()+sleep_cpu()+sleep_disable(), beinhaltet also nicht die Aktivierung von Interrupts (besser nicht benutzen).&lt;br /&gt;
&lt;br /&gt;
Bei Anwendung von sleep_cpu() müssen Interrupts also bereits freigeben sein (sei()), da der Controller sonst nicht mehr &amp;quot;aufwachen&amp;quot; kann. sleep_mode() ist nicht geeignet für die Verwendung in ISR Interrupt-Service-Routinen, da bei deren Abarbeitung Interrupts global deaktiviert sind und somit auch die möglichen &amp;quot;Aufwachinterrupts&amp;quot;. Abhilfe: stattdessen sleep_enable(), sei(), sleep_cpu(), sleep_disable() und evtl. cli() verwenden (vgl. Dokumentation der avr-libc).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/sleep.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
   while (1) {&lt;br /&gt;
...&lt;br /&gt;
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);&lt;br /&gt;
      sleep_mode();&lt;br /&gt;
   &lt;br /&gt;
      // Code hier wird erst nach Auftreten eines entsprechenden&lt;br /&gt;
      // &amp;quot;Aufwach-Interrupts&amp;quot; verarbeitet&lt;br /&gt;
...&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In älteren Versionenen der avr-libc wurden nicht alle AVR-Controller durch die sleep-Funktionen richtig angesteuert. Mit avr-libc 1.2.0 wurde die Anzahl der unterstützten Typen jedoch deutlich erweitert. Bei nicht-unterstützten Typen erreicht man die gewünschte Funktionalität durch direkte &amp;quot;[[Bitmanipulation]]&amp;quot; der entsprechenden Register (vgl. Datenblatt) und Aufruf des Sleep-Befehls via Inline-Assembler oder sleep_cpu():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
   // Sleep-Mode &amp;quot;Power-Save&amp;quot; beim ATmega169 &amp;quot;manuell&amp;quot; aktivieren&lt;br /&gt;
   SMCR = (3&amp;lt;&amp;lt;SM0) | (1&amp;lt;&amp;lt;SE);&lt;br /&gt;
   asm volatile (&amp;quot;sleep&amp;quot;::); // alternativ sleep_cpu() aus sleep.h&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sleep Modi ==&lt;br /&gt;
Zu beachten ist, dass unterschiedliche Prozessoren aus der AVR Familie unterschiedliche Sleep-Modi unterstützen oder nicht unterstützen. Auskunft über die tatsächlichen Gegebenheiten gibt, wie immer, das zum Prozessor gehörende Datenblatt. Die unterschiedlichen Modi unterscheiden sich dadurch, welche Bereiche des Prozessors abgeschaltet werden. Damit korrespondiert unmittelbar welche Möglichkeiten es gibt, den Prozessor aus den jeweiligen Sleep Modus wieder aufzuwecken.&lt;br /&gt;
&lt;br /&gt;
;Idle Mode (SLEEP_MODE_IDLE): Die CPU kann durch SPI, USART, Analog Comperator, ADC, TWI, Timer, Watchdog und irgendeinen anderen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
;ADC Noise Reduction Mode (SLEEP_MODE_ADC): In diesem Modus liegt das Hauptaugenmerk darauf, die CPU soweit stillzulegen, dass der ADC möglichst keine Störungen aus dem inneren der CPU auffangen kann. Aufwachen aus diesem Modus kann ausgelöst werden durch den ADC, externe Interrupts, TWI, Timer und Watchdog.&lt;br /&gt;
&lt;br /&gt;
;Power-Down Mode (SLEEP_MODE_PWR_DOWN): In diesem Modus wird ein externer Oszillator (Quarz, Quarzoszillator) gestoppt. Geweckt werden kann die CPU durch einen externen Level Interrupt, TWI, Watchdog, Brown-Out-Reset&lt;br /&gt;
&lt;br /&gt;
;Power-Save-Mode (SLEEP_MODE_PWR_SAVE): Power-Save ist identisch zu Power-Down mit einer Ausnahme: Ist der Timer 2 auf die Verwendung eines externen Taktes konfiguriert, so läuft dieser Timer auch im Power-Save weiter und kann die CPU mit einem Interrupt aufwecken.&lt;br /&gt;
&lt;br /&gt;
;Standby-Mode (SLEEP_MODE_STANDBY, SLEEP_MODE_EXT_STANDBY): Voraussetzung für den Standby-Modus ist die Verwendung eines Quarzes oder eines Quarzoszillators (also einer externen Taktquelle). Ansonsten ist dieser Modus identisch zum Power-Down Modus. Vorteil dieses Modus ist eine kürzere Aufwachzeit.&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/Power Management and Sleep-Modes&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/96369#832712 Forenbeitrag] zur &amp;quot;Nichtverwendung&amp;quot; von sleep_mode in ISRs.&lt;br /&gt;
&lt;br /&gt;
= Zeiger =&lt;br /&gt;
Zeiger (engl. &#039;&#039;Pointer&#039;&#039;) sind Variablen, die die Adresse von Daten oder Funktionen enthalten und belegen 16 Bits. Die Größe hängt mit dem adressierbaren Speicherbereich zusammen und der GCC reserviert dann den entsprechenden Platz.&lt;br /&gt;
Ggf. ist es also günstiger, Indizes auf Arrays (Listen) zu verwenden, so dass der GCC für die Zeigerarithmetik den erforderlichen RAM nur temporär benötigt.&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [[Zeiger]]&lt;br /&gt;
&lt;br /&gt;
= Speicherzugriffe =&lt;br /&gt;
&lt;br /&gt;
Atmel AVR-Controller verfügen typisch über drei Speicher:&lt;br /&gt;
&lt;br /&gt;
* [[RAM]]: Im RAM (genauer statisches RAM/SRAM) wird vom gcc-Compiler Platz für Variablen reserviert. Auch der Stack befindet sich im RAM. Dieser Speicher ist &amp;quot;flüchtig&amp;quot;, d.h. der Inhalt der Variablen geht beim Ausschalten oder einem Zusammenbruch der Spannungsversorgung verloren.&lt;br /&gt;
&lt;br /&gt;
* Programmspeicher: Ausgeführt als FLASH-Speicher, seitenweise wiederbeschreibbar. Darin ist das Anwendungsprogramm abgelegt.&lt;br /&gt;
&lt;br /&gt;
* [[EEPROM]]: Nichtflüchtiger Speicher, d.h. der einmal geschriebene Inhalt bleibt auch ohne Stromversorgung erhalten. Byte-weise schreib/lesbar. Im EEPROM werden typischerweise gerätespezifische Werte wie z.&amp;amp;nbsp;B. Kalibrierungswerte von Sensoren abgelegt.&lt;br /&gt;
&lt;br /&gt;
Einige AVRs besitzen keinen RAM-Speicher, lediglich die Register können als &amp;quot;Arbeitsvariablen&amp;quot;&lt;br /&gt;
genutzt werden. Da die Anwendung des avr-gcc auf solch &amp;quot;kleinen&amp;quot; Controllern ohnehin selten sinnvoll ist und auch nur bei einigen RAM-losen Typen nach [http://lightner.net/avr/ATtinyAvrGcc.html &amp;quot;Bastelarbeiten&amp;quot;] möglich ist, werden diese Controller hier nicht weiter berücksichtigt. Auch EEPROM-Speicher ist nicht auf allen Typen verfügbar. Generell sollten die nachfolgenden Erläuterungen auf alle ATmega-Controller und die größeren AT90-Typen übertragbar sein. Für die Typen ATtiny2313, ATtiny26 und viele weitere der &amp;quot;ATtiny-Reihe&amp;quot; gelten die Ausführungen ebenfalls.&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* [[Binäre Daten zum Programm hinzufügen]]&lt;br /&gt;
== RAM ==&lt;br /&gt;
&lt;br /&gt;
Die Verwaltung des RAM-Speichers erfolgt durch den Compiler, im Regelfall ist beim Zugriff auf Variablen im RAM nichts Besonderes zu beachten. Die Erläuterungen in jedem brauchbaren C-Buch gelten auch für den vom avr-gcc-Compiler erzeugten Code.&lt;br /&gt;
&lt;br /&gt;
Um Speicher dynamisch (während der Laufzeit) zu reservieren, kann &#039;&#039;&#039;malloc()&#039;&#039;&#039; verwendet werden. malloc(size) &amp;quot;alloziert&amp;quot; (~reserviert) einen gewissen Speicherblock mit &#039;&#039;&#039;size&#039;&#039;&#039; Bytes. Ist kein Platz für den neuen Block, wird NULL (0) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Wird der angelegte Block zu klein (groß), kann die Größe mit realloc() verändert werden. Den allozierten Speicherbereich kann man mit free() wieder freigeben. Wenn das Freigeben eines Blocks vergessen wird spricht man von einem &amp;quot;Speicherleck&amp;quot; (memory leak).&lt;br /&gt;
&lt;br /&gt;
malloc() legt Speicherblöcke im &#039;&#039;&#039;Heap&#039;&#039;&#039; an, belegt man zuviel Platz, dann wächst der Heap zu weit nach oben und überschreibt den Stack, und der Controller kommt in Teufels Küche. Das kann leider nicht nur passieren wenn man insgesamt zu viel Speicher anfordert, sondern auch wenn man Blöcke unterschiedlicher Größe in ungünstiger Reihenfolge alloziert/freigibt (siehe Artikel [[Heap-Fragmentierung]]). Aus diesem Grund sollte man malloc() auf Mikrocontrollern sehr sparsam (am besten gar nicht) verwenden.&lt;br /&gt;
&lt;br /&gt;
Beispiel zur Verwendung von malloc():&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void foo(void) {&lt;br /&gt;
  // neuen speicherbereich anlegen,&lt;br /&gt;
  // platz für 10 uint16&lt;br /&gt;
  uint16_t* pBuffer = malloc(10 * sizeof(uint16_t));&lt;br /&gt;
&lt;br /&gt;
  // darauf zugreifen, als wärs ein gewohnter Buffer&lt;br /&gt;
  pBuffer[2] = 5;&lt;br /&gt;
&lt;br /&gt;
  // Speicher (unbedingt!) wieder freigeben&lt;br /&gt;
  free(pBuffer);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn (wie in obigem Beispiel) dynamischer Speicher nur für die Dauer einer Funktion benötigt und am Ende wieder freigegeben wird, bietet es sich an, statt malloc() &#039;&#039;&#039;alloca()&#039;&#039;&#039; zu verwenden. Der Unterschied zu malloc() ist, dass der Speicher auf dem Stack reserviert wird, und beim Verlassen der Funktion automatisch wieder freigegeben wird. Es kann somit kein Speicherleck und keine Fragmentierung entstehen.&lt;br /&gt;
&lt;br /&gt;
siehe auch:&lt;br /&gt;
* http://www.nongnu.org/avr-libc/user-manual/malloc.html&lt;br /&gt;
&lt;br /&gt;
== Programmspeicher (Flash) ==&lt;br /&gt;
&lt;br /&gt;
Ein Zugriff auf Konstanten im Programmspeicher ist mittels avr-gcc nicht &amp;quot;transparent&amp;quot; möglich. D.h. es sind besondere Zugriffsfunktionen erforderlich, um Daten aus diesem Speicher zu lesen. Grundsätzlich basieren alle Zugriffsfunktionen auf der Assembler-Anweisung lpm (load program memory, bei AVR Controllern mit mehr als 64kB Flash auch elpm). Die Standard-Laufzeitbibliothek des avr-gcc (die avr-libc) stellt diese Funktionen nach Einbinden der Header-Datei pgmspace.h zur Verfügung. Mit diesen Funktionen können einzelne Bytes, Datenworte (16bit) und Datenblöcke gelesen werden. &lt;br /&gt;
&lt;br /&gt;
Deklarationen von Variablen im Flash-Speicher werden durch das &amp;quot;Attribut&amp;quot; PROGMEM ergänzt. Lokale Variablen (eigentlich Konstanten) innerhalb von Funktionen können ebenfalls im Programmspeicher abgelegt werden. Dazu ist bei der Definition jedoch ein &#039;&#039;static&#039;&#039; voranzustellen, da solche &amp;quot;Variablen&amp;quot; nicht auf dem Stack bzw. (bei Optimierung) in Registern verwaltet werden können. Der Compiler &amp;quot;wirft&amp;quot; eine Warnung falls static fehlt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Byte */&lt;br /&gt;
const uint8_t pgmFooByte PROGMEM = 123;&lt;br /&gt;
&lt;br /&gt;
/* Wort */&lt;br /&gt;
const uint16_t pgmFooWort PROGMEM = 12345;&lt;br /&gt;
&lt;br /&gt;
/* Byte-Array */&lt;br /&gt;
const uint8_t pgmFooByteArray1[] PROGMEM = { 18, 3 ,70 };&lt;br /&gt;
const uint8_t pgmFooByteArray2[] PROGMEM = { 30, 7 ,79 };&lt;br /&gt;
&lt;br /&gt;
/* Zeiger */&lt;br /&gt;
const uint8_t * const pgmPointerToArray1 PROGMEM = pgmFooByteArray1;&lt;br /&gt;
const uint8_t * const pgmPointerArray[] PROGMEM = { pgmFooByteArray1, pgmFooByteArray2 };&lt;br /&gt;
&lt;br /&gt;
void foo(void)&lt;br /&gt;
{&lt;br /&gt;
  static const uint8_t pgmTestByteLocal PROGMEM = 0x55;&lt;br /&gt;
  static const char pgmTestStringLocal[] PROGMEM = &amp;quot;im Flash&amp;quot;;&lt;br /&gt;
  // so nicht (static fehlt) &lt;br /&gt;
  // char pgmTestStringLocalFalsch [] PROGMEM = &amp;quot;so nicht&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Byte lesen ===&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion pgm_read_byte aus pgmspace.h erfolgt der Zugriff auf die Daten. Parameter der Funktion ist die Adresse des Bytes im Flash-Speicher.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
const uint8_t pgmFooByte PROGMEM = 123;&lt;br /&gt;
const uint8_t pgmFooByteArray1[] PROGMEM = { 18, 3, 70 };&lt;br /&gt;
&lt;br /&gt;
void foo (void)&lt;br /&gt;
    // Wert der Ram-Variablen myByte auf den Wert von pgmFooByte setzen:&lt;br /&gt;
    uint8_t myByte;&lt;br /&gt;
&lt;br /&gt;
    myByte = pgm_read_byte (&amp;amp;pgmFooByte);&lt;br /&gt;
    // myByte hat nun den Wert 123&lt;br /&gt;
&lt;br /&gt;
    // Schleife ueber ein Array aus Byte-Werten im Flash&lt;br /&gt;
    uint8_t i;&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; 3; i++)&lt;br /&gt;
    {&lt;br /&gt;
        myByte = pgm_read_byte (&amp;amp;pgmFooByteArray1[i]);&lt;br /&gt;
        // mach was mit myByte&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Wort lesen ===&lt;br /&gt;
&lt;br /&gt;
Für &amp;quot;einfache&amp;quot; 16-Bit breite Variablen erfolgt der Zugriff analog zum Byte-Beispiel, jedoch mit der Funktion &amp;lt;code&amp;gt;pgm_read_word&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
const uint16_t pgmFooWort PROGMEM = 12345;&lt;br /&gt;
&lt;br /&gt;
    uint16_t myWord = pgm_read_word (&amp;amp;pgmFooWort);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zeiger auf Werte im Flash sind ebenfalls 16 Bits &amp;quot;groß&amp;quot;.&lt;br /&gt;
Damit ist der mögliche Speicherbereich für &amp;quot;Flash-Konstanten&amp;quot; auf 64kB begrenzt.&amp;lt;ref&amp;gt;Einige avr-libc/pgmspace-Funktionen ermöglichen den Lesezugriff auf den gesamten Flash-Speicher, intern via Assembler Anweisung ELPM. Die Initialisierungswerte des Speicherinhalts jenseits der 64kB-Marke müssen dann jedoch auf anderem Weg angelegt werden, d.h. nicht per PROGMEM; evtl. eigene Section und Linker-Optionen. Alt und nicht ganz korrekt: Die avr-libc pgmspace-Funktionen unterstützen nur die unteren 64kB Flash bei Controllern mit mehr als 64kB.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    const uint8_t *ptrToArray;&lt;br /&gt;
&lt;br /&gt;
    ptrToArray = (const uint8_t*) pgm_read_word (&amp;amp;pgmPointerToArray1);&lt;br /&gt;
    // ptrToArray enthält nun die Startadresse des Byte-Arrays pgmFooByteArray1&lt;br /&gt;
    // Allerdings würde ein direkter Zugriff mit diesem Pointer (z.&amp;amp;nbsp;B. temp=*ptrToArray)&lt;br /&gt;
    // nicht den Inhalt von pgmFooByteArray1[0] liefern, sondern von einer Speicherstelle&lt;br /&gt;
    // im RAM, die die gleiche Adresse hat wie pgmFooByteArray1[0]&lt;br /&gt;
    // Daher muss nun die Funktion pgm_read_byte() benutzt werden, die die in ptrToArray&lt;br /&gt;
    // enthaltene Adresse benutzt und auf das Flash zugreift.&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; 3; i++)&lt;br /&gt;
    {&lt;br /&gt;
        myByte = pgm_read_byte (ptrToArray+i);&lt;br /&gt;
        // mach was mit myByte... (18, 3, 70)&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ptrToArray = (const uint8_t*) pgm_read_word (&amp;amp;pgmPointerArray[1]);&lt;br /&gt;
    &lt;br /&gt;
    // ptrToArray enthält nun die Adresse des ersten Elements des Byte-Arrays pgmFooByteArray2&lt;br /&gt;
    // da im zweiten Element des Pointer-Arrays pgmPointerArray die Adresse&lt;br /&gt;
    // von pgmFooByteArray2 abgelegt ist&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; 3; i++)&lt;br /&gt;
    {&lt;br /&gt;
        myByte = pgm_read_byte (ptrToArray+i);&lt;br /&gt;
        // mach was mit myByte... (30, 7, 79)&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Block lesen ===&lt;br /&gt;
In den Standard-Flash Funktionen ist keine der pgm_read_xxxx Nomenklatur folgenden Funktion enthalten, die einen kompletten Block ausliest. Die enstprechende Funktion ist eine Variante von memcpy und heißt memcpy_P().&lt;br /&gt;
&lt;br /&gt;
Was diese Funktion im Prinzip macht, ist einfach in einer Schleife pgm_read_byte zu benutzen, um einen Speicherblock von der Quelladresse im Flash an eine Zieladresse im SRAM zu kopieren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void pgm_read_block( uint8_t* pTarget, const uint8_t* pSource, size_t len )&lt;br /&gt;
{&lt;br /&gt;
  size_t i;&lt;br /&gt;
&lt;br /&gt;
  for( i = 0; i &amp;lt; len; ++i )&lt;br /&gt;
    *pTarget++ = pgm_read_byte( pSource++ );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit ist es dann natürlich kein Problem mehr ganze Arrays oder Strukturen aus dem Flash in das SRAM zu übertragen.&lt;br /&gt;
&lt;br /&gt;
=== Strings lesen ===&lt;br /&gt;
Strings sind in C nichts anderes als eine Abfolge von Zeichen. Der prinzipielle Weg ist daher identisch zu &amp;quot;Bytes lesen&amp;quot;, wobei allerdings auf die [http://www.mikrocontroller.net/articles/FAQ#Wie_funktioniert_String-Verarbeitung_in_C.3F Besonderheiten von Strings] wie 0-Terminierung geachtet werden muss, bzw. diese zur Steuerung einer Schleife über die Zeichen im String ausgenutzt werden kann&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
const char pgmString[] PROGMEM = &amp;quot;Hello world&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  char c;&lt;br /&gt;
  const char* addr;&lt;br /&gt;
&lt;br /&gt;
  addr = pgmString;&lt;br /&gt;
  while (c = pgm_read_byte (addr++), c != &#039;\0&#039;)&lt;br /&gt;
  {&lt;br /&gt;
    // mach was mit c&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung des Programmierers steht das Repertoir der str-Funktionen auch in jeweils eine Variante zur Verfügung, die mit dem Flash-Speicher arbeiten kann. Die Funktionsnamen tragen den Suffix &amp;lt;tt&amp;gt;_P&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
const char pgmString[] PROGMEM = &amp;quot;Hallo world&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
void foo (void)&lt;br /&gt;
{&lt;br /&gt;
  char string[40];&lt;br /&gt;
&lt;br /&gt;
  strcpy_P (string, pgmString);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Float lesen ===&lt;br /&gt;
&lt;br /&gt;
Auch um floats zu lesen gibt es ein Makro:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
float pgmFloatArray[3] PROGMEM = {1.1, 2.2, 3.3};&lt;br /&gt;
&lt;br /&gt;
void read_float (void)&lt;br /&gt;
{&lt;br /&gt;
   int i;&lt;br /&gt;
   float f;&lt;br /&gt;
&lt;br /&gt;
   for (i=0; i&amp;lt;3; i++) &lt;br /&gt;
   {&lt;br /&gt;
      // entspricht  f = pgmFloatArray[i];&lt;br /&gt;
      f = pgm_read_float (&amp;amp;pgmFloatArray[i]);&lt;br /&gt;
      // mach was mit f &lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TODO: Beispiele für structs und pointer aus Flash auf struct im Flash (menues, state-machines etc.). Eine kleine Einleitung insbesondere auch in Bezug auf die auftretenden Schwierigkeiten liefert [http://www.mail-archive.com/avr-gcc-list@nongnu.org/msg05652.html].&lt;br /&gt;
&lt;br /&gt;
=== Array aus Strings im Flash-Speicher ===&lt;br /&gt;
&lt;br /&gt;
Arrays aus Strings im Flash-Speicher werden in zwei Schritten angelegt: Zuerst die einzelnen Elemente des Arrays und im Anschluss ein Array, in dem die Startaddressen der Strings abgelegt werden. Zum Auslesen wird zuerst die Adresse des i-ten Elements aus dem Array im Flash-Speicher gelesen, die im Anschluss dazu genutzt wird, auf das Element (den String) selbst zuzugreifen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
const char str1[] PROGMEM = &amp;quot;first_A&amp;quot;;&lt;br /&gt;
const char str2[] PROGMEM = &amp;quot;second_A&amp;quot;;&lt;br /&gt;
const char str3[] PROGMEM = &amp;quot;third_A&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const char * const strarray1[] PROGMEM = &lt;br /&gt;
{&lt;br /&gt;
   str1,&lt;br /&gt;
   str2,&lt;br /&gt;
   str3&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
static char work[20];&lt;br /&gt;
&lt;br /&gt;
void read_strings (void)&lt;br /&gt;
{&lt;br /&gt;
    size_t i;&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; sizeof (strarray1) / sizeof (strarray1[0]); i++)&lt;br /&gt;
    {&lt;br /&gt;
        size_t j, len;&lt;br /&gt;
&lt;br /&gt;
        // setze Pointer auf die Addresse des i-ten Elements des&lt;br /&gt;
        // Flash-Arrays (str1, str2, ...)&lt;br /&gt;
        const char *pstrflash = (const char*) pgm_read_word (&amp;amp;strarray1[i]);&lt;br /&gt;
&lt;br /&gt;
        // kopiere den Inhalt der Zeichenkette von der&lt;br /&gt;
        // in pstrflash abgelegten Adresse in das work-Array&lt;br /&gt;
        // analog zu strcpy( work, strarray1[i]) wenn alles im RAM&lt;br /&gt;
        strcpy_P (work, pstrflash);&lt;br /&gt;
&lt;br /&gt;
        // Gleichbedeutend damit:&lt;br /&gt;
        strcpy_P (work, (const char*) pgm_read_word (&amp;amp;strarray1[i]));&lt;br /&gt;
    &lt;br /&gt;
        // Zeichen-fuer-Zeichen&lt;br /&gt;
        len = strlen_P (&amp;amp;strarray1[i]);&lt;br /&gt;
&lt;br /&gt;
        // &amp;lt;= da auch das Stringende-Zeichen kopiert werden soll&lt;br /&gt;
        for (j = 0; j &amp;lt;= len; j++)&lt;br /&gt;
        {&lt;br /&gt;
            // analog zu work[j] = strarray[i][j] wenn alles im RAM&lt;br /&gt;
            work[i] = (char) pgm_read_byte (pstrflash++);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Siehe dazu auch die avr-libc FAQ: [http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_rom_array How do I put an array of strings completely in ROM?]&lt;br /&gt;
&lt;br /&gt;
=== Vereinfachung für Zeichenketten (Strings) im Flash ===&lt;br /&gt;
&lt;br /&gt;
Zeichenketten können innerhalb des Quellcodes als &amp;quot;Flash-Konstanten&amp;quot; ausgewiesen werden. Dazu dient das Makro PSTR aus pgmspace.h. Dies erspart die getrennte Deklaration mit PROGMEM-Attribut.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define MAXLEN 30&lt;br /&gt;
&lt;br /&gt;
char StringImFlash[] PROGMEM = &amp;quot;Erwin Lindemann&amp;quot;;&lt;br /&gt;
char StringImRam[MAXLEN];&lt;br /&gt;
&lt;br /&gt;
void read_string (void)&lt;br /&gt;
{&lt;br /&gt;
    strcpy (StringImRam, &amp;quot;Mueller-Luedenscheidt&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    if (!strncmp_P (StringImRam, StringImFlash, 5))&lt;br /&gt;
    {&lt;br /&gt;
        // mach was, wenn die ersten 5 Zeichen identisch - hier nicht&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        // der Code hier wuerde ausgefuehrt &lt;br /&gt;
    } &lt;br /&gt;
&lt;br /&gt;
    if (!strncmp_P (StringImRam, PSTR(&amp;quot;Mueller-Schmitt&amp;quot;), 5))&lt;br /&gt;
    {&lt;br /&gt;
        // der Code hier wird ausgefuehrt, wenn die ersten &lt;br /&gt;
        // 5 Zeichen uebereinstimmen&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        // wird bei Nicht-Uebereinstimmung ausgefuehrt&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aber Vorsicht: Ersetzt man zum Beispiel&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// Daten im &amp;quot;Flash&amp;quot;&lt;br /&gt;
const char flashText[] PROGMEM = &amp;quot;mit[]&amp;quot;; &lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
durch&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// Hier wird &amp;quot;mit*&amp;quot; im RAM angelegt und flashPointer&lt;br /&gt;
// enthaelt die Adresse&lt;br /&gt;
const char* const flashPointer PROGMEM = &amp;quot;mit*&amp;quot;;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
dann kann es zu Problemen kommen.&lt;br /&gt;
&lt;br /&gt;
Übergibt man Zeichenketten, die im Flash abglegt sind an eine Funktion – also die Adresse des ersten Zeichens – so muss die Funktion entsprechend programmiert sein. Die Funktion selbst hat keine Möglichkeit zu unterscheiden, ob es sich um eine Flash-Adresse oder ein RAM-Adresse handelt. Die avr-libc und viele andere avr-gcc-Bibliotheken halten sich an die Konvention, dass Namen von Funktionen, die Flash-Adressen erwarten, mit dem Suffix &amp;lt;code&amp;gt;_P&amp;lt;/code&amp;gt; versehen sind.&lt;br /&gt;
&lt;br /&gt;
Eine Funktion, die einen im Flash abgelegten String z.&amp;amp;nbsp;B. an eine UART ausgibt, würde dann so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void uart_puts_p (const char *text)&lt;br /&gt;
{&lt;br /&gt;
    char zeichen;&lt;br /&gt;
&lt;br /&gt;
    while ((zeichen = pgm_read_byte (text)))&lt;br /&gt;
    {&lt;br /&gt;
        // so lange, wie mittels pgm_read_byte nicht das Stringende&lt;br /&gt;
        // gelesen wurde: gib dieses Zeichen aus&lt;br /&gt;
&lt;br /&gt;
        uart_putc (zeichen);&lt;br /&gt;
        text++;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Von einigen Bibliotheken werden Makros definiert, die &amp;quot;automatisch&amp;quot; ein PSTR bei Verwendung einer Funktion einfügen. Ein Blick in den Header-File der Bibliothek zeigt, ob dies der Fall ist. Ein Beispiel aus P. Fleurys lcd-Library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// Ausschnitt aus dem Header-File lcd.h der &amp;quot;Fleury-LCD-Lib.&amp;quot;&lt;br /&gt;
extern void lcd_puts_p (const char *progmem_s);&lt;br /&gt;
#define lcd_puts_P(__s) lcd_puts_p(PSTR(__s))&lt;br /&gt;
&lt;br /&gt;
// in einer Anwendung&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;quot;lcd.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
const char StringImFlash[] PROGMEM = &amp;quot;Erwin Lindemann&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
void my_write (void)&lt;br /&gt;
{&lt;br /&gt;
    lcd_puts_p (StringImFlash); &lt;br /&gt;
    lcd_puts_P (&amp;quot;Dr. Kloebner&amp;quot;); &lt;br /&gt;
}&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Flash in der Anwendung schreiben ===&lt;br /&gt;
&lt;br /&gt;
Bei AVRs mit &amp;quot;self-programming&amp;quot;-Option – auch bekannt als [[Bootloader]]-Support – können Teile des Flash-Speichers vom Anwendungsprogramm beschrieben werden. Dies ist nur möglich, wenn die Schreibfunktion in einem besonderen Speicherbereich, der boot-section des Programmspeichers/Flash, abgelegt ist.&lt;br /&gt;
&lt;br /&gt;
Bei einigen kleinen AVRs gibt es keine gesonderte Boot-Section, bei diesen kann der Flashspeicher von jeder Stelle des Programms geschrieben werden. Für Details sei hier auf das jeweilige Controller-Datenblatt und die Erläuterungen zum Modul boot.h der avr-libc verwiesen. Es existieren auch Application-Notes dazu bei atmel.com, die auf avr-gcc-Code übertragbar sind.&lt;br /&gt;
&lt;br /&gt;
Siehe auch: &lt;br /&gt;
* Forumsbeitrag [http://www.mikrocontroller.net/topic/163632#1561622 Daten in Programmspeicher speichern]&lt;br /&gt;
&lt;br /&gt;
=== Warum so kompliziert? ===&lt;br /&gt;
&lt;br /&gt;
Zu dem Thema, warum die Verabeitung von Werten aus dem Flash-Speicher so kompliziert ist, sei hier nur kurz erläutert: Die Harvard-Architektur des AVR weist getrennte Adressräume für Programm(Flash)- und Datenspeicher(RAM) auf. Der C-Standard und der gcc-Compiler sehen keine unterschiedlichen Adressräume vor.&lt;br /&gt;
&lt;br /&gt;
Hat man zum Beispiel eine Funktion string_an_uart(const char* s) und übergibt an diese Funktion die Adresse einer Zeichenkette, z.&amp;amp;nbsp;B. 0x01fe, weiß die Funktion nicht, ob die Adresse auf den Flash-Speicher oder den/das RAM zeigt. Allein aus dem Pointer-Wert, also dem Zahlenwert, kann nicht auf den Ort der Ablage geschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Einige AVR-Compiler bilden die Harvard-Architektur ab, indem sie in einen Pointer nicht nur die Adresse speichern, sondern auch den Ablageort wie &#039;&#039;Flash&#039;&#039; oder &#039;&#039;RAM&#039;&#039;. In einem Aufruf einer Funktion wird dann bei Pointer-Parametern neben der Adresse auch der Speicherbereich, auf den der Pointer zeigt, übergeben. Dies hat jedoch auch Nachteile, denn bei jedem Zugriff über einen Zeiger muss zur &#039;&#039;Laufzeit&#039;&#039; entschieden werden, wie der Zugriff auszuführen ist und entsprechend länglicher und langsamer kann Code ausgeführt werden.&lt;br /&gt;
&lt;br /&gt;
* siehe auch: [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitte Modules/Program Space String Utilities und Abschnitt Modules/Bootloader Support Utilities&lt;br /&gt;
&lt;br /&gt;
== EEPROM ==&lt;br /&gt;
&lt;br /&gt;
Möchte man Werte aus einem Programm heraus so speichern, dass sie auch nach dem Abschalten der Versorgungsspannung noch vorhanden sind und nach dem Wiederherstellen der Versorgungsspannung bei erneutem Programmstart wieder zur Verfügung stehen, dann benutzt man das EEPROM.&lt;br /&gt;
&lt;br /&gt;
Schreib- und Lesezugriffe auf den EEPROM-Speicher erfolgen über die im Modul eeprom.h der avr-libc definierten Funktionen. Mit diesen Funktionen können einzelne Bytes, Datenworte (16bit), Fließkommawerte (16-bit, single-precision, float) und Datenblöcke geschrieben und gelesen werden. &lt;br /&gt;
&lt;br /&gt;
Diese Funktionen kümmern sich auch um diverse Details, die bei der Benutzung des EEPROMS normalerweise notwendig sind:&lt;br /&gt;
* EEPROM Operationen sind im Vergleich relativ langsam. Man muss daher darauf achten, dass eine vorhergehende Operation abgeschlossen ist, ehe die nächste Operation mit dem EEPROM gestartet wird. Die in der avr-libc implementierten Funktionen aus eeprom.h berücksichtigten dies. Soll beim Aufruf einer EEPROM-Funktion sicher gestellt werden, dass diese nicht intern in einer Warteschleife auf den Abschluss der vorherigen Operation wartet, kann vorher per eeprom_is_ready testen, ob der Zugriff auf den EEPROM-Speicher sofort möglich ist.&lt;br /&gt;
* Es ist darauf zu achten, dass die EEPROM Funktionen nicht durch einen Interrupt unterbrochen werden können. Einige Phasen des Zugriffs sind zeitkritisch und müssen in einer definierten Anzahl Takte durchgeführt werden. Durch einen unterbrechenden Interrupt würde diese Restriktion nicht mehr eingehalten. Auch dieses Detail wird von den avr-libc Funktionen berücksichtigt, so dass man sich als C Programmierer nicht darum kümmern muss. Innerhalb der Funktionen werden Interrupts vor der &amp;quot;EEPROM-Sequenz&amp;quot; global deaktiviert und im Anschluss, falls vorher auch schon eingeschaltet, wieder aktiviert.&lt;br /&gt;
&lt;br /&gt;
Man beachte, dass der EEPROM-Speicher nur eine begrenzte Anzahl von Schreibzugriffen zulässt. Beschreibt man eine EEPROM-Zelle öfter als die im Datenblatt zugesicherte Anzahl (typisch 100.000), wird die Funktion der Zelle nicht mehr garantiert. Dies gilt für jede einzelne Zelle. &lt;br /&gt;
&lt;br /&gt;
Bei geschickter Programmierung (z.&amp;amp;nbsp;B. Ring-Puffer), bei der die zu beschreibenden Zellen regelmäßig gewechselt werden, kann man eine deutlich höhere Anzahl an Schreibzugriffen, bezogen auf den gesamten EEPROM-Speicher, erreichen. Auf jeden Fall sollte man aber eine Abschätzung über die zu erwartende Lebensdauer des EEPROM durchführen. Wird ein Wert im EEPROM im Durchschnitt nur einmal pro Woche verändert, wird die garantierte Anzahl der Schreibzyklen innerhalb der voraussichtlichen Verwendungszeit des Controllers wahrscheinlich nicht erreicht. In diesem Fall lohnt es sich daher nicht, erweiterte Programmfunktionen zu implementieren, mit denen die Anzahl der Schreibzugriffe minimiert wird. &lt;br /&gt;
&lt;br /&gt;
Eine weitere Möglichkeit Schreibzyklen einzusparen besteht darin, dass geprüft wird, ob im EEPROM bereits der zu speichernde Wert enthalten ist und nur veränderte Werte zu schreiben. In aktuelleren Versionen der avr-libc sind bereits Funktionen enthalten, die solche Prüfungen enthalten (eeprom_update_*).&lt;br /&gt;
&lt;br /&gt;
Lesezugriffe können beliebig oft durchgeführt werden. Sie unterliegen keinen Einschränkungen in Bezug auf deren Anzahl. &lt;br /&gt;
&lt;br /&gt;
=== EEMEM ===&lt;br /&gt;
Um eine Variable im EEPROM anzulegen, stellt die avr-libc das Makro EEMEM zur Verfügung&amp;lt;ref&amp;gt;In älteren Versionen der avr-libc ist EEMEM noch nicht vorhanden, und man kann sich folgendermassen behelfen:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef EEMEM&lt;br /&gt;
#define EEMEM __attribute__((section (&amp;quot;.eeprom&amp;quot;)))&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/c&amp;gt;&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Byte */&lt;br /&gt;
uint8_t eeFooByte EEMEM = 123;&lt;br /&gt;
&lt;br /&gt;
/* Wort */&lt;br /&gt;
uint16_t eeFooWord EEMEM = 12345;&lt;br /&gt;
&lt;br /&gt;
/* float */&lt;br /&gt;
float eeFooFloat EEMEM;&lt;br /&gt;
&lt;br /&gt;
/* Byte-Array */&lt;br /&gt;
uint8_t eeFooByteArray1[] EEMEM = { 18, 3, 70 };&lt;br /&gt;
uint8_t eeFooByteArray2[] EEMEM = { 30, 7, 79 };&lt;br /&gt;
&lt;br /&gt;
/* 16-bit unsigned short feld */&lt;br /&gt;
uint16_t eeFooWordArray1[4] EEMEM;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die grundsätzliche Vorgehensweise ist identisch zur Verwendung von PROGMEM. Auch hier erzeugt man sich spezielle attributierte Variablen (EEMEM erledigt das), die vom Compiler/Linker nicht wie normale Variablen behandelt werden. Compiler/Linker kümmern sich zwar darum, dass diesen Variablen eine Adresse zugewiesen wird, diese Adresse ist dann aber die Adresse der &#039;Variablen&#039; im EEPROM. Um die dort gespeicherten Werte zu lesen bzw. zu schreiben, übergibt man diese Adresse an spezielle Funktionen, die die entsprechenden Werte aus dem EEPROM holen bzw. das EEPROM neu beschreiben.&lt;br /&gt;
&lt;br /&gt;
Die mittels EEMEM erzeugten &#039;Variablen&#039; sind also mehr als Platzhalter zu verstehen, denn als echte Variablen. Es geht nur darum, im C Programm symbolische Namen zur Verfügung zu haben, anstatt mit echten EEPROM Adressen hantieren zu müssen - etwas das grundsätzlich aber auch genauso gut möglich ist. Nur muss man sich in diesem Fall dann selbst darum kümmern, dass mehrere &#039;Variablen&#039; ohne Überschneidung im EEPROM angeordnet werden.&lt;br /&gt;
&lt;br /&gt;
=== Bytes lesen/schreiben ===&lt;br /&gt;
&lt;br /&gt;
Die avr-libc Funktion zum Lesen eines Bytes heißt eeprom_read_byte. Parameter ist die Adresse des Bytes im EEPROM. Geschrieben wird über die Funktion eeprom_write_byte mit den Parametern Adresse und Inhalt. Anwendungsbeispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#define EEPROM_DEF 0xFF&lt;br /&gt;
&lt;br /&gt;
void eeprom_example (void)&lt;br /&gt;
{&lt;br /&gt;
    uint8_t myByte;&lt;br /&gt;
&lt;br /&gt;
    // myByte lesen (Wert = 123)&lt;br /&gt;
    myByte = eeprom_read_byte (&amp;amp;eeFooByte);&lt;br /&gt;
&lt;br /&gt;
    // der Wert 99 wird im EEPROM an die Adresse der&lt;br /&gt;
    // Variablen eeFooByte geschrieben&lt;br /&gt;
    myByte = 99;&lt;br /&gt;
    eeprom_write_byte(&amp;amp;eeFooByte, myByte); // schreiben&lt;br /&gt;
&lt;br /&gt;
    myByte = eeprom_read_byte (&amp;amp;eeFooByteArray1[1]); &lt;br /&gt;
    // myByte hat nun den Wert 3&lt;br /&gt;
&lt;br /&gt;
    // Beispiel fuer eeprom_update_byte: die EEPROM-Zelle wird nur&lt;br /&gt;
    // dann beschrieben, wenn deren Inhalt sich vom Parameterwert&lt;br /&gt;
    // unterscheidet. In diesem Beispiel erfolgt also kein Schreib-&lt;br /&gt;
    // zugriff, da die Werte gleich sind.&lt;br /&gt;
    eeprom_update_byte(&amp;amp;eeFooByte, myByte);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    // Beispiel zur &amp;quot;Sicherung&amp;quot; gegen leeres EEPROM nach &amp;quot;Chip Erase&amp;quot;&lt;br /&gt;
    // (z. B. wenn die .eep-Datei nach Programmierung einer neuen Version&lt;br /&gt;
    // des Programms nicht in den EEPROM uebertragen wurde und EESAVE&lt;br /&gt;
    // deaktiviert ist (unprogrammed/1)&lt;br /&gt;
    // &lt;br /&gt;
    // Vorsicht: wenn EESAVE &amp;quot;programmed&amp;quot; ist, hilft diese Sicherung nicht&lt;br /&gt;
    // weiter, da die Speicheraddressen in einem neuen/erweiterten Programm&lt;br /&gt;
    // moeglicherweise verschoben wurden. An der Stelle &amp;amp;eeFooByte steht&lt;br /&gt;
    // dann u.U. der Wert einer anderen Variable aus einer &amp;quot;alten&amp;quot; Version.&lt;br /&gt;
&lt;br /&gt;
    uint8_t fooByteDefault = 222;&lt;br /&gt;
    if ((myByte = eeprom_read_byte (&amp;amp;eeFooByte)) == EEPROM_DEF)&lt;br /&gt;
    {&lt;br /&gt;
        myByte = fooByteDefault;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Wort lesen/schreiben ===&lt;br /&gt;
&lt;br /&gt;
Schreiben und Lesen von Datenworten erfolgt analog zur Vorgehensweise bei Bytes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    // lesen&lt;br /&gt;
    uint16_t myWord = eeprom_read_word (&amp;amp;eeFooWord);&lt;br /&gt;
&lt;br /&gt;
    // schreiben&lt;br /&gt;
    eeprom_write_word (&amp;amp;eeFooWord, 2222);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Block lesen/schreiben ===&lt;br /&gt;
&lt;br /&gt;
Lesen und Schreiben von Datenblöcken erfolgt über die Funktionen &amp;lt;code&amp;gt;eeprom_read_block()&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;eeprom_write_block()&amp;lt;/code&amp;gt;. Die Funktionen erwarten drei Parameter: die Adresse der Quell- bzw. Zieldaten im RAM, die EEPROM-Addresse und die Länge des Datenblocks in Bytes als &amp;lt;code&amp;gt;size_t&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint8_t  myByteBuffer[3];&lt;br /&gt;
uint16_t myWordBuffer[4];&lt;br /&gt;
&lt;br /&gt;
void eeprom_block_example (void)&lt;br /&gt;
{&lt;br /&gt;
    /* Datenblock aus EEPROM lesen  */&lt;br /&gt;
&lt;br /&gt;
    /* liest 3 Bytes ab der von eeFooByteArray1 definierten EEPROM-Adresse&lt;br /&gt;
       in das RAM-Array myByteBuffer */&lt;br /&gt;
    eeprom_read_block (myByteBuffer, eeFooByteArray1, 3);&lt;br /&gt;
&lt;br /&gt;
    /* dito mit etwas Absicherung betr. der Länge */&lt;br /&gt;
    eeprom_read_block (myByteBuffer, eeFooByteArray1, sizeof(myByteBuffer));&lt;br /&gt;
&lt;br /&gt;
    /* und nun mit 16-Bit Array */&lt;br /&gt;
    eeprom_read_block (myWordBuffer, eeFooWordArray1, sizeof(myWordBuffer));&lt;br /&gt;
&lt;br /&gt;
    /* Datenblock in EEPROM schreiben */&lt;br /&gt;
    eeprom_write_block (myByteBuffer, eeFooByteArray1, sizeof(myByteBuffer));&lt;br /&gt;
    eeprom_write_block (myWordBuffer, eeFooWordArray1, sizeof(myWordBuffer));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Fließkommawerte lesen/schreiben ===&lt;br /&gt;
&lt;br /&gt;
In der avr-libc stehen auch EEPROM-Funktionen für Variablen des Typs float (Fließkommazahlen mit &amp;quot;einfacher&amp;quot; Genauigkeit) zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
float eeFloat EEMEM = 12.34f;&lt;br /&gt;
&lt;br /&gt;
float void eeprom_float_example(float value)&lt;br /&gt;
{&lt;br /&gt;
   /* float in EEPROM schreiben */&lt;br /&gt;
   eeprom_write_float(&amp;amp;eeFloat, value);&lt;br /&gt;
&lt;br /&gt;
   /* float aus EEPROM lesen */&lt;br /&gt;
   return  eeprom_read_float(&amp;amp;eeFloat);&lt;br /&gt;
}&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== EEPROM-Speicherabbild in .eep-Datei ===&lt;br /&gt;
&lt;br /&gt;
Mit den zum Compiler gehörenden Werkzeugen kann der aus den Variablendeklarationen abgeleitete EEPROM-Inhalt in eine Datei geschrieben werden. Die übliche Dateiendung ist .eep, Daten im Intel Hex-Format. Damit können Standardwerte für den EEPROM-Inhalt im Quellcode definiert werden. &lt;br /&gt;
&lt;br /&gt;
Makefiles nach WinAVR/MFile-Vorlage enthalten bereits die notwendigen Einstellungen, siehe dazu die Erläuterungen im [[AVR-GCC-Tutorial/Exkurs Makefiles|Exkurs Makefiles]].&lt;br /&gt;
&lt;br /&gt;
Der Inhalt der eep-Datei muss ebenfalls zum Mikrocontroller übertragen werden, wenn die Initialisierungswerte aus der Deklaration vom Programm erwartet werden. Ansonsten enthält der EEPROM-Speicher nach der Übertragung des Programmers mittels ISP abhängig von der Einstellung der EESAVE-Fuse&amp;lt;ref&amp;gt;vgl. Datenblatt Abschnitt Fuse Bits&amp;lt;/ref&amp;gt; nicht die korrekten Werte:&lt;br /&gt;
; EESAVE = 0 (programmed): Die Daten im EEPROM bleiben erhalten. Werden sie nicht neu geschrieben, so enthält das EEPROM evtl. Daten, die nicht mehr zum Programm passen.&lt;br /&gt;
; EESAVE = 1 (unprogrammed): Beim Programmieren werden die Daten im EEPROM gelöscht, also auf 0xff gesetzt.&lt;br /&gt;
&lt;br /&gt;
Als Sicherung kann man im Programm nochmals die Standardwerte vorhalten, beim Lesen auf 0xFF prüfen und gegebenenfalls einen Standardwert nutzen.&lt;br /&gt;
&lt;br /&gt;
=== Direkter Zugriff auf EEPROM-Adressen ===&lt;br /&gt;
&lt;br /&gt;
Will man direkt auf bestimmte EEPROM Adressen zugreifen, dann sind folgende Funktionen hilfreich, um sich die Typecasts zu ersparen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Byte aus dem EEPROM lesen&lt;br /&gt;
uint8_t EEPReadByte(uint16_t addr)&lt;br /&gt;
{&lt;br /&gt;
  return eeprom_read_byte((uint8_t *)addr);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Byte in das EEPROM schreiben&lt;br /&gt;
void EEPWriteByte(uint16_t addr, uint8_t val)&lt;br /&gt;
{&lt;br /&gt;
  eeprom_write_byte((uint8_t *)addr, val);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oder als Makro:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#define   EEPReadByte(addr)         eeprom_read_byte((uint8_t *)addr)     &lt;br /&gt;
#define   EEPWriteByte(addr, val)   eeprom_write_byte((uint8_t *)addr, val)&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verwendung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
EEPWriteByte(0x20, 128);   // Byte an die Adresse 0x20 schreiben&lt;br /&gt;
...&lt;br /&gt;
Val=EEPReadByte(0x20);     // EEPROM-Wert von Adresse 0x20 lesen&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bekannte Probleme bei den EEPROM-Funktionen ===&lt;br /&gt;
&lt;br /&gt;
Vorsicht: Bei alten Versionen der avr-libc wurden nicht alle AVR Controller  unterstützt. Z.B. bei der avr-libc Version 1.2.3 insbesondere bei AVRs &amp;quot;der neuen Generation&amp;quot; (ATmega48/88/168/169) funktionieren die Funktionen nicht korrekt (Ursache: unterschiedliche Speicheradressen der EEPROM-Register). In neueren Versionen (z.&amp;amp;nbsp;B. avr-libc 1.4.3 aus WinAVR 20050125) wurde die Zahl der unterstüzten Controller deutlich erweitert und eine Methode zur leichten Anpassung an zukünftige Controller eingeführt.&lt;br /&gt;
&lt;br /&gt;
In jedem Datenblatt zu AVR-Controllern mit EEPROM sind kurze Beispielecodes für den Schreib- und Lesezugriff enthalten. Will oder kann man nicht auf die neue Version aktualisieren, kann der dort gezeigte Code auch mit dem avr-gcc (ohne avr-libc/eeprom.h) genutzt werden (&amp;quot;copy/paste&amp;quot;, gegebenfalls Schutz vor Unterbrechnung/Interrupt ergänzen &#039;&#039;uint8_t sreg; sreg=SREG; cli(); [EEPROM-Code] ; SREG=sreg; return;&#039;&#039;, siehe Abschnitt Interrupts). Im Zweifel hilft ein Blick in den vom Compiler erzeugten Assembler-Code (lst/lss-Dateien).&lt;br /&gt;
&lt;br /&gt;
* siehe auch: [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/EEPROM handling&lt;br /&gt;
&lt;br /&gt;
=== EEPROM Register ===&lt;br /&gt;
Um das EEPROM anzusteuern, sind drei Register von Bedeutung:&lt;br /&gt;
;EEAR: Hier werden die Adressen eingetragen zum Schreiben oder Lesen. Dieses Register unterteilt sich nochmal in EEARH und EEARL, da in einem 8-Bit-Register keine 512 Adressen adressiert werden können.&lt;br /&gt;
;EEDR: Hier werden die Daten eingetragen, die geschrieben werden sollen, bzw. es enthält die gelesenen Daten.&lt;br /&gt;
;EECR: Ist das Kontrollregister für das EEPROM&lt;br /&gt;
&lt;br /&gt;
Das EECR steuert den Zugriff auf das EEPROM und ist wie folgt aufgebaut:&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Aufbau des EECR-Registers&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
!Bit&lt;br /&gt;
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|-&lt;br /&gt;
! Name&lt;br /&gt;
| - || - || - ||- || EERIE || EEMWE || EEWE || EERE&lt;br /&gt;
|-&lt;br /&gt;
! Read/Write&lt;br /&gt;
| R || R || R || R || R/W || R/W || R/W || R/W&lt;br /&gt;
|-&lt;br /&gt;
!Init Value&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bedeutung der Bits&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
;Bit 4-7: nicht belegt&lt;br /&gt;
&lt;br /&gt;
;Bit 3 (EERIE): &#039;&#039;EEPROM Ready Interrupt Enable&#039;&#039;: Wenn das Bit gesetzt ist und globale Interrupts erlaubt sind in Register SREG (Bit 7), wird ein Interrupt ausgelöst nach Beendigung des Schreibzyklus (EEPROM Ready Interrupt). Ist einer der beiden Bits 0, wird kein Interrupt ausgelöst.&lt;br /&gt;
&lt;br /&gt;
;Bit 2 EEMWE): &#039;&#039;EEPROM Master Write Enable&#039;&#039;: Dieses Bit bestimmt, dass, wenn EEWE = 1 gesetzt wird (innerhalb von 4 Taktzyklen), das EEPROM beschrieben wird mit den Daten in EEDR bei Adresse EEAR. Wenn EEMWE = 0 ist und EEWE = 1 gesetzt wird, hat das keine Auswirkungen. Der Schreibvorgang wird dann nicht ausgelöst. Nach 4 Taktzyklen wird das Bit EEMWE automatisch wieder auf 0 gesetzt. Dieses Bit löst den Schreibvorgang nicht aus, es dient sozusagen als Sicherungsbit für EEWE.&lt;br /&gt;
&lt;br /&gt;
;Bit 1 (EEWE): &#039;&#039;EEPROM Write Enable&#039;&#039;: Dieses Bit löst den Schreibvorgang aus, wenn es auf 1 gesetzt wird, sofern vorher EEMWE gesetzt wurde und seitdem nicht mehr als 4 Taktzyklen vergangen sind. Wenn der Schreibvorgang abgeschlossen ist, wird dieses Bit automatisch wieder auf 0 gesetzt und, sofern EERIE gesetzt ist, ein Interrupt ausgelöst. Ein Schreibvorgang sieht typischerweise wie folgt aus:&lt;br /&gt;
:# EEPROM-Bereitschaft abwarten (EEWE=0) &lt;br /&gt;
:# Adresse übergeben an EEAR&lt;br /&gt;
:# Daten übergeben an EEDR&lt;br /&gt;
:# Schreibvorgang auslösen in EECR mit Bit EEMWE=1 und EEWE=1&lt;br /&gt;
:# (Optional) Warten, bis Schreibvorgang abgeschlossen ist&lt;br /&gt;
&lt;br /&gt;
;Bit 0 EERE: &#039;&#039;EEPROM Read Enable&#039;&#039;: Wird dieses Bit auf 1 gesetzt wird das EEPROM an der Adresse in EEAR ausgelesen und die Daten in EEDR gespeichert. Das EEPROM kann nicht ausgelesen werden, wenn bereits eine Schreiboperation gestartet wurde. Es ist daher zu empfehlen, die Bereitschaft vorher zu prüfen. Das EEPROM ist lesebereit, wenn das Bit EEWE=0 ist. Ist der Lesevorgang abgeschlossen, wird das Bit wieder auf 0 gesetzt, und das EEPROM ist für neue Lese- und Schreibbefehle wieder bereit. Ein typischer Lesevorgang kann wie folgt aufgebaut sein:&lt;br /&gt;
:# Bereitschaft zum Lesen prüfen (EEWE=0)&lt;br /&gt;
:# Adresse übergeben an EEAR&lt;br /&gt;
:# Lesezyklus auslösen mit EERE = 1&lt;br /&gt;
:# Warten, bis Lesevorgang abgeschlossen EERE = 0&lt;br /&gt;
:# Daten abholen aus EEDR&lt;br /&gt;
&lt;br /&gt;
= Die Nutzung von sprintf und printf =&lt;br /&gt;
&lt;br /&gt;
Um komfortabel, d.h. formatiert, Ausgaben auf ein Display oder die serielle Schnittstelle zu tätigen, bieten sich &#039;&#039;&#039;sprintf&#039;&#039;&#039; oder &#039;&#039;&#039;printf&#039;&#039;&#039; an. Alle *printf-Varianten sind jedoch ziemlich speicherintensiv und der Einsatz in einem Mikrocontroller mit knappem Speicher muss sorgsam abgewogen werden.&lt;br /&gt;
&lt;br /&gt;
Bei &#039;&#039;&#039;sprintf&#039;&#039;&#039; wird die Ausgabe zunächst in einem Puffer vorbereitet und anschließend mit einfachen Funktionen zeichenweise ausgegeben. Es liegt in der Verantwortung des Programmierers, genügend Platz im Puffer für die erwarteten Zeichen bereitzuhalten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ...&lt;br /&gt;
// nicht dargestellt: Implementierung von uart_puts (vgl. Abschnitt UART)&lt;br /&gt;
// ...&lt;br /&gt;
&lt;br /&gt;
uint16_t counter;&lt;br /&gt;
&lt;br /&gt;
// Ausgabe eines unsigned Integerwertes&lt;br /&gt;
void uart_puti( uint16_t value )&lt;br /&gt;
{&lt;br /&gt;
    uint8_t puffer[20];&lt;br /&gt;
&lt;br /&gt;
    sprintf( puffer, &amp;quot;Zählerstand: %u&amp;quot;, value );&lt;br /&gt;
    uart_puts( puffer );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  counter = 5;&lt;br /&gt;
&lt;br /&gt;
  uart_puti( counter );&lt;br /&gt;
  uart_puti( 42 );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine weitere elegante Möglichkeit besteht darin, den STREAM stdout (Standardausgabe) auf eine eigene Ausgabefunktion umzuleiten. Dazu wird dem Ausgabemechanismus der C-Bibliothek eine neue Ausgabefunktion bekannt gemacht, deren Aufgabe es ist, ein einzelnes Zeichen auszugeben. Wohin die Ausgabe dann tatsächlich stattfindet, ist Sache der Ausgabefunktion. Im Beispiel unten wird auf UART ausgegeben. Alle anderen, höheren Funktionen wie z.&amp;amp;nbsp;B. &#039;&#039;&#039;printf&#039;&#039;&#039;, greifen letztendlich auf diese primitive Ausgabefunktion zurück. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void uart_init(void);&lt;br /&gt;
&lt;br /&gt;
// a. Deklaration der primitiven Ausgabefunktion&lt;br /&gt;
int uart_putchar(char c, FILE *stream);&lt;br /&gt;
&lt;br /&gt;
// b. Umleiten der Standardausgabe stdout (Teil 1)&lt;br /&gt;
static FILE mystdout = FDEV_SETUP_STREAM( uart_putchar, NULL, _FDEV_SETUP_WRITE );&lt;br /&gt;
&lt;br /&gt;
// c. Definition der Ausgabefunktion&lt;br /&gt;
int uart_putchar( char c, FILE *stream )&lt;br /&gt;
{&lt;br /&gt;
    if( c == &#039;\n&#039; )&lt;br /&gt;
        uart_putchar( &#039;\r&#039;, stream );&lt;br /&gt;
&lt;br /&gt;
    loop_until_bit_is_set( UCSRA, UDRE );&lt;br /&gt;
    UDR = c;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void uart_init(void)&lt;br /&gt;
{&lt;br /&gt;
    /* hier µC spezifischen Code zur Initialisierung */&lt;br /&gt;
    /* des UART einfügen... s.o. im AVR-GCC-Tutorial */&lt;br /&gt;
&lt;br /&gt;
    // Beispiel: &lt;br /&gt;
    //&lt;br /&gt;
    // myAVR Board 1.5 mit externem Quarz Q1 3,6864 MHz&lt;br /&gt;
    // 9600 Baud 8N1&lt;br /&gt;
&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
#define F_CPU 3686400&lt;br /&gt;
#endif&lt;br /&gt;
#define UART_BAUD_RATE 9600&lt;br /&gt;
&lt;br /&gt;
// Hilfsmakro zur UBRR-Berechnung (&amp;quot;Formel&amp;quot; laut Datenblatt)&lt;br /&gt;
#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1)&lt;br /&gt;
&lt;br /&gt;
    UCSRB |= (1&amp;lt;&amp;lt;TXEN) | (1&amp;lt;&amp;lt;RXEN);    // UART TX und RX einschalten&lt;br /&gt;
    UCSRC |= (1&amp;lt;&amp;lt;URSEL)|(3&amp;lt;&amp;lt;UCSZ0);    // Asynchron 8N1 &lt;br /&gt;
 &lt;br /&gt;
    UBRRH = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) &amp;gt;&amp;gt; 8 );&lt;br /&gt;
    UBRRL = (uint8_t)UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    int16_t antwort = 42;&lt;br /&gt;
    uart_init();&lt;br /&gt;
&lt;br /&gt;
    // b. Umleiten der Standardausgabe stdout (Teil 2)&lt;br /&gt;
    stdout = &amp;amp;mystdout;&lt;br /&gt;
&lt;br /&gt;
    // Anwendung&lt;br /&gt;
    printf( &amp;quot;Die Antwort ist %d.\n&amp;quot;, antwort );&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Quelle: avr-libc-user-manual-1.4.3.pdf, S.74&lt;br /&gt;
//         + Ergänzungen&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sollen Fließkommazahlen ausgegeben werden, muss im Makefile eine andere (größere) Version der [[FAQ#Aktivieren_der_Floating_Point_Version_von_sprintf_beim_WinAVR_mit_AVR-Studio|printflib]] eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
= Anmerkungen =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= TODO =&lt;br /&gt;
* Aktualisierung Register- und Bitbeschreibungen an aktuelle AVR&lt;br /&gt;
* &amp;quot;naked&amp;quot;-Funktionen&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:avr-gcc Tutorial| ]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Diskussion:Elektronikversender&amp;diff=68124</id>
		<title>Diskussion:Elektronikversender</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Diskussion:Elektronikversender&amp;diff=68124"/>
		<updated>2012-08-28T17:01:17Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: Wortwahl?&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Elektronikversender&amp;diff=68123</id>
		<title>Elektronikversender</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Elektronikversender&amp;diff=68123"/>
		<updated>2012-08-28T17:00:00Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* Waschbär Soft 2010 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Vor- und Nachteile von verschiedenen Elektronik-Versand-Händlern werden relativ häufig im Forum diskutiert. Diese Diskussionen führen nicht selten zu weitestgehend gleichen Ergebnissen. In diesem Artikel sollen daher die Argumente, die für oder gegen einen bestimmten Elektronik-Versender sprechen, zusammengetragen werden. Sobald diese Liste einigermaßen vollständig ist, würde dies sicher einige Diskussions-Threads und/oder Flame-Wars überflüssig machen.&lt;br /&gt;
&lt;br /&gt;
Diese Liste erhebt keinerlei Anspruch auf Vollständigkeit, d.h. wenn ihr einen Versender kennt, der hier noch nicht aufgeführt ist, dann nennt wenigstens die URL und den Namen. Den Rest können auch andere besorgen, die den Versender ebenfalls kennen!&lt;br /&gt;
&lt;br /&gt;
Bitte ergänzt nur allgemeine Sachen (z.&amp;amp;nbsp;B. &amp;quot;liefert immer vollständig&amp;quot;, &amp;quot;günstig&amp;quot; oder &amp;quot;große Auswahl&amp;quot;), aber nicht Sachen wie &amp;quot;mein ATMega 128 hatte verbogene Beine&amp;quot;! Bitte auch die alphabetische Sortierung beibehalten!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Diese Seite kann nur von angemeldeten Benutzern bearbeitet werden!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
__TOC__&lt;br /&gt;
&lt;br /&gt;
== Liste der Versender ==&lt;br /&gt;
&lt;br /&gt;
=== AATiS ===&lt;br /&gt;
Homepage: http://www.aatis.de&lt;br /&gt;
&lt;br /&gt;
* Arbeitskreis Amateurfunk und Technik in der Schule e.V.&lt;br /&gt;
* Bausätze speziell auch für Elektronik-Anfänger, Schüler&lt;br /&gt;
* Literatur, Seminare für Lehrer &lt;br /&gt;
&lt;br /&gt;
=== Actron ===&lt;br /&gt;
Homepage: http://www.actron.de&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;kein&#039;&#039;&#039; Online-Shop!&lt;br /&gt;
* alphanumerische LCDs und Graphikdisplays in großer Auswahl, auch mit Touchscreens&lt;br /&gt;
* für gewerbliche Kunden: etwas verhandeln schadet nie&lt;br /&gt;
* bei kleinen Stückzahlen nicht ganz billig&lt;br /&gt;
* liefern sehr schnell und stets zuverlässig&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=== Adapterprofi ===&lt;br /&gt;
Homepage: http://www.adapterprofi.de&lt;br /&gt;
&lt;br /&gt;
* Bauteile, Gehäuse, Netzteile&lt;br /&gt;
* Viele unterschiedliche HF-Adapter&lt;br /&gt;
* Seite aktuell nicht erreichbar (10.12.2011) ist wohl tot&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== AK Modul Bus Computer GmbH ===&lt;br /&gt;
Homepage: http://www.ak-modul-bus.com/stat/produkte.html&lt;br /&gt;
&lt;br /&gt;
* Interfaces, Messmodule, Funktionsmodelle, Experimentiersysteme&lt;br /&gt;
* Entwicklungssysteme, Baugruppen, Elektor, Zubehör, Bauelemente&lt;br /&gt;
* Software, Lernpakete, Bücher, Sonderposten&lt;br /&gt;
&lt;br /&gt;
=== Allpax ===&lt;br /&gt;
Homepage: http://www.allpax.de&lt;br /&gt;
&lt;br /&gt;
* Liefert auch an Privathaushalte&lt;br /&gt;
* Keine Elektronik an sich, aber ggf. nützliches Zubehör: Größeres, übersichtliches Sortiment an ESD-Beuteln und -Folien, offen und mit Zippverschluss, Pink Poly und Metallisiert (High Shield). Preislich über Farnell, dafür findet man sofort, was man sucht...&lt;br /&gt;
* außerdem Ultraschallreiniger, Waagen und Folienschweißgeräte, sowie viel Fachfremdes&lt;br /&gt;
* Versandkosten: 8,33€ nach Deutschland, diverse EU-Länder 17,85€, Schweiz 34,51€; Versandkostenfrei in D ab 178,50€&lt;br /&gt;
* Gewährt scheinbar auch Privatkunden die Zahlung per Rechnung; bei Bankeinzug 2% Rabatt, bei Vorkasse und Abholung 3%&lt;br /&gt;
&lt;br /&gt;
=== AME-Engineering ===&lt;br /&gt;
Homepage: http://www.ame-engineering.de&lt;br /&gt;
&lt;br /&gt;
* Hochfrequenz-Spezialitäten, Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Amidon ===&lt;br /&gt;
Homepage: http://www.amidon.de&lt;br /&gt;
&lt;br /&gt;
* Sehr großes Sortiment, vorallem für seltene Bauteile, z.&amp;amp;nbsp;B. Dioden&lt;br /&gt;
&lt;br /&gt;
=== Andy&#039;s Funkladen ===&lt;br /&gt;
Homepage: http://www.andyfunk.de&lt;br /&gt;
&lt;br /&gt;
* Alles für Amateur- und CB-Funk&lt;br /&gt;
* Bauteile und Gehäuse&lt;br /&gt;
&lt;br /&gt;
=== Anvilex ===&lt;br /&gt;
Homepage: http://shop.anvilex.com/index.html&lt;br /&gt;
&lt;br /&gt;
* Liefert sehr günstige Break-Out Boards für diverse Packages&lt;br /&gt;
* Hat einige einfache und günstige Programmer auch für FPGAs etc&lt;br /&gt;
&lt;br /&gt;
=== Atlantis Shop 24 ===&lt;br /&gt;
Homepage: http://www.atlantis-shop24.de&lt;br /&gt;
&lt;br /&gt;
* Elektronik nur ein kleiner Teil des Angebotes. Ansonsten eher Drogerie bzw. Haushaltsbedarf&lt;br /&gt;
&lt;br /&gt;
=== Atzert-Elektronik Versand ===&lt;br /&gt;
Homepage: http://www.atzert-elektronik.de&lt;br /&gt;
&lt;br /&gt;
Früher &#039;&#039;EFB-Electronic Versand&#039;&#039;, davor &#039;&#039;MEGAKICK Electronic Stores&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* Mindestens schon der dritte Name und die dritte Webseite für den Endkunden-Versand von [[Elektronikversender#ETT|ETT]]. ETT liefert sonst nur an gewerbliche Kunden.&lt;br /&gt;
* Ladengeschäfte in Bielefeld, Braunschweig, Bremen, Hamburg und Berlin. &lt;br /&gt;
* Die Preise schwanken im Vergleich zu anderen Anbietern, welche ebenfalls ETT-importierte Produkte führen, mal nach oben, mal nach unten.&lt;br /&gt;
&lt;br /&gt;
=== Bassenberg Elektronik ===&lt;br /&gt;
Homepage: http://www.bassenberg.de&lt;br /&gt;
&lt;br /&gt;
* Ladengeschäfte in Braunschweig und Neumünster&lt;br /&gt;
* Beschafft auch nicht mehr gelistete und abgekündigte Bauteile&lt;br /&gt;
* Liefert auch an Privat&lt;br /&gt;
&lt;br /&gt;
=== Batronix ===&lt;br /&gt;
Homepage: http://www.batronix.com&lt;br /&gt;
* Grosses Sortiment an Geräten&lt;br /&gt;
* Bausätze für Microcontroller-Applikationen&lt;br /&gt;
* Liefert auch an Privat&lt;br /&gt;
&lt;br /&gt;
=== BAZ Spezialantennen ===&lt;br /&gt;
Homepage: http://www.spezialantennen.de&lt;br /&gt;
&lt;br /&gt;
* Antennen für Amateurfunk, ISM, WLAN usw.&lt;br /&gt;
&lt;br /&gt;
=== bed - elektronik ===&lt;br /&gt;
Homepage: http://www.bed-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Restposten aktive und passive Bauelemente&lt;br /&gt;
* sehr günstige Preise&lt;br /&gt;
* alles ab Lager lieferbar&lt;br /&gt;
* Versand an Privat&lt;br /&gt;
* ab 60 EUR versandkostenfrei&lt;br /&gt;
&lt;br /&gt;
=== Bfi-Optilas ===&lt;br /&gt;
Homepage: http://www.bfioptilas.de&lt;br /&gt;
&lt;br /&gt;
* Kein Onlineshop&lt;br /&gt;
* spezialisierter Distributor für Hochfrequenzhalbleiter und Optik&lt;br /&gt;
&lt;br /&gt;
=== BG-Electronics.de ===&lt;br /&gt;
Homepage: http://www.bg-electronics.de&lt;br /&gt;
&lt;br /&gt;
* Online Shop für aktive und passive elektronische Bauelememte&lt;br /&gt;
* günstige Preise&lt;br /&gt;
* alle Artikel ab Lager lieferbar, daher kurze Wartezeiten&lt;br /&gt;
* weltweiter Versand&lt;br /&gt;
* zahlreiche Mengenrabatte&lt;br /&gt;
* viele Ersatzteile aus dem Audio-, CarHiFi und TV-Bereich&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
=== B &amp;amp; M electronics ===&lt;br /&gt;
Homepage: http://www.bmelectronics.de&lt;br /&gt;
&lt;br /&gt;
* Bauteile, Platinen und Baugruppen für Amateurfunk&lt;br /&gt;
Seite nicht erreichbar am 22.7.2012 --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Box73 ===&lt;br /&gt;
Homepage: http://www.box73.de&lt;br /&gt;
&lt;br /&gt;
Onlineshop des Funkamateur.&lt;br /&gt;
&lt;br /&gt;
* Bauteile, Bausätze, Literatur aus dem Amateurfunkbereich&lt;br /&gt;
* Preise sind O.K.&lt;br /&gt;
* Bestellungen werden nur Di und Do bearbeitet&lt;br /&gt;
* Ab 50 EUR bei Bankeinzug portofrei.&lt;br /&gt;
&lt;br /&gt;
=== Bürklin OHG ===&lt;br /&gt;
Homepage: http://www.buerklin.com&lt;br /&gt;
&lt;br /&gt;
* große Auswahl, hohe Verfügbarkeit&lt;br /&gt;
* sehr schneller Versand&lt;br /&gt;
* Ladengeschäft in Oberhaching (südlicher Landkreis München)&lt;br /&gt;
* &amp;lt;s&amp;gt;nur an gewerbliche Abnehmer (lt. AGB), private Abnehmer können dennoch im Ladengeschäft einkaufen&amp;lt;br&amp;gt;Angeblich versendet Bürklin seit November 2010 auch an Privatpersonen. Allerdings verlangt Bürklin weiterhin in Adressformularen die Eingabe eines Firmennamens &amp;lt;br&amp;gt;Geben Sie einen Wert in das Feld &amp;quot;Firma&amp;quot; ein.&amp;lt;br&amp;gt;Daher ist diese Information eher mit Vorsicht zu genießen.&amp;lt;/s&amp;gt;&amp;lt;br&amp;gt;Mittlerweile muss man auch keinen Firmennamen mehr eingeben. Die AGB wurde ebenfalls angepasst.&lt;br /&gt;
* 35 EUR Mindestbestellwert (incl. MwSt), darunter 7 EUR Bearbeitungskosten&lt;br /&gt;
&lt;br /&gt;
=== CBsoft, s.r.o. (ltd.) ===&lt;br /&gt;
*Homepage: http://www.jjtubes.eu/&lt;br /&gt;
* Firma in der Slowakei&lt;br /&gt;
* Verkauft Röhren der Firma JJ&lt;br /&gt;
* englischsprachig&lt;br /&gt;
* Zahlungsmöglichkeiten in € mit Paypal und Kreditkarte&lt;br /&gt;
&lt;br /&gt;
=== chiptrade.com ===&lt;br /&gt;
siehe [[#SE Spezial-Electronic AG|SE Spezial-Electronic AG]]&lt;br /&gt;
&lt;br /&gt;
=== ConeleK Electronic ===&lt;br /&gt;
Homepage: http://www.conelek.com&lt;br /&gt;
&lt;br /&gt;
* Sehr kleines Bauteileangebot (Röhren, Röhrensockel)&lt;br /&gt;
* Elektronik-Laborbedarf, insbesondere Nachfüllpackungen mit Steckbrett-Drahtbrücken&lt;br /&gt;
* Werkzeug für Elektronik&lt;br /&gt;
* Stromversorgungen&lt;br /&gt;
* Versand an Privat&lt;br /&gt;
* Versandkosten bis 25kg, Vorkasse 5,90€ (Stand 04/2008)&lt;br /&gt;
&lt;br /&gt;
=== Conrad ===&lt;br /&gt;
Homepage: http://www.conrad.de und http://www.business.conrad.de&lt;br /&gt;
&lt;br /&gt;
* großes Angebot (für Bauteile den &amp;quot;Business&amp;quot;-Katalog beachten, der Hauptkatalog ist dahingehend etwas &amp;quot;dünn&amp;quot;) (Anm.: Bauteile, die nur im Business-Katalog aufgeführt sind, sind in Ladengeschäften nur über Sonderbestellung zu bekommen, d.h. dort in aller Regel nicht vorrätig.)&lt;br /&gt;
* Positiv: Wirklich jedes Bauteil kann einzeln gekauft werden und wird nicht in dämlichen Verpackungseinheiten verkauft, so wie es bei den meisten anderen Elektronik-Lieferanten der Fall ist. Dies ist vor Allem für den Prototypenbau sehr hilfreich.&lt;br /&gt;
* relativ teuer jedoch bis zu 10% Rabatt für Schulen (bei genügend Umsatz)&lt;br /&gt;
* 21 Ladengeschäfte in Deutschland, fünf in Österreich&lt;br /&gt;
* positiv: Bei Business-Kunden wird der Rechnungsbetrag erst nach 14 Tagen abgebucht.&lt;br /&gt;
* haben einen (teuren) 24 Std. Lieferservice für Notfälle - Conrad garantiert aber nicht 100%ig für die Einhaltung der 24 Stunden. Bei Nichteinhaltung gibt es kein Geld zurück.&lt;br /&gt;
* Verfügbarkeit in Filialen kann Online überprüft werden.&lt;br /&gt;
* Verfügbarkeit in Filialen kann über zentale Rufnummer erfragt werden. Abholung bestellter Ware in Filialen möglich, aber trotzdem gleiche Versandkosten.&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
Vorerst Auskommentiert - Subjektiv/Einzelerfahrung, veraltete Informationen (Filialen)&lt;br /&gt;
* Mit jeder Bestellung erhält man zusätzlich Werbung von unseriösen Firmen, wo Gewinne versprochen werden und man sich in Wirklichkeit für irgendwelche Abos verpflichtet. Wenn man bei Conrad anruft und sie zur Rede stellt, erhält man die Antwort, dass diese Werbung anscheinend aus Versehen hineingerutscht ist. So ein Zufall.&lt;br /&gt;
* sehr kulant bei Umtäuschen&lt;br /&gt;
* versuchen bei Rückgaben einen Teil oder den gesamten Betrag einzubehalten (schon mehrfach vorgekommen)&lt;br /&gt;
* Schlampig verpackte Artikel. ICs sind nicht Antistatik-Konform verpackt.&lt;br /&gt;
* Die Filiale München / Tal hat keine Telefonnummer mehr in den Verzeichnissen, anscheinend sind Kundenanfragen dort zu &amp;quot;lästig&amp;quot;. (Kommentar: andere Filialen auch nicht, wird nur noch über eine Sammelnummer über ein Callcenter abgewickelt. Die Ladenbestellung wird dann vom Callcenter per eMail an die Filiale weitergeleitet.)&lt;br /&gt;
* die Ladengeschäfte haben nicht das gesamte Programm vor Ort, man kann jedoch in den Geschäften anrufen und die Verfügbarkeit anfragen, evtl. sogar Teile für ein paar Stunden &amp;quot;zurücklegen lassen&amp;quot; (von Geschäft zu Geschäft verschieden).&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== csd-electronics ===&lt;br /&gt;
Homepage: [http://www.csd-electronics.de csd-electronics.de]&lt;br /&gt;
&lt;br /&gt;
* ATMEL, ICs, Passive und Mechanische Bauteile, Platinen- und Lötzubehör, u.a.&lt;br /&gt;
* ca. 4000 Bauteile lagernd&lt;br /&gt;
* günstig&lt;br /&gt;
* Mengenrabatte für fast jedes Produkt&lt;br /&gt;
* Versand innerhalb Deutschlands: &lt;br /&gt;
* DPD: 3,75€ (ab 50 EUR versandkostenfrei)&lt;br /&gt;
* DHL: 4,50€ (ab 100 EUR versandkostenfrei)&lt;br /&gt;
* Versand EU-weit ab 5,95 EUR&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* schnelle Lieferung, sofern die Artikel auf Lager sind, versandkostenfreie Nachlieferung&lt;br /&gt;
* Bauelemente, die nicht im Shop angeboten werden, können auf Anfrage beschafft werden.&lt;br /&gt;
* Zahlung per Vorkasse (2% Skonto), PayPal, Nachnahme. 1 EUR Aufschlag bei PayPal-Zahlung&lt;br /&gt;
* Zahlung per Bankabbuchung, Kreditkarte oder Rechnung nur für Stammkunden (ab 4 bis 5 Bestellung), Für Institute/Firmen direkt auf Rechnung möglich&lt;br /&gt;
* haben ein Forum, in dem man sich zu Sammelbestellungen organisieren kann und auch allgemeine Fragen stellen kann -zur Zeit (05/2008) offline-&lt;br /&gt;
&lt;br /&gt;
=== dad24 ===&lt;br /&gt;
Homepage, Shop: http://dad24.eu&lt;br /&gt;
E-Bay Shop:     http://stores.ebay.de/Shop-dad24&lt;br /&gt;
&lt;br /&gt;
* Unterschiedliche Preise in den beiden Shops&lt;br /&gt;
* Kleiner, nicht sonderlich schöner Onlineshop (dad24.eu)&lt;br /&gt;
* Kleines Angebot. Lupenleuchten, Lötstationen, Labornetzgeräte, Messgeräte, etc. aus dem unteren Preissegment&lt;br /&gt;
* Jede Woche eine neue &amp;quot;Kategorie der Woche&amp;quot; auf dad24.eu. Produkte aus der Kategorie werden erst im Warenkorb mit einem Rabatt angezeigt, der auch gewährt wird.&lt;br /&gt;
&lt;br /&gt;
=== Darisus ===&lt;br /&gt;
Homepage: http://www.darisus.de&lt;br /&gt;
&lt;br /&gt;
* kompetente Beratung&lt;br /&gt;
* liefert sehr zuverlässig, in Notfällen auch Express&lt;br /&gt;
* Versand innerhalb Deutschlands ab 4,50 EUR&lt;br /&gt;
* Hat auch eine gute Auswahl an CPLDs und einige FPGAs diverser Hersteller&lt;br /&gt;
&lt;br /&gt;
=== Daschke LTD ===&lt;br /&gt;
PDF-Katalog (Achtung, grosse Datei): http://www.daschke-ltd.de/Catalog/&lt;br /&gt;
&lt;br /&gt;
* Prompte Antwort und Hilfe via info ät obige adresse&lt;br /&gt;
* Bezahlung per Paypal und Rechnung möglich. Ist auch Ebay-Händler.&lt;br /&gt;
* sehr faire Preise für Bauteile und Versand&lt;br /&gt;
* Führt eine Vielzahl an unüblichen Steckern und Buchsen&lt;br /&gt;
* Nicht verfügbare Bauteile wurden proaktiv nachbestellt, trotz geringer Bestellmenge. Prima!&lt;br /&gt;
&lt;br /&gt;
=== DES - Der Elektroniker-Shop ===&lt;br /&gt;
Homepage: http://www.DerElektronikerShop.de&lt;br /&gt;
&lt;br /&gt;
* Bauteile&lt;br /&gt;
* Bauteilsätze der [http://www.DieElektronikerseite.de Elektronikerseite]&lt;br /&gt;
* Verkauf des BasicBeetle und Zubehör von [http://www.DieProjektseite.de der Projektseite]&lt;br /&gt;
* Ständig wachsendes Angebot&lt;br /&gt;
* Auch einige SMD-Bauteile verfügbar&lt;br /&gt;
* Kein Mindestbestellwert&lt;br /&gt;
* Versandkosten ab 3,50 EUR (Österreich/Europa ab 4,00 Eur)&lt;br /&gt;
* Versand auch nach Österreich (Europa auf Anfrage)&lt;br /&gt;
* Zahlung per Vorkasse&lt;br /&gt;
* Lieferzeit 1-3 Tage bei Verfügbarkeit&lt;br /&gt;
* PrePaid-Konto möglich&lt;br /&gt;
* Lieferungen auch an Privat&lt;br /&gt;
&lt;br /&gt;
=== Digi-Key ===&lt;br /&gt;
(tlw.) deutsche Homepage: http://de.digikey.com&lt;br /&gt;
&lt;br /&gt;
* optisch nicht besonders ansprechende, aber durchaus sehr funktionelle Website&lt;br /&gt;
* beheimatet in den USA, ein Logistikbüro gibt es in den Niederlanden&lt;br /&gt;
* kostenloser Versand ab 65&amp;amp;#8364;, darunter 18&amp;amp;#8364; Versandkosten&lt;br /&gt;
* macht merkwürdige Plausibilitäts-Checks: wenn man privat über ihrem Dollar Limit (z.B. 400 Dollar bestellt) kommt sofort die Rückfrage nach Firmenname und Firmenadresse&lt;br /&gt;
* Rückfragen nach dem Verwendungszweck kommen ebenfalls schon bei der Bestellung bei bestimmten Bauteilen die der Exportkontrolle unterliegen&lt;br /&gt;
* Versand direkt aus den USA, dafür sehr flott mit UPS Express (in rund zwei bis drei Tagen da)&lt;br /&gt;
* riesiges Angebot, gewissermaßen ein Distributor der auch Kleinmengen an Privatpersonen liefert, entscheidend ist, dass der Hersteller des Produkts geführt wird&lt;br /&gt;
* kein anderer Anbieter, bietet so viele verschiedene passive Bauteile in kleinen Stückzahlen, z.&amp;amp;nbsp;B. SMD Widerstände in Bauform 01005 bis 2512 meist in verschiedenen Toleranzklassen und von verschiedenen Herstellern&lt;br /&gt;
* alle Bauteile mit Herstellerangabe, Digikey kauft ausschließlich direkt vom Hersteller&lt;br /&gt;
* Preise sind auf der deutschen Website in Euro inklusive etwaigem Zoll angegeben, allerdings ohne Mehrwertsteuer, die korrekt abgerechnet wird (d.h. man zahlt bei Versand nach Österreich 20% Mwst., nach Deutschland m.W.n. 19%)&lt;br /&gt;
* Meistens deutlich teurer als Reichelt, doch häufig die beste Anlaufstelle für Privatkunden wenn es um Spezialbauteile geht, und der Hersteller sich im Programm von Digikey befindet&lt;br /&gt;
&amp;lt;!-- * wesentlich teurer als Reichelt, dafür jeder Artikel mit Herstellerangabe&lt;br /&gt;
=&amp;gt; &amp;quot;wesentlich&amp;quot; etwas zu pauschal (vgl. STK500 etc. selbst bei den verglw. hohen Versandkosten) - mt --&amp;gt;&lt;br /&gt;
* Zu beachten ist auch noch folgendes, um unliebsame zusatzkosten zu vermeiden: http://www.mikrocontroller.net/topic/90943#new. &#039;&#039;Anmerkung dazu: Digikey hat wohl zum 1.4.2011 den Versand umgestellt und importiert nun selbst. Zusatzkosten durch Verzollung sollten dann nicht mehr anfallen.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Display Electronics ===&lt;br /&gt;
&lt;br /&gt;
Homepage: http://www.distel.co.uk&lt;br /&gt;
&lt;br /&gt;
* In England&lt;br /&gt;
* Webseite = Augenkrebs &lt;br /&gt;
* Online-Shop versteckt hinter dem Search-Button auf der Homepage&lt;br /&gt;
* Restposten aller Art&lt;br /&gt;
* Mindestbestellwert 10 GBP&lt;br /&gt;
&lt;br /&gt;
=== eHaJo ===&lt;br /&gt;
Homepage: http://www.eHaJo.de&lt;br /&gt;
&lt;br /&gt;
* Bausätze &lt;br /&gt;
* Lötübungen&lt;br /&gt;
* AVR-ISP-Stick&lt;br /&gt;
&lt;br /&gt;
=== Eisch-Kafka-Electronic ===&lt;br /&gt;
Homepage: http://www.eisch-electronic.de&lt;br /&gt;
 &lt;br /&gt;
* Hochfrequenz Bausätze und Bauteile für Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== EleConT ===&lt;br /&gt;
Homepage: http://www.elecont.de/shop/&lt;br /&gt;
&lt;br /&gt;
* Carrierboards für gebräuchliche AVR&lt;br /&gt;
&lt;br /&gt;
=== Electropuces ===&lt;br /&gt;
Homepage: http://perso.wanadoo.fr/electropuces/&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte aus Nantes, Frankreich  (teilweise engl. Menü)&lt;br /&gt;
&lt;br /&gt;
=== Electronic Search ===&lt;br /&gt;
&lt;br /&gt;
Homepage: http://www.electronic-search.de&lt;br /&gt;
&lt;br /&gt;
* Keine Mindestbestellmenge&lt;br /&gt;
* Verkauf auch an Privat/Bastler&lt;br /&gt;
* Fast alle Preise im Online-Shop nur &amp;quot;auf Anfrage&amp;quot;, und nicht im Shop angegeben.&lt;br /&gt;
&lt;br /&gt;
=== electronicpool Rheinstetten ===&lt;br /&gt;
Homepage: http://www.electronicpool.de&lt;br /&gt;
&lt;br /&gt;
* abgekündigte oder schwer beschaffbare elektronische Bauteile&lt;br /&gt;
&lt;br /&gt;
=== Elektronikladen ===&lt;br /&gt;
Homepage: http://www.elektronikladen.de&lt;br /&gt;
&lt;br /&gt;
* Spezialist für Mikrokontroller&lt;br /&gt;
* Entwicklungssysteme, keine Einzelbauteile&lt;br /&gt;
* entsprechende Literatur und Software&lt;br /&gt;
* &amp;quot;Kein Verkauf an Endverbraucher i.S.d. §13 BGB&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Elektronik-Kompendium ===&lt;br /&gt;
Homepage: http://www.elektronik-kompendium.de&lt;br /&gt;
&lt;br /&gt;
* Bausätze diverser Schaltungen (mit Anleitung und Funktionsbeschreibung)&lt;br /&gt;
* erspart lästiges Suchen in anderen Shops&lt;br /&gt;
* kurze Lieferzeiten&lt;br /&gt;
* günstiger Versand&lt;br /&gt;
&lt;br /&gt;
=== Elk Tronic ===&lt;br /&gt;
Homepage: http://www.elk-tronic.de&lt;br /&gt;
&lt;br /&gt;
* kleines Lieferprogramm Adapterplatinen (SMD -&amp;gt; 2,54mm-Raster) und Programmieradapter&lt;br /&gt;
* günstige Preise und Versandspesen&lt;br /&gt;
&lt;br /&gt;
=== Elko-Verkauf ===&lt;br /&gt;
Homepage: http://www.elko-verkauf.de&lt;br /&gt;
&lt;br /&gt;
* Nur Low-ESR-Elkos&lt;br /&gt;
* Elko-Sets für ein Gerät&lt;br /&gt;
&lt;br /&gt;
=== Ellmitron ===&lt;br /&gt;
Homepage: http://www.ellmitron.de/&lt;br /&gt;
Katalog: http://www.ellmitron.de/katalog.pdf&lt;br /&gt;
&lt;br /&gt;
Lehrmittel, Kleinbausätze vor allem für Schüler, Experimentierkästen&lt;br /&gt;
&lt;br /&gt;
=== Elpro Darmstadt ===&lt;br /&gt;
Homepage: http://www.elpro.org&lt;br /&gt;
&lt;br /&gt;
* Kein Mindestbestellwert, aber hohe Versandkosten für kleine Bestellungen. Stand September 2008:&lt;br /&gt;
** Bis 15€: 9,95€ Versandkosten&lt;br /&gt;
** Von €15 bis €75: 5,95€ Versandkosten&lt;br /&gt;
** Von €75 bis €200: 4,49€ Versandkosten&lt;br /&gt;
** Ab €200: Versandkostenfrei&lt;br /&gt;
* Große Auswahl an Mikrocontrollern&lt;br /&gt;
* Sehr große Auswahl an Schaltnetzteilen von Meanwell (geschlossen, offen, auf PCB lötbar, DIN-Schiene)&lt;br /&gt;
* Merkwürdig zu bedienende Shopsoftware, ständig klappt was auf und zu und wird irgendwas nachgeladen. Braucht JavaScript&lt;br /&gt;
* Keine AGBs online. Da Preisangaben ohne MwSt. richtet sich das Angebot vermutlich nicht an Endverbraucher (werden aber beliefert)&lt;br /&gt;
* Bearbeitungszeit (bis Warenausgang) 2-3 Tage.&lt;br /&gt;
* Versand bisher mit DHL&lt;br /&gt;
* gute bis sehr gute Verpackung&lt;br /&gt;
&lt;br /&gt;
=== Eltrix ===&lt;br /&gt;
Homepage: http://eltrix.de/Starteltrix.htm&lt;br /&gt;
&lt;br /&gt;
*  Verbrauchsmaterial, Tipps und Tricks fürs Leiterplattenherstellen und Löten&lt;br /&gt;
&lt;br /&gt;
=== ELV ===&lt;br /&gt;
Homepage: http://www.elv.de&lt;br /&gt;
&lt;br /&gt;
* nicht sehr große Auswahl an Einzelteilen&lt;br /&gt;
* riesiges Angebot an Zubehör für Hobbyisten&lt;br /&gt;
* viele z.T. pfiffige Eigenentwicklungen, Bausätze (auch zum Download auf der Website verfügbar)&lt;br /&gt;
* sonst Sortiment ähnlich Conrad, nicht billig&lt;br /&gt;
* im Allgemeinen nicht billig, merkwürdigerweise sind manche Artikel aber die günstigsten auf dem Markt&lt;br /&gt;
* mühsamer Onlinekatalog&lt;br /&gt;
* Immer mal wieder Fehllieferungen und Wartezeiten (zumindest in die Schweiz). Service erreichte in 3 Fällen nicht das inserierte Niveau.&lt;br /&gt;
* Versandkosten innerhalb Deutschland 4,5&amp;amp;#8364;, ab 150&amp;amp;#8364; Bestellwert versandkostenfrei&lt;br /&gt;
* nicht abwählbare Versandversicherung, die 0,85% des Bestellwertes kostet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Erklärte am 31. August 2010 &amp;quot;... den Betrieb bis auf weiteres zu schließen.&amp;quot; &lt;br /&gt;
=== Embedit Mikrocontrollertechnik ===&lt;br /&gt;
Online Shop: http://shop.embedit.de&lt;br /&gt;
&lt;br /&gt;
* Gute Auswahl an AVR Controllern, aber nur aktuelle Typen, keine AT90Sxxxx. Teilweise exotische Typen wie MLF Gehäuse&lt;br /&gt;
* Atmel und Philips SmartARM Controller&lt;br /&gt;
* Module und Boards mit AVR Controllern&lt;br /&gt;
* Zubehör von Atmel wie STK500 oder AVRISP mkII&lt;br /&gt;
* Diverse aktive und passive Elektronikteile, ständig neue Teile&lt;br /&gt;
* Mechanikteile wie Zahnräder, Steckverbinder usw.&lt;br /&gt;
* Lieferzeit 1-4 Tage, je nachdem wie man zahlt (hab aber auch schon ne Vorauskasse innerhalb eines Tages per Expressbrief bekommen, zuvorkommender Service)&lt;br /&gt;
* Versandkosten ab 3,95 &amp;amp;#8364;, versicherter Versand, Vorauskasse und Nachnahme&lt;br /&gt;
* Keine Versandkosten ab 50 &amp;amp;#8364; Warenwert innerhalb Deutschlands, bei Zahlung per Vorauskasse und Lieferung per Hermes&lt;br /&gt;
* Lieferung in viele EU-Länder&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ETT - Electronic Toys Trading  ===&lt;br /&gt;
Homepage: http://www.ett-online.de&lt;br /&gt;
&lt;br /&gt;
* Großhandel nur für Gewerbekunden.&lt;br /&gt;
* Zweitshop [[Elektronikversender#Atzert-Elektronik_Versand|Atzert-Elektronik Versand]] (früher EFB-Electronic Versand, davor Megakick Electronic-Stores) für Endkunden.&lt;br /&gt;
* Ladengeschäft in Braunschweig für jedermann. Weitere Atzert Ladengeschäfte in Bielefeld, Bremen, Hamburg und Berlin.&lt;br /&gt;
* Eigentümer der Marken McCHECK®, McPower®, McVoice® und anderer, unter denen ETT importierte Messgeräte, Labornetzteile, usw. an Großkunden und Händler vertreibt. Diese sind unter oben genannten Marken dann in vielen Shops anderer Firmen für Endkunden zu finden, nicht nur bei Atzert. Preisvergleiche lohnen.&lt;br /&gt;
&lt;br /&gt;
=== Ettinger GmbH ===&lt;br /&gt;
Homepage: http://www.ettinger.de&lt;br /&gt;
&lt;br /&gt;
* Für gewerbliche Kunden&lt;br /&gt;
* Mechanische Komponenten (Gehäuse, Abstandshalter, Drehknöpfe, usw.)&lt;br /&gt;
* LEDs&lt;br /&gt;
* Gewöhnungsbedürftiger Online-Shop&lt;br /&gt;
&lt;br /&gt;
=== EVE ===&lt;br /&gt;
Homepage: http://www.eve.de&lt;br /&gt;
&lt;br /&gt;
* Zitat aus den AGBs:&lt;br /&gt;
::&#039;&#039;&amp;quot;Zu Bestellungen im Rahmen des Online-Handels sind nur durch uns autorisierte, d. h. zugelassene Käufer berechtigt. Wir gewähren nach erfolgreicher Zertifizierung – ohne hierzu verpflichtet zu sein – dem jeweiligen Käufer das nicht übertragbare, nicht exklusive Recht im Rahmen des Online-Handels Bestellungen uns gegenüber “auszubringen”.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:Dies darf man wohl getrost als Hinweis ansehen, dass Endverbraucher als Kunden nicht gewünscht sind.&lt;br /&gt;
* Versandhaus für elektronische Artikel in Emsdetten&lt;br /&gt;
* machen auch Kabelkonfektion&lt;br /&gt;
* Pb-freie Artikel markiert&lt;br /&gt;
&lt;br /&gt;
=== Farnell ===&lt;br /&gt;
Homepage: http://de.farnell.com&lt;br /&gt;
&lt;br /&gt;
* liefert nur an gewerbliche Abnehmer, Ausnahme sind Studenten und HTL-Schüler (Österreich, Farnell.at). Nachweis wird verlangt (Gewerbeschein oder Immatrikulation).&lt;br /&gt;
* Lieferungen an Privat:&lt;br /&gt;
:* Schweiz: Farnell Schweiz beliefert auch Privatkunden.&lt;br /&gt;
:* Deutschland: Über den Reseller [[#HBE_-_Heinz_B.C3.BCchner_Elektronik.2C_Messtechnik.2C_med._Elektronik_e.K.|HBE]] kann man Produkte aus dem Farnell-Sortiment zu bestellen.&lt;br /&gt;
:* Österreich: [[#Technik-Welt / Industrieshop.at|Technik-Welt / Industrieshop.at]]&lt;br /&gt;
* große Auswahl&lt;br /&gt;
* 12% Rabatt für Studenten und Lehreinrichtungen&lt;br /&gt;
* sehr schneller Versand, Ware ist in 99% aller Fälle am nächsten Tag da (UPS), fehlende Positionen werden relativ rasch versandkostenfrei nachgeliefert&lt;br /&gt;
* Versandkosten: Bestellung bis 49,99&amp;amp;#8364;: 7,95&amp;amp;#8364;;   50,- bis 149,99&amp;amp;#8364;: 5,95&amp;amp;#8364;;   ab EUR 150,- versandkostenfrei&lt;br /&gt;
* hat nach eigenen Aussagen umfangreichstes Sortiment an RoHS-konformen Bauteilen mit Suchfunktion im WWW&lt;br /&gt;
* leistungsfähige parametrische Suchfunktion / teils aber völlig nutzlos, da den Artikeln massenweise Tags fehlen, weswegen die Suchergebnisse unnötig eingeschränkt werden&lt;br /&gt;
* Datenblätter für die meisten Bauteile online&lt;br /&gt;
* Internetpräsenz fällt nachts oft aus (Hinweis auf angebliche geplante Wartungsarbeiten)&lt;br /&gt;
* Sortierfunktion wird bei der Suche ständig zurückgesetzt, im Warenkorb ist überhaupt keine sinnvolle Sortierung möglich&lt;br /&gt;
* Eigenwillige Preispolitik: Einiges sehr günstig, Anderes total überteuert&lt;br /&gt;
&lt;br /&gt;
=== Fibra-Brandt Zweibrücken ===&lt;br /&gt;
Homepage: http://www.fibra-brandt.com&lt;br /&gt;
&lt;br /&gt;
* lagert tausende veraltete und schwer zu findende elektronische Bauteile&lt;br /&gt;
* Halbleiter, IC&#039;s, Transistoren, Spulen und Kondensatoren.&lt;br /&gt;
* Sonderbeschaffung von abgekündigten Halbleitern.&lt;br /&gt;
&lt;br /&gt;
=== Fischer DK2FD ===&lt;br /&gt;
Homepage: http://www.dfe-online.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen für Hochfrequenzmesstechnik und Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Funkamateur Online-Shop ===&lt;br /&gt;
&lt;br /&gt;
Siehe [[Elektronikversender#Box73]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Futurelec ===&lt;br /&gt;
Homepage: http://www.futurlec.com&lt;br /&gt;
&lt;br /&gt;
* günstiger Versender aus Übersee&lt;br /&gt;
* viele Stamp-Boards&lt;br /&gt;
* LED Matrix-Module&lt;br /&gt;
&lt;br /&gt;
=== Future Electronics ===&lt;br /&gt;
Homepage: http://de.futureelectronics.com&lt;br /&gt;
&lt;br /&gt;
* große Auswahl an Teilen&lt;br /&gt;
* Versand auch an Privatpersonen&lt;br /&gt;
* Preisangaben ohne MwSt.&lt;br /&gt;
* Zahlung nur mit Kreditkarte&lt;br /&gt;
* Versandkosten 7,14€ (Brutto)&lt;br /&gt;
* Versand aus den USA mit FedEx, Lieferzeit meist unter 5AT&lt;br /&gt;
* Verzollung usw. wird von FutureElectronics gemacht, keine Nachzahlungen etc.&lt;br /&gt;
&lt;br /&gt;
=== Geist Electronic-Versand GmbH ===&lt;br /&gt;
Homepage: http://www.geist-electronic.de&lt;br /&gt;
&lt;br /&gt;
* Liefern Bauteile für Elektor-Projekte&lt;br /&gt;
* D-78054 Villingen-Schwenningen&lt;br /&gt;
* Versandkosten: 5.40€&lt;br /&gt;
&lt;br /&gt;
=== Giga-Tech ===&lt;br /&gt;
Homepage: http://www.giga-tech.de&lt;br /&gt;
&lt;br /&gt;
* Spezialitäten für Hochfrequenz / Amateurfunk&lt;br /&gt;
* 68542 Heddesheim&lt;br /&gt;
&lt;br /&gt;
=== Grummes Elektronik ===&lt;br /&gt;
Homepage: http://www.grummes.de&lt;br /&gt;
&lt;br /&gt;
* Elektronikversender /CNC-Fräsmaschinen / Schrittmotorsteuerungen / Bauteile&lt;br /&gt;
* Homepage nicht aufrufbar (10.12.2011)&lt;br /&gt;
&lt;br /&gt;
=== Glyn (GLYNshop) ===&lt;br /&gt;
Homepage: https://www.glynshop.com/erp/welcome.do&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;B2B Shop&amp;quot; = nicht für Privatkunden&lt;br /&gt;
* Microcontroller, Evaluation Boards, TFT-Displays, LC-Displays, Memory Cards u.a.&lt;br /&gt;
&lt;br /&gt;
=== guloshop.de ===&lt;br /&gt;
Homepage: http://guloshop.de&lt;br /&gt;
&lt;br /&gt;
* kleiner Shop, konzentriert sich auf Standard-AVRs im DIP-Gehäuse, ist dabei aber meist der billigste Versender in Deutschland&lt;br /&gt;
* ATtiny, ATmega, Breakout-Boards, Programmer, Adapterkabel, IC-Fassungen&lt;br /&gt;
* AVR mit geflashtem Arduino-Bootloader&lt;br /&gt;
* äußerst niedrige Preise&lt;br /&gt;
* liefert schnell und zuverlässig, jedoch nur gegen Vorkasse&lt;br /&gt;
* kein Mindestbestellwert, Versandkosten für kleine Bestellungen: 2,40 EUR, darüber 4,40 EUR&lt;br /&gt;
* ansässig in 90489 Nürnberg&lt;br /&gt;
&lt;br /&gt;
=== H-Tronic ===&lt;br /&gt;
Homepage: http://www.h-tronic.eu/index.php&lt;br /&gt;
&lt;br /&gt;
* Online-Shop einer Entwicklungsfirma, in dem neben Baugruppen und Geräten auch einige Bauelemente und Elektronikzubehör angeboten werden&lt;br /&gt;
* kleines Angebot&lt;br /&gt;
&lt;br /&gt;
=== Hallmanns Elektronik ===&lt;br /&gt;
Homepage: http://www.hallmanns.com &amp;lt;br&amp;gt;&lt;br /&gt;
Adresse: Bruno Hallmanns, Weierstraße 41, 52349 Düren&lt;br /&gt;
&lt;br /&gt;
* Elektronikhändler mit Ladenlokal und Versand&lt;br /&gt;
* Ladentypisches Sortiment (Bauteile, Geräte, PC, Funk, Hifi...)&lt;br /&gt;
&lt;br /&gt;
=== Hari Seligenstadt ===&lt;br /&gt;
Homepage: http://www.hari-ham.com&lt;br /&gt;
&lt;br /&gt;
* Bausätze, Ringkerne, Geräte für Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== HBE - Heinz Büchner Elektronik, Messtechnik, med. Elektronik e.K. ===&lt;br /&gt;
Homepage: http://www.hbe-shop.de/katalog/&lt;br /&gt;
&lt;br /&gt;
* Bezeichnet sich als &#039;&#039;[[#Farnell|Farnell]] Fachhändler&#039;&#039;, bei dem nichtgewerbliche Kunden aus dem Farnell-Sortiment bestellen können.&lt;br /&gt;
* Preise für Farnell-Produkte normalerweise Farnell Netto-Preis + MwSt.&lt;br /&gt;
* Mindestbestellwert 25,- € (netto), Mindermengenzuschlag 5,- € (Stand 06/2010)&lt;br /&gt;
* Versandkosten 4,75 € (netto), ab 75,- € (netto) versandkostenfrei (Stand 06/2010)&lt;br /&gt;
&lt;br /&gt;
=== Heho-Elektronik ===&lt;br /&gt;
Homepage: http://www.heho-elektronik.de&lt;br /&gt;
* Halbleiter / Bauteile, Sortimente, Handy - Akkus, VELLEMAN - Bausätze&lt;br /&gt;
* Aktuelles Angebot, Ladegeräte / Akkuladegeräte, Blei - Akkus&lt;br /&gt;
* Spannungswandler, Audio / Video / USB - Kabel, Netzwerk - Kabel&lt;br /&gt;
* 1-2 Arbeitstage für Waren ab Lager&lt;br /&gt;
* Porto + Verpackung pauschal Euro 4,50&lt;br /&gt;
* Mindestbestellwert von &amp;amp;#8364; 10,00&lt;br /&gt;
&lt;br /&gt;
=== Hinkel ===&lt;br /&gt;
Homepage: http://www.hinkel-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Von der Webseite &amp;quot;Unser Angebot richtet sich an Schulen, Behörden, Handel, Handwerk und Industrie.&amp;quot;&lt;br /&gt;
* Batterien&lt;br /&gt;
* Knopfzellen, spezielle KZH, die man sonst lang sucht, findet man hier&lt;br /&gt;
* Mindestbestellwert von 20&amp;amp;#8364;&lt;br /&gt;
* Standardversand innerhalb Deutschlands 5,80&amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== HN Electronic Components GmbH &amp;amp; Co. KG / Netzteilshop ===&lt;br /&gt;
Homepage gewerbliche Kunden: http://www.hn-electronic.de/&lt;br /&gt;
* Netzteile aller Art&lt;br /&gt;
* Es gibt keinen Onlineshop mehr, wahrscheinlich werden Endkunden nicht beliefert&lt;br /&gt;
** Homepage Endkunden: http://www.netzteilshop.com/hnshop.html&lt;br /&gt;
** Lieferung an Endkunden nur per UPS Nachnahme.&lt;br /&gt;
** Mindestbestellmenge für Endkunden 25 €&lt;br /&gt;
&lt;br /&gt;
=== Home-Electronic24 ===&lt;br /&gt;
Homepage: http://www.home-electronic24.de/&lt;br /&gt;
&lt;br /&gt;
=== HW-Electronics ===&lt;br /&gt;
Homepage: http://www.hw-electronics.de &amp;lt;br&amp;gt;&lt;br /&gt;
Homepage EU: http://hw-electronics.eu/&lt;br /&gt;
&lt;br /&gt;
* Tauch- und Sprühätzanlagen&lt;br /&gt;
* Entwicklungsgeräte&lt;br /&gt;
* Belichtungsgeräte, Materialsätze zum Selbstbau von Belichtungsgeräten&lt;br /&gt;
&lt;br /&gt;
=== ID-Elektronik ===&lt;br /&gt;
Homepage: http://www.id-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Amateurfunk-Baugruppen&lt;br /&gt;
&lt;br /&gt;
=== IT-WNS ===&lt;br /&gt;
Homepage: http://www.it-wns.de&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Bauteile, Platinen, Bausätze&amp;quot; insbesondere mit ATMEGA und ENC28J60&lt;br /&gt;
* Bausätze zu Projekten aus dem Forum, z.&amp;amp;nbsp;B. USBprog, ChipBasic, Mikro-Webserver, Transistortester u.v.a.m.&lt;br /&gt;
* Atmega32/644 Experimentiersystem als Bausatz mit vielen Zusatzmodul-Bausätzen&lt;br /&gt;
* SD-Slots, RFID, Bluetooth-Module, AVR Mikrocontroller uvam.&lt;br /&gt;
* Bauelemente, die nicht im Shop angeboten werden, können auf Anfrage (Kontaktformular) beschafft werden &lt;br /&gt;
* günstige Preise und Versandkosten ab 1,90EUR, kein Mindestbestellwert&lt;br /&gt;
* schneller Versand, sofern die Artikel auf Lager sind, versandkostenfreie Nachlieferung&lt;br /&gt;
&lt;br /&gt;
=== Kabelscheune ===&lt;br /&gt;
Homepage: http://www.kabelscheune.de&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Direktversand von Elektromaterial und Multimediaprodukten&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Kelemen ===&lt;br /&gt;
Homepage: http://www.kelemenantennen.de/Kelemen-Shop/&lt;br /&gt;
&lt;br /&gt;
* Messgeräte, Antennen und Zubehör für den Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Kessler ===&lt;br /&gt;
Homepage: http://www.kessler-electronic.de&lt;br /&gt;
&lt;br /&gt;
* im Preis-Leistungsverhältnis mit Reichelt zu vergleichen (sprich: günstig)&lt;br /&gt;
* Sortiment kleiner als Reichelt und mit gewissen Abweichungen (z. B. andere FPGA und RAMs)&lt;br /&gt;
* oft lange Lieferzeiten&lt;br /&gt;
* Versandkosten innerhalb Deutschlands 4€ (Brief), 5€ (DHL-Paket), 10€ (DHL-Express-Paket)&lt;br /&gt;
&lt;br /&gt;
=== Klein-Electronic ===&lt;br /&gt;
Homepage: http://www.klein-electronic.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen zur Video- und 2,4GHz-Sendetechnik&lt;br /&gt;
&lt;br /&gt;
=== Konni-Antennen ===&lt;br /&gt;
Homepage: http://www.konni-antennen.de&lt;br /&gt;
&lt;br /&gt;
* Antennen für TV, Amateurfunk&lt;br /&gt;
* Zubehör, Einzelteile&lt;br /&gt;
* sehr netter kompetenter Service&lt;br /&gt;
&lt;br /&gt;
=== Köditz Nachrichtentechnik ===&lt;br /&gt;
Homepage: http://www.koeditz-nachrichtentechnik.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen und Bauteile für Amateurfunk und TV-Satellitenempfang&lt;br /&gt;
&lt;br /&gt;
=== Kuhne DB6NT ===&lt;br /&gt;
Homepage: http://www.kuhne-electronic.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen und Bausätze für Mikrowellenamateure&lt;br /&gt;
&lt;br /&gt;
=== LEDSEE Electronics ===&lt;br /&gt;
Homepage: http://www.ledsee.com&lt;br /&gt;
&lt;br /&gt;
* LEDs, LCDs, diverses&lt;br /&gt;
* Lieferung direkt aus China, daher sehr günstig und lange Lieferzeiten&lt;br /&gt;
&lt;br /&gt;
=== LED Microtechnics LTD ===&lt;br /&gt;
Homepage: http://www.ledmeile.de&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;LED Shop und Lampentechnik&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== LED-Tech LED-Shop ===&lt;br /&gt;
Homepage: http://www.led-tech.de&lt;br /&gt;
&lt;br /&gt;
* viele verschiedene LEDs zu sehr guten (meist den günstigsten) Preisen&lt;br /&gt;
* vor allem auf High-Power-LEDs spezialisiert&lt;br /&gt;
* viele verschiedene Treiber für High-Power-LEDs&lt;br /&gt;
* kostenloser Versand&lt;br /&gt;
* haben ein eigenes, sehr umfangreiches Forum&lt;br /&gt;
&lt;br /&gt;
=== Lieske Elektronik ===&lt;br /&gt;
Homepage: http://www.lieske-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* liefert nur an Geschäftskunden&lt;br /&gt;
&lt;br /&gt;
=== Lüdeke Elektronic ===&lt;br /&gt;
Homepage: http://www.luedeke-elektronic.de/&lt;br /&gt;
&lt;br /&gt;
* großes Sortiment, bietet unter anderem auch viele selbst entwickelte Bausätze an&lt;br /&gt;
&lt;br /&gt;
=== LUMITRONIX LEDs-Shop ===&lt;br /&gt;
Homepage: http://www.leds.de&lt;br /&gt;
&lt;br /&gt;
* alles rund um LEDs (auch Zubehör und Lektüre)&lt;br /&gt;
* neben Standard-LEDs auch SMD- und SuperFlux-LEDs&lt;br /&gt;
&lt;br /&gt;
=== Marsch Elektronik, M. Schlimper ===&lt;br /&gt;
Homepage: http://www.marsch-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Online Shop für aktive und passive Bauelemente&lt;br /&gt;
* Versandkosten ab Euro 1,60&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* bietet auch Einsteigersortimente und Widerstandsortimente (auch SMD)&lt;br /&gt;
* liefert nur innerhalb Deutschlands&lt;br /&gt;
* nicht gelistete Artikel können angefragt werden und werden meist auch beschafft&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Mauritz Communication &amp;amp; Electronics ===&lt;br /&gt;
Homepage: http://www.mauritz-shop.eu&lt;br /&gt;
&lt;br /&gt;
* Online Shop für HF-Stecker und Kabel&lt;br /&gt;
* bietet HF-Stecker/Buchsen und Koaxkabel an&lt;br /&gt;
* große Auswahl, auch exotische Teile&lt;br /&gt;
* Kabelkonfektionierung nach Wunsch&lt;br /&gt;
* vernünftige Preise&lt;br /&gt;
* liefert nach Rücksprache auch weltweit&lt;br /&gt;
* Keine Mindestbestellwert, aber 5 € Aufschlag unter 15 €&lt;br /&gt;
* Versand bis 40 kg pauschal 5,95 € per GLS innerhalb DE&lt;br /&gt;
* schneller Versand&lt;br /&gt;
* Paypal oder Vorkasse&lt;br /&gt;
&lt;br /&gt;
=== Mein-Daarle ===&lt;br /&gt;
Homepage: http://www.mein-st-arnual.de/shop/saarbruecken/artikellisteL.html&lt;br /&gt;
&lt;br /&gt;
* Teileliste eines &amp;quot;Händlers aus Saarbrücken&amp;quot; (wahrscheinl.: Frank Skowronek ESS Elektronik Service), &amp;quot;bis sein Onlineshop ans Netz gehen kann&amp;quot;&lt;br /&gt;
* derzeit (4/2011) kein Onlineshop, Kontakt über Formular&lt;br /&gt;
&lt;br /&gt;
=== Micromaus ===&lt;br /&gt;
Homepage: http://www.micromaus.de&lt;br /&gt;
&lt;br /&gt;
* Sensoren&lt;br /&gt;
* Mikrokontroller&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* 22.7.2012: Totalausverkauf wegen Geschäftsaufgabe, 10% auf alle Artikel&lt;br /&gt;
&lt;br /&gt;
=== Microcontroller-Starterkits ===&lt;br /&gt;
Homepage: http://www.microcontroller-starterkits.de&lt;br /&gt;
&lt;br /&gt;
* 22.7.2012: Seite nicht erreichbar&lt;br /&gt;
* Bauteile: CAN, Ethernet, Mikrokontroller AVR und ARM, Linearregler 1,8V 3,3V 5V in SOT223&lt;br /&gt;
* Leerplatinen, Bausätze&lt;br /&gt;
* günstig&lt;br /&gt;
* Abholung in Hattingen möglich&lt;br /&gt;
* Versandkosten innerhalb Deutschlands ab 2,50&amp;amp;#8364;&lt;br /&gt;
* keine Kreditkartenzahlung möglich&lt;br /&gt;
&lt;br /&gt;
=== Mikrocontroller.net ===&lt;br /&gt;
Homepage: http://shop.mikrocontroller.net&lt;br /&gt;
&lt;br /&gt;
* Starterkits, Development Boards und Zubehör für AVR, AVR32, ARM und MSP430&lt;br /&gt;
&lt;br /&gt;
=== Mira Nürnberg ===&lt;br /&gt;
Homepage: http://www.mira-electronic.de&lt;br /&gt;
&lt;br /&gt;
* SMD-Bauteile, SMD-Sortimentboxen&lt;br /&gt;
* Verkauf und Preisangaben nur für Gewerbetreibende&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- 22.7.2012 Seite nicht erreichbar, Domain bei einem Domaingrabber&lt;br /&gt;
=== Karl Müller EME Messtechnik ===&lt;br /&gt;
Homepage: http://www.eme-hf-technik.de&lt;br /&gt;
&lt;br /&gt;
* Hochfrequenz-Messtechnik, HF-Komponenten&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Mouser ===&lt;br /&gt;
Homepage: http://de.mouser.com&lt;br /&gt;
&lt;br /&gt;
* Liefert an Privat&lt;br /&gt;
* Zügige Lieferung mit FedEx aus den USA&lt;br /&gt;
* Keine Halbleiter von Linear, National und Analog&lt;br /&gt;
&lt;br /&gt;
=== MS-Elektronik ===&lt;br /&gt;
Homepage: http://www.ms-elektronik.info&lt;br /&gt;
&lt;br /&gt;
* Liefert an Privat&lt;br /&gt;
* Zügige Lieferung&lt;br /&gt;
* Gute Qualität&lt;br /&gt;
* Viel in Richtung Audio&lt;br /&gt;
* Große Auswahl an Elkos -&amp;gt; kleine Preise&lt;br /&gt;
* kein allzu großes Sortiment&lt;br /&gt;
&lt;br /&gt;
=== Mütron ===&lt;br /&gt;
Homepage: http://www.muetronshop.de&lt;br /&gt;
&lt;br /&gt;
* Keine Privatkunden&lt;br /&gt;
&lt;br /&gt;
=== myAVR Shop ===&lt;br /&gt;
Hompage http://shop.myavr.de&lt;br /&gt;
&lt;br /&gt;
* Kleine Auswahl, aber die angebotene Ware ist sehr preiswert (meist preiswerter als bei Reichelt)&lt;br /&gt;
* Zügige Lieferung (1-2 Werktage)&lt;br /&gt;
* Diverse Zahlungsmöglichkeiten: Rechnung, Vorkasse, Lastschrift, Kreditkarte, PayPal&lt;br /&gt;
* Kein Mindestbestellwert&lt;br /&gt;
* Sehr günstige Versandkosten ab 1,95 Eur&lt;br /&gt;
* Mengenrabatt ab 10 gleichen Artikeln&lt;br /&gt;
&lt;br /&gt;
=== Neuhold-Elektronik ===&lt;br /&gt;
Homepage: http://www.neuhold-elektronik.at &amp;lt;br&amp;gt;&lt;br /&gt;
Shop: http://www.neuhold-elektronik.at/catshop/default.php?language=de&lt;br /&gt;
&lt;br /&gt;
* preiswerte Schnäppchen&lt;br /&gt;
* regelmäßig aktualisierte Angebotsliste herunterladbar&lt;br /&gt;
* Ab 60,- EUR versandkostenfrei in Österreich&lt;br /&gt;
&lt;br /&gt;
=== Octamex ===&lt;br /&gt;
Homepage: http://www.octamex.de&lt;br /&gt;
&lt;br /&gt;
* Leiterplattenchemie (Entwickler, Ätzmittel, CRC-Sprays)&lt;br /&gt;
* Chemisch Zinn&lt;br /&gt;
* Lötstopp-Laminat, Tentingresist, Bestückungsdruck&lt;br /&gt;
* Bungard Basismaterial in 0,5mm 1,0mm 1,5mm Dicke und 18µm, 35µm, 70µm Kupfer&lt;br /&gt;
* Bungard Alucorex für 19&amp;quot; Frontplatten&lt;br /&gt;
* Bungard Cotherm, Alukernbasismaterial&lt;br /&gt;
* Funkmodule 434MHz, 868MHz, 2.4GHz&lt;br /&gt;
* Löttechnik und Zubehör&lt;br /&gt;
* Gehäuse aller Art&lt;br /&gt;
* Messgeräte und Labornetzteile&lt;br /&gt;
* aktive, passive u. mechanische Bauelemente (Widerstände, Kondensatoren, Transistoren, Logik-ICs etc.)&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* Lieferung auch ins Ausland&lt;br /&gt;
* Versandkosten ab 4,50EUR&lt;br /&gt;
* Liefert nur gegen Vorkasse, ausser für Bestandskunden, die schon häufig bestellt haben&lt;br /&gt;
* Zahlung mit EC-Pay oder Kreditkarte nur gegen Aufschlag (bis zu 5%)&lt;br /&gt;
&lt;br /&gt;
=== Online Batterien ===&lt;br /&gt;
Homepage: http://www.online-batterien.de&lt;br /&gt;
&lt;br /&gt;
* Allerlei günstige Batterien &amp;amp; Akkus vieler Marken&lt;br /&gt;
* z.&amp;amp;nbsp;B. &#039;&#039;&#039;40 Stk.&#039;&#039;&#039; DURACELL PLUS LR6 AA 11,59€ (Jan 2010)&lt;br /&gt;
* Beleuchtungsartikel&lt;br /&gt;
* USV&lt;br /&gt;
* Versand ab 3,90€&lt;br /&gt;
&lt;br /&gt;
=== Oppermann ===&lt;br /&gt;
Homepage: http://www.oppermann-electronic.de&lt;br /&gt;
&lt;br /&gt;
* Restposten, auch HF Bauteile&lt;br /&gt;
* auch Privatkunden&lt;br /&gt;
* Lieferung nach üblicher Zeit&lt;br /&gt;
&lt;br /&gt;
=== PCB-Soldering ===&lt;br /&gt;
&lt;br /&gt;
Homepage, Online-Shop: http://www.pcb-soldering.co.uk&lt;br /&gt;
eBay: http://www.allendale-stores.co.uk&lt;br /&gt;
Firmen-Homepage: http://www.allendale-elec.co.uk&lt;br /&gt;
&lt;br /&gt;
* [http://www.aoyue.com/en/products.asp Aoyue] Lötstationen und preiswertes Zubehör (Lötspitzen) für diese. Bei Aoyue-Zubehör bessere Preise (Stand 10/2008) als [[#WilTec_Wildanger_Technik_GmbH|WilTec]]&lt;br /&gt;
* Schnelle Lieferung&lt;br /&gt;
* Dank [http://www.zoll.de/b0_zoll_und_steuern/a0_zoelle/a1_grundlage_zollrecht/b0_zollgebiet/index.html EU Binnenmarkt] nur britische Mehrwertsteuer (VAT), kein Zoll, keine [http://www.zoll.de/b0_zoll_und_steuern/a3_einfuhrumsatzsteuer/index.html Einfuhrumsatzsteuer] fällig.&lt;br /&gt;
* Zwei von drei E-Mails wurden nicht beantwortet&lt;br /&gt;
* Versandart wurde eigenmächtig von &amp;quot;Standard&amp;quot; auf teureres &amp;quot;Signed for&amp;quot; (Einschreiben) geändert&lt;br /&gt;
&lt;br /&gt;
=== Pollin Electronic ===&lt;br /&gt;
Homepage: http://www.pollin.de&lt;br /&gt;
&lt;br /&gt;
* Günstige Restposten aller Art (z.&amp;amp;nbsp;B. &amp;quot;250 g verschiedene ICs&amp;quot; u.dgl.)&lt;br /&gt;
* Produktkategorien:&lt;br /&gt;
** Computer und Zubehör&lt;br /&gt;
** Telefone und Zubehör&lt;br /&gt;
** Antennentechnik&lt;br /&gt;
** HiFi/Car-HiFi/Video/TV&lt;br /&gt;
** Stromversorgung&lt;br /&gt;
** Lichttechnik&lt;br /&gt;
** Messtechnik / Uhren&lt;br /&gt;
** Haustechnik&lt;br /&gt;
** Werkstatt&lt;br /&gt;
** Bauelemente&lt;br /&gt;
** KFZ- und Zweirad&lt;br /&gt;
** Motoren&lt;br /&gt;
** Bausätze&lt;br /&gt;
** Fundgrube&lt;br /&gt;
* Produkte teils schnell ausverkauft &lt;br /&gt;
* Qualität schwankend. Man kann gute Schnäppchen machen aber auch reinfallen. Umtausch ist dann aber problemlos.&lt;br /&gt;
* Es wird öfters von sorgloser Verpackung berichtet, trotz Verpackungspauschale von 0,85 % des Warenwerts (empfindliche und schwere Produkte besser nicht zusammen bestellen). Reklamationen bei Beschädigungen werden freundlich behandelt.&lt;br /&gt;
* Lieferzeit i.d.r. 2-3 Werktage / knappe Woche bei neuer Sonderliste&lt;br /&gt;
* Ladengeschäft in 85104 Pförring&lt;br /&gt;
* Versandkosten  innerhalb Deutschlands 4,50 &amp;amp;#8364; (ab 150&amp;amp;#8364; versandkostenfrei); dazu 0,85 % Verpackungspauschale&lt;br /&gt;
* Zahlung per Nachnahme (+2,50 €) oder Bankeinzug (keine Kreditkarte, keine Überweisung)&lt;br /&gt;
&lt;br /&gt;
=== proma / Isel ===&lt;br /&gt;
Homepage: http://www.isel.com/en/proma_systro.php&lt;br /&gt;
&lt;br /&gt;
The proMa systro GmbH has completed its business transactions since the 20th February 2009.&lt;br /&gt;
Nachfolger: http://idimod.iselshop.de/&lt;br /&gt;
&amp;lt;s&amp;gt;&lt;br /&gt;
* fotobeschichtete Leiterplatten Platinenfrästechnik&lt;br /&gt;
* Chemikalien für die Platinenherstellung: Ätzmittel, Flussmittel für Lötanlagen, etc.&lt;br /&gt;
* Profilgehäuse, u.a. von Conrad und Reichelt vertrieben&lt;br /&gt;
&amp;lt;/s&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== QRP-project ===&lt;br /&gt;
Homepage: http://www.qrpshop.de/&lt;br /&gt;
&lt;br /&gt;
* Bausätze vor allem einfache Kurzwellen-Funkgeräte&lt;br /&gt;
&lt;br /&gt;
=== Reichelt ===&lt;br /&gt;
Homepage: http://www.reichelt.de&lt;br /&gt;
&lt;br /&gt;
* relativ große Auswahl, aber nicht viele &amp;quot;brandaktuelle&amp;quot; Bauteile&lt;br /&gt;
* wenn man höflich fragt, liefern sie ganz selten auch Bauteile, die nicht im Katalog stehen zu &amp;quot;normalen&amp;quot; Preisen (vorausgesetzt der Hersteller ist im Sortiment), z.&amp;amp;nbsp;B. Xilinx XC2S50, aber meist erhält man die Antwort, dass der Artikel nicht im Sortiment ist, obwohl auf der Homepage unter Service extra ein Punkt angeführt ist: &amp;quot;Ich benötige einen Artikel, der nicht im Programm ist&amp;quot;&lt;br /&gt;
* reagiert aber teilweise auch auf Anregungen, neue Produkte in das Angebot aufzunehmen; siehe dazu auch den Artikel [[Reichelt-Wishlist]]&lt;br /&gt;
* liefert schnell und vollständig; wenn etwas ausnahmsweise nicht verfügbar ist, dann liefern sie es auf eigene Kosten nach, wenn der Artikel in absehbarer Zeit wieder vorrätig ist (selbst wenn er nur 0,20€ wert ist).&lt;br /&gt;
* lässt einen dennoch manchmal warten, wenn ein Artikel nicht lieferbar ist! Daher bei der Bestellung immer darauf hinweisen, dass man auch eine Teillieferung akzeptiert. (Laut Auskunft dauert das länger, besser nach der Inet-Bestellung anrufen und nicht lieferbare Teile aus der Bestellung streichen lassen)&lt;br /&gt;
* Lieferzeiten normalerweise 2 - 4 Arbeitstage&lt;br /&gt;
* niedrige Preise (aber unbedingt Qualität des Artikel checken)&lt;br /&gt;
* Versandkosten 5,60€ (Deutschland); 10€ Österreich; Schweiz 16€; EU 15 - 19€;&lt;br /&gt;
* 10€ Mindestbestellwert für alle Länder&lt;br /&gt;
* auch in die Schweiz sehr guter Service&lt;br /&gt;
* holt sich auch ohne Erlaubnis Bankauskünfte bei großen Bestellungen ein&lt;br /&gt;
&lt;br /&gt;
=== RFW Elektronik ===&lt;br /&gt;
Homepage: http://www.rfw-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* HF Bauelemente&lt;br /&gt;
&lt;br /&gt;
=== Ribu ===&lt;br /&gt;
Homepage: http://www.ribu.at&lt;br /&gt;
&lt;br /&gt;
* Sehr guter Elektronikversand in Österreich mit zahlreichen Entwicklungsboards und zahlreichen Elektroniklösungen.&lt;br /&gt;
* Liefert sehr schnell und hat eine ausgezeichnete Beratung. &lt;br /&gt;
* Online-Shop ist sehr übersichtlich und einfach zu bedienen.&lt;br /&gt;
* Lieferstatusanzeige für alle Artikel. Bei Auslaufartikeln ist sogar die noch verfügbare Stückzahl sichbar.&lt;br /&gt;
* Günstige Sonderangebote&lt;br /&gt;
* innerhalb Österreichs 4,90&amp;amp;#8364; Versandkosten, ab 80,- keine Versandkosten&lt;br /&gt;
* ausserhalb Österreichs 13&amp;amp;#8364; Versandkosten, ab 225&amp;amp;#8364; versandkostenfrei&lt;br /&gt;
* liefert auch an Privatkunden&lt;br /&gt;
* Mindestbestellwert innerhalb Österreichs 10&amp;amp;#8364;, ausserhalb 30&amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== Richardson Electronic ===&lt;br /&gt;
Homepage: http://www.richardsonrfpd.com/&lt;br /&gt;
&lt;br /&gt;
* Hochfrequenz-Halbleiter, HF-Röhren,&lt;br /&gt;
&lt;br /&gt;
=== Riedl Elektronik ===&lt;br /&gt;
Homepage: http://www.riedl-electronic.at&lt;br /&gt;
&lt;br /&gt;
* großes Angebot v.a. ICs und Trafos&lt;br /&gt;
* recht günstig&lt;br /&gt;
* Rabatt für Schüler/Student&lt;br /&gt;
* Versand nach AT: 3,95€ bis 1kg, ab 100€ frei Haus&lt;br /&gt;
* Versand AT über 1kg sowie Ausland: Nach Aufwand (wird nicht direkt angezeigt)&lt;br /&gt;
&lt;br /&gt;
=== RLX COMPONENTS s.r.o. ===&lt;br /&gt;
Homepage: http://www.rlx.sk&lt;br /&gt;
&lt;br /&gt;
* Man spricht Deutsch&lt;br /&gt;
* Messgeräte, Mikrocontroller-Boards, Bauelemente&lt;br /&gt;
&lt;br /&gt;
=== RM Computertechnik GmbH ===&lt;br /&gt;
Homepage: http://www.rm-computertechnik.de&lt;br /&gt;
&lt;br /&gt;
* Kerngeschäft ist PC-Technik, aber auch großes Sortiment an Kabeln, Litzen und Steckverbindern&lt;br /&gt;
* handelt auch mit einigen Bauelementen, wie LED&#039;s&lt;br /&gt;
&lt;br /&gt;
=== Robotikhardware===&lt;br /&gt;
Homepage: http://www.robotikhardware.de&lt;br /&gt;
&lt;br /&gt;
* Microcontroller&lt;br /&gt;
* Entwicklungsboards&lt;br /&gt;
* Sensoren&lt;br /&gt;
* Robotik-Zubehör&lt;br /&gt;
* günstige Angebote für Hobbyelektroniker&lt;br /&gt;
* auch einzelne Platinen&lt;br /&gt;
&lt;br /&gt;
=== Robotik-Teile.de===&lt;br /&gt;
Homepage: http://www.robotik-teile.de&lt;br /&gt;
&lt;br /&gt;
* Große Auswahl an Elektronik Produkten &lt;br /&gt;
* Microcontroller, Sensoren, Zubehör, u.v.m.&lt;br /&gt;
* Versandkosten betragen immer 4,90 €&lt;br /&gt;
* Zahlbar ber PayPal, Sofortüberweisung, Vorkasse und Nachnahme&lt;br /&gt;
&lt;br /&gt;
=== Benno Rößle Elektronik ===&lt;br /&gt;
Homepage: http://www.roessle-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Masten, Antennen, Befestigungsmat.,Zubehör, Geräte, Anpassteile, HF-Stecker&lt;br /&gt;
&lt;br /&gt;
=== RS Components ===&lt;br /&gt;
Homepage: http://de.rs-online.com&lt;br /&gt;
&lt;br /&gt;
* lt. AGB nur an gewerbliche Abnehmer und an Studenten. Bei Internetbestellungen wird per Mail nach Belegen gefragt.&lt;br /&gt;
* gute Auswahl insbesondere an &amp;quot;mechanischen Bauteilen&amp;quot;&lt;br /&gt;
* gute Verfügbarkeit&lt;br /&gt;
* sehr schneller Versand, Ware ist in 99% aller Fälle am nächsten Tag da (GP)&lt;br /&gt;
* Preise wurden angepasst, gute Preis/Leistung&lt;br /&gt;
* Preis im Onlineshop sind ohne MwSt angegeben&lt;br /&gt;
* Bei Onlinekauf ist der Versand kostenfrei, ohne Mindesbestellwert.&lt;br /&gt;
* Notify-Me Service für Produktabkündigung&lt;br /&gt;
* Auch größere Stückzahlen über Allied möglich&lt;br /&gt;
* Relativ große Auswahl an Sortimenten (Widerstände, Kondensatoren), Einzelteile können teilweise nachgekauft werden&lt;br /&gt;
* Verfügbarkeitsanzeige im Internet ist ziemlich hilfreich&lt;br /&gt;
* Nützliche Tipps zum Thema RoHS&lt;br /&gt;
* Macht anscheinend Abfragen bei SCHUFA &amp;amp; Co. ohne Einverständnis oder Hinweis in den AGB.&lt;br /&gt;
&lt;br /&gt;
=== Sander Elektronik ===&lt;br /&gt;
Homepage: http://www.sander-electronic.de&lt;br /&gt;
&lt;br /&gt;
* beliefert auch Privatkunden, Bankeinzug möglich&lt;br /&gt;
* ähnlich Segor ein Berliner Versender&lt;br /&gt;
* Hier findet man manche [[MSP430]], die es sonst nicht in kleinen Stückzahlen gibt&lt;br /&gt;
* Herr Sander ist sehr kompetent und selbst Autor von Fachartikeln&lt;br /&gt;
* selbst abgekündigte Halbleiter können noch beschafft werden&lt;br /&gt;
* Bezahlung auch mit Kreditkarte möglich&lt;br /&gt;
* Versandkosten innerhalb Deutschlands ab 3,35&amp;amp;#8364;, innerhalb Europas ab 6&amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== Sasco Holz ===&lt;br /&gt;
Homepage: http://www.sasco.de&lt;br /&gt;
&lt;br /&gt;
* Wie Spoerle eine Tochter von Arrow. &lt;br /&gt;
* Distributor für Analog Devices... &lt;br /&gt;
* Liefert wie Spoerle und Arrow in Deutschland nicht an Privatkunden.&lt;br /&gt;
&lt;br /&gt;
=== Sat-Schneider ===&lt;br /&gt;
Homepage: http://www.sat-schneider.de&lt;br /&gt;
* Bauteile, Ersatzteile  Online-Shop&lt;br /&gt;
* Baugruppen zum Empfang des Digitalen Kurzwellenrundfunks DRM&lt;br /&gt;
&lt;br /&gt;
=== Satistronics ===&lt;br /&gt;
Homepage: http://www.satistronics.com&lt;br /&gt;
&lt;br /&gt;
* typischer &amp;quot;China-Versender&amp;quot;, mit allen Vor- und Nachteilen&lt;br /&gt;
* Lieferzeit bei Standardversand sehr lange (etwa 1 Monat nach D), aber schnellere Lieferung gegen Aufpreis möglich&lt;br /&gt;
* tritt auch bei eBay in Erscheinung ([http://stores.ebay.de/satistronicsstore eBay-Shop]), die Preise dort sind in der Regel aber etwas höher als im Online-Shop&lt;br /&gt;
&lt;br /&gt;
=== Otto Schubert GmbH ===&lt;br /&gt;
Homepage: http://www.schubert-gehaeuse.de&lt;br /&gt;
&lt;br /&gt;
* Kein Online-Shop. Bestellungen nur per Telefon, Fax oder E-Mail &lt;br /&gt;
* Weissblechgehäuse, Gerätegehäuse, wetterfeste Gehäuse&lt;br /&gt;
* Drehkondensatoren&lt;br /&gt;
* Sonderanfertigungen&lt;br /&gt;
* ansässig in 90574 Roßtal&lt;br /&gt;
&lt;br /&gt;
=== Schramm-Software ===&lt;br /&gt;
Homepage: http://www.schramm-software.de/bausatz/&lt;br /&gt;
* Online-Shop, bietet Elektronik-Bausätze mit Mikrocontrollern&lt;br /&gt;
* Bausätze als Lehrmaterial geeignet, da ausführliches Begleitheft mitgeliefert wird (Aufbauanleitung, Schaltung, Controllerprogramm, Experimente...)&lt;br /&gt;
* bisher nur ein relativ kleines Sortiment, soll ergänzt werden&lt;br /&gt;
* Versandkosten innerhalb Deutschlands 2,50 &amp;amp;#8364;, innerhalb der EU 3,50 &amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== Schukat elektronic ===&lt;br /&gt;
Homepage: http://www.schukat.de&lt;br /&gt;
&lt;br /&gt;
* liefert nicht an privaten Endverbraucher&lt;br /&gt;
* einfache und passiver Bauteile oft nur in großen Mindeststückzahlen&lt;br /&gt;
* ICs teilweise recht preiswert (vor allem bei mehr als 1 Stück, z.&amp;amp;nbsp;B. auch AVR)&lt;br /&gt;
* LCDs sehr preiswert und auch als Einzelstücke&lt;br /&gt;
* aktuelle Preise und Verfügbarkeit im Internet (aber nur nach Anmeldung -jetzt nicht mehr bei kleinen Stückzahlen), ebenso Bilder von Gehäusefootprints u.dgl.&lt;br /&gt;
* Abholung in Monheim am Rhein nach Vereinbarung möglich&lt;br /&gt;
* Versandkosten innerhalb Deutschlands ab 5&amp;amp;#8364; (bis 10kg!)&lt;br /&gt;
&lt;br /&gt;
=== Schuricht ===&lt;br /&gt;
Homepage: http://www.schuricht.de&lt;br /&gt;
&lt;br /&gt;
* deutscher Ableger der Distrelec- (Elektronik) und Disdata-Gruppe (Computertechnik)&lt;br /&gt;
* Liefert auch an Privatkunden (getrennte AGBs für gewerbliche und Privatkunden, Lieferung an Privat per Nachnahme: Versandkosten ab 6,54€ plus 4,76€ Nachnahmegebühr).&lt;br /&gt;
** Online-Bestellung von Privatkunde scheiterte daran, dass die  Onlineshop-Bestellformulare nur für gewerbliche Kunden ausgelegt sind und der Onlineshop Bestellungen ohne Firmenangaben nicht annimmt oder gar mit einer internen Fehlermeldung quittierte.&lt;br /&gt;
**Online Bestellung mit &amp;quot;Privat&amp;quot; als Firmenangabe funktionierte einwandfrei.&lt;br /&gt;
**Telefonische Bestellung von Privat funktioniert. Nette, freundliche Behandlung am Telefon, kein Callcenter. Versprochener Rückruf erfolgte mit gewünschten Informationen. Neben Nachnahme wurde für einen relativ teuren Artikel persönliche Abholung angeboten. Angegebene Lieferfrist wurde leicht unterschritten.&lt;br /&gt;
* Papierkatalog über 2000 Seiten, durchgehend farbig, nur für Geschäftskunden erhältlich.&lt;br /&gt;
* Ziemlich teuer&lt;br /&gt;
&lt;br /&gt;
=== Schuro Elektronik GmbH ===&lt;br /&gt;
Homepage: http://www.schuro.de&lt;br /&gt;
&lt;br /&gt;
* Elektronische Bauelemente und Bauteile für den Audio- und Lautsprecherbau (Kondensatoren, Spulen u.dgl.)&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* Versandkosten innerhalb Deutschlands gewichtsabhängig ab 5,75&amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== Segor-electronics ===&lt;br /&gt;
Homepage: http://www.segor.de&lt;br /&gt;
&lt;br /&gt;
* Spezialist für Halbleiter, die ansonsten für nicht-gewerbliche Abnehmer nur schwer erhältlich sind (Preise dahingehend &amp;quot;angemessen&amp;quot;)&lt;br /&gt;
* auch Privatkunden gerne gesehen&lt;br /&gt;
* Ladengeschäft in Berlin&lt;br /&gt;
* kein Mindestbestellwert bei Versand innerhalb der EU&lt;br /&gt;
&lt;br /&gt;
=== SE Spezial-Electronic AG ===&lt;br /&gt;
Homepage: http://www.spezial.de&lt;br /&gt;
&lt;br /&gt;
* Distributor&lt;br /&gt;
* Laut AGB auch Verkauf an Privat.&lt;br /&gt;
* Große Verpackungseinheiten/Mindestbestellmengen pro Bauteil&lt;br /&gt;
* Versandkosten pauschal 9,- €  (Deutschland) (Stand 08/2008)&lt;br /&gt;
&lt;br /&gt;
=== Shortec Electronics ===&lt;br /&gt;
Homepage: http://www.shortec.com&lt;br /&gt;
&lt;br /&gt;
* Unabhängiger Distributor von elektronischen und elektromechanischen Bauelementen aller Hersteller.&lt;br /&gt;
&lt;br /&gt;
=== Small Control Shop ===&lt;br /&gt;
Homepage: http://www.small-control.de&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Bernd Walter Computer Technology&amp;quot;&lt;br /&gt;
* kleines Lieferprogramm aber ein paar interessante Produkte&lt;br /&gt;
&lt;br /&gt;
=== SMG Diffusion - F1GE ===&lt;br /&gt;
Homepage: http://www.smgdiffusion.com&lt;br /&gt;
( Seite nur französisch )&lt;br /&gt;
&lt;br /&gt;
* Videotechnik, &lt;br /&gt;
* 1,2 GHz / 2,4GHz Module&lt;br /&gt;
* Gebraucht-Messgeräte HP, Tek, Philips  u.a.&lt;br /&gt;
* GHz-Halbleiter&lt;br /&gt;
* Koax-Adapter&lt;br /&gt;
* Antennen&lt;br /&gt;
&lt;br /&gt;
=== Spoerle ===&lt;br /&gt;
Homepage: http://www.spoerle.de&lt;br /&gt;
&lt;br /&gt;
* Früher eine Tochterfirma von Arror. Mittlerweile komplett in Arrow aufgegangen, Webseite leitet auf Arrow um.&lt;br /&gt;
* Aus dem Webshop: &amp;quot;Unser Angebot richtet sich nur an Kaufleute und nicht an Verbraucher.&amp;quot;&lt;br /&gt;
* Wenn es wirklich über Arrow sein muss, dann kann man es als Privatperson bei Arrow Electronics North American Components http://www.arrownac.com/ versuchen, die sich normalerweise nicht weigern ihre Produkte zu verkaufen. Allerdings muss man mit großen Mindestmengen (z.&amp;amp;nbsp;B. BC547 in Schritten von 2000 Stück) und hohen Kosten rechnen.&lt;br /&gt;
:Zu den Kosten gehören zum Beispiel ein mehrfacher Mindermengenzuschlag (&#039;&#039;$10 handling charge will be added to each line item less than $30&#039;&#039;), eine satte &#039;&#039;handling and energy fee of $10.22&#039;&#039; (mehr als 10x zu hoch wie die vergleichbare Gebühr für amerikanische Besteller), hohe Versandkosten (ab $20 nach Deutschland). Dazu kommen die üblichen Kosten für den Import aus dem Ausland (Einfuhrumsatzsteuer, Kreditkartengebühr, ...)&lt;br /&gt;
&lt;br /&gt;
=== SR-Systems ===&lt;br /&gt;
Homepage: http://www.sr-systems.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen für Digital-TV, Sende- und Empfangstechnik&lt;br /&gt;
* DVB-S, DVB-T&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Strixner&amp;amp;Holzinger ===&lt;br /&gt;
Homepage: http://www.sh-halbleiter.de&lt;br /&gt;
&lt;br /&gt;
* Ladengeschäft in München&lt;br /&gt;
* Versand &lt;br /&gt;
* riesiges Angebot an Halbleiter, auch schwer beschaffbare&lt;br /&gt;
* Online-Shop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== TAUTEC-ELECTRONICS ===&lt;br /&gt;
Homepage: http://www.tautec-electronics.de&lt;br /&gt;
&lt;br /&gt;
* Online Shop für aktive elektronische Bauelemente&lt;br /&gt;
* günstige Preise (Vorsicht, Preisangaben enthalten keine Mehrwertsteuer) aber Mindestbestellwert 100 Euro&lt;br /&gt;
* alle Artikel ab Lager lieferbar, daher kurze Wartezeiten&lt;br /&gt;
* weltweiter Versand&lt;br /&gt;
* zahlreiche Mengenrabatte&lt;br /&gt;
* viele Ersatzteile aus dem Audio-, Car-HiFi und TV-Bereich&lt;br /&gt;
&lt;br /&gt;
=== TCB-Versand ===&lt;br /&gt;
Homepage: http://www.tcb-versand.de&lt;br /&gt;
&lt;br /&gt;
* insbesondere für Modellbauer ein sehr interresantes Sortiment&lt;br /&gt;
* Stecker,Kabel etc. recht günstig und kleine Mengen abnehmbar &lt;br /&gt;
* Lieferung normal zwischen 1 und 3 Tage&lt;br /&gt;
* leider nur Online-Shop&lt;br /&gt;
&lt;br /&gt;
=== TecHome.de Online-Shop ===&lt;br /&gt;
Hompage: http://www.techome.de/index.html&lt;br /&gt;
&lt;br /&gt;
=== Tec-Shop (Wolfgang Rompel Elektronik) ===&lt;br /&gt;
Homepage: http://www.tec-shop.de&lt;br /&gt;
&lt;br /&gt;
* Kleines, aber ausgesuchtes Sortiment&lt;br /&gt;
* Interessantes Angebot an Sensoren&lt;br /&gt;
&lt;br /&gt;
=== Technik-Welt / Industrieshop.at ===&lt;br /&gt;
Homepage: http://www.industrieshop.at&lt;br /&gt;
&lt;br /&gt;
* Laut Homepage richtet man sich &amp;quot;an den industriellen Kunden&amp;quot;. Laut AGB sieht man das jedoch nicht so eng, Zitat:&lt;br /&gt;
:: &#039;&#039;TW schließt online Verträge nur mit Kunden ab, die natürliche oder juristischen Personen sind, die ihren Wohnsitz oder Sitz in Österreich, einem Mitgliedsstaat der Europäischen Union (EU25) oder der Schweiz haben.&#039;&#039;&lt;br /&gt;
* [[#Farnell|Farnell]] Teile&lt;br /&gt;
* In Österreich&lt;br /&gt;
* Schnelle Lieferung (2 Tage)&lt;br /&gt;
&lt;br /&gt;
=== TIGAL KG ===&lt;br /&gt;
Homepage: http://www.tigal.com&lt;br /&gt;
&lt;br /&gt;
* Boards und Tools für Embedded-Elektronik&lt;br /&gt;
* In Österreich &lt;br /&gt;
* Versandkosten ab € 7,00 in Österreich, ab € 10,00 nach Deutschland.&lt;br /&gt;
* Preisangaben ohne MWSt. Für Privatkunden kommen 20% österreichische Mehrwertsteuer hinzu.&lt;br /&gt;
* U.a. ZeroLogic Logik-Analysatoren.&lt;br /&gt;
&lt;br /&gt;
=== TME (Transfer Multisort Elektronik) ===&lt;br /&gt;
Homepage: [http://www.tme.eu/de]&lt;br /&gt;
&lt;br /&gt;
* Firmensitz in Łódź, Polen&lt;br /&gt;
* Zahlungsabwicklung über deutsches Konto oder PayPal&lt;br /&gt;
* Firmenvertretung in Leipzig, man spricht deutsch&lt;br /&gt;
* Versand mit UPS (etwa 8 Euro inkl. MwSt.); Trackingnummer wird sofort nach Kommissionierung zugesendet&lt;br /&gt;
* als Privatkunde: Mehrwertsteuer beachten (23%). Seit neuestem 17,6% &amp;quot;Strafaufschlag&amp;quot; auf Bruttopreis bei Privatbestellung. Effektiv ergibt dies ca. 45% (!) auf den Nettopreis. Zitat auf Nachfrage: &amp;quot;Bei Rechnungserstellung für Privatkunden wird der angezeigt Preis + 15% (Rabatt für Firmenkunden) + 23% poln. Mwst. ausgewiesen&amp;quot;.&lt;br /&gt;
* sehr großes günstiges SMD Sortiment&lt;br /&gt;
* unmittelbar aktualisierter Lagerbestand, Mindestmengen und Vielfache beachten&lt;br /&gt;
&lt;br /&gt;
=== Trade-Shop / AIR Electronics GmbH ===&lt;br /&gt;
Homepage: http://www.trade-shop.de&lt;br /&gt;
&lt;br /&gt;
* Trotz knackiger Sprüche auf der englischen Version der Webseite (&amp;quot;Electronic Components Superstore&amp;quot;) eher kleines Angebot elektronischer Bauteile&lt;br /&gt;
* 20 Euro Mindestbestellmenge (Stand Februar 2008)&lt;br /&gt;
* ab 6,90 Euro Versandkosten (Deutschland, bis 1kg)  (Stand Februar 2008)&lt;br /&gt;
&lt;br /&gt;
=== Trenkenchu &amp;amp; Stadler GbR ===&lt;br /&gt;
Homepage: http://www.ts-audio.de&lt;br /&gt;
&lt;br /&gt;
* die meisten Artikel sind deutlich teurer als der Marktpreis, es sind jedoch auch Schnäppchen dabei, z.B. HDMI-Kabel&lt;br /&gt;
&lt;br /&gt;
=== TV-Ersatzteile ===&lt;br /&gt;
Homepage: http://www.tversatzteile.de&lt;br /&gt;
&lt;br /&gt;
* TV-, Audio-, Video-Ersatzteile, Aktive / Passive Bauteile&lt;br /&gt;
* Fernbedienungen Haushaltstechnik&lt;br /&gt;
&lt;br /&gt;
=== UKW-Berichte ===&lt;br /&gt;
Homepage: http://www.ukw-berichte.de&lt;br /&gt;
&lt;br /&gt;
* Antennen, Bauteile, Bausätze, Literatur für Amateurfunk&lt;br /&gt;
* ansässig in 91081 Baiersdorf&lt;br /&gt;
&lt;br /&gt;
=== Voelkner ===&lt;br /&gt;
Homepage: Kein Link, entsprechend der Vorgabe des Betreibers der Voelkner Webseite im Impressum:&lt;br /&gt;
&amp;lt;i&amp;gt;&amp;lt;blockquote&amp;gt;voelkner - direkt günstiger&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
wird produziert und betreut von&amp;lt;br/&amp;gt;&lt;br /&gt;
Re-In Retail International GmbH &amp;lt;br/&amp;gt;&lt;br /&gt;
...&amp;lt;br/&amp;gt;&lt;br /&gt;
Eine Verlinkung auf die Website der Firma Re-In Retail International GmbH bedarf einer schriftlichen Genehmigung. &amp;lt;/blockquote&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Großer Teil des Conrad-Programms, identische Nummern, identische Aufkleber auf der Ware, Preise identisch oder nur ein paar Cent abweichend&lt;br /&gt;
* Versandkosten Deutschland: 4,95€; ab 25€ Warenwert und Sofortüberweisung.de versandkostenfrei / Versandkosten-Flatrate für 15€ pro Jahr&lt;br /&gt;
* Versandkosten EU: 9,95€&lt;br /&gt;
* Möglichkeit der Versandkostenflatrate (D): Einmalig 14,95€ / gültig für ein Jahr&lt;br /&gt;
* Legt jeder Bestellung gleich wieder einen Gutschein über 5€ bei MBW 25€ bei (Flat nur bei häufigen, kleinen Bestellungen sinnvoll); außerdem kommt etwa alle 2-3 Monate selbiger Gutschein + versandkostenfreie Lieferung per Mail, ebenfalls MBW 25€&lt;br /&gt;
* Verpackungsqualität wechselnd, mal brauchbar, mal eher Pollin-Niveau. Selbst kleine Bestellungen, die gefahrlos per Brief/Großbrief verschickt werden könnten werden in einem großen Paket versendet.&lt;br /&gt;
&lt;br /&gt;
=== VOTI Webshop ===&lt;br /&gt;
Homepage: http://www.voti.nl/shop/catalog.html&lt;br /&gt;
&lt;br /&gt;
* relativ kleines Lieferprogramm&lt;br /&gt;
* einige interessante Restposten (Surplus)&lt;br /&gt;
&amp;lt;!-- nicht mehr: * verkauft auch VID/PID-Paare für USB-Applikationen --&amp;gt;&lt;br /&gt;
* Sitz in Amersfoort, Niederlande&lt;br /&gt;
&lt;br /&gt;
=== Walter elektronik ===&lt;br /&gt;
Homepage: http://www.walter-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Bauteile, Röhren&lt;br /&gt;
&lt;br /&gt;
=== Waschbär Soft 2010 ===&lt;br /&gt;
Homepage: http://www.xn--waschbr-soft-2010-vqb.de&lt;br /&gt;
&lt;br /&gt;
* Onlineversandhaus für Unterhaltungselektronik, &amp;quot;Haushaltselektronik&amp;quot;, Computer und -zubehör&lt;br /&gt;
* keine elektronischen Bauteile&lt;br /&gt;
&lt;br /&gt;
=== Watterott electronic GmbH===&lt;br /&gt;
Homepage: http://www.watterott.com&lt;br /&gt;
&lt;br /&gt;
* Distributor für Arduino, BeagleBoard, FriendlyARM, Pololu, Seeed Studio, Solarbotics, SparkFun...vollständige [http://www.watterott.net/about#distri Liste hier]&lt;br /&gt;
* Entwicklungskits von Atmel, Luminary Micro, Microchip, Raisonance, TI&lt;br /&gt;
* Spezialbauteile von Davicom, FTDI, VLSI, WIZnet&lt;br /&gt;
* Bungard Basismaterial + Chemie&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* Zahlung: Vorkasse, Sofortüberweisung, PayPal, Nachnahme, Kreditkarte (Visa/Mastercard), Rechnung (nur gewerbliche Kunden)&lt;br /&gt;
* Versandkosten Dtl. (UPS): &lt;br /&gt;
** bis  25 EUR Warenwert: 3,50 Euro&lt;br /&gt;
** bis  50 EUR Warenwert: 2,90 Euro&lt;br /&gt;
** bis 150 EUR Warenwert: 2,00 Euro&lt;br /&gt;
** ab  150 EUR Warenwert: versandkostenfrei&lt;br /&gt;
* Versandkosten EU (UPS): &lt;br /&gt;
** bis 150 EUR Warenwert: 10,00 Euro&lt;br /&gt;
** bis 250 EUR Warenwert:  8,90 Euro&lt;br /&gt;
** bis 500 EUR Warenwert:  7,00 Euro&lt;br /&gt;
** ab  500 EUR Warenwert:  versandkostenfrei&lt;br /&gt;
* Schneller, entgegenkommender Service&lt;br /&gt;
&lt;br /&gt;
=== Westfalia ===&lt;br /&gt;
Homepage Deutschland: http://www.westfalia.de&lt;br /&gt;
Homepage Österreich: http://www.westfalia-versand.at&lt;br /&gt;
&lt;br /&gt;
* Vor 85 Jahren in Hagen, Westfalen gegründet&lt;br /&gt;
* Elektronik nur ein kleiner Teil des Angebotes. Eher insgesamt Haushalts-, Werkstätten-, Agrar- und Gartenbedarf&lt;br /&gt;
* Elektroniksortiment stark schwankend. Momentan (Juni 2008) wenig Auswahl.&lt;br /&gt;
* Mindestbestellwert 18 €, bei Neukundenbestellungen mit Prämienanforderungen (wenig wertiges Geschenk) sogar 50 €.&lt;br /&gt;
* 4,95&amp;amp;#8364; Versandkosten, ab 150&amp;amp;#8364; Bestellwert versandkostenfrei&lt;br /&gt;
* Transportversicherung wird zusätzlich mit einem Zuschlag von 0,8% des Warenwertes berechnet.&lt;br /&gt;
* Einmalige Bestellung führte zu jahrelanger Zusendung von Werbung für Westfalia-Angeboten mit Gewinnspielen (Glücksnummern, Rubbellose, Glücksschlüssel, etc.)&lt;br /&gt;
* Verpackung ähnlich &amp;quot;sorgfältig&amp;quot; wie bei [[#Pollin_Electronic|Pollin Electronic]]. Übergroße Kartons, wenig Verpackungsmaterial, schweres Teil (Labornetzgerät) flog lose im Karton herum und zertrümmerte andere Ware.&lt;br /&gt;
&lt;br /&gt;
=== WilTec Wildanger Technik GmbH ===&lt;br /&gt;
Homepage: http://shop.wiltec.info&lt;br /&gt;
&lt;br /&gt;
* Aoyue Lötgeräte (Heißluft, Löten, Entlöten), Netzteile, Werkzeuge&lt;br /&gt;
* Aoyue Zubehör (Lötspitzen, Heißluftdüsen), Ersatzteile&lt;br /&gt;
* Andere, nicht Elektronik-Angebote, wie KFZ-Tuningteile&lt;br /&gt;
* Versand. Bei Voranmeldung auch Lagerverkauf.&lt;br /&gt;
&lt;br /&gt;
=== Wüstens frag-jan-zuerst ===&lt;br /&gt;
Homepage: http://www.die-wuestens.de/dindex.htm&lt;br /&gt;
&lt;br /&gt;
* Röhrentechnik&lt;br /&gt;
* Hochspannungs-Spezialteile&lt;br /&gt;
&lt;br /&gt;
=== WIMO ===&lt;br /&gt;
Homepage: http://www.wimo.de&lt;br /&gt;
&lt;br /&gt;
* Große Auswahl an Amateurfunktechnik&lt;br /&gt;
&lt;br /&gt;
=== Zech DG0VE ===&lt;br /&gt;
Homepage: http://www.dg0ve.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen für Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Diverse ===&lt;br /&gt;
* http://www.chip-flip.com - Europäisches Bauelementesuchsystem, franchised Lieferantensuche, Datenblätter und viele nützliche Informationen&lt;br /&gt;
* http://www.ecomponents-store.com/ Elektronische Bauelemente kaufen - Hier finden Sie eine große Auswahl an elektronischen und elektromechanischen Bauelementen von über 40 Herstellern.&lt;br /&gt;
* http://www.franchised-distributors.eu/ - Finden Sie Vertragsdistributoren von über 800 Halbleiterherstellern für elektronische und elektromechanische Bauelemente.&lt;br /&gt;
&lt;br /&gt;
TODO: elektronik-fundgrube&lt;br /&gt;
&lt;br /&gt;
==Ebay-Shops==&lt;br /&gt;
&lt;br /&gt;
===Ego-China===&lt;br /&gt;
http://stores.ebay.de/Ego-China-Electronics   TFTs und LCDs &amp;lt;br /&amp;gt; Versand aus China (2-3 Wochen)&lt;br /&gt;
&lt;br /&gt;
===Sure-Electronics===&lt;br /&gt;
http://stores.ebay.de/Sure-Electronics   Highpower LEDs und Verstärker &amp;lt;br /&amp;gt;&lt;br /&gt;
Hat auch einen eigenen Shop: http://www.sureelectronics.net/ &amp;lt;br /&amp;gt;&lt;br /&gt;
Versand aus China&lt;br /&gt;
&lt;br /&gt;
===Ether-Deal===&lt;br /&gt;
http://stores.ebay.de/ether-deal   Unter sonstiges viele versch. Elektronik-teile &amp;lt;br /&amp;gt; Versand aus China&lt;br /&gt;
&lt;br /&gt;
===NooElec===&lt;br /&gt;
http://stores.ebay.de/NooElec USB-AVR Boards (mega32u2) und rgbled-matrizen &amp;lt;br /&amp;gt; Versand aus Kanada&lt;br /&gt;
&lt;br /&gt;
==Messgeräte ==&lt;br /&gt;
=== Neue Messgeräte ===&lt;br /&gt;
&lt;br /&gt;
Viele der oben genannten Elektronikversender verkaufen auch Messgeräte. Darüber hinaus gibt es diverse Versender, die sich hauptsächlich oder ausschließlich auf Messgeräte spezialisiert haben. Allerdings verkaufen viele davon nicht an Privat.&lt;br /&gt;
&lt;br /&gt;
==== CalPlus GmbH ====&lt;br /&gt;
Homepage: http://www.calplus.de &amp;lt;br /&amp;gt;&lt;br /&gt;
Shop: http://www.scopeshop.de&lt;br /&gt;
&lt;br /&gt;
==== Cosinus ComputerMesstechnik ====&lt;br /&gt;
Homepage: http://www.cosinus.de&lt;br /&gt;
&lt;br /&gt;
* Nicht an Privat&lt;br /&gt;
&lt;br /&gt;
==== dataTec ====&lt;br /&gt;
Homepage: http://www.datatec.de&lt;br /&gt;
&lt;br /&gt;
* Große Auswahl&lt;br /&gt;
* &amp;lt;s&amp;gt;(Nicht an Privat)&amp;lt;/s&amp;gt; Bestellung von Privat problemlos möglich, Privatpersonen werden laut ABG per Vorkasse beliefert&lt;br /&gt;
* Studenten bekommen Rabatt, je nach dem, was bestellt wird&lt;br /&gt;
* Umständlicher Bestellvorgang, seitens DataTec teilweise auf dem Postweg -&amp;gt; Es dauert teil sehr lange bis die Ware ankommt&lt;br /&gt;
* Sehr freundlicher und kompetenter Service, per eMail als auch telefonisch&lt;br /&gt;
&lt;br /&gt;
==== Donald4646 ====&lt;br /&gt;
Homepage: http://www.donald4646.co.uk&lt;br /&gt;
&lt;br /&gt;
* In Schottland&lt;br /&gt;
* Als eBay-Shop gestartet&lt;br /&gt;
* Einfache, No-Name und Billigmarken (z.&amp;amp;nbsp;B. Oszilloskope)&lt;br /&gt;
&lt;br /&gt;
==== Elektronik-Kontor Messtechnik GmbH ====&lt;br /&gt;
Homepage: http://www.ekomess.de&lt;br /&gt;
&lt;br /&gt;
==== Meilhaus Electronic GmbH ====&lt;br /&gt;
Homepage: http://www.meilhaus.de&lt;br /&gt;
&lt;br /&gt;
* Diverse Markenhersteller&lt;br /&gt;
* Eigenmarken&lt;br /&gt;
&lt;br /&gt;
==== PinSonne-Elektronik ====&lt;br /&gt;
Homepage: http://www.pinsonne-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Onlineshop&lt;br /&gt;
* Sehr kleines Sortiment&lt;br /&gt;
* UNI-T, RIGOL und andere asiatische Firmen&lt;br /&gt;
&lt;br /&gt;
==== PK elektronik Poppe GmbH ====&lt;br /&gt;
Homepage: http://www.pk-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* U.a. Fluke Distributor.&lt;br /&gt;
&lt;br /&gt;
====Präzitronic Hennig / Messgeräte Chemnitz====&lt;br /&gt;
Homepage: http://www.messgeraete-chemnitz.de&lt;br /&gt;
&lt;br /&gt;
* Owon&lt;br /&gt;
* Selbst übersetzte deutsche Owon-Handbücher&lt;br /&gt;
* Fluke&lt;br /&gt;
* Zusätzlich kleines Angebot an Gebrauchtgeräten&lt;br /&gt;
&lt;br /&gt;
==== ScopeShop Hamburg ====&lt;br /&gt;
&lt;br /&gt;
* Von CalPlus übernommen, siehe [[#CalPlus_GmbH|CalPlus]]&lt;br /&gt;
&lt;br /&gt;
==== SI Scientific Instruments GmbH ====&lt;br /&gt;
Homepage: http://www.si-scientific.de (Onlineshop) &amp;lt;br /&amp;gt;&lt;br /&gt;
Homepage: http://www.si-gmbh.de (komplettes Programm)&lt;br /&gt;
&lt;br /&gt;
* Onlineshop auf si-scientific.de&lt;br /&gt;
* Akzeptiert PayPal&lt;br /&gt;
 &lt;br /&gt;
==== SKY Messtechnik GmbH ====&lt;br /&gt;
Homepage: http://www.sky-messtechnik.de&lt;br /&gt;
&lt;br /&gt;
* Kein Onlineshop (E-Mail oder Telefon)&lt;br /&gt;
&lt;br /&gt;
==== TESTEC ====&lt;br /&gt;
Homepage: http://www.testec.info&lt;br /&gt;
&lt;br /&gt;
* Tastköpfe-Hersteller&lt;br /&gt;
* Hameg Vertriebspartner&lt;br /&gt;
* B+K Precision Generalimporteur&lt;br /&gt;
&lt;br /&gt;
==== Zeitech ====&lt;br /&gt;
Homepage: http://zeitech.eu/shop/&lt;br /&gt;
&lt;br /&gt;
* Diverses (Rigol, Owon, etc.)&lt;br /&gt;
&lt;br /&gt;
=== Gebrauchte Messgeräte ===&lt;br /&gt;
&lt;br /&gt;
Dieser Abschnitt enthält Anbieter bei denen gebrauchte Messgeräte erhältlich sind.&lt;br /&gt;
&lt;br /&gt;
==== Astro Electronic ====&lt;br /&gt;
Homepage: http://www.astro-electronic.de&lt;br /&gt;
&lt;br /&gt;
==== eumex GmbH ====&lt;br /&gt;
Homepage: http://www.eumes.com/pub/de/&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
&lt;br /&gt;
==== HTB-Elektronik ====&lt;br /&gt;
Homepage: http://www.htb-elektronik.com&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
&lt;br /&gt;
==== IX Instrumex ====&lt;br /&gt;
Homepage: http://www.instrumex.de/index.cgi?User:LANGUAGE=de&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
&lt;br /&gt;
==== Christoph Lüders MessTechnik ====&lt;br /&gt;
Homepage: http://www.CLMT.de &amp;lt;br&amp;gt;&lt;br /&gt;
Online-Shop: http://www.shop-016.de/shop-CLMT.html &amp;lt;br&amp;gt;&lt;br /&gt;
eBay: http://myworld.ebay.de/c_h_r/&lt;br /&gt;
&lt;br /&gt;
* Hat 2010 die Restbestände von Förtig übernommen&lt;br /&gt;
&lt;br /&gt;
==== mbmt Messtechnik ====&lt;br /&gt;
Homepage: http://www.mbmt.com&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
* Verkauf nur an Gewerbetreibende&lt;br /&gt;
&lt;br /&gt;
==== Rosenkranz Elektronik ====&lt;br /&gt;
Homepage: http://www.rosenkranz-elektronik.de&amp;lt;br&amp;gt;&lt;br /&gt;
eBay Shop: http://stores.ebay.de/Rosenkranz-Elektronik-GmbH-Shop&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
* Auch auf eBay zu finden&lt;br /&gt;
&lt;br /&gt;
==== Helmut-Singer-Elektronik ====&lt;br /&gt;
Homepage: http://www.helmut-singer.de&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
* Verkauf auch an Privat&lt;br /&gt;
* An den meisten Samstagen im Jahr auch Lagerverkauf, sonst Versand&lt;br /&gt;
&lt;br /&gt;
==== Sphere ====&lt;br /&gt;
Homepage: http://www.sphere.bc.ca&amp;lt;br&amp;gt;&lt;br /&gt;
Messgeräte und Ersatzteile: http://www.sphere.bc.ca/test/index.html&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
* Ersatzteile&lt;br /&gt;
** Besonders bekannt für Tektronix-Ersatzteile&lt;br /&gt;
&lt;br /&gt;
==== Tektronix TekSelect ====&lt;br /&gt;
Homepage: http://www.tek.com/Measurement/tekselect/&lt;br /&gt;
&lt;br /&gt;
* Tektronix verkauft selber gebrauchte und überarbeitete Tektronix-Messgeräte unter dem Label &#039;&#039;TekSelect&#039;&#039;.&lt;br /&gt;
* Original Tektronix-Garantie&lt;br /&gt;
* Der Bestellvorgang nervt, man muss Kontaktaufnahme durch einen &amp;quot;Representative&amp;quot; erbeten.&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [[Platinenhersteller]]&lt;br /&gt;
* [[Lokale Elektroniklieferanten]]&lt;br /&gt;
* [[Eisenwarenversender]]&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://www.xs4all.nl/~ganswijk/chipdir/ Suche nach integrierten Schaltkreisen&lt;br /&gt;
* http://www.alldatasheet.com                Datenblätter&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Lieferanten]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=68012</id>
		<title>STM32</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=68012"/>
		<updated>2012-08-22T17:39:45Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* Installation für STM32 (Windows) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;STM32 ist ein Mikrocontroller-Familie von [http://www.st.com/mcu/inchtml-pages-stm32.html ST] mit einer 32-Bit [http://www.arm.com/products/processors/cortex-m/index.php ARM Cortex-M3/M4] CPU. Diese Architektur ist speziell für den Einsatz in Microcontrollern neu entwickelt und löst damit die bisherigen ARM7-basierten Controller weitestgehend ab. Den STM32 gibt es von ST in unzähligen Varianten mit variabler Peripherie und verschiedenen Gehäusegrößen und -formen. Durch die geringe Chipfläche des Cores ist es ST möglich, eine 32 Bit-CPU für weniger als 1&amp;amp;nbsp;€ anzubieten.&lt;br /&gt;
&lt;br /&gt;
[[Bild:stm32F103xc.png|thumb|right|340px|Blockdiagramm STM32F103xC/D/E]]&lt;br /&gt;
&lt;br /&gt;
== STM32-Familien ==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es sieben STM32-Familien:&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1588.jsp STM32F0]&lt;br /&gt;
** Cortex M0&lt;br /&gt;
** µC zum Einstieg&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1169.jsp STM32F1]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
*** Connectivity line&lt;br /&gt;
*** Performance line&lt;br /&gt;
*** USB Access line&lt;br /&gt;
*** Access Line&lt;br /&gt;
*** Value line &lt;br /&gt;
* [http://www.st.com/internet/mcu/product/250173.jsp STM32F2]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
** Wie die STM32F1 Serie, jedoch 120MHz, Camera-Interface, 32-Bit Timer, Crypto-Engine...&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1605.jsp STM32F3]&lt;br /&gt;
** ARM® Cortex™-M4-based STM32 F3, 72MHz&lt;br /&gt;
** DSP instructions and the floating point unit &lt;br /&gt;
** Fast 12-bit 5 MSPS and precise 16-bit sigma-delta ADCs&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1521.jsp STM32F4]&lt;br /&gt;
** Cortex M4&lt;br /&gt;
** ARM® Cortex™-M4-based STM32 F4, 168MHz&lt;br /&gt;
** DSP instructions and the floating point unit &lt;br /&gt;
* [http://www.st.com/mcu/inchtml-pages-stm32l.html STM32L]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
** Low Power &lt;br /&gt;
** mit LCD Treiber&lt;br /&gt;
* [http://www.st.com/mcu/inchtml-pages-stm32w.html STM32W]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
** RF-MCU &lt;br /&gt;
[http://www.st.com/internet/mcu/class/1734.jsp Hier eine Übersicht zum Auswählen eines STM32Fxxx]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features&#039;&#039;&#039;&lt;br /&gt;
* Cortex-M3 bzw. Cortex-M4 Kern in der STM32F4xx Serie&lt;br /&gt;
* 16KB ... 1MB  [[Flash-ROM]]&lt;br /&gt;
*  4KB ... 192KB [[Speicher#SRAM|SRAM]]&lt;br /&gt;
* 4KB [[Speicher#EEPROM|EEPROM]] (STM32L)&lt;br /&gt;
* 512 one-time programmable Bytes(STM32F2/4)&lt;br /&gt;
* [[IC-Gehäuseformen | Gehäuse]] 36 ... 176 Pins als QFN, LQFP und BGA&lt;br /&gt;
* Derzeit sind über &#039;&#039;&#039;250&#039;&#039;&#039; STM32 Derivate/Varianten verfügbar&lt;br /&gt;
* Bis 72MHz CPU-Takt, bis 120MHz beim STM32F2xx, bis 168 MHz beim STM32F4xx, wobei eine spezielle prefetch-hardware bis 120/168 MHz eine Geschwindigkeit erzielen soll, die 0 Wait-States entspricht. Der CPU-Takt wird über einen Multiplikator aus dem internen RC-Takt oder einem externen Quarz-Takt abgeleitet.&lt;br /&gt;
* Externes Businterface (nur bei Gehäusen ab 100 Pin und nur bei STM32F4, STM32F2 und STM32F1 Performance line)&lt;br /&gt;
* LCD Treiber für 8x40 Punkte (nicht beim STM32F2xx)&lt;br /&gt;
* Spannungsbereich 1,65 ... 3,6V, nur eine Betriebsspannung nötig&lt;br /&gt;
* Temperaturbereich bis 125 °C&lt;br /&gt;
* Bis zu 140 IOs, viele davon [[Pegelwandler|5V-tolerant]]&lt;br /&gt;
* Interner, kalibrierter RC-Oszillator mit 8MHz (16MHz bei STM32F2xx)&lt;br /&gt;
* Externer Quarz&lt;br /&gt;
* Real Time Clock mit eigenem Quarz und separater Stromversorgung&lt;br /&gt;
* Bis zu 16 [[Timer]], je Timer bis zu 4 IC/OC/PWM Ausgänge. Davon 2x Motion Control Timer (bei STM32F103xF/G)&lt;br /&gt;
* Systick Counter&lt;br /&gt;
* Bis zu 3 12-Bit [[AD-Wandler]] mit insgesamt 24 AD-Eingängen, integrierter [[Temperatursensor]], Referenzspannung Vrefint und VBatt Spannungsmessung (STM32F4xx)&lt;br /&gt;
* Bis zu 2 12-Bit [[DA-Wandler]]&lt;br /&gt;
* Bis zu 2 [[DMA]] Controller mit bis zu 12 Kanälen (16 beim STM32F2xx)&lt;br /&gt;
* Bis zu 2x [[I2C|I²C]]&lt;br /&gt;
* Bis zu 5x [[UART|USART]] mit LIN, IrDA und Modem Control (6 beim STM32F2xx)&lt;br /&gt;
* Bis zu 3x [[SPI]]&lt;br /&gt;
* Bis zu 2x [[I2S|I²S]]&lt;br /&gt;
* Bis zu 2x [[CAN]]&lt;br /&gt;
* Unique device ID register (96 Bits)&lt;br /&gt;
* RNG - Random Number Genrator (STM32F2xx)&lt;br /&gt;
* Cryptographic Processor (CRYP) (STM32F2xx)&lt;br /&gt;
* Hash Processor (HASH) (STM32F2xx)&lt;br /&gt;
* Kamera-Interface (DCMI) (STM32F2xx)&lt;br /&gt;
* [[USB]] 2.0 Full Speed / OTG&lt;br /&gt;
* [[USB]] 2.0 Hi Speed OTG mit extra PHY-Chip (STM32F2xx)&lt;br /&gt;
* SDIO Interface (z.B. SD-Card Reader)&lt;br /&gt;
* Ethernet&lt;br /&gt;
* Watchdog mit Window-Mode&lt;br /&gt;
* Jedes Peripheriemodul ist separat einschaltbar, wodurch sich erheblich [[Ultra low power|Strom sparen]] lässt&lt;br /&gt;
* [[JTAG]] und SWD (Serial Wire Debug) Interface&lt;br /&gt;
* Bis zu 6 Hardware-Breakpoints für Debuggen&lt;br /&gt;
* und vieles mehr . . .&lt;br /&gt;
&lt;br /&gt;
== Struktur der Dokumentation: ==&lt;br /&gt;
&lt;br /&gt;
Als Beispiel der Dokumentation soll stellvertretend der [http://www.st.com/mcu/devicedocs-STM32F103RC-110.html STM32F103RC] genannt werden. Die Seite von ST beinhaltet alle nötigen Informationen passend zu diesem Prozessor.&lt;br /&gt;
&lt;br /&gt;
Diese Dokumente von ST beschreiben den Controller:&lt;br /&gt;
&lt;br /&gt;
* [http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00191185.pdf  Datasheet STM32F103xC/D/E]&lt;br /&gt;
* [http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00171190.pdf  Reference Manual (RM0008)]&lt;br /&gt;
* [http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00228163.pdf  Cortex-M3 Programming Manual]&lt;br /&gt;
* [http://www.st.com/stonline/products/literature/pm/13259.pdf Flash Programming Reference]&lt;br /&gt;
&lt;br /&gt;
Im Datasheet sind die speziellen Eigenschaften einer bestimmten Modellreihe beschrieben und die exakten Daten und Pinouts aufgeführt. Die Peripheriemodule werden nur aufgeführt, nicht detailliert beschrieben. In der Referenz ist der gesamte Controller mit Peripheriemodulen im Detail beschrieben, gültig für eine STM32-Familie. Details zum Prozessorkern selbst und den nicht STM32-spezifischen mit dem Cortex-M3 Core assoziierten Modulen wie dem Interrupt-Controller und dem Systick-Timer findet man jedoch nicht dort, sondern im Cortex-M3 Manual. Wer nicht die ST Firmware-Library verwendet, der benötigt zusätzlich die Flash Programming Reference für die Betriebsart des Flash-ROMs, d.h. die frequenzabhängige Konfiguration der Waitstates. Hinzu kommen optionale Dokumente von ARM, die den [http://infocenter.arm.com/help/topic/com.arm.doc.ddi0337-/ Cortex-M3 Kern] / [http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0439c/index.html Cortex-M4 Kern] beschreiben. Hier gibt es den Opcode wenn man ihn in [http://infocenter.arm.com/help/topic/com.arm.doc.ddi0403-/ Assembler] programmieren möchte. Zusätzlich sollten auch die [http://www.st.com/stonline/products/literature/es/14732.pdf Errata Sheets] beachtet werden. Empfohlen sei auch die Appnote &amp;quot;[http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/CD00164185.pdf STM32F10xxx hardware development: getting started]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== ‎STM32F10x Standard Peripherals Library ==&lt;br /&gt;
&lt;br /&gt;
ST bietet eine umfangreiche Firmwarebibliothek, eine einzige Bibliothek für alle STM32 Derivate. Das ist der große Vorteil von ST (gibt es beispielsweise auf den Cortex-M3 Controllern von TI auch, ist teilweise in einem separaten ROM untergebracht). Einmal programmieren und in allen STM32 verwendbar. Alle Funktionen sind gekapselt in einfache Strukturen und Funktionsaufrufe. Somit muss man sich nicht selbst um die Peripherieregister kümmern. Diese Library und ihre Dokumentation setzen das grundlegende Verständnis der Funktion des jeweiligen Peripheriemoduls voraus, wie es die o.A. Referenz und diverse Appnotes vermitteln. Diese FW-Lib (Download von ST) ist ein MUSS für jeden, denn darin sind auch jede Menge Beispiele für alle Peripheriemodule. &lt;br /&gt;
&lt;br /&gt;
Details siehe: [[‎STM32F10x Standard Peripherals Library]].&lt;br /&gt;
&lt;br /&gt;
Mit [http://www.libopencm3.org/wiki/Main_Page libopencm3] ist derzeit auch eine Open-Source Alternative (GPL, Version 3 oder höher) zur ST Library in Entwicklung, die zukünftig auch Cortex-M3 Controller von anderen Herstellern unterstützen soll.&lt;br /&gt;
&lt;br /&gt;
== CMSIS ==&lt;br /&gt;
&lt;br /&gt;
Parallel zur Firmware-Library (FW-Lib) gibt es für die &amp;quot;Selbermacher&amp;quot; die CMSIS (ARM® &#039;&#039;&#039;C&#039;&#039;&#039;ortex™ &#039;&#039;&#039;M&#039;&#039;&#039;icrocontroller &#039;&#039;&#039;S&#039;&#039;&#039;oftware &#039;&#039;&#039;I&#039;&#039;&#039;nterface &#039;&#039;&#039;S&#039;&#039;&#039;tandard), die grundsätzlich nur den herstellerübergreifenden ARM-Core abdeckt. Hierzu gehört bei den Cortex-M4-Cores auch die DSP und Floating-Point Funktionalität. Weiterhin existieren eine Zahl von Helferfunktionen für den NVIC, den Sys-Tick-Counter, sowie eine SystemInit-Funktion, welche sich um die PLL kümmert. &lt;br /&gt;
&lt;br /&gt;
Im Rahmen des CMSIS-Standards ([http://www.onARM.com www.onARM.com]) wurden die Headerdateien standardisiert, der Zugriff auf die Register erfolgt per &#039;&#039;&#039;Peripheral-&amp;gt;Register&#039;&#039;&#039;. Die CMSIS C-Dateien bzw. Header enthalten auch Anpassungen für die verschiedenen Compiler. Die Portierung eines Real-Time-Betriebsystems sollte unter Verwendung der CMSIS, für Chips der verschiedenen Hersteller, stark vereinfacht möglich sein (z.B. einheitliche Adressen für Core-Hardware/Sys-Tick-Counter).&lt;br /&gt;
&lt;br /&gt;
Die CMSIS ist im Download der FW-Lib enthalten. Die Compiler-Hersteller liefern eine jeweils zur ihrer Tool-Version passende bzw. geprüfte FW-Lib (incl. CMSIS) aus. Diese Libs können, gegenüber den Downloads beim Chip-Hersteller, auch ältere Version beinhalten.&lt;br /&gt;
&lt;br /&gt;
== Debug- und Trace-Interface (CoreSight™ Debug and Trace Technologie)==&lt;br /&gt;
&lt;br /&gt;
Übersicht über beide Funktionalitäten und den Schnittstellen:&lt;br /&gt;
http://www.keil.com/support/man/docs/ulink2/ulink2_cs_core_sight.htm&lt;br /&gt;
&lt;br /&gt;
Die Coresight-Debug-Architektur ermöglicht ein nicht-invasives Debugging, d.h. es können während des Betriebes (meistens) ohne Beeinflussung des Prozessors Daten vom Speicher gelesen und in selbigen geschrieben werden.&lt;br /&gt;
&lt;br /&gt;
=== Debugger Funktionen ===&lt;br /&gt;
&lt;br /&gt;
Der Debugger-Teil besitzt drei Funktionen:&lt;br /&gt;
* Run Control: z.B. Programm-Start, Stopp und Einzel-Schritte.&lt;br /&gt;
* (Program) Break Points: Ein Programm hält an, wenn der Programm Counter eine bestimmte Programm-Adresse erreicht.&lt;br /&gt;
** Beinhaltet keine Data Watch Funktionalität, welche im Trace-Teil (DWT) realisiert wird.&lt;br /&gt;
* Memory Access: Lesen und Schreiben von Speicheradressen. &lt;br /&gt;
** Diese Funktionalität beinhaltet keine direkte Flash-Programmierung. Der Programmiervorgang für einen Flash ist herstellerspezifisch und muss von dem verwendeten Debugger unterstützt werden.&lt;br /&gt;
&lt;br /&gt;
=== Trace Funktionen ===&lt;br /&gt;
Die Trace-Funktionalität wird in drei Funktionen aufgeteilt:&lt;br /&gt;
* ETM (Embedded Trace Macrocell): Optional, nicht jede CPU besitzt diese Hardware (Kostenfaktor, Austattung).&lt;br /&gt;
* ITM (Instrumentation Trace Macrocell): Über diesen Kanal kann ein vereinfachtes Trace des Core ermöglicht werden, sowie &amp;quot;printf-ähnlich&amp;quot; Daten über den ITM Channel 0 geschickt und im Debugger ausgegeben werden.&lt;br /&gt;
* DWT (Data Watchpoint &amp;amp; Trace Unit): &lt;br /&gt;
** Data Watch: 4 Access-Break-Points ( z.B. der Debugger bleibt stehen, wenn das Programm auf einen Speicher zugreift oder der Wert einer Variablen einen bestimmten Wert annimmt). &lt;br /&gt;
** Trace Unit: Programmverlauf (durch Lesen des Program Counters) und Interrupt Aufrufe verfolgen, sowie Zeitmessungen.&lt;br /&gt;
&lt;br /&gt;
Einige der Trace-Funktionalitäten können über die JTAG-Schnittstelle angesprochen werden. Die schnelle Trace-Funktionalität (mit 4 bit Parallel-Port) steht nur mit der erweiterten DEBUG + ETM Schnittstelle zur Verfügung. Im Gegensatz zum Debugger-Teil (Run Control, Break Points und Memory Access) werden Trace-Funktionen nicht von allen Debuggern unterstützt. Debugger mit der vollen Trace-Funktionalität kosten deutlich mehr.&lt;br /&gt;
&lt;br /&gt;
* Beispiele für Trace-Port-Aktivierungen für verschiedene Hersteller: http://www.keil.com/support/man/docs/jlink/jlink_capture_tracedata.htm&lt;br /&gt;
&lt;br /&gt;
Die Aktivierung des parallelen Trace-Ports erfordert, je nach CPU Hersteller, zusätzliche Debugger-Makros für die Aktivierung und Port-Freischaltung. Zusätzlich sind die Schnittstellenauswahl und Einstellung (Frequenzen) im Entwicklungs-Tool (IDE) wichtig, um erfolgreich den Programm-Verlauf &amp;quot;tracen&amp;quot; zu können.&lt;br /&gt;
&lt;br /&gt;
=== Debug und Trace-Schnittstellen ===&lt;br /&gt;
Als Debug Interface stehen zwei Varianten zur Auswahl:&lt;br /&gt;
* [[JTAG]]: Dafür sind mindestens 6 Steuerleitungen nötig.   &lt;br /&gt;
* SWD (Serial Wire Debug): Hier mindestens 2  Steuerleitungen (3 mit SWO, zzgl GND und 3,3V). Die SWD Schnittstelle ist in der Regel schneller und kann auch Funktionen aus dem Trace-Teil beinhalten (z.B. ITM, dafür wird der SWO-Pin benötigt).&lt;br /&gt;
&lt;br /&gt;
Standard-JTAG Steckerbelegungen: &lt;br /&gt;
http://www.keil.com/support/man/docs/ulink2/ulink2_hw_connectors.htm&lt;br /&gt;
&lt;br /&gt;
=== Der 10polige JTAG-Stecker von mmvisual ===&lt;br /&gt;
mmvisual hat mit dieser Steckerbelegung die Standard JTAG Schnittstelle erweitert:&lt;br /&gt;
&lt;br /&gt;
Ich habe diesen Part in den Artikel [http://www.mikrocontroller.net/articles/JTAG#Der_10-Polige_JTAG_Stecker_von_mmvisual JTAG] verschoben.&lt;br /&gt;
Hinzu gekommen ist die Adapterplatine 10-Polig auf Standard JTAG 20 Polig mit TTL/V24 Wandler. [http://www.mikrocontroller.net/articles/JTAG#Die_Adapterplatine Siehe hier.]&lt;br /&gt;
&lt;br /&gt;
=== STM32 RS232 (CAN und USB) Programmiertool ===&lt;br /&gt;
&lt;br /&gt;
Auch ohne JTAG lässt sich ein STM32 programmieren (Bootloader-Aktivierung). Dabei stehen, je nach CPU-Typ, verschiedene Möglichkeiten zur Verfügung:&lt;br /&gt;
* RS-232 (bisher alle STMs)&lt;br /&gt;
* USB (nur in bestimmten MCUs mit entsprechender Bootloader-Version und PIN-Anzahl, z.B. STM32F105/107)&lt;br /&gt;
* CAN (wie USB nur in bestimmten MCUs)&lt;br /&gt;
&lt;br /&gt;
3 zusätzliche Verbindungen müssen auf dem Board gepatcht werden. Für einen Test geht es auch mit Tastern für RESET und BOOT0.&amp;lt;br&amp;gt;&lt;br /&gt;
RESET=RTS (L-aktiv)&amp;lt;br&amp;gt;&lt;br /&gt;
BOOT0=DTR (H-aktiv)&amp;lt;br&amp;gt;&lt;br /&gt;
BOOT1=LOW&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Details sind hier im Forum: [http://www.mikrocontroller.net/topic/141711 STM32 Programmiertool]&lt;br /&gt;
&lt;br /&gt;
== Vorteile ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber ARM7:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Interrupt-Controller jetzt Teil des Prozessors (als Core Peripheral), die Vector Table ist jetzt eine echte Vektortabelle, keine Sprungliste wie bei ARM7. Durch Automatismen zwischen Core und NVIC (auto register save r0..r3, lr, sp, pc) bei Interrupt Entry wird eine deutlich schnellere Ausführungszeit bei Interrupts erreicht. Der Interrupt Code muss sich nicht mehr selbst um die Sicherung der o.g. Register kümmern und eine besondere Konfiguration der Handler im Compiler entfällt. Sind vor Beendigung einer ISR (d.h. Rücksprung zum User Code) weitere Interrupts pending, so werden diese ausgeführt, ohne dass eine komplette pop-push-sequenz der Register notwendig ist. Schön beschrieben ist es hier im [http://www.st.com/mcu/files/mcu/1221142709.pdf Insider&#039;s Guide] unter 2.4.5 / Seite 20.&lt;br /&gt;
* Thumb-2 Befehlssatz, deutlich schneller als Thumb-1 und ebenso kompakt&lt;br /&gt;
* Weniger Pins für Debugging benötigt durch SWD&lt;br /&gt;
* Mehr Hardware Breakpoints machen debuggen einfacher&lt;br /&gt;
* Software ist einfacher weil die Umschaltung zwischen ARM Mode und Thumb Mode wegfällt&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber LPC1700 und LPC1300:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Flexiblere Gehäuseformen mit mehr Peripherie bei kleinen Gehäusen&lt;br /&gt;
* FW-Lib für alle STM32 gleich, alle AppNotes/Demos beziehen sich auf diese eine FW-Lib was die Entwicklung der eigenen Applikation sehr beschleunigt.&lt;br /&gt;
* Genauerer und flexiblerer ADC, insbesondere gegenüber LPC1300&lt;br /&gt;
* Flexiblere Varianten der Peripherie &amp;gt;&amp;gt; bei weniger einen deutlichen Preisvorteil&lt;br /&gt;
* ab 0,85 EUR (Stand 2010) Allerdings gibts den LPC1100 mit Cortex-M0 schon ab 0,65 $!&lt;br /&gt;
&#039;&#039;&#039;Nachteil gegenüber LPC1700:&#039;&#039;&#039;&lt;br /&gt;
* STM32F1xx: nur 72 MHz statt 100 MHz (LPC1759: 120 MHz) Taktfrequenz; STM32F2xx hat diesen Nachteil nicht (ebenfalls 120MHz, STM32F4xx mit 168MHz) (Aber NXP hat schon 150MHz angekündigt)&lt;br /&gt;
* Der LPC1700 besitzt deutlich mehr Mechanismen, um die Auswirkung der Waitstates des Flash-ROMs auf Code- und Datenzugriffe zu reduzieren und das bedeutet mehr Performance bei gleicher Taktfrequenz. Beim STM32F2 entfällt dieser Nachteil wohl aufgrund des ART accelerators. &lt;br /&gt;
* Alle LPC1xxx haben 32 Bit Timer. Bei den STM32 haben das nur die STM32F2xx (2 Stück)&lt;br /&gt;
* I2S Einheit von ST hat keinen FIFO und im 24/32Bit Modus müssen 2x16Bit Halbwörter übertragen werden.&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber anderen &amp;quot;Kleinen&amp;quot; wie z.B. PIC, Atmel usw.&#039;&#039;&#039;&lt;br /&gt;
* nahezu gleicher Preis bei Hobby Anwendungen&lt;br /&gt;
* 32 Bit ohne Umwege in Assembler rechenbar&lt;br /&gt;
* bessere Peripherie&lt;br /&gt;
* ... und weitere 1000 Punkte ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteil für Hobby-Anwender&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Nicht direkt &amp;quot;Steckbrettauglich&amp;quot;, da kein DIL Gehäuse verfügbar. Der ebay-Shop dipmicro führt jedoch sehr günstige Lötadapter für Umsetzung von LQFP48 auf DIP48. QFP64 in 0.5mm Pinabstabd und nicht 0.8mm wie AVR&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Hardware-Beschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der STM32 benötigt für den Betrieb nur (Minimalbeschaltung):&lt;br /&gt;
&lt;br /&gt;
* VCC 2..3,3V (je nach Typ)&lt;br /&gt;
* AVCC 2..3,3V (sehr wichtig, der STM32 lässt sich ohne diese Spannung nicht programmieren)&lt;br /&gt;
* GND&lt;br /&gt;
* Reset Pin 100nF nach GND (ein Pull-Up Widerstand von ca. 40k ist intern vorhanden)&lt;br /&gt;
* Boot-Pins: Boot0 -&amp;gt; GND | Boot1 -&amp;gt; Egal ---&amp;gt; Mit der Konfiguration wird kein Bootloader gestartet&lt;br /&gt;
&lt;br /&gt;
ansonsten nur ein paar einzelne Cs 100nF an VCC/GND.&lt;br /&gt;
&lt;br /&gt;
Um Programmieren zu können wird entweder noch die serielle Schnittstelle (Programmieren über den vorprogrammierten Bootloader) oder JTAG oder die SWD Schnittstelle benötigt.&lt;br /&gt;
&lt;br /&gt;
== Programmierung ==&lt;br /&gt;
&lt;br /&gt;
Als Programmieroberfläche kann eine kostenlose Struktur verwendet werden. Es ist für den Einsteiger schwierig herauszufinden welche Open-Source Programme man braucht damit es funktioniert, daher hier eine Zusammenstellung:&lt;br /&gt;
&lt;br /&gt;
* [http://www.eclipse.org Eclipse]&lt;br /&gt;
* [http://www.yagarto.de Yagarto Tools] oder [http://www.codesourcery.com/sgpp/lite_edition.html Codesourcery Lite Edition] oder [https://launchpad.net/gcc-arm-embedded Launchpad]&lt;br /&gt;
* Programmieradapter OOCD, Turtelizer2 oder andere JTAG Programmieradapter&lt;br /&gt;
* Eclipse Plugin &amp;quot;GDB Hardware Debugging&amp;quot; mit [http://www.firefly-power.de/ARM/debugging.html OpenOCD server]&lt;br /&gt;
* [http://www.st.com/internet/com/software/ides_mcu.jsp#stm32 ST Liste: IDEs, Toolsets and Debug tools for MCUs]&lt;br /&gt;
&lt;br /&gt;
* Zum Starten eine fertige Zusammenstellung: [http://www.mikrocontroller.net/topic/216554 Eclipse+codesourcery+st-link]&lt;br /&gt;
&lt;br /&gt;
* [http://www.coocox.org/ Coocox Eclipse IDE] kostenlose IDE für Cortex M0/M3. Hilfreiche Infos gibt es im [http://www.mikrocontroller.net/topic/214719?goto=new#2228482 hier] und [http://www.mikrocontroller.net/topic/214719?goto=new#2229943 hier] Forum&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/265600 STM32F4 mit Code::Blocks]&lt;br /&gt;
&lt;br /&gt;
* [http://emide.org/ emIDE] kostenlose IDE die mit dem Segger J-LINK funktioniert.&lt;br /&gt;
&lt;br /&gt;
Sehr nützlich für Linux-Anwender auch diese Seite: [http://fun-tech.se/stm32/index.php STM32/ARM Cortex-M3 HOWTO: Development under Ubuntu.]&lt;br /&gt;
&lt;br /&gt;
Folgende kommerzielle Umgebungen sind verfügbar:&lt;br /&gt;
&lt;br /&gt;
* [http://www.keil.com Keil µVision] (Demo max. 32KB Code): Die sehr komfortable µVison IDE ist neben dem ARM Compiler per Menue auch für einen beliebigen GNU-Compiler konfigurierbar. Damit besteht das 32k-Limit nur noch für den integrierten Debugger / Simulator. µVison selbst kann kostenlos mit dem MDK-Evaluationkit heruntergeladen werden.&lt;br /&gt;
* [http://www.iar.com IAR] (Demo max. 32KB Code)&lt;br /&gt;
* [http://www.raisonance.com Raisonance Ride7] (GCC Compiler, kostenlose Version auf Debugging von max. 32KB Code limitiert, keine Limitierung beim Complilieren)&lt;br /&gt;
* [http://www.atollic.com Atollic] (Lite Version (bis V2.3.0) ohne Code-Limit, auf GCC basierend. Die neueste Version ab V3 hat fast keine Beschränkungen mehr außer jetzt einen Code-Limit von 32kB. Außerdem werden jetzt die meisten ARM Familien unterstützt. )&lt;br /&gt;
* [http://www.coocox.org CoIDE] (Kostenlose GCC, Eclipse basierende IDE mit einem Code-Generator Tool)&lt;br /&gt;
* [http://www.rowley.co.uk/arm/ Rowley Crossworks] (Demo 30 Tage unbeschränkt, 150$ für nichtkommerzielle Nutzung, auf GCC basierend)&lt;br /&gt;
* [http://www.code-red-tech.com Code Red] (GCC basierend)&lt;br /&gt;
&lt;br /&gt;
Programmieradapter&lt;br /&gt;
* [http://www.segger.com J-Link / J-Trace] Cortex-M3, als [http://www.segger.com/cms/j-link-edu.html NonComercial] J-Link für ca. 60,- zu haben, läuft in µVision, IAR, gdb&lt;br /&gt;
* [http://olimex.com/dev/index.html Olimex] ARM-USB-OCD (ca. 60.-)&lt;br /&gt;
* Keil [http://www.keil.com/arm/ulink2/ ULINK2], [http://www.keil.com/arm/ulinkpro/ ULINK pro]&lt;br /&gt;
* [http://www.st.com/internet/evalboard/product/219866.jsp ST-LINK], [http://www.st.com/internet/evalboard/product/251168.jsp ST-LINK/V2]&lt;br /&gt;
*[http://www.st.com/internet/com/press_release/p3065.jsp STM32xx Discovery] jedes STM32 Discovery board hat einen ST-Link für Programmierung/Debugging per SWD on-board, welcher auch für eigene STM32 Target Hardware benutzt werden kann (ca. 12,- bis 19,-€, je nach Typ).&lt;br /&gt;
* [http://www.raisonance.com/~rlink-debugger-programmer__microcontrollers__tool~tool__T018:4cn9ziz4bnx6.html Raisonance RLink]&lt;br /&gt;
* [http://www.amontec.com Amontec]&lt;br /&gt;
* [http://www.hjtag.com H-JTAG] Personal Edition für ca. 60,- zu haben, läuft mit ADS, SDT, IAR, Vision und RVDS &lt;br /&gt;
&lt;br /&gt;
Programmieradapter Open-Source&lt;br /&gt;
* [http://www.oocdlink.com/ OOCDLink]&lt;br /&gt;
* [https://github.com/texane/stlink Stlink]&lt;br /&gt;
* [http://www.randomprojects.org/wiki/Floss-JTAG FLOSS-JTAG]&lt;br /&gt;
* [http://capitanio.org/mlink/ Linux Demo Code für die Discovery&#039;s ST-Link Programmierung]&lt;br /&gt;
&lt;br /&gt;
Der Controller hat auch einen fest eingebauten Boot-Lader. Damit läßt er sich auch über eine gewöhnliche serielle Schnittstelle programmieren, ohne daß man einen JTAG-Adapter benötigt.&lt;br /&gt;
&lt;br /&gt;
Tipps für Installation mit Eclipse können in [http://www.mikrocontroller.net/topic/214719 diesem Thread] gelesen werden.&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 (Linux) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Variante A ====&lt;br /&gt;
&lt;br /&gt;
* Benötigte Hardware&lt;br /&gt;
** Ein Desktop PC oder Laptop mit Linux OS (openSuSE, Ubuntu, ...) alternativ: Ein Windows System mit Linux in einer virtuellen Maschine &lt;br /&gt;
** root Zugang zum Linux OS (superuser Passwort)&lt;br /&gt;
** GNU C Compiler&lt;br /&gt;
** Programmer ARM-USB-TINY-H (optimal) alternativ: OpenOCD kompatiblen Programmer&lt;br /&gt;
** Prototypboard Olimex STM32-P107 (optimal) alternativ: irgendein board mit STM32 uC und JTAG Port&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
* Download + Installation (in einem Terminal)&lt;br /&gt;
  wget http://hlb-labor.de/cortexm3/install_ToolChain_STM32.sh&lt;br /&gt;
  chmod +x install_ToolChain_STM32.sh&lt;br /&gt;
  ./install_ToolChain_STM32.sh&lt;br /&gt;
 &lt;br /&gt;
Die Installation sollte im Idealfall voll automatisch durchlaufen. Anschliessend wird ein Beispielprojekt mit Multitasking OS und LED-Heartbeat kompiliert und auf den uC programmiert.&lt;br /&gt;
Für andere Protoboards/ Programmer muss die ToolChain entsprechend der readme Anleitung umkonfiguriert werden.&lt;br /&gt;
&lt;br /&gt;
Das Projekt kann im QtCreator (http://qt.nokia.com/) geöffnet und bearbeitet werden.&lt;br /&gt;
&lt;br /&gt;
==== Variante B ====&lt;br /&gt;
&lt;br /&gt;
Die Installation einer Toolchain (Make, Flash, Debug via JTAG, IDE) ist in folgendem Manual beschrieben:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;How-to manual - Installing a toolchain for Cortex-M3/STM32 on Ubuntu 10.04&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*http://www.seng.de/downloads/HowTo_ToolChain_STM32_Ubuntu.pdf&lt;br /&gt;
*http://www.seng.de/downloads/HowTo_ToolChain_STM32_Ubuntu.odt&lt;br /&gt;
&lt;br /&gt;
Die Beschreibung im OpenOffice Format erlaubt die Weiterbearbeitung des Textes und das Entnehmen von Quelltexten ohne den Verlust von Formatierungen.&lt;br /&gt;
&lt;br /&gt;
Verwendete Hardware:&lt;br /&gt;
*JTAG device&lt;br /&gt;
**Olimex “ARM-USB-OCD-H”, basierend auf FTDI “FT2232H”&lt;br /&gt;
*Microcontroller&lt;br /&gt;
**Olimex “STM32-H103” basierend auf STM32F103RBT6 mit 128KB Flash, 20KB RAM, 3xUART, ...&lt;br /&gt;
Die Toolchain sollte sich leicht an andere &amp;quot;FT2232&amp;quot; basierte JTAG Probes und &amp;quot;Cortex-M3&amp;quot; Derivate anpassen lassen.&lt;br /&gt;
&lt;br /&gt;
Das Manual umfasst die Installation und Inbetriebnahme sowie Hinweise und Bug-fixes zu folgenden Komponenten:&lt;br /&gt;
*OpenOCD&lt;br /&gt;
*stm32flash&lt;br /&gt;
*Sourcery CodeBench Lite for ARM EABI&lt;br /&gt;
*STM32F10x standard peripheral library&lt;br /&gt;
*Project templates&lt;br /&gt;
*Makefiles&lt;br /&gt;
*Linker Sript&lt;br /&gt;
*Startup Code&lt;br /&gt;
*Doxygen&lt;br /&gt;
*Git&lt;br /&gt;
*Terminal emulation&lt;br /&gt;
*Eclipse IDE&lt;br /&gt;
*Links zu Datenblättern, Manuals und Toools&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 (Windows) ===&lt;br /&gt;
&lt;br /&gt;
Hier ist der Anfang des Artikels [[STM32 Eclipse Installation]], hier ist neueres beschrieben als hier aufgeführt. Wenn der Artikel fertig ist, dann wird dieser Teil gelöscht.&lt;br /&gt;
&lt;br /&gt;
* Eclipse &amp;quot;Helios&amp;quot; installieren mit GNU ARM Eclipse Plug-in&lt;br /&gt;
Eclipse IDE for C/C++ Developers&amp;lt;ref&amp;gt;http://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/heliosr&amp;lt;/ref&amp;gt; downloaden und installieren&lt;br /&gt;
&lt;br /&gt;
* GNU ARM Eclipse Plug-in&amp;lt;ref&amp;gt;http://sourceforge.net/projects/gnuarmeclipse/&amp;lt;/ref&amp;gt; runterladen und installieren. [http://sourceforge.net/apps/mediawiki/gnuarmeclipse/index.php?title=Main_Page Weitere Infos].&lt;br /&gt;
&lt;br /&gt;
Wird CodeSourcery G++ Lite verwendet, so muss die PATH Variable angepasst &lt;br /&gt;
werden, damit das Plugin die CodeSourcery exe-Files findet&amp;lt;ref&amp;gt;für Discovery notwendig&amp;lt;/ref&amp;gt;. Alternativ das eclipse von einem script aus starten und zuerst den PATH erweitern.&lt;br /&gt;
&lt;br /&gt;
Soll das ST-LINK verwendet werden, so kann der Atollic ST-LINK GDBSERVER aus der Atollic free version genutzt werden. Mit dem gdbclient im Eclipse kann damit problemlos geflasht und gedebuggt werden (JTAG und SWD). &lt;br /&gt;
&lt;br /&gt;
Neuere Versionen von OpenOCD können ebenfalls mit STLINK und STLINK2 Kontakt aufnehmen. Bei vorkompilierten OpenOCD-Packeten (z.B. die von Freddy Chopin) mit libusb-Support und installiertem Herstellertreiber von STM ist noch der libusb-Filtertreiber einzurichten (relativ einfach per libusb-win32 filter wizard GUI).&lt;br /&gt;
&lt;br /&gt;
Die Startup- und Linkerscripts der Atollic free version können für ein Projekt in dieser Konstallation genutzt werden.&lt;br /&gt;
&lt;br /&gt;
* Eclipse &amp;quot;Galileo&amp;quot; installation&amp;lt;ref&amp;gt;[http://www.eclipse.org/] → Downloads → &amp;quot;Eclipse IDE for C/C++ Developers (79 MB)&amp;lt;/ref&amp;gt;. Und das Servicepack 1&amp;lt;ref&amp;gt;[http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo/SR1/eclipse-cpp-galileo-SR1-win32.zip Eclipse SR1]&amp;lt;/ref&amp;gt;&lt;br /&gt;
Entpacken der Datei eclipse-cpp-galileo-SR1-win32.zip nach &amp;quot;C:\WinARM\&amp;quot; (Ordner neu erstellen)&lt;br /&gt;
&lt;br /&gt;
* Eclipse PlugIn&amp;lt;ref&amp;gt;http://download.eclipse.org/tools/cdt/releases/galileo&amp;lt;/ref&amp;gt; hinzufügen: Help → Install New Software... → &amp;quot;Eclipse C/C++ Development Tools&amp;quot; + &amp;quot;Eclipse C/C++ GDB Hardware Debugging&amp;quot; installieren&lt;br /&gt;
&lt;br /&gt;
* Yagarto Tools&amp;lt;ref&amp;gt;[http://www.yagarto.de/] &amp;quot;Download (for Windows)&amp;quot; → &amp;quot;YAGARTO Tools&amp;quot; http://www.yagarto.de/download/yagarto/yagarto-tools-20091223-setup.exe Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\yagarto-tools&amp;quot;&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CodeSourcery: Achtung! Die Menustruktur ändert sich durchaus mal, dann suchen gehen. http://www.codesourcery.com/ → Products → Sourcery G++ → Editions&amp;gt;Lite Edition → ARM → Downloads. Direkter Download&amp;lt;ref&amp;gt;[http://www.codesourcery.com/sgpp/lite/arm/portal/package6496/public/arm-none-eabi/arm-2010q1-188-arm-none-eabi.exe]&amp;lt;/ref&amp;gt;. Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\CodeSourcery&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* OpenOCD: Kompilierte Version für Windows&amp;lt;ref&amp;gt;[http://www.freddiechopin.info/] → Download → Software → OpenOCD&amp;lt;/ref&amp;gt; installieren nach &amp;quot;C:\WinARM\OpenOCD_0_4_0&amp;quot; ist auch auf der Seite&amp;lt;ref&amp;gt;[http://yagarto.de/#ocd Yagarto.de]&amp;lt;/ref&amp;gt; beschrieben. PS: Sollte der Olimex ARM-USB-OCD verwendet werden, dann darf nicht der Treiber von Olimex verwendet werden, sondern der vom OpenOCD Download&amp;lt;ref&amp;gt;[http://www.mikrocontroller.net/topic/173753#1668913]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* ST Firmware: http://www.st.com → Auswahl CPU STM32F103xxx → &amp;quot;Firmware&amp;quot; &amp;quot;STM32F10x_StdPeriph_Lib&amp;quot;&amp;lt;ref&amp;gt;http://www.st.com/mcu/devicedocs-STM32F103RC-110.html&amp;lt;/ref&amp;gt;. Das ZIP &amp;quot;stm32f10x_stdperiph_lib.zip&amp;quot; Entpacken nach &amp;quot;C:\WinARM\examples\stm32_FW3.4.0\&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 auf einem zweiten Rechner===&lt;br /&gt;
&lt;br /&gt;
* Kopieren des Verzeichnisses C:\WinARM\ (Zuvor wurden aus diesem Grund alle Setup-Pakete nach C:\WinARM\... installiert)&lt;br /&gt;
* Die PATH-Variable in der Systemsteuerung mit den C:\WinARM\.... Verzeichnissen nachführen&lt;br /&gt;
* Fertig.&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 mit AtollicTrueStudio (+Demo) ===&lt;br /&gt;
* Installation + Demo: [[STM32 LEDBlinken AtollicTrueStudio]]&lt;br /&gt;
&lt;br /&gt;
== Demo-Projekte ==&lt;br /&gt;
&lt;br /&gt;
* [[prog_bsp_timer_1_timer2|Programmbeispiel für die Verwendung von Timer2 zusammen mit dem Interrupt]]&lt;br /&gt;
* [http://www.firefly-power.de/ARM/printf.html Printf() debugging mit minimalem Aufwand]&lt;br /&gt;
* [[STM32_BLDC_Control_with_HALL_Sensor|Programmbeispiel für BLDC Motoransteuerung (Timer 1) mit HALLSensor (Timer 3)]]&lt;br /&gt;
* [[Cortex_M3_OCM3U]]&lt;br /&gt;
* Martin Thomas hat ein umfangreiches Projekt erstellt, in der die Eclipse Einstellungen enthalten sind:&lt;br /&gt;
** [http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html &amp;quot;ChaN&#039;s FAT-Module with STM32 SPI&amp;quot;]&lt;br /&gt;
* [[STM32 USB-FS-Device Lib]]&lt;br /&gt;
* Modellbau-Sender auf STM32-Basis mit vielen Treibern [http://www.rcos.eu www.rcos.eu]&lt;br /&gt;
* Ausführliches [https://github.com/jkerdels/stm32edu Einstiegs-Tutorial] in Codeform für das [http://www.st.com/internet/evalboard/product/252419.jsp STM32F4 discovery board]&lt;br /&gt;
&lt;br /&gt;
== Errata, Tipps und Tricks ==&lt;br /&gt;
&lt;br /&gt;
* AD-Wandler PA0: Im Errata steht, dass hier Fehler in der Wandlung entstehen könnten, also einen anderen Pin verwenden.&lt;br /&gt;
* CAN-Bus PD0/PD1: Remap geht erst ab der 100-Pin-Version. Steht im RM0008 unter 9.3.3.: &amp;quot;CAN1 alternate function remapping&amp;quot;. Alle Infos von RM0008 9.3.x sind interessant&lt;br /&gt;
* CAN und USB sind nur bei der &amp;quot;◦Connectivity-Line&amp;quot; gleichzeitig nutzbar. Siehe Datenblätter.&lt;br /&gt;
* Mit internem RC-Oszillator kann die CPU mit maximal 64MHz betrieben werden. Mit einem externen Quarz sind dann 72MHz möglich.&lt;br /&gt;
* Für USB Betrieb muss die CPU mit 48MHz oder 72MHz betrieben werden (bei STM32F1xx).&lt;br /&gt;
* Der Idle Interrupt vom Usart wird zwar ausgelöst, aber nicht vom entsprechenden Statusflag angezeigt&lt;br /&gt;
* Der DMA fängt beim aktivieren immer von vorn an zu zählen, auch wenn er nur kurz angehalten wurde&lt;br /&gt;
* STM32F2xx hat kein Flash Size Register, bei STM32F4xx ist zwar ein flash Size Register beschrieben, kollidiert aber in der Adresse mit einem anderen Register&lt;br /&gt;
* Derivate mit internem EEPROM und nur einer Speicherbank haben das &amp;quot;Feature&amp;quot; bei write/erase des Data-Flashes (EEPROM) einen kompletten stall der code execution zu verursachen (inkl. ISR&#039;s, DMA). Desgleichen bei write/erase des internen Flash (ISP-routinen, EEPROM-Emulation).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Tipps für Umsteiger von Atmel/PIC/8051 ===&lt;br /&gt;
* Prozessortakt hat unterschiedliche Taktquellen und eine PLL.&lt;br /&gt;
* Alle Peripheriemodule haben einen extra Clock, den man aktivieren muss.&lt;br /&gt;
* Wenn man z.B. einen UART benutzen möchte, so muss man den Clock vom UART, Alternate Function IO (AFIO) und dem GPIO-Port aktivieren.&lt;br /&gt;
* Ansonsten hat man nahezu doppelt so viele Möglichkeiten in den Peripheriemodulen.&lt;br /&gt;
* Interrupt-Flags müssen in der ISR selber gelöscht werden&lt;br /&gt;
* Forum zu [http://www.mikrocontroller.net/topic/175888 Interrupts vs. Events]&lt;br /&gt;
&lt;br /&gt;
=== Tipp FPU von STM32F4xx nutzen ===&lt;br /&gt;
Es benötigt dafür 2 Dinge, zum einen muss die Compileroption gesetzt sein, zum anderen auch die FPU aktiviert werden:&lt;br /&gt;
&lt;br /&gt;
Compileroption:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;COMMON_FLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Code für das Aktivieren der FPU:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;/*FPU settings*/&lt;br /&gt;
__asm volatile (&amp;quot;ldr     r0, =0xE000ED88&amp;quot;);           /* Enable CP10,CP11 */&lt;br /&gt;
__asm volatile (&amp;quot;ldr     r1,[r0]&amp;quot;);&lt;br /&gt;
__asm volatile (&amp;quot;orr     r1,r1,#(0xF &amp;lt;&amp;lt; 20)&amp;quot;);&lt;br /&gt;
__asm volatile (&amp;quot;str     r1,[r0]&amp;quot;);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ohne Inline-Assembler in C wie in system_stm32f4xx.c aus den Beispielen von ST-Microelectronics:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2)); /* set CP10 and CP11 Full Access */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weiterhin sollte die Toolchain auch Laufzeitbibliotheken mit FPU-Unterstützung mitbringen (CodeBench lite wird ohne ausgeleifert, GCC for ARM embedded von launchpad.org mit).&lt;br /&gt;
&lt;br /&gt;
Mehr dazu in diesem Thread: [http://www.mikrocontroller.net/topic/261021 Floating Pointing Unit STM32F4]&lt;br /&gt;
&lt;br /&gt;
=== Errata vom STM32F4xx die nicht im Errata von ST stehen ===&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/267439#2788478 Aktivieren von DMA], wenn mehr als 3 DMA Kanäle aktiviert werden, kann es sein dass die nicht alle korrekt bedient werden. Auch klappt der DMA mit dem FSMC nicht immer zuverlässig. [https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FWarning%20limit%20simultaneous%20DMAs%20to%202&amp;amp;FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&amp;amp;currentviews=811 siehe hier] [http://blog.frankvh.com/2012/01/13/stm32f2xx-stm32f4xx-dma-maximum-transactions/ und hier]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/260637#2700761 Nerviger Bug in &amp;quot;stm32f4xx.h&amp;quot;] Änderung Struktur GPIO_TypeDef&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/261690#2714754 Batterie wird leer gezogen], nur bei manchen Chips mit Rev. A&lt;br /&gt;
&lt;br /&gt;
== Bezugsquellen ==&lt;br /&gt;
&lt;br /&gt;
=== Controller ===&lt;br /&gt;
&lt;br /&gt;
Versandhäuser für Privatpersonen&lt;br /&gt;
&lt;br /&gt;
* [http://darisusgmbh.de/shop/index.php?cat=c2692_ARM-Cortex.html Darisus]&lt;br /&gt;
* [http://www.hbe-shop.de HBE (Farnell Programm für Private)] &lt;br /&gt;
* [http://www.sander-electronic.de/be00069.html Sander]&lt;br /&gt;
* [http://www.rs-online.com RS-Online]&lt;br /&gt;
*[http://www.tme.eu/de/katalog/index.phtml#cleanParameters%3D1%26search%3DSTM32F10%26bf_szukaj%3D+ TME] &lt;br /&gt;
* [https://www.distrelec.de/ishopWebFront/catalog/product.do/para/keywords/is/STM32_ARM-Microcontroller/and/language/is/de/and/shop/is/DE/and/series/is/1/and/id/is/01/and/node/is/34910.html Distrelec]&lt;br /&gt;
&lt;br /&gt;
Gewerblich liefern natürlich viele wie Mouser, Farnell, Digikey usw...&lt;br /&gt;
&lt;br /&gt;
=== Evaluation Boards ===&lt;br /&gt;
&lt;br /&gt;
* [http://shop.embedded-projects.net/index.php?module=artikel&amp;amp;action=gruppe&amp;amp;id=14 Im Shop von Embedded Projects]&lt;br /&gt;
* [http://www.watterott.com/de/Boards-Kits/ARM/ARM-Cortex-M3 Cortex M3 bei Watterott]&lt;br /&gt;
* [http://www.raisonance.com/~primer-starter-kits__microcontrollers__tool~tool__T018:4enfvamuxbtp.html Primer und Primer2 von Raisonance]&lt;br /&gt;
* [http://www.sander-electronic.de/es0028.html Sander Electronic]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/MP32F103-Stick:_Ein_Mini-Mikrocontroller-Board_mit_USB_und_bis_zu_4MB_Datenspeicher Artikel im Wiki, ARM mit USB und 4MB Speicher]&lt;br /&gt;
* [http://www.futurlec.com/STM32_Development_Board.shtml Futurlec Evalboard, ebenso Header-Board]&lt;br /&gt;
* [http://www.propox.com/products/t_174.html Propox, Header-Boards für 103R und 103V sowie Trägerplatine dafür]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/Cortex_M3_OCM3U Cortex M3 Artikel im Wiki]&lt;br /&gt;
* [http://olimex.com/dev/index.html STM32 bei Olimex]&lt;br /&gt;
* [http://de.farnell.com/jsp/displayProduct.jsp?sku=1824325&amp;amp;action=view&amp;amp;CMP=GRHS-1000962 STM32Discovery bei Farnell] Mikrocontroller Board (STM32F100RBT6B) mit onboard USB-Programming Interface für ca. 12,50€&lt;br /&gt;
* [http://www.de.rs-online.com/web/p/products/7458434/ STM32Discovery bei RS-Components] 12,65 € +MwSt.&lt;br /&gt;
* [http://www.segor.de/#Q=STM32 VL DISCOVERY] STM32 Discovery bei Segor&lt;br /&gt;
* [http://www.watterott.com/de/STM32F4Discovery STM32F4DISCOVERY] STM32F4 Cortex M4 Controller mit JTAG-Debugger auf der Platine bei Watterott für 16,66EUR.&lt;br /&gt;
* [http://www.steitec.net/ARM-Boards/ Steitec, STM32F103 Cortex M3 Board 34,80€]&lt;br /&gt;
* [http://www.mcu-raisonance.com/~open4-development-platform__microcontrollers__tool~tool__T018:g65gu6ghg2n.html/ Open 4 oder auch genannt Evo-Primer]&lt;br /&gt;
* [http://www.wayengineer.com/index.php?main_page=index&amp;amp;cPath=50_66&amp;amp;page=1&amp;amp;sort=3a WayEngineer]&lt;br /&gt;
&lt;br /&gt;
== Weblinks, Foren, Communities ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/173753 Diskussion zum Artikel]&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/mikrocontroller-elektronik?filter=ARM*+STM32*+Cortex* Suche im Forum]&lt;br /&gt;
* [https://my.st.com/public/STe2ecommunities/mcu/Lists/ARM%20CortexM3%20STM32/AllItems.aspx Forum auf der ST Homepage] &lt;br /&gt;
* [http://www.stm32circle.com/hom/index.php STM32 Community] &lt;br /&gt;
*[http://www.arm-forum.de Deutsches ARM-Forum]&lt;br /&gt;
*[http://joe-c.de/pages/posts/einstieg_mikrocontroller_stm32f103_101.php Einstieg:  STM32board mit Kamera (deutsch)] &lt;br /&gt;
* [http://www.ebv.com/fileadmin/products/Press_Print/Brochures/Product_Brochures/EBV_Cortex%20Collection_V2.pdf Übersicht der Cortex Prozessoren und deren Hersteller (nicht nur ST, von EBV)]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/258652 Tutorial]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
[[Kategorie:ARM]]&lt;br /&gt;
[[Kategorie:STM32| ]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=68011</id>
		<title>STM32</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=68011"/>
		<updated>2012-08-22T17:30:40Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* Tipp FPU von STM32F4xx nutzen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;STM32 ist ein Mikrocontroller-Familie von [http://www.st.com/mcu/inchtml-pages-stm32.html ST] mit einer 32-Bit [http://www.arm.com/products/processors/cortex-m/index.php ARM Cortex-M3/M4] CPU. Diese Architektur ist speziell für den Einsatz in Microcontrollern neu entwickelt und löst damit die bisherigen ARM7-basierten Controller weitestgehend ab. Den STM32 gibt es von ST in unzähligen Varianten mit variabler Peripherie und verschiedenen Gehäusegrößen und -formen. Durch die geringe Chipfläche des Cores ist es ST möglich, eine 32 Bit-CPU für weniger als 1&amp;amp;nbsp;€ anzubieten.&lt;br /&gt;
&lt;br /&gt;
[[Bild:stm32F103xc.png|thumb|right|340px|Blockdiagramm STM32F103xC/D/E]]&lt;br /&gt;
&lt;br /&gt;
== STM32-Familien ==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es sieben STM32-Familien:&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1588.jsp STM32F0]&lt;br /&gt;
** Cortex M0&lt;br /&gt;
** µC zum Einstieg&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1169.jsp STM32F1]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
*** Connectivity line&lt;br /&gt;
*** Performance line&lt;br /&gt;
*** USB Access line&lt;br /&gt;
*** Access Line&lt;br /&gt;
*** Value line &lt;br /&gt;
* [http://www.st.com/internet/mcu/product/250173.jsp STM32F2]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
** Wie die STM32F1 Serie, jedoch 120MHz, Camera-Interface, 32-Bit Timer, Crypto-Engine...&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1605.jsp STM32F3]&lt;br /&gt;
** ARM® Cortex™-M4-based STM32 F3, 72MHz&lt;br /&gt;
** DSP instructions and the floating point unit &lt;br /&gt;
** Fast 12-bit 5 MSPS and precise 16-bit sigma-delta ADCs&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1521.jsp STM32F4]&lt;br /&gt;
** Cortex M4&lt;br /&gt;
** ARM® Cortex™-M4-based STM32 F4, 168MHz&lt;br /&gt;
** DSP instructions and the floating point unit &lt;br /&gt;
* [http://www.st.com/mcu/inchtml-pages-stm32l.html STM32L]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
** Low Power &lt;br /&gt;
** mit LCD Treiber&lt;br /&gt;
* [http://www.st.com/mcu/inchtml-pages-stm32w.html STM32W]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
** RF-MCU &lt;br /&gt;
[http://www.st.com/internet/mcu/class/1734.jsp Hier eine Übersicht zum Auswählen eines STM32Fxxx]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features&#039;&#039;&#039;&lt;br /&gt;
* Cortex-M3 bzw. Cortex-M4 Kern in der STM32F4xx Serie&lt;br /&gt;
* 16KB ... 1MB  [[Flash-ROM]]&lt;br /&gt;
*  4KB ... 192KB [[Speicher#SRAM|SRAM]]&lt;br /&gt;
* 4KB [[Speicher#EEPROM|EEPROM]] (STM32L)&lt;br /&gt;
* 512 one-time programmable Bytes(STM32F2/4)&lt;br /&gt;
* [[IC-Gehäuseformen | Gehäuse]] 36 ... 176 Pins als QFN, LQFP und BGA&lt;br /&gt;
* Derzeit sind über &#039;&#039;&#039;250&#039;&#039;&#039; STM32 Derivate/Varianten verfügbar&lt;br /&gt;
* Bis 72MHz CPU-Takt, bis 120MHz beim STM32F2xx, bis 168 MHz beim STM32F4xx, wobei eine spezielle prefetch-hardware bis 120/168 MHz eine Geschwindigkeit erzielen soll, die 0 Wait-States entspricht. Der CPU-Takt wird über einen Multiplikator aus dem internen RC-Takt oder einem externen Quarz-Takt abgeleitet.&lt;br /&gt;
* Externes Businterface (nur bei Gehäusen ab 100 Pin und nur bei STM32F4, STM32F2 und STM32F1 Performance line)&lt;br /&gt;
* LCD Treiber für 8x40 Punkte (nicht beim STM32F2xx)&lt;br /&gt;
* Spannungsbereich 1,65 ... 3,6V, nur eine Betriebsspannung nötig&lt;br /&gt;
* Temperaturbereich bis 125 °C&lt;br /&gt;
* Bis zu 140 IOs, viele davon [[Pegelwandler|5V-tolerant]]&lt;br /&gt;
* Interner, kalibrierter RC-Oszillator mit 8MHz (16MHz bei STM32F2xx)&lt;br /&gt;
* Externer Quarz&lt;br /&gt;
* Real Time Clock mit eigenem Quarz und separater Stromversorgung&lt;br /&gt;
* Bis zu 16 [[Timer]], je Timer bis zu 4 IC/OC/PWM Ausgänge. Davon 2x Motion Control Timer (bei STM32F103xF/G)&lt;br /&gt;
* Systick Counter&lt;br /&gt;
* Bis zu 3 12-Bit [[AD-Wandler]] mit insgesamt 24 AD-Eingängen, integrierter [[Temperatursensor]], Referenzspannung Vrefint und VBatt Spannungsmessung (STM32F4xx)&lt;br /&gt;
* Bis zu 2 12-Bit [[DA-Wandler]]&lt;br /&gt;
* Bis zu 2 [[DMA]] Controller mit bis zu 12 Kanälen (16 beim STM32F2xx)&lt;br /&gt;
* Bis zu 2x [[I2C|I²C]]&lt;br /&gt;
* Bis zu 5x [[UART|USART]] mit LIN, IrDA und Modem Control (6 beim STM32F2xx)&lt;br /&gt;
* Bis zu 3x [[SPI]]&lt;br /&gt;
* Bis zu 2x [[I2S|I²S]]&lt;br /&gt;
* Bis zu 2x [[CAN]]&lt;br /&gt;
* Unique device ID register (96 Bits)&lt;br /&gt;
* RNG - Random Number Genrator (STM32F2xx)&lt;br /&gt;
* Cryptographic Processor (CRYP) (STM32F2xx)&lt;br /&gt;
* Hash Processor (HASH) (STM32F2xx)&lt;br /&gt;
* Kamera-Interface (DCMI) (STM32F2xx)&lt;br /&gt;
* [[USB]] 2.0 Full Speed / OTG&lt;br /&gt;
* [[USB]] 2.0 Hi Speed OTG mit extra PHY-Chip (STM32F2xx)&lt;br /&gt;
* SDIO Interface (z.B. SD-Card Reader)&lt;br /&gt;
* Ethernet&lt;br /&gt;
* Watchdog mit Window-Mode&lt;br /&gt;
* Jedes Peripheriemodul ist separat einschaltbar, wodurch sich erheblich [[Ultra low power|Strom sparen]] lässt&lt;br /&gt;
* [[JTAG]] und SWD (Serial Wire Debug) Interface&lt;br /&gt;
* Bis zu 6 Hardware-Breakpoints für Debuggen&lt;br /&gt;
* und vieles mehr . . .&lt;br /&gt;
&lt;br /&gt;
== Struktur der Dokumentation: ==&lt;br /&gt;
&lt;br /&gt;
Als Beispiel der Dokumentation soll stellvertretend der [http://www.st.com/mcu/devicedocs-STM32F103RC-110.html STM32F103RC] genannt werden. Die Seite von ST beinhaltet alle nötigen Informationen passend zu diesem Prozessor.&lt;br /&gt;
&lt;br /&gt;
Diese Dokumente von ST beschreiben den Controller:&lt;br /&gt;
&lt;br /&gt;
* [http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00191185.pdf  Datasheet STM32F103xC/D/E]&lt;br /&gt;
* [http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00171190.pdf  Reference Manual (RM0008)]&lt;br /&gt;
* [http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00228163.pdf  Cortex-M3 Programming Manual]&lt;br /&gt;
* [http://www.st.com/stonline/products/literature/pm/13259.pdf Flash Programming Reference]&lt;br /&gt;
&lt;br /&gt;
Im Datasheet sind die speziellen Eigenschaften einer bestimmten Modellreihe beschrieben und die exakten Daten und Pinouts aufgeführt. Die Peripheriemodule werden nur aufgeführt, nicht detailliert beschrieben. In der Referenz ist der gesamte Controller mit Peripheriemodulen im Detail beschrieben, gültig für eine STM32-Familie. Details zum Prozessorkern selbst und den nicht STM32-spezifischen mit dem Cortex-M3 Core assoziierten Modulen wie dem Interrupt-Controller und dem Systick-Timer findet man jedoch nicht dort, sondern im Cortex-M3 Manual. Wer nicht die ST Firmware-Library verwendet, der benötigt zusätzlich die Flash Programming Reference für die Betriebsart des Flash-ROMs, d.h. die frequenzabhängige Konfiguration der Waitstates. Hinzu kommen optionale Dokumente von ARM, die den [http://infocenter.arm.com/help/topic/com.arm.doc.ddi0337-/ Cortex-M3 Kern] / [http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0439c/index.html Cortex-M4 Kern] beschreiben. Hier gibt es den Opcode wenn man ihn in [http://infocenter.arm.com/help/topic/com.arm.doc.ddi0403-/ Assembler] programmieren möchte. Zusätzlich sollten auch die [http://www.st.com/stonline/products/literature/es/14732.pdf Errata Sheets] beachtet werden. Empfohlen sei auch die Appnote &amp;quot;[http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/CD00164185.pdf STM32F10xxx hardware development: getting started]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== ‎STM32F10x Standard Peripherals Library ==&lt;br /&gt;
&lt;br /&gt;
ST bietet eine umfangreiche Firmwarebibliothek, eine einzige Bibliothek für alle STM32 Derivate. Das ist der große Vorteil von ST (gibt es beispielsweise auf den Cortex-M3 Controllern von TI auch, ist teilweise in einem separaten ROM untergebracht). Einmal programmieren und in allen STM32 verwendbar. Alle Funktionen sind gekapselt in einfache Strukturen und Funktionsaufrufe. Somit muss man sich nicht selbst um die Peripherieregister kümmern. Diese Library und ihre Dokumentation setzen das grundlegende Verständnis der Funktion des jeweiligen Peripheriemoduls voraus, wie es die o.A. Referenz und diverse Appnotes vermitteln. Diese FW-Lib (Download von ST) ist ein MUSS für jeden, denn darin sind auch jede Menge Beispiele für alle Peripheriemodule. &lt;br /&gt;
&lt;br /&gt;
Details siehe: [[‎STM32F10x Standard Peripherals Library]].&lt;br /&gt;
&lt;br /&gt;
Mit [http://www.libopencm3.org/wiki/Main_Page libopencm3] ist derzeit auch eine Open-Source Alternative (GPL, Version 3 oder höher) zur ST Library in Entwicklung, die zukünftig auch Cortex-M3 Controller von anderen Herstellern unterstützen soll.&lt;br /&gt;
&lt;br /&gt;
== CMSIS ==&lt;br /&gt;
&lt;br /&gt;
Parallel zur Firmware-Library (FW-Lib) gibt es für die &amp;quot;Selbermacher&amp;quot; die CMSIS (ARM® &#039;&#039;&#039;C&#039;&#039;&#039;ortex™ &#039;&#039;&#039;M&#039;&#039;&#039;icrocontroller &#039;&#039;&#039;S&#039;&#039;&#039;oftware &#039;&#039;&#039;I&#039;&#039;&#039;nterface &#039;&#039;&#039;S&#039;&#039;&#039;tandard), die grundsätzlich nur den herstellerübergreifenden ARM-Core abdeckt. Hierzu gehört bei den Cortex-M4-Cores auch die DSP und Floating-Point Funktionalität. Weiterhin existieren eine Zahl von Helferfunktionen für den NVIC, den Sys-Tick-Counter, sowie eine SystemInit-Funktion, welche sich um die PLL kümmert. &lt;br /&gt;
&lt;br /&gt;
Im Rahmen des CMSIS-Standards ([http://www.onARM.com www.onARM.com]) wurden die Headerdateien standardisiert, der Zugriff auf die Register erfolgt per &#039;&#039;&#039;Peripheral-&amp;gt;Register&#039;&#039;&#039;. Die CMSIS C-Dateien bzw. Header enthalten auch Anpassungen für die verschiedenen Compiler. Die Portierung eines Real-Time-Betriebsystems sollte unter Verwendung der CMSIS, für Chips der verschiedenen Hersteller, stark vereinfacht möglich sein (z.B. einheitliche Adressen für Core-Hardware/Sys-Tick-Counter).&lt;br /&gt;
&lt;br /&gt;
Die CMSIS ist im Download der FW-Lib enthalten. Die Compiler-Hersteller liefern eine jeweils zur ihrer Tool-Version passende bzw. geprüfte FW-Lib (incl. CMSIS) aus. Diese Libs können, gegenüber den Downloads beim Chip-Hersteller, auch ältere Version beinhalten.&lt;br /&gt;
&lt;br /&gt;
== Debug- und Trace-Interface (CoreSight™ Debug and Trace Technologie)==&lt;br /&gt;
&lt;br /&gt;
Übersicht über beide Funktionalitäten und den Schnittstellen:&lt;br /&gt;
http://www.keil.com/support/man/docs/ulink2/ulink2_cs_core_sight.htm&lt;br /&gt;
&lt;br /&gt;
Die Coresight-Debug-Architektur ermöglicht ein nicht-invasives Debugging, d.h. es können während des Betriebes (meistens) ohne Beeinflussung des Prozessors Daten vom Speicher gelesen und in selbigen geschrieben werden.&lt;br /&gt;
&lt;br /&gt;
=== Debugger Funktionen ===&lt;br /&gt;
&lt;br /&gt;
Der Debugger-Teil besitzt drei Funktionen:&lt;br /&gt;
* Run Control: z.B. Programm-Start, Stopp und Einzel-Schritte.&lt;br /&gt;
* (Program) Break Points: Ein Programm hält an, wenn der Programm Counter eine bestimmte Programm-Adresse erreicht.&lt;br /&gt;
** Beinhaltet keine Data Watch Funktionalität, welche im Trace-Teil (DWT) realisiert wird.&lt;br /&gt;
* Memory Access: Lesen und Schreiben von Speicheradressen. &lt;br /&gt;
** Diese Funktionalität beinhaltet keine direkte Flash-Programmierung. Der Programmiervorgang für einen Flash ist herstellerspezifisch und muss von dem verwendeten Debugger unterstützt werden.&lt;br /&gt;
&lt;br /&gt;
=== Trace Funktionen ===&lt;br /&gt;
Die Trace-Funktionalität wird in drei Funktionen aufgeteilt:&lt;br /&gt;
* ETM (Embedded Trace Macrocell): Optional, nicht jede CPU besitzt diese Hardware (Kostenfaktor, Austattung).&lt;br /&gt;
* ITM (Instrumentation Trace Macrocell): Über diesen Kanal kann ein vereinfachtes Trace des Core ermöglicht werden, sowie &amp;quot;printf-ähnlich&amp;quot; Daten über den ITM Channel 0 geschickt und im Debugger ausgegeben werden.&lt;br /&gt;
* DWT (Data Watchpoint &amp;amp; Trace Unit): &lt;br /&gt;
** Data Watch: 4 Access-Break-Points ( z.B. der Debugger bleibt stehen, wenn das Programm auf einen Speicher zugreift oder der Wert einer Variablen einen bestimmten Wert annimmt). &lt;br /&gt;
** Trace Unit: Programmverlauf (durch Lesen des Program Counters) und Interrupt Aufrufe verfolgen, sowie Zeitmessungen.&lt;br /&gt;
&lt;br /&gt;
Einige der Trace-Funktionalitäten können über die JTAG-Schnittstelle angesprochen werden. Die schnelle Trace-Funktionalität (mit 4 bit Parallel-Port) steht nur mit der erweiterten DEBUG + ETM Schnittstelle zur Verfügung. Im Gegensatz zum Debugger-Teil (Run Control, Break Points und Memory Access) werden Trace-Funktionen nicht von allen Debuggern unterstützt. Debugger mit der vollen Trace-Funktionalität kosten deutlich mehr.&lt;br /&gt;
&lt;br /&gt;
* Beispiele für Trace-Port-Aktivierungen für verschiedene Hersteller: http://www.keil.com/support/man/docs/jlink/jlink_capture_tracedata.htm&lt;br /&gt;
&lt;br /&gt;
Die Aktivierung des parallelen Trace-Ports erfordert, je nach CPU Hersteller, zusätzliche Debugger-Makros für die Aktivierung und Port-Freischaltung. Zusätzlich sind die Schnittstellenauswahl und Einstellung (Frequenzen) im Entwicklungs-Tool (IDE) wichtig, um erfolgreich den Programm-Verlauf &amp;quot;tracen&amp;quot; zu können.&lt;br /&gt;
&lt;br /&gt;
=== Debug und Trace-Schnittstellen ===&lt;br /&gt;
Als Debug Interface stehen zwei Varianten zur Auswahl:&lt;br /&gt;
* [[JTAG]]: Dafür sind mindestens 6 Steuerleitungen nötig.   &lt;br /&gt;
* SWD (Serial Wire Debug): Hier mindestens 2  Steuerleitungen (3 mit SWO, zzgl GND und 3,3V). Die SWD Schnittstelle ist in der Regel schneller und kann auch Funktionen aus dem Trace-Teil beinhalten (z.B. ITM, dafür wird der SWO-Pin benötigt).&lt;br /&gt;
&lt;br /&gt;
Standard-JTAG Steckerbelegungen: &lt;br /&gt;
http://www.keil.com/support/man/docs/ulink2/ulink2_hw_connectors.htm&lt;br /&gt;
&lt;br /&gt;
=== Der 10polige JTAG-Stecker von mmvisual ===&lt;br /&gt;
mmvisual hat mit dieser Steckerbelegung die Standard JTAG Schnittstelle erweitert:&lt;br /&gt;
&lt;br /&gt;
Ich habe diesen Part in den Artikel [http://www.mikrocontroller.net/articles/JTAG#Der_10-Polige_JTAG_Stecker_von_mmvisual JTAG] verschoben.&lt;br /&gt;
Hinzu gekommen ist die Adapterplatine 10-Polig auf Standard JTAG 20 Polig mit TTL/V24 Wandler. [http://www.mikrocontroller.net/articles/JTAG#Die_Adapterplatine Siehe hier.]&lt;br /&gt;
&lt;br /&gt;
=== STM32 RS232 (CAN und USB) Programmiertool ===&lt;br /&gt;
&lt;br /&gt;
Auch ohne JTAG lässt sich ein STM32 programmieren (Bootloader-Aktivierung). Dabei stehen, je nach CPU-Typ, verschiedene Möglichkeiten zur Verfügung:&lt;br /&gt;
* RS-232 (bisher alle STMs)&lt;br /&gt;
* USB (nur in bestimmten MCUs mit entsprechender Bootloader-Version und PIN-Anzahl, z.B. STM32F105/107)&lt;br /&gt;
* CAN (wie USB nur in bestimmten MCUs)&lt;br /&gt;
&lt;br /&gt;
3 zusätzliche Verbindungen müssen auf dem Board gepatcht werden. Für einen Test geht es auch mit Tastern für RESET und BOOT0.&amp;lt;br&amp;gt;&lt;br /&gt;
RESET=RTS (L-aktiv)&amp;lt;br&amp;gt;&lt;br /&gt;
BOOT0=DTR (H-aktiv)&amp;lt;br&amp;gt;&lt;br /&gt;
BOOT1=LOW&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Details sind hier im Forum: [http://www.mikrocontroller.net/topic/141711 STM32 Programmiertool]&lt;br /&gt;
&lt;br /&gt;
== Vorteile ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber ARM7:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Interrupt-Controller jetzt Teil des Prozessors (als Core Peripheral), die Vector Table ist jetzt eine echte Vektortabelle, keine Sprungliste wie bei ARM7. Durch Automatismen zwischen Core und NVIC (auto register save r0..r3, lr, sp, pc) bei Interrupt Entry wird eine deutlich schnellere Ausführungszeit bei Interrupts erreicht. Der Interrupt Code muss sich nicht mehr selbst um die Sicherung der o.g. Register kümmern und eine besondere Konfiguration der Handler im Compiler entfällt. Sind vor Beendigung einer ISR (d.h. Rücksprung zum User Code) weitere Interrupts pending, so werden diese ausgeführt, ohne dass eine komplette pop-push-sequenz der Register notwendig ist. Schön beschrieben ist es hier im [http://www.st.com/mcu/files/mcu/1221142709.pdf Insider&#039;s Guide] unter 2.4.5 / Seite 20.&lt;br /&gt;
* Thumb-2 Befehlssatz, deutlich schneller als Thumb-1 und ebenso kompakt&lt;br /&gt;
* Weniger Pins für Debugging benötigt durch SWD&lt;br /&gt;
* Mehr Hardware Breakpoints machen debuggen einfacher&lt;br /&gt;
* Software ist einfacher weil die Umschaltung zwischen ARM Mode und Thumb Mode wegfällt&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber LPC1700 und LPC1300:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Flexiblere Gehäuseformen mit mehr Peripherie bei kleinen Gehäusen&lt;br /&gt;
* FW-Lib für alle STM32 gleich, alle AppNotes/Demos beziehen sich auf diese eine FW-Lib was die Entwicklung der eigenen Applikation sehr beschleunigt.&lt;br /&gt;
* Genauerer und flexiblerer ADC, insbesondere gegenüber LPC1300&lt;br /&gt;
* Flexiblere Varianten der Peripherie &amp;gt;&amp;gt; bei weniger einen deutlichen Preisvorteil&lt;br /&gt;
* ab 0,85 EUR (Stand 2010) Allerdings gibts den LPC1100 mit Cortex-M0 schon ab 0,65 $!&lt;br /&gt;
&#039;&#039;&#039;Nachteil gegenüber LPC1700:&#039;&#039;&#039;&lt;br /&gt;
* STM32F1xx: nur 72 MHz statt 100 MHz (LPC1759: 120 MHz) Taktfrequenz; STM32F2xx hat diesen Nachteil nicht (ebenfalls 120MHz, STM32F4xx mit 168MHz) (Aber NXP hat schon 150MHz angekündigt)&lt;br /&gt;
* Der LPC1700 besitzt deutlich mehr Mechanismen, um die Auswirkung der Waitstates des Flash-ROMs auf Code- und Datenzugriffe zu reduzieren und das bedeutet mehr Performance bei gleicher Taktfrequenz. Beim STM32F2 entfällt dieser Nachteil wohl aufgrund des ART accelerators. &lt;br /&gt;
* Alle LPC1xxx haben 32 Bit Timer. Bei den STM32 haben das nur die STM32F2xx (2 Stück)&lt;br /&gt;
* I2S Einheit von ST hat keinen FIFO und im 24/32Bit Modus müssen 2x16Bit Halbwörter übertragen werden.&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber anderen &amp;quot;Kleinen&amp;quot; wie z.B. PIC, Atmel usw.&#039;&#039;&#039;&lt;br /&gt;
* nahezu gleicher Preis bei Hobby Anwendungen&lt;br /&gt;
* 32 Bit ohne Umwege in Assembler rechenbar&lt;br /&gt;
* bessere Peripherie&lt;br /&gt;
* ... und weitere 1000 Punkte ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteil für Hobby-Anwender&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Nicht direkt &amp;quot;Steckbrettauglich&amp;quot;, da kein DIL Gehäuse verfügbar. Der ebay-Shop dipmicro führt jedoch sehr günstige Lötadapter für Umsetzung von LQFP48 auf DIP48. QFP64 in 0.5mm Pinabstabd und nicht 0.8mm wie AVR&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Hardware-Beschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der STM32 benötigt für den Betrieb nur (Minimalbeschaltung):&lt;br /&gt;
&lt;br /&gt;
* VCC 2..3,3V (je nach Typ)&lt;br /&gt;
* AVCC 2..3,3V (sehr wichtig, der STM32 lässt sich ohne diese Spannung nicht programmieren)&lt;br /&gt;
* GND&lt;br /&gt;
* Reset Pin 100nF nach GND (ein Pull-Up Widerstand von ca. 40k ist intern vorhanden)&lt;br /&gt;
* Boot-Pins: Boot0 -&amp;gt; GND | Boot1 -&amp;gt; Egal ---&amp;gt; Mit der Konfiguration wird kein Bootloader gestartet&lt;br /&gt;
&lt;br /&gt;
ansonsten nur ein paar einzelne Cs 100nF an VCC/GND.&lt;br /&gt;
&lt;br /&gt;
Um Programmieren zu können wird entweder noch die serielle Schnittstelle (Programmieren über den vorprogrammierten Bootloader) oder JTAG oder die SWD Schnittstelle benötigt.&lt;br /&gt;
&lt;br /&gt;
== Programmierung ==&lt;br /&gt;
&lt;br /&gt;
Als Programmieroberfläche kann eine kostenlose Struktur verwendet werden. Es ist für den Einsteiger schwierig herauszufinden welche Open-Source Programme man braucht damit es funktioniert, daher hier eine Zusammenstellung:&lt;br /&gt;
&lt;br /&gt;
* [http://www.eclipse.org Eclipse]&lt;br /&gt;
* [http://www.yagarto.de Yagarto Tools] oder [http://www.codesourcery.com/sgpp/lite_edition.html Codesourcery Lite Edition] oder [https://launchpad.net/gcc-arm-embedded Launchpad]&lt;br /&gt;
* Programmieradapter OOCD, Turtelizer2 oder andere JTAG Programmieradapter&lt;br /&gt;
* Eclipse Plugin &amp;quot;GDB Hardware Debugging&amp;quot; mit [http://www.firefly-power.de/ARM/debugging.html OpenOCD server]&lt;br /&gt;
* [http://www.st.com/internet/com/software/ides_mcu.jsp#stm32 ST Liste: IDEs, Toolsets and Debug tools for MCUs]&lt;br /&gt;
&lt;br /&gt;
* Zum Starten eine fertige Zusammenstellung: [http://www.mikrocontroller.net/topic/216554 Eclipse+codesourcery+st-link]&lt;br /&gt;
&lt;br /&gt;
* [http://www.coocox.org/ Coocox Eclipse IDE] kostenlose IDE für Cortex M0/M3. Hilfreiche Infos gibt es im [http://www.mikrocontroller.net/topic/214719?goto=new#2228482 hier] und [http://www.mikrocontroller.net/topic/214719?goto=new#2229943 hier] Forum&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/265600 STM32F4 mit Code::Blocks]&lt;br /&gt;
&lt;br /&gt;
* [http://emide.org/ emIDE] kostenlose IDE die mit dem Segger J-LINK funktioniert.&lt;br /&gt;
&lt;br /&gt;
Sehr nützlich für Linux-Anwender auch diese Seite: [http://fun-tech.se/stm32/index.php STM32/ARM Cortex-M3 HOWTO: Development under Ubuntu.]&lt;br /&gt;
&lt;br /&gt;
Folgende kommerzielle Umgebungen sind verfügbar:&lt;br /&gt;
&lt;br /&gt;
* [http://www.keil.com Keil µVision] (Demo max. 32KB Code): Die sehr komfortable µVison IDE ist neben dem ARM Compiler per Menue auch für einen beliebigen GNU-Compiler konfigurierbar. Damit besteht das 32k-Limit nur noch für den integrierten Debugger / Simulator. µVison selbst kann kostenlos mit dem MDK-Evaluationkit heruntergeladen werden.&lt;br /&gt;
* [http://www.iar.com IAR] (Demo max. 32KB Code)&lt;br /&gt;
* [http://www.raisonance.com Raisonance Ride7] (GCC Compiler, kostenlose Version auf Debugging von max. 32KB Code limitiert, keine Limitierung beim Complilieren)&lt;br /&gt;
* [http://www.atollic.com Atollic] (Lite Version (bis V2.3.0) ohne Code-Limit, auf GCC basierend. Die neueste Version ab V3 hat fast keine Beschränkungen mehr außer jetzt einen Code-Limit von 32kB. Außerdem werden jetzt die meisten ARM Familien unterstützt. )&lt;br /&gt;
* [http://www.coocox.org CoIDE] (Kostenlose GCC, Eclipse basierende IDE mit einem Code-Generator Tool)&lt;br /&gt;
* [http://www.rowley.co.uk/arm/ Rowley Crossworks] (Demo 30 Tage unbeschränkt, 150$ für nichtkommerzielle Nutzung, auf GCC basierend)&lt;br /&gt;
* [http://www.code-red-tech.com Code Red] (GCC basierend)&lt;br /&gt;
&lt;br /&gt;
Programmieradapter&lt;br /&gt;
* [http://www.segger.com J-Link / J-Trace] Cortex-M3, als [http://www.segger.com/cms/j-link-edu.html NonComercial] J-Link für ca. 60,- zu haben, läuft in µVision, IAR, gdb&lt;br /&gt;
* [http://olimex.com/dev/index.html Olimex] ARM-USB-OCD (ca. 60.-)&lt;br /&gt;
* Keil [http://www.keil.com/arm/ulink2/ ULINK2], [http://www.keil.com/arm/ulinkpro/ ULINK pro]&lt;br /&gt;
* [http://www.st.com/internet/evalboard/product/219866.jsp ST-LINK], [http://www.st.com/internet/evalboard/product/251168.jsp ST-LINK/V2]&lt;br /&gt;
*[http://www.st.com/internet/com/press_release/p3065.jsp STM32xx Discovery] jedes STM32 Discovery board hat einen ST-Link für Programmierung/Debugging per SWD on-board, welcher auch für eigene STM32 Target Hardware benutzt werden kann (ca. 12,- bis 19,-€, je nach Typ).&lt;br /&gt;
* [http://www.raisonance.com/~rlink-debugger-programmer__microcontrollers__tool~tool__T018:4cn9ziz4bnx6.html Raisonance RLink]&lt;br /&gt;
* [http://www.amontec.com Amontec]&lt;br /&gt;
* [http://www.hjtag.com H-JTAG] Personal Edition für ca. 60,- zu haben, läuft mit ADS, SDT, IAR, Vision und RVDS &lt;br /&gt;
&lt;br /&gt;
Programmieradapter Open-Source&lt;br /&gt;
* [http://www.oocdlink.com/ OOCDLink]&lt;br /&gt;
* [https://github.com/texane/stlink Stlink]&lt;br /&gt;
* [http://www.randomprojects.org/wiki/Floss-JTAG FLOSS-JTAG]&lt;br /&gt;
* [http://capitanio.org/mlink/ Linux Demo Code für die Discovery&#039;s ST-Link Programmierung]&lt;br /&gt;
&lt;br /&gt;
Der Controller hat auch einen fest eingebauten Boot-Lader. Damit läßt er sich auch über eine gewöhnliche serielle Schnittstelle programmieren, ohne daß man einen JTAG-Adapter benötigt.&lt;br /&gt;
&lt;br /&gt;
Tipps für Installation mit Eclipse können in [http://www.mikrocontroller.net/topic/214719 diesem Thread] gelesen werden.&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 (Linux) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Variante A ====&lt;br /&gt;
&lt;br /&gt;
* Benötigte Hardware&lt;br /&gt;
** Ein Desktop PC oder Laptop mit Linux OS (openSuSE, Ubuntu, ...) alternativ: Ein Windows System mit Linux in einer virtuellen Maschine &lt;br /&gt;
** root Zugang zum Linux OS (superuser Passwort)&lt;br /&gt;
** GNU C Compiler&lt;br /&gt;
** Programmer ARM-USB-TINY-H (optimal) alternativ: OpenOCD kompatiblen Programmer&lt;br /&gt;
** Prototypboard Olimex STM32-P107 (optimal) alternativ: irgendein board mit STM32 uC und JTAG Port&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
* Download + Installation (in einem Terminal)&lt;br /&gt;
  wget http://hlb-labor.de/cortexm3/install_ToolChain_STM32.sh&lt;br /&gt;
  chmod +x install_ToolChain_STM32.sh&lt;br /&gt;
  ./install_ToolChain_STM32.sh&lt;br /&gt;
 &lt;br /&gt;
Die Installation sollte im Idealfall voll automatisch durchlaufen. Anschliessend wird ein Beispielprojekt mit Multitasking OS und LED-Heartbeat kompiliert und auf den uC programmiert.&lt;br /&gt;
Für andere Protoboards/ Programmer muss die ToolChain entsprechend der readme Anleitung umkonfiguriert werden.&lt;br /&gt;
&lt;br /&gt;
Das Projekt kann im QtCreator (http://qt.nokia.com/) geöffnet und bearbeitet werden.&lt;br /&gt;
&lt;br /&gt;
==== Variante B ====&lt;br /&gt;
&lt;br /&gt;
Die Installation einer Toolchain (Make, Flash, Debug via JTAG, IDE) ist in folgendem Manual beschrieben:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;How-to manual - Installing a toolchain for Cortex-M3/STM32 on Ubuntu 10.04&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*http://www.seng.de/downloads/HowTo_ToolChain_STM32_Ubuntu.pdf&lt;br /&gt;
*http://www.seng.de/downloads/HowTo_ToolChain_STM32_Ubuntu.odt&lt;br /&gt;
&lt;br /&gt;
Die Beschreibung im OpenOffice Format erlaubt die Weiterbearbeitung des Textes und das Entnehmen von Quelltexten ohne den Verlust von Formatierungen.&lt;br /&gt;
&lt;br /&gt;
Verwendete Hardware:&lt;br /&gt;
*JTAG device&lt;br /&gt;
**Olimex “ARM-USB-OCD-H”, basierend auf FTDI “FT2232H”&lt;br /&gt;
*Microcontroller&lt;br /&gt;
**Olimex “STM32-H103” basierend auf STM32F103RBT6 mit 128KB Flash, 20KB RAM, 3xUART, ...&lt;br /&gt;
Die Toolchain sollte sich leicht an andere &amp;quot;FT2232&amp;quot; basierte JTAG Probes und &amp;quot;Cortex-M3&amp;quot; Derivate anpassen lassen.&lt;br /&gt;
&lt;br /&gt;
Das Manual umfasst die Installation und Inbetriebnahme sowie Hinweise und Bug-fixes zu folgenden Komponenten:&lt;br /&gt;
*OpenOCD&lt;br /&gt;
*stm32flash&lt;br /&gt;
*Sourcery CodeBench Lite for ARM EABI&lt;br /&gt;
*STM32F10x standard peripheral library&lt;br /&gt;
*Project templates&lt;br /&gt;
*Makefiles&lt;br /&gt;
*Linker Sript&lt;br /&gt;
*Startup Code&lt;br /&gt;
*Doxygen&lt;br /&gt;
*Git&lt;br /&gt;
*Terminal emulation&lt;br /&gt;
*Eclipse IDE&lt;br /&gt;
*Links zu Datenblättern, Manuals und Toools&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 (Windows) ===&lt;br /&gt;
&lt;br /&gt;
Hier ist der Anfang des Artikels [[STM32 Eclipse Installation]], hier ist neueres beschrieben als hier aufgeführt. Wenn der Artikel fertig ist, dann wird dieser Teil gelöscht.&lt;br /&gt;
&lt;br /&gt;
* Eclipse &amp;quot;Helios&amp;quot; installieren mit GNU ARM Eclipse Plug-in&lt;br /&gt;
Eclipse IDE for C/C++ Developers&amp;lt;ref&amp;gt;http://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/heliosr&amp;lt;/ref&amp;gt; downloaden und installieren&lt;br /&gt;
&lt;br /&gt;
* GNU ARM Eclipse Plug-in&amp;lt;ref&amp;gt;http://sourceforge.net/projects/gnuarmeclipse/&amp;lt;/ref&amp;gt; runterladen und installieren. [http://sourceforge.net/apps/mediawiki/gnuarmeclipse/index.php?title=Main_Page Weitere Infos].&lt;br /&gt;
&lt;br /&gt;
Wird CodeSourcery G++ Lite verwendet, so muss die PATH Variable angepasst &lt;br /&gt;
werden, damit das Plugin die CodeSourcery exe-Files findet&amp;lt;ref&amp;gt;für Discovery notwendig&amp;lt;/ref&amp;gt;. Alternativ das eclipse von einem script aus starten und zuerst den PATH erweitern.&lt;br /&gt;
&lt;br /&gt;
Soll das ST-LINK verwendet werden, so kann der Atollic ST-LINK GDBSERVER aus der Atollic free version genutzt werden. Mit dem gdbserver im eclipse kann damit problemlos geflasht und gedebuggt werden (JTAG und SWD). Die Startup- und Linkerscripts der Atollic free version können für ein Projekt in dieser Konstallation genutzt werden.&lt;br /&gt;
&lt;br /&gt;
* Eclipse &amp;quot;Galileo&amp;quot; installation&amp;lt;ref&amp;gt;[http://www.eclipse.org/] → Downloads → &amp;quot;Eclipse IDE for C/C++ Developers (79 MB)&amp;lt;/ref&amp;gt;. Und das Servicepack 1&amp;lt;ref&amp;gt;[http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo/SR1/eclipse-cpp-galileo-SR1-win32.zip Eclipse SR1]&amp;lt;/ref&amp;gt;&lt;br /&gt;
Entpacken der Datei eclipse-cpp-galileo-SR1-win32.zip nach &amp;quot;C:\WinARM\&amp;quot; (Ordner neu erstellen)&lt;br /&gt;
&lt;br /&gt;
* Eclipse PlugIn&amp;lt;ref&amp;gt;http://download.eclipse.org/tools/cdt/releases/galileo&amp;lt;/ref&amp;gt; hinzufügen: Help → Install New Software... → &amp;quot;Eclipse C/C++ Development Tools&amp;quot; + &amp;quot;Eclipse C/C++ GDB Hardware Debugging&amp;quot; installieren&lt;br /&gt;
&lt;br /&gt;
* Yagarto Tools&amp;lt;ref&amp;gt;[http://www.yagarto.de/] &amp;quot;Download (for Windows)&amp;quot; → &amp;quot;YAGARTO Tools&amp;quot; http://www.yagarto.de/download/yagarto/yagarto-tools-20091223-setup.exe Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\yagarto-tools&amp;quot;&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CodeSourcery: Achtung! Die Menustruktur ändert sich durchaus mal, dann suchen gehen. http://www.codesourcery.com/ → Products → Sourcery G++ → Editions&amp;gt;Lite Edition → ARM → Downloads. Direkter Download&amp;lt;ref&amp;gt;[http://www.codesourcery.com/sgpp/lite/arm/portal/package6496/public/arm-none-eabi/arm-2010q1-188-arm-none-eabi.exe]&amp;lt;/ref&amp;gt;. Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\CodeSourcery&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* OpenOCD: Kompilierte Version für Windows&amp;lt;ref&amp;gt;[http://www.freddiechopin.info/] → Download → Software → OpenOCD&amp;lt;/ref&amp;gt; installieren nach &amp;quot;C:\WinARM\OpenOCD_0_4_0&amp;quot; ist auch auf der Seite&amp;lt;ref&amp;gt;[http://yagarto.de/#ocd Yagarto.de]&amp;lt;/ref&amp;gt; beschrieben. PS: Sollte der Olimex ARM-USB-OCD verwendet werden, dann darf nicht der Treiber von Olimex verwendet werden, sondern der vom OpenOCD Download&amp;lt;ref&amp;gt;[http://www.mikrocontroller.net/topic/173753#1668913]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* ST Firmware: http://www.st.com → Auswahl CPU STM32F103xxx → &amp;quot;Firmware&amp;quot; &amp;quot;STM32F10x_StdPeriph_Lib&amp;quot;&amp;lt;ref&amp;gt;http://www.st.com/mcu/devicedocs-STM32F103RC-110.html&amp;lt;/ref&amp;gt;. Das ZIP &amp;quot;stm32f10x_stdperiph_lib.zip&amp;quot; Entpacken nach &amp;quot;C:\WinARM\examples\stm32_FW3.4.0\&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 auf einem zweiten Rechner===&lt;br /&gt;
&lt;br /&gt;
* Kopieren des Verzeichnisses C:\WinARM\ (Zuvor wurden aus diesem Grund alle Setup-Pakete nach C:\WinARM\... installiert)&lt;br /&gt;
* Die PATH-Variable in der Systemsteuerung mit den C:\WinARM\.... Verzeichnissen nachführen&lt;br /&gt;
* Fertig.&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 mit AtollicTrueStudio (+Demo) ===&lt;br /&gt;
* Installation + Demo: [[STM32 LEDBlinken AtollicTrueStudio]]&lt;br /&gt;
&lt;br /&gt;
== Demo-Projekte ==&lt;br /&gt;
&lt;br /&gt;
* [[prog_bsp_timer_1_timer2|Programmbeispiel für die Verwendung von Timer2 zusammen mit dem Interrupt]]&lt;br /&gt;
* [http://www.firefly-power.de/ARM/printf.html Printf() debugging mit minimalem Aufwand]&lt;br /&gt;
* [[STM32_BLDC_Control_with_HALL_Sensor|Programmbeispiel für BLDC Motoransteuerung (Timer 1) mit HALLSensor (Timer 3)]]&lt;br /&gt;
* [[Cortex_M3_OCM3U]]&lt;br /&gt;
* Martin Thomas hat ein umfangreiches Projekt erstellt, in der die Eclipse Einstellungen enthalten sind:&lt;br /&gt;
** [http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html &amp;quot;ChaN&#039;s FAT-Module with STM32 SPI&amp;quot;]&lt;br /&gt;
* [[STM32 USB-FS-Device Lib]]&lt;br /&gt;
* Modellbau-Sender auf STM32-Basis mit vielen Treibern [http://www.rcos.eu www.rcos.eu]&lt;br /&gt;
* Ausführliches [https://github.com/jkerdels/stm32edu Einstiegs-Tutorial] in Codeform für das [http://www.st.com/internet/evalboard/product/252419.jsp STM32F4 discovery board]&lt;br /&gt;
&lt;br /&gt;
== Errata, Tipps und Tricks ==&lt;br /&gt;
&lt;br /&gt;
* AD-Wandler PA0: Im Errata steht, dass hier Fehler in der Wandlung entstehen könnten, also einen anderen Pin verwenden.&lt;br /&gt;
* CAN-Bus PD0/PD1: Remap geht erst ab der 100-Pin-Version. Steht im RM0008 unter 9.3.3.: &amp;quot;CAN1 alternate function remapping&amp;quot;. Alle Infos von RM0008 9.3.x sind interessant&lt;br /&gt;
* CAN und USB sind nur bei der &amp;quot;◦Connectivity-Line&amp;quot; gleichzeitig nutzbar. Siehe Datenblätter.&lt;br /&gt;
* Mit internem RC-Oszillator kann die CPU mit maximal 64MHz betrieben werden. Mit einem externen Quarz sind dann 72MHz möglich.&lt;br /&gt;
* Für USB Betrieb muss die CPU mit 48MHz oder 72MHz betrieben werden (bei STM32F1xx).&lt;br /&gt;
* Der Idle Interrupt vom Usart wird zwar ausgelöst, aber nicht vom entsprechenden Statusflag angezeigt&lt;br /&gt;
* Der DMA fängt beim aktivieren immer von vorn an zu zählen, auch wenn er nur kurz angehalten wurde&lt;br /&gt;
* STM32F2xx hat kein Flash Size Register, bei STM32F4xx ist zwar ein flash Size Register beschrieben, kollidiert aber in der Adresse mit einem anderen Register&lt;br /&gt;
* Derivate mit internem EEPROM und nur einer Speicherbank haben das &amp;quot;Feature&amp;quot; bei write/erase des Data-Flashes (EEPROM) einen kompletten stall der code execution zu verursachen (inkl. ISR&#039;s, DMA). Desgleichen bei write/erase des internen Flash (ISP-routinen, EEPROM-Emulation).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Tipps für Umsteiger von Atmel/PIC/8051 ===&lt;br /&gt;
* Prozessortakt hat unterschiedliche Taktquellen und eine PLL.&lt;br /&gt;
* Alle Peripheriemodule haben einen extra Clock, den man aktivieren muss.&lt;br /&gt;
* Wenn man z.B. einen UART benutzen möchte, so muss man den Clock vom UART, Alternate Function IO (AFIO) und dem GPIO-Port aktivieren.&lt;br /&gt;
* Ansonsten hat man nahezu doppelt so viele Möglichkeiten in den Peripheriemodulen.&lt;br /&gt;
* Interrupt-Flags müssen in der ISR selber gelöscht werden&lt;br /&gt;
* Forum zu [http://www.mikrocontroller.net/topic/175888 Interrupts vs. Events]&lt;br /&gt;
&lt;br /&gt;
=== Tipp FPU von STM32F4xx nutzen ===&lt;br /&gt;
Es benötigt dafür 2 Dinge, zum einen muss die Compileroption gesetzt sein, zum anderen auch die FPU aktiviert werden:&lt;br /&gt;
&lt;br /&gt;
Compileroption:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;COMMON_FLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Code für das Aktivieren der FPU:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;/*FPU settings*/&lt;br /&gt;
__asm volatile (&amp;quot;ldr     r0, =0xE000ED88&amp;quot;);           /* Enable CP10,CP11 */&lt;br /&gt;
__asm volatile (&amp;quot;ldr     r1,[r0]&amp;quot;);&lt;br /&gt;
__asm volatile (&amp;quot;orr     r1,r1,#(0xF &amp;lt;&amp;lt; 20)&amp;quot;);&lt;br /&gt;
__asm volatile (&amp;quot;str     r1,[r0]&amp;quot;);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ohne Inline-Assembler in C wie in system_stm32f4xx.c aus den Beispielen von ST-Microelectronics:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2)); /* set CP10 and CP11 Full Access */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Weiterhin sollte die Toolchain auch Laufzeitbibliotheken mit FPU-Unterstützung mitbringen (CodeBench lite wird ohne ausgeleifert, GCC for ARM embedded von launchpad.org mit).&lt;br /&gt;
&lt;br /&gt;
Mehr dazu in diesem Thread: [http://www.mikrocontroller.net/topic/261021 Floating Pointing Unit STM32F4]&lt;br /&gt;
&lt;br /&gt;
=== Errata vom STM32F4xx die nicht im Errata von ST stehen ===&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/267439#2788478 Aktivieren von DMA], wenn mehr als 3 DMA Kanäle aktiviert werden, kann es sein dass die nicht alle korrekt bedient werden. Auch klappt der DMA mit dem FSMC nicht immer zuverlässig. [https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FWarning%20limit%20simultaneous%20DMAs%20to%202&amp;amp;FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&amp;amp;currentviews=811 siehe hier] [http://blog.frankvh.com/2012/01/13/stm32f2xx-stm32f4xx-dma-maximum-transactions/ und hier]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/260637#2700761 Nerviger Bug in &amp;quot;stm32f4xx.h&amp;quot;] Änderung Struktur GPIO_TypeDef&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/261690#2714754 Batterie wird leer gezogen], nur bei manchen Chips mit Rev. A&lt;br /&gt;
&lt;br /&gt;
== Bezugsquellen ==&lt;br /&gt;
&lt;br /&gt;
=== Controller ===&lt;br /&gt;
&lt;br /&gt;
Versandhäuser für Privatpersonen&lt;br /&gt;
&lt;br /&gt;
* [http://darisusgmbh.de/shop/index.php?cat=c2692_ARM-Cortex.html Darisus]&lt;br /&gt;
* [http://www.hbe-shop.de HBE (Farnell Programm für Private)] &lt;br /&gt;
* [http://www.sander-electronic.de/be00069.html Sander]&lt;br /&gt;
* [http://www.rs-online.com RS-Online]&lt;br /&gt;
*[http://www.tme.eu/de/katalog/index.phtml#cleanParameters%3D1%26search%3DSTM32F10%26bf_szukaj%3D+ TME] &lt;br /&gt;
* [https://www.distrelec.de/ishopWebFront/catalog/product.do/para/keywords/is/STM32_ARM-Microcontroller/and/language/is/de/and/shop/is/DE/and/series/is/1/and/id/is/01/and/node/is/34910.html Distrelec]&lt;br /&gt;
&lt;br /&gt;
Gewerblich liefern natürlich viele wie Mouser, Farnell, Digikey usw...&lt;br /&gt;
&lt;br /&gt;
=== Evaluation Boards ===&lt;br /&gt;
&lt;br /&gt;
* [http://shop.embedded-projects.net/index.php?module=artikel&amp;amp;action=gruppe&amp;amp;id=14 Im Shop von Embedded Projects]&lt;br /&gt;
* [http://www.watterott.com/de/Boards-Kits/ARM/ARM-Cortex-M3 Cortex M3 bei Watterott]&lt;br /&gt;
* [http://www.raisonance.com/~primer-starter-kits__microcontrollers__tool~tool__T018:4enfvamuxbtp.html Primer und Primer2 von Raisonance]&lt;br /&gt;
* [http://www.sander-electronic.de/es0028.html Sander Electronic]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/MP32F103-Stick:_Ein_Mini-Mikrocontroller-Board_mit_USB_und_bis_zu_4MB_Datenspeicher Artikel im Wiki, ARM mit USB und 4MB Speicher]&lt;br /&gt;
* [http://www.futurlec.com/STM32_Development_Board.shtml Futurlec Evalboard, ebenso Header-Board]&lt;br /&gt;
* [http://www.propox.com/products/t_174.html Propox, Header-Boards für 103R und 103V sowie Trägerplatine dafür]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/Cortex_M3_OCM3U Cortex M3 Artikel im Wiki]&lt;br /&gt;
* [http://olimex.com/dev/index.html STM32 bei Olimex]&lt;br /&gt;
* [http://de.farnell.com/jsp/displayProduct.jsp?sku=1824325&amp;amp;action=view&amp;amp;CMP=GRHS-1000962 STM32Discovery bei Farnell] Mikrocontroller Board (STM32F100RBT6B) mit onboard USB-Programming Interface für ca. 12,50€&lt;br /&gt;
* [http://www.de.rs-online.com/web/p/products/7458434/ STM32Discovery bei RS-Components] 12,65 € +MwSt.&lt;br /&gt;
* [http://www.segor.de/#Q=STM32 VL DISCOVERY] STM32 Discovery bei Segor&lt;br /&gt;
* [http://www.watterott.com/de/STM32F4Discovery STM32F4DISCOVERY] STM32F4 Cortex M4 Controller mit JTAG-Debugger auf der Platine bei Watterott für 16,66EUR.&lt;br /&gt;
* [http://www.steitec.net/ARM-Boards/ Steitec, STM32F103 Cortex M3 Board 34,80€]&lt;br /&gt;
* [http://www.mcu-raisonance.com/~open4-development-platform__microcontrollers__tool~tool__T018:g65gu6ghg2n.html/ Open 4 oder auch genannt Evo-Primer]&lt;br /&gt;
* [http://www.wayengineer.com/index.php?main_page=index&amp;amp;cPath=50_66&amp;amp;page=1&amp;amp;sort=3a WayEngineer]&lt;br /&gt;
&lt;br /&gt;
== Weblinks, Foren, Communities ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/173753 Diskussion zum Artikel]&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/mikrocontroller-elektronik?filter=ARM*+STM32*+Cortex* Suche im Forum]&lt;br /&gt;
* [https://my.st.com/public/STe2ecommunities/mcu/Lists/ARM%20CortexM3%20STM32/AllItems.aspx Forum auf der ST Homepage] &lt;br /&gt;
* [http://www.stm32circle.com/hom/index.php STM32 Community] &lt;br /&gt;
*[http://www.arm-forum.de Deutsches ARM-Forum]&lt;br /&gt;
*[http://joe-c.de/pages/posts/einstieg_mikrocontroller_stm32f103_101.php Einstieg:  STM32board mit Kamera (deutsch)] &lt;br /&gt;
* [http://www.ebv.com/fileadmin/products/Press_Print/Brochures/Product_Brochures/EBV_Cortex%20Collection_V2.pdf Übersicht der Cortex Prozessoren und deren Hersteller (nicht nur ST, von EBV)]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/258652 Tutorial]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
[[Kategorie:ARM]]&lt;br /&gt;
[[Kategorie:STM32| ]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=68010</id>
		<title>STM32</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=STM32&amp;diff=68010"/>
		<updated>2012-08-22T17:27:32Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* Tipp FPU von STM32F4xx nutzen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;STM32 ist ein Mikrocontroller-Familie von [http://www.st.com/mcu/inchtml-pages-stm32.html ST] mit einer 32-Bit [http://www.arm.com/products/processors/cortex-m/index.php ARM Cortex-M3/M4] CPU. Diese Architektur ist speziell für den Einsatz in Microcontrollern neu entwickelt und löst damit die bisherigen ARM7-basierten Controller weitestgehend ab. Den STM32 gibt es von ST in unzähligen Varianten mit variabler Peripherie und verschiedenen Gehäusegrößen und -formen. Durch die geringe Chipfläche des Cores ist es ST möglich, eine 32 Bit-CPU für weniger als 1&amp;amp;nbsp;€ anzubieten.&lt;br /&gt;
&lt;br /&gt;
[[Bild:stm32F103xc.png|thumb|right|340px|Blockdiagramm STM32F103xC/D/E]]&lt;br /&gt;
&lt;br /&gt;
== STM32-Familien ==&lt;br /&gt;
&lt;br /&gt;
Bisher gibt es sieben STM32-Familien:&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1588.jsp STM32F0]&lt;br /&gt;
** Cortex M0&lt;br /&gt;
** µC zum Einstieg&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1169.jsp STM32F1]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
*** Connectivity line&lt;br /&gt;
*** Performance line&lt;br /&gt;
*** USB Access line&lt;br /&gt;
*** Access Line&lt;br /&gt;
*** Value line &lt;br /&gt;
* [http://www.st.com/internet/mcu/product/250173.jsp STM32F2]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
** Wie die STM32F1 Serie, jedoch 120MHz, Camera-Interface, 32-Bit Timer, Crypto-Engine...&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1605.jsp STM32F3]&lt;br /&gt;
** ARM® Cortex™-M4-based STM32 F3, 72MHz&lt;br /&gt;
** DSP instructions and the floating point unit &lt;br /&gt;
** Fast 12-bit 5 MSPS and precise 16-bit sigma-delta ADCs&lt;br /&gt;
* [http://www.st.com/internet/mcu/subclass/1521.jsp STM32F4]&lt;br /&gt;
** Cortex M4&lt;br /&gt;
** ARM® Cortex™-M4-based STM32 F4, 168MHz&lt;br /&gt;
** DSP instructions and the floating point unit &lt;br /&gt;
* [http://www.st.com/mcu/inchtml-pages-stm32l.html STM32L]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
** Low Power &lt;br /&gt;
** mit LCD Treiber&lt;br /&gt;
* [http://www.st.com/mcu/inchtml-pages-stm32w.html STM32W]&lt;br /&gt;
** Cortex M3&lt;br /&gt;
** RF-MCU &lt;br /&gt;
[http://www.st.com/internet/mcu/class/1734.jsp Hier eine Übersicht zum Auswählen eines STM32Fxxx]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Features&#039;&#039;&#039;&lt;br /&gt;
* Cortex-M3 bzw. Cortex-M4 Kern in der STM32F4xx Serie&lt;br /&gt;
* 16KB ... 1MB  [[Flash-ROM]]&lt;br /&gt;
*  4KB ... 192KB [[Speicher#SRAM|SRAM]]&lt;br /&gt;
* 4KB [[Speicher#EEPROM|EEPROM]] (STM32L)&lt;br /&gt;
* 512 one-time programmable Bytes(STM32F2/4)&lt;br /&gt;
* [[IC-Gehäuseformen | Gehäuse]] 36 ... 176 Pins als QFN, LQFP und BGA&lt;br /&gt;
* Derzeit sind über &#039;&#039;&#039;250&#039;&#039;&#039; STM32 Derivate/Varianten verfügbar&lt;br /&gt;
* Bis 72MHz CPU-Takt, bis 120MHz beim STM32F2xx, bis 168 MHz beim STM32F4xx, wobei eine spezielle prefetch-hardware bis 120/168 MHz eine Geschwindigkeit erzielen soll, die 0 Wait-States entspricht. Der CPU-Takt wird über einen Multiplikator aus dem internen RC-Takt oder einem externen Quarz-Takt abgeleitet.&lt;br /&gt;
* Externes Businterface (nur bei Gehäusen ab 100 Pin und nur bei STM32F4, STM32F2 und STM32F1 Performance line)&lt;br /&gt;
* LCD Treiber für 8x40 Punkte (nicht beim STM32F2xx)&lt;br /&gt;
* Spannungsbereich 1,65 ... 3,6V, nur eine Betriebsspannung nötig&lt;br /&gt;
* Temperaturbereich bis 125 °C&lt;br /&gt;
* Bis zu 140 IOs, viele davon [[Pegelwandler|5V-tolerant]]&lt;br /&gt;
* Interner, kalibrierter RC-Oszillator mit 8MHz (16MHz bei STM32F2xx)&lt;br /&gt;
* Externer Quarz&lt;br /&gt;
* Real Time Clock mit eigenem Quarz und separater Stromversorgung&lt;br /&gt;
* Bis zu 16 [[Timer]], je Timer bis zu 4 IC/OC/PWM Ausgänge. Davon 2x Motion Control Timer (bei STM32F103xF/G)&lt;br /&gt;
* Systick Counter&lt;br /&gt;
* Bis zu 3 12-Bit [[AD-Wandler]] mit insgesamt 24 AD-Eingängen, integrierter [[Temperatursensor]], Referenzspannung Vrefint und VBatt Spannungsmessung (STM32F4xx)&lt;br /&gt;
* Bis zu 2 12-Bit [[DA-Wandler]]&lt;br /&gt;
* Bis zu 2 [[DMA]] Controller mit bis zu 12 Kanälen (16 beim STM32F2xx)&lt;br /&gt;
* Bis zu 2x [[I2C|I²C]]&lt;br /&gt;
* Bis zu 5x [[UART|USART]] mit LIN, IrDA und Modem Control (6 beim STM32F2xx)&lt;br /&gt;
* Bis zu 3x [[SPI]]&lt;br /&gt;
* Bis zu 2x [[I2S|I²S]]&lt;br /&gt;
* Bis zu 2x [[CAN]]&lt;br /&gt;
* Unique device ID register (96 Bits)&lt;br /&gt;
* RNG - Random Number Genrator (STM32F2xx)&lt;br /&gt;
* Cryptographic Processor (CRYP) (STM32F2xx)&lt;br /&gt;
* Hash Processor (HASH) (STM32F2xx)&lt;br /&gt;
* Kamera-Interface (DCMI) (STM32F2xx)&lt;br /&gt;
* [[USB]] 2.0 Full Speed / OTG&lt;br /&gt;
* [[USB]] 2.0 Hi Speed OTG mit extra PHY-Chip (STM32F2xx)&lt;br /&gt;
* SDIO Interface (z.B. SD-Card Reader)&lt;br /&gt;
* Ethernet&lt;br /&gt;
* Watchdog mit Window-Mode&lt;br /&gt;
* Jedes Peripheriemodul ist separat einschaltbar, wodurch sich erheblich [[Ultra low power|Strom sparen]] lässt&lt;br /&gt;
* [[JTAG]] und SWD (Serial Wire Debug) Interface&lt;br /&gt;
* Bis zu 6 Hardware-Breakpoints für Debuggen&lt;br /&gt;
* und vieles mehr . . .&lt;br /&gt;
&lt;br /&gt;
== Struktur der Dokumentation: ==&lt;br /&gt;
&lt;br /&gt;
Als Beispiel der Dokumentation soll stellvertretend der [http://www.st.com/mcu/devicedocs-STM32F103RC-110.html STM32F103RC] genannt werden. Die Seite von ST beinhaltet alle nötigen Informationen passend zu diesem Prozessor.&lt;br /&gt;
&lt;br /&gt;
Diese Dokumente von ST beschreiben den Controller:&lt;br /&gt;
&lt;br /&gt;
* [http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/DATASHEET/CD00191185.pdf  Datasheet STM32F103xC/D/E]&lt;br /&gt;
* [http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/REFERENCE_MANUAL/CD00171190.pdf  Reference Manual (RM0008)]&lt;br /&gt;
* [http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/PROGRAMMING_MANUAL/CD00228163.pdf  Cortex-M3 Programming Manual]&lt;br /&gt;
* [http://www.st.com/stonline/products/literature/pm/13259.pdf Flash Programming Reference]&lt;br /&gt;
&lt;br /&gt;
Im Datasheet sind die speziellen Eigenschaften einer bestimmten Modellreihe beschrieben und die exakten Daten und Pinouts aufgeführt. Die Peripheriemodule werden nur aufgeführt, nicht detailliert beschrieben. In der Referenz ist der gesamte Controller mit Peripheriemodulen im Detail beschrieben, gültig für eine STM32-Familie. Details zum Prozessorkern selbst und den nicht STM32-spezifischen mit dem Cortex-M3 Core assoziierten Modulen wie dem Interrupt-Controller und dem Systick-Timer findet man jedoch nicht dort, sondern im Cortex-M3 Manual. Wer nicht die ST Firmware-Library verwendet, der benötigt zusätzlich die Flash Programming Reference für die Betriebsart des Flash-ROMs, d.h. die frequenzabhängige Konfiguration der Waitstates. Hinzu kommen optionale Dokumente von ARM, die den [http://infocenter.arm.com/help/topic/com.arm.doc.ddi0337-/ Cortex-M3 Kern] / [http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0439c/index.html Cortex-M4 Kern] beschreiben. Hier gibt es den Opcode wenn man ihn in [http://infocenter.arm.com/help/topic/com.arm.doc.ddi0403-/ Assembler] programmieren möchte. Zusätzlich sollten auch die [http://www.st.com/stonline/products/literature/es/14732.pdf Errata Sheets] beachtet werden. Empfohlen sei auch die Appnote &amp;quot;[http://www.st.com/internet/com/TECHNICAL_RESOURCES/TECHNICAL_LITERATURE/APPLICATION_NOTE/CD00164185.pdf STM32F10xxx hardware development: getting started]&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== ‎STM32F10x Standard Peripherals Library ==&lt;br /&gt;
&lt;br /&gt;
ST bietet eine umfangreiche Firmwarebibliothek, eine einzige Bibliothek für alle STM32 Derivate. Das ist der große Vorteil von ST (gibt es beispielsweise auf den Cortex-M3 Controllern von TI auch, ist teilweise in einem separaten ROM untergebracht). Einmal programmieren und in allen STM32 verwendbar. Alle Funktionen sind gekapselt in einfache Strukturen und Funktionsaufrufe. Somit muss man sich nicht selbst um die Peripherieregister kümmern. Diese Library und ihre Dokumentation setzen das grundlegende Verständnis der Funktion des jeweiligen Peripheriemoduls voraus, wie es die o.A. Referenz und diverse Appnotes vermitteln. Diese FW-Lib (Download von ST) ist ein MUSS für jeden, denn darin sind auch jede Menge Beispiele für alle Peripheriemodule. &lt;br /&gt;
&lt;br /&gt;
Details siehe: [[‎STM32F10x Standard Peripherals Library]].&lt;br /&gt;
&lt;br /&gt;
Mit [http://www.libopencm3.org/wiki/Main_Page libopencm3] ist derzeit auch eine Open-Source Alternative (GPL, Version 3 oder höher) zur ST Library in Entwicklung, die zukünftig auch Cortex-M3 Controller von anderen Herstellern unterstützen soll.&lt;br /&gt;
&lt;br /&gt;
== CMSIS ==&lt;br /&gt;
&lt;br /&gt;
Parallel zur Firmware-Library (FW-Lib) gibt es für die &amp;quot;Selbermacher&amp;quot; die CMSIS (ARM® &#039;&#039;&#039;C&#039;&#039;&#039;ortex™ &#039;&#039;&#039;M&#039;&#039;&#039;icrocontroller &#039;&#039;&#039;S&#039;&#039;&#039;oftware &#039;&#039;&#039;I&#039;&#039;&#039;nterface &#039;&#039;&#039;S&#039;&#039;&#039;tandard), die grundsätzlich nur den herstellerübergreifenden ARM-Core abdeckt. Hierzu gehört bei den Cortex-M4-Cores auch die DSP und Floating-Point Funktionalität. Weiterhin existieren eine Zahl von Helferfunktionen für den NVIC, den Sys-Tick-Counter, sowie eine SystemInit-Funktion, welche sich um die PLL kümmert. &lt;br /&gt;
&lt;br /&gt;
Im Rahmen des CMSIS-Standards ([http://www.onARM.com www.onARM.com]) wurden die Headerdateien standardisiert, der Zugriff auf die Register erfolgt per &#039;&#039;&#039;Peripheral-&amp;gt;Register&#039;&#039;&#039;. Die CMSIS C-Dateien bzw. Header enthalten auch Anpassungen für die verschiedenen Compiler. Die Portierung eines Real-Time-Betriebsystems sollte unter Verwendung der CMSIS, für Chips der verschiedenen Hersteller, stark vereinfacht möglich sein (z.B. einheitliche Adressen für Core-Hardware/Sys-Tick-Counter).&lt;br /&gt;
&lt;br /&gt;
Die CMSIS ist im Download der FW-Lib enthalten. Die Compiler-Hersteller liefern eine jeweils zur ihrer Tool-Version passende bzw. geprüfte FW-Lib (incl. CMSIS) aus. Diese Libs können, gegenüber den Downloads beim Chip-Hersteller, auch ältere Version beinhalten.&lt;br /&gt;
&lt;br /&gt;
== Debug- und Trace-Interface (CoreSight™ Debug and Trace Technologie)==&lt;br /&gt;
&lt;br /&gt;
Übersicht über beide Funktionalitäten und den Schnittstellen:&lt;br /&gt;
http://www.keil.com/support/man/docs/ulink2/ulink2_cs_core_sight.htm&lt;br /&gt;
&lt;br /&gt;
Die Coresight-Debug-Architektur ermöglicht ein nicht-invasives Debugging, d.h. es können während des Betriebes (meistens) ohne Beeinflussung des Prozessors Daten vom Speicher gelesen und in selbigen geschrieben werden.&lt;br /&gt;
&lt;br /&gt;
=== Debugger Funktionen ===&lt;br /&gt;
&lt;br /&gt;
Der Debugger-Teil besitzt drei Funktionen:&lt;br /&gt;
* Run Control: z.B. Programm-Start, Stopp und Einzel-Schritte.&lt;br /&gt;
* (Program) Break Points: Ein Programm hält an, wenn der Programm Counter eine bestimmte Programm-Adresse erreicht.&lt;br /&gt;
** Beinhaltet keine Data Watch Funktionalität, welche im Trace-Teil (DWT) realisiert wird.&lt;br /&gt;
* Memory Access: Lesen und Schreiben von Speicheradressen. &lt;br /&gt;
** Diese Funktionalität beinhaltet keine direkte Flash-Programmierung. Der Programmiervorgang für einen Flash ist herstellerspezifisch und muss von dem verwendeten Debugger unterstützt werden.&lt;br /&gt;
&lt;br /&gt;
=== Trace Funktionen ===&lt;br /&gt;
Die Trace-Funktionalität wird in drei Funktionen aufgeteilt:&lt;br /&gt;
* ETM (Embedded Trace Macrocell): Optional, nicht jede CPU besitzt diese Hardware (Kostenfaktor, Austattung).&lt;br /&gt;
* ITM (Instrumentation Trace Macrocell): Über diesen Kanal kann ein vereinfachtes Trace des Core ermöglicht werden, sowie &amp;quot;printf-ähnlich&amp;quot; Daten über den ITM Channel 0 geschickt und im Debugger ausgegeben werden.&lt;br /&gt;
* DWT (Data Watchpoint &amp;amp; Trace Unit): &lt;br /&gt;
** Data Watch: 4 Access-Break-Points ( z.B. der Debugger bleibt stehen, wenn das Programm auf einen Speicher zugreift oder der Wert einer Variablen einen bestimmten Wert annimmt). &lt;br /&gt;
** Trace Unit: Programmverlauf (durch Lesen des Program Counters) und Interrupt Aufrufe verfolgen, sowie Zeitmessungen.&lt;br /&gt;
&lt;br /&gt;
Einige der Trace-Funktionalitäten können über die JTAG-Schnittstelle angesprochen werden. Die schnelle Trace-Funktionalität (mit 4 bit Parallel-Port) steht nur mit der erweiterten DEBUG + ETM Schnittstelle zur Verfügung. Im Gegensatz zum Debugger-Teil (Run Control, Break Points und Memory Access) werden Trace-Funktionen nicht von allen Debuggern unterstützt. Debugger mit der vollen Trace-Funktionalität kosten deutlich mehr.&lt;br /&gt;
&lt;br /&gt;
* Beispiele für Trace-Port-Aktivierungen für verschiedene Hersteller: http://www.keil.com/support/man/docs/jlink/jlink_capture_tracedata.htm&lt;br /&gt;
&lt;br /&gt;
Die Aktivierung des parallelen Trace-Ports erfordert, je nach CPU Hersteller, zusätzliche Debugger-Makros für die Aktivierung und Port-Freischaltung. Zusätzlich sind die Schnittstellenauswahl und Einstellung (Frequenzen) im Entwicklungs-Tool (IDE) wichtig, um erfolgreich den Programm-Verlauf &amp;quot;tracen&amp;quot; zu können.&lt;br /&gt;
&lt;br /&gt;
=== Debug und Trace-Schnittstellen ===&lt;br /&gt;
Als Debug Interface stehen zwei Varianten zur Auswahl:&lt;br /&gt;
* [[JTAG]]: Dafür sind mindestens 6 Steuerleitungen nötig.   &lt;br /&gt;
* SWD (Serial Wire Debug): Hier mindestens 2  Steuerleitungen (3 mit SWO, zzgl GND und 3,3V). Die SWD Schnittstelle ist in der Regel schneller und kann auch Funktionen aus dem Trace-Teil beinhalten (z.B. ITM, dafür wird der SWO-Pin benötigt).&lt;br /&gt;
&lt;br /&gt;
Standard-JTAG Steckerbelegungen: &lt;br /&gt;
http://www.keil.com/support/man/docs/ulink2/ulink2_hw_connectors.htm&lt;br /&gt;
&lt;br /&gt;
=== Der 10polige JTAG-Stecker von mmvisual ===&lt;br /&gt;
mmvisual hat mit dieser Steckerbelegung die Standard JTAG Schnittstelle erweitert:&lt;br /&gt;
&lt;br /&gt;
Ich habe diesen Part in den Artikel [http://www.mikrocontroller.net/articles/JTAG#Der_10-Polige_JTAG_Stecker_von_mmvisual JTAG] verschoben.&lt;br /&gt;
Hinzu gekommen ist die Adapterplatine 10-Polig auf Standard JTAG 20 Polig mit TTL/V24 Wandler. [http://www.mikrocontroller.net/articles/JTAG#Die_Adapterplatine Siehe hier.]&lt;br /&gt;
&lt;br /&gt;
=== STM32 RS232 (CAN und USB) Programmiertool ===&lt;br /&gt;
&lt;br /&gt;
Auch ohne JTAG lässt sich ein STM32 programmieren (Bootloader-Aktivierung). Dabei stehen, je nach CPU-Typ, verschiedene Möglichkeiten zur Verfügung:&lt;br /&gt;
* RS-232 (bisher alle STMs)&lt;br /&gt;
* USB (nur in bestimmten MCUs mit entsprechender Bootloader-Version und PIN-Anzahl, z.B. STM32F105/107)&lt;br /&gt;
* CAN (wie USB nur in bestimmten MCUs)&lt;br /&gt;
&lt;br /&gt;
3 zusätzliche Verbindungen müssen auf dem Board gepatcht werden. Für einen Test geht es auch mit Tastern für RESET und BOOT0.&amp;lt;br&amp;gt;&lt;br /&gt;
RESET=RTS (L-aktiv)&amp;lt;br&amp;gt;&lt;br /&gt;
BOOT0=DTR (H-aktiv)&amp;lt;br&amp;gt;&lt;br /&gt;
BOOT1=LOW&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Details sind hier im Forum: [http://www.mikrocontroller.net/topic/141711 STM32 Programmiertool]&lt;br /&gt;
&lt;br /&gt;
== Vorteile ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber ARM7:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Interrupt-Controller jetzt Teil des Prozessors (als Core Peripheral), die Vector Table ist jetzt eine echte Vektortabelle, keine Sprungliste wie bei ARM7. Durch Automatismen zwischen Core und NVIC (auto register save r0..r3, lr, sp, pc) bei Interrupt Entry wird eine deutlich schnellere Ausführungszeit bei Interrupts erreicht. Der Interrupt Code muss sich nicht mehr selbst um die Sicherung der o.g. Register kümmern und eine besondere Konfiguration der Handler im Compiler entfällt. Sind vor Beendigung einer ISR (d.h. Rücksprung zum User Code) weitere Interrupts pending, so werden diese ausgeführt, ohne dass eine komplette pop-push-sequenz der Register notwendig ist. Schön beschrieben ist es hier im [http://www.st.com/mcu/files/mcu/1221142709.pdf Insider&#039;s Guide] unter 2.4.5 / Seite 20.&lt;br /&gt;
* Thumb-2 Befehlssatz, deutlich schneller als Thumb-1 und ebenso kompakt&lt;br /&gt;
* Weniger Pins für Debugging benötigt durch SWD&lt;br /&gt;
* Mehr Hardware Breakpoints machen debuggen einfacher&lt;br /&gt;
* Software ist einfacher weil die Umschaltung zwischen ARM Mode und Thumb Mode wegfällt&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber LPC1700 und LPC1300:&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Flexiblere Gehäuseformen mit mehr Peripherie bei kleinen Gehäusen&lt;br /&gt;
* FW-Lib für alle STM32 gleich, alle AppNotes/Demos beziehen sich auf diese eine FW-Lib was die Entwicklung der eigenen Applikation sehr beschleunigt.&lt;br /&gt;
* Genauerer und flexiblerer ADC, insbesondere gegenüber LPC1300&lt;br /&gt;
* Flexiblere Varianten der Peripherie &amp;gt;&amp;gt; bei weniger einen deutlichen Preisvorteil&lt;br /&gt;
* ab 0,85 EUR (Stand 2010) Allerdings gibts den LPC1100 mit Cortex-M0 schon ab 0,65 $!&lt;br /&gt;
&#039;&#039;&#039;Nachteil gegenüber LPC1700:&#039;&#039;&#039;&lt;br /&gt;
* STM32F1xx: nur 72 MHz statt 100 MHz (LPC1759: 120 MHz) Taktfrequenz; STM32F2xx hat diesen Nachteil nicht (ebenfalls 120MHz, STM32F4xx mit 168MHz) (Aber NXP hat schon 150MHz angekündigt)&lt;br /&gt;
* Der LPC1700 besitzt deutlich mehr Mechanismen, um die Auswirkung der Waitstates des Flash-ROMs auf Code- und Datenzugriffe zu reduzieren und das bedeutet mehr Performance bei gleicher Taktfrequenz. Beim STM32F2 entfällt dieser Nachteil wohl aufgrund des ART accelerators. &lt;br /&gt;
* Alle LPC1xxx haben 32 Bit Timer. Bei den STM32 haben das nur die STM32F2xx (2 Stück)&lt;br /&gt;
* I2S Einheit von ST hat keinen FIFO und im 24/32Bit Modus müssen 2x16Bit Halbwörter übertragen werden.&lt;br /&gt;
&#039;&#039;&#039;Vorteile gegenüber anderen &amp;quot;Kleinen&amp;quot; wie z.B. PIC, Atmel usw.&#039;&#039;&#039;&lt;br /&gt;
* nahezu gleicher Preis bei Hobby Anwendungen&lt;br /&gt;
* 32 Bit ohne Umwege in Assembler rechenbar&lt;br /&gt;
* bessere Peripherie&lt;br /&gt;
* ... und weitere 1000 Punkte ...&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Nachteil für Hobby-Anwender&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* Nicht direkt &amp;quot;Steckbrettauglich&amp;quot;, da kein DIL Gehäuse verfügbar. Der ebay-Shop dipmicro führt jedoch sehr günstige Lötadapter für Umsetzung von LQFP48 auf DIP48. QFP64 in 0.5mm Pinabstabd und nicht 0.8mm wie AVR&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Hardware-Beschaltung ==&lt;br /&gt;
&lt;br /&gt;
Der STM32 benötigt für den Betrieb nur (Minimalbeschaltung):&lt;br /&gt;
&lt;br /&gt;
* VCC 2..3,3V (je nach Typ)&lt;br /&gt;
* AVCC 2..3,3V (sehr wichtig, der STM32 lässt sich ohne diese Spannung nicht programmieren)&lt;br /&gt;
* GND&lt;br /&gt;
* Reset Pin 100nF nach GND (ein Pull-Up Widerstand von ca. 40k ist intern vorhanden)&lt;br /&gt;
* Boot-Pins: Boot0 -&amp;gt; GND | Boot1 -&amp;gt; Egal ---&amp;gt; Mit der Konfiguration wird kein Bootloader gestartet&lt;br /&gt;
&lt;br /&gt;
ansonsten nur ein paar einzelne Cs 100nF an VCC/GND.&lt;br /&gt;
&lt;br /&gt;
Um Programmieren zu können wird entweder noch die serielle Schnittstelle (Programmieren über den vorprogrammierten Bootloader) oder JTAG oder die SWD Schnittstelle benötigt.&lt;br /&gt;
&lt;br /&gt;
== Programmierung ==&lt;br /&gt;
&lt;br /&gt;
Als Programmieroberfläche kann eine kostenlose Struktur verwendet werden. Es ist für den Einsteiger schwierig herauszufinden welche Open-Source Programme man braucht damit es funktioniert, daher hier eine Zusammenstellung:&lt;br /&gt;
&lt;br /&gt;
* [http://www.eclipse.org Eclipse]&lt;br /&gt;
* [http://www.yagarto.de Yagarto Tools] oder [http://www.codesourcery.com/sgpp/lite_edition.html Codesourcery Lite Edition] oder [https://launchpad.net/gcc-arm-embedded Launchpad]&lt;br /&gt;
* Programmieradapter OOCD, Turtelizer2 oder andere JTAG Programmieradapter&lt;br /&gt;
* Eclipse Plugin &amp;quot;GDB Hardware Debugging&amp;quot; mit [http://www.firefly-power.de/ARM/debugging.html OpenOCD server]&lt;br /&gt;
* [http://www.st.com/internet/com/software/ides_mcu.jsp#stm32 ST Liste: IDEs, Toolsets and Debug tools for MCUs]&lt;br /&gt;
&lt;br /&gt;
* Zum Starten eine fertige Zusammenstellung: [http://www.mikrocontroller.net/topic/216554 Eclipse+codesourcery+st-link]&lt;br /&gt;
&lt;br /&gt;
* [http://www.coocox.org/ Coocox Eclipse IDE] kostenlose IDE für Cortex M0/M3. Hilfreiche Infos gibt es im [http://www.mikrocontroller.net/topic/214719?goto=new#2228482 hier] und [http://www.mikrocontroller.net/topic/214719?goto=new#2229943 hier] Forum&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/265600 STM32F4 mit Code::Blocks]&lt;br /&gt;
&lt;br /&gt;
* [http://emide.org/ emIDE] kostenlose IDE die mit dem Segger J-LINK funktioniert.&lt;br /&gt;
&lt;br /&gt;
Sehr nützlich für Linux-Anwender auch diese Seite: [http://fun-tech.se/stm32/index.php STM32/ARM Cortex-M3 HOWTO: Development under Ubuntu.]&lt;br /&gt;
&lt;br /&gt;
Folgende kommerzielle Umgebungen sind verfügbar:&lt;br /&gt;
&lt;br /&gt;
* [http://www.keil.com Keil µVision] (Demo max. 32KB Code): Die sehr komfortable µVison IDE ist neben dem ARM Compiler per Menue auch für einen beliebigen GNU-Compiler konfigurierbar. Damit besteht das 32k-Limit nur noch für den integrierten Debugger / Simulator. µVison selbst kann kostenlos mit dem MDK-Evaluationkit heruntergeladen werden.&lt;br /&gt;
* [http://www.iar.com IAR] (Demo max. 32KB Code)&lt;br /&gt;
* [http://www.raisonance.com Raisonance Ride7] (GCC Compiler, kostenlose Version auf Debugging von max. 32KB Code limitiert, keine Limitierung beim Complilieren)&lt;br /&gt;
* [http://www.atollic.com Atollic] (Lite Version (bis V2.3.0) ohne Code-Limit, auf GCC basierend. Die neueste Version ab V3 hat fast keine Beschränkungen mehr außer jetzt einen Code-Limit von 32kB. Außerdem werden jetzt die meisten ARM Familien unterstützt. )&lt;br /&gt;
* [http://www.coocox.org CoIDE] (Kostenlose GCC, Eclipse basierende IDE mit einem Code-Generator Tool)&lt;br /&gt;
* [http://www.rowley.co.uk/arm/ Rowley Crossworks] (Demo 30 Tage unbeschränkt, 150$ für nichtkommerzielle Nutzung, auf GCC basierend)&lt;br /&gt;
* [http://www.code-red-tech.com Code Red] (GCC basierend)&lt;br /&gt;
&lt;br /&gt;
Programmieradapter&lt;br /&gt;
* [http://www.segger.com J-Link / J-Trace] Cortex-M3, als [http://www.segger.com/cms/j-link-edu.html NonComercial] J-Link für ca. 60,- zu haben, läuft in µVision, IAR, gdb&lt;br /&gt;
* [http://olimex.com/dev/index.html Olimex] ARM-USB-OCD (ca. 60.-)&lt;br /&gt;
* Keil [http://www.keil.com/arm/ulink2/ ULINK2], [http://www.keil.com/arm/ulinkpro/ ULINK pro]&lt;br /&gt;
* [http://www.st.com/internet/evalboard/product/219866.jsp ST-LINK], [http://www.st.com/internet/evalboard/product/251168.jsp ST-LINK/V2]&lt;br /&gt;
*[http://www.st.com/internet/com/press_release/p3065.jsp STM32xx Discovery] jedes STM32 Discovery board hat einen ST-Link für Programmierung/Debugging per SWD on-board, welcher auch für eigene STM32 Target Hardware benutzt werden kann (ca. 12,- bis 19,-€, je nach Typ).&lt;br /&gt;
* [http://www.raisonance.com/~rlink-debugger-programmer__microcontrollers__tool~tool__T018:4cn9ziz4bnx6.html Raisonance RLink]&lt;br /&gt;
* [http://www.amontec.com Amontec]&lt;br /&gt;
* [http://www.hjtag.com H-JTAG] Personal Edition für ca. 60,- zu haben, läuft mit ADS, SDT, IAR, Vision und RVDS &lt;br /&gt;
&lt;br /&gt;
Programmieradapter Open-Source&lt;br /&gt;
* [http://www.oocdlink.com/ OOCDLink]&lt;br /&gt;
* [https://github.com/texane/stlink Stlink]&lt;br /&gt;
* [http://www.randomprojects.org/wiki/Floss-JTAG FLOSS-JTAG]&lt;br /&gt;
* [http://capitanio.org/mlink/ Linux Demo Code für die Discovery&#039;s ST-Link Programmierung]&lt;br /&gt;
&lt;br /&gt;
Der Controller hat auch einen fest eingebauten Boot-Lader. Damit läßt er sich auch über eine gewöhnliche serielle Schnittstelle programmieren, ohne daß man einen JTAG-Adapter benötigt.&lt;br /&gt;
&lt;br /&gt;
Tipps für Installation mit Eclipse können in [http://www.mikrocontroller.net/topic/214719 diesem Thread] gelesen werden.&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 (Linux) ===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==== Variante A ====&lt;br /&gt;
&lt;br /&gt;
* Benötigte Hardware&lt;br /&gt;
** Ein Desktop PC oder Laptop mit Linux OS (openSuSE, Ubuntu, ...) alternativ: Ein Windows System mit Linux in einer virtuellen Maschine &lt;br /&gt;
** root Zugang zum Linux OS (superuser Passwort)&lt;br /&gt;
** GNU C Compiler&lt;br /&gt;
** Programmer ARM-USB-TINY-H (optimal) alternativ: OpenOCD kompatiblen Programmer&lt;br /&gt;
** Prototypboard Olimex STM32-P107 (optimal) alternativ: irgendein board mit STM32 uC und JTAG Port&lt;br /&gt;
&lt;br /&gt;
  &lt;br /&gt;
* Download + Installation (in einem Terminal)&lt;br /&gt;
  wget http://hlb-labor.de/cortexm3/install_ToolChain_STM32.sh&lt;br /&gt;
  chmod +x install_ToolChain_STM32.sh&lt;br /&gt;
  ./install_ToolChain_STM32.sh&lt;br /&gt;
 &lt;br /&gt;
Die Installation sollte im Idealfall voll automatisch durchlaufen. Anschliessend wird ein Beispielprojekt mit Multitasking OS und LED-Heartbeat kompiliert und auf den uC programmiert.&lt;br /&gt;
Für andere Protoboards/ Programmer muss die ToolChain entsprechend der readme Anleitung umkonfiguriert werden.&lt;br /&gt;
&lt;br /&gt;
Das Projekt kann im QtCreator (http://qt.nokia.com/) geöffnet und bearbeitet werden.&lt;br /&gt;
&lt;br /&gt;
==== Variante B ====&lt;br /&gt;
&lt;br /&gt;
Die Installation einer Toolchain (Make, Flash, Debug via JTAG, IDE) ist in folgendem Manual beschrieben:&lt;br /&gt;
&lt;br /&gt;
&amp;quot;How-to manual - Installing a toolchain for Cortex-M3/STM32 on Ubuntu 10.04&amp;quot;&lt;br /&gt;
&lt;br /&gt;
*http://www.seng.de/downloads/HowTo_ToolChain_STM32_Ubuntu.pdf&lt;br /&gt;
*http://www.seng.de/downloads/HowTo_ToolChain_STM32_Ubuntu.odt&lt;br /&gt;
&lt;br /&gt;
Die Beschreibung im OpenOffice Format erlaubt die Weiterbearbeitung des Textes und das Entnehmen von Quelltexten ohne den Verlust von Formatierungen.&lt;br /&gt;
&lt;br /&gt;
Verwendete Hardware:&lt;br /&gt;
*JTAG device&lt;br /&gt;
**Olimex “ARM-USB-OCD-H”, basierend auf FTDI “FT2232H”&lt;br /&gt;
*Microcontroller&lt;br /&gt;
**Olimex “STM32-H103” basierend auf STM32F103RBT6 mit 128KB Flash, 20KB RAM, 3xUART, ...&lt;br /&gt;
Die Toolchain sollte sich leicht an andere &amp;quot;FT2232&amp;quot; basierte JTAG Probes und &amp;quot;Cortex-M3&amp;quot; Derivate anpassen lassen.&lt;br /&gt;
&lt;br /&gt;
Das Manual umfasst die Installation und Inbetriebnahme sowie Hinweise und Bug-fixes zu folgenden Komponenten:&lt;br /&gt;
*OpenOCD&lt;br /&gt;
*stm32flash&lt;br /&gt;
*Sourcery CodeBench Lite for ARM EABI&lt;br /&gt;
*STM32F10x standard peripheral library&lt;br /&gt;
*Project templates&lt;br /&gt;
*Makefiles&lt;br /&gt;
*Linker Sript&lt;br /&gt;
*Startup Code&lt;br /&gt;
*Doxygen&lt;br /&gt;
*Git&lt;br /&gt;
*Terminal emulation&lt;br /&gt;
*Eclipse IDE&lt;br /&gt;
*Links zu Datenblättern, Manuals und Toools&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 (Windows) ===&lt;br /&gt;
&lt;br /&gt;
Hier ist der Anfang des Artikels [[STM32 Eclipse Installation]], hier ist neueres beschrieben als hier aufgeführt. Wenn der Artikel fertig ist, dann wird dieser Teil gelöscht.&lt;br /&gt;
&lt;br /&gt;
* Eclipse &amp;quot;Helios&amp;quot; installieren mit GNU ARM Eclipse Plug-in&lt;br /&gt;
Eclipse IDE for C/C++ Developers&amp;lt;ref&amp;gt;http://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/heliosr&amp;lt;/ref&amp;gt; downloaden und installieren&lt;br /&gt;
&lt;br /&gt;
* GNU ARM Eclipse Plug-in&amp;lt;ref&amp;gt;http://sourceforge.net/projects/gnuarmeclipse/&amp;lt;/ref&amp;gt; runterladen und installieren. [http://sourceforge.net/apps/mediawiki/gnuarmeclipse/index.php?title=Main_Page Weitere Infos].&lt;br /&gt;
&lt;br /&gt;
Wird CodeSourcery G++ Lite verwendet, so muss die PATH Variable angepasst &lt;br /&gt;
werden, damit das Plugin die CodeSourcery exe-Files findet&amp;lt;ref&amp;gt;für Discovery notwendig&amp;lt;/ref&amp;gt;. Alternativ das eclipse von einem script aus starten und zuerst den PATH erweitern.&lt;br /&gt;
&lt;br /&gt;
Soll das ST-LINK verwendet werden, so kann der Atollic ST-LINK GDBSERVER aus der Atollic free version genutzt werden. Mit dem gdbserver im eclipse kann damit problemlos geflasht und gedebuggt werden (JTAG und SWD). Die Startup- und Linkerscripts der Atollic free version können für ein Projekt in dieser Konstallation genutzt werden.&lt;br /&gt;
&lt;br /&gt;
* Eclipse &amp;quot;Galileo&amp;quot; installation&amp;lt;ref&amp;gt;[http://www.eclipse.org/] → Downloads → &amp;quot;Eclipse IDE for C/C++ Developers (79 MB)&amp;lt;/ref&amp;gt;. Und das Servicepack 1&amp;lt;ref&amp;gt;[http://www.eclipse.org/downloads/download.php?file=/technology/epp/downloads/release/galileo/SR1/eclipse-cpp-galileo-SR1-win32.zip Eclipse SR1]&amp;lt;/ref&amp;gt;&lt;br /&gt;
Entpacken der Datei eclipse-cpp-galileo-SR1-win32.zip nach &amp;quot;C:\WinARM\&amp;quot; (Ordner neu erstellen)&lt;br /&gt;
&lt;br /&gt;
* Eclipse PlugIn&amp;lt;ref&amp;gt;http://download.eclipse.org/tools/cdt/releases/galileo&amp;lt;/ref&amp;gt; hinzufügen: Help → Install New Software... → &amp;quot;Eclipse C/C++ Development Tools&amp;quot; + &amp;quot;Eclipse C/C++ GDB Hardware Debugging&amp;quot; installieren&lt;br /&gt;
&lt;br /&gt;
* Yagarto Tools&amp;lt;ref&amp;gt;[http://www.yagarto.de/] &amp;quot;Download (for Windows)&amp;quot; → &amp;quot;YAGARTO Tools&amp;quot; http://www.yagarto.de/download/yagarto/yagarto-tools-20091223-setup.exe Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\yagarto-tools&amp;quot;&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* CodeSourcery: Achtung! Die Menustruktur ändert sich durchaus mal, dann suchen gehen. http://www.codesourcery.com/ → Products → Sourcery G++ → Editions&amp;gt;Lite Edition → ARM → Downloads. Direkter Download&amp;lt;ref&amp;gt;[http://www.codesourcery.com/sgpp/lite/arm/portal/package6496/public/arm-none-eabi/arm-2010q1-188-arm-none-eabi.exe]&amp;lt;/ref&amp;gt;. Installieren, Auswahl Verzeichnis &amp;quot;C:\WinARM\CodeSourcery&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* OpenOCD: Kompilierte Version für Windows&amp;lt;ref&amp;gt;[http://www.freddiechopin.info/] → Download → Software → OpenOCD&amp;lt;/ref&amp;gt; installieren nach &amp;quot;C:\WinARM\OpenOCD_0_4_0&amp;quot; ist auch auf der Seite&amp;lt;ref&amp;gt;[http://yagarto.de/#ocd Yagarto.de]&amp;lt;/ref&amp;gt; beschrieben. PS: Sollte der Olimex ARM-USB-OCD verwendet werden, dann darf nicht der Treiber von Olimex verwendet werden, sondern der vom OpenOCD Download&amp;lt;ref&amp;gt;[http://www.mikrocontroller.net/topic/173753#1668913]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
* ST Firmware: http://www.st.com → Auswahl CPU STM32F103xxx → &amp;quot;Firmware&amp;quot; &amp;quot;STM32F10x_StdPeriph_Lib&amp;quot;&amp;lt;ref&amp;gt;http://www.st.com/mcu/devicedocs-STM32F103RC-110.html&amp;lt;/ref&amp;gt;. Das ZIP &amp;quot;stm32f10x_stdperiph_lib.zip&amp;quot; Entpacken nach &amp;quot;C:\WinARM\examples\stm32_FW3.4.0\&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 auf einem zweiten Rechner===&lt;br /&gt;
&lt;br /&gt;
* Kopieren des Verzeichnisses C:\WinARM\ (Zuvor wurden aus diesem Grund alle Setup-Pakete nach C:\WinARM\... installiert)&lt;br /&gt;
* Die PATH-Variable in der Systemsteuerung mit den C:\WinARM\.... Verzeichnissen nachführen&lt;br /&gt;
* Fertig.&lt;br /&gt;
&lt;br /&gt;
=== Installation für STM32 mit AtollicTrueStudio (+Demo) ===&lt;br /&gt;
* Installation + Demo: [[STM32 LEDBlinken AtollicTrueStudio]]&lt;br /&gt;
&lt;br /&gt;
== Demo-Projekte ==&lt;br /&gt;
&lt;br /&gt;
* [[prog_bsp_timer_1_timer2|Programmbeispiel für die Verwendung von Timer2 zusammen mit dem Interrupt]]&lt;br /&gt;
* [http://www.firefly-power.de/ARM/printf.html Printf() debugging mit minimalem Aufwand]&lt;br /&gt;
* [[STM32_BLDC_Control_with_HALL_Sensor|Programmbeispiel für BLDC Motoransteuerung (Timer 1) mit HALLSensor (Timer 3)]]&lt;br /&gt;
* [[Cortex_M3_OCM3U]]&lt;br /&gt;
* Martin Thomas hat ein umfangreiches Projekt erstellt, in der die Eclipse Einstellungen enthalten sind:&lt;br /&gt;
** [http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/index.html &amp;quot;ChaN&#039;s FAT-Module with STM32 SPI&amp;quot;]&lt;br /&gt;
* [[STM32 USB-FS-Device Lib]]&lt;br /&gt;
* Modellbau-Sender auf STM32-Basis mit vielen Treibern [http://www.rcos.eu www.rcos.eu]&lt;br /&gt;
* Ausführliches [https://github.com/jkerdels/stm32edu Einstiegs-Tutorial] in Codeform für das [http://www.st.com/internet/evalboard/product/252419.jsp STM32F4 discovery board]&lt;br /&gt;
&lt;br /&gt;
== Errata, Tipps und Tricks ==&lt;br /&gt;
&lt;br /&gt;
* AD-Wandler PA0: Im Errata steht, dass hier Fehler in der Wandlung entstehen könnten, also einen anderen Pin verwenden.&lt;br /&gt;
* CAN-Bus PD0/PD1: Remap geht erst ab der 100-Pin-Version. Steht im RM0008 unter 9.3.3.: &amp;quot;CAN1 alternate function remapping&amp;quot;. Alle Infos von RM0008 9.3.x sind interessant&lt;br /&gt;
* CAN und USB sind nur bei der &amp;quot;◦Connectivity-Line&amp;quot; gleichzeitig nutzbar. Siehe Datenblätter.&lt;br /&gt;
* Mit internem RC-Oszillator kann die CPU mit maximal 64MHz betrieben werden. Mit einem externen Quarz sind dann 72MHz möglich.&lt;br /&gt;
* Für USB Betrieb muss die CPU mit 48MHz oder 72MHz betrieben werden (bei STM32F1xx).&lt;br /&gt;
* Der Idle Interrupt vom Usart wird zwar ausgelöst, aber nicht vom entsprechenden Statusflag angezeigt&lt;br /&gt;
* Der DMA fängt beim aktivieren immer von vorn an zu zählen, auch wenn er nur kurz angehalten wurde&lt;br /&gt;
* STM32F2xx hat kein Flash Size Register, bei STM32F4xx ist zwar ein flash Size Register beschrieben, kollidiert aber in der Adresse mit einem anderen Register&lt;br /&gt;
* Derivate mit internem EEPROM und nur einer Speicherbank haben das &amp;quot;Feature&amp;quot; bei write/erase des Data-Flashes (EEPROM) einen kompletten stall der code execution zu verursachen (inkl. ISR&#039;s, DMA). Desgleichen bei write/erase des internen Flash (ISP-routinen, EEPROM-Emulation).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Tipps für Umsteiger von Atmel/PIC/8051 ===&lt;br /&gt;
* Prozessortakt hat unterschiedliche Taktquellen und eine PLL.&lt;br /&gt;
* Alle Peripheriemodule haben einen extra Clock, den man aktivieren muss.&lt;br /&gt;
* Wenn man z.B. einen UART benutzen möchte, so muss man den Clock vom UART, Alternate Function IO (AFIO) und dem GPIO-Port aktivieren.&lt;br /&gt;
* Ansonsten hat man nahezu doppelt so viele Möglichkeiten in den Peripheriemodulen.&lt;br /&gt;
* Interrupt-Flags müssen in der ISR selber gelöscht werden&lt;br /&gt;
* Forum zu [http://www.mikrocontroller.net/topic/175888 Interrupts vs. Events]&lt;br /&gt;
&lt;br /&gt;
=== Tipp FPU von STM32F4xx nutzen ===&lt;br /&gt;
Es benötigt dafür 2 Dinge, zum einen muss die Compileroption gesetzt sein, zum anderen auch die FPU aktiviert werden:&lt;br /&gt;
&lt;br /&gt;
Compileroption:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;COMMON_FLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Code für das Aktivieren der FPU:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;/*FPU settings*/&lt;br /&gt;
__asm volatile (&amp;quot;ldr     r0, =0xE000ED88&amp;quot;);           /* Enable CP10,CP11 */&lt;br /&gt;
__asm volatile (&amp;quot;ldr     r1,[r0]&amp;quot;);&lt;br /&gt;
__asm volatile (&amp;quot;orr     r1,r1,#(0xF &amp;lt;&amp;lt; 20)&amp;quot;);&lt;br /&gt;
__asm volatile (&amp;quot;str     r1,[r0]&amp;quot;);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ohne Inline-Assembler in C wie in system_stm32f4xx.c aus den Beispielen von ST-Microelectronics:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
SCB-&amp;gt;CPACR |= ((3UL &amp;lt;&amp;lt; 10*2)|(3UL &amp;lt;&amp;lt; 11*2)); /* set CP10 and CP11 Full Access */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mehr dazu in diesem Thread: [http://www.mikrocontroller.net/topic/261021 Floating Pointing Unit STM32F4]&lt;br /&gt;
&lt;br /&gt;
=== Errata vom STM32F4xx die nicht im Errata von ST stehen ===&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/267439#2788478 Aktivieren von DMA], wenn mehr als 3 DMA Kanäle aktiviert werden, kann es sein dass die nicht alle korrekt bedient werden. Auch klappt der DMA mit dem FSMC nicht immer zuverlässig. [https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2Fpublic%2FSTe2ecommunities%2Fmcu%2FLists%2Fcortex_mx_stm32%2FWarning%20limit%20simultaneous%20DMAs%20to%202&amp;amp;FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&amp;amp;currentviews=811 siehe hier] [http://blog.frankvh.com/2012/01/13/stm32f2xx-stm32f4xx-dma-maximum-transactions/ und hier]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/260637#2700761 Nerviger Bug in &amp;quot;stm32f4xx.h&amp;quot;] Änderung Struktur GPIO_TypeDef&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/261690#2714754 Batterie wird leer gezogen], nur bei manchen Chips mit Rev. A&lt;br /&gt;
&lt;br /&gt;
== Bezugsquellen ==&lt;br /&gt;
&lt;br /&gt;
=== Controller ===&lt;br /&gt;
&lt;br /&gt;
Versandhäuser für Privatpersonen&lt;br /&gt;
&lt;br /&gt;
* [http://darisusgmbh.de/shop/index.php?cat=c2692_ARM-Cortex.html Darisus]&lt;br /&gt;
* [http://www.hbe-shop.de HBE (Farnell Programm für Private)] &lt;br /&gt;
* [http://www.sander-electronic.de/be00069.html Sander]&lt;br /&gt;
* [http://www.rs-online.com RS-Online]&lt;br /&gt;
*[http://www.tme.eu/de/katalog/index.phtml#cleanParameters%3D1%26search%3DSTM32F10%26bf_szukaj%3D+ TME] &lt;br /&gt;
* [https://www.distrelec.de/ishopWebFront/catalog/product.do/para/keywords/is/STM32_ARM-Microcontroller/and/language/is/de/and/shop/is/DE/and/series/is/1/and/id/is/01/and/node/is/34910.html Distrelec]&lt;br /&gt;
&lt;br /&gt;
Gewerblich liefern natürlich viele wie Mouser, Farnell, Digikey usw...&lt;br /&gt;
&lt;br /&gt;
=== Evaluation Boards ===&lt;br /&gt;
&lt;br /&gt;
* [http://shop.embedded-projects.net/index.php?module=artikel&amp;amp;action=gruppe&amp;amp;id=14 Im Shop von Embedded Projects]&lt;br /&gt;
* [http://www.watterott.com/de/Boards-Kits/ARM/ARM-Cortex-M3 Cortex M3 bei Watterott]&lt;br /&gt;
* [http://www.raisonance.com/~primer-starter-kits__microcontrollers__tool~tool__T018:4enfvamuxbtp.html Primer und Primer2 von Raisonance]&lt;br /&gt;
* [http://www.sander-electronic.de/es0028.html Sander Electronic]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/MP32F103-Stick:_Ein_Mini-Mikrocontroller-Board_mit_USB_und_bis_zu_4MB_Datenspeicher Artikel im Wiki, ARM mit USB und 4MB Speicher]&lt;br /&gt;
* [http://www.futurlec.com/STM32_Development_Board.shtml Futurlec Evalboard, ebenso Header-Board]&lt;br /&gt;
* [http://www.propox.com/products/t_174.html Propox, Header-Boards für 103R und 103V sowie Trägerplatine dafür]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/Cortex_M3_OCM3U Cortex M3 Artikel im Wiki]&lt;br /&gt;
* [http://olimex.com/dev/index.html STM32 bei Olimex]&lt;br /&gt;
* [http://de.farnell.com/jsp/displayProduct.jsp?sku=1824325&amp;amp;action=view&amp;amp;CMP=GRHS-1000962 STM32Discovery bei Farnell] Mikrocontroller Board (STM32F100RBT6B) mit onboard USB-Programming Interface für ca. 12,50€&lt;br /&gt;
* [http://www.de.rs-online.com/web/p/products/7458434/ STM32Discovery bei RS-Components] 12,65 € +MwSt.&lt;br /&gt;
* [http://www.segor.de/#Q=STM32 VL DISCOVERY] STM32 Discovery bei Segor&lt;br /&gt;
* [http://www.watterott.com/de/STM32F4Discovery STM32F4DISCOVERY] STM32F4 Cortex M4 Controller mit JTAG-Debugger auf der Platine bei Watterott für 16,66EUR.&lt;br /&gt;
* [http://www.steitec.net/ARM-Boards/ Steitec, STM32F103 Cortex M3 Board 34,80€]&lt;br /&gt;
* [http://www.mcu-raisonance.com/~open4-development-platform__microcontrollers__tool~tool__T018:g65gu6ghg2n.html/ Open 4 oder auch genannt Evo-Primer]&lt;br /&gt;
* [http://www.wayengineer.com/index.php?main_page=index&amp;amp;cPath=50_66&amp;amp;page=1&amp;amp;sort=3a WayEngineer]&lt;br /&gt;
&lt;br /&gt;
== Weblinks, Foren, Communities ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/173753 Diskussion zum Artikel]&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/mikrocontroller-elektronik?filter=ARM*+STM32*+Cortex* Suche im Forum]&lt;br /&gt;
* [https://my.st.com/public/STe2ecommunities/mcu/Lists/ARM%20CortexM3%20STM32/AllItems.aspx Forum auf der ST Homepage] &lt;br /&gt;
* [http://www.stm32circle.com/hom/index.php STM32 Community] &lt;br /&gt;
*[http://www.arm-forum.de Deutsches ARM-Forum]&lt;br /&gt;
*[http://joe-c.de/pages/posts/einstieg_mikrocontroller_stm32f103_101.php Einstieg:  STM32board mit Kamera (deutsch)] &lt;br /&gt;
* [http://www.ebv.com/fileadmin/products/Press_Print/Brochures/Product_Brochures/EBV_Cortex%20Collection_V2.pdf Übersicht der Cortex Prozessoren und deren Hersteller (nicht nur ST, von EBV)]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/258652 Tutorial]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
[[Kategorie:ARM]]&lt;br /&gt;
[[Kategorie:STM32| ]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=MMC-_und_SD-Karten&amp;diff=67717</id>
		<title>MMC- und SD-Karten</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=MMC-_und_SD-Karten&amp;diff=67717"/>
		<updated>2012-08-03T16:08:30Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: OpenFAT dazu&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;MMC- und SD-Speicherkarten lassen sich im [[SPI]]-Modus relativ einfach mit einem Mikrocontroller ansteuern. Prinzipiell gibt es zwischen SD-Card und MMC nicht viele Unterschiede, allerdings sind SD-Karten weiter verbreitet, in der Regel schneller als MMCs, und haben ein besser implementiertes SPI-Interface. Es existieren diverse Varianten (miniSD, microSD), die zur normalen SD-Card weitgehend kompatibel sind.&lt;br /&gt;
&lt;br /&gt;
Die Karte liest das anliegende Datenbit mit der steigenden Taktflanke ein, als SPI-Modi eignen sich somit Mode 0 (CPOL=0, CPHA=0) und Mode 3 (CPOL=1, CPHA=1) (siehe auch [[Serial Peripheral Interface]]). Bei MMCs ist der SPI-Modus nicht genau spezifiziert, somit kommt es durchaus mal vor dass der SPI-Modus je nach Karte unterschiedlich gewählt werden muss, oder dass die Karte überhaupt nicht zuverlässig funktioniert (siehe [http://www.mikrocontroller.net/forum/read-1-343528.html Beitrag im Forum]).&lt;br /&gt;
&lt;br /&gt;
== DOs und DON&#039;Ts bei der Ansteuerung ==&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Lasst euch nicht verrückt machen&#039;&#039;&#039; wenn es einfach nicht funktioniert, sondern probiert zu allererst mal eine SD-Karte eines anderen Herstellers aus. Die MMC-Implementierung für AVR von Elm Chan z.&amp;amp;nbsp;B. funktioniert mit SanDisk problemlos hat aber mit Platinum Karten ein Problem.&lt;br /&gt;
* Taktfrequenz bei der Initialisierung nicht höher als 400kHz&lt;br /&gt;
* Ein Pullup-Widerstand am Ausgang der MMC/SD Karte (DO) ist für eine saubere Initialisierung per SPI notwendig! [http://www.mikrocontroller.net/topic/112421#1001693 (Thread mit Erklärung dazu)]&lt;br /&gt;
* Saubere Versorgung: Kein Dioden-Pfusch, mit dem eine vorhandene 5V Versorgung mittels in Reihe geschalteter Dioden auf irgendwas im Bereich 3V &amp;quot;geregelt&amp;quot; wird. Stattdessen einen guten 3,3V-Regler verwenden. Die Karte mag es nicht, wenn mehr als 60mV Ripple auf Vcc ist. LM317 oder LM1117-ADC/-3.3 mit entspechenden Kondensatoren reicht zumindest bei Basteleien allemal.&lt;br /&gt;
* Sauberer Anschluss der Digitalschnittstelle: Spannungsteiler &amp;quot;verschleifen&amp;quot; die Signale bei hohen Frequenzen und die Übertragungsrate muss dann begrenzt werden. Also entweder ein [http://www.mikrocontroller.net/articles/Pegelwandler Pegelwandler] oder gleich an ein 3,3V I/O anschließen.&lt;br /&gt;
* Ein Pullup-Widerstand an der Select-Leitung (/CS) schadet nicht und stellt sicher, dass die Karte erst mit Absicht selektiert wird.&lt;br /&gt;
* Nachdem die Karte deselektiert wurde (/CS auf high), die Taktleitung noch einige Male pulsen, damit die Karte DO hochohmig/tri-state schaltet (vgl. Chans Erläuterungen).&lt;br /&gt;
* Die Karten verfügen weder über einen Reset- noch einen Sleep-Anschluss. Moderne Karten reduzieren bei Nichtbenutzung ihren Stromverbrauch, einen vollständigen Reset kann man jedoch nicht per Software auslösen. Daher sollten die Karten per P-Channel-FET oder Spannungsregler/-wandler mit Enable-Funktion so angeschlossen werden, dass über Versorgung an/aus ein (Power-On-)Reset ausgelöst werden kann. Dabei darauf achten, dass vorhandene Pull-Up-Widerstände bei abgeschalteter Versorgung ebenfalls deaktiviert werden (vgl. z.&amp;amp;nbsp;B. Schaltplan für den Anschluss von SD-Card/MMC per SPI an AVR in Chans Beispielen. Link unten).&lt;br /&gt;
* Guter Kontakt im Steckplatz, sehr gut eignen sich mit der Zange verbogene Stiftleisten, oft sieht es aus als ob es &amp;quot;passt&amp;quot;, aber es gibt doch keinen Kontakt, daher bei Fehlern: Immer Durchmessen! Auch zu erwähnen wären da alte ISA-Bus Buchsen, die auf jedem alten PC Mainboard drauf sind. Um sicher zu gehen, dass der Kontakt wirklich gut ist, sollte man aber trotzdem SD-Slots benutzen. Diese bekommt man u.a. bei CSD (günstig), Reichelt (teuer) oder aus alten Kartenlesern.&lt;br /&gt;
* Guter Kontakt #2: Was sich im übrigen auch sehr gut eignet sind Adapter von MiniSD auf normales SD-Format, um dann MiniSD zu benutzen. Wenn man eine Stiftleiste im 2.54mm-Format oder Lötnägel im selben Format auf der Platine hat, kann man daran wunderbar den SD-Kartenadapter anlöten. Das ist mechanisch recht stabil. Ein kleines Manko ist allerdings, daß dann eine Gold-Lötzinn-Legierung durch die vergoldeten Kontakte entsteht und das soll ja dem Lötzinn langfristig nicht sehr zuträglich sein. Aber für&#039;s Hobby funktioniert das wunderbar.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;0&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
||[[Bild:SD Steck Stift.jpg]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&amp;lt;sup&amp;gt;(Liefere Bild in besserer Qualität nach!)&amp;lt;/sup&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Bibliotheken zur Ansteuerung ==&lt;br /&gt;
&lt;br /&gt;
* [http://elm-chan.org/fsw/ff/00index_e.html ELM ChaN FatFs]  FAT(12,16,32)-Dateisystem. Klein und übersichtlich, hochoptimiert, frei auch für kommerzielle Anwendung. Beispiele für AVR, H8, LPC2k mit MCI u.a. enthalten (&amp;quot;samples&amp;quot;), neuere Versionen mit LFN-Unterstützung. Beispiel für AT91SAM7 inkl. DMA im Projekt [[ARM MP3/AAC Player]]. (siehe auch [http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/ M. Thomas&#039; ARM+SD/MMC Seite])&lt;br /&gt;
&lt;br /&gt;
* [http://elm-chan.org/fsw/ff/00index_p.html ELM ChaN Petit FatFS] FAT(12,16,32)-Dateisystem. Sehr klein. Beispiele für AVR.&lt;br /&gt;
&lt;br /&gt;
* [http://sourceforge.net/projects/efsl EFSL] FAT16/32-Dateisystem, unterstützt Partitionen und Superfloppys, Beispielcode für AVR, LPC2000 und AT91SAM7 enthalten (siehe auch [http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/arm_memcards/ M. Thomas&#039; ARM+SD/MMC Seite])&lt;br /&gt;
&lt;br /&gt;
* [http://www.holger-klabunde.de/avr/avrboard.htm#cf Holger Klabundes FAT16/32] mit Beispielen für AVR MMC/SD und CF, LPC2k mit SPI&lt;br /&gt;
&lt;br /&gt;
* libfat aus dem [http://sourceforge.net/projects/devkitpro devkitpro-Projekt] u.a. LFN-Unterstützung.&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikro-control.de/Joomla/index.php?option=com_content&amp;amp;task=view&amp;amp;id=18&amp;amp;Itemid=30 SD-Logger] - FAT 16, für den privaten Einsatz kostenfrei&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-4-125350.html MMC-Ansteuerung mit FAT16 von Ulrich Radig]&lt;br /&gt;
&lt;br /&gt;
* [http://www.zws.com/products/dosfs/index.html DOSFS Free FAT12/FAT16/FAT32 Filesystem] &amp;quot;DOSFS is a free FAT-compatible filesystem intended for fairly low-end embedded applications. Intended target systems would be in the ballpark of 1K RAM, 4K ROM or more&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/48481 MMC/SD-Karte mit FAT16 an AVR] von Roland Riegel&lt;br /&gt;
&lt;br /&gt;
* [ftp://ftp.circuitcellar.com/pub/Circuit_Cellar/2005/176/Sham176.zip Circuit Cellar FAT16 MMC/SD] mit MMC/SD Hardwaretreiber für MSP430&lt;br /&gt;
&lt;br /&gt;
* [http://www.analog.com &amp;quot;Implementing FAT32 File Systems on ADSP-BF533 Blackfin Processors&amp;quot;] Application Note und Code von ADI&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/dyn/products/tools.asp?family_id=682 FAT-Code in Atmel&#039;s AVR32 UC3 Software-Library]&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/FAT32 AVR FAT16/32] Bibliothek mit Wiki. Unterstützt LFN und Ordner Rekursiv löschen. SVN für neuste Version.&lt;br /&gt;
&lt;br /&gt;
* [http://www.embedded-os.de/index.html?pcfat_port.htm pC/FAT driver] &amp;quot;using SPI for sector read/write to MMC/MMCplus/HD-MMC/M-Bridge/SD/SDHC-cards on different platforms&amp;quot;&lt;br /&gt;
&lt;br /&gt;
* [http://www.dharmanitech.com/2009/01/sd-card-interfacing-with-atmega8-fat32.html SD Card Interfacing with ATmega8] (FAT32 implementation) by CC Dharmani&lt;br /&gt;
&lt;br /&gt;
* [http://www.blacksphere.co.nz/main/openfat OpenFAT]: &amp;quot;OpenFAT is a FAT filesystem implementation intended for use with embedded microcontrollers in small systems. (...) OpenFAT is licensed under the GPL, version 3.&amp;quot;&lt;br /&gt;
&lt;br /&gt;
== Allgemeine Informationen ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.digitalspirit.org/file/index.php/obj/docs/sd/ Datenblätter] ( [http://www.digitalspirit.org/file/index.php/obj-download/docs/sd/ProductManualSDCardv2.2final.pdf SD Card Product Manual 2.2] )&lt;br /&gt;
&lt;br /&gt;
* [http://elm-chan.org/docs/mmc/mmc_e.html ELM ChaN - How to Use an MMC]&lt;br /&gt;
&lt;br /&gt;
* [http://elm-chan.org/fsw/ff/00index_e.html ELM ChaN - FatFs Generic FAT File System Module]&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/list-1-1.html?filter=MMC*+SD Beiträge zum Thema MMC/SD im Forum (ca. 200 Threads)]&lt;br /&gt;
&lt;br /&gt;
* [http://www.shop.display3000.com/elektronikmodule/sd-speicherkartenplatine.html Weiter unten im Text (runterscrollen) gibt es interessante Oszi-Bilder zu den oft genannten Spannungsteilern oder Transistorlösungen als Pegelwandler]&lt;br /&gt;
&lt;br /&gt;
* [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=2680&amp;amp;dDocName=en547784 Microchip Memory Disk Drive System mit FAT32 und SDHC Unterstützung]&lt;br /&gt;
&lt;br /&gt;
* [http://www.ifas.htwk-leipzig.de/easytoweb/download/D&amp;amp;E_11_2006_Anbindung_von_SD-Karten.pdf Gute Beschreibung der SDIO-Architektur und wie man eine SD-Karte mit ARM bzw. AVR benutzt]&lt;br /&gt;
&lt;br /&gt;
== Bauteile ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.instructables.com/id/EZD6Q18LYGES1762SJ/ DIY SD-Card Fassung aus einem alten Floppy Kabel]&lt;br /&gt;
&lt;br /&gt;
* [http://www.watterott.com/index.php?page=search&amp;amp;page_action=query&amp;amp;desc=on&amp;amp;sdesc=on&amp;amp;keywords=multicomp&amp;amp;x=0&amp;amp;y=0 Halter für SD-Karten]&lt;br /&gt;
&lt;br /&gt;
* [http://www.shop.display3000.com/elektronikmodule/sd-speicherkartenplatine.html günstige Komplettlösung mit bidirektionalem Pegelwandler, Spannungsregler, Kartenhalter]&lt;br /&gt;
&lt;br /&gt;
== Projekte ==&lt;br /&gt;
&lt;br /&gt;
* [http://retromaster.wordpress.com/ufe/ Ultimate Floppy Emulator] von Retromaster (PIC32 @ 80 Mhz, 16 Mb SDRAM)&lt;br /&gt;
&lt;br /&gt;
[[Category:Bauteile]]&lt;br /&gt;
[[Category:Datenübertragung]]&lt;br /&gt;
[[Kategorie:Speicher und Dateisysteme]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Kategorie:Boards&amp;diff=66547</id>
		<title>Kategorie:Boards</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Kategorie:Boards&amp;diff=66547"/>
		<updated>2012-05-28T06:48:04Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: Änderungen von 58.23.208.70 (Diskussion) rückgängig gemacht und letzte Version von Doschi wiederhergestellt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Kategorie:!Hauptkategorie]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Mthomas&amp;diff=66068</id>
		<title>Benutzer:Mthomas</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Mthomas&amp;diff=66068"/>
		<updated>2012-05-03T09:12:42Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* http://www.siwawi.arubi.uni-kl.de/avr_projects/&lt;br /&gt;
* http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Mthomas&amp;diff=66067</id>
		<title>Benutzer:Mthomas</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Mthomas&amp;diff=66067"/>
		<updated>2012-05-03T09:12:24Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: Hob den Schutz von „Benutzer:Mthomas“ auf&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* http://www.siwawi.arubi.uni-kl.de/avr_projects/&lt;br /&gt;
* http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/&lt;br /&gt;
&lt;br /&gt;
:{| {{Tabelle}}&lt;br /&gt;
 |-&lt;br /&gt;
 | 1&lt;br /&gt;
 | 2   &lt;br /&gt;
 |-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Mthomas&amp;diff=66061</id>
		<title>Benutzer:Mthomas</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Mthomas&amp;diff=66061"/>
		<updated>2012-05-03T01:40:54Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: Schützte „Benutzer:Mthomas“: Weblink-Spam:&amp;amp;#32;Vorlage:Tabelle im Text genutzt - versuch Kaskadenschutz ([edit=sysop] (bis 3. November 2012, 02:40 Uhr (UTC)) [move=sysop] (bis 3. November 2012, 02:40 Uhr (UTC))) [kaskadierend]&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* http://www.siwawi.arubi.uni-kl.de/avr_projects/&lt;br /&gt;
* http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/&lt;br /&gt;
&lt;br /&gt;
:{| {{Tabelle}}&lt;br /&gt;
 |-&lt;br /&gt;
 | 1&lt;br /&gt;
 | 2   &lt;br /&gt;
 |-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Benutzer:Mthomas&amp;diff=66060</id>
		<title>Benutzer:Mthomas</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Benutzer:Mthomas&amp;diff=66060"/>
		<updated>2012-05-03T01:39:22Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;* http://www.siwawi.arubi.uni-kl.de/avr_projects/&lt;br /&gt;
* http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/&lt;br /&gt;
&lt;br /&gt;
:{| {{Tabelle}}&lt;br /&gt;
 |-&lt;br /&gt;
 | 1&lt;br /&gt;
 | 2   &lt;br /&gt;
 |-&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Vorlage:Tabelle&amp;diff=66059</id>
		<title>Vorlage:Tabelle</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Vorlage:Tabelle&amp;diff=66059"/>
		<updated>2012-05-03T01:32:24Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: Schützte „Vorlage:Tabelle“ ([edit=sysop] (bis 3. Mai 2013, 01:32 Uhr (UTC)) [move=sysop] (bis 3. Mai 2013, 01:32 Uhr (UTC)))&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;border=&amp;quot;1&amp;quot; cellpadding=&amp;quot;4&amp;quot; style=&amp;quot;margin: 1em 1em 1em 0; background: #f9f9f9; border: 1px #AAA solid; border-collapse: collapse; empty-cells:show; {{{1}}} }&amp;quot;&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR-GCC-Tutorial&amp;diff=65884</id>
		<title>AVR-GCC-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR-GCC-Tutorial&amp;diff=65884"/>
		<updated>2012-04-23T19:31:42Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* Programmieren mit Interrupts */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Voraussetzungen =&lt;br /&gt;
&lt;br /&gt;
Vorausgesetzt werden Grundkenntnisse der Programmiersprache C. Diese Kenntnisse kann man sich online erarbeiten, z. B. mit dem [http://www.schellong.de/c.htm C Tutorial von Helmut Schellong] ([[C|Liste von C-Tutorials]]). Nicht erforderlich sind Vorkenntnisse in der Programmierung von Mikrocontrollern, weder in Assembler noch in einer anderen Sprache.&lt;br /&gt;
&lt;br /&gt;
= Vorwort =&lt;br /&gt;
&lt;br /&gt;
Dieses Tutorial soll den Einstieg in die Programmierung von Atmel [[AVR]]-Mikrocontrollern in der Programmiersprache [[C]] mit dem freien C-Compiler [[AVR-GCC]] aus der [http://gcc.gnu.org/ GNU Compiler Collection] erleichtern.&lt;br /&gt;
&lt;br /&gt;
In diesem Text wird häufig auf die Standardbibliothek avr-libc verwiesen, für die es eine [http://www.nongnu.org/avr-libc/user-manual/index.html Online-Dokumentation] gibt, in der sich auch viele nützliche Informationen zum Compiler und zur Programmierung von AVR Controllern finden (beim Paket WinAVR gehört die avr-libc Dokumentation zum Lieferumfang und wird mitinstalliert).&lt;br /&gt;
&lt;br /&gt;
Der Compiler und die Standardbibliothek avr-libc werden stetig weiterentwickelt. Einige Unterschiede, die sich im Verlauf der Entwicklung ergeben haben, werden im Haupttext und Anhang zwar erläutert, Anfängern sei jedoch empfohlen, die aktuellen Versionen zu nutzen (für MS-Windows: aktuelle Version des [[WinAVR]]-Pakets; für Linux: siehe Artikel [[AVR und Linux]]).&lt;br /&gt;
&lt;br /&gt;
Das ursprüngliche Tutorial stammt von Christian Schifferle, viele neue Abschnitte und aktuelle Anpassungen von Martin Thomas.&lt;br /&gt;
&lt;br /&gt;
Dieses Tutorial ist in PDF-Form hier erhältlich (nicht immer auf aktuellem Stand):&lt;br /&gt;
[[Media:AVR-GCC-Tutorial.pdf]]&lt;br /&gt;
&lt;br /&gt;
== Weiterführende Kapitel ==&lt;br /&gt;
&lt;br /&gt;
Um dieses riesige Tutorial etwas überschaubarer zu gestalten, wurden einige Kapitel ausgelagert, die nicht unmittelbar mit den Grundlagen von avr-gcc in Verbindung stehen. All diese Seiten gehören zur [[:Kategorie:avr-gcc Tutorial]].&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Der UART|Der UART]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Analoge Ein- und Ausgabe|Analoge Ein- und Ausgabe]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Der Watchdog|Der Watchdog]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Die Timer und Zähler des AVR|Die Timer und Zähler des AVR]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Exkurs Makefiles|Exkurs Makefiles]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/LCD-Ansteuerung|LCD-Ansteuerung]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Alte Quellen|Alte Quellen anpassen]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Assembler und Inline-Assembler|Assembler und Inline-Assembler]]&lt;br /&gt;
&lt;br /&gt;
= Benötigte Werkzeuge =&lt;br /&gt;
&lt;br /&gt;
Um eigene Programme für AVRs mittels avr-gcc/avr-libc zu erstellen und zu testen, wird folgende Hard- und Software benötigt:&lt;br /&gt;
&lt;br /&gt;
* Platine oder Versuchsaufbau für die Aufnahme eines AVR Controllers, der vom avr-gcc Compiler unterstützt wird (alle ATmegas und die meisten AT90, siehe Dokumentation der avr-libc für unterstützte Typen). Dieses Testboard kann durchaus auch selbst gelötet oder auf einem Steckbrett aufgebaut werden. Einige Registerbeschreibungen dieses Tutorials beziehen sich auf den inzwischen veralteten AT90S2313. Der weitaus größte Teil des Textes ist aber für alle Controller der AVR-Familie gültig. Brauchbare Testplattformen sind auch das [[STK500]] und der [[AVR Butterfly]] von Atmel. Weitere Infos findet man in den Artikeln [[AVR#Starterkits|AVR Starterkits]] und [[AVR-Tutorial: Equipment]].&lt;br /&gt;
&lt;br /&gt;
* Der avr-gcc Compiler und die avr-libc. Kostenlos erhältlich für nahezu alle Plattformen und Betriebssysteme. Für MS-Windows im Paket [[WinAVR]]; für Unix/Linux siehe auch Hinweise im Artikel [[AVR-GCC]] und im Artikel [[AVR und Linux]].&lt;br /&gt;
&lt;br /&gt;
* Programmiersoftware und -[[AVR In System Programmer |hardware]] z. B. PonyProg (siehe auch: [[Pony-Prog Tutorial]]) oder [[AVRDUDE]] mit [[STK200]]-Dongle oder die von Atmel verfügbare Hard- und Software ([[STK500]], Atmel AVRISP, [[AVR-Studio]]).&lt;br /&gt;
&lt;br /&gt;
* Nicht unbedingt erforderlich, aber zur Simulation und zum Debuggen unter MS-Windows recht nützlich: [[AVR-Studio]] (siehe Artikel [[AVR-GCC-Tutorial/Exkurs_Makefiles|Exkurs: Makefiles]]).&lt;br /&gt;
&lt;br /&gt;
* Wer unter Windows und Linux gleichermassen entwickeln will, der sollte sich die [http://www.eclipse.org/ IDE Eclipse for C/C++ Developers] und das [http://avr-eclipse.sourceforge.net/wiki/index.php/The_AVR_Eclipse_Plugin AVR-Eclipse Plugin ] ansehen, beide sind unter Windows und Linux einfach zu installieren. Hier gibt es auch einen [[AVR_Eclipse|Artikel AVR Eclipse]] in dieser Wiki. Ebenfalls unter Linux und Windows verfügbar ist die Entwicklungsumgebung [http://www.codeblocks.org/ Code::Blocks] (aktuelle, stabile Versionen sind als Nightly Builds regelmäßig im [http://forums.codeblocks.org/ Forum] verfügbar). Innerhalb dieser Entwicklungsumgebung können ohne die Installation zusätzlicher Plugins &amp;quot;AVR-Projekte&amp;quot; angelegt werden. Für Linux gibt es auch noch das [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=25220&amp;amp;postdays=0&amp;amp;postorder=asc&amp;amp;start=0 KontrollerLab].&lt;br /&gt;
&lt;br /&gt;
= Was tun, wenn&#039;s nicht klappt? =&lt;br /&gt;
&lt;br /&gt;
* Herausfinden, ob es tatsächlich ein avr(-gcc) spezifisches Problem ist oder nur die eigenen C-Kenntnisse einer Auffrischung bedürfen. Allgemeine C-Fragen kann man eventuell &amp;quot;beim freundlichen Programmierer zwei Büro-, Zimmer- oder Haustüren weiter&amp;quot; loswerden. Ansonsten: [[C]]-Buch (gibt&#039;s auch &amp;quot;gratis&amp;quot; online) lesen.&lt;br /&gt;
&lt;br /&gt;
* Die [[AVR Checkliste]] durcharbeiten.&lt;br /&gt;
&lt;br /&gt;
* Die &#039;&#039;&#039;[http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc]&#039;&#039;&#039; lesen, vor allem (aber nicht nur) den Abschnitt Related Pages/&#039;&#039;&#039;Frequently Asked Questions&#039;&#039;&#039; = Oft gestellte Fragen (und Antworten dazu). Z.Zt leider nur in englischer Sprache verfügbar.&lt;br /&gt;
&lt;br /&gt;
* Den Artikel [[AVR-GCC]] in diesem Wiki lesen.&lt;br /&gt;
&lt;br /&gt;
* Das [http://www.mikrocontroller.net/forum/gcc GCC-Forum auf  www.mikrocontroller.net] nach vergleichbaren Problemen absuchen.&lt;br /&gt;
&lt;br /&gt;
* Das avr-gcc-Forum bei [http://www.avrfreaks.net AVRfreaks] nach vergleichbaren Problemen absuchen.&lt;br /&gt;
&lt;br /&gt;
* Das [http://lists.gnu.org/archive/html/avr-gcc-list/ Archiv der avr-gcc Mailing-Liste] nach vergleichbaren Problemen absuchen.&lt;br /&gt;
&lt;br /&gt;
* Nach Beispielcode suchen. Vor allem im &#039;&#039;Projects&#039;&#039;-Bereich von [http://www.avrfreaks.net AVRfreaks] (anmelden).&lt;br /&gt;
&lt;br /&gt;
* Google oder yahoo befragen schadet nie.&lt;br /&gt;
&lt;br /&gt;
* Bei Problemen mit der Ansteuerung interner AVR-Funktionen mit C-Code: das Datenblatt des Controllers lesen (ganz und am Besten zweimal). Datenblätter sind  auf den [http://www.atmel.com Atmel Webseiten] als pdf-Dateien verfügbar. Das komplette Datenblatt (complete) und nicht die Kurzfassung (summary) verwenden.&lt;br /&gt;
&lt;br /&gt;
* Die Beispielprogramme im [[AVR-Tutorial]] sind zwar in AVR-Assembler verfasst, Erläuterungen und Vorgehensweisen sind aber auch auf C-Programme übertragbar.&lt;br /&gt;
&lt;br /&gt;
* Einen Beitrag in eines der Foren oder eine Mail an die Mailing-Liste schreiben. Dabei möglichst viel Information geben: Controller, Compilerversion, genutzte Bibliotheken, Ausschnitte aus dem Quellcode oder besser ein [http://www.mikrocontroller.net/topic/72767#598986 Testprojekt] mit allen notwendigen Dateien, um das Problem nachzuvollziehen, sowie genaue Fehlermeldungen bzw. Beschreibung des Fehlverhaltens. Bei Ansteuerung externer Geräte die Beschaltung beschreiben oder skizzieren (z. B. mit [http://www.tech-chat.de/ Andys ASCII Circuit]). Siehe dazu auch: &#039;&#039;&#039;[http://www.tty1.net/smart-questions_de.html &amp;quot;Wie man Fragen richtig stellt&amp;quot;]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= Erzeugen von Maschinencode =&lt;br /&gt;
&lt;br /&gt;
Aus dem C-Quellcode erzeugt der avr-gcc Compiler (zusammen mit Hilfsprogrammen wie z.&amp;amp;nbsp;B. Präprozessor, Assembler und Linker) Maschinencode für den AVR-Controller. Üblicherweise liegt dieser Code dann im Intel Hex-Format vor (&amp;quot;Hex-Datei&amp;quot;). Die Programmiersoftware (z.&amp;amp;nbsp;B. [[AVRDUDE]], PonyProg oder AVRStudio/STK500-plugin) liest diese Datei ein und überträgt die enthaltene Information (den Maschinencode) in den Speicher des Controllers. Im Prinzip sind also &amp;quot;nur&amp;quot; der avr-gcc-Compiler (und wenige Hilfsprogramme) mit den &amp;quot;richtigen&amp;quot; Optionen aufzurufen, um aus C-Code eine &amp;quot;Hex-Datei&amp;quot; zu erzeugen. Grundsätzlich stehen dazu zwei verschiedene Ansätze zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
* Die Verwendung einer integrierten Entwicklungsumgebung (IDE = &#039;&#039;&#039;I&#039;&#039;&#039;ntegrated &#039;&#039;&#039;D&#039;&#039;&#039;evelopment &#039;&#039;&#039;E&#039;&#039;&#039;nvironment), bei der alle Einstellungen z.&amp;amp;nbsp;B. in Dialogboxen durchgeführt werden können. Unter Anderem kann AVRStudio ab Version 4.12 (kostenlos auf [http://www.atmel.com/ atmel.com]) zusammen mit WinAVR als integrierte Entwicklungsumgebung für den Compiler avr-gcc genutzt werden (dazu müssen AVRStudio und WinAVR auf dem Rechner installiert sein). Weitere IDEs (ohne Anspruch auf Vollständigkeit): [http://www.eclipse.org/ Eclipse for C/C++ Developers] (d.h. inkl. CDT) und das [http://avr-eclipse.sourceforge.net/wiki/index.php/The_AVR_Eclipse_Plugin AVR-Eclipse Plugin] (für diverse Plattformen, u.a. Linux und MS Windows, IDE und Plugin kostenlos), [http://sourceforge.net/projects/kontrollerlab KontrollerLab] (Linux/KDE, kostenlos). [http://www.atmanecl.com/EnglishSite/SoftwareEnglish.htm AtmanAvr] (MS Windows, relativ günstig), KamAVR (MS-Windows, kostenlos, wird augenscheinlich nicht mehr weiterentwickelt), [http://www.amctools.com/vmlab.htm VMLab] (MS Windows, ab Version 3.12 ebenfalls kostenlos). Integrierte Entwicklungsumgebungen unterscheiden sich stark in Ihrer Bedienung und stehen auch nicht für alle Plattformen zur Verfügung, auf denen der Compiler  ausführbar ist (z.&amp;amp;nbsp;B. AVRStudio nur für MS-Windows). Zur Anwendung des avr-gcc Compilers mit IDEs sei hier auf deren Dokumentation verwiesen. &lt;br /&gt;
&lt;br /&gt;
* Die Nutzung des Programms make mit passenden Makefiles. In den folgenden Abschnitten wird die Generierung von Maschinencode für einen AVR (&amp;quot;hex-Datei&amp;quot;) aus C-Quellcode (&amp;quot;c-Dateien&amp;quot;) anhand von &amp;quot;make&amp;quot; und den &amp;quot;Makefiles&amp;quot; näher erläutert. Viele der darin beschriebenen Optionen findet man auch im Konfigurationsdialog des avr-gcc-Plugins von AVRStudio (AVRStudio generiert ein makefile in einem Unterverzeichnis des Projektverzeichnisses). &lt;br /&gt;
&lt;br /&gt;
Beim Wechsel vom makefile-Ansatz nach WinAVR-Vorlage zu AVRStudio ist darauf zu achten, dass AVRStudio (Stand: AVRStudio Version 4.13) bei einem neuen Projekt die Optimierungsoption (vgl. Artikel [[AVR-GCC-Tutorial/Exkurs_Makefiles|AVR-GCC-Tutorial/Exkurs: Makefiles]], typisch: -Os) nicht einstellt und die mathematische Bibliothek der avr-libc (libm.a, Linker-Option -lm) nicht einbindet. (Hinweis: Bei Version 4.16 wird beides bereits gesetzt). Beides ist Standard bei Verwendung von makefiles nach WinAVR-Vorlage und sollte daher auch im Konfigurationsdialog des avr-gcc-Plugins von AVRStudio &amp;quot;manuell&amp;quot; eingestellt werden, um auch mit AVRStudio kompakten Code zu erzeugen.&lt;br /&gt;
&lt;br /&gt;
= Einführungsbeispiel =&lt;br /&gt;
&lt;br /&gt;
Zum Einstieg ein kleines Beispiel, an dem die Nutzung des Compilers und der Hilfsprogramme (der sogenannten &#039;&#039;Toolchain&#039;&#039;) demonstriert wird. Detaillierte Erläuterungen folgen in den weiteren Abschnitten dieses Tutorials.&lt;br /&gt;
&lt;br /&gt;
Das Programm soll auf einem AVR Mikrocontroller einige Ausgänge ein- und andere ausschalten. Das Beispiel ist für einen ATmega16 programmiert ([http://www.atmel.com/dyn/resources/prod_documents/doc2466.pdf Datenblatt]), kann aber sinngemäß für andere Controller der AVR-Familie modifiziert werden. &lt;br /&gt;
&lt;br /&gt;
Ein kurzes Wort zur Hardware: Bei diesem Programm werden alle Pins von PORTB auf Ausgang gesetzt, und einige davon werden auf HIGH andere auf LOW gesetzt. Das kann je nach angeschlossener Hardware an diesen Pins kritisch sein. Am ungefährlichsten ist es, wenn nichts an den Pins angeschlossen ist und man die Funktion des Programmes durch eine Spannungsmessung mit einem Multimeter kontrolliert. Die Spannung wird dabei zwischen GND-Pin und den einzelnen Pins von PORTB gemessen.&lt;br /&gt;
&lt;br /&gt;
Zunächst der Quellcode der Anwendung, der in einer Text-Datei mit dem Namen &#039;&#039;main.c&#039;&#039; abgespeichert wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/* Alle Zeichen zwischen Schrägstrich-Stern &lt;br /&gt;
   und Stern-Schrägstrich sind Kommentare */&lt;br /&gt;
&lt;br /&gt;
// Zeilenkommentare sind ebenfalls möglich&lt;br /&gt;
// alle auf die beiden Schrägstriche folgenden&lt;br /&gt;
// Zeichen einer Zeile sind Kommentar&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;          // (1)&lt;br /&gt;
&lt;br /&gt;
int main (void) {            // (2)&lt;br /&gt;
&lt;br /&gt;
   DDRB  = 0xFF;             // (3)&lt;br /&gt;
   PORTB = 0x03;             // (4)&lt;br /&gt;
&lt;br /&gt;
   while(1) {                // (5)&lt;br /&gt;
     /* &amp;quot;leere&amp;quot; Schleife*/   // (6)&lt;br /&gt;
   }                         // (7)&lt;br /&gt;
&lt;br /&gt;
   /* wird nie erreicht */&lt;br /&gt;
   return 0;                 // (8)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# In dieser Zeile wird eine sogenannte Header-Datei eingebunden. In &amp;lt;code&amp;gt;avr/io.h&amp;lt;/code&amp;gt; sind die Registernamen definiert, die im späteren Verlauf genutzt werden. Auch unter Windows wird ein&amp;amp;nbsp;&amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; zur Kennzeichnung von Unterverzeichnissen in Include-Dateinamen verwendet und kein&amp;amp;nbsp;&amp;lt;code&amp;gt;\&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Hier beginnt das eigentliche Programm. Jedes C-Programm beginnt mit den Anweisungen in der Funktion &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Die Anschlüsse eines AVR (Pins) werden zu Blöcken zusammengefasst, einen solchen Block bezeichnet man als Port. Beim ATmega16 hat jeder Port 8 Anschlüsse, bei kleineren AVRs können einem Port auch weniger als 8 Anschlüsse zugeordnet sein. Da per Definition (Datenblatt) alle gesetzten Bits in einem Datenrichtungsregister den entsprechenden Anschluss auf Ausgang schalten, werden mit DDRB=0xff alle Anschlüsse des Ports B als Ausgänge eingestellt.&lt;br /&gt;
# Die den ersten beiden Bits des Ports zugeordneten Anschlüsse (PB0 und PB1) werden 1, alle anderen Anschlüsse des Ports B (PB2-PB7) zu 0. Aktivierte Ausgänge (logisch 1 oder &amp;quot;high&amp;quot;) liegen auf Betriebsspannung (VCC, meist 5 Volt), nicht aktivierte Ausgänge führen 0 Volt (GND, Bezugspotential). Es ist sinnvoll, sich möglichst frühzeitig eine alternative Schreibweise beizubringen, die wegen der leichteren Überprüfbarkeit und Portierbarkeit oft im weiteren Tutorial und in Forenbeiträgen benutzt wird. Die Zuordnung sieht in diesem Fall so aus, Näheres dazu im Artikel [[Bitmanipulation]]:&amp;lt;c&amp;gt;PORTB = (1&amp;lt;&amp;lt;PB1) | (1&amp;lt;&amp;lt;PB0);&amp;lt;/c&amp;gt;&lt;br /&gt;
# ist der Beginn der sogenannte &#039;&#039;Hauptschleife&#039;&#039; (main-loop). Dies ist eine Endlosschleife, welche kontinuierlich wiederkehrende Befehle enthält.&lt;br /&gt;
# In diesem Beispiel ist die Hauptschleife leer. Der Controller durchläuft die Schleife immer wieder, ohne dass etwas passiert. Eine solche Schleife ist notwendig, da es auf dem Controller kein Betriebssystem gibt, das nach Beendigung des Programmes die Kontrolle übernehmen könnte. Ohne diese Schleife kehrt das Programm aus &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; zurück, alle Interrupts werden deaktiviert und eine Endlosschleife betreten.&lt;br /&gt;
# Ende der Hauptschleife und Sprung zur passenden, öffnenden Klammer, also zu 5.&lt;br /&gt;
# ist das Programmende. Die Zeile ist nur aus Gründen der C-Kompatibilität enthalten: &amp;lt;c&amp;gt;int main(void)&amp;lt;/c&amp;gt; besagt, dass die Funktion einen int-Wert zurückgibt. Die Anweisung wird aber nicht erreicht, da das Programm die Hauptschleife nie verlässt.&lt;br /&gt;
&lt;br /&gt;
Um diesen Quellcode in ein lauffähiges Programm zu übersetzen, wird hier ein Makefile genutzt. Das verwendete Makefile findet sich auf der Seite [[Beispiel Makefile]] und basiert auf der Vorlage, die in WinAVR mitgeliefert wird und wurde bereits angepasst (Controllertyp ATmega16). Man kann das Makefile bearbeiten und an andere Controller anpassen oder sich mit dem Programm MFile menügesteuert ein Makefile &amp;quot;zusammenklicken&amp;quot;. Das Makefile speichert man unter dem Namen &amp;lt;code&amp;gt;Makefile&amp;lt;/code&amp;gt; (ohne Endung) im selben Verzeichnis, in dem auch die Datei &amp;lt;code&amp;gt;main.c&amp;lt;/code&amp;gt; mit dem Programmcode abgelegt ist. Detailliertere Erklärungen zur Funktion von Makefiles finden sich im Artikel [[AVR-GCC-Tutorial/Exkurs_Makefiles|Exkurs: Makefiles]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
D:\beispiel&amp;gt;dir&lt;br /&gt;
&lt;br /&gt;
 Verzeichnis von D:\beispiel&lt;br /&gt;
&lt;br /&gt;
28.11.2006  22:53    &amp;lt;DIR&amp;gt;          .&lt;br /&gt;
28.11.2006  22:53    &amp;lt;DIR&amp;gt;          ..&lt;br /&gt;
28.11.2006  20:06               118 main.c&lt;br /&gt;
28.11.2006  20:03            16.810 Makefile&lt;br /&gt;
               2 Datei(en)         16.928 Bytes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun gibt man &#039;&#039;make all&#039;&#039; ein. Falls das mit WinAVR installierte Programmers Notepad genutzt wird, gibt es dazu einen Menüpunkt im Tools Menü. Sind alle Einstellungen korrekt, entsteht eine Datei &amp;lt;code&amp;gt;main.hex&amp;lt;/code&amp;gt;, in welcher der Code für den AVR enthalten ist. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
D:\beispiel&amp;gt;make all&lt;br /&gt;
&lt;br /&gt;
-------- begin --------&lt;br /&gt;
avr-gcc (GCC) 3.4.6&lt;br /&gt;
Copyright (C) 2006 Free Software Foundation, Inc.&lt;br /&gt;
This is free software; see the source for copying conditions.  There is NO&lt;br /&gt;
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&lt;br /&gt;
&lt;br /&gt;
Compiling C: main.c&lt;br /&gt;
avr-gcc -c -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=1000000UL -Os -funsigned-char -f&lt;br /&gt;
unsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wundef&lt;br /&gt;
 -Wa,-adhlns=obj/main.lst  -std=gnu99 -Wundef -MD -MP -MF .dep/main.o.d main.c -&lt;br /&gt;
o obj/main.o&lt;br /&gt;
&lt;br /&gt;
Linking: main.elf&lt;br /&gt;
avr-gcc -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=1000000UL -Os -funsigned-char -funs&lt;br /&gt;
igned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wundef -W&lt;br /&gt;
a,-adhlns=obj/main.o  -std=gnu99 -Wundef -MD -MP -MF .dep/main.elf.d obj/main.o&lt;br /&gt;
--output main.elf -Wl,-Map=main.map,--cref    -lm&lt;br /&gt;
&lt;br /&gt;
Creating load file for Flash: main.hex&lt;br /&gt;
avr-objcopy -O ihex -R .eeprom main.elf main.hex&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Inhalt der hex-Datei kann nun zum Controller übertragen werden. Dies kann z.&amp;amp;nbsp;B. über In-System-Programming ([[ISP]]) erfolgen, das im [[AVR-Tutorial: Equipment]] beschrieben ist. Makefiles nach der WinAVR/MFile-Vorlage sind für die Nutzung des Programms [[AVRDUDE]] vorbereitet. Wenn man den Typ und Anschluss des Programmiergerätes richtig eingestellt hat, kann mit &#039;&#039;make program&#039;&#039; die Übertragung mittels AVRDUDE gestartet werden. Jede andere Software, die hex-Dateien lesen und zu einem AVR übertragen kann&amp;lt;ref&amp;gt;z.&amp;amp;nbsp;B. [[Pony-Prog_Tutorial|Ponyprog]], yapp, AVRStudio&amp;lt;/ref&amp;gt;, kann natürlich ebenfalls genutzt werden.&lt;br /&gt;
&lt;br /&gt;
Startet man nun den Controller (Reset-Taster oder Stromzufuhr aus/an), werden vom Programm die Anschlüsse PB0 und PB1 auf 1 gesetzt. Man kann mit einem Messgerät nun an diesem Anschluss die Betriebsspannung messen oder eine [[LED]] leuchten lassen (Anode an den Pin, Vorwiderstand nicht vergessen). An den Anschlüssen PB2-PB7 misst man 0 Volt. Eine mit der Anode mit einem dieser Anschlüsse verbundene LED leuchtet nicht.&lt;br /&gt;
&lt;br /&gt;
= Ganzzahlige Datentypen (Integer) =&lt;br /&gt;
&lt;br /&gt;
Bei der Programmierung von Mikrokontrollern ist die Definition einiger ganzzahliger Datentypen sinnvoll, an denen eindeutig die Bit-Länge abgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Standardisierte Datentypen werden in der Header-Datei &amp;lt;code&amp;gt;stdint.h&amp;lt;/code&amp;gt; definiert, die folgendermaßen eingebunden werden kann:&lt;br /&gt;
&amp;lt;c&amp;gt;#include &amp;lt;stdint.h&amp;gt;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| {{Tabelle}}&lt;br /&gt;
|+ &#039;&#039;&#039;int-Typen aus &amp;lt;code&amp;gt;stdint.h&amp;lt;/code&amp;gt; (C99)&#039;&#039;&#039;&amp;lt;br/&amp;gt;&amp;amp;nbsp;&lt;br /&gt;
|- bgcolor=&amp;quot;#d0d0ff&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;5&amp;quot;| Vorzeichenbehaftete int-Typen&lt;br /&gt;
|- bgcolor=&amp;quot;#e8e8ff&amp;quot;&lt;br /&gt;
! Typname || Bit-Breite ||colspan=&amp;quot;2&amp;quot;| Wertebereich&lt;br /&gt;
|align=&amp;quot;center| &#039;&#039;&#039;C-Entsprechung&#039;&#039;&#039; (avr-gcc)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;int8_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 8 || −128 ⋯ 127 || −2&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt; ⋯ 2&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;signed char&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;int16_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 16 || −32768 ⋯ 32767 || −2&amp;lt;sup&amp;gt;15&amp;lt;/sup&amp;gt; ⋯ 2&amp;lt;sup&amp;gt;15&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;signed short&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;signed int&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;int32_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 32 || −2147483648 ⋯ 2147483647 || −2&amp;lt;sup&amp;gt;31&amp;lt;/sup&amp;gt; ⋯ 2&amp;lt;sup&amp;gt;31&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;signed long&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;int64_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 64 || −9223372036854775808 ⋯ 9223372036854775807 || −2&amp;lt;sup&amp;gt;63&amp;lt;/sup&amp;gt; ⋯ 2&amp;lt;sup&amp;gt;63&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;signed long long&amp;lt;/code&amp;gt;&lt;br /&gt;
|- bgcolor=&amp;quot;#d0d0ff&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;5&amp;quot;| Vorzeichenlose int-Typen&lt;br /&gt;
|- bgcolor=&amp;quot;#e8e8ff&amp;quot;&lt;br /&gt;
! Typname || Bit-Breite ||colspan=&amp;quot;2&amp;quot;| Wertebereich&lt;br /&gt;
|align=&amp;quot;center| &#039;&#039;&#039;C-Entsprechung&#039;&#039;&#039; (avr-gcc)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 8 || 0 ⋯ 255 || 0 ⋯ 2&amp;lt;sup&amp;gt;8&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;unsigned char&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 16 || 0 ⋯ 65535 || 0 ⋯ 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;unsigned short&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;unsigned int&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;uint32_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 32 || 0 ⋯ 4294967295 || 0 ⋯ 2&amp;lt;sup&amp;gt;32&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;unsigned long&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;uint64_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 64 || 0 ⋯ 18446744073709551615 || 0 ⋯ 2&amp;lt;sup&amp;gt;64&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;unsigned long long&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Neben den Typen gibt es auch Makros für die Bereichsgrenzen wie &amp;lt;code&amp;gt;INT8_MIN&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;UINT16_MAX&amp;lt;/code&amp;gt;. Siehe dazu auch: [http://www.nongnu.org/avr-libc/user-manual/group__avr__stdint.html Dokumentation der avr-libc: Standard Integer Types].&lt;br /&gt;
&lt;br /&gt;
= Bitfelder =&lt;br /&gt;
&lt;br /&gt;
Beim Programmieren von Mikrocontrollern muss auf jedes Byte oder sogar auf&lt;br /&gt;
jedes Bit geachtet werden. Oft müssen wir in einer Variablen lediglich den&lt;br /&gt;
Zustand 0 oder 1 speichern. Wenn wir nun zur Speicherung eines einzelnen Wertes&lt;br /&gt;
den kleinsten bekannten Datentypen, nämlich &#039;&#039;&#039;unsigned char&#039;&#039;&#039;, nehmen, dann&lt;br /&gt;
verschwenden wir 7 Bits, da ein &#039;&#039;&#039;unsigned char&#039;&#039;&#039; ja 8 Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
Hier bietet uns die Programmiersprache C ein mächtiges Werkzeug an, mit dessen&lt;br /&gt;
Hilfe wir 8 Bits in eine einzelne Bytevariable zusammenfassen und (fast) wie&lt;br /&gt;
8 einzelne Variablen ansprechen können. Die Rede ist von sogenannten Bitfeldern. Diese werden als Strukturelemente definiert. Sehen wir uns dazu doch am besten gleich ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
struct {&lt;br /&gt;
   unsigned bStatus_1:1; // 1 Bit für bStatus_1&lt;br /&gt;
   unsigned bStatus_2:1; // 1 Bit für bStatus_2&lt;br /&gt;
   unsigned bNochNBit:1; // Und hier noch mal ein Bit&lt;br /&gt;
   unsigned b2Bits:2;    // Dieses Feld ist 2 Bits breit&lt;br /&gt;
   // All das hat in einer einzigen Byte-Variable Platz.&lt;br /&gt;
   // die 3 verbleibenden Bits bleiben ungenutzt&lt;br /&gt;
} x;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Zugriff auf ein solches Feld erfolgt nun, wie beim Strukturzugriff bekannt,&lt;br /&gt;
über den Punkt- oder den Dereferenzierungs-Operator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
x.bStatus_1 = 1;&lt;br /&gt;
x.bStatus_2 = 0;&lt;br /&gt;
x.b2Bits = 3;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bitfelder sparen Platz im RAM, zu Lasten von Platz im Flash, verschlechtern aber unter Umständen die Les- und Wartbarkeit des Codes. Anfängern wird deshalb geraten, ein &amp;quot;ganzes&amp;quot; Byte (uint8_t) zu nutzen, auch wenn nur ein Bitwert gespeichert werden soll.&lt;br /&gt;
&lt;br /&gt;
= Grundsätzlicher Programmaufbau eines µC-Programms =&lt;br /&gt;
&lt;br /&gt;
Wir unterscheiden zwischen 2 verschiedenen Methoden, um ein&lt;br /&gt;
Mikrocontroller-Programm zu schreiben, und zwar völlig unabhängig davon, in&lt;br /&gt;
welcher Programmiersprache das Programm geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
== Sequentieller Programmablauf ==&lt;br /&gt;
&lt;br /&gt;
[[Image:Sequentielle Programme.gif|left]]&lt;br /&gt;
Bei dieser Programmiertechnik wird eine Endlosschleife programmiert, welche im&lt;br /&gt;
Wesentlichen immer den gleichen Aufbau hat. Es wird hier nach dem sogenannten EVA-Prinzip gehandelt. EVA steht für &amp;quot;Eingabe, Verarbeitung, Ausgabe&amp;quot;.&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
== Interruptgesteuerter Programmablauf ==&lt;br /&gt;
&lt;br /&gt;
[[Image:Interrupt Programme.gif|left]]&lt;br /&gt;
Bei dieser Methode werden beim Programmstart zuerst die gewünschten Interruptquellen aktiviert und dann in eine Endlosschleife gegangen, in welcher Dinge erledigt werden können, welche nicht zeitkritisch sind. Wenn ein Interrupt ausgelöst wird, so wird automatisch die zugeordnete Interruptfunktion ausgeführt.&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
= Zugriff auf Register =&lt;br /&gt;
&lt;br /&gt;
Die AVR-Controller verfügen über eine Vielzahl von Registern. Die meisten&lt;br /&gt;
davon sind sogenannte Schreib-/Leseregister. Das heißt, das Programm kann die&lt;br /&gt;
Inhalte der Register sowohl auslesen als auch beschreiben.&lt;br /&gt;
&lt;br /&gt;
Register haben einen besonderen Stellenwert bei den AVR Controllern. Sie dienen dem Zugriff auf die Ports und die Schnittstellen des Controllers. Wir unterscheiden zwischen 8-Bit und 16-Bit Registern. Vorerst behandeln wir die 8-Bit Register.&lt;br /&gt;
&lt;br /&gt;
Einzelne Register sind bei allen AVRs vorhanden, andere wiederum nur bei bestimmten Typen. So sind beispielsweise die Register, welche für den Zugriff auf den UART notwendig sind, selbstverständlich nur bei denjenigen Modellen vorhanden, welche über einen integrierten Hardware UART bzw. USART verfügen.&lt;br /&gt;
&lt;br /&gt;
Die Namen der Register sind in den Headerdateien zu den entsprechenden AVR-Typen definiert. Dazu muss man den Namen der controllerspezifischen Headerdatei nicht kennen. Es reicht aus, die allgemeine Headerdatei &#039;&#039;avr/io.h&#039;&#039; einzubinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ist im Makefile der MCU-Typ z.&amp;amp;nbsp;B. mit dem Inhalt atmega8 definiert (und wird somit per -mmcu=atmega8 an den Compiler übergeben), wird beim Einlesen der io.h-Datei implizit (&amp;quot;automatisch&amp;quot;) auch die iom8.h-Datei mit den Register-Definitionen für den ATmega8 eingelesen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Wohl besser als Anhang - spaeter... --&amp;gt;&lt;br /&gt;
Intern wird diese &amp;quot;Automatik&amp;quot; wie folgt realisiert: Der Controllertyp wird dem Compiler als Parameter übergeben (vgl. &#039;&#039;avr-gcc -c -mmcu=atmega16 [...]&#039;&#039; im Einführungsbeispiel). Wird ein Makefile nach der WinAVR/mfile-Vorlage verwendet, setzt man die Variable &#039;&#039;MCU&#039;&#039;, der Inhalt dieser Variable wird dann an passender Stelle für die Compilerparameter verwendet. Der Compiler definiert intern eine dem mmcu-Parameter zugeordnete &amp;quot;Variable&amp;quot; (genauer: ein Makro) mit dem Namen des Controllers, vorangestelltem &#039;&#039;__AVR_&#039;&#039; und angehängten Unterstrichen (z.&amp;amp;nbsp;B. wird bei &#039;&#039;-mmcu=atmega16&#039;&#039; das Makro &#039;&#039;__AVR_ATmega16__&#039;&#039; definiert). Beim Einbinden der Header-Datei &#039;&#039;avr/io.h&#039;&#039; wird geprüft, ob das jeweilige Makro definiert ist und die zum Controller passende Definitionsdatei eingelesen. Zur Veranschaulichung einige Ausschnitte aus einem Makefile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[...]&lt;br /&gt;
# MCU Type (&amp;quot;name&amp;quot;) setzen:&lt;br /&gt;
MCU = atmega16&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
## Verwendung des Inhalts von MCU (hier atmega16) fuer die &lt;br /&gt;
## Compiler- und Assembler-Parameter&lt;br /&gt;
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)&lt;br /&gt;
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)&lt;br /&gt;
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
## Aufruf des Compilers:&lt;br /&gt;
## mit den Parametern ($(ALL_CFLAGS) ist -mmcu=$(MCU)[...] = -mmcu=atmega16[...]&lt;br /&gt;
$(OBJDIR)/%.o : %.c&lt;br /&gt;
	@echo&lt;br /&gt;
	@echo $(MSG_COMPILING) $&amp;lt;&lt;br /&gt;
	$(CC) -c $(ALL_CFLAGS) $&amp;lt; -o $@ &lt;br /&gt;
[...]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da --mmcu=atmega16 übergeben wurde, wird __AVR_ATmega16__ definiert und kann in avr/io.h zur Fallunterscheidung genutzt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// avr/io.h &lt;br /&gt;
// (bei WinAVR-Standardinstallation in C:\WinAVR\avr\include\avr)&lt;br /&gt;
[...]&lt;br /&gt;
#if defined (__AVR_AT94K__)&lt;br /&gt;
#  include &amp;lt;avr/ioat94k.h&amp;gt;&lt;br /&gt;
// [...]&lt;br /&gt;
#elif defined (__AVR_ATmega16__)&lt;br /&gt;
// da __AVR_ATmega16__ definiert ist, wird avr/iom16.h eingebunden:&lt;br /&gt;
#  include &amp;lt;avr/iom16.h&amp;gt;&lt;br /&gt;
// [...]&lt;br /&gt;
#else&lt;br /&gt;
#  if !defined(__COMPILING_AVR_LIBC__)&lt;br /&gt;
#    warning &amp;quot;device type not defined&amp;quot;&lt;br /&gt;
#  endif&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Beispiele in den folgenden Abschnitten demonstrieren den Zugriff auf Register anhand der Register für I/O-Ports (PORTx, DDRx, PINx), die Vorgehensweise ist jedoch für alle Register (z.&amp;amp;nbsp;B. die des UART, ADC, SPI) analog.&lt;br /&gt;
&lt;br /&gt;
== Schreiben in Register ==&lt;br /&gt;
&lt;br /&gt;
Zum Schreiben kann man Register einfach wie eine Variable setzen.&amp;lt;ref&amp;gt;In Quellcodes, die für ältere Versionen des avr-gcc/der avr-libc entwickelt wurden, erfolgt der Schreibzugriff über die Funktion outp(). Aktuelle Versionen des Compilers unterstützen den Zugriff nun direkt, outp() ist nicht mehr erforderlich.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    /* Setzt das Richtungsregister des Ports A auf 0xff &lt;br /&gt;
       (alle Pins als Ausgang, vgl. Abschnitt Zugriff auf Ports): */&lt;br /&gt;
    DDRA = 0xff;    &lt;br /&gt;
&lt;br /&gt;
    /* Setzt PortA auf 0x03, Bit 0 und 1 &amp;quot;high&amp;quot;, restliche &amp;quot;low&amp;quot;: */&lt;br /&gt;
    PORTA = 0x03;   &lt;br /&gt;
&lt;br /&gt;
    // Setzen der Bits 0,1,2,3 und 4&lt;br /&gt;
    // Binär 00011111 = Hexadezimal 1F&lt;br /&gt;
    DDRB = 0x1F;    /* direkte Zuweisung - unübersichtlich */&lt;br /&gt;
&lt;br /&gt;
    /* Ausführliche Schreibweise: identische Funktionalität, mehr Tipparbeit&lt;br /&gt;
       aber übersichtlicher und selbsterklärend: */&lt;br /&gt;
    DDRB = (1 &amp;lt;&amp;lt; DDB0) | (1 &amp;lt;&amp;lt; DDB1) | (1 &amp;lt;&amp;lt; DDB2) | (1 &amp;lt;&amp;lt; DDB3) | (1 &amp;lt;&amp;lt; DDB4);&lt;br /&gt;
&lt;br /&gt;
    while (1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die ausführliche Schreibweise sollte bevorzugt verwendet werden, da dadurch die Zuweisungen selbsterklärend sind und somit der Code leichter nachvollzogen werden kann. Atmel verwendet sie auch bei Beispielen in Datenblätten und in den allermeisten Quellcodes zu Application-Notes. Mehr zu der Schreibweise mit &amp;quot;|&amp;quot; und &amp;quot;&amp;lt;&amp;lt;&amp;quot; findet man unter [[Bitmanipulation]].&lt;br /&gt;
&lt;br /&gt;
Der gcc C-Compiler unterstützt ab Version 4.3.0 Konstanten im Binärformat, z.&amp;amp;nbsp;B. DDRB&amp;amp;nbsp;=&amp;amp;nbsp;0b00011111. Diese Schreibweise ist jedoch nur in GNU-C verfügbar und nicht in ISO-C definiert. Man sollte sie daher nicht verwenden, wenn Code mit anderen ausgetauscht oder mit anderen Compilern bzw. älteren Versionen des gcc genutzt werden soll.&lt;br /&gt;
&lt;br /&gt;
== Verändern von Registerinhalten ==&lt;br /&gt;
&lt;br /&gt;
Einzelne Bits setzt und löscht man &amp;quot;Standard-C-konform&amp;quot; mittels logischer (Bit-) Operationen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
 x |= (1 &amp;lt;&amp;lt; Bitnummer);  // Hiermit wird ein Bit in x gesetzt&lt;br /&gt;
 x &amp;amp;= ~(1 &amp;lt;&amp;lt; Bitnummer); // Hiermit wird ein Bit in x geloescht&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es wird jeweils nur der Zustand des angegebenen Bits geändert, der vorherige Zustand der anderen Bits bleibt erhalten. &lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
#define MEINBIT 2&lt;br /&gt;
...&lt;br /&gt;
PORTA |= (1 &amp;lt;&amp;lt; MEINBIT);    /* setzt Bit 2 an PortA auf 1 */&lt;br /&gt;
PORTA &amp;amp;= ~(1 &amp;lt;&amp;lt; MEINBIT);   /* loescht Bit 2 an PortA */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit dieser Methode lassen sich auch mehrere Bits eines Registers gleichzeitig setzen und löschen.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
DDRA &amp;amp;= ~( (1&amp;lt;&amp;lt;PA0) | (1&amp;lt;&amp;lt;PA3) );  /* PA0 und PA3 als Eingaenge */&lt;br /&gt;
PORTA |= (1&amp;lt;&amp;lt;PA0) | (1&amp;lt;&amp;lt;PA3);      /* Interne Pull-Up fuer beide einschalten */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei bestimmten AVR Registern mit Bits, die durch Beschreiben mit einer logischen 1 gelöscht werden, muss eine absolute Zuweisung benutzt werden. Ein ODER löscht in diesen Registern ALLE gesetzten Bits!&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
TIFR2 = (1&amp;lt;&amp;lt;OCF2A); // Nur Bit OCF2A löschen&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Quellcodes, die für ältere Version den des avr-gcc/der avr-libc entwickelt wurden, werden einzelne Bits mittels der Funktionen sbi und cbi gesetzt bzw. gelöscht. Beide Funktionen sind nicht mehr erforderlich.&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* [[Bitmanipulation]]&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/Special Function Registers&lt;br /&gt;
&lt;br /&gt;
== Lesen aus Registern ==&lt;br /&gt;
&lt;br /&gt;
Zum Lesen kann man auf Register einfach wie auf eine Variable zugreifen. In Quellcodes, die für ältere Versionen des avr-gcc/der avr-libc entwickelt wurden, erfolgt der Lesezugriff über die Funktion inp(). Aktuelle Versionen des Compilers unterstützen den Zugriff nun direkt und inp() ist nicht mehr erforderlich.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
uint8_t foo;&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    /* kopiert den Status der Eingabepins an PortB &lt;br /&gt;
       in die Variable foo: */&lt;br /&gt;
    foo = PINB;    &lt;br /&gt;
    //...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Abfrage der Zustände von Bits erfolgt durch Einlesen des gesamten Registerinhalts und ausblenden der Bits deren Zustand nicht von Interesse ist. Einige Beispiele zum Prüfen ob Bits gesetzt oder gelöscht sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#define MEINBIT0 0 &lt;br /&gt;
#define MEINBIT2 2&lt;br /&gt;
&lt;br /&gt;
uint8_t i;&lt;br /&gt;
&lt;br /&gt;
extern test1();&lt;br /&gt;
&lt;br /&gt;
// Funkion test1 aufrufen, wenn Bit 0 in Register PINA gesetzt (1) ist&lt;br /&gt;
i = PINA;         // Inhalt in Arbeitsvariable&lt;br /&gt;
i = i &amp;amp; 0x01;     // alle Bits bis auf Bit 0 ausblenden (bitweise und)&lt;br /&gt;
                  // falls das Bit gesetzt war, hat i den Inhalt 1&lt;br /&gt;
if ( i != 0 ) {   // Ergebnis ungleich 0 (wahr)? &lt;br /&gt;
  test1();         // dann muss Bit 0 in i gesetzt sein -&amp;gt; Funktion aufrufen&lt;br /&gt;
}&lt;br /&gt;
// verkürzt:&lt;br /&gt;
if ( ( PINA &amp;amp; 0x01 ) != 0 ) {&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
// nochmals verkürzt:&lt;br /&gt;
if ( PINA &amp;amp; 0x01 ) {&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
// mit definierter Bitnummer:&lt;br /&gt;
if ( PINA &amp;amp; ( 1 &amp;lt;&amp;lt; MEINBIT0 ) ) {&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Funktion aufrufen, wenn Bit 0 und/oder Bit 2 gesetzt ist. (Bit 0 und 2 also Wert 5) &lt;br /&gt;
// (Bedenke: Bit 0 hat Wert 1, Bit 1 hat Wert 2 und Bit 2 hat Wert 4)&lt;br /&gt;
if ( PINA &amp;amp; 0x05 ) {&lt;br /&gt;
  test1();  // Vergleich &amp;lt;&amp;gt; 0 (wahr), also mindestens eines der Bits gesetzt&lt;br /&gt;
}&lt;br /&gt;
// mit definierten Bitnummern:&lt;br /&gt;
if ( PINA &amp;amp; ( ( 1 &amp;lt;&amp;lt; MEINBIT0 ) | ( 1 &amp;lt;&amp;lt; MEINBIT2 ) ) ) {&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Funktion aufrufen, wenn Bit 0 und Bit 2 gesetzt sind&lt;br /&gt;
if ( ( PINA &amp;amp; 0x05 ) == 0x05 ) {  // nur wahr, wenn beide Bits gesetzt&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Funktion test2() aufrufen, wenn Bit 0 gelöscht (0) ist&lt;br /&gt;
i = PINA;        // einlesen in temporäre Variable&lt;br /&gt;
i = i &amp;amp; 0x01;    // maskieren von Bit 0&lt;br /&gt;
if ( i == 0 ) {  // Vergleich ist wahr, wenn Bit 0 nicht gesetzt ist&lt;br /&gt;
  test2();&lt;br /&gt;
}&lt;br /&gt;
// analog mit not-Operator&lt;br /&gt;
if ( !i ) {&lt;br /&gt;
  test2();&lt;br /&gt;
}&lt;br /&gt;
// nochmals verkürzt:&lt;br /&gt;
if ( !( PINA &amp;amp; 0x01 ) ) {&lt;br /&gt;
  test2();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Warten auf einen bestimmten Zustand ==&lt;br /&gt;
&lt;br /&gt;
Es gibt in der Bibliothek avr-libc Funktionen, die warten, bis ein bestimmter Zustand eines Bits erreicht ist. Es ist allerdings normalerweise eine eher unschöne Programmiertechnik, da in diesen Funktionen &amp;quot;blockierend&amp;quot; gewartet wird. Der Programmablauf bleibt also an dieser Stelle stehen, bis das maskierte Ereignis erfolgt ist. Setzt man den [[Watchdog]] ein, muss man darauf achten, dass dieser auch noch getriggert wird (Zurücksetzen des Watchdogtimers). &lt;br /&gt;
&lt;br /&gt;
Die Funktion &#039;&#039;&#039;loop_until_bit_is_set&#039;&#039;&#039; wartet in einer Schleife, bis das definierte Bit gesetzt ist. Wenn das Bit beim Aufruf der Funktion bereits gesetzt ist, wird die Funktion sofort wieder verlassen. Das niederwertigste Bit hat die Bitnummer 0. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
/* Warten bis Bit Nr. 2 (das dritte Bit) in Register PINA gesetzt (1) ist */&lt;br /&gt;
&lt;br /&gt;
#define WARTEPIN PINA&lt;br /&gt;
#define WARTEBIT PA2&lt;br /&gt;
&lt;br /&gt;
// mit der avr-libc Funktion:&lt;br /&gt;
loop_until_bit_is_set(WARTEPIN, WARTEBIT);&lt;br /&gt;
&lt;br /&gt;
// dito in &amp;quot;C-Standard&amp;quot;:&lt;br /&gt;
// Durchlaufe die (leere) Schleife solange das WARTEBIT in Register WARTEPIN&lt;br /&gt;
// _nicht_ ungleich 0 (also 0) ist.&lt;br /&gt;
while ( !(WARTEPIN &amp;amp; (1 &amp;lt;&amp;lt; WARTEBIT)) ) {}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Funktion &#039;&#039;&#039;loop_until_bit_is_clear&#039;&#039;&#039; wartet in einer Schleife, bis das definierte Bit gelöscht ist. Wenn das Bit beim Aufruf der Funktion bereits gelöscht ist, wird die Funktion sofort wieder verlassen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
/* Warten bis Bit Nr. 4 (das fuenfte Bit) in Register PINB geloescht (0) ist */&lt;br /&gt;
#define WARTEPIN PINB&lt;br /&gt;
#define WARTEBIT PB4&lt;br /&gt;
&lt;br /&gt;
// avr-libc-Funktion:&lt;br /&gt;
loop_until_bit_is_clear(WARTEPIN, WARTEBIT);&lt;br /&gt;
&lt;br /&gt;
// dito in &amp;quot;C-Standard&amp;quot;:&lt;br /&gt;
// Durchlaufe die (leere) Schleife solange das WARTEBIT in Register WARTEPIN&lt;br /&gt;
// gesetzt (1) ist &lt;br /&gt;
while ( WARTEPIN &amp;amp; (1&amp;lt;&amp;lt;WARTEBIT) ) {}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Universeller und auch auf andere Plattformen besser übertragbar ist die Verwendung von C-Standardoperationen.&lt;br /&gt;
&lt;br /&gt;
Siehe auch: &lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/Special Function Registers&lt;br /&gt;
* [[Bitmanipulation]]&lt;br /&gt;
&lt;br /&gt;
== 16-Bit Register (ADC, ICR1, OCR1x, TCNT1, UBRR) ==&lt;br /&gt;
&lt;br /&gt;
Einige der Portregister in den AVR-Controllern sind 16 Bit breit. Im Datenblatt sind diese Register üblicherweise mit dem Suffix &amp;quot;L&amp;quot; (Low-Byte) und &amp;quot;H&amp;quot; (High-Byte) versehen. Die avr-libc definiert zusätzlich die meisten dieser Variablen die Bezeichnung ohne &amp;quot;L&amp;quot; oder &amp;quot;H&amp;quot;. Auf diese Register kann dann direkt zugegriffen werden. Dies ist zum Beispiel der Fall für Register wie ADC oder TCNT1.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
    uint16_t foo;&lt;br /&gt;
&lt;br /&gt;
    /* setzt die Wort-Variable foo auf den Wert der letzten AD-Wandlung */&lt;br /&gt;
    foo = ADC; &lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei anderen Registern, wie zum Beispiel Baudraten-Register, liegen High- und Low-Teil nicht direkt nebeneinander im SFR-Bereich, so dass ein 16-Bit Zugriff nicht möglich ist und der Zugriff zusammengebastelt werden muss:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
#define F_CPU 3686400&lt;br /&gt;
#endif&lt;br /&gt;
#define UART_BAUD_RATE 9600&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
   uint16_t baud = F_CPU / (UART_BAUD_RATE * 16L) -1;&lt;br /&gt;
&lt;br /&gt;
   UBRRH = (uint8_t) (baud &amp;gt;&amp;gt; 8);&lt;br /&gt;
   UBRRL = (uint8_t) baud;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei einigen AVR-Typen wie ATmega8 oder ATmega16 teilen sich UBRRH und UCSRC die gleiche Speicher-Adresse. Damit der AVR trotzdem zwischen den beiden Registern unterscheiden kann, bestimmt das Bit7 (URSEL), welches Register tatsächlich beschrieben werden soll. &#039;&#039;1000 0011&#039;&#039; (0x83) adressiert demnach UCSRC und übergibt den Wert &#039;&#039;3&#039;&#039; und &#039;&#039;0000 0011&#039;&#039; (0x3) adressiert UBRRH und übergibt ebenfalls den Wert &#039;&#039;3&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Speziell bei den 16-Bit-Timern und auch beim ADC ist es bei allen Zugriffen auf Datenregister erforderlich, dass diese Daten synchronisiert sind. Wenn z.&amp;amp;nbsp;B. bei einem 16-Bit-Timer das High-Byte des Zählregisters gelesen wurde und vor dem Lesezugriff auf das Low-Byte ein Überlauf des Low-Bytes stattfindet, erhält man einen völlig unsinnigen Wert. Auch die Compare-Register müssen synchron geschrieben werden, da es ansonsten zu unerwünschten Compare-Ereignissen kommen kann. &lt;br /&gt;
&lt;br /&gt;
Beim ADC besteht das Problem darin, dass zwischen den Zugriffen auf die beiden Teilregister eine Wandlung beendet werden kann und der ADC ein neues Ergebnis in ADCL und ADCH schreiben will, wodurch High- und Low-Byte nicht zusammenpassen.&lt;br /&gt;
&lt;br /&gt;
Um diese Datenmüllproduktion zu verhindern, gibt es in beiden Fällen eine Synchronisation, die jeweils durch den Zugriff auf das Low-Byte ausgelöst wird:&lt;br /&gt;
* Bei den Timer-Registern (das gilt für alle TCNT-, OCR- und ICR-Register bei den 16-Bit-Timern) wird bei einem &#039;&#039;Lesezugriff&#039;&#039; auf das Low-Byte automatisch das High-Byte in ein temporäres Register, das ansonsten nach außen nicht sichtbar ist, geschoben. Greift man nun &#039;&#039;anschließend&#039;&#039; auf das High-Byte zu, dann wird eben dieses temporäre Register gelesen.&lt;br /&gt;
* Bei einem &#039;&#039;Schreibzugriff&#039;&#039; auf eines der genannten Register wird das High-Byte in besagtem temporären Register zwischengespeichert und erst beim Schreiben des Low-Bytes werden &#039;&#039;beide&#039;&#039; gleichzeitig in das eigentliche Register übernommen.&lt;br /&gt;
&lt;br /&gt;
Das bedeutet für die Reihenfolge:&lt;br /&gt;
* Lesezugriff: Erst Low-Byte, dann High-Byte&lt;br /&gt;
* Schreibzugriff: Erst High-Byte, dann Low-Byte&lt;br /&gt;
&lt;br /&gt;
Des weiteren ist zu beachten, dass es für all diese 16-Bit-Register nur ein einziges temporäres Register gibt, so dass das Auftreten eines Interrupts, in dessen Handler ein solches Register manipuliert wird, bei einem durch ihn unterbrochenen Zugriff i.d.R. zu Datenmüll führt. 16-Bit-Zugriffe sind generell nicht atomar! Wenn mit Interrupts gearbeitet wird, kann es erforderlich sein, vor einem solchen Zugriff auf ein 16-Bit-Register die Interrupt-Bearbeitung zu deaktivieren.&lt;br /&gt;
&lt;br /&gt;
Beim ADC-Datenregister ADCH/ADCL ist die Synchronisierung anders gelöst. Hier wird beim Lesezugriff (ADCH/ADCL sind logischerweise read-only) auf das Low-Byte ADCL beide Teilregister für Zugriffe seitens des ADC so lange gesperrt, bis das High-Byte ADCH ausgelesen wurde. Dadurch kann der ADC nach einem Zugriff auf ADCL keinen neuen Wert in ADCH/ADCL ablegen, bis ADCH gelesen wurde. Ergebnisse von Wandlungen, die zwischen einem Zugriff auf ADCL und ADCH beendet werden, gehen verloren!&lt;br /&gt;
&lt;br /&gt;
Nach einem Zugriff auf ADCL muss grundsätzlich ADCH gelesen werden!&lt;br /&gt;
&lt;br /&gt;
In beiden Fällen – also sowohl bei den Timern als auch beim ADC – werden vom C-Compiler 16-Bit Pseudo-Register zur Verfügung gestellt (z.&amp;amp;nbsp;B. TCNT1H/TCNT1L → TCNT1, ADCH/ADCL → ADC bzw. ADCW), bei deren Verwendung der Compiler automatisch die richtige Zugriffsreihenfolge regelt. In C-Programmen sollten grundsätzlich diese 16-Bit-Register verwendet werden! Sollte trotzdem ein Zugriff auf ein Teilregister erforderlich sein, sind obige Angaben zu berücksichtigen.&lt;br /&gt;
&lt;br /&gt;
Es ist darauf zu achten, dass auch ein Zugriff auf die 16-Bit-Register vom Compiler in zwei 8-Bit-Zugriffe aufgeteilt wird und dementsprechend genauso nicht-atomar ist wie die Einzelzugriffe. Auch hier gilt, dass u.U. die Interrupt-Bearbeitung gesperrt werden muss, um Datenmüll zu vermeiden.&lt;br /&gt;
&lt;br /&gt;
Beim ADC gibt es für den Fall, dass eine Auflösung von 8 Bit ausreicht, die Möglichkeit, das Ergebnis &amp;quot;linksbündig&amp;quot; in ADCH/ADCL auszurichten, so dass die relevanten 8 MSB in ADCH stehen. In diesem Fall muss bzw. sollte nur ADCH ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
ADC und ADCW sind unterschiedliche Bezeichner für das selbe Registerpaar. Üblicherweise kann man in C-Programmen ADC verwenden, was analog zu den anderen 16-Bit-Registern benannt ist. ADCW (ADC Word) existiert nur deshalb, weil die Headerdateien auch für Assembler vorgesehen sind und es bereits einen Assembler-Befehl namens &#039;&#039;adc&#039;&#039; gibt. &lt;br /&gt;
&lt;br /&gt;
Im Umgang mit 16-Bit Registern siehe auch:&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Related Pages/Frequently Asked Questions/Nr. 8&lt;br /&gt;
* Datenblatt Abschnitt &#039;&#039;Accessing 16-bit Registers&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== IO-Register als Parameter und Variablen ==&lt;br /&gt;
&lt;br /&gt;
Um Register als Parameter für eigene Funktionen übergeben zu können, muss man sie als einen volatile uint8_t Pointer übergeben. Zum Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
uint8_t key_pressed (volatile uint8_t *inputreg, uint8_t inputbit)&lt;br /&gt;
{&lt;br /&gt;
  static uint8_t last_state = 0;&lt;br /&gt;
 &lt;br /&gt;
  if (last_state == (*inputreg &amp;amp; (1&amp;lt;&amp;lt;inputbit)))&lt;br /&gt;
     return 0; /* keine Änderung */&lt;br /&gt;
 &lt;br /&gt;
  /* Wenn doch, warten bis etwaiges Prellen vorbei ist: */&lt;br /&gt;
  _delay_ms(20);&lt;br /&gt;
&lt;br /&gt;
  /* Zustand für nächsten Aufruf merken: */&lt;br /&gt;
  last_state = *inputreg &amp;amp; (1&amp;lt;&amp;lt;inputbit);&lt;br /&gt;
 &lt;br /&gt;
  /* und den entprellten Tastendruck zurückgeben: */&lt;br /&gt;
  return *inputreg &amp;amp; (1&amp;lt;&amp;lt;inputbit);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Beispiel für einen Funktionsaufruf: */&lt;br /&gt;
&lt;br /&gt;
void foo (void)&lt;br /&gt;
{&lt;br /&gt;
   uint8_t i = key_pressed (&amp;amp;PINB, PB1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Aufruf der Funktion mit call by value würde Folgendes bewirken: Beim Funktionseintritt wird nur eine Kopie des momentanen Portzustandes angefertigt, die sich unabhängig vom tatsächlichen Zustand das Ports nicht mehr ändert, womit die Funktion wirkungslos wäre. Die Übergabe eines Zeigers wäre die Lösung, wenn der Compiler nicht optimieren würde. Denn dadurch wird im Programm nicht von der Hardware gelesen, sondern wieder nur von einem Abbild im Speicher. Das Ergebnis wäre das gleiche wie oben. Mit dem Schlüsselwort volatile sagt man nun dem Compiler, dass die entsprechende Variable entweder durch andere Softwareroutinen (Interrupts) oder durch die Hardware verändert werden kann.&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_port_pass avr-libc FAQ: &amp;quot;How do I pass an IO port as a parameter to a function?&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
= Zugriff auf IO-Ports =&lt;br /&gt;
&lt;br /&gt;
Jeder AVR implementiert eine unterschiedliche Menge an GPIO-Registern&lt;br /&gt;
(GPIO - General Purpose Input/Output). Diese Register dienen dazu:&lt;br /&gt;
* einzustellen welche der Anschlüsse (&amp;quot;Beinchen&amp;quot;) des Controllers als Ein- oder Ausgänge dienen&lt;br /&gt;
* bei Ausgängen deren Zustand festzulegen&lt;br /&gt;
* bei Eingängen deren Zustand zu erfassen&lt;br /&gt;
&lt;br /&gt;
Mittels GPIO werden digitale Zustände gesetzt und erfasst, d.h. die Spannung an einem Ausgang wird ein- oder ausgeschaltet und an einem Eingang wird erfasst, ob die anliegende Spannung über oder unter einem bestimmten Schwellwert liegt. Im Datenblatt Abschnitt Electrical Characteristics/DC Characteristics finden sich die Spannungswerte (V_OL, V_OH für Ausgänge, V_IL, V_IH für Eingänge).&lt;br /&gt;
&lt;br /&gt;
Die Verarbeitung von analogen Eingangswerten und die Ausgabe von Analogwerten wird in Kapitel [[AVR-GCC-Tutorial#Analoge_Ein-_und_Ausgabe|Analoge Ein- und Ausgabe]] behandelt.&lt;br /&gt;
&lt;br /&gt;
Die physischen Ein- und Ausgänge werden bei AVR-Controllern zu logischen Ports gruppiert.&lt;br /&gt;
&lt;br /&gt;
Alle Ports werden über Register gesteuert. Dazu sind jedem Port 3 Register zugeordnet:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! DDRx&lt;br /&gt;
| Datenrichtungsregister für Port&#039;&#039;&#039;x&#039;&#039;&#039;. &lt;br /&gt;
&#039;&#039;&#039;x&#039;&#039;&#039; entspricht &#039;&#039;&#039;A&#039;&#039;&#039;, &#039;&#039;&#039;B&#039;&#039;&#039;, &#039;&#039;&#039; C&#039;&#039;&#039;, &#039;&#039;&#039;D&#039;&#039;&#039; usw. (abhängig von der Anzahl der Ports des verwendeten AVR). Bit im Register gesetzt (1) für Ausgang, Bit gelöscht (0) für Eingang.&lt;br /&gt;
|- &lt;br /&gt;
! PINx&lt;br /&gt;
| Eingangsadresse für Port&#039;&#039;&#039;x&#039;&#039;&#039;. &lt;br /&gt;
Zustand des Ports. Die Bits in PINx entsprechen dem Zustand der als Eingang definierten Portpins. Bit 1 wenn Pin &amp;quot;high&amp;quot;, Bit 0 wenn Portpin low.&lt;br /&gt;
|-&lt;br /&gt;
! PORTx&lt;br /&gt;
| Datenregister für Port&#039;&#039;&#039;x&#039;&#039;&#039;. &lt;br /&gt;
Dieses Register wird verwendet, um die Ausgänge eines Ports anzusteuern. Bei Pins, die mittels DDRx auf Eingang geschaltet wurden, können über PORTx&lt;br /&gt;
die internen Pull-Up Widerstände aktiviert oder deaktiviert werden (1 = aktiv).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Beispiele gehen von einem AVR aus, der sowohl Port A als auch Port B besitzt. Sie müssen für andere AVRs (zum Beispiel ATmega8/48/88/168) entsprechend angepasst werden.&lt;br /&gt;
&lt;br /&gt;
== Datenrichtung bestimmen ==&lt;br /&gt;
&lt;br /&gt;
Zuerst muss die Datenrichtung der verwendeten Pins bestimmt werden. Um dies zu erreichen, wird das Datenrichtungsregister des entsprechenden Ports beschrieben.&lt;br /&gt;
&lt;br /&gt;
Für jeden Pin, der als Ausgang verwendet werden soll, muss dabei das&lt;br /&gt;
entsprechende Bit auf dem Port gesetzt werden. Soll der Pin als Eingang&lt;br /&gt;
verwendet werden, muss das entsprechende Bit gelöscht sein.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
Angenommen am Port B sollen die Pins 0 bis 4 als Ausgänge definiert werden, die noch verbleibenden Pins 5 bis 7 sollen als Eingänge fungieren. Dazu ist es daher notwendig, im für das Port B zuständigen Datenrichtungsregister DDRB folgende Bitkonfiguration einzutragen&lt;br /&gt;
&lt;br /&gt;
   +---+---+---+---+---+---+---+---+&lt;br /&gt;
   | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |&lt;br /&gt;
   +---+---+---+---+---+---+---+---+&lt;br /&gt;
   | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |&lt;br /&gt;
&lt;br /&gt;
In C liest sich das dann so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// in io.h wird u.a. DDRB definiert:&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  // Setzen der Bits 0,1,2,3 und 4&lt;br /&gt;
  // Binär 00011111 = Hexadezimal 1F&lt;br /&gt;
  // direkte Zuweisung - standardkonform */&lt;br /&gt;
  DDRB = 0x1F;    /* &lt;br /&gt;
&lt;br /&gt;
  // übersichtliche Alternative - Binärschreibweise, aber kein ISO-C&lt;br /&gt;
  DDRB = 0b00011111;&lt;br /&gt;
&lt;br /&gt;
  // Ausführliche Schreibweise: identische Funktionalität, mehr Tipparbeit&lt;br /&gt;
  // aber übersichtlicher und selbsterklärend:&lt;br /&gt;
  DDRB = (1 &amp;lt;&amp;lt; DDB0) | (1 &amp;lt;&amp;lt; DDB1) | (1 &amp;lt;&amp;lt; DDB2) | (1 &amp;lt;&amp;lt; DDB3) | (1 &amp;lt;&amp;lt; DDB4); &lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Pins 5 bis 7 werden (da 0) als Eingänge geschaltet. Weitere Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  // Alle Pins des Ports B als Ausgang definieren:&lt;br /&gt;
  DDRB = 0xff; &lt;br /&gt;
  // Pin0 wieder auf Eingang und andere im ursprünglichen Zustand belassen:&lt;br /&gt;
  DDRB &amp;amp;= ~(1 &amp;lt;&amp;lt; DDB0);&lt;br /&gt;
  // Pin 3 und 4 auf Eingang und andere im ursprünglichen Zustand belassen:&lt;br /&gt;
  DDRB &amp;amp;= ~((1 &amp;lt;&amp;lt; DDB3) | (1 &amp;lt;&amp;lt; DDB4));&lt;br /&gt;
  // Pin 0 und 3 wieder auf Ausgang und andere im ursprünglichen Zustand belassen:&lt;br /&gt;
  DDRB |= (1 &amp;lt;&amp;lt; DDB0) | (1 &amp;lt;&amp;lt; DDB3);&lt;br /&gt;
  // Alle Pins auf Eingang:&lt;br /&gt;
  DDRB = 0x00;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Vordefinierte Bitnummern für I/O-Register ==&lt;br /&gt;
&lt;br /&gt;
Die Bitnummern (z.&amp;amp;nbsp;B. PCx, PINCx und DDCx für den Port C) sind in den io*.h-Dateien der avr-libc definiert und dienen lediglich der besseren Lesbarkeit. Man muss diese Definitionen nicht verwenden oder kann auch einfach &amp;quot;immer&amp;quot; PAx, PBx, PCx usw. nutzen, auch wenn der Zugriff auf Bits in DDRx- oder PINx-Registern erfolgt. Für den Compiler sind die Ausdrücke (1&amp;lt;&amp;lt;PC7), (1&amp;lt;&amp;lt;DDC7) und (1&amp;lt;&amp;lt;PINC7) identisch zu (1&amp;lt;&amp;lt;7) (genauer: der Präprozessor ersetzt die Ausdrücke (1&amp;lt;&amp;lt;PC7),... zu (1&amp;lt;&amp;lt;7)). Ein Ausschnitt der Definitionen für Port C eines ATmega32 aus der iom32.h-Datei zur Verdeutlichung (analog für die weiteren Ports):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
/* PORTC */&lt;br /&gt;
#define PC7     7&lt;br /&gt;
#define PC6     6&lt;br /&gt;
#define PC5     5&lt;br /&gt;
#define PC4     4&lt;br /&gt;
#define PC3     3&lt;br /&gt;
#define PC2     2&lt;br /&gt;
#define PC1     1&lt;br /&gt;
#define PC0     0&lt;br /&gt;
&lt;br /&gt;
/* DDRC */&lt;br /&gt;
#define DDC7    7&lt;br /&gt;
#define DDC6    6&lt;br /&gt;
#define DDC5    5&lt;br /&gt;
#define DDC4    4&lt;br /&gt;
#define DDC3    3&lt;br /&gt;
#define DDC2    2&lt;br /&gt;
#define DDC1    1&lt;br /&gt;
#define DDC0    0&lt;br /&gt;
&lt;br /&gt;
/* PINC */&lt;br /&gt;
#define PINC7   7&lt;br /&gt;
#define PINC6   6&lt;br /&gt;
#define PINC5   5&lt;br /&gt;
#define PINC4   4&lt;br /&gt;
#define PINC3   3&lt;br /&gt;
#define PINC2   2&lt;br /&gt;
#define PINC1   1&lt;br /&gt;
#define PINC0   0&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Digitale Signale ==&lt;br /&gt;
&lt;br /&gt;
Am einfachsten ist es, digitale Signale mit dem Mikrocontroller zu erfassen bzw. auszugeben.&lt;br /&gt;
&lt;br /&gt;
== Ausgänge ==&lt;br /&gt;
Will man als Ausgang definierte Pins (entsprechende DDRx-Bits = 1) auf Logisch 1 setzen, setzt man die  entsprechenden Bits im Portregister.&lt;br /&gt;
&lt;br /&gt;
Mit dem Befehl&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
    PORTB = 0x04; /* besser PORTB=(1&amp;lt;&amp;lt;PB2) */&lt;br /&gt;
&lt;br /&gt;
    // übersichtliche Alternative - Binärschreibweise&lt;br /&gt;
    PORTB = 0b00000100;    /* direkte Zuweisung - übersichtlich */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
wird also der Ausgang an Pin PB2 gesetzt (Beachte, dass die Bits immer &#039;&#039;von 0 an&#039;&#039; gezählt werden, das niederwertigste Bit ist also Bitnummer 0 und nicht etwa Bitnummer 1).&lt;br /&gt;
&lt;br /&gt;
Man beachte, dass bei der Zuweisung mittels &#039;&#039;&#039;=&#039;&#039;&#039; immer alle Pins gleichzeitig angegeben werden. Man sollte also, wenn nur bestimmte Ausgänge geschaltet werden sollen, zuerst den aktuellen Wert des Ports einlesen und das Bit des gewünschten Ports in diesen Wert einfließen lassen. Will man also nur den dritten Pin (Bit Nr. 2) an Port B auf &amp;quot;high&amp;quot; setzen und den Status der anderen Ausgänge unverändert lassen, nutze man diese Form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
    PORTB = PORTB | 0x04; /* besser: PORTB = PORTB | ( 1&amp;lt;&amp;lt;PB2 ) */&lt;br /&gt;
    /* vereinfacht durch Nutzung des |= Operators : */&lt;br /&gt;
    PORTB |= (1&amp;lt;&amp;lt;PB2);&lt;br /&gt;
&lt;br /&gt;
    /* auch mehrere &amp;quot;gleichzeitig&amp;quot;: */&lt;br /&gt;
    PORTB |= (1&amp;lt;&amp;lt;PB4) | (1&amp;lt;&amp;lt;PB5); /* Pins PB4 und PB5 &amp;quot;high&amp;quot; */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Ausschalten&amp;quot;, also  Ausgänge auf &amp;quot;low&amp;quot; setzen, erfolgt analog:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
    PORTB &amp;amp;= ~(1&amp;lt;&amp;lt;PB2); /* löscht Bit 2 in PORTB und setzt damit Pin PB2 auf low */ &lt;br /&gt;
    PORTB &amp;amp;= ~( (1&amp;lt;&amp;lt;PB4) | (1&amp;lt;&amp;lt;PB5) ); /* Pin PB4 und Pin PB5 &amp;quot;low&amp;quot; */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Siehe auch [[Bitmanipulation]]&lt;br /&gt;
&lt;br /&gt;
In Quellcodes, die für ältere Version den des avr-gcc/der avr-libc entwickelt wurden, werden einzelne Bits mittels der Funktionen sbi und cbi gesetzt bzw. gelöscht. Beide Funktionen sind in aktuellen Versionen der avr-libc nicht mehr enthalten und auch nicht mehr erforderlich.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Falls der Anfangszustand von Ausgängen kritisch ist, muss die Reihenfolge beachtet werden, mit der die Datenrichtung (DDRx) eingestellt und der Ausgabewert (PORTx) gesetzt wird:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Für Ausgangspins, die mit Anfangswert &amp;quot;high&amp;quot; initialisiert werden sollen:&lt;br /&gt;
* zuerst die Bits im PORTx-Register setzen&lt;br /&gt;
* anschließend die Datenrichtung auf Ausgang stellen&lt;br /&gt;
&lt;br /&gt;
Daraus ergibt sich die Abfolge für einen Pin, der bisher als Eingang mit abgeschaltetem Pull-Up konfiguriert war:&lt;br /&gt;
* setze PORTx: interner Pull-Up aktiv&lt;br /&gt;
* setze DDRx: Ausgang (&amp;quot;high&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Bei der Reihenfolge erst DDRx und dann PORTx kann es zu einem kurzen &amp;quot;low-Puls&amp;quot; kommen, der auch externe Pull-Up-Widerstände &amp;quot;überstimmt&amp;quot;. Die (ungünstige) Abfolge: Eingang -&amp;gt; setze DDRx: Ausgang (auf &amp;quot;low&amp;quot;, da PORTx nach Reset 0) -&amp;gt; setze PORTx: Ausgang auf high. Vergleiche dazu auch das Datenblatt Abschnitt &#039;&#039;Configuring the Pin&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Eingänge (Wie kommen Signale in den &amp;amp;micro;C) ==&lt;br /&gt;
&lt;br /&gt;
Die digitalen Eingangssignale können auf verschiedene Arten zu unserer Logik gelangen.&lt;br /&gt;
&lt;br /&gt;
=== Signalkopplung ===&lt;br /&gt;
&lt;br /&gt;
Am einfachsten ist es, wenn die Signale direkt aus einer anderen digitalen Schaltung übernommen werden können. Hat der Ausgang der entsprechenden Schaltung TTL-Pegel dann können wir sogar direkt den Ausgang der Schaltung mit einem Eingangspin von unserem Controller verbinden.&lt;br /&gt;
&lt;br /&gt;
Hat der Ausgang der anderen Schaltung keinen TTL-Pegel so müssen wir den Pegel über entsprechende Hardware (z.&amp;amp;nbsp;B. Optokoppler, [[Widerstand#Spannungsteiler|Spannungsteiler]], &amp;quot;Levelshifter&amp;quot; aka [[Pegelwandler]]) anpassen.&lt;br /&gt;
&lt;br /&gt;
Die Masse der beiden Schaltungen muss selbstverständlich miteinander verbunden werden. Der Software selber ist es natürlich letztendlich egal, wie das Signal eingespeist wird. Wir können ja ohnehin lediglich prüfen, ob an einem Pin unseres Controllers eine logische 1 (Spannung größer ca. 0,7*Vcc) oder eine logische 0 (Spannung kleiner ca. 0,2*Vcc) anliegt. Detaillierte Informationen darüber, ab welcher Spannung ein Eingang als 0 (&amp;quot;low&amp;quot;) bzw. 1 (&amp;quot;high&amp;quot;) erkannt wird, liefert die Tabelle DC Characteristics im Datenblatt des genutzten Controllers.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Spannungstabelle&#039;&#039;&#039; &amp;lt;br /&amp;gt; &amp;lt;small&amp;gt;(ca. Grenzwerte)&amp;lt;/small&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
! Low || High&lt;br /&gt;
|-&lt;br /&gt;
! bei 5 V&lt;br /&gt;
| 1 V || 3,5 V&lt;br /&gt;
|-&lt;br /&gt;
! bei 3,3 V&lt;br /&gt;
| 0,66 V || 2,31 V&lt;br /&gt;
|-&lt;br /&gt;
! bei 1,8 V&lt;br /&gt;
| 0,36 V || 1,26 V&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Abfrage der Zustände der Portpins erfolgt direkt über den Registernamen.&lt;br /&gt;
&lt;br /&gt;
{{Warnung|Dabei ist wichtig, zur Abfrage der Eingänge &#039;&#039;nicht&#039;&#039; etwa Portregister &#039;&#039;&#039;PORTx&#039;&#039;&#039; zu verwenden, sondern Eingangsregister &#039;&#039;&#039;PINx&#039;&#039;&#039;. Ansonsten liest man nicht den Zustand der Eingänge, sondern den Status der internen Pull-Up-Widerstände. Die Abfrage der Pinzustände über PORTx statt PINx ist ein häufiger Fehler beim AVR-&amp;quot;Erstkontakt&amp;quot;.}}&lt;br /&gt;
&lt;br /&gt;
Will man also die aktuellen Signalzustände von Port D abfragen und in eine Variable namens bPortD abspeichern, schreibt man folgende Befehlszeilen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
uint8_t bPortD;&lt;br /&gt;
...&lt;br /&gt;
bPortD = PIND;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit den C-Bitoperationen kann man den Status der Bits abfragen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
/* Fuehre Aktion aus, wenn Bit Nr. 1 (das &amp;quot;zweite&amp;quot; Bit) in PINC gesetzt (1) ist */&lt;br /&gt;
if ( PINC &amp;amp; (1&amp;lt;&amp;lt;PINC1) ) {&lt;br /&gt;
  /* Aktion */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Fuehre Aktion aus, wenn Bit Nr. 2 (das &amp;quot;dritte&amp;quot; Bit) in PINB geloescht (0) ist */&lt;br /&gt;
if ( !(PINB &amp;amp; (1&amp;lt;&amp;lt;PINB2)) ) {&lt;br /&gt;
  /* Aktion */&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Siehe auch [[Bitmanipulation#Bits_prüfen]]&lt;br /&gt;
&lt;br /&gt;
=== Interne Pull-Up Widerstände ===&lt;br /&gt;
&lt;br /&gt;
Portpins für Ein- und Ausgänge (GPIO) eines AVR verfügen über zuschaltbare interne Pull-Up Widerstände (nominal mehrere 10kOhm, z.&amp;amp;nbsp;B. ATmega16 20-50kOhm). Diese können in vielen Fällen statt externer Widerstände genutzt werden.&lt;br /&gt;
&lt;br /&gt;
Die internen Pull-Up Widerstände von Vcc zu den einzelnen Portpins werden über das Register &#039;&#039;&#039; PORTx&#039;&#039;&#039; aktiviert bzw. deaktiviert, wenn ein Pin als &#039;&#039;&#039; Eingang&#039;&#039;&#039; geschaltet ist.&lt;br /&gt;
&lt;br /&gt;
Wird der Wert des entsprechenden Portpins auf 1 gesetzt, so ist der Pull-Up Widerstand aktiviert. Bei einem Wert von 0 ist der Pull-Up Widerstand nicht aktiv. Man sollte jeweils entweder den internen oder einen externen Pull-Up Widerstand verwenden, aber nicht beide zusammen.&lt;br /&gt;
&lt;br /&gt;
Im Beispiel werden alle Pins des Ports D als Eingänge geschaltet und alle Pull-Up Widerstände aktiviert. Weiterhin wird Pin PC7 als Eingang geschaltet und dessen interner Pull-Up Widerstand aktiviert, ohne die Einstellungen für die anderen Portpins (PC0-PC6) zu verändern.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
DDRD  = 0x00; /* alle Pins von Port D als Eingang */&lt;br /&gt;
PORTD = 0xff; /* interne Pull-Ups an allen Port-Pins aktivieren */&lt;br /&gt;
...&lt;br /&gt;
DDRC  &amp;amp;= ~(1&amp;lt;&amp;lt;PC7);  /* Pin PC7 als Eingang */&lt;br /&gt;
PORTC |= (1&amp;lt;&amp;lt;PC7);    /* internen Pull-Up an PC7 aktivieren */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Taster und Schalter ===&lt;br /&gt;
&lt;br /&gt;
Der Anschluss mechanischer Kontakte an den Mikrocontroller, ist zwischen zwei unterschiedliche Methoden zu unterscheiden: &#039;&#039;Active Low&#039;&#039; und &#039;&#039;Active High&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery widths=&amp;quot;300&amp;quot; heights=&amp;quot;300&amp;quot; caption=&amp;quot;Anschluss mechanischer Kontakte an einen µC&amp;quot;&amp;gt;&lt;br /&gt;
Image:Active Low.gif|&#039;&#039;&#039;Active Low:&#039;&#039;&#039; Bei dieser Methode wird der Kontakt zwischen den Eingangspin des Controllers und Masse geschaltet. Damit bei offenem Schalter der Controller kein undefiniertes Signal bekommt, wird zwischen die Versorgungsspannung und den Eingangspin ein sogenannter &#039;&#039;&#039;Pull-Up&#039;&#039;&#039; Widerstand geschaltet. Dieser dient dazu, den Pegel bei geöffnetem Schalter auf logisch 1 zu ziehen.&lt;br /&gt;
Image:Active High.gif|&#039;&#039;&#039;Active High:&#039;&#039;&#039; Hier wird der Kontakt zwischen die Versorgungsspannung und den Eingangspin geschaltet. Damit bei offener Schalterstellung kein undefiniertes Signal am Controller ansteht, wird zwischen den Eingangspin und die Masse ein &#039;&#039;&#039;Pull-Down&#039;&#039;&#039; Widerstand geschaltet. Dieser dient dazu, den Pegel bei geöffneter Schalterstellung auf logisch 0 zu halten. &lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Widerstandswert von Pull-Up- und Pull-Down-Widerständen ist an sich nicht kritisch. Wird er allerdings zu hoch gewählt, ist die Wirkung eventuell nicht gegeben. Als üblicher Wert haben sich 10 kOhm eingebürgert. Die AVRs verfügen an den meisten Pins über zuschaltbare interne Pull-Up Widerstände (vgl. Abschnitt [[AVR-GCC-Tutorial#Interne Pull-Up Widerstände|Interne Pull-Up Widerstände]]), welche insbesondere wie hier bei Tastern und ähnlichen Bauteilen (z.&amp;amp;nbsp;B. Drehgebern) statt externer Bauteile verwendet werden können. Interne Pull-Down-Widerstand sind nicht verfügbar und müssen daher in Form zusätzlicher Bauteile in die Schaltung eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
==== Taster entprellen ====&lt;br /&gt;
&lt;br /&gt;
Siehe: &#039;&#039;[[Entprellung#Warteschleifen-Verfahren|Entprellung: Warteschleifen-Verfahren]]&lt;br /&gt;
&lt;br /&gt;
= Warteschleifen (delay.h) =&lt;br /&gt;
&lt;br /&gt;
Der Programmablauf kann verschiedene Arten von Wartefunktionen erfordern:&lt;br /&gt;
&lt;br /&gt;
* Warten im Sinn von Zeitvertrödeln&lt;br /&gt;
* Warten auf einen bestimmten Zustand an den I/O-Pins&lt;br /&gt;
* Warten auf einen bestimmten Zeitpunkt (siehe Timer)&lt;br /&gt;
* Warten auf einen bestimmten Zählerstand (siehe Counter)&lt;br /&gt;
&lt;br /&gt;
Der einfachste Fall, das Zeitvertrödeln, kann in vielen Fällen und mit großer Genauigkeit anhand der avr-libc Bibliotheksfunktionen _delay_ms() und _delay_us() erledigt werden. Die Bibliotheksfunktionen sind einfachen Zählschleifen (Warteschleifen) vorzuziehen, da leere Zählschleifen ohne besondere Vorkehrungen sonst bei eingeschalteter Optimierung vom avr-gcc-Compiler wegoptimiert werden. Weiterhin sind die Bibliotheksfunktionen bereits darauf vorbereitet, die in F_CPU definierte Taktfrequenz zu verwenden. Außerdem sind die Funktionen der Bibliothek wirklich getestet.&lt;br /&gt;
&lt;br /&gt;
Einfach!? Schon, aber während gewartet wird, macht der µC nichts anderes mehr (abgesehen von möglicherweise auftretenden Interrupts, falls welche aktiviert sind). Die Wartefunktion blockiert den Programmablauf. Möchte man einerseits warten, um z.&amp;amp;nbsp;B. eine LED blinken zu lassen und gleichzeitig andere Aktionen ausführen z.&amp;amp;nbsp;B. weitere LED bedienen, sollten die Timer/Counter des AVR verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Die Bibliotheksfunktionen funktionieren allerdings nur dann korrekt, wenn sie mit zur Übersetzungszeit (beim Compilieren) bekannten konstanten Werten aufgerufen werden. Der Quellcode muss mit eingeschalteter Optimierung übersetzt werden, sonst wird sehr viel Maschinencode erzeugt, und die Wartezeiten stimmen nicht mehr mit dem Parameter überein.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Einschränkung liegt darin, daß sie möglicherweise länger warten, als erwartet, nämlich in dem Fall, daß Interrupts auftreten und die _delay...()-Funktion unterbrechen. Genau genommen warten diese nämlich nicht eine bestimmte Zeit, sondern verbrauchen eine bestimmte Anzahl von Prozessortakten. Die wiederum ist so bemessen, daß ohne Unterbrechung durch Interrupts die gewünschte Wartezeit erreicht wird.&lt;br /&gt;
Wird das Warten aber durch eine oder mehrere ISR unterbrochen, die zusammen 1% Prozessorzeit verbrauchen, dann dauert das Warten etwa 1% länger. Bei 50% Last durch die ISR dauert das Warten doppelt solange wie gewünscht, bei 90% zehnmal solange...&lt;br /&gt;
&lt;br /&gt;
Abhängig von der Version der Bibliothek verhalten sich die Bibliotheksfunktionen etwas unterschiedlich.&lt;br /&gt;
&lt;br /&gt;
== avr-libc Versionen kleiner 1.6 ==&lt;br /&gt;
&lt;br /&gt;
Die Wartezeit der Funktion _delay_ms() ist auf 262,14ms/F_CPU (in MHz) begrenzt, d.h. bei 20 MHz kann man nur max. 13,1ms warten. Die Wartezeit der Funktion _delay_us() ist auf 768us/F_CPU (in MHz) begrenzt, d.h. bei 20 MHz kann man nur max. 38,4µs warten. Längere Wartezeiten müssen dann über einen mehrfachen Aufruf in einer Schleife gelöst werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Blinken einer LED an PORTB Pin PB0 im ca. 1s Rhythmus&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert &lt;br /&gt;
   (z.&amp;amp;nbsp;B. durch Übergabe als Parameter zum Compiler innerhalb &lt;br /&gt;
   des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die&lt;br /&gt;
   &amp;quot;nachträgliche&amp;quot; Definition hinweist */&lt;br /&gt;
#warning &amp;quot;F_CPU war noch nicht definiert, wird nun mit 3686400 definiert&amp;quot;&lt;br /&gt;
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */&lt;br /&gt;
#endif&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;     /* in älteren avr-libc Versionen &amp;lt;avr/delay.h&amp;gt; */ &lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 lange, variable Verzögerungszeit, Einheit in Millisekunden&lt;br /&gt;
&lt;br /&gt;
Die maximale Zeit pro Funktionsaufruf ist begrenzt auf &lt;br /&gt;
262.14 ms / F_CPU in MHz (im Beispiel: &lt;br /&gt;
262.1 / 3.6864 = max. 71 ms) &lt;br /&gt;
&lt;br /&gt;
Daher wird die kleine Warteschleife mehrfach aufgerufen,&lt;br /&gt;
um auf eine längere Wartezeit zu kommen. Die zusätzliche &lt;br /&gt;
Prüfung der Schleifenbedingung lässt die Wartezeit geringfügig&lt;br /&gt;
ungenau werden (macht hier vielleicht 2-3ms aus).&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
void long_delay(uint16_t ms)&lt;br /&gt;
{&lt;br /&gt;
    for(; ms&amp;gt;0; ms--) _delay_ms(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main( void )&lt;br /&gt;
{&lt;br /&gt;
    DDRB = ( 1 &amp;lt;&amp;lt; PB0 );        // PB0 an PORTB als Ausgang setzen&lt;br /&gt;
&lt;br /&gt;
    while( 1 )                  // Endlosschleife&lt;br /&gt;
    {                &lt;br /&gt;
        PORTB ^= ( 1 &amp;lt;&amp;lt; PB0 );  // Toggle PB0 z.&amp;amp;nbsp;B. angeschlossene LED&lt;br /&gt;
        long_delay(1000);       // Eine Sekunde warten...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== avr-libc Versionen ab 1.6 ==&lt;br /&gt;
&lt;br /&gt;
_delay_ms() kann mit einem Argument bis 6553,5 ms (= 6,5535 Sekunden) benutzt werden. Es ist nicht möglich, eine Variable als Argument zu übergeben. Wird die früher gültige Grenze von 262,14 ms/F_CPU (in MHz) überschritten, so arbeitet _delay_ms() einfach etwas ungenauer und zählt nur noch mit einer Auflösung von 1/10 ms. Eine Verzögerung von 1000,10 ms ließe sich nicht mehr von einer von 1000,19 ms unterscheiden. Ein Verlust, der sich im Allgemeinen verschmerzen lässt. Dem Programmierer wird keine Rückmeldung gegeben, dass die Funktion ggf. gröber arbeitet, d.h. wenn es darauf ankommt, bitte den Parameter wie bisher geschickt wählen.&lt;br /&gt;
&lt;br /&gt;
Die Funktion _delay_us() wurde ebenfalls erweitert. Wenn deren maximal als genau behandelbares Argument überschritten wird, benutzt diese intern _delay_ms(). Damit gelten in diesem Fall die _delay_ms() Einschränkungen.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Blinken einer LED an PORTB Pin PB0 im ca. 1s Rhythmus, avr-libc ab Version 1.6&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert &lt;br /&gt;
   (z.B. durch Übergabe als Parameter zum Compiler innerhalb &lt;br /&gt;
   des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die&lt;br /&gt;
   &amp;quot;nachträgliche&amp;quot; Definition hinweist */&lt;br /&gt;
#warning &amp;quot;F_CPU war noch nicht definiert, wird nun mit 3686400 definiert&amp;quot;&lt;br /&gt;
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */&lt;br /&gt;
#endif&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main( void )&lt;br /&gt;
{&lt;br /&gt;
    DDRB = ( 1 &amp;lt;&amp;lt; PB0 );        // PB0 an PORTB als Ausgang setzen&lt;br /&gt;
&lt;br /&gt;
    while( 1 ) {                // Endlosschleife&lt;br /&gt;
        PORTB ^= ( 1 &amp;lt;&amp;lt; PB0 );  // Toggle PB0 z.B. angeschlossene LED&lt;br /&gt;
        _delay_ms(1000);        // Eine Sekunde +/-1/10000 Sekunde warten...&lt;br /&gt;
                                // funktioniert nicht mit Bibliotheken vor 1.6&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trick zur Übergabe einer Variablen an _delay_ms():&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
#warning &amp;quot;F_CPU war noch nicht definiert, wird nun mit 3686400 definiert&amp;quot;&lt;br /&gt;
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */&lt;br /&gt;
#endif&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void sleep ( uint8_t ms )&lt;br /&gt;
{&lt;br /&gt;
    for(; ms &amp;gt; 0; ms--) _delay_ms(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main( void )&lt;br /&gt;
{&lt;br /&gt;
    int x = 0;                  // Variable als Wartezeit erstellen&lt;br /&gt;
    DDRB = ( 1 &amp;lt;&amp;lt; PB0 );        // PB0 an PORTB als Ausgang setzen&lt;br /&gt;
&lt;br /&gt;
    while( 1 ) {                // Endlosschleife&lt;br /&gt;
        PORTB ^= ( 1 &amp;lt;&amp;lt; PB0 );  // Toggle PB0 z.B. angeschlossene LED&lt;br /&gt;
        sleep(x); &lt;br /&gt;
        x++;       &lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die _delay_ms() und die _delay_us aus &#039;&#039;&#039;avr-libc 1.7.0&#039;&#039;&#039; sind fehlerhaft. _delay_ms () läuft 4x schneller als erwartet. Abhilfe ist eine korrigierte Includedatei: [http://www.mikrocontroller.net/topic/196738#1943039]&lt;br /&gt;
&lt;br /&gt;
= Programmieren mit Interrupts =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:right; margin:2em;&amp;quot;&amp;gt;&lt;br /&gt;
[[Image:Interrupt Programme.gif]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Nachdem wir nun alles Wissenswerte für die serielle Programmerstellung&lt;br /&gt;
gelernt haben nehmen wir jetzt ein völlig anderes Thema in Angriff, nämlich&lt;br /&gt;
die Programmierung unter Zuhilfenahme der Interrupts des AVR.&lt;br /&gt;
&lt;br /&gt;
Tritt ein Interrupt auf, unterbricht (engl. interrupts) der Controller die Verarbeitung des Hauptprogramms und verzweigt zu einer Interruptroutine. Das Hauptprogramm wird also beim Eintreffen eines Interrupts unterbrochen, die Interruptroutine ausgeführt und danach erst wieder das Hauptprogramm an der Unterbrechungsstelle fortgesetzt (vgl. die Abbildung).&lt;br /&gt;
&lt;br /&gt;
Um Interrupts verarbeiten zu können, ist folgendes zu beachten:&lt;br /&gt;
&lt;br /&gt;
* Für jede aktivierte Interruptquelle ist eine Funktion zu programmieren, in der die beim Auftreten des jeweiligen Interrupts erforderlichen Verarbeitungsschritte enthalten sind. Für diese Funktion exisiteren verschiede Bezeichnungen. Üblich sind die englischen Begriffe Interrupt-Handler oder Interrupt-Service-Routinen (ISR), man findet aber auch die Bezeichnungen Interruptverarbeitungs- oder -behandlungsroutine oder auch kurz Interuptroutine. Zum Beispiel wird üblicherweise in der ISR zur Verarbeitung des Empfangsinterrupts eines UARTs (UART-RX Interrupt) das empfangene Zeichen in einen Zwischenspeicher (FIFO-Buffer) kopiert, dessen Inhalt später von anderen Programmteilen geleert wird. Sofern der Zwischenspeicher ausreichend groß ist, geht also kein Zeichen verloren, auch wenn im Hauptprogramm zeitintensive Operationen durchgeführt werden.&lt;br /&gt;
* Die benötigten Interrupts sind in den jeweiligen Funktionsbausteinen einzuschalten. Dies erfolgt über das jeweilige Aktivierungsbit (Interrupt Enable) in einem der Hardwareregister (z.B. RX(Complete)Interrupt Enable eines UARTs)&lt;br /&gt;
* Sämtliche Interrupts werden über einen weiteren globalen Schalter aktiviert und deaktiviert. Zur Verarbeitung der Interrupts ist dieser Schalter zu aktivieren (sei(), siehe untern).&lt;br /&gt;
 &lt;br /&gt;
Alle Punkte sind zu beachten. Fehlt z.B. die globale Aktivierung, werden Interruptroutinen auch dann nicht aufgerufen, wenn sie im Funktionsbaustein eingeschaltet sind und eine Behandlungsroutine verhanden ist.&lt;br /&gt;
&lt;br /&gt;
Siehe auch&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-1-235092.html#new Ausführlicher Thread im Forum]&lt;br /&gt;
* Artikel [[Interrupt]]&lt;br /&gt;
* Artikel [[Multitasking]]&lt;br /&gt;
{{Clear}}&lt;br /&gt;
&lt;br /&gt;
== Anforderungen an Interrupt-Routinen ==&lt;br /&gt;
&lt;br /&gt;
Um unliebsamen Überraschungen vorzubeugen, sollten einige Grundregeln bei der Implementierung der Interruptroutinen beachtet werden. Interruptroutinen sollten möglichst kurz und schnell abarbeitbar sein, daraus folgt:&lt;br /&gt;
&lt;br /&gt;
* Keine umfangreichen Berechnungen innerhalb der Interruptroutine. (*)&lt;br /&gt;
* Keine langen Programmschleifen.&lt;br /&gt;
* Obwohl es möglich ist, während der Abarbeitung einer Interruptroutine andere oder sogar den gleichen Interrupt wieder zuzulassen, wird davon ohne genaue Kenntnis der internen Abläufe dringend abgeraten.&lt;br /&gt;
&lt;br /&gt;
Interruptroutinen (ISRs) sollten also möglichst kurz sein und keine Schleifen mit vielen Durchläufen enthalten. Längere Operationen können meist in einen &amp;quot;Interrupt-Teil&amp;quot; in einer ISR und einen &amp;quot;Arbeitsteil&amp;quot; im Hauptprogramm aufgetrennt werden. Z.B. Speichern des Zustands aller Eingänge im EEPROM in bestimmten Zeitabständen: ISR-Teil: Zeitvergleich (Timer,RTC) mit Logzeit/-intervall. Bei Übereinstimmung ein globales Flag setzen (volatile bei Flag-Deklaration nicht vergessen, s.u.). Dann im Hauptprogramm prüfen, ob das Flag gesetzt ist. Wenn ja: die Daten im EEPROM ablegen und Flag löschen.&lt;br /&gt;
&lt;br /&gt;
(*)&lt;br /&gt;
Hinweis: &lt;br /&gt;
Es gibt allerdings die seltene Situation, dass man gerade eingelesene&lt;br /&gt;
ADC-Werte sofort verarbeiten muss. Besonders dann, wenn man mehrere Werte sehr&lt;br /&gt;
schnell hintereinander bekommt. Dann bleibt einem nichts anderes übrig, als die&lt;br /&gt;
Werte noch in der ISR zu verarbeiten. Kommt aber sehr selten vor und sollte&lt;br /&gt;
durch geeignete Wahl des Systemtaktes bzw. Auswahl des Controllers vermieden werden!&lt;br /&gt;
&lt;br /&gt;
== Interrupt-Quellen ==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Ereignisse können einen Interrupt auf einem AVR AT90S2313 auslösen, wobei die Reihenfolge der Auflistung auch die Priorität der Interrupts aufzeigt.&lt;br /&gt;
&lt;br /&gt;
* Reset&lt;br /&gt;
* Externer Interrupt 0&lt;br /&gt;
* Externer Interrupt 1&lt;br /&gt;
* Timer/Counter 1 Capture Ereignis&lt;br /&gt;
* Timer/Counter 1 Compare Match&lt;br /&gt;
* Timer/Counter 1 Überlauf&lt;br /&gt;
* Timer/Counter 0 Überlauf&lt;br /&gt;
* UART Zeichen empfangen&lt;br /&gt;
* UART Datenregister leer&lt;br /&gt;
* UART Zeichen gesendet&lt;br /&gt;
* Analoger Komparator&lt;br /&gt;
&lt;br /&gt;
Die Anzahl der möglichen Interruptquellen variiert zwischen den verschiedenen Microcontroller-Typen. Im Zweifel hilft ein Blick ins Datenblatt (&amp;quot;Interrupt Vectors&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
== Register ==&lt;br /&gt;
&lt;br /&gt;
Der AT90S2313 verfügt über 2 Register die mit den&lt;br /&gt;
Interrupts zusammen hängen.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;GIMSK&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;G&#039;&#039;&#039;eneral &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;M&#039;&#039;&#039;a&#039;&#039;&#039;sk&#039;&#039;&#039; Register.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit &lt;br /&gt;
| 7 || 6|| 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;INT1&#039;&#039;&#039; || &#039;&#039;&#039;INT0&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W || R/W || R || R || R || R || R || R&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;INT1&#039;&#039;&#039; (External &#039;&#039;&#039;Int&#039;&#039;&#039;errupt Request &#039;&#039;&#039;1&#039;&#039;&#039; Enable)&lt;br /&gt;
:Wenn dieses Bit gesetzt ist, wird ein Interrupt ausgelöst, wenn am &#039;&#039;&#039;INT1&#039;&#039;&#039;-Pin eine steigende oder fallende (je nach Konfiguration im &#039;&#039;&#039;MCUCR&#039;&#039;&#039;) Flanke erkannt wird.&lt;br /&gt;
:Das Global Enable Interrupt Flag muss selbstverständlich auch gesetzt sein.&lt;br /&gt;
:Der Interrupt wird auch ausgelöst, wenn der Pin als Ausgang geschaltet ist. Auf diese Weise bietet sich die Möglichkeit, Software-Interrupts zu realisieren.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;INT0&#039;&#039;&#039; (External &#039;&#039;&#039;Int&#039;&#039;&#039;errupt Request &#039;&#039;&#039;0&#039;&#039;&#039; Enable)&lt;br /&gt;
:Wenn dieses Bit gesetzt ist, wird ein Interrupt ausgelöst, wenn am &#039;&#039;&#039;INT0&#039;&#039;&#039;-Pin eine steigende oder fallende (je nach Konfiguration im &#039;&#039;&#039;MCUCR&#039;&#039;&#039;) Flanke erkannt wird.&lt;br /&gt;
:Das Global Enable Interrupt Flag muss selbstverständlich auch gesetzt sein.&lt;br /&gt;
:Der Interrupt wird auch ausgelöst, wenn der Pin als Ausgang geschaltet ist. Auf diese Weise bietet sich die Möglichkeit, Software-Interrupts zu realisieren.&lt;br /&gt;
&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;GIFR&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;G&#039;&#039;&#039;eneral &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;F&#039;&#039;&#039;lag &#039;&#039;&#039;R&#039;&#039;&#039;egister.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;INTF1&#039;&#039;&#039; || &#039;&#039;&#039;INTF0&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W || R/W || R || R || R || R || R || R&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;INTF1&#039;&#039;&#039; (External &#039;&#039;&#039;Int&#039;&#039;&#039;errupt Flag &#039;&#039;&#039;1&#039;&#039;&#039;)&lt;br /&gt;
:Dieses Bit wird gesetzt, wenn am &#039;&#039;&#039;INT1&#039;&#039;&#039;-Pin eine Interrupt-Bedingung, entsprechend der Konfiguration, als eingetreten erkannt wird. Wenn das Global Enable Interrupt Flag gesetzt ist, wird die Interruptroutine angesprungen.&lt;br /&gt;
:Das Flag wird automatisch gelöscht, wenn die Interruptroutine beendet ist. Alternativ kann das Flag gelöscht werden, indem der Wert &#039;&#039;&#039;1(!)&#039;&#039;&#039; eingeschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;INTF0&#039;&#039;&#039; (External &#039;&#039;&#039;Int&#039;&#039;&#039;errupt Flag &#039;&#039;&#039;0&#039;&#039;&#039;)&lt;br /&gt;
:Dieses Bit wird gesetzt, wenn am &#039;&#039;&#039;INT0&#039;&#039;&#039;-Pin eine Interrupt-Bedingung, entsprechend der Konfiguration, als eingetreten erkannt wird. Wenn das Global Enable Interrupt Flag gesetzt ist, wird die Interruptroutine angesprungen.&lt;br /&gt;
:Das Flag wird automatisch gelöscht, wenn die Interruptroutine beendet ist. Alternativ kann das Flag gelöscht werden, indem der Wert &#039;&#039;&#039;1(!)&#039;&#039;&#039; eingeschrieben wird.&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;MCUCR&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;MCU&#039;&#039;&#039; &#039;&#039;&#039;C&#039;&#039;&#039;ontrol &#039;&#039;&#039;R&#039;&#039;&#039;egister.&lt;br /&gt;
&lt;br /&gt;
Das MCU Control Register enthält Kontrollbits für allgemeine MCU-Funktionen.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;SE&#039;&#039;&#039;|| &#039;&#039;&#039;SM&#039;&#039;&#039;|| &#039;&#039;&#039;ISC11&#039;&#039;&#039;|| &#039;&#039;&#039;ISC10&#039;&#039;&#039;|| &#039;&#039;&#039;ISC01&#039;&#039;&#039;|| &#039;&#039;&#039;ISC00&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R || R || R/W || R/W || R/W || R/W || R/W || R/W&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SE&#039;&#039;&#039; (&#039;&#039;&#039;S&#039;&#039;&#039;leep &#039;&#039;&#039;E&#039;&#039;&#039;nable)&lt;br /&gt;
:Dieses Bit muss gesetzt sein, um den Controller mit dem &#039;&#039;&#039;SLEEP&#039;&#039;&#039;-Befehl in den Schlafzustand versetzen zu können.&lt;br /&gt;
:Um den Schlafmodus nicht irrtümlich einzuschalten, wird empfohlen, das Bit erst unmittelbar vor Ausführung des &#039;&#039;&#039;SLEEP&#039;&#039;&#039;-Befehls zu setzen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SM&#039;&#039;&#039; (&#039;&#039;&#039;S&#039;&#039;&#039;leep &#039;&#039;&#039;M&#039;&#039;&#039;ode)&lt;br /&gt;
:Dieses Bit bestimmt über den Schlafmodus.&lt;br /&gt;
:Ist das Bit gelöscht, so wird der &#039;&#039;&#039;Idle&#039;&#039;&#039;-Modus ausgeführt. Ist das Bit gesetzt, so wird der &#039;&#039;&#039;Power-Down&#039;&#039;&#039;-Modus ausgeführt. (für andere AVR Controller siehe Abschnitt &amp;quot;Sleep-Mode&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ISC11&#039;&#039;&#039;, &#039;&#039;&#039;ISC10&#039;&#039;&#039; (&#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;S&#039;&#039;&#039;ense &#039;&#039;&#039;C&#039;&#039;&#039;ontrol &#039;&#039;&#039;1&#039;&#039;&#039; Bits)&lt;br /&gt;
:Diese beiden Bits bestimmen, ob die steigende oder die fallende Flanke für die Interrupterkennung am &#039;&#039;&#039;INT1&#039;&#039;&#039;-Pin ausgewertet wird.&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! ISC11 || ISC10 || Bedeutung&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Low Level an &#039;&#039;&#039;INT1&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
&lt;br /&gt;
Der Interrupt wird getriggert, solange der Pin auf 0 bleibt.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Reserviert&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Die fallende Flanke an &#039;&#039;&#039;INT1&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Die steigende Flanke an &#039;&#039;&#039;INT1&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ISC01&#039;&#039;&#039;, &#039;&#039;&#039;ISC00&#039;&#039;&#039; (&#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;S&#039;&#039;&#039;ense &#039;&#039;&#039;C&#039;&#039;&#039;ontrol &#039;&#039;&#039;0&#039;&#039;&#039; Bits)&lt;br /&gt;
:Diese beiden Bits bestimmen, ob die steigende oder die fallende Flanke für die Interrupterkennung am &#039;&#039;&#039;INT0&#039;&#039;&#039;-Pin ausgewertet wird.&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! ISC01 || ISC00 || Bedeutung&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Low Level an &#039;&#039;&#039;INT0&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
&lt;br /&gt;
Der Interrupt wird getriggert, solange der Pin auf 0 bleibt.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Reserviert&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Die fallende Flanke an &#039;&#039;&#039;INT0&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Die steigende Flanke an &#039;&#039;&#039;INT0&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Allgemeines über die Interrupt-Abarbeitung ==&lt;br /&gt;
&lt;br /&gt;
Wenn ein Interrupt eintrifft, wird automatisch das &#039;&#039;&#039;Global Interrupt Enable&#039;&#039;&#039; Bit im Status Register &#039;&#039;&#039;SREG&#039;&#039;&#039; gelöscht und alle weiteren Interrupts unterbunden. Obwohl es möglich ist, zu diesem Zeitpunkt bereits wieder das GIE-bit zu setzen, wird dringend davon abgeraten. Dieses wird nämlich automatisch gesetzt, wenn die Interruptroutine beendet wird. Wenn in der Zwischenzeit weitere Interrupts eintreffen, werden die zugehörigen Interrupt-Bits gesetzt und die Interrupts bei Beendigung der laufenden Interrupt-Routine in der Reihenfolge ihrer Priorität ausgeführt. Dies kann&lt;br /&gt;
eigentlich nur dann zu Problemen führen, wenn ein hoch priorisierter Interrupt ständig und in kurzer Folge auftritt. Dieser sperrt dann möglicherweise alle anderen Interrupts mit niedrigerer Priorität. Dies ist einer der Gründe, weshalb die Interrupt-Routinen sehr kurz gehalten werden sollen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- === Das Status-Register ===&lt;br /&gt;
&lt;br /&gt;
Es gilt auch zu beachten, dass das Status-Register während der Abarbeitung einer Interruptroutine nicht automatisch gesichert wird. Falls notwendig, muss dies vom Programmierer selber vorgesehen werden. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interrupts mit dem AVR GCC Compiler (WinAVR) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- &#039;&#039;Anmerkung eines Nutzers: Ich habe mir das Thema hier angearbeitet und hatte am Anfang starke Probleme: Jeder Interrupt muss nochmals einzeln aktiviert werden. Es reicht nicht nur per &#039;&#039;sei()&#039;&#039; die Interrupts global zu aktiveren.&#039;&#039; - mthomas: Hoffentlich duch die modifizerte Einleitung etwas offensichtlicher erläutert. Ansonsten bitte per Eintrag auf die Diskussionseite nochmals melden) --&amp;gt; &lt;br /&gt;
&amp;lt;!-- Selbstverständlich können alle interruptspezifischen Registerzugriffe wie gewohnt über I/O-Adressierung vorgenommen werden. Etwas einfacher geht es jedoch, wenn wir die vom Compiler zur Verfügung gestellten Mittel einsetzen.--&amp;gt;&lt;br /&gt;
Funktionen zur Interrupt-Verarbeitung werden in den Includedateien &#039;&#039;interrupt.h&#039;&#039;  der avr-libc zur Verfügung gestellt (bei älterem Quellcode zusätzlich &#039;&#039;signal.h&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// fuer sei(), cli() und ISR():&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Makro &#039;&#039;&#039;sei()&#039;&#039;&#039; schaltet die Interrupts ein. Eigentlich wird nichts anderes gemacht, als das &#039;&#039;&#039;Global Interrupt Enable&#039;&#039;&#039; Bit im Status Register gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    sei();&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Makro &#039;&#039;&#039;cli()&#039;&#039;&#039; schaltet die Interrupts aus, oder anders gesagt, das &#039;&#039;&#039;Global Interrupt Enable&#039;&#039;&#039; Bit im Status Register wird gelöscht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    cli();&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oft steht man vor der Aufgabe, dass eine Codesequenz nicht unterbrochen werden darf. Es liegt dann nahe, zu Beginn dieser Sequenz ein cli() und am Ende ein sei() einzufügen. Dies ist jedoch ungünstig, wenn die Interrupts vor Aufruf der Sequenz deaktiviert waren und danach auch weiterhin deaktiviert bleiben sollen. Ein sei() würde ungeachtet des vorherigen  Zustands die Interrupts aktivieren, was zu unerwünschten Seiteneffekten führen kann. Die aus dem folgenden Beispiel ersichtliche Vorgehensweise ist in solchen Fällen vorzuziehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
#include &amp;lt;inttypes.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
void NichtUnterbrechenBitte(void)&lt;br /&gt;
{&lt;br /&gt;
   uint8_t tmp_sreg;  // temporaerer Speicher fuer das Statusregister&lt;br /&gt;
&lt;br /&gt;
   tmp_sreg = SREG;   // Statusregister (also auch das I-Flag darin) sichern&lt;br /&gt;
   cli();             // Interrupts global deaktivieren&lt;br /&gt;
&lt;br /&gt;
   /* hier &amp;quot;unterbrechnungsfreier&amp;quot; Code */&lt;br /&gt;
&lt;br /&gt;
   /* Beispiel Anfang&lt;br /&gt;
     JTAG-Interface eines ATmega16 per Software deaktivieren &lt;br /&gt;
     und damit die JTAG-Pins an PORTC für &amp;quot;general I/O&amp;quot; nutzbar machen&lt;br /&gt;
     ohne die JTAG-Fuse-Bit zu aendern. Dazu ist eine &amp;quot;timed sequence&amp;quot;&lt;br /&gt;
     einzuhalten (vgl Datenblatt ATmega16, Stand 10/04, S. 229): &lt;br /&gt;
     Das JTD-Bit muss zweimal innerhalb von 4 Taktzyklen geschrieben &lt;br /&gt;
     werden. Ein Interrupt zwischen den beiden Schreibzugriffen wuerde &lt;br /&gt;
     die erforderliche Sequenz &amp;quot;brechen&amp;quot;, das JTAG-Interface bliebe&lt;br /&gt;
     weiterhin aktiv und die IO-Pins weiterhin für JTAG reserviert. */&lt;br /&gt;
&lt;br /&gt;
   MCUCSR |= (1&amp;lt;&amp;lt;JTD);&lt;br /&gt;
   MCUCSR |= (1&amp;lt;&amp;lt;JTD); // 2 mal in Folge ,vgl. Datenblatt fuer mehr Information&lt;br /&gt;
&lt;br /&gt;
   /* Beispiel Ende */&lt;br /&gt;
  &lt;br /&gt;
   SREG = tmp_sreg;     // Status-Register wieder herstellen &lt;br /&gt;
                      // somit auch das I-Flag auf gesicherten Zustand setzen&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NichtSoGut(void)&lt;br /&gt;
{&lt;br /&gt;
   cli();&lt;br /&gt;
   &lt;br /&gt;
   /* hier &amp;quot;unterbrechnungsfreier&amp;quot; Code */&lt;br /&gt;
   &lt;br /&gt;
   sei();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
   //...&lt;br /&gt;
&lt;br /&gt;
   cli();  &lt;br /&gt;
   // Interrupts global deaktiviert &lt;br /&gt;
&lt;br /&gt;
   NichtUnterbrechenBitte();&lt;br /&gt;
   // auch nach Aufruf der Funktion deaktiviert&lt;br /&gt;
&lt;br /&gt;
   sei();&lt;br /&gt;
   // Interrupts global aktiviert &lt;br /&gt;
&lt;br /&gt;
   NichtUnterbrechenBitte();&lt;br /&gt;
   // weiterhin aktiviert&lt;br /&gt;
   //...&lt;br /&gt;
&lt;br /&gt;
   /* Verdeutlichung der unguenstigen Vorgehensweise mit cli/sei: */&lt;br /&gt;
   cli();  &lt;br /&gt;
   // Interrupts jetzt global deaktiviert &lt;br /&gt;
&lt;br /&gt;
   NichtSoGut();&lt;br /&gt;
   // nach Aufruf der Funktion sind Interrupts global aktiviert &lt;br /&gt;
   // dies ist mglw. ungewollt!&lt;br /&gt;
   //...&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- mt: besser so nicht(?), lieber &amp;quot;datenblattkonform&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font face=&amp;quot;Courier New&amp;quot;&amp;gt;&#039;&#039;&#039;timer_enable_int (unsigned char ints);&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;/font&amp;gt;Schaltet Timerbezogene Interrupts ein bzw. aus.&amp;lt;br /&amp;gt;&lt;br /&gt;
Wenn als Argument &#039;&#039;&#039;ints&#039;&#039;&#039; der Wert 0 übergeben wird so werden alle&lt;br /&gt;
Timerinterrupts ausgeschaltet, ansonsten muss in &#039;&#039;&#039;ints&#039;&#039;&#039; angegeben werden,&lt;br /&gt;
welche Interrupts zu aktivieren sind. Dabei müssen einfach die entsprechend zu&lt;br /&gt;
setzenden Bits definiert werden.&amp;lt;br /&amp;gt;&lt;br /&gt;
Beispiel: &#039;&#039;&#039;&amp;lt;font face=&amp;quot;Courier New&amp;quot;&amp;gt;timer_enable_int (1 &amp;lt;&amp;lt; TOIE1));&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;/font&amp;gt;&#039;&#039;&#039;Achtung: Wenn ein Timerinterrupt eingeschaltet wird während ein&lt;br /&gt;
anderer Timerinterrupt bereits läuft, dann müssen beide Bits angegeben werden&lt;br /&gt;
sonst wird der andere Timerinterrupt versehentlich ausgeschaltet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font face=&amp;quot;Courier New&amp;quot;&amp;gt;&#039;&#039;&#039;enable_external_int (unsigned char ints);&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;/font&amp;gt;Schaltet die externen Interrupts ein bzw. aus.&amp;lt;br /&amp;gt;&lt;br /&gt;
Wenn als Argument &#039;&#039;&#039;ints&#039;&#039;&#039; der Wert 0 übergeben wird so werden alle externen&lt;br /&gt;
Interrrups ausgeschaltet, ansonsten muss in &#039;&#039;&#039;ints&#039;&#039;&#039; angegeben werden, welche&lt;br /&gt;
Interrupts zu aktivieren sind. Dabei müssen einfach die entsprechend zu&lt;br /&gt;
setzenden Bits definiert werden.&amp;lt;br /&amp;gt;&lt;br /&gt;
Beispiel: &#039;&#039;&#039;&amp;lt;font face=&amp;quot;Courier New&amp;quot;&amp;gt;enable_external_int ((1&amp;lt;&lt;br /&gt;
&amp;lt;/font&amp;gt;&#039;&#039;&#039;Schaltet die externen Interrupts 0 und 1 ein.&lt;br /&gt;
&lt;br /&gt;
Nachdem nun die Interrupts aktiviert sind, braucht es selbstverständlich noch den auszuführenden Code, der ablaufen soll, wenn ein Interrupt eintrifft.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Zu den aktivierten Interrupts ist eine Funktion zu programmieren, deren Code aufgerufen wird, wenn der betreffende Interrupt auftritt (Interrupt-Handler, Interrupt-Service-Routine). Dazu existiert die Definition (ein Makro) &#039;&#039;&#039;ISR&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== ISR ===&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;ISR()&#039;&#039; ersetzt bei neueren Versionen der avr-libc &#039;&#039;SIGNAL()&#039;&#039;. SIGNAL sollte nicht mehr genutzt werden, zur Portierung von SIGNAL nach ISR siehe den [[AVR-GCC-Tutorial#Anhang|Anhang]].)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
ISR(Vectorname) /* vormals: SIGNAL(siglabel) dabei Vectorname != siglabel ! */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;ISR&#039;&#039; wird eine Funktion für die Bearbeitung eines Interrupts eingeleitet. Als Argument muss dabei die Benennung des entsprechenden Interruptvektors angegeben werden. Diese sind in den jeweiligen Includedateien IOxxxx.h zu finden. Die Bezeichnung entspricht dem Namen aus dem Datenblatt, bei dem die Leerzeichen durch Unterstriche ersetzt sind und ein &#039;&#039;_vect&#039;&#039; angehängt ist.&lt;br /&gt;
&lt;br /&gt;
Als Beispiel ein Ausschnitt aus der Datei für den ATmega8 (bei WinAVR Standardinstallation in C:\WinAVR\avr\include\avr\iom8.h) in der neben den aktuellen Namen für &#039;&#039;ISR&#039;&#039; (*_vect) noch die Bezeichnungen für das inzwischen nicht mehr aktuelle &#039;&#039;SIGNAL&#039;&#039; (SIG_*) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
/* $Id: iom8.h,v 1.13 2005/10/30 22:11:23 joerg_wunsch Exp $ */&lt;br /&gt;
&lt;br /&gt;
/* avr/iom8.h - definitions for ATmega8 */&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
/* Interrupt vectors */&lt;br /&gt;
&lt;br /&gt;
/* External Interrupt Request 0 */&lt;br /&gt;
#define INT0_vect                       _VECTOR(1)&lt;br /&gt;
#define SIG_INTERRUPT0                  _VECTOR(1)&lt;br /&gt;
&lt;br /&gt;
/* External Interrupt Request 1 */&lt;br /&gt;
#define INT1_vect                       _VECTOR(2)&lt;br /&gt;
#define SIG_INTERRUPT1                  _VECTOR(2)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter2 Compare Match */&lt;br /&gt;
#define TIMER2_COMP_vect                _VECTOR(3)&lt;br /&gt;
#define SIG_OUTPUT_COMPARE2             _VECTOR(3)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter2 Overflow */&lt;br /&gt;
#define TIMER2_OVF_vect                 _VECTOR(4)&lt;br /&gt;
#define SIG_OVERFLOW2                   _VECTOR(4)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter1 Capture Event */&lt;br /&gt;
#define TIMER1_CAPT_vect                _VECTOR(5)&lt;br /&gt;
#define SIG_INPUT_CAPTURE1              _VECTOR(5)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter1 Compare Match A */&lt;br /&gt;
#define TIMER1_COMPA_vect               _VECTOR(6)&lt;br /&gt;
#define SIG_OUTPUT_COMPARE1A            _VECTOR(6)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter1 Compare Match B */&lt;br /&gt;
#define TIMER1_COMPB_vect               _VECTOR(7)&lt;br /&gt;
#define SIG_OUTPUT_COMPARE1B            _VECTOR(7)&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--Vor Nutzung von SIGNAL muss ebenfalls die Header-Datei signal.h eingebunden werden.--&amp;gt; &lt;br /&gt;
Mögliche Funktionsrümpfe für Interruptfunktionen sind zum Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
/* veraltet: #include &amp;lt;avr/signal.h&amp;gt; */&lt;br /&gt;
&lt;br /&gt;
ISR(INT0_vect)       /* veraltet: SIGNAL(SIG_INTERRUPT0) */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER0_OVF_vect) /* veraltet: SIGNAL(SIG_OVERFLOW0) */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ISR(USART_RXC_vect) /* veraltet: SIGNAL(SIG_UART_RECV) */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// und so weiter und so fort...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auf die korrekte Schreibweise der Vektorbezeichnung ist zu achten. Der gcc-Compiler prüft erst ab Version 4.x, ob ein Signal/Interrupt der angegebenen Bezeichnung tatsächlich in der Includedatei definiert ist und gibt andernfalls eine Warnung aus. Bei WinAVR (ab 2/2005) wurde die Überprüfung auch in den mitgelieferten Compiler der Version 3.x integriert. Aus dem gcc-Quellcode Version 3.x selbst erstellte Compiler enthalten die Prüfung nicht (vgl. [[AVR-GCC]]). &lt;br /&gt;
&lt;br /&gt;
Während der Ausführung der Funktion sind alle weiteren Interrupts automatisch gesperrt. Beim Verlassen der Funktion werden die Interrupts wieder zugelassen.&lt;br /&gt;
&lt;br /&gt;
Sollte während der Abarbeitung der Interruptroutine ein weiterer Interrupt (gleiche oder andere Interruptquelle) auftreten, so wird das entsprechende Bit im zugeordneten Interrupt Flag Register gesetzt und die entsprechende Interruptroutine automatisch nach dem Beenden der aktuellen Funktion aufgerufen.&lt;br /&gt;
&lt;br /&gt;
Ein Problem ergibt sich eigentlich nur dann, wenn während der Abarbeitung der aktuellen Interruptroutine mehrere gleichartige Interrupts auftreten. Die entsprechende Interruptroutine wird im Nachhinein zwar aufgerufen jedoch wissen wir nicht, ob nun der entsprechende Interrupt einmal, zweimal oder gar noch öfter aufgetreten ist. Deshalb soll hier noch einmal betont werden, dass Interruptroutinen so schnell wie nur irgend möglich wieder verlassen werden sollten.&lt;br /&gt;
&lt;br /&gt;
=== Unterbrechbare Interruptroutinen ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Faustregel&amp;quot;: im Zweifel &#039;&#039;&#039;ISR&#039;&#039;&#039;. Die nachfolgend beschriebene Methode nur dann verwenden, wenn man sich über die unterschiedliche Funktionsweise im Klaren ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ISR(XXX,ISR_NOBLOCK) /* veraltet: INTERRUPT(SIG_OVERFLOW0) */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt-Code */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei steht XXX für den oben beschriebenen Namen des Vektors (also z.&amp;amp;nbsp;B. &#039;&#039;TIMER0_OVF_vect&#039;&#039;). Der Unterschied im Vergleich zu einer herkömmlichen ISR ist, dass hier beim Aufrufen der Funktion das &#039;&#039;&#039;Global Enable Interrupt&#039;&#039;&#039; Bit durch Einfügen einer SEI-Anweisung direkt wieder gesetzt und somit alle Interrupts zugelassen werden &amp;amp;ndash; auch XXX-Interrupts. &lt;br /&gt;
&lt;br /&gt;
Bei unsachgemässer Handhabung kann dies zu erheblichen Problemen wie einem Stack-Overflow oder anderen unerwarteten Effekten führen und sollte wirklich nur dann eingesetzt werden, wenn man sich sicher ist, das Ganze auch im Griff zu haben.&lt;br /&gt;
&lt;br /&gt;
Insbesondere sollte möglichst am ISR-Anfang die auslösende IRQ-Quelle deaktiviert und erst am Ende der ISR wieder aktiviert werden. Robuster als die Verwendung einer NOBLOCK-ISR ist daher folgender ISR-Aufbau:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ISR (XXX) &lt;br /&gt;
{&lt;br /&gt;
    // Implementiere die ISR ohne zunaechst weitere IRQs zuzulassen&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;&amp;lt;Dektiviere die XXX-IRQ&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    // Erlaube alle Interrupts (ausser XXX)&lt;br /&gt;
    sei();&lt;br /&gt;
&lt;br /&gt;
    //... Code ...&lt;br /&gt;
&lt;br /&gt;
    // IRQs global deaktivieren um die XXX-IRQ wieder gefahrlos &lt;br /&gt;
    // aktivieren zu koennen&lt;br /&gt;
    cli();&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;&amp;lt;Aktiviere die XXX-IRQ&amp;gt;&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Auf diese Weise kann sich die XXX-IRQ nicht selbst unterbrechen, was zu einer Art Endlosschleife führen würde.&lt;br /&gt;
&lt;br /&gt;
Siehe auch: Hinweise in [[AVR-GCC]]&lt;br /&gt;
&lt;br /&gt;
siehe dazu: http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html&lt;br /&gt;
&lt;br /&gt;
== Datenaustausch mit Interrupt-Routinen ==&lt;br /&gt;
&lt;br /&gt;
Variablen, die sowohl in Interrupt-Routinen (ISR = Interrupt Service Routine(s)) als auch vom übrigen Programmcode geschrieben oder gelesen werden, müssen mit einem &#039;&#039;&#039;volatile&#039;&#039;&#039; deklariert werden. Damit wird dem Compiler mitgeteilt, dass der Inhalt der Variablen vor jedem Lesezugriff aus dem Speicher gelesen und nach jedem Schreibzugriff in den Speicher geschrieben wird. Ansonsten könnte der Compiler den Code so optimieren, dass der Wert der Variablen nur in Prozessorregistern zwischengespeichert wird, die nichts von der Änderung woanders mitbekommen.&lt;br /&gt;
&lt;br /&gt;
Zur Veranschaulichung ein Codefragment für eine Tastenentprellung mit Erkennung einer &amp;quot;lange gedrückten&amp;quot; Taste.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
// Schwellwerte&lt;br /&gt;
// Entprellung: &lt;br /&gt;
#define CNTDEBOUNCE 10&lt;br /&gt;
// &amp;quot;lange gedrueckt:&amp;quot;&lt;br /&gt;
#define CNTREPEAT 200&lt;br /&gt;
&lt;br /&gt;
// hier z.&amp;amp;nbsp;B. Taste an Pin2 PortA &amp;quot;active low&amp;quot; = 0 wenn gedrueckt&lt;br /&gt;
#define KEY_PIN  PINA&lt;br /&gt;
#define KEY_PINNO PA2&lt;br /&gt;
&lt;br /&gt;
// beachte: volatile! &lt;br /&gt;
volatile uint8_t gKeyCounter;&lt;br /&gt;
&lt;br /&gt;
// Timer-Compare Interrupt ISR, wird z.B. alle 10ms ausgefuehrt&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
   // hier wird gKeyCounter veraendert. Die übrigen&lt;br /&gt;
   // Programmteile müssen diese Aenderung &amp;quot;sehen&amp;quot;:&lt;br /&gt;
   // volatile -&amp;gt; aktuellen Wert immer in den Speicher schreiben&lt;br /&gt;
   if ( !(KEY_PIN &amp;amp; (1&amp;lt;&amp;lt;KEY_PINNO)) ) {&lt;br /&gt;
      if (gKeyCounter &amp;lt; CNTREPEAT) gKeyCounter++;&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
      gKeyCounter = 0;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
//...&lt;br /&gt;
    /* hier: Initialisierung der Ports und des Timer-Interrupts */&lt;br /&gt;
//... &lt;br /&gt;
   // hier wird auf gKeyCounter zugegriffen. Dazu muss der in der&lt;br /&gt;
   // ISR geschriebene Wert bekannt sein:&lt;br /&gt;
   // volatile -&amp;gt; aktuellen Wert immer aus dem Speicher lesen&lt;br /&gt;
   if ( gKeyCounter &amp;gt; CNTDEBOUNCE ) { // Taste mind. 10*10 ms &amp;quot;prellfrei&amp;quot;&lt;br /&gt;
       if (gKeyCounter == CNTREPEAT) {&lt;br /&gt;
          /* hier: Code fuer &amp;quot;Taste lange gedrueckt&amp;quot; */&lt;br /&gt;
       }&lt;br /&gt;
       else {&lt;br /&gt;
          /* hier: Code fuer &amp;quot;Taste kurz gedrueckt&amp;quot; */&lt;br /&gt;
       }&lt;br /&gt;
   }&lt;br /&gt;
//...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wird innerhalb einer ISR mehrfach auf eine mit volatile deklarierte Variable zugegriffen, wirkt sich dies ungünstig auf die Verarbeitungsgeschwindigkeit aus, da bei jedem Zugriff mit dem Speicherinhalt abgeglichen wird. Da bei AVR-Controllern &#039;&#039;innerhalb&#039;&#039; einer ISR keine Unterbrechungen zu erwarten sind, bietet es sich an, einen Zwischenspeicher in Form einer lokalen Variable zu verwenden, deren Inhalt zu Beginn und am Ende mit dem der volatile Variable synchronisiert wird. Lokale Variable werden bei eingeschalteter Optimierung mit hoher Wahrscheinlichkeit in Prozessorregistern verwaltet und der Zugriff darauf ist daher nur mit wenigen internen Operationen verbunden. Die ISR aus dem vorherigen Beispiel lässt sich so optimieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
   uint8_t tmp_kc;&lt;br /&gt;
&lt;br /&gt;
   tmp_kc = gKeyCounter; // Uebernahme in lokale Arbeitsvariable&lt;br /&gt;
&lt;br /&gt;
   if ( !(KEY_PIN &amp;amp; (1&amp;lt;&amp;lt;KEY_PINNO)) ) {&lt;br /&gt;
      if (tmp_kc &amp;lt; CNTREPEAT) {&lt;br /&gt;
         tmp_kc++;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
      tmp_kc = 0;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   gKeyCounter = tmp_kc; // Zurueckschreiben&lt;br /&gt;
}&lt;br /&gt;
//...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zum Vergleich die Disassemblies (Ausschnitte der &amp;quot;lss-Dateien&amp;quot;, compiliert für ATmega162) im Anschluss. Man erkennt den viermaligen Zugriff auf die Speicheraddresse von &#039;&#039;gKeyCounter&#039;&#039; (hier 0x032A) in der ISR ohne &amp;quot;Cache&amp;quot;-Variable und den zweimaligen Zugriff in der Variante mit Zwischenspeicher. Im Beispiel ist der Vorteil gering, bei komplexeren Routinen kann die Zwischenspeicherung in lokalen Variablen jedoch zu deutlicheren Verbesserungen führen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
     86a:	1f 92       	push	r1&lt;br /&gt;
     86c:	0f 92       	push	r0&lt;br /&gt;
     86e:	0f b6       	in	r0, 0x3f	; 63&lt;br /&gt;
     870:	0f 92       	push	r0&lt;br /&gt;
     872:	11 24       	eor	r1, r1&lt;br /&gt;
     874:	8f 93       	push	r24&lt;br /&gt;
    if ( !(KEY_PIN &amp;amp; (1&amp;lt;&amp;lt;KEY_PINNO)) ) {&lt;br /&gt;
     876:	ca 99       	sbic	0x19, 2	; 25&lt;br /&gt;
     878:	0a c0       	rjmp	.+20     	; 0x88e &amp;lt;__vector_13+0x24&amp;gt;&lt;br /&gt;
      if (gKeyCounter &amp;lt; CNTREPEAT) gKeyCounter++;&lt;br /&gt;
     87a:	80 91 2a 03 	lds	r24, 0x032A&lt;br /&gt;
     87e:	88 3c       	cpi	r24, 0xC8	; 200 &lt;br /&gt;
     880:	40 f4       	brcc	.+16     	; 0x892 &amp;lt;__vector_13+0x28&amp;gt;&lt;br /&gt;
     882:	80 91 2a 03 	lds	r24, 0x032A&lt;br /&gt;
     886:	8f 5f       	subi	r24, 0xFF	; 255&lt;br /&gt;
     888:	80 93 2a 03 	sts	0x032A, r24&lt;br /&gt;
     88c:	02 c0       	rjmp	.+4      	; 0x892 &amp;lt;__vector_13+0x28&amp;gt;&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
      gKeyCounter = 0;&lt;br /&gt;
     88e:	10 92 2a 03 	sts	0x032A, r1&lt;br /&gt;
     892:	8f 91       	pop	r24&lt;br /&gt;
     894:	0f 90       	pop	r0&lt;br /&gt;
     896:	0f be       	out	0x3f, r0	; 63&lt;br /&gt;
     898:	0f 90       	pop	r0&lt;br /&gt;
     89a:	1f 90       	pop	r1&lt;br /&gt;
     89c:	18 95       	reti&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
     86a:	1f 92       	push	r1&lt;br /&gt;
     86c:	0f 92       	push	r0&lt;br /&gt;
     86e:	0f b6       	in	r0, 0x3f	; 63&lt;br /&gt;
     870:	0f 92       	push	r0&lt;br /&gt;
     872:	11 24       	eor	r1, r1&lt;br /&gt;
     874:	8f 93       	push	r24&lt;br /&gt;
   uint8_t tmp_kc;&lt;br /&gt;
 &lt;br /&gt;
   tmp_kc = gKeyCounter;&lt;br /&gt;
     876:	80 91 2a 03 	lds	r24, 0x032A&lt;br /&gt;
 &lt;br /&gt;
   if ( !(KEY_PIN &amp;amp; (1&amp;lt;&amp;lt;KEY_PINNO)) ) {&lt;br /&gt;
     87a:	ca 9b       	sbis	0x19, 2	; 25&lt;br /&gt;
     87c:	02 c0       	rjmp	.+4      	; 0x882 &amp;lt;__vector_13+0x18&amp;gt;&lt;br /&gt;
     87e:	80 e0       	ldi	r24, 0x00	; 0&lt;br /&gt;
     880:	03 c0       	rjmp	.+6      	; 0x888 &amp;lt;__vector_13+0x1e&amp;gt;&lt;br /&gt;
      if (tmp_kc &amp;lt; CNTREPEAT) {&lt;br /&gt;
     882:	88 3c       	cpi	r24, 0xC8	; 200&lt;br /&gt;
     884:	08 f4       	brcc	.+2      	; 0x888 &amp;lt;__vector_13+0x1e&amp;gt;&lt;br /&gt;
         tmp_kc++;&lt;br /&gt;
     886:	8f 5f       	subi	r24, 0xFF	; 255&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
      tmp_kc = 0;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   gKeyCounter = tmp_kc;&lt;br /&gt;
     888:	80 93 2a 03 	sts	0x032A, r24&lt;br /&gt;
     88c:	8f 91       	pop	r24&lt;br /&gt;
     88e:	0f 90       	pop	r0&lt;br /&gt;
     890:	0f be       	out	0x3f, r0	; 63&lt;br /&gt;
     892:	0f 90       	pop	r0&lt;br /&gt;
     894:	1f 90       	pop	r1&lt;br /&gt;
     896:	18 95       	reti&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== volatile und Pointer ===&lt;br /&gt;
&lt;br /&gt;
Bei &#039;&#039;&#039;volatile&#039;&#039;&#039; in Verbindung mit Pointern ist zu beachten, ob der Pointer selbst oder die Variable, auf die der Pointer zeigt, &#039;&#039;&#039;volatile&#039;&#039;&#039; ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
volatile uint8_t *a;   // das Ziel von a ist volatile&lt;br /&gt;
&lt;br /&gt;
uint8_t *volatile a;   // a selbst ist volatile&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls der Pointer volatile ist (zweiter Fall im Beispiel), ist zu beachten, dass der Wert des Pointers, also eine Speicheradresse, intern in mehr als einem Byte verwaltet wird. Lese- und Schreibzugriffe im Hauptprogramm (außerhalb von Interrupt-Routinen) sind daher so zu implementieren, dass alle Teilbytes der Adresse konsistent bleiben, vgl. dazu den folgenden Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=== Variablen größer 1 Byte ===&lt;br /&gt;
&lt;br /&gt;
Bei Variablen größer ein Byte, auf die in Interrupt-Routinen und im Hauptprogramm zugegriffen wird, muss darauf geachtet werden, dass die Zugriffe auf die einzelnen Bytes außerhalb der ISR nicht durch einen Interrupt unterbrochen werden. (Allgemeinplatz: AVRs sind 8-bit Controller). Zur Veranschaulichung ein Codefragment:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
volatile uint16_t gMyCounter16bit;&lt;br /&gt;
//...&lt;br /&gt;
ISR(...)&lt;br /&gt;
{&lt;br /&gt;
//...&lt;br /&gt;
   gMyCounter16Bit++;&lt;br /&gt;
//...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
   uint16_t tmpCnt;&lt;br /&gt;
//...&lt;br /&gt;
   // nicht gut: Mglw. hier ein Fehler, wenn ein Byte von MyCounter &lt;br /&gt;
   // schon in tmpCnt kopiert ist aber vor dem Kopieren des zweiten Bytes &lt;br /&gt;
   // ein Interrupt auftritt, der den Inhalt von MyCounter verändert.&lt;br /&gt;
   tmpCnt = gMyCounter16bit; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   // besser: Änderungen &amp;quot;außerhalb&amp;quot; verhindern -&amp;gt; alle &amp;quot;Teilbytes&amp;quot;&lt;br /&gt;
   // bleiben konsistent&lt;br /&gt;
   cli();  // Interrupts deaktivieren&lt;br /&gt;
   tmpCnt = gMyCounter16Bit;&lt;br /&gt;
   sei();  // wieder aktivieren&lt;br /&gt;
&lt;br /&gt;
   // oder: vorheriger Status des globalen Interrupt-Flags bleibt erhalten&lt;br /&gt;
   uint8_t sreg_tmp;&lt;br /&gt;
   sreg_tmp = SREG;    /* Sichern */&lt;br /&gt;
   cli()&lt;br /&gt;
   tmpCnt = gMyCounter16Bit;&lt;br /&gt;
   SREG = sreg_tmp;    /* Wiederherstellen */&lt;br /&gt;
&lt;br /&gt;
   // oder: mehrfach lesen, bis man konsistente Daten hat&lt;br /&gt;
   uint16_t count1 = gMyCounter16Bit;&lt;br /&gt;
   uint16_t count2 = gMyCounter16Bit;&lt;br /&gt;
   while (count1 != count2) {&lt;br /&gt;
       count1 = count2;&lt;br /&gt;
       count2 = gMyCounter16Bit;&lt;br /&gt;
   }&lt;br /&gt;
   tmpCnt = count1;&lt;br /&gt;
//...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die avr-libc bietet ab Version 1.6.0(?) einige Hilfsfunktionen/Makros, mit der im Beispiel oben gezeigten Funktionalität, die zusätzlich auch sogenannte [http://en.wikipedia.org/wiki/Memory_barrier memory barriers] beinhalten. Diese stehen nach #include &amp;lt;util/atomic.h&amp;gt; zur Verfügung.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
#include &amp;lt;util/atomic.h&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
    // analog zu cli, Zugriff, sei:&lt;br /&gt;
    ATOMIC_BLOCK(ATOMIC_FORCEON) {&lt;br /&gt;
        tmpCnt = gMyCounter16Bit;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
// oder:&lt;br /&gt;
&lt;br /&gt;
    // analog zu Sicherung des SREG, cli, Zugriff und Zurückschreiben des SREG:&lt;br /&gt;
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {&lt;br /&gt;
        tmpCnt = gMyCounter16Bit;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* siehe auch [http://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html Dokumentation der avr-libc zu atomic.h]&lt;br /&gt;
&lt;br /&gt;
== Interrupt-Routinen und Registerzugriffe ==&lt;br /&gt;
&lt;br /&gt;
Falls Register sowohl im Hauptprogramm als auch in Interrupt-Routinen verändert werden, ist darauf zu achten, dass diese Zugriffe sich nicht überlappen. Nur wenige Anweisungen lassen sich in sogenannte &amp;quot;atomare&amp;quot; Zugriffe übersetzen, die nicht von Interrupt-Routinen unterbrochen werden können. &lt;br /&gt;
&lt;br /&gt;
Zur Veranschaulichung eine Anweisung, bei der ein Bit und im Anschluss drei Bits in einem Register gesetzt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
//...&lt;br /&gt;
	PORTA |= (1&amp;lt;&amp;lt;PA0);&lt;br /&gt;
	&lt;br /&gt;
	PORTA |= (1&amp;lt;&amp;lt;PA2)|(1&amp;lt;&amp;lt;PA3)|(1&amp;lt;&amp;lt;PA4);&lt;br /&gt;
//...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Compiler übersetzt diese Anweisungen für einen ATmega128 bei Optimierungsstufe &amp;quot;S&amp;quot; nach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
        PORTA |= (1&amp;lt;&amp;lt;PA0);&lt;br /&gt;
  d2:	d8 9a       	sbi	0x1b, 0	; 27 (a)&lt;br /&gt;
	&lt;br /&gt;
        PORTA |= (1&amp;lt;&amp;lt;PA2)|(1&amp;lt;&amp;lt;PA3)|(1&amp;lt;&amp;lt;PA4);&lt;br /&gt;
  d4:	8b b3       	in	r24, 0x1b	; 27 (b)&lt;br /&gt;
  d6:	8c 61       	ori	r24, 0x1C	; 28 (c)&lt;br /&gt;
  d8:	8b bb       	out	0x1b, r24	; 27 (d)&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Setzen des einzelnen Bits wird bei eingeschalteter Optimierung für Register im unteren Speicherbereich in eine einzige Assembler-Anweisung (sbi) übersetzt und ist nicht anfällig für Unterbrechungen durch Interrupts. Die Anweisung zum Setzen von drei Bits wird jedoch in drei abhängige Assembler-Anweisungen übersetzt und bietet damit zwei &amp;quot;Angriffspunkte&amp;quot; für Unterbrechungen. Eine Interrupt-Routine könnte nach dem Laden des Ausgangszustands in den Zwischenspeicher (hier Register 24) den Wert des Registers ändern, z.&amp;amp;nbsp;B. ein Bit löschen. Damit würde der Zwischenspeicher nicht mehr mit dem tatsächlichen Zustand übereinstimmen aber dennoch nach der Bitoperation (hier ori) in das Register zurückgeschrieben. &lt;br /&gt;
&lt;br /&gt;
Beispiel: PORTA sei anfangs 0b00000000. Die erste Anweisung (a) setzt Bit 0, PORTA ist danach 0b00000001. Nun wird im ersten Teil der zweiten Anweisung der Portzustand in ein Register eingelesen (b). Unmittelbar darauf (vor (c)) &amp;quot;feuert&amp;quot; ein Interrupt, in dessen Interrupt-Routine Bit 0 von PORTA gelöscht wird. Nach Verlassen der Interrupt-Routine hat PORTA den Wert 0b00000000. In den beiden noch folgenden Anweisungen des Hauptprogramms wird nun der zwischengespeicherte &amp;quot;alte&amp;quot; Zustand 0b00000001 mit 0b00011100 logisch-oder-verknüft (c) und das Ergebnis 0b00011101 in PortA geschrieben (d). Obwohl zwischenzeitlich Bit 0 gelöscht wurde, ist es nach (d) wieder gesetzt. &lt;br /&gt;
&lt;br /&gt;
Lösungsmöglichkeiten:&lt;br /&gt;
* Register ohne besondere Vorkehrungen nicht in Interruptroutinen &#039;&#039;und&#039;&#039; im Hauptprogramm verändern.&lt;br /&gt;
* Interrupts vor Veränderungen in Registern, die auch in ISRs verändert werden, deaktivieren (&amp;quot;cli&amp;quot;).&lt;br /&gt;
* Bits einzeln löschen oder setzen. sbi und cbi können nicht unterbrochen werden. Vorsicht: nur Register im unteren Speicherbereich sind mittels sbi/cbi ansprechbar. Der Compiler kann nur für diese sbi/cbi-Anweisungen generieren. Für Register außerhalb dieses Adressbereichs (&amp;quot;Memory-Mapped&amp;quot;-Register) werden auch zur Manipulation einzelner Bits abhängige Anweisungen erzeugt (lds,...,sts).&lt;br /&gt;
&lt;br /&gt;
* siehe auch: [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Frequently asked Questions/Fragen Nr. 1 und 8. (Stand: avr-libc Vers. 1.0.4)&lt;br /&gt;
&lt;br /&gt;
== Interruptflags löschen ==&lt;br /&gt;
&lt;br /&gt;
Beim Löschen von Interruptflags haben AVRs eine Besonderheit, die auch im Datenblatt beschrieben ist: Es wird zum Löschen eine 1 in das betreffende Bit geschrieben. &lt;br /&gt;
&lt;br /&gt;
Hinweis: Dazu &#039;&#039;&#039;nicht&#039;&#039;&#039; übliche bitweise VerODERung nehmen, sondern eine direkte Zuweisung machen ([http://www.mikrocontroller.net/topic/171148#1640133 Erklärung]).&lt;br /&gt;
&lt;br /&gt;
== Was macht das Hauptprogramm? ==&lt;br /&gt;
&lt;br /&gt;
Im einfachsten (Ausnahme-)Fall gar nichts mehr. Es ist also durchaus denkbar, ein Programm zu schreiben, welches in der main-Funktion lediglich noch die Interrupts aktiviert und dann in einer Endlosschleife verharrt. Sämtliche Funktionen werden dann in den ISRs abgearbeitet. Diese Vorgehensweise ist jedoch bei den meisten Anwendungen schlecht: man verschenkt eine Verarbeitungsebene und hat außerdem möglicherweise Probleme durch Interruptroutinen, die zu viel Verarbeitungszeit benötigen.&lt;br /&gt;
&lt;br /&gt;
Normalerweise wird man in den Interruptroutinen nur die bei Auftreten des jeweiligen Interruptereignisses unbedingt notwendigen Operationen ausführen lassen. Alle weniger kritischen Aufgaben werden dann im Hauptprogramm abgearbeitet.&lt;br /&gt;
&lt;br /&gt;
* siehe auch: [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/Interrupts and Signals&lt;br /&gt;
&lt;br /&gt;
= Sleep-Modes =&lt;br /&gt;
&lt;br /&gt;
AVR Controller verfügen über eine Reihe von sogenannten [[Sleep Mode |&#039;&#039;Sleep-Modes&#039;&#039;]] (&amp;quot;Schlaf-Modi&amp;quot;). Diese ermöglichen es, Teile des Controllers abzuschalten. Zum Einen kann damit besonders bei Batteriebetrieb Strom gespart werden, zum Anderen können Komponenten des Controllers deaktiviert werden, die die Genauigkeit des Analog-Digital-Wandlers bzw. des Analog-Comparators negativ beeinflussen. Der Controller wird durch Interrupts aus dem Schlaf geweckt. Welche Interrupts den jeweiligen Schlafmodus beenden, ist einer Tabelle im Datenblatt des jeweiligen Controllers zu entnehmen.&lt;br /&gt;
Die Funktionen (eigentlich Makros) der avr-libc stehen nach Einbinden der header-Datei &#039;&#039;sleep.h&#039;&#039; zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
;set_sleep_mode (uint8_t mode): Setzt den Schlafmodus, der bei Aufruf von sleep() aktiviert wird. In sleep.h sind einige Konstanten definiert (z.&amp;amp;nbsp;B. SLEEP_MODE_PWR_DOWN). Die definierten Modi werden jedoch nicht alle von sämtlichten AVR-Controllern unterstützt.&lt;br /&gt;
;sleep_enable(): Aktiviert den gesetzten Schlafmodus, versetzt den Controller aber noch nicht in den Schlafmodus&lt;br /&gt;
;sleep_cpu(): Versetzt den Controller in den Schlafmodus .sleep_cpu wird im Prinzip durch die Assembler-Anweisung &#039;&#039;sleep&#039;&#039; ersetzt.&lt;br /&gt;
;sleep_disable(): Deaktiviert den gesetzten Schlafmodus&lt;br /&gt;
;sleep_mode(): Versetzt den Controller in den mit set_sleep_mode gewählten Schlafmodus. Das Makro entspricht sleep_enable()+sleep_cpu()+sleep_disable(), beinhaltet also nicht die Aktivierung von Interrupts (besser nicht benutzen).&lt;br /&gt;
&lt;br /&gt;
Bei Anwendung von sleep_cpu() müssen Interrupts also bereits freigeben sein (sei()), da der Controller sonst nicht mehr &amp;quot;aufwachen&amp;quot; kann. sleep_mode() ist nicht geeignet für die Verwendung in ISR Interrupt-Service-Routinen, da bei deren Abarbeitung Interrupts global deaktiviert sind und somit auch die möglichen &amp;quot;Aufwachinterrupts&amp;quot;. Abhilfe: stattdessen sleep_enable(), sei(), sleep_cpu(), sleep_disable() und evtl. cli() verwenden (vgl. Dokumentation der avr-libc).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/sleep.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
   while (1) {&lt;br /&gt;
...&lt;br /&gt;
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);&lt;br /&gt;
      sleep_mode();&lt;br /&gt;
   &lt;br /&gt;
      // Code hier wird erst nach Auftreten eines entsprechenden&lt;br /&gt;
      // &amp;quot;Aufwach-Interrupts&amp;quot; verarbeitet&lt;br /&gt;
...&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In älteren Versionenen der avr-libc wurden nicht alle AVR-Controller durch die sleep-Funktionen richtig angesteuert. Mit avr-libc 1.2.0 wurde die Anzahl der unterstützten Typen jedoch deutlich erweitert. Bei nicht-unterstützten Typen erreicht man die gewünschte Funktionalität durch direkte &amp;quot;[[Bitmanipulation]]&amp;quot; der entsprechenden Register (vgl. Datenblatt) und Aufruf des Sleep-Befehls via Inline-Assembler oder sleep_cpu():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
   // Sleep-Mode &amp;quot;Power-Save&amp;quot; beim ATmega169 &amp;quot;manuell&amp;quot; aktivieren&lt;br /&gt;
   SMCR = (3&amp;lt;&amp;lt;SM0) | (1&amp;lt;&amp;lt;SE);&lt;br /&gt;
   asm volatile (&amp;quot;sleep&amp;quot;::); // alternativ sleep_cpu() aus sleep.h&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sleep Modi ==&lt;br /&gt;
Zu beachten ist, dass unterschiedliche Prozessoren aus der AVR Familie unterschiedliche Sleep-Modi unterstützen oder nicht unterstützen. Auskunft über die tatsächlichen Gegebenheiten gibt, wie immer, das zum Prozessor gehörende Datenblatt. Die unterschiedlichen Modi unterscheiden sich dadurch, welche Bereiche des Prozessors abgeschaltet werden. Damit korrespondiert unmittelbar welche Möglichkeiten es gibt, den Prozessor aus den jeweiligen Sleep Modus wieder aufzuwecken.&lt;br /&gt;
&lt;br /&gt;
;Idle Mode (SLEEP_MODE_IDLE): Die CPU kann durch SPI, USART, Analog Comperator, ADC, TWI, Timer, Watchdog und irgendeinen anderen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
;ADC Noise Reduction Mode (SLEEP_MODE_ADC): In diesem Modus liegt das Hauptaugenmerk darauf, die CPU soweit stillzulegen, dass der ADC möglichst keine Störungen aus dem inneren der CPU auffangen kann. Aufwachen aus diesem Modus kann ausgelöst werden durch den ADC, externe Interrupts, TWI, Timer und Watchdog.&lt;br /&gt;
&lt;br /&gt;
;Power-Down Mode (SLEEP_MODE_PWR_DOWN): In diesem Modus wird ein externer Oszillator (Quarz, Quarzoszillator) gestoppt. Geweckt werden kann die CPU durch einen externen Level Interrupt, TWI, Watchdog, Brown-Out-Reset&lt;br /&gt;
&lt;br /&gt;
;Power-Save-Mode (SLEEP_MODE_PWR_SAVE): Power-Save ist identisch zu Power-Down mit einer Ausnahme: Ist der Timer 2 auf die Verwendung eines externen Taktes konfiguriert, so läuft dieser Timer auch im Power-Save weiter und kann die CPU mit einem Interrupt aufwecken.&lt;br /&gt;
&lt;br /&gt;
;Standby-Mode (SLEEP_MODE_STANDBY, SLEEP_MODE_EXT_STANDBY): Voraussetzung für den Standby-Modus ist die Verwendung eines Quarzes oder eines Quarzoszillators (also einer externen Taktquelle). Ansonsten ist dieser Modus identisch zum Power-Down Modus. Vorteil dieses Modus ist eine kürzere Aufwachzeit.&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/Power Management and Sleep-Modes&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/96369#832712 Forenbeitrag] zur &amp;quot;Nichtverwendung&amp;quot; von sleep_mode in ISRs.&lt;br /&gt;
&lt;br /&gt;
= Zeiger =&lt;br /&gt;
Zeiger (engl. &#039;&#039;Pointer&#039;&#039;) sind Variablen, die die Adresse von Daten oder Funktionen enthalten und belegen 16 Bits. Die Größe hängt mit dem adressierbaren Speicherbereich zusammen und der GCC reserviert dann den entsprechenden Platz.&lt;br /&gt;
Ggf. ist es also günstiger, Indizes auf Arrays (Listen) zu verwenden, so dass der GCC für die Zeigerarithmetik den erforderlichen RAM nur temporär benötigt.&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [[Zeiger]]&lt;br /&gt;
&lt;br /&gt;
= Speicherzugriffe =&lt;br /&gt;
&lt;br /&gt;
Atmel AVR-Controller verfügen typisch über drei Speicher:&lt;br /&gt;
&lt;br /&gt;
* [[RAM]]: Im RAM (genauer statisches RAM/SRAM) wird vom gcc-Compiler Platz für Variablen reserviert. Auch der Stack befindet sich im RAM. Dieser Speicher ist &amp;quot;flüchtig&amp;quot;, d.h. der Inhalt der Variablen geht beim Ausschalten oder einem Zusammenbruch der Spannungsversorgung verloren.&lt;br /&gt;
&lt;br /&gt;
* Programmspeicher: Ausgeführt als FLASH-Speicher, seitenweise wiederbeschreibbar. Darin ist das Anwendungsprogramm abgelegt.&lt;br /&gt;
&lt;br /&gt;
* [[EEPROM]]: Nichtflüchtiger Speicher, d.h. der einmal geschriebene Inhalt bleibt auch ohne Stromversorgung erhalten. Byte-weise schreib/lesbar. Im EEPROM werden typischerweise gerätespezifische Werte wie z.&amp;amp;nbsp;B. Kalibrierungswerte von Sensoren abgelegt.&lt;br /&gt;
&lt;br /&gt;
Einige AVRs besitzen keinen RAM-Speicher, lediglich die Register können als &amp;quot;Arbeitsvariablen&amp;quot;&lt;br /&gt;
genutzt werden. Da die Anwendung des avr-gcc auf solch &amp;quot;kleinen&amp;quot; Controllern ohnehin selten sinnvoll ist und auch nur bei einigen RAM-losen Typen nach [http://lightner.net/avr/ATtinyAvrGcc.html &amp;quot;Bastelarbeiten&amp;quot;] möglich ist, werden diese Controller hier nicht weiter berücksichtigt. Auch EEPROM-Speicher ist nicht auf allen Typen verfügbar. Generell sollten die nachfolgenden Erläuterungen auf alle ATmega-Controller und die größeren AT90-Typen übertragbar sein. Für die Typen ATtiny2313, ATtiny26 und viele weitere der &amp;quot;ATtiny-Reihe&amp;quot; gelten die Ausführungen ebenfalls.&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* [[Binäre Daten zum Programm hinzufügen]]&lt;br /&gt;
== RAM ==&lt;br /&gt;
&lt;br /&gt;
Die Verwaltung des RAM-Speichers erfolgt durch den Compiler, im Regelfall ist beim Zugriff auf Variablen im RAM nichts Besonderes zu beachten. Die Erläuterungen in jedem brauchbaren C-Buch gelten auch für den vom avr-gcc-Compiler erzeugten Code.&lt;br /&gt;
&lt;br /&gt;
Um Speicher dynamisch (während der Laufzeit) zu reservieren, kann &#039;&#039;&#039;malloc()&#039;&#039;&#039; verwendet werden. malloc(size) &amp;quot;alloziert&amp;quot; (~reserviert) einen gewissen Speicherblock mit &#039;&#039;&#039;size&#039;&#039;&#039; Bytes. Ist kein Platz für den neuen Block, wird NULL (0) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Wird der angelegte Block zu klein (groß), kann die Größe mit realloc() verändert werden. Den allozierten Speicherbereich kann man mit free() wieder freigeben. Wenn das Freigeben eines Blocks vergessen wird spricht man von einem &amp;quot;Speicherleck&amp;quot; (memory leak).&lt;br /&gt;
&lt;br /&gt;
malloc() legt Speicherblöcke im &#039;&#039;&#039;Heap&#039;&#039;&#039; an, belegt man zuviel Platz, dann wächst der Heap zu weit nach oben und überschreibt den Stack, und der Controller kommt in Teufels Küche. Das kann leider nicht nur passieren wenn man insgesamt zu viel Speicher anfordert, sondern auch wenn man Blöcke unterschiedlicher Größe in ungünstiger Reihenfolge alloziert/freigibt (siehe Artikel [[Heap-Fragmentierung]]). Aus diesem Grund sollte man malloc() auf Mikrocontrollern sehr sparsam (am besten gar nicht) verwenden.&lt;br /&gt;
&lt;br /&gt;
Beispiel zur Verwendung von malloc():&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void foo(void) {&lt;br /&gt;
  // neuen speicherbereich anlegen,&lt;br /&gt;
  // platz für 10 uint16&lt;br /&gt;
  uint16_t* pBuffer = malloc(10 * sizeof(uint16_t));&lt;br /&gt;
&lt;br /&gt;
  // darauf zugreifen, als wärs ein gewohnter Buffer&lt;br /&gt;
  pBuffer[2] = 5;&lt;br /&gt;
&lt;br /&gt;
  // Speicher (unbedingt!) wieder freigeben&lt;br /&gt;
  free(pBuffer);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn (wie in obigem Beispiel) dynamischer Speicher nur für die Dauer einer Funktion benötigt und am Ende wieder freigegeben wird, bietet es sich an, statt malloc() &#039;&#039;&#039;alloca()&#039;&#039;&#039; zu verwenden. Der Unterschied zu malloc() ist, dass der Speicher auf dem Stack reserviert wird, und beim Verlassen der Funktion automatisch wieder freigegeben wird. Es kann somit kein Speicherleck und keine Fragmentierung entstehen.&lt;br /&gt;
&lt;br /&gt;
siehe auch:&lt;br /&gt;
* http://www.nongnu.org/avr-libc/user-manual/malloc.html&lt;br /&gt;
&lt;br /&gt;
== Programmspeicher (Flash) ==&lt;br /&gt;
&lt;br /&gt;
Ein Zugriff auf Konstanten im Programmspeicher ist mittels avr-gcc nicht &amp;quot;transparent&amp;quot; möglich. D.h. es sind besondere Zugriffsfunktionen erforderlich, um Daten aus diesem Speicher zu lesen. Grundsätzlich basieren alle Zugriffsfunktionen auf der Assembler-Anweisung lpm (load program memory, bei AVR Controllern mit mehr als 64kB Flash auch elpm). Die Standard-Laufzeitbibliothek des avr-gcc (die avr-libc) stellt diese Funktionen nach Einbinden der Header-Datei pgmspace.h zur Verfügung. Mit diesen Funktionen können einzelne Bytes, Datenworte (16bit) und Datenblöcke gelesen werden. &lt;br /&gt;
&lt;br /&gt;
Deklarationen von Variablen im Flash-Speicher werden durch das &amp;quot;Attribut&amp;quot; PROGMEM ergänzt. Lokale Variablen (eigentlich Konstanten) innerhalb von Funktionen können ebenfalls im Programmspeicher abgelegt werden. Dazu ist bei der Definition jedoch ein &#039;&#039;static&#039;&#039; voranzustellen, da solche &amp;quot;Variablen&amp;quot; nicht auf dem Stack bzw. (bei Optimierung) in Registern verwaltet werden können. Der Compiler &amp;quot;wirft&amp;quot; eine Warnung falls static fehlt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Byte */&lt;br /&gt;
const uint8_t pgmFooByte PROGMEM = 123;&lt;br /&gt;
&lt;br /&gt;
/* Wort */&lt;br /&gt;
const uint16_t pgmFooWort PROGMEM = 12345;&lt;br /&gt;
&lt;br /&gt;
/* Byte-Array */&lt;br /&gt;
const uint8_t pgmFooByteArray1[] PROGMEM = { 18, 3 ,70 };&lt;br /&gt;
const uint8_t pgmFooByteArray2[] PROGMEM = { 30, 7 ,79 };&lt;br /&gt;
&lt;br /&gt;
/* Zeiger */&lt;br /&gt;
const uint8_t * const pgmPointerToArray1 PROGMEM = pgmFooByteArray1;&lt;br /&gt;
const uint8_t * const pgmPointerArray[] PROGMEM = { pgmFooByteArray1, pgmFooByteArray2 };&lt;br /&gt;
&lt;br /&gt;
void foo(void)&lt;br /&gt;
{&lt;br /&gt;
  static const uint8_t pgmTestByteLocal PROGMEM = 0x55;&lt;br /&gt;
  static const char pgmTestStringLocal[] PROGMEM = &amp;quot;im Flash&amp;quot;;&lt;br /&gt;
  // so nicht (static fehlt) &lt;br /&gt;
  // char pgmTestStringLocalFalsch [] PROGMEM = &amp;quot;so nicht&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Byte lesen ===&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion pgm_read_byte aus pgmspace.h erfolgt der Zugriff auf die Daten. Parameter der Funktion ist die Adresse des Bytes im Flash-Speicher.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
const uint8_t pgmFooByte PROGMEM = 123;&lt;br /&gt;
const uint8_t pgmFooByteArray1[] PROGMEM = { 18, 3, 70 };&lt;br /&gt;
&lt;br /&gt;
void foo (void)&lt;br /&gt;
    // Wert der Ram-Variablen myByte auf den Wert von pgmFooByte setzen:&lt;br /&gt;
    uint8_t myByte;&lt;br /&gt;
&lt;br /&gt;
    myByte = pgm_read_byte (&amp;amp;pgmFooByte);&lt;br /&gt;
    // myByte hat nun den Wert 123&lt;br /&gt;
&lt;br /&gt;
    // Schleife ueber ein Array aus Byte-Werten im Flash&lt;br /&gt;
    uint8_t i;&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; 3; i++)&lt;br /&gt;
    {&lt;br /&gt;
        myByte = pgm_read_byte (&amp;amp;pgmFooByteArray1[i]);&lt;br /&gt;
        // mach was mit myByte&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Wort lesen ===&lt;br /&gt;
&lt;br /&gt;
Für &amp;quot;einfache&amp;quot; 16-Bit breite Variablen erfolgt der Zugriff analog zum Byte-Beispiel, jedoch mit der Funktion &amp;lt;code&amp;gt;pgm_read_word&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
const uint16_t pgmFooWort PROGMEM = 12345;&lt;br /&gt;
&lt;br /&gt;
    uint16_t myWord = pgm_read_word (&amp;amp;pgmFooWort);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zeiger auf Werte im Flash sind ebenfalls 16 Bits &amp;quot;groß&amp;quot;.&lt;br /&gt;
Damit ist der mögliche Speicherbereich für &amp;quot;Flash-Konstanten&amp;quot; auf 64kB begrenzt.&amp;lt;ref&amp;gt;Einige avr-libc/pgmspace-Funktionen ermöglichen den Lesezugriff auf den gesamten Flash-Speicher, intern via Assembler Anweisung ELPM. Die Initialisierungswerte des Speicherinhalts jenseits der 64kB-Marke müssen dann jedoch auf anderem Weg angelegt werden, d.h. nicht per PROGMEM; evtl. eigene Section und Linker-Optionen. Alt und nicht ganz korrekt: Die avr-libc pgmspace-Funktionen unterstützen nur die unteren 64kB Flash bei Controllern mit mehr als 64kB.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    const uint8_t *ptrToArray;&lt;br /&gt;
&lt;br /&gt;
    ptrToArray = (const uint8_t*) pgm_read_word (&amp;amp;pgmPointerToArray1);&lt;br /&gt;
    // ptrToArray enthält nun die Startadresse des Byte-Arrays pgmFooByteArray1&lt;br /&gt;
    // Allerdings würde ein direkter Zugriff mit diesem Pointer (z.&amp;amp;nbsp;B. temp=*ptrToArray)&lt;br /&gt;
    // nicht den Inhalt von pgmFooByteArray1[0] liefern, sondern von einer Speicherstelle&lt;br /&gt;
    // im RAM, die die gleiche Adresse hat wie pgmFooByteArray1[0]&lt;br /&gt;
    // Daher muss nun die Funktion pgm_read_byte() benutzt werden, die die in ptrToArray&lt;br /&gt;
    // enthaltene Adresse benutzt und auf das Flash zugreift.&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; 3; i++)&lt;br /&gt;
    {&lt;br /&gt;
        myByte = pgm_read_byte (ptrToArray+i);&lt;br /&gt;
        // mach was mit myByte... (18, 3, 70)&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ptrToArray = (const uint8_t*) pgm_read_word (&amp;amp;pgmPointerArray[1]);&lt;br /&gt;
    &lt;br /&gt;
    // ptrToArray enthält nun die Adresse des ersten Elements des Byte-Arrays pgmFooByteArray2&lt;br /&gt;
    // da im zweiten Element des Pointer-Arrays pgmPointerArray die Adresse&lt;br /&gt;
    // von pgmFooByteArray2 abgelegt ist&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; 3; i++)&lt;br /&gt;
    {&lt;br /&gt;
        myByte = pgm_read_byte (ptrToArray+i);&lt;br /&gt;
        // mach was mit myByte... (30, 7, 79)&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Block lesen ===&lt;br /&gt;
In den Standard-Flash Funktionen ist keine der pgm_read_xxxx Nomenklatur folgenden Funktion enthalten, die einen kompletten Block ausliest. Die enstprechende Funktion ist eine Variante von memcpy und heißt memcpy_P().&lt;br /&gt;
&lt;br /&gt;
Was diese Funktion im Prinzip macht, ist einfach in einer Schleife pgm_read_byte zu benutzen, um einen Speicherblock von der Quelladresse im Flash an eine Zieladresse im SRAM zu kopieren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void pgm_read_block( uint8_t* pTarget, const uint8_t* pSource, size_t len )&lt;br /&gt;
{&lt;br /&gt;
  size_t i;&lt;br /&gt;
&lt;br /&gt;
  for( i = 0; i &amp;lt; len; ++i )&lt;br /&gt;
    *pTarget++ = pgm_read_byte( pSource++ );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit ist es dann natürlich kein Problem mehr ganze Arrays oder Strukturen aus dem Flash in das SRAM zu übertragen.&lt;br /&gt;
&lt;br /&gt;
=== Strings lesen ===&lt;br /&gt;
Strings sind in C nichts anderes als eine Abfolge von Zeichen. Der prinzipielle Weg ist daher identisch zu &amp;quot;Bytes lesen&amp;quot;, wobei allerdings auf die [http://www.mikrocontroller.net/articles/FAQ#Wie_funktioniert_String-Verarbeitung_in_C.3F Besonderheiten von Strings] wie 0-Terminierung geachtet werden muss, bzw. diese zur Steuerung einer Schleife über die Zeichen im String ausgenutzt werden kann&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
const char pgmString[] PROGMEM = &amp;quot;Hello world&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  char c;&lt;br /&gt;
  const char* addr;&lt;br /&gt;
&lt;br /&gt;
  addr = pgmString;&lt;br /&gt;
  while (c = pgm_read_byte (addr++), c != &#039;\0&#039;)&lt;br /&gt;
  {&lt;br /&gt;
    // mach was mit c&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung des Programmierers steht das Repertoir der str-Funktionen auch in jeweils eine Variante zur Verfügung, die mit dem Flash-Speicher arbeiten kann. Die Funktionsnamen tragen den Suffix &amp;lt;tt&amp;gt;_P&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
const char pgmString[] PROGMEM = &amp;quot;Hallo world&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
void foo (void)&lt;br /&gt;
{&lt;br /&gt;
  char string[40];&lt;br /&gt;
&lt;br /&gt;
  strcpy_P (string, pgmString);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Float lesen ===&lt;br /&gt;
&lt;br /&gt;
Auch um floats zu lesen gibt es ein Makro:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
float pgmFloatArray[3] PROGMEM = {1.1, 2.2, 3.3};&lt;br /&gt;
&lt;br /&gt;
void read_float (void)&lt;br /&gt;
{&lt;br /&gt;
   int i;&lt;br /&gt;
   float f;&lt;br /&gt;
&lt;br /&gt;
   for (i=0; i&amp;lt;3; i++) &lt;br /&gt;
   {&lt;br /&gt;
      // entspricht  f = pgmFloatArray[i];&lt;br /&gt;
      f = pgm_read_float (&amp;amp;pgmFloatArray[i]);&lt;br /&gt;
      // mach was mit f &lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TODO: Beispiele für structs und pointer aus Flash auf struct im Flash (menues, state-machines etc.). Eine kleine Einleitung insbesondere auch in Bezug auf die auftretenden Schwierigkeiten liefert [http://www.mail-archive.com/avr-gcc-list@nongnu.org/msg05652.html].&lt;br /&gt;
&lt;br /&gt;
=== Array aus Strings im Flash-Speicher ===&lt;br /&gt;
&lt;br /&gt;
Arrays aus Strings im Flash-Speicher werden in zwei Schritten angelegt: Zuerst die einzelnen Elemente des Arrays und im Anschluss ein Array, in dem die Startaddressen der Strings abgelegt werden. Zum Auslesen wird zuerst die Adresse des i-ten Elements aus dem Array im Flash-Speicher gelesen, die im Anschluss dazu genutzt wird, auf das Element (den String) selbst zuzugreifen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
const char str1[] PROGMEM = &amp;quot;first_A&amp;quot;;&lt;br /&gt;
const char str2[] PROGMEM = &amp;quot;second_A&amp;quot;;&lt;br /&gt;
const char str3[] PROGMEM = &amp;quot;third_A&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const char * const strarray1[] PROGMEM = &lt;br /&gt;
{&lt;br /&gt;
   str1,&lt;br /&gt;
   str2,&lt;br /&gt;
   str3&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
static char work[20];&lt;br /&gt;
&lt;br /&gt;
void read_strings (void)&lt;br /&gt;
{&lt;br /&gt;
    size_t i;&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; sizeof (strarray1) / sizeof (strarray1[0]); i++)&lt;br /&gt;
    {&lt;br /&gt;
        size_t j, len;&lt;br /&gt;
&lt;br /&gt;
        // setze Pointer auf die Addresse des i-ten Elements des&lt;br /&gt;
        // Flash-Arrays (str1, str2, ...)&lt;br /&gt;
        const char *pstrflash = (const char*) pgm_read_word (&amp;amp;strarray1[i]);&lt;br /&gt;
&lt;br /&gt;
        // kopiere den Inhalt der Zeichenkette von der&lt;br /&gt;
        // in pstrflash abgelegten Adresse in das work-Array&lt;br /&gt;
        // analog zu strcpy( work, strarray1[i]) wenn alles im RAM&lt;br /&gt;
        strcpy_P (work, pstrflash);&lt;br /&gt;
&lt;br /&gt;
        // Gleichbedeutend damit:&lt;br /&gt;
        strcpy_P (work, (const char*) pgm_read_word (&amp;amp;strarray1[i]));&lt;br /&gt;
    &lt;br /&gt;
        // Zeichen-fuer-Zeichen&lt;br /&gt;
        len = strlen_P (&amp;amp;strarray1[i]);&lt;br /&gt;
&lt;br /&gt;
        // &amp;lt;= da auch das Stringende-Zeichen kopiert werden soll&lt;br /&gt;
        for (j = 0; j &amp;lt;= len; j++)&lt;br /&gt;
        {&lt;br /&gt;
            // analog zu work[j] = strarray[i][j] wenn alles im RAM&lt;br /&gt;
            work[i] = (char) pgm_read_byte (pstrflash++);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Siehe dazu auch die avr-libc FAQ: [http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_rom_array How do I put an array of strings completely in ROM?]&lt;br /&gt;
&lt;br /&gt;
=== Vereinfachung für Zeichenketten (Strings) im Flash ===&lt;br /&gt;
&lt;br /&gt;
Zeichenketten können innerhalb des Quellcodes als &amp;quot;Flash-Konstanten&amp;quot; ausgewiesen werden. Dazu dient das Makro PSTR aus pgmspace.h. Dies erspart die getrennte Deklaration mit PROGMEM-Attribut.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define MAXLEN 30&lt;br /&gt;
&lt;br /&gt;
char StringImFlash[] PROGMEM = &amp;quot;Erwin Lindemann&amp;quot;;&lt;br /&gt;
char StringImRam[MAXLEN];&lt;br /&gt;
&lt;br /&gt;
void read_string (void)&lt;br /&gt;
{&lt;br /&gt;
    strcpy (StringImRam, &amp;quot;Mueller-Luedenscheidt&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    if (!strncmp_P (StringImRam, StringImFlash, 5))&lt;br /&gt;
    {&lt;br /&gt;
        // mach was, wenn die ersten 5 Zeichen identisch - hier nicht&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        // der Code hier wuerde ausgefuehrt &lt;br /&gt;
    } &lt;br /&gt;
&lt;br /&gt;
    if (!strncmp_P (StringImRam, PSTR(&amp;quot;Mueller-Schmitt&amp;quot;), 5))&lt;br /&gt;
    {&lt;br /&gt;
        // der Code hier wird ausgefuehrt, wenn die ersten &lt;br /&gt;
        // 5 Zeichen uebereinstimmen&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        // wird bei Nicht-Uebereinstimmung ausgefuehrt&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aber Vorsicht: Ersetzt man zum Beispiel&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// Daten im &amp;quot;Flash&amp;quot;&lt;br /&gt;
const char flashText[] PROGMEM = &amp;quot;mit[]&amp;quot;; &lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
durch&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// Hier wird &amp;quot;mit*&amp;quot; im RAM angelegt und flashPointer&lt;br /&gt;
// enthaelt die Adresse&lt;br /&gt;
const char* const flashPointer PROGMEM = &amp;quot;mit*&amp;quot;;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
dann kann es zu Problemen kommen.&lt;br /&gt;
&lt;br /&gt;
Übergibt man Zeichenketten, die im Flash abglegt sind an eine Funktion – also die Adresse des ersten Zeichens – so muss die Funktion entsprechend programmiert sein. Die Funktion selbst hat keine Möglichkeit zu unterscheiden, ob es sich um eine Flash-Adresse oder ein RAM-Adresse handelt. Die avr-libc und viele andere avr-gcc-Bibliotheken halten sich an die Konvention, dass Namen von Funktionen, die Flash-Adressen erwarten, mit dem Suffix &amp;lt;code&amp;gt;_P&amp;lt;/code&amp;gt; versehen sind.&lt;br /&gt;
&lt;br /&gt;
Eine Funktion, die einen im Flash abgelegten String z.&amp;amp;nbsp;B. an eine UART ausgibt, würde dann so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void uart_puts_p (const char *text)&lt;br /&gt;
{&lt;br /&gt;
    char zeichen;&lt;br /&gt;
&lt;br /&gt;
    while ((zeichen = pgm_read_byte (text)))&lt;br /&gt;
    {&lt;br /&gt;
        // so lange, wie mittels pgm_read_byte nicht das Stringende&lt;br /&gt;
        // gelesen wurde: gib dieses Zeichen aus&lt;br /&gt;
&lt;br /&gt;
        uart_putc (zeichen);&lt;br /&gt;
        text++;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Von einigen Bibliotheken werden Makros definiert, die &amp;quot;automatisch&amp;quot; ein PSTR bei Verwendung einer Funktion einfügen. Ein Blick in den Header-File der Bibliothek zeigt, ob dies der Fall ist. Ein Beispiel aus P. Fleurys lcd-Library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// Ausschnitt aus dem Header-File lcd.h der &amp;quot;Fleury-LCD-Lib.&amp;quot;&lt;br /&gt;
extern void lcd_puts_p (const char *progmem_s);&lt;br /&gt;
#define lcd_puts_P(__s) lcd_puts_p(PSTR(__s))&lt;br /&gt;
&lt;br /&gt;
// in einer Anwendung&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;quot;lcd.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
const char StringImFlash[] PROGMEM = &amp;quot;Erwin Lindemann&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
void my_write (coid)&lt;br /&gt;
{&lt;br /&gt;
    lcd_puts_p (StringImFlash); &lt;br /&gt;
    lcd_puts_P (&amp;quot;Dr. Kloebner&amp;quot;); &lt;br /&gt;
}&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Flash in der Anwendung schreiben ===&lt;br /&gt;
&lt;br /&gt;
Bei AVRs mit &amp;quot;self-programming&amp;quot;-Option – auch bekannt als [[Bootloader]]-Support – können Teile des Flash-Speichers vom Anwendungsprogramm beschrieben werden. Dies ist nur möglich, wenn die Schreibfunktion in einem besonderen Speicherbereich, der boot-section des Programmspeichers/Flash, abgelegt ist.&lt;br /&gt;
&lt;br /&gt;
Bei einigen kleinen AVRs gibt es keine gesonderte Boot-Section, bei diesen kann der Flashspeicher von jeder Stelle des Programms geschrieben werden. Für Details sei hier auf das jeweilige Controller-Datenblatt und die Erläuterungen zum Modul boot.h der avr-libc verwiesen. Es existieren auch Application-Notes dazu bei atmel.com, die auf avr-gcc-Code übertragbar sind.&lt;br /&gt;
&lt;br /&gt;
Siehe auch: &lt;br /&gt;
* Forumsbeitrag [http://www.mikrocontroller.net/topic/163632#1561622 Daten in Programmspeicher speichern]&lt;br /&gt;
&lt;br /&gt;
=== Warum so kompliziert? ===&lt;br /&gt;
&lt;br /&gt;
Zu dem Thema, warum die Verabeitung von Werten aus dem Flash-Speicher so kompliziert ist, sei hier nur kurz erläutert: Die Harvard-Architektur des AVR weist getrennte Adressräume für Programm(Flash)- und Datenspeicher(RAM) auf. Der C-Standard und der gcc-Compiler sehen keine unterschiedlichen Adressräume vor.&lt;br /&gt;
&lt;br /&gt;
Hat man zum Beispiel eine Funktion string_an_uart(const char* s) und übergibt an diese Funktion die Adresse einer Zeichenkette, z.&amp;amp;nbsp;B. 0x01fe, weiß die Funktion nicht, ob die Adresse auf den Flash-Speicher oder den/das RAM zeigt. Allein aus dem Pointer-Wert, also dem Zahlenwert, kann nicht auf den Ort der Ablage geschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Einige AVR-Compiler bilden die Harvard-Architektur ab, indem sie in einen Pointer nicht nur die Adresse speichern, sondern auch den Ablageort wie &#039;&#039;Flash&#039;&#039; oder &#039;&#039;RAM&#039;&#039;. In einem Aufruf einer Funktion wird dann bei Pointer-Parametern neben der Adresse auch der Speicherbereich, auf den der Pointer zeigt, übergeben. Dies hat jedoch auch Nachteile, denn bei jedem Zugriff über einen Zeiger muss zur &#039;&#039;Laufzeit&#039;&#039; entschieden werden, wie der Zugriff auszuführen ist und entsprechend länglicher und langsamer kann Code ausgeführt werden.&lt;br /&gt;
&lt;br /&gt;
* siehe auch: [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitte Modules/Program Space String Utilities und Abschnitt Modules/Bootloader Support Utilities&lt;br /&gt;
&lt;br /&gt;
== EEPROM ==&lt;br /&gt;
&lt;br /&gt;
Man beachte, dass der EEPROM-Speicher nur eine begrenzte Anzahl von Schreibzugriffen zulässt. Beschreibt man eine EEPROM-Zelle öfter als die im Datenblatt zugesicherte Anzahl (typisch 100.000), wird die Funktion der Zelle nicht mehr garantiert. &lt;br /&gt;
Dies gilt für jede einzelne Zelle. Bei geschickter Programmierung (z.&amp;amp;nbsp;B. Ring-Puffer), bei der die zu beschreibenden Zellen regelmäßig gewechselt werden, kann man eine deutlich höhere Anzahl an Schreibzugriffen, bezogen auf den Gesamtspeicher, erreichen.&lt;br /&gt;
&lt;br /&gt;
Schreib- und Lesezugriffe auf den EEPROM-Speicher erfolgen über die im Modul eeprom.h definierten Funktionen. Mit diesen Funktionen können einzelne Bytes, Datenworte (16bit) und Datenblöcke geschrieben und gelesen werden. &lt;br /&gt;
&lt;br /&gt;
Bei Nutzung des EEPROMs ist zu beachten, dass vor dem Zugriff auf diesen Speicher abgefragt wird, ob der Controller die vorherige EEPROM-Operation abgeschlossen hat. Die avr-libc-Funktionen beinhalten diese Prüfung, man muss sie nicht selbst implementieren. Man sollte auch verhindern, dass der Zugriff durch die Abarbeitung einer Interrupt-Routine unterbrochen wird, da bestimme Befehlsabfolgen vorgegeben sind, die innerhalb weniger Taktzyklen aufeinanderfolgen müssen (&amp;quot;timed sequence&amp;quot;). Auch dies muss bei Nutzung der Funktionen aus der avr-libc/eeprom.h-Datei nicht selbst implementiert werden. Innerhalb der Funktionen werden Interrupts vor der &amp;quot;EEPROM-Sequenz&amp;quot; global deaktiviert und im Anschluss, falls vorher auch schon eingeschaltet, wieder aktiviert.&lt;br /&gt;
&lt;br /&gt;
Um eine Variable im EEPROM anzulegen, stellt die avr-libc das Makro EEMEM zur Verfügung&amp;lt;ref&amp;gt;In älteren Versionen der avr-libc ist EEMEM noch nicht vorhanden, und man kann sich folgendermassen behelfen:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef EEMEM&lt;br /&gt;
#define EEMEM __attribute__((section (&amp;quot;.eeprom&amp;quot;)))&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/c&amp;gt;&amp;lt;/ref&amp;gt;, das analog zu PROGMEM verwendet wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Byte */&lt;br /&gt;
uint8_t eeFooByte EEMEM = 123;&lt;br /&gt;
&lt;br /&gt;
/* Wort */&lt;br /&gt;
uint16_t eeFooWord EEMEM = 12345;&lt;br /&gt;
&lt;br /&gt;
/* float */&lt;br /&gt;
float eeFooFloat EEMEM;&lt;br /&gt;
&lt;br /&gt;
/* Byte-Array */&lt;br /&gt;
uint8_t eeFooByteArray1[] EEMEM = { 18, 3, 70 };&lt;br /&gt;
uint8_t eeFooByteArray2[] EEMEM = { 30, 7, 79 };&lt;br /&gt;
&lt;br /&gt;
/* 16-bit unsigned short feld */&lt;br /&gt;
uint16_t eeFooWordArray1[4] EEMEM;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bytes lesen/schreiben ===&lt;br /&gt;
&lt;br /&gt;
Die avr-libc Funktion zum Lesen eines Bytes heißt eeprom_read_byte. Parameter ist die Adresse des Bytes im EEPROM. Geschrieben wird über die Funktion eeprom_write_byte mit den Parametern Adresse und Inhalt. Anwendungsbeispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#define EEPROM_DEF 0xFF&lt;br /&gt;
&lt;br /&gt;
void eeprom_example (void)&lt;br /&gt;
{&lt;br /&gt;
    uint8_t myByte;&lt;br /&gt;
&lt;br /&gt;
    // myByte lesen (Wert = 123)&lt;br /&gt;
    myByte = eeprom_read_byte (&amp;amp;eeFooByte);&lt;br /&gt;
&lt;br /&gt;
    // der Wert 99 wird im EEPROM an die Adresse der&lt;br /&gt;
    // Variablen eeFooByte geschrieben&lt;br /&gt;
    myByte = 99;&lt;br /&gt;
    eeprom_write_byte(&amp;amp;eeFooByte, myByte); // schreiben&lt;br /&gt;
&lt;br /&gt;
    myByte = eeprom_read_byte (&amp;amp;eeFooByteArray1[1]); &lt;br /&gt;
    // myByte hat nun den Wert 3&lt;br /&gt;
&lt;br /&gt;
    // Beispiel zur &amp;quot;Sicherung&amp;quot; gegen leeres EEPROM nach &amp;quot;Chip Erase&amp;quot;&lt;br /&gt;
    // (z. B. wenn die .eep-Datei nach Programmierung einer neuen Version&lt;br /&gt;
    // des Programms nicht in den EEPROM uebertragen wurde und EESAVE&lt;br /&gt;
    // deaktiviert ist (unprogrammed/1)&lt;br /&gt;
    // &lt;br /&gt;
    // Vorsicht: wenn EESAVE &amp;quot;programmed&amp;quot; ist, hilft diese Sicherung nicht&lt;br /&gt;
    // weiter, da die Speicheraddressen in einem neuen/erweiterten Programm&lt;br /&gt;
    // moeglicherweise verschoben wurden. An der Stelle &amp;amp;eeFooByte steht&lt;br /&gt;
    // dann u.U. der Wert einer anderen Variable aus einer &amp;quot;alten&amp;quot; Version.&lt;br /&gt;
&lt;br /&gt;
    uint8_t fooByteDefault = 222;&lt;br /&gt;
    if ((myByte = eeprom_read_byte (&amp;amp;eeFooByte)) == EEPROM_DEF)&lt;br /&gt;
    {&lt;br /&gt;
        myByte = fooByteDefault;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Wort lesen/schreiben ===&lt;br /&gt;
&lt;br /&gt;
Schreiben und Lesen von Datenworten erfolgt analog zur Vorgehensweise bei Bytes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    // lesen&lt;br /&gt;
    uint16_t myWord = eeprom_read_word (&amp;amp;eeFooWord);&lt;br /&gt;
&lt;br /&gt;
    // schreiben&lt;br /&gt;
    eeprom_write_word (&amp;amp;eeFooWord, 2222);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Block lesen/schreiben ===&lt;br /&gt;
&lt;br /&gt;
Lesen und Schreiben von Datenblöcken erfolgt über die Funktionen &amp;lt;code&amp;gt;eeprom_read_block()&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;eeprom_write_block()&amp;lt;/code&amp;gt;. Die Funktionen erwarten drei Parameter: die Adresse der Quell- bzw. Zieldaten im RAM, die EEPROM-Addresse und die Länge des Datenblocks in Bytes als &amp;lt;code&amp;gt;size_t&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint8_t  myByteBuffer[3];&lt;br /&gt;
uint16_t myWordBuffer[4];&lt;br /&gt;
&lt;br /&gt;
void eeprom_block_example (void)&lt;br /&gt;
{&lt;br /&gt;
    /* Datenblock aus EEPROM lesen  */&lt;br /&gt;
&lt;br /&gt;
    /* liest 3 Bytes ab der von eeFooByteArray1 definierten EEPROM-Adresse&lt;br /&gt;
       in das RAM-Array myByteBuffer */&lt;br /&gt;
    eeprom_read_block (myByteBuffer, eeFooByteArray1, 3);&lt;br /&gt;
&lt;br /&gt;
    /* dito mit etwas Absicherung betr. der Länge */&lt;br /&gt;
    eeprom_read_block (myByteBuffer, eeFooByteArray1, sizeof(myByteBuffer));&lt;br /&gt;
&lt;br /&gt;
    /* und nun mit 16-Bit Array */&lt;br /&gt;
    eeprom_read_block (myWordBuffer, eeFooWordArray1, sizeof(myWordBuffer));&lt;br /&gt;
&lt;br /&gt;
    /* Datenblock in EEPROM schreiben */&lt;br /&gt;
    eeprom_write_block (myByteBuffer, eeFooByteArray1, sizeof(myByteBuffer));&lt;br /&gt;
    eeprom_write_block (myWordBuffer, eeFooWordArray1, sizeof(myWordBuffer));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ebenso lassen sich float-Variablen lesen und schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
float eeFloat EEMEM = 12.34f;&lt;br /&gt;
&lt;br /&gt;
float void eeprom_float_example (float value)&lt;br /&gt;
{&lt;br /&gt;
   /* float in EEPROM schreiben */&lt;br /&gt;
   eeprom_write_float (&amp;amp;eeFloat, value);&lt;br /&gt;
&lt;br /&gt;
   /* float aus EEPROM lesen */&lt;br /&gt;
   return  eeprom_read_float (&amp;amp;eeFloat);&lt;br /&gt;
}&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== EEPROM-Speicherabbild in .eep-Datei ===&lt;br /&gt;
&lt;br /&gt;
Mit den zum Compiler gehörenden Werkzeugen kann der aus den Variablendeklarationen abgeleitete EEPROM-Inhalt in eine Datei geschrieben werden. Die übliche Dateiendung ist .eep, Daten im Intel Hex-Format. Damit können Standardwerte für den EEPROM-Inhalt im Quellcode definiert werden. &lt;br /&gt;
&lt;br /&gt;
Makefiles nach WinAVR/MFile-Vorlage enthalten bereits die notwendigen Einstellungen, siehe dazu die Erläuterungen im [[AVR-GCC-Tutorial/Exkurs Makefiles|Exkurs Makefiles]].&lt;br /&gt;
&lt;br /&gt;
Der Inhalt der eep-Datei muss ebenfalls zum Mikrocontroller übertragen werden, wenn die Initialisierungswerte aus der Deklaration vom Programm erwartet werden. Ansonsten enthält der EEPROM-Speicher nach der Übertragung des Programmers mittels ISP abhängig von der Einstellung der EESAVE-Fuse&amp;lt;ref&amp;gt;vgl. Datenblatt Abschnitt Fuse Bits&amp;lt;/ref&amp;gt; nicht die korrekten Werte:&lt;br /&gt;
; EESAVE = 0 (programmed): Die Daten im EEPROM bleiben erhalten. Werden sie nicht neu geschrieben, so enthält das EEPROM evtl. Daten, die nicht mehr zum Programm passen.&lt;br /&gt;
; EESAVE = 1 (unprogrammed): Beim Programmieren werden die Daten im EEPROM gelöscht, also auf 0xff gesetzt.&lt;br /&gt;
&lt;br /&gt;
Als Sicherung kann man im Programm nochmals die Standardwerte vorhalten, beim Lesen auf 0xFF prüfen und gegebenenfalls einen Standardwert nutzen.&lt;br /&gt;
&lt;br /&gt;
=== Direkter Zugriff auf EEPROM-Adressen ===&lt;br /&gt;
&lt;br /&gt;
Will man direkt auf bestimmte EEPROM Adressen zugreifen, dann sind folgende Funktionen hilfreich, um sich die Typecasts zu ersparen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Byte aus dem EEPROM lesen&lt;br /&gt;
uint8_t EEPReadByte(uint16_t addr)&lt;br /&gt;
{&lt;br /&gt;
  return eeprom_read_byte((uint8_t *)addr);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Byte in das EEPROM schreiben&lt;br /&gt;
void EEPWriteByte(uint16_t addr, uint8_t val)&lt;br /&gt;
{&lt;br /&gt;
  eeprom_write_byte((uint8_t *)addr, val);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oder als Makro:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#define   EEPReadByte(addr)         eeprom_read_byte((uint8_t *)addr)     &lt;br /&gt;
#define   EEPWriteByte(addr, val)   eeprom_write_byte((uint8_t *)addr, val)&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verwendung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
EEPWriteByte(0x20, 128);   // Byte an die Adresse 0x20 schreiben&lt;br /&gt;
...&lt;br /&gt;
Val=EEPReadByte(0x20);     // EEPROM-Wert von Adresse 0x20 lesen&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bekannte Probleme bei den EEPROM-Funktionen ===&lt;br /&gt;
&lt;br /&gt;
Vorsicht: Bei alten Versionen der avr-libc wurden nicht alle AVR Controller  unterstützt. Z.B. bei der avr-libc Version 1.2.3 insbesondere bei AVRs &amp;quot;der neuen Generation&amp;quot; (ATmega48/88/168/169) funktionieren die Funktionen nicht korrekt (Ursache: unterschiedliche Speicheradressen der EEPROM-Register). In neueren Versionen (z.&amp;amp;nbsp;B. avr-libc 1.4.3 aus WinAVR 20050125) wurde die Zahl der unterstüzten Controller deutlich erweitert und eine Methode zur leichten Anpassung an zukünftige Controller eingeführt.&lt;br /&gt;
&lt;br /&gt;
In jedem Datenblatt zu AVR-Controllern mit EEPROM sind kurze Beispielecodes für den Schreib- und Lesezugriff enthalten. Will oder kann man nicht auf die neue Version aktualisieren, kann der dort gezeigte Code auch mit dem avr-gcc (ohne avr-libc/eeprom.h) genutzt werden (&amp;quot;copy/paste&amp;quot;, gegebenfalls Schutz vor Unterbrechnung/Interrupt ergänzen &#039;&#039;uint8_t sreg; sreg=SREG; cli(); [EEPROM-Code] ; SREG=sreg; return;&#039;&#039;, siehe Abschnitt Interrupts). Im Zweifel hilft ein Blick in den vom Compiler erzeugten Assembler-Code (lst/lss-Dateien).&lt;br /&gt;
&lt;br /&gt;
* siehe auch: [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/EEPROM handling&lt;br /&gt;
&lt;br /&gt;
=== EEPROM Register ===&lt;br /&gt;
Um das EEPROM anzusteuern, sind drei Register von Bedeutung:&lt;br /&gt;
;EEAR: Hier werden die Adressen eingetragen zum Schreiben oder Lesen. Dieses Register unterteilt sich nochmal in EEARH und EEARL, da in einem 8-Bit-Register keine 512 Adressen adressiert werden können.&lt;br /&gt;
;EEDR: Hier werden die Daten eingetragen, die geschrieben werden sollen, bzw. es enthält die gelesenen Daten.&lt;br /&gt;
;EECR: Ist das Kontrollregister für das EEPROM&lt;br /&gt;
&lt;br /&gt;
Das EECR steuert den Zugriff auf das EEPROM und ist wie folgt aufgebaut:&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Aufbau des EECR-Registers&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
!Bit&lt;br /&gt;
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|-&lt;br /&gt;
! Name&lt;br /&gt;
| - || - || - ||- || EERIE || EEMWE || EEWE || EERE&lt;br /&gt;
|-&lt;br /&gt;
! Read/Write&lt;br /&gt;
| R || R || R || R || R/W || R/W || R/W || R/W&lt;br /&gt;
|-&lt;br /&gt;
!Init Value&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bedeutung der Bits&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
;Bit 4-7: nicht belegt&lt;br /&gt;
&lt;br /&gt;
;Bit 3 (EERIE): &#039;&#039;EEPROM Ready Interrupt Enable&#039;&#039;: Wenn das Bit gesetzt ist und globale Interrupts erlaubt sind in Register SREG (Bit 7), wird ein Interrupt ausgelöst nach Beendigung des Schreibzyklus (EEPROM Ready Interrupt). Ist einer der beiden Bits 0, wird kein Interrupt ausgelöst.&lt;br /&gt;
&lt;br /&gt;
;Bit 2 EEMWE): &#039;&#039;EEPROM Master Write Enable&#039;&#039;: Dieses Bit bestimmt, dass, wenn EEWE = 1 gesetzt wird (innerhalb von 4 Taktzyklen), das EEPROM beschrieben wird mit den Daten in EEDR bei Adresse EEAR. Wenn EEMWE = 0 ist und EEWE = 1 gesetzt wird, hat das keine Auswirkungen. Der Schreibvorgang wird dann nicht ausgelöst. Nach 4 Taktzyklen wird das Bit EEMWE automatisch wieder auf 0 gesetzt. Dieses Bit löst den Schreibvorgang nicht aus, es dient sozusagen als Sicherungsbit für EEWE.&lt;br /&gt;
&lt;br /&gt;
;Bit 1 (EEWE): &#039;&#039;EEPROM Write Enable&#039;&#039;: Dieses Bit löst den Schreibvorgang aus, wenn es auf 1 gesetzt wird, sofern vorher EEMWE gesetzt wurde und seitdem nicht mehr als 4 Taktzyklen vergangen sind. Wenn der Schreibvorgang abgeschlossen ist, wird dieses Bit automatisch wieder auf 0 gesetzt und, sofern EERIE gesetzt ist, ein Interrupt ausgelöst. Ein Schreibvorgang sieht typischerweise wie folgt aus:&lt;br /&gt;
:# EEPROM-Bereitschaft abwarten (EEWE=0) &lt;br /&gt;
:# Adresse übergeben an EEAR&lt;br /&gt;
:# Daten übergeben an EEDR&lt;br /&gt;
:# Schreibvorgang auslösen in EECR mit Bit EEMWE=1 und EEWE=1&lt;br /&gt;
:# (Optional) Warten, bis Schreibvorgang abgeschlossen ist&lt;br /&gt;
&lt;br /&gt;
;Bit 0 EERE: &#039;&#039;EEPROM Read Enable&#039;&#039;: Wird dieses Bit auf 1 gesetzt wird das EEPROM an der Adresse in EEAR ausgelesen und die Daten in EEDR gespeichert. Das EEPROM kann nicht ausgelesen werden, wenn bereits eine Schreiboperation gestartet wurde. Es ist daher zu empfehlen, die Bereitschaft vorher zu prüfen. Das EEPROM ist lesebereit, wenn das Bit EEWE=0 ist. Ist der Lesevorgang abgeschlossen, wird das Bit wieder auf 0 gesetzt, und das EEPROM ist für neue Lese- und Schreibbefehle wieder bereit. Ein typischer Lesevorgang kann wie folgt aufgebaut sein:&lt;br /&gt;
:# Bereitschaft zum Lesen prüfen (EEWE=0)&lt;br /&gt;
:# Adresse übergeben an EEAR&lt;br /&gt;
:# Lesezyklus auslösen mit EERE = 1&lt;br /&gt;
:# Warten, bis Lesevorgang abgeschlossen EERE = 0&lt;br /&gt;
:# Daten abholen aus EEDR&lt;br /&gt;
&lt;br /&gt;
= Die Nutzung von sprintf und printf =&lt;br /&gt;
&lt;br /&gt;
Um komfortabel, d.h. formatiert, Ausgaben auf ein Display oder die serielle Schnittstelle zu tätigen, bieten sich &#039;&#039;&#039;sprintf&#039;&#039;&#039; oder &#039;&#039;&#039;printf&#039;&#039;&#039; an. Alle *printf-Varianten sind jedoch ziemlich speicherintensiv und der Einsatz in einem Mikrocontroller mit knappem Speicher muss sorgsam abgewogen werden.&lt;br /&gt;
&lt;br /&gt;
Bei &#039;&#039;&#039;sprintf&#039;&#039;&#039; wird die Ausgabe zunächst in einem Puffer vorbereitet und anschließend mit einfachen Funktionen zeichenweise ausgegeben. Es liegt in der Verantwortung des Programmierers, genügend Platz im Puffer für die erwarteten Zeichen bereitzuhalten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ...&lt;br /&gt;
// nicht dargestellt: Implementierung von uart_puts (vgl. Abschnitt UART)&lt;br /&gt;
// ...&lt;br /&gt;
&lt;br /&gt;
uint16_t counter;&lt;br /&gt;
&lt;br /&gt;
// Ausgabe eines unsigned Integerwertes&lt;br /&gt;
void uart_puti( uint16_t value )&lt;br /&gt;
{&lt;br /&gt;
    uint8_t puffer[20];&lt;br /&gt;
&lt;br /&gt;
    sprintf( puffer, &amp;quot;Zählerstand: %u&amp;quot;, value );&lt;br /&gt;
    uart_puts( puffer );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  counter = 5;&lt;br /&gt;
&lt;br /&gt;
  uart_puti( counter );&lt;br /&gt;
  uart_puti( 42 );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine weitere elegante Möglichkeit besteht darin, den STREAM stdout (Standardausgabe) auf eine eigene Ausgabefunktion umzuleiten. Dazu wird dem Ausgabemechanismus der C-Bibliothek eine neue Ausgabefunktion bekannt gemacht, deren Aufgabe es ist, ein einzelnes Zeichen auszugeben. Wohin die Ausgabe dann tatsächlich stattfindet, ist Sache der Ausgabefunktion. Im Beispiel unten wird auf UART ausgegeben. Alle anderen, höheren Funktionen wie z.&amp;amp;nbsp;B. &#039;&#039;&#039;printf&#039;&#039;&#039;, greifen letztendlich auf diese primitive Ausgabefunktion zurück. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void uart_init(void);&lt;br /&gt;
&lt;br /&gt;
// a. Deklaration der primitiven Ausgabefunktion&lt;br /&gt;
int uart_putchar(char c, FILE *stream);&lt;br /&gt;
&lt;br /&gt;
// b. Umleiten der Standardausgabe stdout (Teil 1)&lt;br /&gt;
static FILE mystdout = FDEV_SETUP_STREAM( uart_putchar, NULL, _FDEV_SETUP_WRITE );&lt;br /&gt;
&lt;br /&gt;
// c. Definition der Ausgabefunktion&lt;br /&gt;
int uart_putchar( char c, FILE *stream )&lt;br /&gt;
{&lt;br /&gt;
    if( c == &#039;\n&#039; )&lt;br /&gt;
        uart_putchar( &#039;\r&#039;, stream );&lt;br /&gt;
&lt;br /&gt;
    loop_until_bit_is_set( UCSRA, UDRE );&lt;br /&gt;
    UDR = c;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void uart_init(void)&lt;br /&gt;
{&lt;br /&gt;
    /* hier µC spezifischen Code zur Initialisierung */&lt;br /&gt;
    /* des UART einfügen... s.o. im AVR-GCC-Tutorial */&lt;br /&gt;
&lt;br /&gt;
    // Beispiel: &lt;br /&gt;
    //&lt;br /&gt;
    // myAVR Board 1.5 mit externem Quarz Q1 3,6864 MHz&lt;br /&gt;
    // 9600 Baud 8N1&lt;br /&gt;
&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
#define F_CPU 3686400&lt;br /&gt;
#endif&lt;br /&gt;
#define UART_BAUD_RATE 9600&lt;br /&gt;
&lt;br /&gt;
// Hilfsmakro zur UBRR-Berechnung (&amp;quot;Formel&amp;quot; laut Datenblatt)&lt;br /&gt;
#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1)&lt;br /&gt;
&lt;br /&gt;
    UCSRB |= (1&amp;lt;&amp;lt;TXEN) | (1&amp;lt;&amp;lt;RXEN);    // UART TX und RX einschalten&lt;br /&gt;
    UCSRC |= (1&amp;lt;&amp;lt;URSEL)|(3&amp;lt;&amp;lt;UCSZ0);    // Asynchron 8N1 &lt;br /&gt;
 &lt;br /&gt;
    UBRRH = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) &amp;gt;&amp;gt; 8 );&lt;br /&gt;
    UBRRL = (uint8_t)UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    int16_t antwort = 42;&lt;br /&gt;
    uart_init();&lt;br /&gt;
&lt;br /&gt;
    // b. Umleiten der Standardausgabe stdout (Teil 2)&lt;br /&gt;
    stdout = &amp;amp;mystdout;&lt;br /&gt;
&lt;br /&gt;
    // Anwendung&lt;br /&gt;
    printf( &amp;quot;Die Antwort ist %d.\n&amp;quot;, antwort );&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Quelle: avr-libc-user-manual-1.4.3.pdf, S.74&lt;br /&gt;
//         + Ergänzungen&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sollen Fließkommazahlen ausgegeben werden, muss im Makefile eine andere (größere) Version der [[FAQ#Aktivieren_der_Floating_Point_Version_von_sprintf_beim_WinAVR_mit_AVR-Studio|printflib]] eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
= Anmerkungen =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= TODO =&lt;br /&gt;
* Aktualisierung Register- und Bitbeschreibungen an aktuelle AVR&lt;br /&gt;
* &amp;quot;naked&amp;quot;-Funktionen&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:avr-gcc Tutorial| ]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=ARM_Cortex_Mikrocontroller&amp;diff=65849</id>
		<title>ARM Cortex Mikrocontroller</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=ARM_Cortex_Mikrocontroller&amp;diff=65849"/>
		<updated>2012-04-21T20:14:56Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Die Firma ARM stellt selbst keine Prozessoren/Controller her, sondern entwickelt nur sogenannte &amp;quot;IP-Cores&amp;quot;, die von Herstellern wie Atmel, Philips, TI und vielen anderen lizenziert werden. Diese Hersteller ergänzen den Core um Speicher und Peripherie. Der Vorteil dieses Modells ist, dass dadurch sehr viele Prozessoren mit unterschiedlichster Ausstattung verfügbar sind, die alle mit dem selben Befehlssatz (und damit dem selben Compiler) programmierbar sind.&lt;br /&gt;
&lt;br /&gt;
Allen ARM-Cores gemeinsam ist die 32 Bit RISC-Architektur. Manche ARM-Cores besitzen neben dem 32 Bit ARM-Befehlssatz noch einen zusätzlichen, kleineren 16 Bit-Befehlssatz (&#039;&#039;&#039;Thumb&#039;&#039;&#039;-Modus, erkennbar am &#039;&#039;&#039;T&#039;&#039;&#039; in der Bezeichnung, z.&amp;amp;nbsp;B. ARM7&#039;&#039;&#039;T&#039;&#039;&#039;DMI). Der Vorteil des Thumb-Befehlssatzes ist der geringere Platzbedarf des Codes; der Nachteil ist die etwas niedrigere Geschwindigkeit. Die ARMv7M-Architektur (man beachtet das &#039;&#039;&#039;v&#039;&#039;&#039;), also z.&amp;amp;nbsp;B. Controller mit Cortex-M3-Kern, unterstützen ausschließlich den Thumb2-Befehlssatz.&lt;br /&gt;
&lt;br /&gt;
Seit wenigen Jahren sind ARM-basierte Mikrocontroller erhältlich, die Aufgrund der vergleichbar einfachen Beschaltung und mit einer &#039;&#039;&#039;deutlich&#039;&#039;&#039; größeren Power eine echte Alternative zu 8-Bit-Controllern darstellen. &lt;br /&gt;
&lt;br /&gt;
Eine sehr aktuelle Variante des ARM ist die Cortex-M3 Familie die &#039;&#039;&#039;[[LPC1xxx]]&#039;&#039;&#039;, als eine echte Konkurrenz zu 8- und 16-Bit Mikrocontrollern wie dem [[AVR]] und [[MSP430]] gedacht ist. Der Cortex-M3 enthält einige Verbesserungen gegenüber dem ARM7TDMI-Kern und ist bereits dabei diesen zu ersetzen. Um den Einstieg zu erleichtern ist für den LPC1xxx bereits eine &#039;&#039;&#039;[http://www.mikrocontroller.net/articles/Codebase_f%C3%BCr_LPC1xxx#Allgemeine_Informationen_zum_Aufbau_der_Code_Base Code-Base]&#039;&#039;&#039;  und ein preisgünstiges &#039;&#039;&#039;[http://www.mikrocontroller.net/wikisoftware/index.php?title=LPC1xxx_Entwicklungskit_LPCXpresso&amp;amp;action=edit Entwicklungskit]&#039;&#039;&#039; vorhanden. Controllerfamilien dieser Klasse sind:&lt;br /&gt;
&lt;br /&gt;
* [http://www.nxp.com LPC13xx/LPC17xx] von NXP oder die inzwischen schon sehr ausführliche, [http://www.mikrocontroller.net/articles/LPC1xxx &#039;&#039;&#039;interne Seite zur Cortex-M3 Familie&#039;&#039;&#039; von LPC]&lt;br /&gt;
* [http://focus.ti.com/general/docs/gencontent.tsp?contentId=54556&amp;amp;DCMP=Luminary&amp;amp;HQS=Other+OT+stellaris Stellaris-Serie] von [http://www.ti.com Texas Instruments] (vormals Luminary Micro)&lt;br /&gt;
* [http://www.atmel.com/products/at91/sam3landing.asp?family_id=605 AT91SAM3] von Atmel&lt;br /&gt;
* [[STM32]] von STMicroelectronics&lt;br /&gt;
* [http://www.toshiba-components.com/microcontroller/TMPM330.html TMPM330] von Toshiba&lt;br /&gt;
* [http://www.fujitsu.com/global/services/microelectronics/product/micom/roadmap/industrial/fm3/ FM3-Serie] von Fujitsu&lt;br /&gt;
* [http://www.energymicro.com/ EFM32-Serie] von Energy Micro&lt;br /&gt;
* [http://www.infineon.com/XMC4000 XMC4000] von Infineon&lt;br /&gt;
* [https://www.silabs.com/products/mcu/Pages/ARM-32bit-microcontroller.aspx SiM3U1xx] von Silabs&lt;br /&gt;
* [http://www.holtek.com.tw/english/products/32bit_flashmcu.htm HT32] von Holtek Semiconductor&lt;br /&gt;
&lt;br /&gt;
Als günstigere Variante gibt es dann noch die Cortex-M0 Cores. Diese&lt;br /&gt;
werden beispielsweise in folgenden Controllern eingesetzt:&lt;br /&gt;
&lt;br /&gt;
* [http://ics.nxp.com/products/lpc1000/lpc11xx/ LPC11xx] von [http://www.nxp.com NXP]&lt;br /&gt;
* [http://www.nuvoton.com/hq/enu/ProductAndSales/ProductLines/IndustrialIC/ARMMicrocontroller/ARMCortexTMM0/Pages/default.aspx NuMicro-Controller] von nuvoton (ex Winbond), laut Datenblatt mit 2.5-5.5V Betriebssspannung!!!&lt;br /&gt;
&lt;br /&gt;
Eine schon etwas ältere Controller-Familie ist der &#039;&#039;&#039;ARM7&#039;&#039;&#039;TDMI.  Core. Controllerfamilien dieser Klasse sind:&lt;br /&gt;
* NXP (ehemals Philips) [[LPC2000]] &lt;br /&gt;
* Atmel [[AT91SAM]]7&lt;br /&gt;
* Analog Devices [[ADuC7xxx]]&lt;br /&gt;
* [http://focus.ti.com/mcu/docs/mcuprodoverview.tsp?sectionId=95&amp;amp;tabId=203&amp;amp;familyId=454 Texas Instruments TMS470]&lt;br /&gt;
* SAMSUNG S3C24x0 [http://www.samsung.com/global/business/semiconductor/productInfo.do?fmly_id=229&amp;amp;partnum=S3C2410]&lt;br /&gt;
* STR7xx von ST Microelectronics [http://www.st.com/mcu/inchtml-pages-str7.html]&lt;br /&gt;
* und viele weitere&lt;br /&gt;
&lt;br /&gt;
Mehr Informationen zur ARM-Architektur finden sich in der [http://de.wikipedia.org/wiki/ARM-Architektur Wikipedia], weiterführende Links in der [[Linksammlung#ARM|Linksammlung]].&lt;br /&gt;
&lt;br /&gt;
== Compiler ==&lt;br /&gt;
&lt;br /&gt;
Einer der beliebtesten Compiler für ARM-Prozessoren ist der GCC. Er kann sowohl ARM- als auch Thumb-Code erzeugen. Ein komplettes Paket mit allen benötigten Tools für Windows ist [http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/#winarm WinARM] (wird derzeit nicht gepflegt), für Linux und Mac OS X gibt es fertige Komplettpakete [http://www.mikrocontroller.net/en/arm-gcc hier]. Alternative Pakete sind [http://gnuarm.com/ GNUARM] (Linux, Windows, wird derzeit nicht gepflegt), [http://www.yagarto.de/ Yagarto] (Windows, mit Eclipse-Integration), [http://www.codesourcery.com/gnu_toolchains/arm CodeSourcery CodeBench Lite] (alter Name: Codesourcery G++ lite, für Linux, Windows) und [https://launchpad.net/gcc-arm-embedded GNU Tools for ARM Embedded Processors] (bereitgestellt auf launchpad.net).&lt;br /&gt;
&lt;br /&gt;
Inzwischen schon weiter verbreitet ist auch das &#039;&#039;&#039;kostenlose&#039;&#039;&#039; auf Eclipse basierende Entwicklungspaket von [http://www.code-red-tech.com/red-suite-4-nxp.php &#039;&#039;&#039;Code-Red&#039;&#039;&#039;] oder [http://www.coocox.org/CooCox_CoIDE.htm &#039;&#039;&#039;CooCox IDE&#039;&#039;&#039;]&lt;br /&gt;
&lt;br /&gt;
Kommerzielle Entwicklungsumgebungen für ARM-basierte Mikrocontroller sind z.&amp;amp;nbsp;B. [http://rowley.co.uk/arm/ Crossworks ARM] (GCC-basiert, Windows, Mac OS und Linux), [http://www.iar.com/ewarm/ IAR Embedded Workbench for ARM] (Windows) und [http://www.keil.com/arm/ MDK-ARM von Keil/ARM] (Windows).&lt;br /&gt;
&lt;br /&gt;
Für das MBED Board (mbed NXP LPC1768) ist ein kostenloser Onlinecompiler verfügbar (ARM Realview), der sich durch die Bereitstellung von sehr leistungsfähigen Funktionen (API&#039;s) auszeichnet. Den praktischen Nutzen für eine professionelle Anwendung mag man zu Recht in Frage stellen. Um mal schnell was zu programmieren ist das Ding unschlagbar, es ist faktisch keine Installation oder Einarbeitung in eine IDE nötig.&lt;br /&gt;
&lt;br /&gt;
== JTAG ==&lt;br /&gt;
&lt;br /&gt;
Alle ARM-basierten Prozessoren verwenden ein einheitliches [[JTAG]]-Interface, über das Debugging und Speicherzugriff erfolgen kann. Nicht standardisiert sind allerdings die Verfahren zum Beschreiben des Flash-ROMs, deshalb muss man beachten ob die verwendete JTAG-Software Programmierroutinen für den jeweiligen Controller besitzt.&lt;br /&gt;
&lt;br /&gt;
Ein einfacher JTAG-Adapter für den Parallelport ist der &amp;quot;Wiggler&amp;quot;-kompatible, den man selbst bauen kann oder z.&amp;amp;nbsp;B. im [http://shop.embedded-projects.net/index.php?module=artikel&amp;amp;action=artikel&amp;amp;id=48 Embedded Projects Shop] für &amp;amp;euro; 10,00 bestellen kann. Als Software lässt sich unter Windows und Linux [http://openocd.berlios.de/ OpenOCD] (zusammen mit [[GDB]]) oder [http://rowley.co.uk Crossworks ARM] verwenden. &lt;br /&gt;
&lt;br /&gt;
Für USB gibt es [http://shop.embedded-projects.net/index.php?module=artikel&amp;amp;action=artikel&amp;amp;id=436 hier] einen ebenfalls OpenOCD-kompatiblen JTAG-Adapter zum Preis von ca 45€.&lt;br /&gt;
&lt;br /&gt;
Von NXP sind &amp;lt;u&amp;gt;sehr preiswerte&amp;lt;/u&amp;gt; Entwicklungskits (ca. 25€ für Evaluation-Board incl. USB-JTAG Programmer und Debugger) erhältlich z.B. &#039;&#039;&#039;[http://www.watterott.com/index.php?page=search&amp;amp;keywords=LPCXpresso&amp;amp;cat=&amp;amp;mnf=&amp;amp;x=0&amp;amp;y=0 Watterott]&#039;&#039;&#039;. Siehe dazu auch die Dokumentation von NXP zu den &#039;&#039;&#039;[http://www.nxp.com/documents/leaflet/75016842.pdf LPCXpresso-Entwicklungskits]&#039;&#039;&#039; (PDF), oder diese &#039;&#039;&#039;[http://www.mikrocontroller.net/wikisoftware/index.php?title=LPC1xxx_Entwicklungskit_LPCXpresso Beschreibung]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
Der [http://www.segger.com/cms/jlink.html J-Link]-&amp;quot;Emulator&amp;quot; von Segger wird von vielen Softwarepaketen unterstützt und ist für den nicht-kommerziellen Einsatz zu günstigen Konditionen erhältlich.&lt;br /&gt;
&lt;br /&gt;
Als Alternative zum Beschreiben des Flash über JTAG ist oft ein serieller [[Bootloader]] im Controller enthalten.&lt;br /&gt;
&lt;br /&gt;
== Freie Software ==&lt;br /&gt;
&lt;br /&gt;
=== ARM/XSCALE/CORTEX Instruction Set Simulator ===&lt;br /&gt;
&lt;br /&gt;
Die Firma Lauterbach bietet unter der Artikelnummer LA-8809 einen Instruction Set Simulator für ARM Cores an. Die Demoversion ist zur Evaluierung kostenlos. Einschränkungen bestehen in der Anzahl der zu ladenen Debugsymbole. Der Simulator unterstützt alle gängigen ARM Derivate und lädt alle üblichen Debugformate, wie die des RealView,  IAR und TI Compilers, oder der freien GCC Tools.&lt;br /&gt;
&lt;br /&gt;
Zum Simulator gibt es entsprechende zugehörige Debugtools, die allerdings käuflich zu erwerben sind.&lt;br /&gt;
&lt;br /&gt;
Weblinks: &lt;br /&gt;
[[http://www.lauterbach.com/frames.html?dwnload.html Download area mit ARM/XSCALE/CORTEX Simulator]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [[Linksammlung#ARM|Linksammlung (Abschnitt ARM)]]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/LPC1xxx Beschreibung der LPC1xxx-Familie]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/LPC1xxx_Entwicklungskit_LPCXpresso LPCXpresso-Entwicklungskit]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/Installationsanleitung_C-Entwicklungsumgebung_f%C3%BCr_LPC1xxx_von_Code_Red Installationsanleitung zur IDE von Code-Red]&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/Codebase_f%C3%BCr_LPC1xxx LPC1xxx Codebase]&lt;br /&gt;
* [[ARM-elf-GCC-Tutorial]]&lt;br /&gt;
* [[AVR32]]&lt;br /&gt;
* [[Blackfin]]&lt;br /&gt;
* [[AT91SAM9260]]&lt;br /&gt;
* [[STM32]]&lt;br /&gt;
* [[JTAG]]&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://embdev.net/forum/arm-gcc ARM-GCC Forum] im englischsprachigen &amp;quot;Ableger&amp;quot; von microcontroller.net embdev.net u.a. für WinARM, Yagarto, CS Codebench&lt;br /&gt;
* [http://infocenter.arm.com/help/index.jsp Infocenter von ARM Ltd.]&lt;br /&gt;
* [http://www.open-research.org.uk/ARMuC/ ARMuC ARM microcontroller Wiki]&lt;br /&gt;
* [http://chaosradio.ccc.de/cre151.html Chaosradio Express - Die ARM-Architektur]&lt;br /&gt;
&lt;br /&gt;
== Literatur ==&lt;br /&gt;
*ARM Systems Developer&#039;s Guide (2004) ISBN 1558608745 [http://books.google.de/books?id=HKKUkDQE17QC&amp;amp;output=html Im Buch blättern] [http://www.mkp.com/companions/defaultindividual.asp?isbn=9781558608740 Programmbeispiele aus dem Buch, u.a. FFT, FIR/IIR-Filter, Division, Wurzel]&lt;br /&gt;
*ARM Assembly Language - an Introduction (2007) ISBN 1847536964 [http://books.google.de/books?id=8KJX5R8mMvsC&amp;amp;output=html Im Buch blättern]   [http://www.lulu.com/content/1172076 Verlagsseite &amp;quot;Book on demand&amp;quot;]&lt;br /&gt;
*ARM Rechnerarchitekturen für System-on-Chip-Design (2002) ISBN 3826608542&lt;br /&gt;
*Co-Verification of Hardware and Software for Arm Soc Design (2004) ISBN 0750677309&lt;br /&gt;
*ARM System-on-Chip Architecture (2000) ISBN 0201675196 [http://books.google.de/books?id=J_Fu_YTVD9gC&amp;amp;printsec=frontcover&amp;amp;output=html&amp;amp;source=gbs_summary_r&amp;amp;cad=0 Im Buch blättern]&lt;br /&gt;
*ARM Architecture Reference Manual ISBN 0201737191 [http://books.google.de/books?id=O5G-6WX1xWsC&amp;amp;printsec=frontcover&amp;amp;output=html&amp;amp;source=gbs_summary_r&amp;amp;cad=0 Im Buch blättern]&lt;br /&gt;
*Messen, Steuern und Regeln mit ARM-Mikrocontrollern ISBN 3772340172 [http://books.google.de/books?id=TKs4kN-zNYQC&amp;amp;output=html im Buch blättern]&lt;br /&gt;
*Programming Arm Microcontrollers: Using C and the Lpc2100 Family (2005? /ab 1. Dezember 2008) ISBN 0321263359&lt;br /&gt;
*Arm Assembly: Fundamentals and Techniques (ab 1. März 2009) ISBN 1439806101&lt;br /&gt;
*Reliable Embedded Systems: Using 8051 and ARM Microcontrollers (2007) ISBN 0321252918 600 Seiten mit CD [http://vig.pearsoned.co.uk/catalog/academic/product/0,1144,0321252918-TOC,00.html Inhaltsverzeichnis]&lt;br /&gt;
* C und C++ für Embedded Systems (u.a. ARM Cortex-M3) mitp-Verlag 2008 ISBN 382665949X&lt;br /&gt;
&lt;br /&gt;
== Artikel aus der Kategorie ARM ==&lt;br /&gt;
&amp;lt;ncl style=compact maxdepth=2 headings=bullet headstart=2&lt;br /&gt;
      showcats=1 showarts=1&amp;gt;ARM&amp;lt;/ncl&amp;gt;&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM| ]]&lt;br /&gt;
__NOTOC__&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR-Studio&amp;diff=65848</id>
		<title>AVR-Studio</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR-Studio&amp;diff=65848"/>
		<updated>2012-04-21T20:03:11Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* Offizielle Seite */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das &#039;&#039;&#039;AVR-Studio&#039;&#039;&#039; ist eine kostenlose Entwicklungsumgebung ([[Editoren/IDEs|IDE]]) für die Programmierung der [[AVR]]-[[Mikrocontroller]] von Atmel. Sie basiert ab Version 5 auf der Visual Studio Shell von Microsoft und besteht aus einer Projektverwaltung, einem [[Editoren/IDEs#Texteditoren für Programmierer|Editor]], einem [[AVR-Studio#Debugger|Debugger]] und Werkzeugen zum beschreiben der Mikrocontroller.&lt;br /&gt;
&lt;br /&gt;
Mit dem AVR Studio kann in [[Assembler]] sowie in [[C]]/[[C-Plusplus|C++]] programmiert werden. Für die Unterstützung von C/C++ musste bis einschließlich Version 4 vor der Installation des AVR Studio der GNU C Compiler für AVRs [[WinAVR]] installiert werden. Ab AVR Studio 5 ist eine vollständige Toolchain zur Entwicklung von C-Projekten enthalten. Atmel bietet weiterhin eine Erweiterung zwecks Erstellung von Projekten mit eingeschränkter C++-Unterstützung an (siehe [[AVR_Studio#Tipps_.26_Tricks|Tipps &amp;amp; Tricks]]).&lt;br /&gt;
&lt;br /&gt;
== Debugger ==&lt;br /&gt;
Die AVR-Studio-Umgebung sieht unabhängig von der speziellen Debug-Plattform größtenteils identisch aus. Es existieren folgende Debug-Möglichkeiten:&lt;br /&gt;
# [[AVR-Simulation#AVR_Studio|AVR Simulator]]&lt;br /&gt;
# AVR In-Circuit Emulator / [[JTAG]]-Adapter: AVR Dragon, AVR ONE!, JTAGICE3, JTAGICE mkII&lt;br /&gt;
&#039;&#039;&#039;Simulation&#039;&#039;&#039;&lt;br /&gt;
* die meisten AVR-Mikrocontroller werden unterstützt&lt;br /&gt;
* z.T langsamer als eine Emulation (insbesondere bei größeren Projekten)&lt;br /&gt;
* Wechselwirkung mit Peripherie nur über vordefinierte Stimuli möglich&lt;br /&gt;
* Anzeige aller Register zu jeder Zeit möglich&lt;br /&gt;
&#039;&#039;&#039;Emulation&#039;&#039;&#039;&lt;br /&gt;
* Unterstützung von Mikrocontrollern plattformabhängig eingeschränkt&lt;br /&gt;
* z.T. schneller als Simulation&lt;br /&gt;
* Debugging in tatsächlicher Hardwareumgebung&lt;br /&gt;
* Register nicht uneingeschränkt lesbar&lt;br /&gt;
&lt;br /&gt;
== Tipps &amp;amp; Tricks ==&lt;br /&gt;
&lt;br /&gt;
* [[AVR-Studio Bugs]]&lt;br /&gt;
&lt;br /&gt;
* [[AVR-Simulation]]&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/193587#1894280 Pfad zum Hexfile]&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/237681#2411339 Anzeige der Größe benutzter Speicherbereiche in AVR Studio 5]&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/236601#2413654 C++ Templates (beta) für AVR Studio 5] (Vorsicht: kein vollständiger Funktionsumfang, siehe [http://support.atmel.no/bin/customer.exe?=&amp;amp;action=viewKbEntry&amp;amp;id=1001 FAQ])&lt;br /&gt;
&lt;br /&gt;
* [http://www.rn-wissen.de/index.php/AVR_Studio_5#Eigene_Templates_erzeugen Erstellung eigener Templates in AVR Studio 5] &lt;br /&gt;
&lt;br /&gt;
== Downloads ==&lt;br /&gt;
&lt;br /&gt;
=== Offizielle Seite ===&lt;br /&gt;
* http://www.atmel.com/avrstudio&lt;br /&gt;
* http://www.atmel.no/beta_ware/ (gelegentlich Aktualisierungen und Testversionen)&lt;br /&gt;
&lt;br /&gt;
=== Direktlinks Installer ===&lt;br /&gt;
&lt;br /&gt;
Anm.: Die MD5 Checksumme dient zum Überprüfen der Downloads auf Vollständigkeit. Die aktuelle Version ist &#039;&#039;&#039;fett&#039;&#039;&#039; markiert.&lt;br /&gt;
&lt;br /&gt;
Im Falle nicht eingepflegter Updates hier der Direktlink-Präfix (entsprechenden Dateinamen aus dem Formularlink kopieren und hinter dem letzten Schrägstrich einfügen):&lt;br /&gt;
&lt;br /&gt;
http://www.atmel.com/Images/&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/Images/as6installer-6.0.1703-full.exe as6installer-6.0.1703-full.exe] &#039;&#039;&#039;Atmel Studio 6 BETA installer   (731MB, updated 2012/03)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/Images/as6installer-6.0.1703-small.exe as6installer-6.0.1703-small.exe] &#039;&#039;&#039;Atmel Studio 6 BETA installer   (516MB, updated 2012/03)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/Images/as5installer-stable-5.1.208-full.exe as5installer-stable-5.1.208-full.exe] &#039;&#039;&#039;AVR Studio 5.1 installer (includes VSS, .NET4.0, ASF 2.11.0 and Toolchain 3.3.1)   (616MB, updated 2012/02)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/Images/as5installer-stable-5.1.208-small.exe as5installer-stable-5.1.208-small.exe] &#039;&#039;&#039;AVR Studio 5.1 installer (includes ASF 2.11.0 and Toolchain 3.3.1)  (396 MB, updated 2012/02)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/Images/as5installer-5.1.148.beta-full.exe as5installer-5.1.148.beta-full.exe] AVR Studio 5.1 Beta installer (includes VSS and .NET) (523 MB, updated 2011/12)&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/Images/as5installer-5.1.148.beta-small.exe as5installer-5.1.148.beta-small.exe] AVR Studio 5.1 Beta installer  (308 MB, updated 2011/12)&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/Images/AvrStudio4Setup.exe AvrStudio4Setup.exe] &#039;&#039;&#039;AVR Studio 4.19 (build 730) (124 MB, updated 2011/09/11)&#039;&#039;&#039;  MD5:609209DB9A1C6191945421299101DC15&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/Images/AvrStudio417Setup.exe AvrStudio417Setup.exe] AVR Studio 4.17 (build 666) (112 MB, updated 07/09) MD5:9705a9362da76aa9779322127640a184&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/Images/AvrStudio416Setup.exe AvrStudio416Setup.exe] AVR Studio 4.16 (build 628) (126 MB, updated 02/09) (last version for Win98) MD5:d1c412d7a05a9ad95486d7ea680f68e5&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/Images/aStudio4b589.exe aStudio4b589.exe] AVR Studio 4.14 (build 589) (89 MB, updated 04/08)&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/Images/aStudio4b528.exe aStudio4b528.exe]  AVR Studio 4.13 (build 528) (73 MB, updated 03/07)&lt;br /&gt;
&lt;br /&gt;
=== Direktlinks Zusatzsoftware ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/Images/AVRQTouchStudioSetup_VSS_dotNET.exe AVRQTouchStudioSetup_VSS_dotNET.exe] AVR QTouch Studio mit .NET (373 MB, updated 03/10)&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/Images/avr-toolchain-installer-3.3.0.710-win32.win32.x86.exe avr-toolchain-installer-3.3.0.710-win32.win32.x86.exe] &#039;&#039;&#039;AVR Toolchain 3.3.0 (94 MB, updated 2011/09/11, AVR-GCC: 4.5.1, AVR-LIBC: 1.7.1)&#039;&#039;&#039; MD5: 1c43bac156cb1e4cb77dfc7a833cf237&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/Images/avr-toolchain-installer-3.2.3.579-win32.win32.x86.exe avr-toolchain-installer-3.2.3.579-win32.win32.x86.exe] AVR Toolchain 3.2.3 (95 MB, updated 06/11, AVR-GCC: 4.5.1, AVR-LIBC: 1.7.1)&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/Images/avr-toolchain-installer-3.0.0.240-win32.win32.x86.exe avr-toolchain-installer-3.0.0.240-win32.win32.x86.exe] AVR Toolchain 3.0.0 (87 MB, updated 09/10, AVR-GCC: 4.4.3, AVR-LIBC: 1.7.0) MD5:999B3DC3DF471B3A667CF0FE90A522E8. Update util/delay.h [http://www.mikrocontroller.net/topic/196738#1943039] beachten.&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/Images/asf-standalone-archive-2.10.0.zip asf-standalone-archive-2.10.0.zip] &#039;&#039;&#039;AVR SoftwareFramework 2.10.0 - drivers and libraries (87 MB, revision 2.10.0, updated 2012/1/12)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/Images/asf-standalone-archive-2.9.0.zip asf-standalone-archive-2.9.0.zip] AVR SoftwareFramework 2.9.0 - drivers and libraries (79 MB, revision 2.9.0, updated 12/11)&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/Images/as5.1-asf-vsix-stable-2.11.1.30-win32.win32.x86.zip as5.1-asf-vsix-stable-2.11.1.30-win32.win32.x86.zip] &#039;&#039;&#039;AVRStudio5-ASF-Update-2.11.1.30 (174 MB, revision 2.11.1, updated 2012/02/)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/Images/AVRStudio5-ASF-Update-2.8.1.76.exe AVRStudio5-ASF-Update-2.8.1.76.exe] AVRStudio5-ASF-Update-2.8.1.76 (222 MB, revision 2.8.1, updated 2011/10/11)&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://www.youtube.com/user/AtmelCorporation#g/c/8F325BE889E62E50 YouTube-Playlist: AVR Studio 5 Tutorial]&lt;br /&gt;
&lt;br /&gt;
* [http://www.avrfreaks.net/index.php?name=PNphpBB2&amp;amp;file=viewtopic&amp;amp;t=82994 How to install JTAGICE mkII (and AVR Dragon and AVRISP mkII) on Windows 7 x64] auf avrfreaks.net (ggf. kostenlos registrieren). Siehe auch Hinweis von Denny [http://www.mikrocontroller.net/topic/146857#1476962] im Forum.&lt;br /&gt;
&lt;br /&gt;
*[http://avr-eclipse.sourceforge.net/wiki/index.php/The_AVR_Eclipse_Plugin AVR Eclipse Plugin]&lt;br /&gt;
&lt;br /&gt;
*[http://avrstudio5.wordpress.com/ AVR Studio 5 Blog] - Useful hints and tips for installation troubleshooting with the new AVR Studio 5&lt;br /&gt;
&lt;br /&gt;
[[Category:AVR]]&lt;br /&gt;
[[Kategorie:Entwicklungstools]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Vorlage:Navigation_zur%C3%BCckhochvor&amp;diff=65847</id>
		<title>Vorlage:Navigation zurückhochvor</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Vorlage:Navigation_zur%C3%BCckhochvor&amp;diff=65847"/>
		<updated>2012-04-21T19:57:32Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: Schützte „Vorlage:Navigation zurückhochvor“ ([edit=autoconfirmed] (unbeschränkt) [move=autoconfirmed] (unbeschränkt))&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;&lt;br /&gt;
[[{{{zurücklink}}}|Zurück zu {{{zurücktext}}}]] | [[{{{hochlink}}}|Hoch zu {{{hochtext}}}]] | [[{{{vorlink}}}|Vor zu {{{vortext}}}]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Vorlage:Navigation_zur%C3%BCckhochvor&amp;diff=65846</id>
		<title>Vorlage:Navigation zurückhochvor</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Vorlage:Navigation_zur%C3%BCckhochvor&amp;diff=65846"/>
		<updated>2012-04-21T19:56:15Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: Änderungen von 188.165.212.59 (Diskussion) rückgängig gemacht und letzte Version von Yahp wiederhergestellt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&amp;lt;div style=&amp;quot;text-align: center;&amp;quot;&amp;gt;&lt;br /&gt;
[[{{{zurücklink}}}|Zurück zu {{{zurücktext}}}]] | [[{{{hochlink}}}|Hoch zu {{{hochtext}}}]] | [[{{{vorlink}}}|Vor zu {{{vortext}}}]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Temperatursensor&amp;diff=64829</id>
		<title>Temperatursensor</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Temperatursensor&amp;diff=64829"/>
		<updated>2012-03-07T18:20:30Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Will man mit einem [[Mikrocontroller]] Temperaturen messen, dann braucht man&lt;br /&gt;
* einen [[Sensor]], der die Temperatur z.&amp;amp;nbsp;B. in eine Spannung oder einen Strom umsetzt&lt;br /&gt;
* einen [[ADC | AD-Wandler]], der das Signal digitalisiert. Der kann auf dem Sensor oder dem Mikrocontroller integriert sein.&lt;br /&gt;
&lt;br /&gt;
Temperatursensoren gibt es nun in allen möglichen Varianten. Vom temperaturabhängigen [[Widerstand]] bis zum fertig abgeglichenen All-in-one-Bauteil mit digitalem Ausgang. Wie bei allen Sensoren sollte man auch hier genau hinschauen und [[Auflösung und Genauigkeit]] unterscheiden.&lt;br /&gt;
&lt;br /&gt;
== Analoge Temperatursensoren ==&lt;br /&gt;
&lt;br /&gt;
=== PT100 ===&lt;br /&gt;
&lt;br /&gt;
Unter einem PT100 versteht man einen Platinwiderstand, der bei 0°C einen Widerstand von 100Ω hat.&lt;br /&gt;
Platinwiderstände sind temperaturabhängige Widerstände mit hoher Wiederholgenauigkeit und Konstanz[http://de.wikipedia.org/wiki/Konstante].  Wegen der relativ geringen Widerstandsänderung von nur ca. 0,4Ω pro Grad ist etwas mehr Schaltungsaufwand erforderlich als bei anderen Sensoren. Genauere Formeln zur Temperaturbestimmung gibt es u.a. bei der [http://de.wikipedia.org/wiki/Pt100 Wikipedia]. Ein Schaltplan findet sich bei der [http://www.heise.de/ct/artikel/Sensibelchen-289608.html c&#039;t].&lt;br /&gt;
&lt;br /&gt;
Die Sensoren gibt es auch mit anderen Widerstandswerten, z.&amp;amp;nbsp;B. mit 1000&amp;amp;Omega; und heißen dann entsprechend PT1000.&lt;br /&gt;
&lt;br /&gt;
Vorteil:&lt;br /&gt;
* genormt&lt;br /&gt;
* großer Meßbereich&lt;br /&gt;
* hohe Linearität&lt;br /&gt;
* hohe Wiederholgenauigkeit&lt;br /&gt;
* einfach austauschbar&lt;br /&gt;
&lt;br /&gt;
Nachteil:&lt;br /&gt;
* relativ teuer (bei segor.de ab 3,80&amp;amp;euro;)&lt;br /&gt;
* brauchen aufwendigere Auswerteschaltung&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://www.heise.de/ct/04/22/236/ c&#039;t-Artikel: Mikrocontroller-Programmierung: Timer, Sensoren und Drehgeber (mit PT100 Schaltung)]&lt;br /&gt;
* [http://pdfserv.maxim-ic.com/en/an/AN3450.pdf Maxim AN3450 Positive Analog Feedback Compensates PT100 Transducer]&lt;br /&gt;
&lt;br /&gt;
=== NTC/PTC ===&lt;br /&gt;
&lt;br /&gt;
NTC und PTC sind temperaturabhängige Widerstände.&lt;br /&gt;
&lt;br /&gt;
* NTC (engl. &#039;&#039;&#039;N&#039;&#039;&#039;egative &#039;&#039;&#039;T&#039;&#039;&#039;emperature &#039;&#039;&#039;C&#039;&#039;&#039;oefficient, Heißleiter), hat bei hohen Temperaturen seinen niedrigsten Widerstand, z.&amp;amp;nbsp;B. Silizium&lt;br /&gt;
* PTC (engl. &#039;&#039;&#039;P&#039;&#039;&#039;ositive &#039;&#039;&#039;T&#039;&#039;&#039;emperature &#039;&#039;&#039;C&#039;&#039;&#039;oefficient, Kaltleiter), hat bei niedrigen Temperaturen seinen geringsten Widerstand, z.&amp;amp;nbsp;B. Glühlampe&lt;br /&gt;
&lt;br /&gt;
Um den Widerstandswert zu messen schaltet man sie mit einem normalen Widerstand oder einer [[Konstantstromquelle]] in Reihe zu einem [[Spannungsteiler]] und misst den Spannungsabfall. Eine Beispielschaltung findet sich [http://www.mathar.com/msp_thermo1.html hier].&lt;br /&gt;
&lt;br /&gt;
Vorteil:&lt;br /&gt;
* billig (z.B. [http://www.reichelt.de/?ARTICLE=9594 KTY81-110] bei Reichelt  ~0,60&amp;amp;euro;)&lt;br /&gt;
&lt;br /&gt;
Nachteil:&lt;br /&gt;
* müssen für höhere Genauigkeiten abgeglichen werden&lt;br /&gt;
* brauchen A/D-Wandler&lt;br /&gt;
* sind nichtlinear&lt;br /&gt;
&lt;br /&gt;
Beispiele:&lt;br /&gt;
* KTY10-5&lt;br /&gt;
* KTY13-6&lt;br /&gt;
* KTY81-121&lt;br /&gt;
* KTY81-122&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://www.sprut.de/electronic/temeratur/temp.htm Temperaturabhängige Stromquelle und NTC/PTC inclusive Linearisierung]&lt;br /&gt;
*[http://www.umnicom.de/Elektronik/Mikrokontroller/Atmel/AtFan/AtFan.html#2.2.2 Berechnung des Linearisierungswiderstandes für gewünschten Temperaturbereich] der fällt sonst immer vom Himmel&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/208587#2065880 KTY 10-5 Formelprobleme]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/225563 Codesammlung: Beispiel mit 0,5°C Auflösung]&lt;br /&gt;
&lt;br /&gt;
=== LMx35 ===&lt;br /&gt;
&lt;br /&gt;
Eine IC-Familie, die pro Kelvin Temperaturänderung ihre Ausgangsspannung um 10&amp;amp;nbsp;mV ändert. Die ICs gibt es in verschiedenen Genauigkeiten und Temperaturbereichen mit den Bezeichnungen LM135(A), LM235(A) und LM335(A). Der günstigste ist der LM335 mit einem Temperaturbereich von −40 … +100°C.&lt;br /&gt;
In verschiedenen Bauformen erhältlich. Beispielschaltungen finden sich im [http://www.national.com/ds.cgi/LM/LM135.pdf Datenblatt] und [http://www.suessbrich.info/elek/elektherm1.html hier]&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* hat auch ohne Kalibrierung eine Genauigkeit von einem Grad (bei 25°C)&lt;br /&gt;
* relativ billig (LM335 bei Reichelt ab 0,50&amp;amp;nbsp;€)&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* benötigt A/D-Wandler&lt;br /&gt;
* bei längerer Anschlussleitung störanfällig&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://www.schramm-software.de/tipps/temperaturmessung/analogsensoren.htm Test-Schaltungen und -Code zur Auswertung mit ADC (AVR-Assembler)]&lt;br /&gt;
&lt;br /&gt;
=== LM334 ===&lt;br /&gt;
&lt;br /&gt;
Ein IC ähnlich dem LM335 mit dem Unterschied, dass der durch das IC fließende Strom proportional von der Temperatur abhängt. Mit einer einfachen Schaltung aus nur zwei Widerständen kann man dann den Strom in einer Weise wandeln, dass pro Kelvin eine Spannungsänderung von 10mV ausgegeben wird. Da die Strom-Spannungswandlung auf der Platine (und damit nahe am AD-Wandler) stattfindet und die Übertragung des Messwerts durch einen Strom stattfindet, sind Störungen durch Netzbrumm etc. viel geringer als beim LM335&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
&amp;lt;!-- * hat auch ohne Kalibrierung eine Genauigkeit von einem Grad (bei 25°C) &lt;br /&gt;
Laut Datenblatt +-3°C&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* relativ billig ([http://www.reichelt.de/?ARTICLE=10468 Reichelt 0,54 &amp;amp;euro;])&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* benötigt A/D-Wandler&lt;br /&gt;
* Bereich 0°C-70°C&lt;br /&gt;
&lt;br /&gt;
Ähnliche ICs:&lt;br /&gt;
* AD592 (Ausgangsstrom 1µA pro Kelvin, absolute Temperatur) [http://www.reichelt.de/?ARTICLE=3825 Reichelt: 3,75 €], Conrad 174912 8,50 &amp;amp;euro;&lt;br /&gt;
&lt;br /&gt;
=== SMT160-30 ===&lt;br /&gt;
&lt;br /&gt;
Ist ein Zwischending zwischen Digital und Analog. Sein Ausgangssignal ist ein digitales PWM-Signal, zu dessen Messung man am besten den Input-Capture-Eingang eines Mikrocontrollers verwendet. Man kann ihn also wie einen analogen Sensor nur indirekt auslesen, anstatt über einen AD-Wandler hier über einen Timer.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* Digitales PWM-Signal ist unempfindlich gegen Störeinflüsse&lt;br /&gt;
* gibt es in SO8, TO18, TO92 und &amp;lt;b&amp;gt;TO220&amp;lt;/b&amp;gt;, gut befestigbar, z.B am Kühlkörper&lt;br /&gt;
* linear&lt;br /&gt;
* kein Abgleich nötig&lt;br /&gt;
&lt;br /&gt;
Nachteile (viele):&lt;br /&gt;
* benötigt Timer&lt;br /&gt;
* jittert extrem, genaue Messungen nur über Mittelung / Filterung möglich&lt;br /&gt;
* nicht nur das PWM-Verhältnis, sondern auf die Frequenz ist temp-abhängig (1-4kHz)&lt;br /&gt;
* teuer (Farnell 10,90&amp;amp;euro; +16%, Conrad 9,xx&amp;amp;euro; , www.hy-line.de ??).&lt;br /&gt;
* TO92 Gehäuse ist günstiger, dafür weniger genau&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* http://www.hy-line.de/co/sensor-tec/hersteller/smartec/smt-160-30/index.html&lt;br /&gt;
&lt;br /&gt;
=== Thermoelement ===&lt;br /&gt;
&lt;br /&gt;
Ein Thermoelement besteht im einfachsten Fall aus zwei ungleichen Metallendrähten, die an einem Punkt miteinander verbunden sind und bei dem die Verbindungsstelle einer anderen Temperatur ausgesetzt ist als die offenen Enden der Drähte. An den offenen Enden der Drähten entsteht eine Spannung (Thermospannung). Dieser Effekt wurde 1821 von Thomas Seebeck entdeckt ([http://de.wikipedia.org/wiki/Seebeck-Effekt Seebeck-Effekt] bei Wikipedia). Eine weitere Anwendung ist der thermoelektrische Generator (&amp;quot;Thermogenerator&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Vorteil:&lt;br /&gt;
* über einen sehr weiten Temperaturbereich einsetzbar&lt;br /&gt;
&lt;br /&gt;
Nachteil:&lt;br /&gt;
* die sehr geringen Temperaturspannungen im Mikrovoltbereich benötigen eine sehr gute Auswertelektronik (guter Analogteil + AD-Wandler).&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
&amp;lt;!-- Der Link wird von NI umgebogen zur Homepage. Recherche nach dem Autor brachte nix hervor :-(&lt;br /&gt;
* [http://digital.ni.com/worldwide/germany.nsf/web/all/7A4F02BAEFEC22AC802567F6003E0D6E  Temperaturmessung mit Thermoelementen] - Eine Einführung von David Potter (deutsche Überarbeitung: G.Sinkovic) (inkl. Erläuterung der Kaltstellenkompensation) --&amp;gt;&lt;br /&gt;
* [http://www.sensorwell.at/fileadmin/templates/images/data_sheets/temperatur_messtechnik.pdf Warum Thermoelemente Relativtemperaturen messen! oder Was ist eine Kaltstelle?] - Technische Information von www.sensorwell.at (PDF, ca. 600kB)&lt;br /&gt;
&lt;br /&gt;
== Digitale Temperatursensoren ==&lt;br /&gt;
&lt;br /&gt;
=== DS1621 ===&lt;br /&gt;
&lt;br /&gt;
Der DS1621 ist Temperatursensor und A/D-Wandler in einem. Er gibt seine Daten per [[I²C]]-[[Bus]] aus. Ein Schaltplan für einen elektronischen Thermometer mit diesem IC findet sich [http://www.myplace.nu/avr/thermo/ hier].&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* bereits kalibriert&lt;br /&gt;
* kein A/D-Wandler nötig&lt;br /&gt;
* da I²C ein Bus ist, kann man mehrere DS1621 und andere I²C-Bausteine zusammen anschließen und braucht dafür trotzdem nur zwei I/O-Ports.&lt;br /&gt;
* Messbereich -55°C to +125°C &lt;br /&gt;
* Genauigkeit +-0,5°C&lt;br /&gt;
* Auflösung besser 0,01°C, wenn man die beiden Zählerregister (Count-Remain und Count-per-C) auswertet&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* teuer (Segor 5,80&amp;amp;euro;; RS 3,95&amp;amp;euro;; Conrad 5,22&amp;amp;euro;)&lt;br /&gt;
* obwohl die meisten Register [[Speicher#NVRAM | nichtflüchtig]] sind, kann man ihn nicht als Stand-Alone-Thermostat einsetzen, da er erst nach einem Start-Conversion-Befehl zu messen beginnt.&lt;br /&gt;
&lt;br /&gt;
Nachfolger:&lt;br /&gt;
* DS1631, DS1631A (Auto-Start-&amp;gt; Stand-Alone-Thermostat), DS1731&lt;br /&gt;
* weitere Stand-Alone-Thermostaten: DS1821, DS1629&lt;br /&gt;
&lt;br /&gt;
=== LM75 ===&lt;br /&gt;
&lt;br /&gt;
Der LM75 ist so ähnlich wie der DS1621, allerdings nur in SMD erhältlich und nicht so genau. Er ist aber öfters mal auf PC-Mainboards zu finden, so dass man beim Schlachten eines solchen günstig an einen Temperatursensor kommen kann. Eine Beispiel Schaltplan mit einem ATmega8 findet man [http://www.ucblog.de/2010/09/mikrocontroller-thermometer-schaltplan/ hier]&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* bereits kalibriert&lt;br /&gt;
* kein A/D-Wandler nötig&lt;br /&gt;
* I²C-Bus Ausgang&lt;br /&gt;
* billiger als DS1621 (Reichelt 1,45 &amp;amp;euro;; RS 3V: 3,75&amp;amp;euro;; 5V: 2,72&amp;amp;euro;)&lt;br /&gt;
* Auflösung +-0,5°C&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* nur im SMD-Gehäuse erhältlich&lt;br /&gt;
* relativ ungenau (+-2°C), kann man jedoch kalibrieren / kompensieren&lt;br /&gt;
&lt;br /&gt;
Kompatible Typen:&lt;br /&gt;
* AD7415ART&lt;br /&gt;
* DS7505S+&lt;br /&gt;
&lt;br /&gt;
=== LM76 ===&lt;br /&gt;
&lt;br /&gt;
Der LM76 ähnlich dem LM75, bietet aber eine 8-fach höhere Auflösung und eine Genauigkeit von 0.5 bzw. 1°C.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* höhere Auflösung&lt;br /&gt;
* höhere Genauigkeit&lt;br /&gt;
&lt;br /&gt;
Nachteil:&lt;br /&gt;
* schwerer zu beschaffen&lt;br /&gt;
&lt;br /&gt;
=== TMP175 / TMP75 ===&lt;br /&gt;
&lt;br /&gt;
Ähnelt dem LM75 stark! Temperatursensor von Texas Instruments.&lt;br /&gt;
&lt;br /&gt;
=== DS18S20 / DS18B20 ===&lt;br /&gt;
&lt;br /&gt;
Der DS18S20 (Nachfolger des DS1820) und DS18B20 sind scheinbar Temperatursensoren und A/D-Wandler in einem. Wenn man genauer hinschaut, stellt man fest, dass es sich um direktwandelnde Sensoren handelt. Die Temperatur wird ohne Umweg über eine analoge Zwischengröße (Spannung oder Strom) in ein digitales Signal überführt.&lt;br /&gt;
&lt;br /&gt;
Die Datenkommunikation erfolgt über ein 1-Wire-Interface, wodurch man am [[Mikrocontroller]] mit nur einem einzigen I/O-Pin auskommen kann. Außerdem beherrschen sie die parasitäre Stromversorgung, d.h., man braucht für Daten und Stromversorgung zusammen nur zwei Leitungen.&lt;br /&gt;
&lt;br /&gt;
Beim DS18B20 sind Auflösungen von 9, 10, 11 und 12 Bits konfigurierbar. Je kleiner die Auflösung, desto kürzer ist die Messzeit. Der DS18S20 hat eine feste Auflösung von 12 Bits, wobei die unteren 3 Bits aufwändiger auszuwerten sind als beim DS18B20. Der DS18S20 ist als Ersatz für den DS1820 gedacht. Der Hersteller empfiehlt den DS18B20 für Neuentwicklungen.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* bereits kalibriert&lt;br /&gt;
* Genauigkeit +-0,5°C&lt;br /&gt;
* 1-Wire-Ausgang&lt;br /&gt;
&lt;br /&gt;
Nachteil:&lt;br /&gt;
* relativ teuer: Reichelt: 2,50&amp;amp;euro; / CSD: 1,85&amp;amp;euro; / Conrad 5,08&amp;amp;euro;&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://pdfserv.maxim-ic.com/en/ds/DS18S20.pdf Datenblatt DS18S20] &lt;br /&gt;
* [http://pdfserv.maxim-ic.com/en/ds/DS18B20.pdf Datenblatt DS18B20]&lt;br /&gt;
* [http://www.maxim-ic.com/app-notes/index.mvp/id/4377 Vergleich DS18B20 &amp;lt;-&amp;gt; DS18S20]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/6505 Code zur Ansteuerung (ASM ATTiny12)]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/14792 Code zur Ansteuerung (AVR-GCC)]&lt;br /&gt;
* [http://gandalf.arubi.uni-kl.de/avr_projects/tempsensor/ Code zur Ansteuerung mit CRC-Prüfung (AVR-GCC)]&lt;br /&gt;
* [http://www.schramm-software.de/tipps/temperaturmessung/digitalsensoren.htm Code zur Ansteuerung mit CRC-Prüfung (AVR-Assembler)]&lt;br /&gt;
* [http://chaokhun.kmitl.ac.th/~kswichit/avrthermo/avrthermo.html LED-Thermometer mit AT90S2313 (C)]&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-4-248219.html Webserver zur Ansteuerung von bis zu 63 Bausteinen]&lt;br /&gt;
* [http://www.teslabs.com/openplayer/docs/docs/other/ds18b20_pre1.pdf PDF Anleitung zur Beschaltung und Programmierung (C)]&lt;br /&gt;
*[http://www.digitemp.com/building.shtml Anleitung Sensorfühleraufbau (DigiTemp)]&lt;br /&gt;
* http://www.mikrocontroller.net/topic/14792 &lt;br /&gt;
* http://www.mikrocontroller.net/topic/232156 (Timing der parasitären Versorgung)&lt;br /&gt;
&lt;br /&gt;
=== DS1822 ===&lt;br /&gt;
&lt;br /&gt;
Ähnlich wie DS18S20, aber weniger genau (+-2°) und in großen Stückzahlen billiger. Wegen der geringeren Verbreitung kommt der Preisvorteil aber bei Einzelstücken nicht beim Kunden an. So kostet er bei Reichelt mit 3,50&amp;amp;euro; mehr als der DS18S20.&lt;br /&gt;
&lt;br /&gt;
=== DS1921 / DS1922 ===&lt;br /&gt;
&lt;br /&gt;
Sind wie die DS1821 1-wire-Sensoren mit zusätzlicher Logging-Funktion.&lt;br /&gt;
Im iButton-Gehäuse befindet sich eine Lithium-Zelle, eine RTC, CMOS-RAM und der Temp-Sensor. Nach umfangreicher Progammierung startet der Button seine Mission (Aufzeichnung des Temperaturverlaufs).&lt;br /&gt;
Gibt es auch mit zusätzlicher Feuchtemessung (DS1923).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== TSic ===&lt;br /&gt;
&lt;br /&gt;
Die TSic Sensoren werden baugleich von 3 Herstellern angeboten:&lt;br /&gt;
* ZMD ([http://www.zmd.biz/temp.php?group=temp&amp;amp;content=products Homepage]) ([http://tarr.uspto.gov/servlet/tarr?regser=serial&amp;amp;entry=78673282 Trademark])&lt;br /&gt;
* IST AG ([http://www.ist-ag.com/eh/ist-ag/de/home.nsf/contentview/8F5D32432CAC53C2C1257405003C2433 Homepage])&lt;br /&gt;
* Hygrosens ([http://www.hygrosens.de/english/shop/list.html?tx_ttproducts_pi1%5Bcat%5D=11&amp;amp;cHash=dcd89b823b Homepage])&lt;br /&gt;
&lt;br /&gt;
Die TSic Sensoren ([http://www.zmd.biz/pdf/ZMD%20TSic%20Data%20Sheet%20V3%207.pdf Datenblatt]) geben ihre Temperaturmessdaten automatisch in einem festen Intervall aus. Daher muss der Host nur warten bis die nächsten Messdaten rausgeschickt werden. Die TSic Sensoren die es im freien Handel gibt, geben ihre Messdaten alle 100ms (10Hz) aus. &lt;br /&gt;
Zur Übertragung wird das [http://www.zmd.biz/pdf/IST_TSic_ZACwire_V2.3%20Digital%20Output_17-Oct-06.pdf ZACwire] Protokoll benutzt. Es handelt sich um eine einfach zwei Byte Übertragung per Manchester-Code. Diese zwei Byte repräsentieren den digital gewandelten Temperaturwert. Im Gegensatz zu Sensoren wie den DS18xxx von Dallas muss dieser Wert aber erst auf einen dezimalen Wert umgerechnet werden. &lt;br /&gt;
Die Sensoren kommen mit 3 Pins aus (VCC, GND, Dout).&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* Bereits kalibriert&lt;br /&gt;
* Verschiedene Genauigkeiten lieferbar&lt;br /&gt;
* Sehr einfaches Kommunikationsprotokoll&lt;br /&gt;
* Geringer Stromverbrauch&lt;br /&gt;
* Hochgenau: bis zu +/- 0.1°C (TSic 50x)&lt;br /&gt;
&lt;br /&gt;
Nachteil:&lt;br /&gt;
* Recht teuer (Reichelt: 4,70&amp;amp;euro; für den TSic206)&lt;br /&gt;
* Nur ein Sensor an einem I/O nutzbar (Kein Bussystem)&lt;br /&gt;
&lt;br /&gt;
Achtung! &lt;br /&gt;
Die TSic Sensoren gibt es auch als Version mit analog Ausgang. Bei der Typenbezeichnung gibt die 3. Stelle an ob es sich um die analog- oder Digitalversion handelt (1 = analog, 6 = digital). &lt;br /&gt;
Der TSic201 ist also analog, wärend der TSic206 ein digitaler ist.&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://www.avr-projekte.de/zacwireasm.htm Zacwire Protokoll, AVR-Assembler]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/45573#347765 Ansatz zum Empfang der Daten]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/225554# Beispiel mit Strobe ohne Interrupt]&lt;br /&gt;
* [http://ethersex.de/index.php/Zacwire Fertige Ansteuerung durch AVR in Ethersex]&lt;br /&gt;
* [http://www.zmd.biz/temp.php?group=temp&amp;amp;content=products Herstellerseite mit Datenblättern und FAQ]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/82087 Diskussion mit Beispielcode (MSP430, AVR, PIC) blockierend]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/144424#1367539 C++ Interrupt]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/88847 noch mehr C, problematisch Interrupt]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/151791#1426974 C für ATmega8]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/159149#1510455 auch problematisch]&lt;br /&gt;
* [http://www.sinc.sunysb.edu/Stu/maman/ESE_381.htm Projekt mit tsic sensor, evtl. code]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/188462#1837622 fertiger Code zum Einlesen des Zacwire-Protokolls für PIC in ASM]&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=55103 RN: Bascom]&lt;br /&gt;
* [http://www.mikrocontroller.net/search?query=tsic* Suche in den Foren]&lt;br /&gt;
* [http://www.avr-projekte.de/tinyclock.htm TSIC206 Thermometer mit Uhr und Kalender. Komplette Bauanleitung mit ASM Quellcode für AT-Tiny2313]&lt;br /&gt;
&lt;br /&gt;
=== SHT1x/SHT7x ===&lt;br /&gt;
&lt;br /&gt;
Der SHT1x/SHT7x (SHT10, SHT11, SHT15, STH71, SHT75) sind kombinierte Temperatur- und Feuchtesensoren von [http://www.sensirion.com Sensirion]. Sie unterscheiden sich in Bauform und Genauigkeit.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* digitale Schnittstelle mit einfacher [[I²C]]-&#039;&#039;ähnlicher&#039;&#039; Ansteuerung&lt;br /&gt;
* keine Kalibrierung notwendig&lt;br /&gt;
* Beispielcode (C, MC51) auf der Sensirion-Seite verfügbar (relativ leicht portierbar)&lt;br /&gt;
* interne Heizelemente (Funktionsprüfung, &amp;quot;rauhe&amp;quot; Umgebung)&lt;br /&gt;
* Spannungsmonitor (&amp;quot;Battery fail&amp;quot;)&lt;br /&gt;
* sehr hohe Genauigkeit&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* kann nicht am [[I²C]] Bus betrieben werden, theoretisch gleiche Clockleitung möglich, fixe Adresse&lt;br /&gt;
* relativ teuer (Farnell 18,60&amp;amp;euro;)(SHT11 bei CSD 14€)&lt;br /&gt;
&lt;br /&gt;
[http://www.sensirion.com/en/01_humidity_sensors/00_humidity_sensors.htm Übersicht] der Temperatur- /Feutchtigkeitssensoren von Sensirion.&lt;br /&gt;
&lt;br /&gt;
=== SHT21 ===&lt;br /&gt;
&lt;br /&gt;
[http://www.sensirion.com Sensirion] bietet auch den SHT21 Feuchtigkeits- und Temperatursensor an, welcher wesentlich genauer ist.&lt;br /&gt;
    &lt;br /&gt;
Vorteile:&lt;br /&gt;
* I2C digital, PWM and SDM/analog Volt Ausgabe&lt;br /&gt;
* Maximal 5 Messungen/s @ 14bit&lt;br /&gt;
* Temperaturbereich von -40 – +125°C&lt;br /&gt;
* Feuchtigkeit mit einer Genauigkeit von +-3%RH&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
*  teuer (Farnell 23 €, Segor 29 €)&lt;br /&gt;
* nur als SMD-Package&lt;br /&gt;
&lt;br /&gt;
Application Notes und Datenblätter findet man [http://www.sensirion.com/en/01_humidity_sensors/10_Overview.htm hier].&lt;br /&gt;
&lt;br /&gt;
=== ADT7310 ===&lt;br /&gt;
&lt;br /&gt;
Der [http://www.analog.com/en/sensors/digital-temperature-sensors/adt7310/products/product.html ADT7310] von [http://www.analog.com/ Analog Devices] besitzt eine Auflösung von 16 Bit und eine Genauigkeit von ±0.5°C im Bereich von −40°C bis +105°C.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* Ansteuerung per [[SPI]] (für [[I2C]] siehe [http://www.analog.com/en/sensors/digital-temperature-sensors/adt7410/products/product.html ADT7410])&lt;br /&gt;
* keine Kalibrierung notwendig&lt;br /&gt;
* hohe [[Auflösung und Genauigkeit]]&lt;br /&gt;
* programmierbarer [[Interrupt]]ausgang für Unter- und Übertemperatur&lt;br /&gt;
* relativ günstig (ca. 3€ bei Digi-Key, Stand 12/2011)&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* TBD&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Sensorik]]&lt;br /&gt;
[[Category:Bauteile]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Elektronikversender&amp;diff=64130</id>
		<title>Elektronikversender</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Elektronikversender&amp;diff=64130"/>
		<updated>2012-02-09T23:19:12Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* Glyn (GLYNshop) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Die Vor- und Nachteile von verschiedenen Elektronik-Versand-Händlern werden relativ häufig im Forum diskutiert. Diese Diskussionen führen nicht selten zu weitestgehend gleichen Ergebnissen. In diesem Artikel sollen daher die Argumente, die für oder gegen einen bestimmten Elektronik-Versender sprechen, zusammengetragen werden. Sobald diese Liste einigermaßen vollständig ist, würde dies sicher einige Diskussions-Threads und/oder Flame-Wars überflüssig machen.&lt;br /&gt;
&lt;br /&gt;
Diese Liste erhebt keinerlei Anspruch auf Vollständigkeit, d.h. wenn ihr einen Versender kennt, der hier noch nicht aufgeführt ist, dann nennt wenigstens die URL und den Namen. Den Rest können auch andere besorgen, die den Versender ebenfalls kennen!&lt;br /&gt;
&lt;br /&gt;
Bitte ergänzt nur allgemeine Sachen (z.&amp;amp;nbsp;B. &amp;quot;liefert immer vollständig&amp;quot;, &amp;quot;günstig&amp;quot; oder &amp;quot;große Auswahl&amp;quot;), aber nicht Sachen wie &amp;quot;mein ATMega 128 hatte verbogene Beine&amp;quot;! Bitte auch die alphabetische Sortierung beibehalten!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Diese Seite kann nur von angemeldeten Benutzern bearbeitet werden!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Liste der Versender ==&lt;br /&gt;
&lt;br /&gt;
=== AATiS ===&lt;br /&gt;
Homepage: http://www.aatis.de&lt;br /&gt;
&lt;br /&gt;
* Arbeitskreis Amateurfunk und Technik in der Schule e.V.&lt;br /&gt;
* Bausätze speziell auch für Elektronik-Anfänger, Schüler&lt;br /&gt;
* Literatur, Seminare für Lehrer &lt;br /&gt;
&lt;br /&gt;
=== Actron ===&lt;br /&gt;
Homepage: http://www.actron.de&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;kein&#039;&#039;&#039; Online-Shop!&lt;br /&gt;
* alphanumerische LCDs und Graphikdisplays in großer Auswahl, auch mit Touchscreens&lt;br /&gt;
* für gewerbliche Kunden: etwas verhandeln schadet nie&lt;br /&gt;
* bei kleinen Stückzahlen nicht ganz billig&lt;br /&gt;
* liefern sehr schnell und stets zuverlässig&lt;br /&gt;
&lt;br /&gt;
=== Adapterprofi ===&lt;br /&gt;
Homepage: http://www.adapterprofi.de&lt;br /&gt;
&lt;br /&gt;
* Bauteile, Gehäuse, Netzteile&lt;br /&gt;
* Viele unterschiedliche HF-Adapter&lt;br /&gt;
* Seite aktuell nicht erreichbar (10.12.2011)&lt;br /&gt;
&lt;br /&gt;
=== AK Modul Bus Computer GmbH ===&lt;br /&gt;
Homepage: http://www.ak-modul-bus.com/stat/produkte.html&lt;br /&gt;
&lt;br /&gt;
* Interfaces, Messmodule, Funktionsmodelle, Experimentiersysteme&lt;br /&gt;
* Entwicklungssysteme, Baugruppen, Elektor, Zubehör, Bauelemente&lt;br /&gt;
* Software, Lernpakete, Bücher, Sonderposten&lt;br /&gt;
&lt;br /&gt;
=== Allpax ===&lt;br /&gt;
Homepage: http://www.allpax.de&lt;br /&gt;
&lt;br /&gt;
* Liefert auch an Privathaushalte&lt;br /&gt;
* Keine Elektronik an sich, aber ggf. nützliches Zubehör: Größeres, übersichtliches Sortiment an ESD-Beuteln und -Folien, offen und mit Zippverschluss, Pink Poly und Metallisiert (High Shield). Preislich über Farnell, dafür findet man sofort, was man sucht...&lt;br /&gt;
* außerdem Ultraschallreiniger, Waagen und Folienschweißgeräte, sowie viel Fachfremdes&lt;br /&gt;
* Versandkosten: 8,33€ nach Deutschland, diverse EU-Länder 17,85€, Schweiz 34,51€; Versandkostenfrei in D ab 178,50€&lt;br /&gt;
* Gewährt scheinbar auch Privatkunden die Zahlung per Rechnung; bei Bankeinzug 2% Rabatt, bei Vorkasse und Abholung 3%&lt;br /&gt;
&lt;br /&gt;
=== AME-Engineering ===&lt;br /&gt;
Homepage: http://www.ame-engineering.de&lt;br /&gt;
&lt;br /&gt;
* Hochfrequenz-Spezialitäten, Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Amidon ===&lt;br /&gt;
Homepage: http://www.amidon.de&lt;br /&gt;
&lt;br /&gt;
* Sehr großes Sortiment, vorallem für seltene Bauteile, z.&amp;amp;nbsp;B. Dioden&lt;br /&gt;
&lt;br /&gt;
=== Andy&#039;s Funkladen ===&lt;br /&gt;
Homepage: http://www.andyfunk.de&lt;br /&gt;
&lt;br /&gt;
* Alles für Amateur- und CB-Funk&lt;br /&gt;
* Bauteile und Gehäuse&lt;br /&gt;
&lt;br /&gt;
=== Anvilex ===&lt;br /&gt;
Homepage: http://shop.anvilex.com/index.html&lt;br /&gt;
&lt;br /&gt;
* Liefert sehr günstige Break-Out Boards für diverse Packages&lt;br /&gt;
* Hat einige einfache und günstige Programmer auch für FPGAs etc&lt;br /&gt;
&lt;br /&gt;
=== Atlantis Shop 24 ===&lt;br /&gt;
Homepage: http://www.atlantis-shop24.de&lt;br /&gt;
&lt;br /&gt;
* Elektronik nur ein kleiner Teil des Angebotes. Ansonsten eher Drogerie bzw. Haushaltsbedarf&lt;br /&gt;
&lt;br /&gt;
=== Atzert-Elektronik Versand ===&lt;br /&gt;
Homepage: http://www.atzert-elektronik.de&lt;br /&gt;
&lt;br /&gt;
Früher &#039;&#039;EFB-Electronic Versand&#039;&#039;, davor &#039;&#039;MEGAKICK Electronic Stores&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* Mindestens schon der dritte Name und die dritte Webseite für den Endkunden-Versand von [[Elektronikversender#ETT|ETT]]. ETT liefert sonst nur an gewerbliche Kunden.&lt;br /&gt;
* Ladengeschäfte in Bielefeld, Braunschweig, Bremen, Hamburg und Berlin. &lt;br /&gt;
* Die Preise schwanken im Vergleich zu anderen Anbietern, welche ebenfalls ETT-importierte Produkte führen, mal nach oben, mal nach unten.&lt;br /&gt;
&lt;br /&gt;
=== Bassenberg Elektronik ===&lt;br /&gt;
Homepage: http://www.bassenberg.de&lt;br /&gt;
&lt;br /&gt;
* Ladengeschäfte in Braunschweig und Neumünster&lt;br /&gt;
* Beschafft auch nicht mehr gelistete und abgekündigte Bauteile&lt;br /&gt;
* Liefert auch an Privat&lt;br /&gt;
&lt;br /&gt;
=== Batronix ===&lt;br /&gt;
Homepage: http://www.batronix.com&lt;br /&gt;
* Grosses Sortiment an Geräten&lt;br /&gt;
* Bausätze für Microcontroller-Applikationen&lt;br /&gt;
* Liefert auch an Privat&lt;br /&gt;
&lt;br /&gt;
=== BAZ Spezialantennen ===&lt;br /&gt;
Homepage: http://www.spezialantennen.de&lt;br /&gt;
&lt;br /&gt;
* Antennen für Amateurfunk, ISM, WLAN usw.&lt;br /&gt;
&lt;br /&gt;
=== Bfi-Optilas ===&lt;br /&gt;
Homepage: http://www.bfioptilas.de&lt;br /&gt;
&lt;br /&gt;
* Kein Onlineshop&lt;br /&gt;
* spezialisierter Distributor für Hochfrequenzhalbleiter und Optik&lt;br /&gt;
&lt;br /&gt;
=== BG-Electronics.de ===&lt;br /&gt;
Homepage: http://www.bg-electronics.de&lt;br /&gt;
&lt;br /&gt;
* Online Shop für aktive und passive elektronische Bauelememte&lt;br /&gt;
* günstige Preise&lt;br /&gt;
* alle Artikel ab Lager lieferbar, daher kurze Wartezeiten&lt;br /&gt;
* weltweiter Versand&lt;br /&gt;
* zahlreiche Mengenrabatte&lt;br /&gt;
* viele Ersatzteile aus dem Audio-, CarHiFi und TV-Bereich&lt;br /&gt;
&lt;br /&gt;
=== B &amp;amp; M electronics ===&lt;br /&gt;
Homepage: http://www.bmelectronics.de&lt;br /&gt;
&lt;br /&gt;
* Bauteile, Platinen und Baugruppen für Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Box73 ===&lt;br /&gt;
Homepage: http://www.box73.de&lt;br /&gt;
&lt;br /&gt;
Onlineshop des Funkamateur.&lt;br /&gt;
&lt;br /&gt;
* Bauteile, Bausätze, Literatur aus dem Amateurfunkbereich&lt;br /&gt;
* Preise sind O.K.&lt;br /&gt;
* Bestellungen werden nur Di und Do bearbeitet&lt;br /&gt;
* Ab 50 EUR bei Bankeinzug portofrei.&lt;br /&gt;
&lt;br /&gt;
=== Bürklin OHG ===&lt;br /&gt;
Homepage: http://www.buerklin.com&lt;br /&gt;
&lt;br /&gt;
* große Auswahl, hohe Verfügbarkeit&lt;br /&gt;
* sehr schneller Versand&lt;br /&gt;
* Ladengeschäft in München&lt;br /&gt;
* &amp;lt;s&amp;gt;nur an gewerbliche Abnehmer (lt. AGB), private Abnehmer können dennoch im Ladengeschäft einkaufen&amp;lt;br&amp;gt;Angeblich versendet Bürklin seit November 2010 auch an Privatpersonen. Allerdings verlangt Bürklin weiterhin in Adressformularen die Eingabe eines Firmennamens &amp;lt;br&amp;gt;Geben Sie einen Wert in das Feld &amp;quot;Firma&amp;quot; ein.&amp;lt;br&amp;gt;Daher ist diese Information eher mit Vorsicht zu genießen.&amp;lt;/s&amp;gt;&amp;lt;br&amp;gt;Mittlerweile muss man auch keinen Firmennamen mehr eingeben. Die AGB wurde ebenfalls angepasst.&lt;br /&gt;
* 35 EUR Mindestbestellwert, darunter 7 EUR Bearbeitungskosten (incl. MWSt)&lt;br /&gt;
&lt;br /&gt;
=== CBsoft, s.r.o. (ltd.) ===&lt;br /&gt;
*Homepage: http://www.jjtubes.eu/&lt;br /&gt;
* Firma in der Slowakei&lt;br /&gt;
* Verkauft Röhren der Firma JJ&lt;br /&gt;
* englischsprachig&lt;br /&gt;
* Zahlungsmöglichkeiten in € mit Paypal und Kreditkarte&lt;br /&gt;
&lt;br /&gt;
=== chiptrade.com ===&lt;br /&gt;
Homepage: http://www.chiptrade.com&lt;br /&gt;
* kein Onlineshop!&lt;br /&gt;
* Produkte von: Trinamic Motion Control, Datasphere/BlueSerial, connectBlue, Tectus RFID, Korenix, CentiPad, eye2m und Televideo&lt;br /&gt;
&lt;br /&gt;
=== ConeleK Electronic ===&lt;br /&gt;
Homepage: http://www.conelek.com&lt;br /&gt;
&lt;br /&gt;
* Sehr kleines Bauteileangebot (Röhren, Röhrensockel)&lt;br /&gt;
* Elektronik-Laborbedarf, insbesondere Nachfüllpackungen mit Steckbrett-Drahtbrücken&lt;br /&gt;
* Werkzeug für Elektronik&lt;br /&gt;
* Stromversorgungen&lt;br /&gt;
* Versand an Privat&lt;br /&gt;
* Versandkosten bis 25kg, Vorkasse 5,90€ (Stand 04/2008)&lt;br /&gt;
&lt;br /&gt;
=== Conrad ===&lt;br /&gt;
Homepage: http://www.conrad.de und http://www.business.conrad.de&lt;br /&gt;
&lt;br /&gt;
* großes Angebot (für Bauteile den &amp;quot;Business&amp;quot;-Katalog beachten, der Hauptkatalog ist dahingehend etwas &amp;quot;dünn&amp;quot;) (Anm.: Bauteile, die nur im Business-Katalog aufgeführt sind, sind in Ladengeschäften nur über Sonderbestellung zu bekommen, d.h. dort in aller Regel nicht vorrätig.)&lt;br /&gt;
* Positiv: Wirklich jedes Bauteil kann einzeln gekauft werden und wird nicht in dämlichen Verpackungseinheiten verkauft, so wie es bei den meisten anderen Elektronik-Lieferanten der Fall ist. Dies ist vor Allem für den Prototypenbau sehr hilfreich.&lt;br /&gt;
* relativ teuer jedoch bis zu 10% Rabatt für Schulen (bei genügend Umsatz)&lt;br /&gt;
* 21 Ladengeschäfte in Deutschland, fünf in Österreich&lt;br /&gt;
* positiv: Bei Business-Kunden wird der Rechnungsbetrag erst nach 14 Tagen abgebucht.&lt;br /&gt;
* haben einen (teuren) 24 Std. Lieferservice für Notfälle - Conrad garantiert aber nicht 100%ig für die Einhaltung der 24 Stunden. Bei Nichteinhaltung gibt es kein Geld zurück.&lt;br /&gt;
* Verfügbarkeit in Filialen kann Online überprüft werden.&lt;br /&gt;
* Verfügbarkeit in Filialen kann über zentale Rufnummer erfragt werden. Abholung bestellter Ware in Filialen möglich, aber trotzdem gleiche Versandkosten.&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
Vorerst Auskommentiert - Subjektiv/Einzelerfahrung, veraltete Informationen (Filialen)&lt;br /&gt;
* Mit jeder Bestellung erhält man zusätzlich Werbung von unseriösen Firmen, wo Gewinne versprochen werden und man sich in Wirklichkeit für irgendwelche Abos verpflichtet. Wenn man bei Conrad anruft und sie zur Rede stellt, erhält man die Antwort, dass diese Werbung anscheinend aus Versehen hineingerutscht ist. So ein Zufall.&lt;br /&gt;
* sehr kulant bei Umtäuschen&lt;br /&gt;
* versuchen bei Rückgaben einen Teil oder den gesamten Betrag einzubehalten (schon mehrfach vorgekommen)&lt;br /&gt;
* Schlampig verpackte Artikel. ICs sind nicht Antistatik-Konform verpackt.&lt;br /&gt;
* Die Filiale München / Tal hat keine Telefonnummer mehr in den Verzeichnissen, anscheinend sind Kundenanfragen dort zu &amp;quot;lästig&amp;quot;. (Kommentar: andere Filialen auch nicht, wird nur noch über eine Sammelnummer über ein Callcenter abgewickelt. Die Ladenbestellung wird dann vom Callcenter per eMail an die Filiale weitergeleitet.)&lt;br /&gt;
* die Ladengeschäfte haben nicht das gesamte Programm vor Ort, man kann jedoch in den Geschäften anrufen und die Verfügbarkeit anfragen, evtl. sogar Teile für ein paar Stunden &amp;quot;zurücklegen lassen&amp;quot; (von Geschäft zu Geschäft verschieden).&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== csd-electronics ===&lt;br /&gt;
Homepage: [http://www.csd-electronics.de csd-electronics.de]&lt;br /&gt;
&lt;br /&gt;
* ATMEL, ICs, Passive und Mechanische Bauteile, Platinen- und Lötzubehör, u.a.&lt;br /&gt;
* günstig&lt;br /&gt;
* Mengenrabatte für fast jedes Produkt&lt;br /&gt;
* Versand innerhalb Deutschlands pauschal 3,59€ (ab 100 EUR versandkostenfrei)&lt;br /&gt;
* Versand EU-weit ab 6,95 EUR&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* schnelle Lieferung, sofern die Artikel auf Lager sind, versandkostenfreie Nachlieferung&lt;br /&gt;
* Bauelemente, die nicht im Shop angeboten werden, können auf Anfrage beschafft werden.&lt;br /&gt;
* Zahlung bei Vorkasse(2% Skonto), Bankabbuchung, Kreditkarte, PayPal&lt;br /&gt;
* Ist man bereits Kunde, kann man &amp;quot;auf Rechnung&amp;quot; (Zahlung innerhalb von 21 Tagen) bestellen.&lt;br /&gt;
* haben ein Forum, in dem man sich zu Sammelbestellungen organisieren kann und auch allgemeine Fragen stellen kann -zur Zeit (05/2008) offline-&lt;br /&gt;
&lt;br /&gt;
=== dad24 ===&lt;br /&gt;
Homepage, Shop: http://dad24.eu&lt;br /&gt;
E-Bay Shop:     http://stores.ebay.de/Shop-dad24&lt;br /&gt;
&lt;br /&gt;
* Unterschiedliche Preise in den beiden Shops&lt;br /&gt;
* Kleiner, nicht sonderlich schöner Onlineshop (dad24.eu)&lt;br /&gt;
* Kleines Angebot. Lupenleuchten, Lötstationen, Labornetzgeräte, Messgeräte, etc. aus dem unteren Preissegment&lt;br /&gt;
* Jede Woche eine neue &amp;quot;Kategorie der Woche&amp;quot; auf dad24.eu. Produkte aus der Kategorie werden erst im Warenkorb mit einem Rabatt angezeigt, der auch gewährt wird.&lt;br /&gt;
&lt;br /&gt;
=== Darisus ===&lt;br /&gt;
Homepage: http://www.darisus.de&lt;br /&gt;
&lt;br /&gt;
* kompetente Beratung&lt;br /&gt;
* liefert sehr zuverlässig, in Notfällen auch Express&lt;br /&gt;
* Versand innerhalb Deutschlands ab 4,50 EUR&lt;br /&gt;
* Hat auch eine gute Auswahl an CPLDs und einige FPGAs diverser Hersteller&lt;br /&gt;
&lt;br /&gt;
=== Daschke LTD ===&lt;br /&gt;
PDF-Katalog (Achtung, grosse Datei): http://www.daschke-ltd.de/Catalog/&lt;br /&gt;
&lt;br /&gt;
* Prompte Antwort und Hilfe via info ät obige adresse&lt;br /&gt;
* Bezahlung per Paypal und Rechnung möglich. Ist auch Ebay-Händler.&lt;br /&gt;
* sehr faire Preise für Bauteile und Versand&lt;br /&gt;
* Führt eine Vielzahl an unüblichen Steckern und Buchsen&lt;br /&gt;
* Nicht verfügbare Bauteile wurden proaktiv nachbestellt, trotz geringer Bestellmenge. Prima!&lt;br /&gt;
&lt;br /&gt;
=== DES - Der Elektroniker-Shop ===&lt;br /&gt;
Homepage: http://www.DerElektronikerShop.de&lt;br /&gt;
&lt;br /&gt;
* Bauteile&lt;br /&gt;
* Bauteilsätze der [http://www.DieElektronikerseite.de Elektronikerseite]&lt;br /&gt;
* Verkauf des BasicBeetle und Zubehör von [http://www.DieProjektseite.de der Projektseite]&lt;br /&gt;
* Ständig wachsendes Angebot&lt;br /&gt;
* Auch einige SMD-Bauteile verfügbar&lt;br /&gt;
* Kein Mindestbestellwert&lt;br /&gt;
* Versandkosten ab 3,50 EUR (Österreich/Europa ab 4,00 Eur)&lt;br /&gt;
* Versand auch nach Österreich (Europa auf Anfrage)&lt;br /&gt;
* Zahlung per Vorkasse&lt;br /&gt;
* Lieferzeit 1-3 Tage bei Verfügbarkeit&lt;br /&gt;
* PrePaid-Konto möglich&lt;br /&gt;
* Lieferungen auch an Privat&lt;br /&gt;
&lt;br /&gt;
=== Digi-Key ===&lt;br /&gt;
(tlw.) deutsche Homepage: http://de.digikey.com&lt;br /&gt;
&lt;br /&gt;
* optisch nicht besonders ansprechende, aber durchaus sehr funktionelle Website&lt;br /&gt;
* beheimatet in den USA, ein Logistikbüro gibt es in den Niederlanden&lt;br /&gt;
* kostenloser Versand ab 65&amp;amp;#8364;, darunter 18&amp;amp;#8364; Versandkosten&lt;br /&gt;
* macht merkwürdige Plausibilitäts-Checks: wenn man privat über ihrem Dollar Limit (z.B. 400 Dollar bestellt) kommt sofort die Rückfrage nach Firmenname und Firmenadresse&lt;br /&gt;
* Rückfragen nach dem Verwendungszweck kommen ebenfalls schon bei der Bestellung bei bestimmten Bauteilen die der Exportkontrolle unterliegen&lt;br /&gt;
* Versand direkt aus den USA, dafür sehr flott mit UPS Express (in rund zwei bis drei Tagen da)&lt;br /&gt;
* riesiges Angebot, gewissermaßen ein Distributor der auch Kleinmengen an Privatpersonen liefert, entscheidend ist, dass der Hersteller des Produkts geführt wird&lt;br /&gt;
* kein anderer Anbieter, bietet so viele verschiedene passive Bauteile in kleinen Stückzahlen, z.&amp;amp;nbsp;B. SMD Widerstände in Bauform 01005 bis 2512 meist in verschiedenen Toleranzklassen und von verschiedenen Herstellern&lt;br /&gt;
* alle Bauteile mit Herstellerangabe, Digikey kauft ausschließlich direkt vom Hersteller&lt;br /&gt;
* Preise sind auf der deutschen Website in Euro inklusive etwaigem Zoll angegeben, allerdings ohne Mehrwertsteuer, die korrekt abgerechnet wird (d.h. man zahlt bei Versand nach Österreich 20% Mwst., nach Deutschland m.W.n. 19%)&lt;br /&gt;
* Meistens deutlich teurer als Reichelt, doch häufig die beste Anlaufstelle für Privatkunden wenn es um Spezialbauteile geht, und der Hersteller sich im Programm von Digikey befindet&lt;br /&gt;
&amp;lt;!-- * wesentlich teurer als Reichelt, dafür jeder Artikel mit Herstellerangabe&lt;br /&gt;
=&amp;gt; &amp;quot;wesentlich&amp;quot; etwas zu pauschal (vgl. STK500 etc. selbst bei den verglw. hohen Versandkosten) - mt --&amp;gt;&lt;br /&gt;
* Zu beachten ist auch noch folgendes, um unliebsame zusatzkosten zu vermeiden: http://www.mikrocontroller.net/topic/90943#new. &#039;&#039;Anmerkung dazu: Digikey hat wohl zum 1.4.2011 den Versand umgestellt und importiert nun selbst. Zusatzkosten durch Verzollung sollten dann nicht mehr anfallen.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Display Electronics ===&lt;br /&gt;
&lt;br /&gt;
Homepage: http://www.distel.co.uk&lt;br /&gt;
&lt;br /&gt;
* In England&lt;br /&gt;
* Webseite = Augenkrebs &lt;br /&gt;
* Online-Shop versteckt hinter dem Search-Button auf der Homepage&lt;br /&gt;
* Restposten aller Art&lt;br /&gt;
* Mindestbestellwert 10 GBP&lt;br /&gt;
&lt;br /&gt;
=== eHaJo ===&lt;br /&gt;
Homepage: http://www.eHaJo.de&lt;br /&gt;
&lt;br /&gt;
* Bausätze &lt;br /&gt;
* Lötübungen&lt;br /&gt;
* AVR-ISP-Stick&lt;br /&gt;
&lt;br /&gt;
=== Eisch-Kafka-Electronic ===&lt;br /&gt;
Homepage: http://www.eisch-electronic.de&lt;br /&gt;
 &lt;br /&gt;
* Hochfrequenz Bausätze und Bauteile für Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== EleConT ===&lt;br /&gt;
Homepage: http://www.elecont.de/shop/&lt;br /&gt;
&lt;br /&gt;
* Carrierboards für gebräuchliche AVR&lt;br /&gt;
&lt;br /&gt;
=== Electropuces ===&lt;br /&gt;
Homepage: http://perso.wanadoo.fr/electropuces/&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte aus Nantes, Frankreich  (teilweise engl. Menü)&lt;br /&gt;
&lt;br /&gt;
=== Electronic Search ===&lt;br /&gt;
&lt;br /&gt;
Homepage: http://www.electronic-search.de&lt;br /&gt;
&lt;br /&gt;
* Keine Mindestbestellmenge&lt;br /&gt;
* Verkauf auch an Privat/Bastler&lt;br /&gt;
* Fast alle Preise im Online-Shop nur &amp;quot;auf Anfrage&amp;quot;, und nicht im Shop angegeben.&lt;br /&gt;
&lt;br /&gt;
=== electronicpool Rheinstetten ===&lt;br /&gt;
Homepage: http://www.electronicpool.de&lt;br /&gt;
&lt;br /&gt;
* abgekündigte oder schwer beschaffbare elektronische Bauteile&lt;br /&gt;
&lt;br /&gt;
=== Elektronikladen ===&lt;br /&gt;
Homepage: http://www.elektronikladen.de&lt;br /&gt;
&lt;br /&gt;
* Spezialist für Mikrokontroller&lt;br /&gt;
* Entwicklungssysteme, keine Einzelbauteile&lt;br /&gt;
* entsprechende Literatur und Software&lt;br /&gt;
* &amp;quot;Kein Verkauf an Endverbraucher i.S.d. §13 BGB&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Elektronik-Kompendium ===&lt;br /&gt;
Homepage: http://www.elektronik-kompendium.de&lt;br /&gt;
&lt;br /&gt;
* Bausätze diverser Schaltungen (mit Anleitung und Funktionsbeschreibung)&lt;br /&gt;
* erspart lästiges Suchen in anderen Shops&lt;br /&gt;
* kurze Lieferzeiten&lt;br /&gt;
* günstiger Versand&lt;br /&gt;
&lt;br /&gt;
=== Elk Tronic ===&lt;br /&gt;
Homepage: http://www.elk-tronic.de&lt;br /&gt;
&lt;br /&gt;
* kleines Lieferprogramm Adapterplatinen (SMD -&amp;gt; 2,54mm-Raster) und Programmieradapter&lt;br /&gt;
* günstige Preise und Versandspesen&lt;br /&gt;
&lt;br /&gt;
=== Elko-Verkauf ===&lt;br /&gt;
Homepage: http://www.elko-verkauf.de&lt;br /&gt;
&lt;br /&gt;
* Nur Low-ESR-Elkos&lt;br /&gt;
* Elko-Sets für ein Gerät&lt;br /&gt;
&lt;br /&gt;
=== Ellmitron ===&lt;br /&gt;
Homepage: http://www.ellmitron.de/&lt;br /&gt;
Katalog: http://www.ellmitron.de/katalog.pdf&lt;br /&gt;
&lt;br /&gt;
Lehrmittel, Kleinbausätze vor allem für Schüler, Experimentierkästen&lt;br /&gt;
&lt;br /&gt;
=== Elpro Darmstadt ===&lt;br /&gt;
Homepage: http://www.elpro.org&lt;br /&gt;
&lt;br /&gt;
* Kein Mindestbestellwert, aber hohe Versandkosten für kleine Bestellungen. Stand September 2008:&lt;br /&gt;
** Bis 15€: 9,95€ Versandkosten&lt;br /&gt;
** Von €15 bis €75: 5,95€ Versandkosten&lt;br /&gt;
** Von €75 bis €200: 4,49€ Versandkosten&lt;br /&gt;
** Ab €200: Versandkostenfrei&lt;br /&gt;
* Große Auswahl an Mikrocontrollern&lt;br /&gt;
* Sehr große Auswahl an Schaltnetzteilen von Meanwell (geschlossen, offen, auf PCB lötbar, DIN-Schiene)&lt;br /&gt;
* Merkwürdig zu bedienende Shopsoftware, ständig klappt was auf und zu und wird irgendwas nachgeladen. Braucht JavaScript&lt;br /&gt;
* Keine AGBs online. Da Preisangaben ohne MwSt. richtet sich das Angebot vermutlich nicht an Endverbraucher (werden aber beliefert)&lt;br /&gt;
* Bearbeitungszeit (bis Warenausgang) 2-3 Tage.&lt;br /&gt;
* Versand bisher mit DHL&lt;br /&gt;
* gute bis sehr gute Verpackung&lt;br /&gt;
&lt;br /&gt;
=== Eltrix ===&lt;br /&gt;
Homepage: http://eltrix.de/Starteltrix.htm&lt;br /&gt;
&lt;br /&gt;
*  Verbrauchsmaterial, Tipps und Tricks fürs Leiterplattenherstellen und Löten&lt;br /&gt;
&lt;br /&gt;
=== ELV ===&lt;br /&gt;
Homepage: http://www.elv.de&lt;br /&gt;
&lt;br /&gt;
* nicht sehr große Auswahl an Einzelteilen&lt;br /&gt;
* riesiges Angebot an Zubehör für Hobbyisten&lt;br /&gt;
* viele z.T. pfiffige Eigenentwicklungen, Bausätze (auch zum Download auf der Website verfügbar)&lt;br /&gt;
* sonst Sortiment ähnlich Conrad, nicht billig&lt;br /&gt;
* im Allgemeinen nicht billig, merkwürdigerweise sind manche Artikel aber die günstigsten auf dem Markt&lt;br /&gt;
* mühsamer Onlinekatalog&lt;br /&gt;
* Immer mal wieder Fehllieferungen und Wartezeiten (zumindest in die Schweiz). Service erreichte in 3 Fällen nicht das inserierte Niveau.&lt;br /&gt;
* Versandkosten innerhalb Deutschland 4,5&amp;amp;#8364;, ab 150&amp;amp;#8364; Bestellwert versandkostenfrei&lt;br /&gt;
* nicht abwählbare Versandversicherung, die 0,85% des Bestellwertes kostet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Erklärte am 31. August 2010 &amp;quot;... den Betrieb bis auf weiteres zu schließen.&amp;quot; &lt;br /&gt;
=== Embedit Mikrocontrollertechnik ===&lt;br /&gt;
Online Shop: http://shop.embedit.de&lt;br /&gt;
&lt;br /&gt;
* Gute Auswahl an AVR Controllern, aber nur aktuelle Typen, keine AT90Sxxxx. Teilweise exotische Typen wie MLF Gehäuse&lt;br /&gt;
* Atmel und Philips SmartARM Controller&lt;br /&gt;
* Module und Boards mit AVR Controllern&lt;br /&gt;
* Zubehör von Atmel wie STK500 oder AVRISP mkII&lt;br /&gt;
* Diverse aktive und passive Elektronikteile, ständig neue Teile&lt;br /&gt;
* Mechanikteile wie Zahnräder, Steckverbinder usw.&lt;br /&gt;
* Lieferzeit 1-4 Tage, je nachdem wie man zahlt (hab aber auch schon ne Vorauskasse innerhalb eines Tages per Expressbrief bekommen, zuvorkommender Service)&lt;br /&gt;
* Versandkosten ab 3,95 &amp;amp;#8364;, versicherter Versand, Vorauskasse und Nachnahme&lt;br /&gt;
* Keine Versandkosten ab 50 &amp;amp;#8364; Warenwert innerhalb Deutschlands, bei Zahlung per Vorauskasse und Lieferung per Hermes&lt;br /&gt;
* Lieferung in viele EU-Länder&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ETT - Electronic Toys Trading  ===&lt;br /&gt;
Homepage: http://www.ett-online.de&lt;br /&gt;
&lt;br /&gt;
* Großhandel nur für Gewerbekunden.&lt;br /&gt;
* Zweitshop [[Elektronikversender#Atzert-Elektronik_Versand|Atzert-Elektronik Versand]] (früher EFB-Electronic Versand, davor Megakick Electronic-Stores) für Endkunden.&lt;br /&gt;
* Ladengeschäft in Braunschweig für jedermann. Weitere Atzert Ladengeschäfte in Bielefeld, Bremen, Hamburg und Berlin.&lt;br /&gt;
* Eigentümer der Marken McCHECK®, McPower®, McVoice® und anderer, unter denen ETT importierte Messgeräte, Labornetzteile, usw. an Großkunden und Händler vertreibt. Diese sind unter oben genannten Marken dann in vielen Shops anderer Firmen für Endkunden zu finden, nicht nur bei Atzert. Preisvergleiche lohnen.&lt;br /&gt;
&lt;br /&gt;
=== Ettinger GmbH ===&lt;br /&gt;
Homepage: http://www.ettinger.de&lt;br /&gt;
&lt;br /&gt;
* Für gewerbliche Kunden&lt;br /&gt;
* Mechanische Komponenten (Gehäuse, Abstandshalter, Drehknöpfe, usw.)&lt;br /&gt;
* LEDs&lt;br /&gt;
* Gewöhnungsbedürftiger Online-Shop&lt;br /&gt;
&lt;br /&gt;
=== EVE ===&lt;br /&gt;
Homepage: http://www.eve.de&lt;br /&gt;
&lt;br /&gt;
* Zitat aus den AGBs:&lt;br /&gt;
::&#039;&#039;&amp;quot;Zu Bestellungen im Rahmen des Online-Handels sind nur durch uns autorisierte, d. h. zugelassene Käufer berechtigt. Wir gewähren nach erfolgreicher Zertifizierung – ohne hierzu verpflichtet zu sein – dem jeweiligen Käufer das nicht übertragbare, nicht exklusive Recht im Rahmen des Online-Handels Bestellungen uns gegenüber “auszubringen”.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:Dies darf man wohl getrost als Hinweis ansehen, dass Endverbraucher als Kunden nicht gewünscht sind.&lt;br /&gt;
* Versandhaus für elektronische Artikel in Emsdetten&lt;br /&gt;
* machen auch Kabelkonfektion&lt;br /&gt;
* Pb-freie Artikel markiert&lt;br /&gt;
&lt;br /&gt;
=== Farnell ===&lt;br /&gt;
Homepage: http://de.farnell.com&lt;br /&gt;
&lt;br /&gt;
* liefert nur an gewerbliche Abnehmer, Ausnahme sind Studenten und HTL-Schüler (Österreich, Farnell.at). Nachweis wird verlangt (Gewerbeschein oder Immatrikulation).&lt;br /&gt;
* Lieferungen an Privat:&lt;br /&gt;
:* Schweiz: Farnell Schweiz beliefert auch Privatkunden.&lt;br /&gt;
:* Deutschland: Über den Reseller [[#HBE_-_Heinz_B.C3.BCchner_Elektronik.2C_Messtechnik.2C_med._Elektronik_e.K.|HBE]] kann man Produkte aus dem Farnell-Sortiment zu bestellen.&lt;br /&gt;
:* Österreich: [[#Technik-Welt / Industrieshop.at|Technik-Welt / Industrieshop.at]]&lt;br /&gt;
* große Auswahl&lt;br /&gt;
* 12% Rabatt für Studenten und Lehreinrichtungen&lt;br /&gt;
* sehr schneller Versand, Ware ist in 99% aller Fälle am nächsten Tag da (UPS), fehlende Positionen werden relativ rasch versandkostenfrei nachgeliefert&lt;br /&gt;
* Versandkosten: Bestellung bis 49,99&amp;amp;#8364;: 7,95&amp;amp;#8364;;   50,- bis 149,99&amp;amp;#8364;: 5,95&amp;amp;#8364;;   ab EUR 150,- versandkostenfrei&lt;br /&gt;
* hat nach eigenen Aussagen umfangreichstes Sortiment an RoHS-konformen Bauteilen mit Suchfunktion im WWW&lt;br /&gt;
* leistungsfähige parametrische Suchfunktion / teils aber völlig nutzlos, da den Artikeln massenweise Tags fehlen, weswegen die Suchergebnisse unnötig eingeschränkt werden&lt;br /&gt;
* Datenblätter für die meisten Bauteile online&lt;br /&gt;
* Internetpräsenz fällt nachts oft aus (Hinweis auf angebliche geplante Wartungsarbeiten)&lt;br /&gt;
* Sortierfunktion wird bei der Suche ständig zurückgesetzt, im Warenkorb ist überhaupt keine sinnvolle Sortierung möglich&lt;br /&gt;
* Eigenwillige Preispolitik: Einiges sehr günstig, Anderes total überteuert&lt;br /&gt;
&lt;br /&gt;
=== Fibra-Brandt Zweibrücken ===&lt;br /&gt;
Homepage: http://www.fibra-brandt.com&lt;br /&gt;
&lt;br /&gt;
* lagert tausende veraltete und schwer zu findende elektronische Bauteile&lt;br /&gt;
* Halbleiter, IC&#039;s, Transistoren, Spulen und Kondensatoren.&lt;br /&gt;
* Sonderbeschaffung von abgekündigten Halbleitern.&lt;br /&gt;
&lt;br /&gt;
=== Fischer DK2FD ===&lt;br /&gt;
Homepage: http://www.dfe-online.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen für Hochfrequenzmesstechnik und Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Funkamateur Online-Shop ===&lt;br /&gt;
&lt;br /&gt;
Siehe [[Elektronikversender#Box73]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Futurelec ===&lt;br /&gt;
Homepage: http://www.futurlec.com&lt;br /&gt;
&lt;br /&gt;
* günstiger Versender aus Übersee&lt;br /&gt;
* viele Stamp-Boards&lt;br /&gt;
* LED Matrix-Module&lt;br /&gt;
&lt;br /&gt;
=== Geist Electronic-Versand GmbH ===&lt;br /&gt;
Homepage: http://www.geist-electronic.de&lt;br /&gt;
&lt;br /&gt;
* Liefern Bauteile für Elektor-Projekte&lt;br /&gt;
* D-78054 Villingen-Schwenningen&lt;br /&gt;
* Versandkosten: 5.40€&lt;br /&gt;
&lt;br /&gt;
=== Giga-Tech ===&lt;br /&gt;
Homepage: http://www.giga-tech.de&lt;br /&gt;
&lt;br /&gt;
* Spezialitäten für Hochfrequenz / Amateurfunk&lt;br /&gt;
* 68542 Heddesheim&lt;br /&gt;
&lt;br /&gt;
=== Grummes Elektronik ===&lt;br /&gt;
Homepage: http://www.grummes.de&lt;br /&gt;
&lt;br /&gt;
* Elektronikversender /CNC-Fräsmaschinen / Schrittmotorsteuerungen / Bauteile&lt;br /&gt;
* Homepage nicht aufrufbar (10.12.2011)&lt;br /&gt;
&lt;br /&gt;
=== Glyn (GLYNshop) ===&lt;br /&gt;
Homepage: https://www.glynshop.com/erp/welcome.do&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;B2B Shop&amp;quot; = nicht für Privatkunden&lt;br /&gt;
* Microcontroller, Evaluation Boards, TFT-Displays, LC-Displays, Memory Cards u.a.&lt;br /&gt;
&lt;br /&gt;
=== H-Tronic ===&lt;br /&gt;
Homepage: http://www.h-tronic.eu/index.php&lt;br /&gt;
&lt;br /&gt;
* Online-Shop einer Entwicklungsfirma, in dem neben Baugruppen und Geräten auch einige Bauelemente und Elektronikzubehör angeboten werden&lt;br /&gt;
* kleines Angebot&lt;br /&gt;
&lt;br /&gt;
=== Hallmanns Elektronik ===&lt;br /&gt;
Homepage: http://www.hallmanns.com &amp;lt;br&amp;gt;&lt;br /&gt;
Adresse: Bruno Hallmanns, Weierstraße 41, 52349 Düren&lt;br /&gt;
&lt;br /&gt;
* Elektronikhändler mit Ladenlokal und Versand&lt;br /&gt;
* Ladentypisches Sortiment (Bauteile, Geräte, PC, Funk, Hifi...)&lt;br /&gt;
&lt;br /&gt;
=== Hari Seligenstadt ===&lt;br /&gt;
Homepage: http://www.hari-ham.com&lt;br /&gt;
&lt;br /&gt;
* Bausätze, Ringkerne, Geräte für Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== HBE - Heinz Büchner Elektronik, Messtechnik, med. Elektronik e.K. ===&lt;br /&gt;
Homepage: http://www.hbe-shop.de/katalog/&lt;br /&gt;
&lt;br /&gt;
* Bezeichnet sich als &#039;&#039;[[#Farnell|Farnell]] Fachhändler&#039;&#039;, bei dem nichtgewerbliche Kunden aus dem Farnell-Sortiment bestellen können.&lt;br /&gt;
* Preise für Farnell-Produkte normalerweise Farnell Netto-Preis + MwSt.&lt;br /&gt;
* Mindestbestellwert 25,- € (netto), Mindermengenzuschlag 5,- € (Stand 06/2010)&lt;br /&gt;
* Versandkosten 4,75 € (netto), ab 75,- € (netto) versandkostenfrei (Stand 06/2010)&lt;br /&gt;
&lt;br /&gt;
=== Heho-Elektronik ===&lt;br /&gt;
Homepage: http://www.heho-elektronik.de&lt;br /&gt;
* Halbleiter / Bauteile, Sortimente, Handy - Akkus, VELLEMAN - Bausätze&lt;br /&gt;
* Aktuelles Angebot, Ladegeräte / Akkuladegeräte, Blei - Akkus&lt;br /&gt;
* Spannungswandler, Audio / Video / USB - Kabel, Netzwerk - Kabel&lt;br /&gt;
* 1-2 Arbeitstage für Waren ab Lager&lt;br /&gt;
* Porto + Verpackung pauschal Euro 4,50&lt;br /&gt;
* Mindestbestellwert von &amp;amp;#8364; 10,00&lt;br /&gt;
&lt;br /&gt;
=== Hinkel ===&lt;br /&gt;
Homepage: http://www.hinkel-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Von der Webseite &amp;quot;Unser Angebot richtet sich an Schulen, Behörden, Handel, Handwerk und Industrie.&amp;quot;&lt;br /&gt;
* Batterien&lt;br /&gt;
* Knopfzellen, spezielle KZH, die man sonst lang sucht, findet man hier&lt;br /&gt;
* Mindestbestellwert von 20&amp;amp;#8364;&lt;br /&gt;
* Standardversand innerhalb Deutschlands 5,80&amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== HN Electronic Components GmbH &amp;amp; Co. KG / Netzteilshop ===&lt;br /&gt;
Homepage gewerbliche Kunden: http://www.hn-electronic.de/homed/framed.html &amp;lt;br /&amp;gt;&lt;br /&gt;
Homepage Endkunden: http://www.netzteilshop.com/hnshop.html&lt;br /&gt;
&lt;br /&gt;
* Netzteile aller Art&lt;br /&gt;
* Lieferung an Endkunden nur per UPS Nachnahme.&lt;br /&gt;
* Mindestbestellmenge für Endkunden 25 €&lt;br /&gt;
&lt;br /&gt;
=== HW-Electronics ===&lt;br /&gt;
Homepage: http://www.hw-electronics.de &amp;lt;br&amp;gt;&lt;br /&gt;
Homepage EU: http://hw-electronics.eu/&lt;br /&gt;
&lt;br /&gt;
* Tauch- und Sprühätzanlagen&lt;br /&gt;
* Entwicklungsgeräte&lt;br /&gt;
* Belichtungsgeräte, Materialsätze zum Selbstbau von Belichtungsgeräten&lt;br /&gt;
&lt;br /&gt;
=== ID-Elektronik ===&lt;br /&gt;
Homepage: http://www.id-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Amateurfunk-Baugruppen&lt;br /&gt;
&lt;br /&gt;
=== IT-WNS ===&lt;br /&gt;
Homepage: http://www.it-wns.de&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Bauteile, Platinen, Bausätze&amp;quot; insbesondere mit ATMEGA und ENC28J60&lt;br /&gt;
* Bausätze zu Projekten aus dem Forum, z.&amp;amp;nbsp;B. USBprog, ChipBasic, Mikro-Webserver, Transistortester u.v.a.m.&lt;br /&gt;
* Atmega32/644 Experimentiersystem als Bausatz mit vielen Zusatzmodul-Bausätzen&lt;br /&gt;
* SD-Slots, RFID, Bluetooth-Module, AVR Mikrocontroller uvam.&lt;br /&gt;
* Bauelemente, die nicht im Shop angeboten werden, können auf Anfrage (Kontaktformular) beschafft werden &lt;br /&gt;
* günstige Preise und Versandkosten ab 1,90EUR, kein Mindestbestellwert&lt;br /&gt;
* schneller Versand, sofern die Artikel auf Lager sind, versandkostenfreie Nachlieferung&lt;br /&gt;
&lt;br /&gt;
=== Kabelscheune ===&lt;br /&gt;
Homepage: http://www.kabelscheune.de&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Direktversand von Elektromaterial und Multimediaprodukten&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Kelemen ===&lt;br /&gt;
Homepage: http://www.kelemenantennen.de/Kelemen-Shop/&lt;br /&gt;
&lt;br /&gt;
* Messgeräte, Antennen und Zubehör für den Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Kessler ===&lt;br /&gt;
Homepage: http://www.kessler-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* im Preis-Leistungsverhältnis mit Reichelt zu vergleichen (sprich: günstig)&lt;br /&gt;
* Sortiment kleiner als Reichelt und mit gewissen Abweichungen (z. B. andere FPGA und RAMs)&lt;br /&gt;
* oft lange Lieferzeiten&lt;br /&gt;
* Versandkosten innerhalb Deutschlands 4,95&amp;amp;#8364; bei Bankeinzug und 6,90&amp;amp;#8364; bei Nachnahme plus Nachnahmegebühren&lt;br /&gt;
* Der Download-Katalog ist von 2002! Online aktueller&lt;br /&gt;
&lt;br /&gt;
=== Klein-Electronic ===&lt;br /&gt;
Homepage: http://www.klein-electronic.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen zur Video- und 2,4GHz-Sendetechnik&lt;br /&gt;
&lt;br /&gt;
=== Konni-Antennen ===&lt;br /&gt;
Homepage: http://www.konni-antennen.de&lt;br /&gt;
&lt;br /&gt;
* Antennen für TV, Amateurfunk&lt;br /&gt;
* Zubehör, Einzelteile&lt;br /&gt;
&lt;br /&gt;
=== Köditz Nachrichtentechnik ===&lt;br /&gt;
Homepage: http://www.koeditz-nachrichtentechnik.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen und Bauteile für Amateurfunk und TV-Satellitenempfang&lt;br /&gt;
&lt;br /&gt;
=== Kuhne DB6NT ===&lt;br /&gt;
Homepage: http://www.kuhne-electronic.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen und Bausätze für Mikrowellenamateure&lt;br /&gt;
&lt;br /&gt;
=== LEDSEE Electronics ===&lt;br /&gt;
Homepage: http://www.ledsee.com&lt;br /&gt;
&lt;br /&gt;
* LEDs, LCDs, diverses&lt;br /&gt;
* Lieferung direkt aus China, daher sehr günstig und lange Lieferzeiten&lt;br /&gt;
&lt;br /&gt;
=== LED Microtechnics LTD ===&lt;br /&gt;
Homepage: http://www.ledmeile.de&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;LED Shop und Lampentechnik&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== LED-Tech LED-Shop ===&lt;br /&gt;
Homepage: http://www.led-tech.de&lt;br /&gt;
&lt;br /&gt;
* viele verschiedene LEDs zu sehr guten (meist den günstigsten) Preisen&lt;br /&gt;
* vor allem auf High-Power-LEDs spezialisiert&lt;br /&gt;
* viele verschiedene Treiber für High-Power-LEDs&lt;br /&gt;
* kostenloser Versand&lt;br /&gt;
* haben ein eigenes, sehr umfangreiches Forum&lt;br /&gt;
&lt;br /&gt;
=== Lieske Elektronik ===&lt;br /&gt;
Homepage: http://www.lieske-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* liefert nur an Geschäftskunden&lt;br /&gt;
&lt;br /&gt;
=== LUMITRONIX LEDs-Shop ===&lt;br /&gt;
Homepage: http://www.leds.de&lt;br /&gt;
&lt;br /&gt;
* alles rund um LEDs (auch Zubehör und Lektüre)&lt;br /&gt;
* neben Standard-LEDs auch SMD- und SuperFlux-LEDs&lt;br /&gt;
&lt;br /&gt;
=== Marsch Elektronik, M. Schlimper ===&lt;br /&gt;
Homepage: http://www.marsch-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Online Shop für aktive und passive Bauelemente&lt;br /&gt;
* Versandkosten ab Euro 1,60&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* liefert nur innerhalb Deutschlands&lt;br /&gt;
* nicht gelistete Artikel können angefragt werden und werden meist auch beschafft&lt;br /&gt;
&lt;br /&gt;
=== Mein-Daarle ===&lt;br /&gt;
Homepage: http://www.mein-st-arnual.de/shop/saarbruecken/artikellisteL.html&lt;br /&gt;
&lt;br /&gt;
* Teileliste eines &amp;quot;Händlers aus Saarbrücken&amp;quot; (wahrscheinl.: Frank Skowronek ESS Elektronik Service), &amp;quot;bis sein Onlineshop ans Netz gehen kann&amp;quot;&lt;br /&gt;
* derzeit (4/2011) kein Onlineshop, Kontakt über Formular&lt;br /&gt;
&lt;br /&gt;
=== Micromaus ===&lt;br /&gt;
Homepage: http://www.micromaus.de&lt;br /&gt;
&lt;br /&gt;
* Sensoren&lt;br /&gt;
* Mikrokontroller&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
&lt;br /&gt;
=== Microcontroller-Starterkits ===&lt;br /&gt;
Homepage: http://www.microcontroller-starterkits.de&lt;br /&gt;
&lt;br /&gt;
* Bauteile: CAN, Ethernet, Mikrokontroller AVR und ARM, Linearregler 1,8V 3,3V 5V in SOT223&lt;br /&gt;
* Leerplatinen, Bausätze&lt;br /&gt;
* günstig&lt;br /&gt;
* Abholung in Hattingen möglich&lt;br /&gt;
* Versandkosten innerhalb Deutschlands ab 2,50&amp;amp;#8364;&lt;br /&gt;
* keine Kreditkartenzahlung möglich&lt;br /&gt;
&lt;br /&gt;
=== Mikrocontroller.net ===&lt;br /&gt;
Homepage: http://shop.mikrocontroller.net&lt;br /&gt;
&lt;br /&gt;
* Starterkits, Development Boards und Zubehör für AVR, AVR32, ARM und MSP430&lt;br /&gt;
&lt;br /&gt;
=== Mira Nürnberg ===&lt;br /&gt;
Homepage: http://www.mira-electronic.de&lt;br /&gt;
&lt;br /&gt;
* SMD-Bauteile, SMD-Sortimentboxen&lt;br /&gt;
* Verkauf und Preisangaben nur für Gewerbetreibende&lt;br /&gt;
&lt;br /&gt;
=== Karl Müller EME Messtechnik ===&lt;br /&gt;
Homepage: http://www.eme-hf-technik.de&lt;br /&gt;
&lt;br /&gt;
* Hochfrequenz-Messtechnik, HF-Komponenten&lt;br /&gt;
&lt;br /&gt;
=== Mouser ===&lt;br /&gt;
Homepage: http://de.mouser.com&lt;br /&gt;
&lt;br /&gt;
* Liefert an Privat&lt;br /&gt;
* Zügige Lieferung mit FedEx aus den USA&lt;br /&gt;
* Keine Halbleiter von Linear, National und Analog&lt;br /&gt;
&lt;br /&gt;
=== MS-Elektronik ===&lt;br /&gt;
Homepage: http://www.ms-elektronik.info&lt;br /&gt;
&lt;br /&gt;
* Liefert an Privat&lt;br /&gt;
* Zügige Lieferung&lt;br /&gt;
* Gute Qualität&lt;br /&gt;
* Viel in Richtung Audio&lt;br /&gt;
* Große Auswahl an Elkos -&amp;gt; kleine Preise&lt;br /&gt;
* kein allzu großes Sortiment&lt;br /&gt;
&lt;br /&gt;
=== Mütron ===&lt;br /&gt;
Homepage: http://www.muetronshop.de&lt;br /&gt;
&lt;br /&gt;
* Keine Privatkunden&lt;br /&gt;
&lt;br /&gt;
=== myAVR Shop ===&lt;br /&gt;
Hompage http://shop.myavr.de&lt;br /&gt;
&lt;br /&gt;
* Kleine Auswahl, aber die angebotene Ware ist sehr preiswert (meist preiswerter als bei Reichelt)&lt;br /&gt;
* Zügige Lieferung (1-2 Werktage)&lt;br /&gt;
* Diverse Zahlungsmöglichkeiten: Rechnung, Vorkasse, Lastschrift, Kreditkarte, PayPal&lt;br /&gt;
* Kein Mindestbestellwert&lt;br /&gt;
* Sehr günstige Versandkosten ab 1,95 Eur&lt;br /&gt;
* Mengenrabatt ab 10 gleichen Artikeln&lt;br /&gt;
&lt;br /&gt;
=== Neuhold-Elektronik ===&lt;br /&gt;
Homepage: http://www.neuhold-elektronik.at &amp;lt;br&amp;gt;&lt;br /&gt;
Shop: http://www.neuhold-elektronik.at/catshop/default.php?language=de&lt;br /&gt;
&lt;br /&gt;
* preiswerte Schnäppchen&lt;br /&gt;
* regelmäßig aktualisierte Angebotsliste herunterladbar&lt;br /&gt;
* Ab 60,- EUR versandkostenfrei in Österreich&lt;br /&gt;
&lt;br /&gt;
=== Octamex ===&lt;br /&gt;
Homepage: http://www.octamex.de&lt;br /&gt;
&lt;br /&gt;
* preiswerte Leiterplattenchemie &lt;br /&gt;
* Chemisch Zinn&lt;br /&gt;
* Ätzmittel Natriumpersulfat, Eisen-III-Chlorid&lt;br /&gt;
* Entwickler positiv und negativ&lt;br /&gt;
* Lötstopp-Laminat, Tentingresist, Bestückungsdruck&lt;br /&gt;
* Bungard Basismaterial in 0,5mm 1,0mm 1,5mm Dicke und 18µm, 35µm, 70µm Kupfer&lt;br /&gt;
* Bungard Alucorex für 19&amp;quot; Frontplatten&lt;br /&gt;
* Gehäuse aller Art&lt;br /&gt;
* Quarze in Industriequalität&lt;br /&gt;
* aktive und passive Halbleiter (Widerstände, Kondensatoren, Transistoren, Logik-ICs etc.)&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* Lieferung auch ins Ausland&lt;br /&gt;
* Versandkosten ab 2,55EUR&lt;br /&gt;
* Liefert nur gegen Vorkasse, ausser für Bestandskunden, die schon häufig bestellt haben&lt;br /&gt;
* Zahlung mit EC-Pay oder Kreditkarte nur gegen erheblichen Aufschlag (bis zu 5%)&lt;br /&gt;
&lt;br /&gt;
=== Online Batterien ===&lt;br /&gt;
Homepage: http://www.online-batterien.de&lt;br /&gt;
&lt;br /&gt;
* Allerlei günstige Batterien &amp;amp; Akkus vieler Marken&lt;br /&gt;
* z.&amp;amp;nbsp;B. &#039;&#039;&#039;40 Stk.&#039;&#039;&#039; DURACELL PLUS LR6 AA 11,59€ (Jan 2010)&lt;br /&gt;
* Beleuchtungsartikel&lt;br /&gt;
* USV&lt;br /&gt;
* Versand ab 3,90€&lt;br /&gt;
&lt;br /&gt;
=== Oppermann ===&lt;br /&gt;
Homepage: http://www.oppermann-electronic.de&lt;br /&gt;
&lt;br /&gt;
* Restposten, auch HF Bauteile&lt;br /&gt;
* auch Privatkunden&lt;br /&gt;
* Lieferung nach üblicher Zeit&lt;br /&gt;
&lt;br /&gt;
=== PCB-Soldering ===&lt;br /&gt;
&lt;br /&gt;
Homepage, Online-Shop: http://www.pcb-soldering.co.uk&lt;br /&gt;
eBay: http://www.allendale-stores.co.uk&lt;br /&gt;
Firmen-Homepage: http://www.allendale-elec.co.uk&lt;br /&gt;
&lt;br /&gt;
* [http://www.aoyue.com/en/products.asp Aoyue] Lötstationen und preiswertes Zubehör (Lötspitzen) für diese. Bei Aoyue-Zubehör bessere Preise (Stand 10/2008) als [[#WilTec_Wildanger_Technik_GmbH|WilTec]]&lt;br /&gt;
* Schnelle Lieferung&lt;br /&gt;
* Dank [http://www.zoll.de/b0_zoll_und_steuern/a0_zoelle/a1_grundlage_zollrecht/b0_zollgebiet/index.html EU Binnenmarkt] nur britische Mehrwertsteuer (VAT), kein Zoll, keine [http://www.zoll.de/b0_zoll_und_steuern/a3_einfuhrumsatzsteuer/index.html Einfuhrumsatzsteuer] fällig.&lt;br /&gt;
* Zwei von drei E-Mails wurden nicht beantwortet&lt;br /&gt;
* Versandart wurde eigenmächtig von &amp;quot;Standard&amp;quot; auf teureres &amp;quot;Signed for&amp;quot; (Einschreiben) geändert&lt;br /&gt;
&lt;br /&gt;
=== Pollin Electronic ===&lt;br /&gt;
Homepage: http://www.pollin.de&lt;br /&gt;
&lt;br /&gt;
* Günstige Restposten aller Art (z.&amp;amp;nbsp;B. &amp;quot;250 g verschiedene ICs&amp;quot; u.dgl.)&lt;br /&gt;
* Produktkategorien:&lt;br /&gt;
** Computer und Zubehör&lt;br /&gt;
** Telefone und Zubehör&lt;br /&gt;
** Antennentechnik&lt;br /&gt;
** HiFi/Car-HiFi/Video/TV&lt;br /&gt;
** Stromversorgung&lt;br /&gt;
** Lichttechnik&lt;br /&gt;
** Messtechnik / Uhren&lt;br /&gt;
** Haustechnik&lt;br /&gt;
** Werkstatt&lt;br /&gt;
** Bauelemente&lt;br /&gt;
** KFZ- und Zweirad&lt;br /&gt;
** Motoren&lt;br /&gt;
** Bausätze&lt;br /&gt;
** Fundgrube&lt;br /&gt;
* Produkte teils schnell ausverkauft &lt;br /&gt;
* Qualität schwankend. Man kann gute Schnäppchen machen aber auch reinfallen. Umtausch ist dann aber problemlos.&lt;br /&gt;
* Es wird öfters von sorgloser Verpackung berichtet, trotz Verpackungspauschale von 0,85 % des Warenwerts (empfindliche und schwere Produkte besser nicht zusammen bestellen). Reklamationen bei Beschädigungen werden freundlich behandelt.&lt;br /&gt;
* Lieferzeit i.d.r. 2-3 Werktage / knappe Woche bei neuer Sonderliste&lt;br /&gt;
* Ladengeschäft in 85104 Pförring&lt;br /&gt;
* Versandkosten  innerhalb Deutschlands 4,50 &amp;amp;#8364; (ab 150&amp;amp;#8364; versandkostenfrei); dazu 0,85 % Verpackungspauschale&lt;br /&gt;
* Zahlung per Nachnahme (+2,50 €) oder Bankeinzug (keine Kreditkarte, keine Überweisung)&lt;br /&gt;
&lt;br /&gt;
=== proma / Isel ===&lt;br /&gt;
Homepage: http://www.proma-technologie.com/deutsch/rundum_l/proma_fs_1.html&lt;br /&gt;
&lt;br /&gt;
* fotobeschichtete Leiterplatten Platinenfrästechnik&lt;br /&gt;
* Chemikalien für die Platinenherstellung: Ätzmittel, Flussmittel für Lötanlagen, etc.&lt;br /&gt;
* Profilgehäuse, u.a. von Conrad und Reichelt vertrieben&lt;br /&gt;
&lt;br /&gt;
=== QRP-project ===&lt;br /&gt;
Homepage: http://www.qrpshop.de/sitemap.htm&lt;br /&gt;
* Bausätze vor allem einfache Kurzwellen-Funkgeräte&lt;br /&gt;
&lt;br /&gt;
=== Reichelt ===&lt;br /&gt;
Homepage: http://www.reichelt.de&lt;br /&gt;
&lt;br /&gt;
* relativ große Auswahl, aber nicht viele &amp;quot;brandaktuelle&amp;quot; Bauteile&lt;br /&gt;
* wenn man höflich fragt, liefern sie ganz selten auch Bauteile, die nicht im Katalog stehen zu &amp;quot;normalen&amp;quot; Preisen (vorausgesetzt der Hersteller ist im Sortiment), z.&amp;amp;nbsp;B. Xilinx XC2S50, aber meist erhält man die Antwort, dass der Artikel nicht im Sortiment ist, obwohl auf der Homepage unter Service extra ein Punkt angeführt ist: &amp;quot;Ich benötige einen Artikel, der nicht im Programm ist&amp;quot;&lt;br /&gt;
* reagiert aber teilweise auch auf Anregungen, neue Produkte in das Angebot aufzunehmen; siehe dazu auch den Artikel [[Reichelt-Wishlist]]&lt;br /&gt;
* liefert schnell und vollständig; wenn etwas ausnahmsweise nicht verfügbar ist, dann liefern sie es auf eigene Kosten nach, wenn der Artikel in absehbarer Zeit wieder vorrätig ist (selbst wenn er nur 0,20€ wert ist).&lt;br /&gt;
* lässt einen dennoch manchmal warten, wenn ein Artikel nicht lieferbar ist! Daher bei der Bestellung immer darauf hinweisen, dass man auch eine Teillieferung akzeptiert. (Laut Auskunft dauert das länger, besser nach der Inet-Bestellung anrufen und nicht lieferbare Teile aus der Bestellung streichen lassen)&lt;br /&gt;
* Lieferzeiten normalerweise 2 - 4 Arbeitstage&lt;br /&gt;
* niedrige Preise (aber unbedingt Qualität des Artikel checken)&lt;br /&gt;
* Versandkosten 5,60€ (Deutschland); 10€ Österreich; Schweiz 16€; EU 15 - 19€;&lt;br /&gt;
* 10€ Mindestbestellwert für alle Länder&lt;br /&gt;
* auch in die Schweiz sehr guter Service&lt;br /&gt;
* holt sich auch ohne Erlaubnis Bankauskünfte bei großen Bestellungen ein&lt;br /&gt;
&lt;br /&gt;
=== RFW Elektronik ===&lt;br /&gt;
Homepage: http://www.rfw-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* HF Bauelemente&lt;br /&gt;
&lt;br /&gt;
=== Ribu ===&lt;br /&gt;
Homepage: http://www.ribu.at&lt;br /&gt;
&lt;br /&gt;
* Sehr guter Elektronikversand in Österreich mit zahlreichen Entwicklungsboards und zahlreichen Elektroniklösungen.&lt;br /&gt;
* Liefert sehr schnell und hat eine ausgezeichnete Beratung. &lt;br /&gt;
* Online-Shop ist sehr übersichtlich und einfach zu bedienen.&lt;br /&gt;
* Lieferstatusanzeige für alle Artikel. Bei Auslaufartikeln ist sogar die noch verfügbare Stückzahl sichbar.&lt;br /&gt;
* Günstige Sonderangebote&lt;br /&gt;
* innerhalb Österreichs 4,90&amp;amp;#8364; Versandkosten, ab 80,- keine Versandkosten&lt;br /&gt;
* ausserhalb Österreichs 13&amp;amp;#8364; Versandkosten, ab 225&amp;amp;#8364; versandkostenfrei&lt;br /&gt;
* liefert auch an Privatkunden&lt;br /&gt;
* Mindestbestellwert innerhalb Österreichs 10&amp;amp;#8364;, ausserhalb 30&amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== Richardson Electronic ===&lt;br /&gt;
Homepage: http://www.rell.com/international/index.asp?ID=GE&lt;br /&gt;
&lt;br /&gt;
* Hochfrequenz-Halbleiter, HF-Röhren,&lt;br /&gt;
&lt;br /&gt;
=== Riedl Elektronik ===&lt;br /&gt;
Homepage: http://www.riedl-electronic.at&lt;br /&gt;
&lt;br /&gt;
* großes Angebot v.a. ICs und Trafos&lt;br /&gt;
* recht günstig&lt;br /&gt;
* Rabatt für Schüler/Student&lt;br /&gt;
* Versand nach AT: 3,95€ bis 1kg, ab 100€ frei Haus&lt;br /&gt;
* Versand AT über 1kg sowie Ausland: Nach Aufwand (wird nicht direkt angezeigt)&lt;br /&gt;
&lt;br /&gt;
=== RLX COMPONENTS s.r.o. ===&lt;br /&gt;
Homepage: http://www.rlx.sk&lt;br /&gt;
&lt;br /&gt;
* Man spricht Deutsch&lt;br /&gt;
* Messgeräte, Mikrocontroller-Boards, Bauelemente&lt;br /&gt;
&lt;br /&gt;
=== RM Computertechnik GmbH ===&lt;br /&gt;
Homepage: http://www.rm-computertechnik.de&lt;br /&gt;
&lt;br /&gt;
* Kerngeschäft ist PC-Technik, aber auch großes Sortiment an Kabeln, Litzen und Steckverbindern&lt;br /&gt;
* handelt auch mit einigen Bauelementen, wie LED&#039;s&lt;br /&gt;
&lt;br /&gt;
=== Robotikhardware===&lt;br /&gt;
Homepage: http://www.robotikhardware.de&lt;br /&gt;
&lt;br /&gt;
* Microcontroller&lt;br /&gt;
* Entwicklungsboards&lt;br /&gt;
* Sensoren&lt;br /&gt;
* Robotik-Zubehör&lt;br /&gt;
* günstiges Angebote für Hobby-Elektroniker&lt;br /&gt;
* auch einzelne Platinen&lt;br /&gt;
&lt;br /&gt;
=== Benno Rößle Elektronik ===&lt;br /&gt;
Homepage: http://www.roessle-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Masten, Antennen, Befestigungsmat.,Zubehör, Geräte, Anpassteile, HF-Stecker&lt;br /&gt;
&lt;br /&gt;
=== RS Components ===&lt;br /&gt;
Homepage: http://de.rs-online.com&lt;br /&gt;
&lt;br /&gt;
* lt. AGB nur an gewerbliche Abnehmer, fragt bei Internetbestellungen aber nicht nach. Anm.: mitlerweile machen sie es doch.&lt;br /&gt;
* gute Auswahl insbesondere an &amp;quot;mechanischen Bauteilen&amp;quot;&lt;br /&gt;
* gute Verfügbarkeit&lt;br /&gt;
* sehr schneller Versand, Ware ist in 99% aller Fälle am nächsten Tag da (GP)&lt;br /&gt;
* Preise wurden angepasst, gute Preis/Leistung&lt;br /&gt;
* Preis im Onlineshop sind ohne MwSt angegeben&lt;br /&gt;
* Bei Onlinekauf ist der Versand kostenfrei, ohne Mindesbestellwert.&lt;br /&gt;
* Notify-Me Service für Produktabkündigung&lt;br /&gt;
* Auch größere Stückzahlen über Allied möglich&lt;br /&gt;
* Relativ große Auswahl an Sortimenten (Widerstände, Kondensatoren), Einzelteile können teilweise nachgekauft werden&lt;br /&gt;
* Verfügbarkeitsanzeige im Internet ist ziemlich hilfreich&lt;br /&gt;
* Nützliche Tipps zum Thema RoHS&lt;br /&gt;
&lt;br /&gt;
=== Sander Elektronik ===&lt;br /&gt;
Homepage: http://www.sander-electronic.de&lt;br /&gt;
&lt;br /&gt;
* beliefert auch Privatkunden, Bankeinzug möglich&lt;br /&gt;
* ähnlich Segor ein Berliner Versender&lt;br /&gt;
* Hier findet man manche [[MSP430]], die es sonst nicht in kleinen Stückzahlen gibt&lt;br /&gt;
* Herr Sander ist sehr kompetent und selbst Autor von Fachartikeln&lt;br /&gt;
* selbst abgekündigte Halbleiter können noch beschafft werden&lt;br /&gt;
* Bezahlung auch mit Kreditkarte möglich&lt;br /&gt;
* Versandkosten innerhalb Deutschlands ab 3,35&amp;amp;#8364;, innerhalb Europas ab 6&amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== Sasco Holz ===&lt;br /&gt;
Homepage: http://www.sasco.de&lt;br /&gt;
&lt;br /&gt;
* Wie Spoerle eine Tochter von Arrow. &lt;br /&gt;
* Distributor für Analog Devices... &lt;br /&gt;
* Liefert wie Spoerle und Arrow in Deutschland nicht an Privatkunden.&lt;br /&gt;
&lt;br /&gt;
=== Sat-Schneider ===&lt;br /&gt;
Homepage: http://www.sat-schneider.de&lt;br /&gt;
* Bauteile, Ersatzteile  Online-Shop&lt;br /&gt;
* Baugruppen zum Empfang des Digitalen Kurzwellenrundfunks DRM&lt;br /&gt;
&lt;br /&gt;
=== Otto Schubert GmbH ===&lt;br /&gt;
Homepage: http://www.schubert-gehaeuse.de&lt;br /&gt;
&lt;br /&gt;
* Kein Online-Shop. Bestellungen nur per Telefon, Fax oder E-Mail &lt;br /&gt;
* Weissblechgehäuse, Gerätegehäuse, wetterfeste Gehäuse&lt;br /&gt;
* Drehkondensatoren&lt;br /&gt;
* Sonderanfertigungen&lt;br /&gt;
&lt;br /&gt;
=== Schramm-Software ===&lt;br /&gt;
Homepage: http://www.schramm-software.de/bausatz/&lt;br /&gt;
* Online-Shop, bietet Elektronik-Bausätze mit Mikrocontrollern&lt;br /&gt;
* Bausätze als Lehrmaterial geeignet, da ausführliches Begleitheft mitgeliefert wird (Aufbauanleitung, Schaltung, Controllerprogramm, Experimente...)&lt;br /&gt;
* bisher nur ein relativ kleines Sortiment, soll ergänzt werden&lt;br /&gt;
* Versandkosten innerhalb Deutschlands 2,50 &amp;amp;#8364;, innerhalb der EU 3,50 &amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== Schukat elektronic ===&lt;br /&gt;
Homepage: http://www.schukat.de&lt;br /&gt;
&lt;br /&gt;
* liefert nicht an privaten Endverbraucher&lt;br /&gt;
* einfache und passiver Bauteile oft nur in großen Mindeststückzahlen&lt;br /&gt;
* ICs teilweise recht preiswert (vor allem bei mehr als 1 Stück, z.&amp;amp;nbsp;B. auch AVR)&lt;br /&gt;
* LCDs sehr preiswert und auch als Einzelstücke&lt;br /&gt;
* aktuelle Preise und Verfügbarkeit im Internet (aber nur nach Anmeldung -jetzt nicht mehr bei kleinen Stückzahlen), ebenso Bilder von Gehäusefootprints u.dgl.&lt;br /&gt;
* Abholung in Monheim am Rhein nach Vereinbarung möglich&lt;br /&gt;
* Versandkosten innerhalb Deutschlands ab 5&amp;amp;#8364; (bis 10kg!)&lt;br /&gt;
&lt;br /&gt;
=== Schuricht ===&lt;br /&gt;
Homepage: http://www.schuricht.de&lt;br /&gt;
&lt;br /&gt;
* deutscher Ableger der Distrelec- (Elektronik) und Disdata-Gruppe (Computertechnik)&lt;br /&gt;
* Liefert auch an Privatkunden (getrennte AGBs für gewerbliche und Privatkunden, Lieferung an Privat per Nachnahme: Versandkosten ab 6,54€ plus 4,76€ Nachnahmegebühr).&lt;br /&gt;
** Online-Bestellung von Privatkunde scheiterte daran, dass die  Onlineshop-Bestellformulare nur für gewerbliche Kunden ausgelegt sind und der Onlineshop Bestellungen ohne Firmenangaben nicht annimmt oder gar mit einer internen Fehlermeldung quittierte.&lt;br /&gt;
**Online Bestellung mit &amp;quot;Privat&amp;quot; als Firmenangabe funktionierte einwandfrei.&lt;br /&gt;
**Telefonische Bestellung von Privat funktioniert. Nette, freundliche Behandlung am Telefon, kein Callcenter. Versprochener Rückruf erfolgte mit gewünschten Informationen. Neben Nachnahme wurde für einen relativ teuren Artikel persönliche Abholung angeboten. Angegebene Lieferfrist wurde leicht unterschritten.&lt;br /&gt;
* Papierkatalog über 2000 Seiten, durchgehend farbig, nur für Geschäftskunden erhältlich.&lt;br /&gt;
* Ziemlich teuer&lt;br /&gt;
&lt;br /&gt;
=== Schuro Elektronik GmbH ===&lt;br /&gt;
Homepage: http://www.schuro.de&lt;br /&gt;
&lt;br /&gt;
* Elektronische Bauelemente und Bauteile für den Audio- und Lautsprecherbau (Kondensatoren, Spulen u.dgl.)&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* Versandkosten innerhalb Deutschlands gewichtsabhängig ab 5,75&amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== Segor-electronics ===&lt;br /&gt;
Homepage: http://www.segor.de&lt;br /&gt;
&lt;br /&gt;
* Spezialist für Halbleiter, die ansonsten für nicht-gewerbliche Abnehmer nur schwer erhältlich sind (Preise dahingehend &amp;quot;angemessen&amp;quot;)&lt;br /&gt;
* auch Privatkunden gerne gesehen&lt;br /&gt;
* Ladengeschäft in Berlin&lt;br /&gt;
* kein Mindestbestellwert bei Versand innerhalb der EU&lt;br /&gt;
&lt;br /&gt;
=== SE Spezial-Electronic AG ===&lt;br /&gt;
Homepage: http://www.spezial.de&lt;br /&gt;
&lt;br /&gt;
* Distributor&lt;br /&gt;
* Laut AGB auch Verkauf an Privat.&lt;br /&gt;
* Große Verpackungseinheiten/Mindestbestellmengen pro Bauteil&lt;br /&gt;
* Versandkosten pauschal 9,- €  (Deutschland) (Stand 08/2008)&lt;br /&gt;
&lt;br /&gt;
=== Shortec Electronics ===&lt;br /&gt;
Homepage: http://www.shortec.com&lt;br /&gt;
&lt;br /&gt;
* Unabhängiger Distributor von elektronischen und elektromechanischen Bauelementen aller Hersteller.&lt;br /&gt;
&lt;br /&gt;
=== Small Control Shop ===&lt;br /&gt;
Homepage: http://www.small-control.de&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Bernd Walter Computer Technology&amp;quot;&lt;br /&gt;
* kleines Lieferprogramm aber ein paar interessante Produkte&lt;br /&gt;
&lt;br /&gt;
=== SMG Diffusion - F1GE ===&lt;br /&gt;
Homepage: http://www.smgdiffusion.com&lt;br /&gt;
( Seite nur französisch )&lt;br /&gt;
&lt;br /&gt;
* Videotechnik, &lt;br /&gt;
* 1,2 GHz / 2,4GHz Module&lt;br /&gt;
* Gebraucht-Messgeräte HP, Tek, Philips  u.a.&lt;br /&gt;
* GHz-Halbleiter&lt;br /&gt;
* Koax-Adapter&lt;br /&gt;
* Antennen&lt;br /&gt;
&lt;br /&gt;
=== Spoerle ===&lt;br /&gt;
Homepage: http://www.spoerle.de&lt;br /&gt;
&lt;br /&gt;
* Früher eine Tochterfirma von Arror. Mittlerweile komplett in Arrow aufgegangen, Webseite leitet auf Arrow um.&lt;br /&gt;
* Aus dem Webshop: &amp;quot;Unser Angebot richtet sich nur an Kaufleute und nicht an Verbraucher.&amp;quot;&lt;br /&gt;
* Wenn es wirklich über Arrow sein muss, dann kann man es als Privatperson bei Arrow Electronics North American Components http://www.arrownac.com/ versuchen, die sich normalerweise nicht weigern ihre Produkte zu verkaufen. Allerdings muss man mit großen Mindestmengen (z.&amp;amp;nbsp;B. BC547 in Schritten von 2000 Stück) und hohen Kosten rechnen.&lt;br /&gt;
:Zu den Kosten gehören zum Beispiel ein mehrfacher Mindermengenzuschlag (&#039;&#039;$10 handling charge will be added to each line item less than $30&#039;&#039;), eine satte &#039;&#039;handling and energy fee of $10.22&#039;&#039; (mehr als 10x zu hoch wie die vergleichbare Gebühr für amerikanische Besteller), hohe Versandkosten (ab $20 nach Deutschland). Dazu kommen die üblichen Kosten für den Import aus dem Ausland (Einfuhrumsatzsteuer, Kreditkartengebühr, ...)&lt;br /&gt;
&lt;br /&gt;
=== SR-Systems ===&lt;br /&gt;
Homepage: http://www.sr-systems.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen für Digital-TV, Sende- und Empfangstechnik&lt;br /&gt;
* DVB-S, DVB-T&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Strixner&amp;amp;Holzinger ===&lt;br /&gt;
Homepage: http://www.sh-halbleiter.de&lt;br /&gt;
&lt;br /&gt;
* Ladengeschäft in München&lt;br /&gt;
* Versand &lt;br /&gt;
* riesiges Angebot an Halbleiter, auch schwer beschaffbare&lt;br /&gt;
* Online-Shop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== TAUTEC-ELECTRONICS ===&lt;br /&gt;
Homepage: http://www.tautec-electronics.de&lt;br /&gt;
&lt;br /&gt;
* Online Shop für aktive elektronische Bauelemente&lt;br /&gt;
* günstige Preise (Vorsicht, Preisangaben enthalten keine Mehrwertsteuer) aber Mindestbestellwert 100 Euro&lt;br /&gt;
* alle Artikel ab Lager lieferbar, daher kurze Wartezeiten&lt;br /&gt;
* weltweiter Versand&lt;br /&gt;
* zahlreiche Mengenrabatte&lt;br /&gt;
* viele Ersatzteile aus dem Audio-, Car-HiFi und TV-Bereich&lt;br /&gt;
&lt;br /&gt;
=== TCB-Versand ===&lt;br /&gt;
Homepage: http://www.tcb-versand.de&lt;br /&gt;
&lt;br /&gt;
* insbesondere für Modellbauer ein sehr interresantes Sortiment&lt;br /&gt;
* Stecker,Kabel etc. recht günstig und kleine Mengen abnehmbar &lt;br /&gt;
* Lieferung normal zwischen 1 und 3 Tage&lt;br /&gt;
* leider nur Online-Shop&lt;br /&gt;
&lt;br /&gt;
=== Tec-Shop (Wolfgang Rompel Elektronik) ===&lt;br /&gt;
Homepage: http://www.tec-shop.de&lt;br /&gt;
&lt;br /&gt;
* Kleines, aber ausgesuchtes Sortiment&lt;br /&gt;
* Interessantes Angebot an Sensoren&lt;br /&gt;
&lt;br /&gt;
=== Technik-Welt / Industrieshop.at ===&lt;br /&gt;
Homepage: http://www.industrieshop.at&lt;br /&gt;
&lt;br /&gt;
* Laut Homepage richtet man sich &amp;quot;an den industriellen Kunden&amp;quot;. Laut AGB sieht man das jedoch nicht so eng, Zitat:&lt;br /&gt;
:: &#039;&#039;TW schließt online Verträge nur mit Kunden ab, die natürliche oder juristischen Personen sind, die ihren Wohnsitz oder Sitz in Österreich, einem Mitgliedsstaat der Europäischen Union (EU25) oder der Schweiz haben.&#039;&#039;&lt;br /&gt;
* [[#Farnell|Farnell]] Teile&lt;br /&gt;
* In Österreich&lt;br /&gt;
* Schnelle Lieferung (2 Tage)&lt;br /&gt;
&lt;br /&gt;
=== TIGAL KG ===&lt;br /&gt;
Homepage: http://www.tigal.com&lt;br /&gt;
&lt;br /&gt;
* Boards und Tools für Embedded-Elektronik&lt;br /&gt;
* In Österreich &lt;br /&gt;
* Versandkosten ab € 7,00 in Österreich, ab € 10,00 nach Deutschland.&lt;br /&gt;
* Preisangaben ohne MWSt. Für Privatkunden kommen 20% österreichische Mehrwertsteuer hinzu.&lt;br /&gt;
* U.a. ZeroLogic Logik-Analysatoren.&lt;br /&gt;
&lt;br /&gt;
=== TME (Transfer Multisort Elektronik) ===&lt;br /&gt;
Homepage: [http://www.tme.pl/index.phtml?lang=de www.tme.pl]&lt;br /&gt;
&lt;br /&gt;
* Firmensitz in Łódź, Polen&lt;br /&gt;
* Zahlungsabwicklung über deutsches Konto&lt;br /&gt;
* als Privatkunde: Mehrwertsteuer beachten (22%)&lt;br /&gt;
* sehr großes günstiges SMD Sortiment&lt;br /&gt;
&lt;br /&gt;
=== Trade-Shop / AIR Electronics GmbH ===&lt;br /&gt;
Homepage: http://www.trade-shop.de&lt;br /&gt;
&lt;br /&gt;
* Trotz knackiger Sprüche auf der englischen Version der Webseite (&amp;quot;Electronic Components Superstore&amp;quot;) eher kleines Angebot elektronischer Bauteile&lt;br /&gt;
* 20 Euro Mindestbestellmenge (Stand Februar 2008)&lt;br /&gt;
* ab 6,90 Euro Versandkosten (Deutschland, bis 1kg)  (Stand Februar 2008)&lt;br /&gt;
&lt;br /&gt;
=== Trenkenchu &amp;amp; Stadler GbR ===&lt;br /&gt;
Homepage: http://www.ts-audio.de&lt;br /&gt;
&lt;br /&gt;
* die meisten Artikel sind deutlich teurer als der Marktpreis, nur bei exotischen Bauelementen kann man durchaus ein Schnäppchen machen&lt;br /&gt;
&lt;br /&gt;
=== TV-Ersatzteile ===&lt;br /&gt;
Homepage: http://www.tversatzteile.de&lt;br /&gt;
&lt;br /&gt;
* TV-, Audio-, Video-Ersatzteile, Aktive / Passive Bauteile&lt;br /&gt;
* Fernbedienungen Haushaltstechnik&lt;br /&gt;
&lt;br /&gt;
=== UKW-Berichte ===&lt;br /&gt;
Homepage: http://www.ukw-berichte.de&lt;br /&gt;
&lt;br /&gt;
* Antennen, Bauteile, Bausätze, Literatur für Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Voelkner ===&lt;br /&gt;
Homepage: Kein Link, entsprechend der Vorgabe des Betreibers der Voelkner Webseite im Impressum:&lt;br /&gt;
&amp;lt;i&amp;gt;&amp;lt;blockquote&amp;gt;voelkner - direkt günstiger&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
wird produziert und betreut von&amp;lt;br/&amp;gt;&lt;br /&gt;
Re-In Retail International GmbH &amp;lt;br/&amp;gt;&lt;br /&gt;
...&amp;lt;br/&amp;gt;&lt;br /&gt;
Eine Verlinkung auf die Website der Firma Re-In Retail International GmbH bedarf einer schriftlichen Genehmigung. &amp;lt;/blockquote&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Großer Teil des Conrad-Programms, identische Nummern, identische Aufkleber auf der Ware, Preise identisch oder nur ein paar Cent abweichend&lt;br /&gt;
* Versandkosten Deutschland: 4,95€; ab 25€ Warenwert und Sofortüberweisung.de versandkostenfrei / Versandkosten-Flatrate für 15€ pro Jahr&lt;br /&gt;
* Versandkosten EU: 9,95€&lt;br /&gt;
* Möglichkeit der Versandkostenflatrate (D): Einmalig 9,95€ / gültig für ein Jahr&lt;br /&gt;
* Legt jeder Bestellung gleich wieder einen Gutschein über 5€ bei MBW 25€ bei (Flat nur bei häufigen, kleinen Bestellungen sinnvoll); außerdem kommt etwa alle 2-3 Monate selbiger Gutschein + versandkostenfreie Lieferung per Mail, ebenfalls MBW 25€&lt;br /&gt;
* Verpackungsqualität wechselnd, mal brauchbar, mal eher Pollin-Niveau. Selbst kleine Bestellungen, die gefahrlos per Brief/Großbrief verschickt werden könnten werden in einem großen Paket versendet.&lt;br /&gt;
&lt;br /&gt;
=== VOTI Webshop ===&lt;br /&gt;
Homepage: http://www.voti.nl/shop/catalog.html&lt;br /&gt;
&lt;br /&gt;
* relativ kleines Lieferprogramm&lt;br /&gt;
* einige interessante Restposten (Surplus)&lt;br /&gt;
&amp;lt;!-- nicht mehr: * verkauft auch VID/PID-Paare für USB-Applikationen --&amp;gt;&lt;br /&gt;
* Sitz in Amersfoort, Niederlande&lt;br /&gt;
&lt;br /&gt;
=== Walter elektronik ===&lt;br /&gt;
Homepage: http://www.walter-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Bauteile, Röhren&lt;br /&gt;
&lt;br /&gt;
=== Watterott electronic GmbH===&lt;br /&gt;
Homepage: http://www.watterott.com&lt;br /&gt;
&lt;br /&gt;
* Distributor für Arduino, BeagleBoard, FriendlyARM, Pololu, Seeed Studio, Solarbotics, SparkFun...vollständige [http://www.watterott.net/about#distri Liste hier]&lt;br /&gt;
* Entwicklungskits von Atmel, Luminary Micro, Microchip, Raisonance, TI&lt;br /&gt;
* Spezialbauteile von Davicom, FTDI, VLSI, WIZnet&lt;br /&gt;
* Bungard Basismaterial + Chemie&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* Zahlung: Vorkasse, Sofortüberweisung, PayPal, Nachnahme, Kreditkarte (Visa/Mastercard), Rechnung (nur gewerbliche Kunden)&lt;br /&gt;
* Versandkosten Dtl. (UPS): &lt;br /&gt;
** bis  25 EUR Warenwert: 3,50 Euro&lt;br /&gt;
** bis  50 EUR Warenwert: 2,90 Euro&lt;br /&gt;
** bis 150 EUR Warenwert: 2,00 Euro&lt;br /&gt;
** ab  150 EUR Warenwert: versandkostenfrei&lt;br /&gt;
* Versandkosten EU (UPS): &lt;br /&gt;
** bis 150 EUR Warenwert: 10,00 Euro&lt;br /&gt;
** bis 250 EUR Warenwert:  8,90 Euro&lt;br /&gt;
** bis 500 EUR Warenwert:  7,00 Euro&lt;br /&gt;
** ab  500 EUR Warenwert:  versandkostenfrei&lt;br /&gt;
* Schneller, entgegenkommender Service&lt;br /&gt;
&lt;br /&gt;
=== Westfalia ===&lt;br /&gt;
Homepage Deutschland: http://www.westfalia.de&lt;br /&gt;
Homepage Österreich: http://www.westfalia-versand.at&lt;br /&gt;
&lt;br /&gt;
* Vor 85 Jahren in Hagen, Westfalen gegründet&lt;br /&gt;
* Elektronik nur ein kleiner Teil des Angebotes. Eher insgesamt Haushalts-, Werkstätten-, Agrar- und Gartenbedarf&lt;br /&gt;
* Elektroniksortiment stark schwankend. Momentan (Juni 2008) wenig Auswahl.&lt;br /&gt;
* Mindestbestellwert 18 €, bei Neukundenbestellungen mit Prämienanforderungen (wenig wertiges Geschenk) sogar 50 €.&lt;br /&gt;
* 4,95&amp;amp;#8364; Versandkosten, ab 150&amp;amp;#8364; Bestellwert versandkostenfrei&lt;br /&gt;
* Transportversicherung wird zusätzlich mit einem Zuschlag von 0,8% des Warenwertes berechnet.&lt;br /&gt;
* Einmalige Bestellung führte zu jahrelanger Zusendung von Werbung für Westfalia-Angeboten mit Gewinnspielen (Glücksnummern, Rubbellose, Glücksschlüssel, etc.)&lt;br /&gt;
* Verpackung ähnlich &amp;quot;sorgfältig&amp;quot; wie bei [[#Pollin_Electronic|Pollin Electronic]]. Übergroße Kartons, wenig Verpackungsmaterial, schweres Teil (Labornetzgerät) flog lose im Karton herum und zertrümmerte andere Ware.&lt;br /&gt;
&lt;br /&gt;
=== WilTec Wildanger Technik GmbH ===&lt;br /&gt;
Homepage: http://shop.wiltec.info&lt;br /&gt;
&lt;br /&gt;
* Aoyue Lötgeräte (Heißluft, Löten, Entlöten), Netzteile, Werkzeuge&lt;br /&gt;
* Aoyue Zubehör (Lötspitzen, Heißluftdüsen), Ersatzteile&lt;br /&gt;
* Andere, nicht Elektronik-Angebote, wie KFZ-Tuningteile&lt;br /&gt;
* Versand. Bei Voranmeldung auch Lagerverkauf.&lt;br /&gt;
&lt;br /&gt;
=== Wüstens frag-jan-zuerst ===&lt;br /&gt;
Homepage: http://www.die-wuestens.de/dindex.htm&lt;br /&gt;
&lt;br /&gt;
* Röhrentechnik&lt;br /&gt;
* Hochspannungs-Spezialteile&lt;br /&gt;
&lt;br /&gt;
=== WIMO ===&lt;br /&gt;
Homepage: http://www.wimo.de&lt;br /&gt;
&lt;br /&gt;
* Große Auswahl an Amateurfunktechnik&lt;br /&gt;
&lt;br /&gt;
=== Zech DG0VE ===&lt;br /&gt;
Homepage: http://www.dg0ve.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen für Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Diverse ===&lt;br /&gt;
* http://www.chip-flip.com - Europäisches Bauelementesuchsystem, franchised Lieferantensuche, Datenblätter und viele nützliche Informationen&lt;br /&gt;
* http://www.ecomponents-store.com/ Elektronische Bauelemente kaufen - Hier finden Sie eine große Auswahl an elektronischen und elektromechanischen Bauelementen von über 40 Herstellern.&lt;br /&gt;
* http://www.franchised-distributors.eu/ - Finden Sie Vertragsdistributoren von über 800 Halbleiterherstellern für elektronische und elektromechanische Bauelemente.&lt;br /&gt;
&lt;br /&gt;
TODO: elektronik-fundgrube&lt;br /&gt;
&lt;br /&gt;
==Messgeräte ==&lt;br /&gt;
=== Neue Messgeräte ===&lt;br /&gt;
&lt;br /&gt;
Viele der oben genannten Elektronikversender verkaufen auch Messgeräte. Darüber hinaus gibt es diverse Versender, die sich hauptsächlich oder ausschließlich auf Messgeräte spezialisiert haben. Allerdings verkaufen viele davon nicht an Privat.&lt;br /&gt;
&lt;br /&gt;
==== CalPlus GmbH ====&lt;br /&gt;
Homepage: http://www.calplus.de &amp;lt;br /&amp;gt;&lt;br /&gt;
Shop: http://www.scopeshop.de&lt;br /&gt;
&lt;br /&gt;
==== Cosinus ComputerMesstechnik ====&lt;br /&gt;
Homepage: http://www.cosinus.de&lt;br /&gt;
&lt;br /&gt;
* Nicht an Privat&lt;br /&gt;
&lt;br /&gt;
==== dataTec ====&lt;br /&gt;
Homepage: http://www.datatec.de&lt;br /&gt;
&lt;br /&gt;
* Große Auswahl&lt;br /&gt;
* (Nicht an Privat) Bestellung von Privat problemlos möglich (11/2011)&lt;br /&gt;
* Studenten bekommen Rabatt, je nach dem, was bestellt wird&lt;br /&gt;
* Umständlicher Bestellvorgang, seitens DataTec teilweise auf dem Postweg -&amp;gt; Es dauert teil sehr lange bis die Ware ankommt&lt;br /&gt;
* Sehr freundlicher und kompetenter Service, per eMail als auch telefonisch&lt;br /&gt;
&lt;br /&gt;
==== Donald4646 ====&lt;br /&gt;
Homepage: http://www.donald4646.co.uk&lt;br /&gt;
&lt;br /&gt;
* In Schottland&lt;br /&gt;
* Als eBay-Shop gestartet&lt;br /&gt;
* Einfache, No-Name und Billigmarken (z.&amp;amp;nbsp;B. Oszilloskope)&lt;br /&gt;
&lt;br /&gt;
==== Elektronik-Kontor Messtechnik GmbH ====&lt;br /&gt;
Homepage: http://www.ekomess.de&lt;br /&gt;
&lt;br /&gt;
==== Meilhaus Electronic GmbH ====&lt;br /&gt;
Homepage: http://www.meilhaus.de&lt;br /&gt;
&lt;br /&gt;
* Diverse Markenhersteller&lt;br /&gt;
* Eigenmarken&lt;br /&gt;
&lt;br /&gt;
==== PinSonne-Elektronik ====&lt;br /&gt;
Homepage: http://www.pinsonne-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Onlineshop&lt;br /&gt;
* Sehr kleines Sortiment&lt;br /&gt;
* UNI-T, RIGOL und andere asiatische Firmen&lt;br /&gt;
&lt;br /&gt;
==== PK elektronik Poppe GmbH ====&lt;br /&gt;
Homepage: http://www.pk-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* U.a. Fluke Distributor.&lt;br /&gt;
&lt;br /&gt;
====Präzitronic Hennig / Messgeräte Chemnitz====&lt;br /&gt;
Homepage: http://www.messgeraete-chemnitz.de&lt;br /&gt;
&lt;br /&gt;
* Owon&lt;br /&gt;
* Selbst übersetzte deutsche Owon-Handbücher&lt;br /&gt;
* Fluke&lt;br /&gt;
* Zusätzlich kleines Angebot an Gebrauchtgeräten&lt;br /&gt;
&lt;br /&gt;
==== ScopeShop Hamburg ====&lt;br /&gt;
&lt;br /&gt;
* Von CalPlus übernommen, siehe [[#CalPlus_GmbH|CalPlus]]&lt;br /&gt;
&lt;br /&gt;
==== SI Scientific Instruments GmbH ====&lt;br /&gt;
Homepage: http://www.si-scientific.de (Onlineshop) &amp;lt;br /&amp;gt;&lt;br /&gt;
Homepage: http://www.si-gmbh.de (komplettes Programm)&lt;br /&gt;
&lt;br /&gt;
* Onlineshop auf si-scientific.de&lt;br /&gt;
* Akzeptiert PayPal&lt;br /&gt;
 &lt;br /&gt;
==== SKY Messtechnik GmbH ====&lt;br /&gt;
Homepage: http://www.sky-messtechnik.de&lt;br /&gt;
&lt;br /&gt;
* Kein Onlineshop (E-Mail oder Telefon)&lt;br /&gt;
&lt;br /&gt;
==== TESTEC ====&lt;br /&gt;
Homepage: http://www.testec.info&lt;br /&gt;
&lt;br /&gt;
* Tastköpfe-Hersteller&lt;br /&gt;
* Hameg Vertriebspartner&lt;br /&gt;
* B+K Precision Generalimporteur&lt;br /&gt;
&lt;br /&gt;
==== Zeitech ====&lt;br /&gt;
Homepage: http://zeitech.eu/shop/&lt;br /&gt;
&lt;br /&gt;
* Diverses (Rigol, Owon, etc.)&lt;br /&gt;
&lt;br /&gt;
=== Gebrauchte Messgeräte ===&lt;br /&gt;
&lt;br /&gt;
Dieser Abschnitt enthält Anbieter bei denen gebrauchte Messgeräte erhältlich sind.&lt;br /&gt;
&lt;br /&gt;
==== Astro Electronic ====&lt;br /&gt;
Homepage: http://www.astro-electronic.de&lt;br /&gt;
&lt;br /&gt;
==== eumex GmbH ====&lt;br /&gt;
Homepage: http://www.eumes.com/pub/de/&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
&lt;br /&gt;
==== HTB-Elektronik ====&lt;br /&gt;
Homepage: http://www.htb-elektronik.com&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
&lt;br /&gt;
==== IX Instrumex ====&lt;br /&gt;
Homepage: http://www.instrumex.de/index.cgi?User:LANGUAGE=de&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
&lt;br /&gt;
==== Christoph Lüders MessTechnik ====&lt;br /&gt;
Homepage: http://www.CLMT.de &amp;lt;br&amp;gt;&lt;br /&gt;
Online-Shop: http://www.shop-016.de/shop-CLMT.html &amp;lt;br&amp;gt;&lt;br /&gt;
eBay: http://myworld.ebay.de/c_h_r/&lt;br /&gt;
&lt;br /&gt;
* Hat 2010 die Restbestände von Förtig übernommen&lt;br /&gt;
&lt;br /&gt;
==== mbmt Messtechnik ====&lt;br /&gt;
Homepage: http://www.mbmt.com&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
* Verkauf nur an Gewerbetreibende&lt;br /&gt;
&lt;br /&gt;
==== Rosenkranz Elektronik ====&lt;br /&gt;
Homepage: http://www.rosenkranz-elektronik.de&amp;lt;br&amp;gt;&lt;br /&gt;
eBay Shop: http://stores.ebay.de/Rosenkranz-Elektronik-GmbH-Shop&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
* Auch auf eBay zu finden&lt;br /&gt;
&lt;br /&gt;
==== Helmut-Singer-Elektronik ====&lt;br /&gt;
Homepage: http://www.helmut-singer.de&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
* Verkauf auch an Privat&lt;br /&gt;
* An den meisten Samstagen im Jahr auch Lagerverkauf, sonst Versand&lt;br /&gt;
&lt;br /&gt;
==== Sphere ====&lt;br /&gt;
Homepage: http://www.sphere.bc.ca&amp;lt;br&amp;gt;&lt;br /&gt;
Messgeräte und Ersatzteile: http://www.sphere.bc.ca/test/index.html&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
* Ersatzteile&lt;br /&gt;
** Besonders bekannt für Tektronix-Ersatzteile&lt;br /&gt;
&lt;br /&gt;
==== Tektronix TekSelect ====&lt;br /&gt;
Homepage: http://www.tek.com/Measurement/tekselect/&lt;br /&gt;
&lt;br /&gt;
* Tektronix verkauft selber gebrauchte und überarbeitete Tektronix-Messgeräte unter dem Label &#039;&#039;TekSelect&#039;&#039;.&lt;br /&gt;
* Original Tektronix-Garantie&lt;br /&gt;
* Der Bestellvorgang nervt, man muss Kontaktaufnahme durch einen &amp;quot;Representative&amp;quot; erbeten.&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [[Platinenhersteller]]&lt;br /&gt;
* [[Lokale Elektroniklieferanten]]&lt;br /&gt;
* [[Eisenwarenversender]]&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://www.xs4all.nl/~ganswijk/chipdir/ Suche nach integrierten Schaltkreisen&lt;br /&gt;
* http://www.alldatasheet.com                Datenblätter&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Bauteile|!]]&lt;br /&gt;
[[Kategorie:Lieferanten]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR-Studio&amp;diff=63365</id>
		<title>AVR-Studio</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR-Studio&amp;diff=63365"/>
		<updated>2012-01-19T17:15:45Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* Debugger */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Das &#039;&#039;&#039;AVR-Studio&#039;&#039;&#039; ist eine kostenlose Entwicklungsumgebung ([[Editoren/IDEs|IDE]]) für die Programmierung der [[AVR]]-[[Mikrocontroller]] von Atmel. Sie basiert ab Version 5 auf der Visual Studio Shell von Microsoft und besteht aus einer Projektverwaltung, einem [[Editoren/IDEs#Texteditoren für Programmierer|Editor]], einem [[AVR-Studio#Debugger|Debugger]] und Werkzeugen zum beschreiben der Mikrocontroller.&lt;br /&gt;
&lt;br /&gt;
Mit dem AVR Studio kann in [[Assembler]] sowie in [[C]]/[[C-Plusplus|C++]] programmiert werden. Für die Unterstützung von C/C++ musste bis einschließlich Version 4 vor der Installation des AVR Studio der GNU C Compiler für AVRs [[WinAVR]] installiert werden. Ab AVR Studio 5 ist eine vollständige Toolchain zur Entwicklung von C-Projekten enthalten. Atmel bietet weiterhin eine Erweiterung zwecks Erstellung von Projekten mit eingeschränkter C++-Unterstützung an (siehe [[AVR_Studio#Tipps_.26_Tricks|Tipps &amp;amp; Tricks]]).&lt;br /&gt;
&lt;br /&gt;
== Debugger ==&lt;br /&gt;
Die AVR-Studio-Umgebung sieht unabhängig von der speziellen Debug-Plattform größtenteils identisch aus. Es existieren folgende Debug-Möglichkeiten:&lt;br /&gt;
# [[AVR-Simulation#AVR_Studio|AVR Simulator]]&lt;br /&gt;
# AVR In-Circuit Emulator / [[JTAG]]-Adapter: AVR Dragon, AVR ONE!, JTAGICE3, JTAGICE mkII&lt;br /&gt;
&#039;&#039;&#039;Simulation&#039;&#039;&#039;&lt;br /&gt;
* die meisten AVR-Mikrocontroller werden unterstützt&lt;br /&gt;
* z.T langsamer als eine Emulation (insbesondere bei größeren Projekten)&lt;br /&gt;
* Wechselwirkung mit Peripherie nur über vordefinierte Stimuli möglich&lt;br /&gt;
* Anzeige aller Register zu jeder Zeit möglich&lt;br /&gt;
&#039;&#039;&#039;Emulation&#039;&#039;&#039;&lt;br /&gt;
* Unterstützung von Mikrocontrollern plattformabhängig eingeschränkt&lt;br /&gt;
* z.T. schneller als Simulation&lt;br /&gt;
* Debugging in tatsächlicher Hardwareumgebung&lt;br /&gt;
* Register nicht uneingeschränkt lesbar&lt;br /&gt;
&lt;br /&gt;
== Tipps &amp;amp; Tricks ==&lt;br /&gt;
&lt;br /&gt;
* [[AVR-Studio Bugs]]&lt;br /&gt;
&lt;br /&gt;
* [[AVR-Simulation]]&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/193587#1894280 Pfad zum Hexfile]&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/237681#2411339 Anzeige der Größe benutzter Speicherbereiche in AVR Studio 5]&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/236601#2413654 C++ Templates (beta) für AVR Studio 5] (Vorsicht: kein vollständiger Funktionsumfang, siehe [http://support.atmel.no/bin/customer.exe?=&amp;amp;action=viewKbEntry&amp;amp;id=1001 FAQ])&lt;br /&gt;
&lt;br /&gt;
* [http://www.rn-wissen.de/index.php/AVR_Studio_5#Eigene_Templates_erzeugen Erstellung eigener Templates in AVR Studio 5] &lt;br /&gt;
&lt;br /&gt;
== Downloads ==&lt;br /&gt;
&lt;br /&gt;
=== Offizielle Seite ===&lt;br /&gt;
* http://www.atmel.com/avrstudio&lt;br /&gt;
&lt;br /&gt;
=== Direktlinks Installer ===&lt;br /&gt;
&lt;br /&gt;
Anm.: Die MD5 Checksumme dient zum Überprüfen der Downloads auf Vollständigkeit. Die aktuelle Version ist &#039;&#039;&#039;fett&#039;&#039;&#039; markiert.&lt;br /&gt;
&lt;br /&gt;
Im Falle nicht eingepflegter Updates hier der Direktlink-Präfix (entsprechenden Dateinamen aus dem Formularlink kopieren und hinter dem letzten Schrägstrich einfügen):&lt;br /&gt;
&lt;br /&gt;
http://www.atmel.com/dyn/resources/prod_documents/&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/as5installer-5.1.148.beta-full.exe as5installer-5.1.148.beta-full.exe] AVR Studio 5.1 Beta installer (includes VSS and .NET) (523 MB, updated 2011/12)&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/as5installer-5.1.148.beta-small.exe as5installer-5.1.148.beta-small.exe] AVR Studio 5.1 Beta installer  (308 MB, updated 2011/12)&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/as5installer-full-5.0.1223.exe as5installer-5.0.1223-full.exe] &#039;&#039;&#039;AVR Studio 5 installer (includes VSS and .NET) (605MB, updated 2011/11/25)&#039;&#039;&#039;  &lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/as5installer-small-5.0.1223.exe as5installer-5.0.1223-small.exe] &#039;&#039;&#039;AVR Studio 5 installer (390 MB, updated 2011/11/25)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/as5installer-5.0.1163-full.exe as5installer-5.0.1163-full.exe] AVR Studio 5 installer (includes VSS and .NET) (602MB, updated 2011/05/11)  MD5:3C9371A8CF8A5D9663C107D00A22B6F1&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/as5installer-5.0.1163-small.exe as5installer-5.0.1163-small.exe] AVR Studio 5 installer (387 MB, updated 2011/05/11)  MD5:E0BD9F82DDDCF74B05C6BA1582F2C642&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/avrstudio5.0.beta2.noVSSnoDotNet.exe Avrstudio5.0.beta2.noVSSnoDotNet.exe] AVR Studio 5.0 Beta 2 ohne Visual Studio Shell und .NET (339 MB)&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/avrstudio5.0.beta2.exe AvrStudio5.0.beta2.exe] AVR Studio 5.0 Beta 2 (554 MB)&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/avrstudio5.0.beta.exe AvrStudio5.0.beta.exe] AVR Studio 5.0 Beta (523 MB)&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/AvrStudio4Setup.exe AvrStudio4Setup.exe] &#039;&#039;&#039;AVR Studio 4.19 (build 730) (124 MB, updated 2011/09/11)&#039;&#039;&#039;  MD5:609209DB9A1C6191945421299101DC15&lt;br /&gt;
&lt;br /&gt;
*[http://distribute.atmel.no/tools/avr/beta/4.19%20Build720/AvrStudio4Setup.exe AvrStudio4Setup.exe] AVR Studio 4.19 Beta (build 720)  (123 MB, updated 2011/04/11)  MD5:?&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/AvrStudio417Setup.exe AvrStudio417Setup.exe] AVR Studio 4.17 (build 666) (112 MB, updated 07/09) MD5:9705a9362da76aa9779322127640a184&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/AvrStudio416Setup.exe AvrStudio416Setup.exe] AVR Studio 4.16 (build 628) (126 MB, updated 02/09) (last version for Win98) MD5:d1c412d7a05a9ad95486d7ea680f68e5&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/aStudio4b623.exe aStudio4b623.exe] AVR Studio 4.15 (build 623) (94 MB, updated 11/08)&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/aStudio4b589.exe aStudio4b589.exe] AVR Studio 4.14 (build 589) (89 MB, updated 04/08)&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/aStudio4b528.exe aStudio4b528.exe]  AVR Studio 4.13 (build 528) (73 MB, updated 03/07)&lt;br /&gt;
&lt;br /&gt;
=== Direktlinks Zusatzsoftware ===&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/AVRQTouchStudioSetup_VSS_dotNET.exe AVRQTouchStudioSetup_VSS_dotNET.exe] AVR QTouch Studio mit .NET (373 MB, updated 03/10)&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/avr-toolchain-installer-3.3.0.710-win32.win32.x86.exe avr-toolchain-installer-3.3.0.710-win32.win32.x86.exe] &#039;&#039;&#039;AVR Toolchain 3.3.0 (94 MB, updated 2011/09/11, AVR-GCC: 4.5.1, AVR-LIBC: 1.7.1)&#039;&#039;&#039; MD5: 1c43bac156cb1e4cb77dfc7a833cf237&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/avr-toolchain-installer-3.2.3.579-win32.win32.x86.exe avr-toolchain-installer-3.2.3.579-win32.win32.x86.exe] AVR Toolchain 3.2.3 (95 MB, updated 06/11, AVR-GCC: 4.5.1, AVR-LIBC: 1.7.1)&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/avr-toolchain-installer-3.0.0.240-win32.win32.x86.exe avr-toolchain-installer-3.0.0.240-win32.win32.x86.exe] AVR Toolchain 3.0.0 (87 MB, updated 09/10, AVR-GCC: 4.4.3, AVR-LIBC: 1.7.0) MD5:999B3DC3DF471B3A667CF0FE90A522E8. Update util/delay.h [http://www.mikrocontroller.net/topic/196738#1943039] beachten.&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/asf-standalone-archive-2.9.0.zip asf-standalone-archive-2.9.0.zip] &#039;&#039;&#039;AVR SoftwareFramework 2.9.0 - drivers and libraries (80 MB, revision 2.9.0, updated 2012/01/19)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/asf-standalone-archive-2.6.1.33.zip asf-standalone-archive-2.6.1.33.zip] AVR SoftwareFramework 2.6.1.33 - drivers and libraries&lt;br /&gt;
&lt;br /&gt;
*[http://www.atmel.com/dyn/resources/prod_documents/AVR-SoftwareFramework-2.3.1.zip AVR-SoftwareFramework-2.3.1.zip] AVR SoftwareFramework 2.3.1 - drivers and libraries&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/AVRStudio5-ASF-Update-2.8.1.76.exe AVRStudio5-ASF-Update-2.8.1.76.exe] &#039;&#039;&#039;AVRStudio5-ASF-Update-2.8.1.76 (222 MB, revision 2.8.1, updated 2011/10/11)&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/AVRStudio5-ASF-Update-2.7.0.43.exe AVRStudio5-ASF-Update-2.7.0.43.exe] AVRStudio5-ASF-Update-2.7.0.43 (214 MB, revision 2.7.0, updated 2011/8/11)&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/AVRStudio5-ASF-Update-2.6.1.27.exe AVRStudio5-ASF-Update-2.6.1.27.exe] AVRStudio5-ASF-Update-2.6.1.27&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/dyn/resources/prod_documents/AVR2025_MAC_v_2_7_0.exe AVR2025_MAC_v_2_7_0.exe] IEEE 802.15.4 MAC Stack&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://www.youtube.com/user/AtmelCorporation#g/c/8F325BE889E62E50 YouTube-Playlist: AVR Studio 5 Tutorial]&lt;br /&gt;
&lt;br /&gt;
* [http://www.avrfreaks.net/index.php?name=PNphpBB2&amp;amp;file=viewtopic&amp;amp;t=82994 How to install JTAGICE mkII (and AVR Dragon and AVRISP mkII) on Windows 7 x64] auf avrfreaks.net (ggf. kostenlos registrieren). Siehe auch Hinweis von Denny [http://www.mikrocontroller.net/topic/146857#1476962] im Forum.&lt;br /&gt;
&lt;br /&gt;
*[http://avr-eclipse.sourceforge.net/wiki/index.php/The_AVR_Eclipse_Plugin AVR Eclipse Plugin]&lt;br /&gt;
&lt;br /&gt;
*[http://avrstudio5.wordpress.com/ AVR Studio 5 Blog] - Useful hints and tips for installation troubleshooting with the new AVR Studio 5&lt;br /&gt;
&lt;br /&gt;
[[Category:AVR]]&lt;br /&gt;
[[Kategorie:Entwicklungstools]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=AVR-GCC-Tutorial&amp;diff=63363</id>
		<title>AVR-GCC-Tutorial</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=AVR-GCC-Tutorial&amp;diff=63363"/>
		<updated>2012-01-19T17:08:26Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* Nutzung des ADC */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Voraussetzungen =&lt;br /&gt;
&lt;br /&gt;
Vorausgesetzt werden Grundkenntnisse der Programmiersprache C. Diese Kenntnisse kann man sich online erarbeiten, z. B. mit dem [http://www.schellong.de/c.htm C Tutorial von Helmut Schellong] ([[C|Liste von C-Tutorials]]). Nicht erforderlich sind Vorkenntnisse in der Programmierung von Mikrocontrollern, weder in Assembler noch in einer anderen Sprache.&lt;br /&gt;
&lt;br /&gt;
= Vorwort =&lt;br /&gt;
&lt;br /&gt;
Dieses Tutorial soll den Einstieg in die Programmierung von Atmel [[AVR]]-Mikrocontrollern in der Programmiersprache [[C]] mit dem freien C-Compiler [[AVR-GCC]] aus der [http://gcc.gnu.org/ GNU Compiler Collection] erleichtern.&lt;br /&gt;
&lt;br /&gt;
In diesem Text wird häufig auf die Standardbibliothek avr-libc verwiesen, für die es eine [http://www.nongnu.org/avr-libc/user-manual/index.html Online-Dokumentation] gibt, in der sich auch viele nützliche Informationen zum Compiler und zur Programmierung von AVR Controllern finden (beim Paket WinAVR gehört die avr-libc Dokumentation zum Lieferumfang und wird mitinstalliert).&lt;br /&gt;
&lt;br /&gt;
Der Compiler und die Standardbibliothek avr-libc werden stetig weiterentwickelt. Einige Unterschiede, die sich im Verlauf der Entwicklung ergeben haben, werden im Haupttext und Anhang zwar erläutert, Anfängern sei jedoch empfohlen, die aktuellen Versionen zu nutzen (für MS-Windows: aktuelle Version des [[WinAVR]]-Pakets; für Linux: siehe Artikel [[AVR und Linux]]).&lt;br /&gt;
&lt;br /&gt;
Das ursprüngliche Tutorial stammt von Christian Schifferle, viele neue Abschnitte und aktuelle Anpassungen von Martin Thomas.&lt;br /&gt;
&lt;br /&gt;
Dieses Tutorial ist in PDF-Form hier erhältlich (nicht immer auf aktuellem Stand):&lt;br /&gt;
[[Media:AVR-GCC-Tutorial.pdf]]&lt;br /&gt;
&lt;br /&gt;
== Weiterführende Kapitel ==&lt;br /&gt;
&lt;br /&gt;
Um dieses riesige Tutorial etwas überschaubarer zu gestalten, wurden einige Kapitel ausgelagert, die nicht unmittelbar mit den Grundlagen von avr-gcc in Verbindung stehen. All diese Seiten gehören zur [[:Kategorie:avr-gcc Tutorial]].&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Der UART|Der UART]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Der Watchdog|Der Watchdog]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Die Timer und Zähler des AVR|Die Timer und Zähler des AVR]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Exkurs Makefiles|Exkurs Makefiles]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/LCD-Ansteuerung|LCD-Ansteuerung]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Alte Quellen|Alte Quellen anpassen]]&lt;br /&gt;
: &amp;amp;rarr; [[AVR-GCC-Tutorial/Assembler und Inline-Assembler|Assembler und Inline-Assembler]]&lt;br /&gt;
&lt;br /&gt;
= Benötigte Werkzeuge =&lt;br /&gt;
&lt;br /&gt;
Um eigene Programme für AVRs mittels avr-gcc/avr-libc zu erstellen und zu testen, wird folgende Hard- und Software benötigt:&lt;br /&gt;
&lt;br /&gt;
* Platine oder Versuchsaufbau für die Aufnahme eines AVR Controllers, der vom avr-gcc Compiler unterstützt wird (alle ATmegas und die meisten AT90, siehe Dokumentation der avr-libc für unterstützte Typen). Dieses Testboard kann durchaus auch selbst gelötet oder auf einem Steckbrett aufgebaut werden. Einige Registerbeschreibungen dieses Tutorials beziehen sich auf den inzwischen veralteten AT90S2313. Der weitaus größte Teil des Textes ist aber für alle Controller der AVR-Familie gültig. Brauchbare Testplattformen sind auch das [[STK500]] und der [[AVR Butterfly]] von Atmel. Weitere Infos findet man in den Artikeln [[AVR#Starterkits|AVR Starterkits]] und [[AVR-Tutorial: Equipment]].&lt;br /&gt;
&lt;br /&gt;
* Der avr-gcc Compiler und die avr-libc. Kostenlos erhältlich für nahezu alle Plattformen und Betriebssysteme. Für MS-Windows im Paket [[WinAVR]]; für Unix/Linux siehe auch Hinweise im Artikel [[AVR-GCC]] und im Artikel [[AVR und Linux]].&lt;br /&gt;
&lt;br /&gt;
* Programmiersoftware und -[[AVR In System Programmer |hardware]] z. B. PonyProg (siehe auch: [[Pony-Prog Tutorial]]) oder [[AVRDUDE]] mit [[STK200]]-Dongle oder die von Atmel verfügbare Hard- und Software ([[STK500]], Atmel AVRISP, [[AVR-Studio]]).&lt;br /&gt;
&lt;br /&gt;
* Nicht unbedingt erforderlich, aber zur Simulation und zum Debuggen unter MS-Windows recht nützlich: [[AVR-Studio]] (siehe Artikel [[AVR-GCC-Tutorial/Exkurs_Makefiles|Exkurs: Makefiles]]).&lt;br /&gt;
&lt;br /&gt;
* Wer unter Windows und Linux gleichermassen entwickeln will, der sollte sich die [http://www.eclipse.org/ IDE Eclipse for C/C++ Developers] und das [http://avr-eclipse.sourceforge.net/wiki/index.php/The_AVR_Eclipse_Plugin AVR-Eclipse Plugin ] ansehen, beide sind unter Windows und Linux einfach zu installieren. Hier gibt es auch einen [[AVR_Eclipse|Artikel AVR Eclipse]] in dieser Wiki. Ebenfalls unter Linux und Windows verfügbar ist die Entwicklungsumgebung [http://www.codeblocks.org/ Code::Blocks] (aktuelle, stabile Versionen sind als Nightly Builds regelmäßig im [http://forums.codeblocks.org/ Forum] verfügbar). Innerhalb dieser Entwicklungsumgebung können ohne die Installation zusätzlicher Plugins &amp;quot;AVR-Projekte&amp;quot; angelegt werden. Für Linux gibt es auch noch das [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=25220&amp;amp;postdays=0&amp;amp;postorder=asc&amp;amp;start=0 KontrollerLab].&lt;br /&gt;
&lt;br /&gt;
= Was tun, wenn&#039;s nicht klappt? =&lt;br /&gt;
&lt;br /&gt;
* Herausfinden, ob es tatsächlich ein avr(-gcc) spezifisches Problem ist oder nur die eigenen C-Kenntnisse einer Auffrischung bedürfen. Allgemeine C-Fragen kann man eventuell &amp;quot;beim freundlichen Programmierer zwei Büro-, Zimmer- oder Haustüren weiter&amp;quot; loswerden. Ansonsten: [[C]]-Buch (gibt&#039;s auch &amp;quot;gratis&amp;quot; online) lesen.&lt;br /&gt;
&lt;br /&gt;
* Die [[AVR Checkliste]] durcharbeiten.&lt;br /&gt;
&lt;br /&gt;
* Die &#039;&#039;&#039;[http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc]&#039;&#039;&#039; lesen, vor allem (aber nicht nur) den Abschnitt Related Pages/&#039;&#039;&#039;Frequently Asked Questions&#039;&#039;&#039; = Oft gestellte Fragen (und Antworten dazu). Z.Zt leider nur in englischer Sprache verfügbar.&lt;br /&gt;
&lt;br /&gt;
* Den Artikel [[AVR-GCC]] in diesem Wiki lesen.&lt;br /&gt;
&lt;br /&gt;
* Das [http://www.mikrocontroller.net/forum/gcc GCC-Forum auf  www.mikrocontroller.net] nach vergleichbaren Problemen absuchen.&lt;br /&gt;
&lt;br /&gt;
* Das avr-gcc-Forum bei [http://www.avrfreaks.net AVRfreaks] nach vergleichbaren Problemen absuchen.&lt;br /&gt;
&lt;br /&gt;
* Das [http://lists.gnu.org/archive/html/avr-gcc-list/ Archiv der avr-gcc Mailing-Liste] nach vergleichbaren Problemen absuchen.&lt;br /&gt;
&lt;br /&gt;
* Nach Beispielcode suchen. Vor allem im &#039;&#039;Projects&#039;&#039;-Bereich von [http://www.avrfreaks.net AVRfreaks] (anmelden).&lt;br /&gt;
&lt;br /&gt;
* Google oder yahoo befragen schadet nie.&lt;br /&gt;
&lt;br /&gt;
* Bei Problemen mit der Ansteuerung interner AVR-Funktionen mit C-Code: das Datenblatt des Controllers lesen (ganz und am Besten zweimal). Datenblätter sind  auf den [http://www.atmel.com Atmel Webseiten] als pdf-Dateien verfügbar. Das komplette Datenblatt (complete) und nicht die Kurzfassung (summary) verwenden.&lt;br /&gt;
&lt;br /&gt;
* Die Beispielprogramme im [[AVR-Tutorial]] sind zwar in AVR-Assembler verfasst, Erläuterungen und Vorgehensweisen sind aber auch auf C-Programme übertragbar.&lt;br /&gt;
&lt;br /&gt;
* Einen Beitrag in eines der Foren oder eine Mail an die Mailing-Liste schreiben. Dabei möglichst viel Information geben: Controller, Compilerversion, genutzte Bibliotheken, Ausschnitte aus dem Quellcode oder besser ein [http://www.mikrocontroller.net/topic/72767#598986 Testprojekt] mit allen notwendigen Dateien, um das Problem nachzuvollziehen, sowie genaue Fehlermeldungen bzw. Beschreibung des Fehlverhaltens. Bei Ansteuerung externer Geräte die Beschaltung beschreiben oder skizzieren (z. B. mit [http://www.tech-chat.de/ Andys ASCII Circuit]). Siehe dazu auch: &#039;&#039;&#039;[http://www.tty1.net/smart-questions_de.html &amp;quot;Wie man Fragen richtig stellt&amp;quot;]&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
= Erzeugen von Maschinencode =&lt;br /&gt;
&lt;br /&gt;
Aus dem C-Quellcode erzeugt der avr-gcc Compiler (zusammen mit Hilfsprogrammen wie z.&amp;amp;nbsp;B. Präprozessor, Assembler und Linker) Maschinencode für den AVR-Controller. Üblicherweise liegt dieser Code dann im Intel Hex-Format vor (&amp;quot;Hex-Datei&amp;quot;). Die Programmiersoftware (z.&amp;amp;nbsp;B. [[AVRDUDE]], PonyProg oder AVRStudio/STK500-plugin) liest diese Datei ein und überträgt die enthaltene Information (den Maschinencode) in den Speicher des Controllers. Im Prinzip sind also &amp;quot;nur&amp;quot; der avr-gcc-Compiler (und wenige Hilfsprogramme) mit den &amp;quot;richtigen&amp;quot; Optionen aufzurufen, um aus C-Code eine &amp;quot;Hex-Datei&amp;quot; zu erzeugen. Grundsätzlich stehen dazu zwei verschiedene Ansätze zur Verfügung:&lt;br /&gt;
&lt;br /&gt;
* Die Verwendung einer integrierten Entwicklungsumgebung (IDE = &#039;&#039;&#039;I&#039;&#039;&#039;ntegrated &#039;&#039;&#039;D&#039;&#039;&#039;evelopment &#039;&#039;&#039;E&#039;&#039;&#039;nvironment), bei der alle Einstellungen z.&amp;amp;nbsp;B. in Dialogboxen durchgeführt werden können. Unter Anderem kann AVRStudio ab Version 4.12 (kostenlos auf [http://www.atmel.com/ atmel.com]) zusammen mit WinAVR als integrierte Entwicklungsumgebung für den Compiler avr-gcc genutzt werden (dazu müssen AVRStudio und WinAVR auf dem Rechner installiert sein). Weitere IDEs (ohne Anspruch auf Vollständigkeit): [http://www.eclipse.org/ Eclipse for C/C++ Developers] (d.h. inkl. CDT) und das [http://avr-eclipse.sourceforge.net/wiki/index.php/The_AVR_Eclipse_Plugin AVR-Eclipse Plugin] (für diverse Plattformen, u.a. Linux und MS Windows, IDE und Plugin kostenlos), [http://sourceforge.net/projects/kontrollerlab KontrollerLab] (Linux/KDE, kostenlos). [http://www.atmanecl.com/EnglishSite/SoftwareEnglish.htm AtmanAvr] (MS Windows, relativ günstig), KamAVR (MS-Windows, kostenlos, wird augenscheinlich nicht mehr weiterentwickelt), [http://www.amctools.com/vmlab.htm VMLab] (MS Windows, ab Version 3.12 ebenfalls kostenlos). Integrierte Entwicklungsumgebungen unterscheiden sich stark in Ihrer Bedienung und stehen auch nicht für alle Plattformen zur Verfügung, auf denen der Compiler  ausführbar ist (z.&amp;amp;nbsp;B. AVRStudio nur für MS-Windows). Zur Anwendung des avr-gcc Compilers mit IDEs sei hier auf deren Dokumentation verwiesen. &lt;br /&gt;
&lt;br /&gt;
* Die Nutzung des Programms make mit passenden Makefiles. In den folgenden Abschnitten wird die Generierung von Maschinencode für einen AVR (&amp;quot;hex-Datei&amp;quot;) aus C-Quellcode (&amp;quot;c-Dateien&amp;quot;) anhand von &amp;quot;make&amp;quot; und den &amp;quot;Makefiles&amp;quot; näher erläutert. Viele der darin beschriebenen Optionen findet man auch im Konfigurationsdialog des avr-gcc-Plugins von AVRStudio (AVRStudio generiert ein makefile in einem Unterverzeichnis des Projektverzeichnisses). &lt;br /&gt;
&lt;br /&gt;
Beim Wechsel vom makefile-Ansatz nach WinAVR-Vorlage zu AVRStudio ist darauf zu achten, dass AVRStudio (Stand: AVRStudio Version 4.13) bei einem neuen Projekt die Optimierungsoption (vgl. Artikel [[AVR-GCC-Tutorial/Exkurs_Makefiles|AVR-GCC-Tutorial/Exkurs: Makefiles]], typisch: -Os) nicht einstellt und die mathematische Bibliothek der avr-libc (libm.a, Linker-Option -lm) nicht einbindet. (Hinweis: Bei Version 4.16 wird beides bereits gesetzt). Beides ist Standard bei Verwendung von makefiles nach WinAVR-Vorlage und sollte daher auch im Konfigurationsdialog des avr-gcc-Plugins von AVRStudio &amp;quot;manuell&amp;quot; eingestellt werden, um auch mit AVRStudio kompakten Code zu erzeugen.&lt;br /&gt;
&lt;br /&gt;
= Einführungsbeispiel =&lt;br /&gt;
&lt;br /&gt;
Zum Einstieg ein kleines Beispiel, an dem die Nutzung des Compilers und der Hilfsprogramme (der sogenannten &#039;&#039;Toolchain&#039;&#039;) demonstriert wird. Detaillierte Erläuterungen folgen in den weiteren Abschnitten dieses Tutorials.&lt;br /&gt;
&lt;br /&gt;
Das Programm soll auf einem AVR Mikrocontroller einige Ausgänge ein- und andere ausschalten. Das Beispiel ist für einen ATmega16 programmiert ([http://www.atmel.com/dyn/resources/prod_documents/doc2466.pdf Datenblatt]), kann aber sinngemäß für andere Controller der AVR-Familie modifiziert werden. &lt;br /&gt;
&lt;br /&gt;
Ein kurzes Wort zur Hardware: Bei diesem Programm werden alle Pins von PORTB auf Ausgang gesetzt, und einige davon werden auf HIGH andere auf LOW gesetzt. Das kann je nach angeschlossener Hardware an diesen Pins kritisch sein. Am ungefährlichsten ist es, wenn nichts an den Pins angeschlossen ist und man die Funktion des Programmes durch eine Spannungsmessung mit einem Multimeter kontrolliert. Die Spannung wird dabei zwischen GND-Pin und den einzelnen Pins von PORTB gemessen.&lt;br /&gt;
&lt;br /&gt;
Zunächst der Quellcode der Anwendung, der in einer Text-Datei mit dem Namen &#039;&#039;main.c&#039;&#039; abgespeichert wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
/* Alle Zeichen zwischen Schrägstrich-Stern &lt;br /&gt;
   und Stern-Schrägstrich sind Kommentare */&lt;br /&gt;
&lt;br /&gt;
// Zeilenkommentare sind ebenfalls möglich&lt;br /&gt;
// alle auf die beiden Schrägstriche folgenden&lt;br /&gt;
// Zeichen einer Zeile sind Kommentar&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;          // (1)&lt;br /&gt;
&lt;br /&gt;
int main (void) {            // (2)&lt;br /&gt;
&lt;br /&gt;
   DDRB  = 0xFF;             // (3)&lt;br /&gt;
   PORTB = 0x03;             // (4)&lt;br /&gt;
&lt;br /&gt;
   while(1) {                // (5)&lt;br /&gt;
     /* &amp;quot;leere&amp;quot; Schleife*/   // (6)&lt;br /&gt;
   }                         // (7)&lt;br /&gt;
&lt;br /&gt;
   /* wird nie erreicht */&lt;br /&gt;
   return 0;                 // (8)&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
# In dieser Zeile wird eine sogenannte Header-Datei eingebunden. In &amp;lt;code&amp;gt;avr/io.h&amp;lt;/code&amp;gt; sind die Registernamen definiert, die im späteren Verlauf genutzt werden. Auch unter Windows wird ein&amp;amp;nbsp;&amp;lt;code&amp;gt;/&amp;lt;/code&amp;gt; zur Kennzeichnung von Unterverzeichnissen in Include-Dateinamen verwendet und kein&amp;amp;nbsp;&amp;lt;code&amp;gt;\&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Hier beginnt das eigentliche Programm. Jedes C-Programm beginnt mit den Anweisungen in der Funktion &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt;.&lt;br /&gt;
# Die Anschlüsse eines AVR (&amp;quot;Beinchen&amp;quot;) werden zu Blöcken zusammengefasst, einen solchen Block bezeichnet man als Port. Beim ATmega16 hat jeder Port 8 Anschlüsse, bei kleineren AVRs können einem Port auch weniger als 8 Anschlüsse zugeordnet sein. Da per Definition (Datenblatt) alle gesetzten Bits in einem Datenrichtungsregister den entsprechenden Anschluss auf Ausgang schalten, werden mit DDRB=0xff alle Anschlüsse des Ports B als Ausgänge eingestellt.&lt;br /&gt;
# stellt die Werte der Ausgänge ein. Die den ersten beiden Bits des Ports zugeordneten Anschlüsse (PB0 und PB1) werden 1, alle anderen Anschlüsse des Ports B (PB2-PB7) zu 0. Aktivierte Ausgänge (logisch 1 oder &amp;quot;high&amp;quot;) liegen auf Betriebsspannung (VCC, meist 5 Volt), nicht aktivierte Ausgänge führen 0 Volt (GND, Bezugspotential). Es ist sinnvoll, sich möglichst frühzeitig eine alternative Schreibweise beizubringen, die wegen der leichteren Überprüfbarkeit und Portierbarkeit oft im weiteren Tutorial und in Forenbeiträgen benutzt wird. Die Zuordnung sieht in diesem Fall so aus, Näheres dazu im Artikel [[Bitmanipulation]]:&amp;lt;c&amp;gt;PORTB = (1&amp;lt;&amp;lt;PB1) | (1&amp;lt;&amp;lt;PB0);&amp;lt;/c&amp;gt;&lt;br /&gt;
# ist der Beginn der sogenannte &#039;&#039;Hauptschleife&#039;&#039; (main-loop). Dies ist eine Endlosschleife, welche kontinuierlich wiederkehrende Befehle enthält.&lt;br /&gt;
# In diesem Beispiel ist die Hauptschleife leer. Der Controller durchläuft die Schleife immer wieder, ohne dass etwas passiert. Eine solche Schleife ist notwendig, da es auf dem Controller kein Betriebssystem gibt, das nach Beendigung des Programmes die Kontrolle übernehmen könnte. Ohne diese Schleife kehrt das Programm aus &amp;lt;code&amp;gt;main&amp;lt;/code&amp;gt; zurück, alle Interrupts werden deaktiviert und eine Endlosschleife betreten.&lt;br /&gt;
# Ende der Hauptschleife und Sprung zur passenden, öffnenden Klammer, also zu 5.&lt;br /&gt;
# ist das Programmende. Die Zeile ist nur aus Gründen der C-Kompatibilität enthalten: &amp;lt;c&amp;gt;int main(void)&amp;lt;/c&amp;gt; besagt, dass die Funktion einen int-Wert zurückgibt. Die Anweisung wird aber nicht erreicht, da das Programm die Hauptschleife nie verlässt.&lt;br /&gt;
&lt;br /&gt;
Um diesen Quellcode in ein lauffähiges Programm zu übersetzen, wird hier ein Makefile genutzt. Das verwendete Makefile findet sich auf der Seite [[Beispiel Makefile]] und basiert auf der Vorlage, die in WinAVR mitgeliefert wird und wurde bereits angepasst (Controllertyp ATmega16). Man kann das Makefile bearbeiten und an andere Controller anpassen oder sich mit dem Programm MFile menügesteuert ein Makefile &amp;quot;zusammenklicken&amp;quot;. Das Makefile speichert man unter dem Namen &amp;lt;code&amp;gt;Makefile&amp;lt;/code&amp;gt; (ohne Endung) im selben Verzeichnis, in dem auch die Datei &amp;lt;code&amp;gt;main.c&amp;lt;/code&amp;gt; mit dem Programmcode abgelegt ist. Detailliertere Erklärungen zur Funktion von Makefiles finden sich im Artikel [[AVR-GCC-Tutorial/Exkurs_Makefiles|Exkurs: Makefiles]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
D:\beispiel&amp;gt;dir&lt;br /&gt;
&lt;br /&gt;
 Verzeichnis von D:\beispiel&lt;br /&gt;
&lt;br /&gt;
28.11.2006  22:53    &amp;lt;DIR&amp;gt;          .&lt;br /&gt;
28.11.2006  22:53    &amp;lt;DIR&amp;gt;          ..&lt;br /&gt;
28.11.2006  20:06               118 main.c&lt;br /&gt;
28.11.2006  20:03            16.810 Makefile&lt;br /&gt;
               2 Datei(en)         16.928 Bytes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nun gibt man &#039;&#039;make all&#039;&#039; ein. Falls das mit WinAVR installierte Programmers Notepad genutzt wird, gibt es dazu einen Menüpunkt im Tools Menü. Sind alle Einstellungen korrekt, entsteht eine Datei &amp;lt;code&amp;gt;main.hex&amp;lt;/code&amp;gt;, in welcher der Code für den AVR enthalten ist. &lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
D:\beispiel&amp;gt;make all&lt;br /&gt;
&lt;br /&gt;
-------- begin --------&lt;br /&gt;
avr-gcc (GCC) 3.4.6&lt;br /&gt;
Copyright (C) 2006 Free Software Foundation, Inc.&lt;br /&gt;
This is free software; see the source for copying conditions.  There is NO&lt;br /&gt;
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&lt;br /&gt;
&lt;br /&gt;
Compiling C: main.c&lt;br /&gt;
avr-gcc -c -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=1000000UL -Os -funsigned-char -f&lt;br /&gt;
unsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wundef&lt;br /&gt;
 -Wa,-adhlns=obj/main.lst  -std=gnu99 -Wundef -MD -MP -MF .dep/main.o.d main.c -&lt;br /&gt;
o obj/main.o&lt;br /&gt;
&lt;br /&gt;
Linking: main.elf&lt;br /&gt;
avr-gcc -mmcu=atmega16 -I. -gdwarf-2 -DF_CPU=1000000UL -Os -funsigned-char -funs&lt;br /&gt;
igned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wundef -W&lt;br /&gt;
a,-adhlns=obj/main.o  -std=gnu99 -Wundef -MD -MP -MF .dep/main.elf.d obj/main.o&lt;br /&gt;
--output main.elf -Wl,-Map=main.map,--cref    -lm&lt;br /&gt;
&lt;br /&gt;
Creating load file for Flash: main.hex&lt;br /&gt;
avr-objcopy -O ihex -R .eeprom main.elf main.hex&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Inhalt der hex-Datei kann nun zum Controller übertragen werden. Dies kann z.&amp;amp;nbsp;B. über In-System-Programming ([[ISP]]) erfolgen, das im [[AVR-Tutorial: Equipment]] beschrieben ist. Makefiles nach der WinAVR/MFile-Vorlage sind für die Nutzung des Programms [[AVRDUDE]] vorbereitet. Wenn man den Typ und Anschluss des Programmiergerätes richtig eingestellt hat, kann mit &#039;&#039;make program&#039;&#039; die Übertragung mittels AVRDUDE gestartet werden. Jede andere Software, die hex-Dateien lesen und zu einem AVR übertragen kann&amp;lt;ref&amp;gt;z.&amp;amp;nbsp;B. [[Pony-Prog_Tutorial|Ponyprog]], yapp, AVRStudio&amp;lt;/ref&amp;gt;, kann natürlich ebenfalls genutzt werden.&lt;br /&gt;
&lt;br /&gt;
Startet man nun den Controller (Reset-Taster oder Stromzufuhr aus/an), werden vom Programm die Anschlüsse PB0 und PB1 auf 1 gesetzt. Man kann mit einem Messgerät nun an diesem Anschluss die Betriebsspannung messen oder eine [[LED]] leuchten lassen (Anode an den Pin, Vorwiderstand nicht vergessen). An den Anschlüssen PB2-PB7 misst man 0 Volt. Eine mit der Anode mit einem dieser Anschlüsse verbundene LED leuchtet nicht.&lt;br /&gt;
&lt;br /&gt;
= Ganzzahlige (Integer) Datentypen =&lt;br /&gt;
&lt;br /&gt;
Bei der Programmierung von Mikrokontrollern ist die Definition einiger ganzzahliger Datentypen sinnvoll, an denen eindeutig die Bit-Länge abgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Standardisierte Datentypen werden in der Header-Datei &amp;lt;code&amp;gt;stdint.h&amp;lt;/code&amp;gt; definiert, die folgendermaßen eingebunden werden kann:&lt;br /&gt;
&amp;lt;c&amp;gt;#include &amp;lt;stdint.h&amp;gt;&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| {{Tabelle}}&lt;br /&gt;
|+ &#039;&#039;&#039;int-Typen aus &amp;lt;code&amp;gt;stdint.h&amp;lt;/code&amp;gt; (C99)&#039;&#039;&#039;&amp;lt;br/&amp;gt;&amp;amp;nbsp;&lt;br /&gt;
|- bgcolor=&amp;quot;#d0d0ff&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;5&amp;quot;| Vorzeichenbehaftete int-Typen&lt;br /&gt;
|- bgcolor=&amp;quot;#e8e8ff&amp;quot;&lt;br /&gt;
! Typname || Bit-Breite ||colspan=&amp;quot;2&amp;quot;| Wertebereich&lt;br /&gt;
|align=&amp;quot;center| &#039;&#039;&#039;C-Entsprechung&#039;&#039;&#039; (avr-gcc)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;int8_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 8 || −128 ⋯ 127 || −2&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt; ⋯ 2&amp;lt;sup&amp;gt;7&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;signed char&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;int16_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 16 || −32768 ⋯ 32767 || −2&amp;lt;sup&amp;gt;15&amp;lt;/sup&amp;gt; ⋯ 2&amp;lt;sup&amp;gt;15&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;signed short&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;signed int&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;int32_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 32 || −2147483648 ⋯ 2147483647 || −2&amp;lt;sup&amp;gt;31&amp;lt;/sup&amp;gt; ⋯ 2&amp;lt;sup&amp;gt;31&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;signed long&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;int64_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 64 || −9223372036854775808 ⋯ 9223372036854775807 || −2&amp;lt;sup&amp;gt;63&amp;lt;/sup&amp;gt; ⋯ 2&amp;lt;sup&amp;gt;63&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;signed long long&amp;lt;/code&amp;gt;&lt;br /&gt;
|- bgcolor=&amp;quot;#d0d0ff&amp;quot;&lt;br /&gt;
!colspan=&amp;quot;5&amp;quot;| Vorzeichenlose int-Typen&lt;br /&gt;
|- bgcolor=&amp;quot;#e8e8ff&amp;quot;&lt;br /&gt;
! Typname || Bit-Breite ||colspan=&amp;quot;2&amp;quot;| Wertebereich&lt;br /&gt;
|align=&amp;quot;center| &#039;&#039;&#039;C-Entsprechung&#039;&#039;&#039; (avr-gcc)&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;uint8_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 8 || 0 ⋯ 255 || 0 ⋯ 2&amp;lt;sup&amp;gt;8&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;unsigned char&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;uint16_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 16 || 0 ⋯ 65535 || 0 ⋯ 2&amp;lt;sup&amp;gt;16&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;unsigned short&amp;lt;/code&amp;gt;, &amp;lt;code&amp;gt;unsigned int&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;uint32_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 32 || 0 ⋯ 4294967295 || 0 ⋯ 2&amp;lt;sup&amp;gt;32&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;unsigned long&amp;lt;/code&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|&amp;lt;code&amp;gt;uint64_t&amp;lt;/code&amp;gt; ||align=&amp;quot;right&amp;quot;| 64 || 0 ⋯ 18446744073709551615 || 0 ⋯ 2&amp;lt;sup&amp;gt;64&amp;lt;/sup&amp;gt;−1 || &amp;lt;code&amp;gt;unsigned long long&amp;lt;/code&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Neben den Typen gibt es auch Makros für die Bereichsgrenzen wie &amp;lt;code&amp;gt;INT8_MIN&amp;lt;/code&amp;gt; oder &amp;lt;code&amp;gt;UINT16_MAX&amp;lt;/code&amp;gt;. Siehe dazu auch: [http://www.nongnu.org/avr-libc/user-manual/group__avr__stdint.html Dokumentation der avr-libc: Standard Integer Types].&lt;br /&gt;
&lt;br /&gt;
= Bitfelder =&lt;br /&gt;
&lt;br /&gt;
Beim Programmieren von Mikrocontrollern muss auf jedes Byte oder sogar auf&lt;br /&gt;
jedes Bit geachtet werden. Oft müssen wir in einer Variablen lediglich den&lt;br /&gt;
Zustand 0 oder 1 speichern. Wenn wir nun zur Speicherung eines einzelnen Wertes&lt;br /&gt;
den kleinsten bekannten Datentypen, nämlich &#039;&#039;&#039;unsigned char&#039;&#039;&#039;, nehmen, dann&lt;br /&gt;
verschwenden wir 7 Bits, da ein &#039;&#039;&#039;unsigned char&#039;&#039;&#039; ja 8 Bits breit ist.&lt;br /&gt;
&lt;br /&gt;
Hier bietet uns die Programmiersprache C ein mächtiges Werkzeug an, mit dessen&lt;br /&gt;
Hilfe wir 8 Bits in eine einzelne Bytevariable zusammenfassen und (fast) wie&lt;br /&gt;
8 einzelne Variablen ansprechen können. Die Rede ist von sogenannten Bitfeldern. Diese werden als Strukturelemente definiert. Sehen wir uns dazu doch am besten gleich ein Beispiel an:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
struct {&lt;br /&gt;
   unsigned bStatus_1:1; // 1 Bit für bStatus_1&lt;br /&gt;
   unsigned bStatus_2:1; // 1 Bit für bStatus_2&lt;br /&gt;
   unsigned bNochNBit:1; // Und hier noch mal ein Bit&lt;br /&gt;
   unsigned b2Bits:2;    // Dieses Feld ist 2 Bits breit&lt;br /&gt;
   // All das hat in einer einzigen Byte-Variable Platz.&lt;br /&gt;
   // die 3 verbleibenden Bits bleiben ungenutzt&lt;br /&gt;
} x;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Zugriff auf ein solches Feld erfolgt nun, wie beim Strukturzugriff bekannt,&lt;br /&gt;
über den Punkt- oder den Dereferenzierungs-Operator:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
x.bStatus_1 = 1;&lt;br /&gt;
x.bStatus_2 = 0;&lt;br /&gt;
x.b2Bits = 3;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bitfelder sparen Platz im RAM, zu Lasten von Platz im Flash, verschlechtern aber unter Umständen die Les- und Wartbarkeit des Codes. Anfängern wird deshalb geraten, ein &amp;quot;ganzes&amp;quot; Byte (uint8_t) zu nutzen, auch wenn nur ein Bitwert gespeichert werden soll.&lt;br /&gt;
&lt;br /&gt;
= Grundsätzlicher Programmaufbau eines µC-Programms =&lt;br /&gt;
&lt;br /&gt;
Wir unterscheiden zwischen 2 verschiedenen Methoden, um ein&lt;br /&gt;
Mikrocontroller-Programm zu schreiben, und zwar völlig unabhängig davon, in&lt;br /&gt;
welcher Programmiersprache das Programm geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
== Sequentieller Programmablauf ==&lt;br /&gt;
&lt;br /&gt;
[[Image:Sequentielle Programme.gif|left]]&lt;br /&gt;
Bei dieser Programmiertechnik wird eine Endlosschleife programmiert, welche im&lt;br /&gt;
Wesentlichen immer den gleichen Aufbau hat. Es wird hier nach dem sogenannten EVA-Prinzip gehandelt. EVA steht für &amp;quot;Eingabe, Verarbeitung, Ausgabe&amp;quot;:&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
== Interruptgesteuerter Programmablauf ==&lt;br /&gt;
&lt;br /&gt;
[[Image:Interrupt Programme.gif|left]]&lt;br /&gt;
Bei dieser Methode werden beim Programmstart zuerst die gewünschten Interruptquellen aktiviert und dann in eine Endlosschleife gegangen, in welcher Dinge erledigt werden können, welche nicht zeitkritisch sind. Wenn ein Interrupt ausgelöst wird, so wird automatisch die zugeordnete Interruptfunktion ausgeführt.&lt;br /&gt;
{{Absatz}}&lt;br /&gt;
&lt;br /&gt;
= Zugriff auf Register =&lt;br /&gt;
&lt;br /&gt;
Die AVR-Controller verfügen über eine Vielzahl von Registern. Die meisten&lt;br /&gt;
davon sind sogenannte Schreib-/Leseregister. Das heißt, das Programm kann die&lt;br /&gt;
Inhalte der Register sowohl auslesen als auch beschreiben.&lt;br /&gt;
&lt;br /&gt;
Register haben einen besonderen Stellenwert bei den AVR Controllern. Sie dienen dem Zugriff auf die Ports und die Schnittstellen des Controllers. Wir unterscheiden zwischen 8-Bit und 16-Bit Registern. Vorerst behandeln wir die 8-Bit Register.&lt;br /&gt;
&lt;br /&gt;
Einzelne Register sind bei allen AVRs vorhanden, andere wiederum nur bei bestimmten Typen. So sind beispielsweise die Register, welche für den Zugriff auf den UART notwendig sind, selbstverständlich nur bei denjenigen Modellen vorhanden, welche über einen integrierten Hardware UART bzw. USART verfügen.&lt;br /&gt;
&lt;br /&gt;
Die Namen der Register sind in den Headerdateien zu den entsprechenden AVR-Typen definiert. Dazu muss man den Namen der controllerspezifischen Headerdatei nicht kennen. Es reicht aus, die allgemeine Headerdatei &#039;&#039;avr/io.h&#039;&#039; einzubinden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ist im Makefile der MCU-Typ z.&amp;amp;nbsp;B. mit dem Inhalt atmega8 definiert (und wird somit per -mmcu=atmega8 an den Compiler übergeben), wird beim Einlesen der io.h-Datei implizit (&amp;quot;automatisch&amp;quot;) auch die iom8.h-Datei mit den Register-Definitionen für den ATmega8 eingelesen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Wohl besser als Anhang - spaeter... --&amp;gt;&lt;br /&gt;
Intern wird diese &amp;quot;Automatik&amp;quot; wie folgt realisiert: Der Controllertyp wird dem Compiler als Parameter übergeben (vgl. &#039;&#039;avr-gcc -c -mmcu=atmega16 [...]&#039;&#039; im Einführungsbeispiel). Wird ein Makefile nach der WinAVR/mfile-Vorlage verwendet, setzt man die Variable &#039;&#039;MCU&#039;&#039;, der Inhalt dieser Variable wird dann an passender Stelle für die Compilerparameter verwendet. Der Compiler definiert intern eine dem mmcu-Parameter zugeordnete &amp;quot;Variable&amp;quot; (genauer: ein Makro) mit dem Namen des Controllers, vorangestelltem &#039;&#039;__AVR_&#039;&#039; und angehängten Unterstrichen (z.&amp;amp;nbsp;B. wird bei &#039;&#039;-mmcu=atmega16&#039;&#039; das Makro &#039;&#039;__AVR_ATmega16__&#039;&#039; definiert). Beim Einbinden der Header-Datei &#039;&#039;avr/io.h&#039;&#039; wird geprüft, ob das jeweilige Makro definiert ist und die zum Controller passende Definitionsdatei eingelesen. Zur Veranschaulichung einige Ausschnitte aus einem Makefile:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
[...]&lt;br /&gt;
# MCU Type (&amp;quot;name&amp;quot;) setzen:&lt;br /&gt;
MCU = atmega16&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
## Verwendung des Inhalts von MCU (hier atmega16) fuer die &lt;br /&gt;
## Compiler- und Assembler-Parameter&lt;br /&gt;
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS)&lt;br /&gt;
ALL_CPPFLAGS = -mmcu=$(MCU) -I. -x c++ $(CPPFLAGS) $(GENDEPFLAGS)&lt;br /&gt;
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)&lt;br /&gt;
[...]&lt;br /&gt;
&lt;br /&gt;
[...]&lt;br /&gt;
## Aufruf des Compilers:&lt;br /&gt;
## mit den Parametern ($(ALL_CFLAGS) ist -mmcu=$(MCU)[...] = -mmcu=atmega16[...]&lt;br /&gt;
$(OBJDIR)/%.o : %.c&lt;br /&gt;
	@echo&lt;br /&gt;
	@echo $(MSG_COMPILING) $&amp;lt;&lt;br /&gt;
	$(CC) -c $(ALL_CFLAGS) $&amp;lt; -o $@ &lt;br /&gt;
[...]&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Da --mmcu=atmega16 übergeben wurde, wird __AVR_ATmega16__ definiert und kann in avr/io.h zur Fallunterscheidung genutzt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// avr/io.h &lt;br /&gt;
// (bei WinAVR-Standardinstallation in C:\WinAVR\avr\include\avr)&lt;br /&gt;
[...]&lt;br /&gt;
#if defined (__AVR_AT94K__)&lt;br /&gt;
#  include &amp;lt;avr/ioat94k.h&amp;gt;&lt;br /&gt;
// [...]&lt;br /&gt;
#elif defined (__AVR_ATmega16__)&lt;br /&gt;
// da __AVR_ATmega16__ definiert ist, wird avr/iom16.h eingebunden:&lt;br /&gt;
#  include &amp;lt;avr/iom16.h&amp;gt;&lt;br /&gt;
// [...]&lt;br /&gt;
#else&lt;br /&gt;
#  if !defined(__COMPILING_AVR_LIBC__)&lt;br /&gt;
#    warning &amp;quot;device type not defined&amp;quot;&lt;br /&gt;
#  endif&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Beispiele in den folgenden Abschnitten demonstrieren den Zugriff auf Register anhand der Register für I/O-Ports (PORTx, DDRx, PINx), die Vorgehensweise ist jedoch für alle Register (z.&amp;amp;nbsp;B. die des UART, ADC, SPI) analog.&lt;br /&gt;
&lt;br /&gt;
== Schreiben in Register ==&lt;br /&gt;
&lt;br /&gt;
Zum Schreiben kann man Register einfach wie eine Variable setzen.&amp;lt;ref&amp;gt;In Quellcodes, die für ältere Versionen des avr-gcc/der avr-libc entwickelt wurden, erfolgt der Schreibzugriff über die Funktion outp(). Aktuelle Versionen des Compilers unterstützen den Zugriff nun direkt, outp() ist nicht mehr erforderlich.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
    /* Setzt das Richtungsregister des Ports A auf 0xff &lt;br /&gt;
       (alle Pins als Ausgang, vgl. Abschnitt Zugriff auf Ports): */&lt;br /&gt;
    DDRA = 0xff;    &lt;br /&gt;
&lt;br /&gt;
    /* Setzt PortA auf 0x03, Bit 0 und 1 &amp;quot;high&amp;quot;, restliche &amp;quot;low&amp;quot;: */&lt;br /&gt;
    PORTA = 0x03;   &lt;br /&gt;
&lt;br /&gt;
    // Setzen der Bits 0,1,2,3 und 4&lt;br /&gt;
    // Binär 00011111 = Hexadezimal 1F&lt;br /&gt;
    DDRB = 0x1F;    /* direkte Zuweisung - unübersichtlich */&lt;br /&gt;
&lt;br /&gt;
    /* Ausführliche Schreibweise: identische Funktionalität, mehr Tipparbeit&lt;br /&gt;
       aber übersichtlicher und selbsterklärend: */&lt;br /&gt;
    DDRB = (1 &amp;lt;&amp;lt; DDB0) | (1 &amp;lt;&amp;lt; DDB1) | (1 &amp;lt;&amp;lt; DDB2) | (1 &amp;lt;&amp;lt; DDB3) | (1 &amp;lt;&amp;lt; DDB4);&lt;br /&gt;
&lt;br /&gt;
    while (1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die ausführliche Schreibweise sollte bevorzugt verwendet werden, da dadurch die Zuweisungen selbsterklärend sind und somit der Code leichter nachvollzogen werden kann. Atmel verwendet sie auch bei Beispielen in Datenblätten und in den allermeisten Quellcodes zu Application-Notes. Mehr zu der Schreibweise mit &amp;quot;|&amp;quot; und &amp;quot;&amp;lt;&amp;lt;&amp;quot; findet man unter [[Bitmanipulation]].&lt;br /&gt;
&lt;br /&gt;
Der gcc C-Compiler unterstützt ab Version 4.3.0 Konstanten im Binärformat, z.&amp;amp;nbsp;B. DDRB&amp;amp;nbsp;=&amp;amp;nbsp;0b00011111. Diese Schreibweise ist jedoch nur in GNU-C verfügbar und nicht in ISO-C definiert. Man sollte sie daher nicht verwenden, wenn Code mit anderen ausgetauscht oder mit anderen Compilern bzw. älteren Versionen des gcc genutzt werden soll.&lt;br /&gt;
&lt;br /&gt;
== Verändern von Registerinhalten ==&lt;br /&gt;
&lt;br /&gt;
Einzelne Bits setzt und löscht man &amp;quot;Standard-C-konform&amp;quot; mittels logischer (Bit-) Operationen. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
 x |= (1 &amp;lt;&amp;lt; Bitnummer);  // Hiermit wird ein Bit in x gesetzt&lt;br /&gt;
 x &amp;amp;= ~(1 &amp;lt;&amp;lt; Bitnummer); // Hiermit wird ein Bit in x geloescht&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Es wird jeweils nur der Zustand des angegebenen Bits geändert, der vorherige Zustand der anderen Bits bleibt erhalten. &lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
#define MEINBIT 2&lt;br /&gt;
...&lt;br /&gt;
PORTA |= (1 &amp;lt;&amp;lt; MEINBIT);    /* setzt Bit 2 an PortA auf 1 */&lt;br /&gt;
PORTA &amp;amp;= ~(1 &amp;lt;&amp;lt; MEINBIT);   /* loescht Bit 2 an PortA */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit dieser Methode lassen sich auch mehrere Bits eines Registers gleichzeitig setzen und löschen.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
DDRA &amp;amp;= ~( (1&amp;lt;&amp;lt;PA0) | (1&amp;lt;&amp;lt;PA3) );  /* PA0 und PA3 als Eingaenge */&lt;br /&gt;
PORTA |= (1&amp;lt;&amp;lt;PA0) | (1&amp;lt;&amp;lt;PA3);      /* Interne Pull-Up fuer beide einschalten */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei bestimmten AVR Registern mit Bits, die durch Beschreiben mit einer logischen 1 gelöscht werden, muss eine absolute Zuweisung benutzt werden. Ein ODER löscht in diesen Registern ALLE gesetzten Bits!&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
TIFR2 = (1&amp;lt;&amp;lt;OCF2A); // Nur Bit OCF2A löschen&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In Quellcodes, die für ältere Version den des avr-gcc/der avr-libc entwickelt wurden, werden einzelne Bits mittels der Funktionen sbi und cbi gesetzt bzw. gelöscht. Beide Funktionen sind nicht mehr erforderlich.&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* [[Bitmanipulation]]&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/Special Function Registers&lt;br /&gt;
&lt;br /&gt;
== Lesen aus Registern ==&lt;br /&gt;
&lt;br /&gt;
Zum Lesen kann man auf Register einfach wie auf eine Variable zugreifen. In Quellcodes, die für ältere Versionen des avr-gcc/der avr-libc entwickelt wurden, erfolgt der Lesezugriff über die Funktion inp(). Aktuelle Versionen des Compilers unterstützen den Zugriff nun direkt und inp() ist nicht mehr erforderlich.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
uint8_t foo;&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    /* kopiert den Status der Eingabepins an PortB &lt;br /&gt;
       in die Variable foo: */&lt;br /&gt;
    foo = PINB;    &lt;br /&gt;
    //...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Abfrage der Zustände von Bits erfolgt durch Einlesen des gesamten Registerinhalts und ausblenden der Bits deren Zustand nicht von Interesse ist. Einige Beispiele zum Prüfen ob Bits gesetzt oder gelöscht sind:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#define MEINBIT0 0 &lt;br /&gt;
#define MEINBIT2 2&lt;br /&gt;
&lt;br /&gt;
uint8_t i;&lt;br /&gt;
&lt;br /&gt;
extern test1();&lt;br /&gt;
&lt;br /&gt;
// Funkion test1 aufrufen, wenn Bit 0 in Register PINA gesetzt (1) ist&lt;br /&gt;
i = PINA;         // Inhalt in Arbeitsvariable&lt;br /&gt;
i = i &amp;amp; 0x01;     // alle Bits bis auf Bit 0 ausblenden (bitweise und)&lt;br /&gt;
                  // falls das Bit gesetzt war, hat i den Inhalt 1&lt;br /&gt;
if ( i != 0 ) {   // Ergebnis ungleich 0 (wahr)? &lt;br /&gt;
  test1();         // dann muss Bit 0 in i gesetzt sein -&amp;gt; Funktion aufrufen&lt;br /&gt;
}&lt;br /&gt;
// verkürzt:&lt;br /&gt;
if ( ( PINA &amp;amp; 0x01 ) != 0 ) {&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
// nochmals verkürzt:&lt;br /&gt;
if ( PINA &amp;amp; 0x01 ) {&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
// mit definierter Bitnummer:&lt;br /&gt;
if ( PINA &amp;amp; ( 1 &amp;lt;&amp;lt; MEINBIT0 ) ) {&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Funktion aufrufen, wenn Bit 0 und/oder Bit 2 gesetzt ist. (Bit 0 und 2 also Wert 5) &lt;br /&gt;
// (Bedenke: Bit 0 hat Wert 1, Bit 1 hat Wert 2 und Bit 2 hat Wert 4)&lt;br /&gt;
if ( PINA &amp;amp; 0x05 ) {&lt;br /&gt;
  test1();  // Vergleich &amp;lt;&amp;gt; 0 (wahr), also mindestens eines der Bits gesetzt&lt;br /&gt;
}&lt;br /&gt;
// mit definierten Bitnummern:&lt;br /&gt;
if ( PINA &amp;amp; ( ( 1 &amp;lt;&amp;lt; MEINBIT0 ) | ( 1 &amp;lt;&amp;lt; MEINBIT2 ) ) ) {&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Funktion aufrufen, wenn Bit 0 und Bit 2 gesetzt sind&lt;br /&gt;
if ( ( PINA &amp;amp; 0x05 ) == 0x05 ) {  // nur wahr, wenn beide Bits gesetzt&lt;br /&gt;
  test1();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Funktion test2() aufrufen, wenn Bit 0 gelöscht (0) ist&lt;br /&gt;
i = PINA;        // einlesen in temporäre Variable&lt;br /&gt;
i = i &amp;amp; 0x01;    // maskieren von Bit 0&lt;br /&gt;
if ( i == 0 ) {  // Vergleich ist wahr, wenn Bit 0 nicht gesetzt ist&lt;br /&gt;
  test2();&lt;br /&gt;
}&lt;br /&gt;
// analog mit not-Operator&lt;br /&gt;
if ( !i ) {&lt;br /&gt;
  test2();&lt;br /&gt;
}&lt;br /&gt;
// nochmals verkürzt:&lt;br /&gt;
if ( !( PINA &amp;amp; 0x01 ) ) {&lt;br /&gt;
  test2();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Warten auf einen bestimmten Zustand ==&lt;br /&gt;
&lt;br /&gt;
Es gibt in der Bibliothek avr-libc Funktionen, die warten, bis ein bestimmter Zustand eines Bits erreicht ist. Es ist allerdings normalerweise eine eher unschöne Programmiertechnik, da in diesen Funktionen &amp;quot;blockierend&amp;quot; gewartet wird. Der Programmablauf bleibt also an dieser Stelle stehen, bis das maskierte Ereignis erfolgt ist. Setzt man den [[Watchdog]] ein, muss man darauf achten, dass dieser auch noch getriggert wird (Zurücksetzen des Watchdogtimers). &lt;br /&gt;
&lt;br /&gt;
Die Funktion &#039;&#039;&#039;loop_until_bit_is_set&#039;&#039;&#039; wartet in einer Schleife, bis das definierte Bit gesetzt ist. Wenn das Bit beim Aufruf der Funktion bereits gesetzt ist, wird die Funktion sofort wieder verlassen. Das niederwertigste Bit hat die Bitnummer 0. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
/* Warten bis Bit Nr. 2 (das dritte Bit) in Register PINA gesetzt (1) ist */&lt;br /&gt;
&lt;br /&gt;
#define WARTEPIN PINA&lt;br /&gt;
#define WARTEBIT PA2&lt;br /&gt;
&lt;br /&gt;
// mit der avr-libc Funktion:&lt;br /&gt;
loop_until_bit_is_set(WARTEPIN, WARTEBIT);&lt;br /&gt;
&lt;br /&gt;
// dito in &amp;quot;C-Standard&amp;quot;:&lt;br /&gt;
// Durchlaufe die (leere) Schleife solange das WARTEBIT in Register WARTEPIN&lt;br /&gt;
// _nicht_ ungleich 0 (also 0) ist.&lt;br /&gt;
while ( !(WARTEPIN &amp;amp; (1 &amp;lt;&amp;lt; WARTEBIT)) ) {}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Funktion &#039;&#039;&#039;loop_until_bit_is_clear&#039;&#039;&#039; wartet in einer Schleife, bis das definierte Bit gelöscht ist. Wenn das Bit beim Aufruf der Funktion bereits gelöscht ist, wird die Funktion sofort wieder verlassen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
/* Warten bis Bit Nr. 4 (das fuenfte Bit) in Register PINB geloescht (0) ist */&lt;br /&gt;
#define WARTEPIN PINB&lt;br /&gt;
#define WARTEBIT PB4&lt;br /&gt;
&lt;br /&gt;
// avr-libc-Funktion:&lt;br /&gt;
loop_until_bit_is_clear(WARTEPIN, WARTEBIT);&lt;br /&gt;
&lt;br /&gt;
// dito in &amp;quot;C-Standard&amp;quot;:&lt;br /&gt;
// Durchlaufe die (leere) Schleife solange das WARTEBIT in Register WARTEPIN&lt;br /&gt;
// gesetzt (1) ist &lt;br /&gt;
while ( WARTEPIN &amp;amp; (1&amp;lt;&amp;lt;WARTEBIT) ) {}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Universeller und auch auf andere Plattformen besser übertragbar ist die Verwendung von C-Standardoperationen.&lt;br /&gt;
&lt;br /&gt;
Siehe auch: &lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/Special Function Registers&lt;br /&gt;
* [[Bitmanipulation]]&lt;br /&gt;
&lt;br /&gt;
== 16-Bit Register (ADC, ICR1, OCR1x, TCNT1, UBRR) ==&lt;br /&gt;
&lt;br /&gt;
Einige der Portregister in den AVR-Controllern sind 16 Bit breit. Im Datenblatt sind diese Register üblicherweise mit dem Suffix &amp;quot;L&amp;quot; (Low-Byte) und &amp;quot;H&amp;quot; (High-Byte) versehen. Die avr-libc definiert zusätzlich die meisten dieser Variablen die Bezeichnung ohne &amp;quot;L&amp;quot; oder &amp;quot;H&amp;quot;. Auf diese Register kann dann direkt zugegriffen werden. Dies ist zum Beispiel der Fall für Register wie ADC oder TCNT1.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
    uint16_t foo;&lt;br /&gt;
&lt;br /&gt;
    /* setzt die Wort-Variable foo auf den Wert der letzten AD-Wandlung */&lt;br /&gt;
    foo = ADC; &lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei anderen Registern, wie zum Beispiel Baudraten-Register, liegen High- und Low-Teil nicht direkt nebeneinander im SFR-Bereich, so dass ein 16-Bit Zugriff nicht möglich ist und der Zugriff zusammengebastelt werden muss:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
#define F_CPU 3686400&lt;br /&gt;
#endif&lt;br /&gt;
#define UART_BAUD_RATE 9600&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
   uint16_t baud = F_CPU / (UART_BAUD_RATE * 16L) -1;&lt;br /&gt;
&lt;br /&gt;
   UBRRH = (uint8_t) (baud &amp;gt;&amp;gt; 8);&lt;br /&gt;
   UBRRL = (uint8_t) baud;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Bei einigen AVR-Typen wie ATmega8 oder ATmega16 teilen sich UBRRH und UCSRC die gleiche Speicher-Adresse. Damit der AVR trotzdem zwischen den beiden Registern unterscheiden kann, bestimmt das Bit7 (URSEL), welches Register tatsächlich beschrieben werden soll. &#039;&#039;1000 0011&#039;&#039; (0x83) adressiert demnach UCSRC und übergibt den Wert &#039;&#039;3&#039;&#039; und &#039;&#039;0000 0011&#039;&#039; (0x3) adressiert UBRRH und übergibt ebenfalls den Wert &#039;&#039;3&#039;&#039;. &lt;br /&gt;
&lt;br /&gt;
Speziell bei den 16-Bit-Timern und auch beim ADC ist es bei allen Zugriffen auf Datenregister erforderlich, dass diese Daten synchronisiert sind. Wenn z.&amp;amp;nbsp;B. bei einem 16-Bit-Timer das High-Byte des Zählregisters gelesen wurde und vor dem Lesezugriff auf das Low-Byte ein Überlauf des Low-Bytes stattfindet, erhält man einen völlig unsinnigen Wert. Auch die Compare-Register müssen synchron geschrieben werden, da es ansonsten zu unerwünschten Compare-Ereignissen kommen kann. &lt;br /&gt;
&lt;br /&gt;
Beim ADC besteht das Problem darin, dass zwischen den Zugriffen auf die beiden Teilregister eine Wandlung beendet werden kann und der ADC ein neues Ergebnis in ADCL und ADCH schreiben will, wodurch High- und Low-Byte nicht zusammenpassen.&lt;br /&gt;
&lt;br /&gt;
Um diese Datenmüllproduktion zu verhindern, gibt es in beiden Fällen eine Synchronisation, die jeweils durch den Zugriff auf das Low-Byte ausgelöst wird:&lt;br /&gt;
* Bei den Timer-Registern (das gilt für alle TCNT-, OCR- und ICR-Register bei den 16-Bit-Timern) wird bei einem &#039;&#039;Lesezugriff&#039;&#039; auf das Low-Byte automatisch das High-Byte in ein temporäres Register, das ansonsten nach außen nicht sichtbar ist, geschoben. Greift man nun &#039;&#039;anschließend&#039;&#039; auf das High-Byte zu, dann wird eben dieses temporäre Register gelesen.&lt;br /&gt;
* Bei einem &#039;&#039;Schreibzugriff&#039;&#039; auf eines der genannten Register wird das High-Byte in besagtem temporären Register zwischengespeichert und erst beim Schreiben des Low-Bytes werden &#039;&#039;beide&#039;&#039; gleichzeitig in das eigentliche Register übernommen.&lt;br /&gt;
&lt;br /&gt;
Das bedeutet für die Reihenfolge:&lt;br /&gt;
* Lesezugriff: Erst Low-Byte, dann High-Byte&lt;br /&gt;
* Schreibzugriff: Erst High-Byte, dann Low-Byte&lt;br /&gt;
&lt;br /&gt;
Des weiteren ist zu beachten, dass es für all diese 16-Bit-Register nur ein einziges temporäres Register gibt, so dass das Auftreten eines Interrupts, in dessen Handler ein solches Register manipuliert wird, bei einem durch ihn unterbrochenen Zugriff i.d.R. zu Datenmüll führt. 16-Bit-Zugriffe sind generell nicht atomar! Wenn mit Interrupts gearbeitet wird, kann es erforderlich sein, vor einem solchen Zugriff auf ein 16-Bit-Register die Interrupt-Bearbeitung zu deaktivieren.&lt;br /&gt;
&lt;br /&gt;
Beim ADC-Datenregister ADCH/ADCL ist die Synchronisierung anders gelöst. Hier wird beim Lesezugriff (ADCH/ADCL sind logischerweise read-only) auf das Low-Byte ADCL beide Teilregister für Zugriffe seitens des ADC so lange gesperrt, bis das High-Byte ADCH ausgelesen wurde. Dadurch kann der ADC nach einem Zugriff auf ADCL keinen neuen Wert in ADCH/ADCL ablegen, bis ADCH gelesen wurde. Ergebnisse von Wandlungen, die zwischen einem Zugriff auf ADCL und ADCH beendet werden, gehen verloren!&lt;br /&gt;
&lt;br /&gt;
Nach einem Zugriff auf ADCL muss grundsätzlich ADCH gelesen werden!&lt;br /&gt;
&lt;br /&gt;
In beiden Fällen – also sowohl bei den Timern als auch beim ADC – werden vom C-Compiler 16-Bit Pseudo-Register zur Verfügung gestellt (z.&amp;amp;nbsp;B. TCNT1H/TCNT1L → TCNT1, ADCH/ADCL → ADC bzw. ADCW), bei deren Verwendung der Compiler automatisch die richtige Zugriffsreihenfolge regelt. In C-Programmen sollten grundsätzlich diese 16-Bit-Register verwendet werden! Sollte trotzdem ein Zugriff auf ein Teilregister erforderlich sein, sind obige Angaben zu berücksichtigen.&lt;br /&gt;
&lt;br /&gt;
Es ist darauf zu achten, dass auch ein Zugriff auf die 16-Bit-Register vom Compiler in zwei 8-Bit-Zugriffe aufgeteilt wird und dementsprechend genauso nicht-atomar ist wie die Einzelzugriffe. Auch hier gilt, dass u.U. die Interrupt-Bearbeitung gesperrt werden muss, um Datenmüll zu vermeiden.&lt;br /&gt;
&lt;br /&gt;
Beim ADC gibt es für den Fall, dass eine Auflösung von 8 Bit ausreicht, die Möglichkeit, das Ergebnis &amp;quot;linksbündig&amp;quot; in ADCH/ADCL auszurichten, so dass die relevanten 8 MSB in ADCH stehen. In diesem Fall muss bzw. sollte nur ADCH ausgelesen werden.&lt;br /&gt;
&lt;br /&gt;
ADC und ADCW sind unterschiedliche Bezeichner für das selbe Registerpaar. Üblicherweise kann man in C-Programmen ADC verwenden, was analog zu den anderen 16-Bit-Registern benannt ist. ADCW (ADC Word) existiert nur deshalb, weil die Headerdateien auch für Assembler vorgesehen sind und es bereits einen Assembler-Befehl namens &#039;&#039;adc&#039;&#039; gibt. &lt;br /&gt;
&lt;br /&gt;
Im Umgang mit 16-Bit Registern siehe auch:&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Related Pages/Frequently Asked Questions/Nr. 8&lt;br /&gt;
* Datenblatt Abschnitt &#039;&#039;Accessing 16-bit Registers&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== IO-Register als Parameter und Variablen ==&lt;br /&gt;
&lt;br /&gt;
Um Register als Parameter für eigene Funktionen übergeben zu können, muss man sie als einen volatile uint8_t Pointer übergeben. Zum Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
uint8_t key_pressed (volatile uint8_t *inputreg, uint8_t inputbit)&lt;br /&gt;
{&lt;br /&gt;
  static uint8_t last_state = 0;&lt;br /&gt;
 &lt;br /&gt;
  if (last_state == (*inputreg &amp;amp; (1&amp;lt;&amp;lt;inputbit)))&lt;br /&gt;
     return 0; /* keine Änderung */&lt;br /&gt;
 &lt;br /&gt;
  /* Wenn doch, warten bis etwaiges Prellen vorbei ist: */&lt;br /&gt;
  _delay_ms(20);&lt;br /&gt;
&lt;br /&gt;
  /* Zustand für nächsten Aufruf merken: */&lt;br /&gt;
  last_state = *inputreg &amp;amp; (1&amp;lt;&amp;lt;inputbit);&lt;br /&gt;
 &lt;br /&gt;
  /* und den entprellten Tastendruck zurückgeben: */&lt;br /&gt;
  return *inputreg &amp;amp; (1&amp;lt;&amp;lt;inputbit);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Beispiel für einen Funktionsaufruf: */&lt;br /&gt;
&lt;br /&gt;
void foo (void)&lt;br /&gt;
{&lt;br /&gt;
   uint8_t i = key_pressed (&amp;amp;PINB, PB1);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ein Aufruf der Funktion mit call by value würde Folgendes bewirken: Beim Funktionseintritt wird nur eine Kopie des momentanen Portzustandes angefertigt, die sich unabhängig vom tatsächlichen Zustand das Ports nicht mehr ändert, womit die Funktion wirkungslos wäre. Die Übergabe eines Zeigers wäre die Lösung, wenn der Compiler nicht optimieren würde. Denn dadurch wird im Programm nicht von der Hardware gelesen, sondern wieder nur von einem Abbild im Speicher. Das Ergebnis wäre das gleiche wie oben. Mit dem Schlüsselwort volatile sagt man nun dem Compiler, dass die entsprechende Variable entweder durch andere Softwareroutinen (Interrupts) oder durch die Hardware verändert werden kann.&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_port_pass avr-libc FAQ: &amp;quot;How do I pass an IO port as a parameter to a function?&amp;quot;]&lt;br /&gt;
&lt;br /&gt;
= Zugriff auf IO-Ports =&lt;br /&gt;
&lt;br /&gt;
Jeder AVR implementiert eine unterschiedliche Menge an GPIO-Registern&lt;br /&gt;
(GPIO - General Purpose Input/Output). Diese Register dienen dazu:&lt;br /&gt;
* einzustellen welche der Anschlüsse (&amp;quot;Beinchen&amp;quot;) des Controllers als Ein- oder Ausgänge dienen&lt;br /&gt;
* bei Ausgängen deren Zustand festzulegen&lt;br /&gt;
* bei Eingängen deren Zustand zu erfassen&lt;br /&gt;
&lt;br /&gt;
Mittels GPIO werden digitale Zustände gesetzt und erfasst, d.h. die Spannung an einem Ausgang wird ein- oder ausgeschaltet und an einem Eingang wird erfasst, ob die anliegende Spannung über oder unter einem bestimmten Schwellwert liegt. Im Datenblatt Abschnitt Electrical Characteristics/DC Characteristics finden sich die Spannungswerte (V_OL, V_OH für Ausgänge, V_IL, V_IH für Eingänge).&lt;br /&gt;
&lt;br /&gt;
Die Verarbeitung von analogen Eingangswerten und die Ausgabe von Analogwerten wird in Kapitel [[AVR-GCC-Tutorial#Analoge_Ein-_und_Ausgabe|Analoge Ein- und Ausgabe]] behandelt.&lt;br /&gt;
&lt;br /&gt;
Die physischen Ein- und Ausgänge werden bei AVR-Controllern zu logischen Ports gruppiert.&lt;br /&gt;
&lt;br /&gt;
Alle Ports werden über Register gesteuert. Dazu sind jedem Port 3 Register zugeordnet:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! DDRx&lt;br /&gt;
| Datenrichtungsregister für Port&#039;&#039;&#039;x&#039;&#039;&#039;. &lt;br /&gt;
&#039;&#039;&#039;x&#039;&#039;&#039; entspricht &#039;&#039;&#039;A&#039;&#039;&#039;, &#039;&#039;&#039;B&#039;&#039;&#039;, &#039;&#039;&#039; C&#039;&#039;&#039;, &#039;&#039;&#039;D&#039;&#039;&#039; usw. (abhängig von der Anzahl der Ports des verwendeten AVR). Bit im Register gesetzt (1) für Ausgang, Bit gelöscht (0) für Eingang.&lt;br /&gt;
|- &lt;br /&gt;
! PINx&lt;br /&gt;
| Eingangsadresse für Port&#039;&#039;&#039;x&#039;&#039;&#039;. &lt;br /&gt;
Zustand des Ports. Die Bits in PINx entsprechen dem Zustand der als Eingang definierten Portpins. Bit 1 wenn Pin &amp;quot;high&amp;quot;, Bit 0 wenn Portpin low.&lt;br /&gt;
|-&lt;br /&gt;
! PORTx&lt;br /&gt;
| Datenregister für Port&#039;&#039;&#039;x&#039;&#039;&#039;. &lt;br /&gt;
Dieses Register wird verwendet, um die Ausgänge eines Ports anzusteuern. Bei Pins, die mittels DDRx auf Eingang geschaltet wurden, können über PORTx&lt;br /&gt;
die internen Pull-Up Widerstände aktiviert oder deaktiviert werden (1 = aktiv).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Die folgenden Beispiele gehen von einem AVR aus, der sowohl Port A als auch Port B besitzt. Sie müssen für andere AVRs (zum Beispiel ATmega8/48/88/168) entsprechend angepasst werden.&lt;br /&gt;
&lt;br /&gt;
== Datenrichtung bestimmen ==&lt;br /&gt;
&lt;br /&gt;
Zuerst muss die Datenrichtung der verwendeten Pins bestimmt werden. Um dies zu erreichen, wird das Datenrichtungsregister des entsprechenden Ports beschrieben.&lt;br /&gt;
&lt;br /&gt;
Für jeden Pin, der als Ausgang verwendet werden soll, muss dabei das&lt;br /&gt;
entsprechende Bit auf dem Port gesetzt werden. Soll der Pin als Eingang&lt;br /&gt;
verwendet werden, muss das entsprechende Bit gelöscht sein.&lt;br /&gt;
&lt;br /&gt;
Beispiel:&lt;br /&gt;
Angenommen am Port B sollen die Pins 0 bis 4 als Ausgänge definiert werden, die noch verbleibenden Pins 5 bis 7 sollen als Eingänge fungieren. Dazu ist es daher notwendig, im für das Port B zuständigen Datenrichtungsregister DDRB folgende Bitkonfiguration einzutragen&lt;br /&gt;
&lt;br /&gt;
   +---+---+---+---+---+---+---+---+&lt;br /&gt;
   | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |&lt;br /&gt;
   +---+---+---+---+---+---+---+---+&lt;br /&gt;
     7   6   5   4   3   2   1   0&lt;br /&gt;
&lt;br /&gt;
In C liest sich das dann so:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// in io.h wird u.a. DDRB definiert:&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  // Setzen der Bits 0,1,2,3 und 4&lt;br /&gt;
  // Binär 00011111 = Hexadezimal 1F&lt;br /&gt;
  // direkte Zuweisung - standardkonform */&lt;br /&gt;
  DDRB = 0x1F;    /* &lt;br /&gt;
&lt;br /&gt;
  // übersichtliche Alternative - Binärschreibweise, aber kein ISO-C&lt;br /&gt;
  DDRB = 0b00011111;&lt;br /&gt;
&lt;br /&gt;
  // Ausführliche Schreibweise: identische Funktionalität, mehr Tipparbeit&lt;br /&gt;
  // aber übersichtlicher und selbsterklärend:&lt;br /&gt;
  DDRB = (1 &amp;lt;&amp;lt; DDB0) | (1 &amp;lt;&amp;lt; DDB1) | (1 &amp;lt;&amp;lt; DDB2) | (1 &amp;lt;&amp;lt; DDB3) | (1 &amp;lt;&amp;lt; DDB4); &lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die Pins 5 bis 7 werden (da 0) als Eingänge geschaltet. Weitere Beispiele:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  // Alle Pins des Ports B als Ausgang definieren:&lt;br /&gt;
  DDRB = 0xff; &lt;br /&gt;
  // Pin0 wieder auf Eingang und andere im ursprünglichen Zustand belassen:&lt;br /&gt;
  DDRB &amp;amp;= ~(1 &amp;lt;&amp;lt; DDB0);&lt;br /&gt;
  // Pin 3 und 4 auf Eingang und andere im ursprünglichen Zustand belassen:&lt;br /&gt;
  DDRB &amp;amp;= ~((1 &amp;lt;&amp;lt; DDB3) | (1 &amp;lt;&amp;lt; DDB4));&lt;br /&gt;
  // Pin 0 und 3 wieder auf Ausgang und andere im ursprünglichen Zustand belassen:&lt;br /&gt;
  DDRB |= (1 &amp;lt;&amp;lt; DDB0) | (1 &amp;lt;&amp;lt; DDB3);&lt;br /&gt;
  // Alle Pins auf Eingang:&lt;br /&gt;
  DDRB = 0x00;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Vordefinierte Bitnummern für I/O-Register ==&lt;br /&gt;
&lt;br /&gt;
Die Bitnummern (z.&amp;amp;nbsp;B. PCx, PINCx und DDCx für den Port C) sind in den io*.h-Dateien der avr-libc definiert und dienen lediglich der besseren Lesbarkeit. Man muss diese Definitionen nicht verwenden oder kann auch einfach &amp;quot;immer&amp;quot; PAx, PBx, PCx usw. nutzen, auch wenn der Zugriff auf Bits in DDRx- oder PINx-Registern erfolgt. Für den Compiler sind die Ausdrücke (1&amp;lt;&amp;lt;PC7), (1&amp;lt;&amp;lt;DDC7) und (1&amp;lt;&amp;lt;PINC7) identisch zu (1&amp;lt;&amp;lt;7) (genauer: der Präprozessor ersetzt die Ausdrücke (1&amp;lt;&amp;lt;PC7),... zu (1&amp;lt;&amp;lt;7)). Ein Ausschnitt der Definitionen für Port C eines ATmega32 aus der iom32.h-Datei zur Verdeutlichung (analog für die weiteren Ports):&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
/* PORTC */&lt;br /&gt;
#define PC7     7&lt;br /&gt;
#define PC6     6&lt;br /&gt;
#define PC5     5&lt;br /&gt;
#define PC4     4&lt;br /&gt;
#define PC3     3&lt;br /&gt;
#define PC2     2&lt;br /&gt;
#define PC1     1&lt;br /&gt;
#define PC0     0&lt;br /&gt;
&lt;br /&gt;
/* DDRC */&lt;br /&gt;
#define DDC7    7&lt;br /&gt;
#define DDC6    6&lt;br /&gt;
#define DDC5    5&lt;br /&gt;
#define DDC4    4&lt;br /&gt;
#define DDC3    3&lt;br /&gt;
#define DDC2    2&lt;br /&gt;
#define DDC1    1&lt;br /&gt;
#define DDC0    0&lt;br /&gt;
&lt;br /&gt;
/* PINC */&lt;br /&gt;
#define PINC7   7&lt;br /&gt;
#define PINC6   6&lt;br /&gt;
#define PINC5   5&lt;br /&gt;
#define PINC4   4&lt;br /&gt;
#define PINC3   3&lt;br /&gt;
#define PINC2   2&lt;br /&gt;
#define PINC1   1&lt;br /&gt;
#define PINC0   0&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Digitale Signale ==&lt;br /&gt;
&lt;br /&gt;
Am einfachsten ist es, digitale Signale mit dem Mikrocontroller zu erfassen bzw. auszugeben.&lt;br /&gt;
&lt;br /&gt;
== Ausgänge ==&lt;br /&gt;
Will man als Ausgang definierte Pins (entsprechende DDRx-Bits = 1) auf Logisch 1 setzen, setzt man die  entsprechenden Bits im Portregister.&lt;br /&gt;
&lt;br /&gt;
Mit dem Befehl&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
    PORTB = 0x04; /* besser PORTB=(1&amp;lt;&amp;lt;PB2) */&lt;br /&gt;
&lt;br /&gt;
    // übersichtliche Alternative - Binärschreibweise&lt;br /&gt;
    PORTB = 0b00000100;    /* direkte Zuweisung - übersichtlich */&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
wird also der Ausgang an Pin PB2 gesetzt (Beachte, dass die Bits immer &#039;&#039;von 0 an&#039;&#039; gezählt werden, das niederwertigste Bit ist also Bitnummer 0 und nicht etwa Bitnummer 1).&lt;br /&gt;
&lt;br /&gt;
Man beachte, dass bei der Zuweisung mittels &#039;&#039;&#039;=&#039;&#039;&#039; immer alle Pins gleichzeitig angegeben werden. Man sollte also, wenn nur bestimmte Ausgänge geschaltet werden sollen, zuerst den aktuellen Wert des Ports einlesen und das Bit des gewünschten Ports in diesen Wert einfließen lassen. Will man also nur den dritten Pin (Bit Nr. 2) an Port B auf &amp;quot;high&amp;quot; setzen und den Status der anderen Ausgänge unverändert lassen, nutze man diese Form:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
    PORTB = PORTB | 0x04; /* besser: PORTB = PORTB | ( 1&amp;lt;&amp;lt;PB2 ) */&lt;br /&gt;
    /* vereinfacht durch Nutzung des |= Operators : */&lt;br /&gt;
    PORTB |= (1&amp;lt;&amp;lt;PB2);&lt;br /&gt;
&lt;br /&gt;
    /* auch mehrere &amp;quot;gleichzeitig&amp;quot;: */&lt;br /&gt;
    PORTB |= (1&amp;lt;&amp;lt;PB4) | (1&amp;lt;&amp;lt;PB5); /* Pins PB4 und PB5 &amp;quot;high&amp;quot; */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Ausschalten&amp;quot;, also  Ausgänge auf &amp;quot;low&amp;quot; setzen, erfolgt analog:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
    PORTB &amp;amp;= ~(1&amp;lt;&amp;lt;PB2); /* löscht Bit 2 in PORTB und setzt damit Pin PB2 auf low */ &lt;br /&gt;
    PORTB &amp;amp;= ~( (1&amp;lt;&amp;lt;PB4) | (1&amp;lt;&amp;lt;PB5) ); /* Pin PB4 und Pin PB5 &amp;quot;low&amp;quot; */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Siehe auch [[Bitmanipulation]]&lt;br /&gt;
&lt;br /&gt;
In Quellcodes, die für ältere Version den des avr-gcc/der avr-libc entwickelt wurden, werden einzelne Bits mittels der Funktionen sbi und cbi gesetzt bzw. gelöscht. Beide Funktionen sind in aktuellen Versionen der avr-libc nicht mehr enthalten und auch nicht mehr erforderlich.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Falls der Anfangszustand von Ausgängen kritisch ist, muss die Reihenfolge beachtet werden, mit der die Datenrichtung (DDRx) eingestellt und der Ausgabewert (PORTx) gesetzt wird:&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Für Ausgangspins, die mit Anfangswert &amp;quot;high&amp;quot; initialisiert werden sollen:&lt;br /&gt;
* zuerst die Bits im PORTx-Register setzen&lt;br /&gt;
* anschließend die Datenrichtung auf Ausgang stellen&lt;br /&gt;
&lt;br /&gt;
Daraus ergibt sich die Abfolge für einen Pin, der bisher als Eingang mit abgeschaltetem Pull-Up konfiguriert war:&lt;br /&gt;
* setze PORTx: interner Pull-Up aktiv&lt;br /&gt;
* setze DDRx: Ausgang (&amp;quot;high&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
Bei der Reihenfolge erst DDRx und dann PORTx kann es zu einem kurzen &amp;quot;low-Puls&amp;quot; kommen, der auch externe Pull-Up-Widerstände &amp;quot;überstimmt&amp;quot;. Die (ungünstige) Abfolge: Eingang -&amp;gt; setze DDRx: Ausgang (auf &amp;quot;low&amp;quot;, da PORTx nach Reset 0) -&amp;gt; setze PORTx: Ausgang auf high. Vergleiche dazu auch das Datenblatt Abschnitt &#039;&#039;Configuring the Pin&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Eingänge (Wie kommen Signale in den &amp;amp;micro;C) ==&lt;br /&gt;
&lt;br /&gt;
Die digitalen Eingangssignale können auf verschiedene Arten zu unserer Logik gelangen.&lt;br /&gt;
&lt;br /&gt;
=== Signalkopplung ===&lt;br /&gt;
&lt;br /&gt;
Am einfachsten ist es, wenn die Signale direkt aus einer anderen digitalen Schaltung übernommen werden können. Hat der Ausgang der entsprechenden Schaltung TTL-Pegel dann können wir sogar direkt den Ausgang der Schaltung mit einem Eingangspin von unserem Controller verbinden.&lt;br /&gt;
&lt;br /&gt;
Hat der Ausgang der anderen Schaltung keinen TTL-Pegel so müssen wir den Pegel über entsprechende Hardware (z.&amp;amp;nbsp;B. Optokoppler, [[Widerstand#Spannungsteiler|Spannungsteiler]], &amp;quot;Levelshifter&amp;quot; aka [[Pegelwandler]]) anpassen.&lt;br /&gt;
&lt;br /&gt;
Die Masse der beiden Schaltungen muss selbstverständlich miteinander verbunden werden. Der Software selber ist es natürlich letztendlich egal, wie das Signal eingespeist wird. Wir können ja ohnehin lediglich prüfen, ob an einem Pin unseres Controllers eine logische 1 (Spannung größer ca. 0,7*Vcc) oder eine logische 0 (Spannung kleiner ca. 0,2*Vcc) anliegt. Detaillierte Informationen darüber, ab welcher Spannung ein Eingang als 0 (&amp;quot;low&amp;quot;) bzw. 1 (&amp;quot;high&amp;quot;) erkannt wird, liefert die Tabelle DC Characteristics im Datenblatt des genutzten Controllers.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Spannungstabelle&#039;&#039;&#039; &amp;lt;br /&amp;gt; &amp;lt;small&amp;gt;(ca. Grenzwerte)&amp;lt;/small&amp;gt;&lt;br /&gt;
|&lt;br /&gt;
! Low || High&lt;br /&gt;
|-&lt;br /&gt;
! bei 5 V&lt;br /&gt;
| 1 V || 3,5 V&lt;br /&gt;
|-&lt;br /&gt;
! bei 3,3 V&lt;br /&gt;
| 0,66 V || 2,31 V&lt;br /&gt;
|-&lt;br /&gt;
! bei 1,8 V&lt;br /&gt;
| 0,36 V || 1,26 V&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die Abfrage der Zustände der Portpins erfolgt direkt über den Registernamen.&lt;br /&gt;
&lt;br /&gt;
{{Warnung|Dabei ist wichtig, zur Abfrage der Eingänge &#039;&#039;nicht&#039;&#039; etwa Portregister &#039;&#039;&#039;PORTx&#039;&#039;&#039; zu verwenden, sondern Eingangsregister &#039;&#039;&#039;PINx&#039;&#039;&#039;. Ansonsten liest man nicht den Zustand der Eingänge, sondern den Status der internen Pull-Up-Widerstände. Die Abfrage der Pinzustände über PORTx statt PINx ist ein häufiger Fehler beim AVR-&amp;quot;Erstkontakt&amp;quot;.}}&lt;br /&gt;
&lt;br /&gt;
Will man also die aktuellen Signalzustände von Port D abfragen und in eine Variable namens bPortD abspeichern, schreibt man folgende Befehlszeilen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
uint8_t bPortD;&lt;br /&gt;
...&lt;br /&gt;
bPortD = PIND;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit den C-Bitoperationen kann man den Status der Bits abfragen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
/* Fuehre Aktion aus, wenn Bit Nr. 1 (das &amp;quot;zweite&amp;quot; Bit) in PINC gesetzt (1) ist */&lt;br /&gt;
if ( PINC &amp;amp; (1&amp;lt;&amp;lt;PINC1) ) {&lt;br /&gt;
  /* Aktion */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* Fuehre Aktion aus, wenn Bit Nr. 2 (das &amp;quot;dritte&amp;quot; Bit) in PINB geloescht (0) ist */&lt;br /&gt;
if ( !(PINB &amp;amp; (1&amp;lt;&amp;lt;PINB2)) ) {&lt;br /&gt;
  /* Aktion */&lt;br /&gt;
}&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Siehe auch [[Bitmanipulation#Bits_prüfen]]&lt;br /&gt;
&lt;br /&gt;
=== Interne Pull-Up Widerstände ===&lt;br /&gt;
&lt;br /&gt;
Portpins für Ein- und Ausgänge (GPIO) eines AVR verfügen über zuschaltbare interne Pull-Up Widerstände (nominal mehrere 10kOhm, z.&amp;amp;nbsp;B. ATmega16 20-50kOhm). Diese können in vielen Fällen statt externer Widerstände genutzt werden.&lt;br /&gt;
&lt;br /&gt;
Die internen Pull-Up Widerstände von Vcc zu den einzelnen Portpins werden über das Register &#039;&#039;&#039; PORTx&#039;&#039;&#039; aktiviert bzw. deaktiviert, wenn ein Pin als &#039;&#039;&#039; Eingang&#039;&#039;&#039; geschaltet ist.&lt;br /&gt;
&lt;br /&gt;
Wird der Wert des entsprechenden Portpins auf 1 gesetzt, so ist der Pull-Up Widerstand aktiviert. Bei einem Wert von 0 ist der Pull-Up Widerstand nicht aktiv. Man sollte jeweils entweder den internen oder einen externen Pull-Up Widerstand verwenden, aber nicht beide zusammen.&lt;br /&gt;
&lt;br /&gt;
Im Beispiel werden alle Pins des Ports D als Eingänge geschaltet und alle Pull-Up Widerstände aktiviert. Weiterhin wird Pin PC7 als Eingang geschaltet und dessen interner Pull-Up Widerstand aktiviert, ohne die Einstellungen für die anderen Portpins (PC0-PC6) zu verändern.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
DDRD  = 0x00; /* alle Pins von Port D als Eingang */&lt;br /&gt;
PORTD = 0xff; /* interne Pull-Ups an allen Port-Pins aktivieren */&lt;br /&gt;
...&lt;br /&gt;
DDRC  &amp;amp;= ~(1&amp;lt;&amp;lt;PC7);  /* Pin PC7 als Eingang */&lt;br /&gt;
PORTC |= (1&amp;lt;&amp;lt;PC7);    /* internen Pull-Up an PC7 aktivieren */&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Tasten und Schalter ===&lt;br /&gt;
&lt;br /&gt;
Der Anschluss mechanischer Kontakte an den Mikrocontroller, ist zwischen zwei unterschiedliche Methoden zu unterscheiden: &#039;&#039;Active Low&#039;&#039; und &#039;&#039;Active High&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;gallery widths=&amp;quot;300&amp;quot; heights=&amp;quot;300&amp;quot; caption=&amp;quot;Anschluss mechanischer Kontakte an einen µC&amp;quot;&amp;gt;&lt;br /&gt;
Image:Active Low.gif|&#039;&#039;&#039;Active Low:&#039;&#039;&#039; Bei dieser Methode wird der Kontakt zwischen den Eingangspin des Controllers und Masse geschaltet. Damit bei offenem Schalter der Controller kein undefiniertes Signal bekommt, wird zwischen die Versorgungsspannung und den Eingangspin ein sogenannter &#039;&#039;&#039;Pull-Up&#039;&#039;&#039; Widerstand geschaltet. Dieser dient dazu, den Pegel bei geöffnetem Schalter auf logisch 1 zu ziehen.&lt;br /&gt;
Image:Active High.gif|&#039;&#039;&#039;Active High:&#039;&#039;&#039; Hier wird der Kontakt zwischen die Versorgungsspannung und den Eingangspin geschaltet. Damit bei offener Schalterstellung kein undefiniertes Signal am Controller ansteht, wird zwischen den Eingangspin und die Masse ein &#039;&#039;&#039;Pull-Down&#039;&#039;&#039; Widerstand geschaltet. Dieser dient dazu, den Pegel bei geöffneter Schalterstellung auf logisch 0 zu halten. &lt;br /&gt;
&amp;lt;/gallery&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Widerstandswert von Pull-Up- und Pull-Down-Widerständen ist an sich nicht kritisch. Wird er allerdings zu hoch gewählt, ist die Wirkung eventuell nicht gegeben. Als üblicher Wert haben sich 10 kOhm eingebürgert. Die AVRs verfügen an den meisten Pins über zuschaltbare interne Pull-Up Widerstände (vgl. Abschnitt [[AVR-GCC-Tutorial#Interne Pull-Up Widerstände|Interne Pull-Up Widerstände]]), welche insbesondere wie hier bei Tastern und ähnlichen Bauteilen (z.&amp;amp;nbsp;B. Drehgebern) statt externer Bauteile verwendet werden können. Interne Pull-Down-Widerstand sind nicht verfügbar und müssen daher in Form zusätzlicher Bauteile in die Schaltung eingefügt werden.&lt;br /&gt;
&lt;br /&gt;
==== (Tasten-)Entprellung ====&lt;br /&gt;
&lt;br /&gt;
Siehe: &#039;&#039;[[Entprellung#Warteschleifen-Verfahren|Entprellung: Warteschleifen-Verfahren]]&lt;br /&gt;
&lt;br /&gt;
= Analoge Ein- und Ausgabe =&lt;br /&gt;
&lt;br /&gt;
Analoge Eingangswerte werden in der Regel über den AVR Analog-Digital-Converter (AD-Wandler, ADC) eingelesen, der in vielen Typen verfügbar ist (typisch 10bit Auflösung). Durch diesen werden analoge Signale (Spannungen) in digitale Zahlenwerte gewandelt. Bei AVRs, die über keinen internen AD-Wandler verfügen (z.&amp;amp;nbsp;B. ATmega162), kann durch externe Beschaltung (R/C-Netzwerk und Zeitmessung) die Funktion des AD-Wandlers simuliert werden.&lt;br /&gt;
&lt;br /&gt;
Es gibt innerhalb der ATMega- und ATTiny-AVR Reihe keine Typen mit eingebautem Digital-Analog-Konverter (DAC) - diese Funktion ist erst ab der XMEGA-Reihe der AVR-Familie verfügbar, die aber wegen ihrer vielen Unterschiede im Umfang dieses Tutorials nicht behandelt wird.&lt;br /&gt;
Die Umsetzung zu einer analogen Spannung muss daher durch externe Komponenten vorgenommen werden. Das kann z.&amp;amp;nbsp;B. durch PWM und deren Filterung zu (fast) DC, oder einem sogenannten R2R-Netzwerk erfolgen.&lt;br /&gt;
&lt;br /&gt;
Unabhängig davon besteht natürlich immer die Möglichkeit, spezielle Bausteine zur Analog-Digital- bzw. Digital-Analog-Wandlung zu nutzen und diese über eine digitale Schnittstelle (z.b. SPI oder I2C) mit einem AVR anzusteuern.&lt;br /&gt;
&lt;br /&gt;
== AC (Analog Comparator) ==&lt;br /&gt;
&lt;br /&gt;
Der Comparator vergleicht 2 Spannungen an den Pins AIN0 und AIN1 und gibt einen Status aus welche der beiden Spannungen größer ist. AIN0 Dient dabei als Referenzspannung (Sollwert) und AIN1 als Vergleichsspannung (Istwert). Als Referenzspannung kann auch alternativ eine interne Referenzspannung ausgewählt werden.&lt;br /&gt;
&lt;br /&gt;
Liegt die Vergleichsspannung (IST) unter der der Referenzspannung (SOLL) gibt der Comparator eine logische 1 aus. Ist die Vergleichsspannung hingegen größer als die Referenzspannung wird eine logische 0 ausgegeben.&lt;br /&gt;
&lt;br /&gt;
Der Comparator arbeitet völlig autark bzw. parallel zum Prozessor. Für mobile Anwendungen empfiehlt es sich ihn abzuschalten sofern er nicht benötigt wird, da er ansonsten Strom benötigt. Der Comparator kann interruptgesteuert abgefragt werden oder im Pollingbetrieb.&lt;br /&gt;
&lt;br /&gt;
Das Steuer- bzw. Statusregister ist wie folgt aufgebaut:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;ACSR - Analog Comparator Status Register&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7|| 6|| 5|| 4|| 3|| 2|| 1|| 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;ACD&#039;&#039;&#039;|| &#039;&#039;&#039;ACBG&#039;&#039;&#039;|| &#039;&#039;&#039;ACO&#039;&#039;&#039;|| &#039;&#039;&#039;ACI&#039;&#039;&#039;|| &#039;&#039;&#039;ACIE&#039;&#039;&#039;|| &#039;&#039;&#039;ACIC&#039;&#039;&#039;|| &#039;&#039;&#039;ACIS1&#039;&#039;&#039;|| &#039;&#039;&#039;ACIS0&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W|| R/W|| R|| R/W|| R/W|| R/W|| R/W|| R/W&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0|| 0|| n/a|| 0|| 0|| 0|| 0|| 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
;Bit 7 ACD: Analog Comparator Disable: 0 = Comparator ein, 1 = Comparator aus. Wird dieses Bit geändert kann ein Interrupt ausgelöst werden. Soll dies vermieden werden muss das Bit 3 ACIE ggf. abgeschaltet werden.&lt;br /&gt;
&lt;br /&gt;
;Bit 6 ACBG: Analog Comparator Bandgap Select: Ermöglicht das umschalten zwischen interner und externer Referenzspannung. 1 = interne (~1,3 Volt), 0 = externe Referenzspannung (an Pin AIN0)&lt;br /&gt;
&lt;br /&gt;
;Bit 5 ACO: Analog Comparator Output: Hier wird das Ergebnis des Vergleichs angezeigt. Es liegt typischerweise nach 1-2 Taktzyklen vor.&lt;br /&gt;
:: IST &amp;lt; SOLL &amp;amp;rarr; 1&lt;br /&gt;
:: IST &amp;gt; SOLL &amp;amp;rarr; 0&lt;br /&gt;
&lt;br /&gt;
;Bit 4 ACI: Analog Comparator Interrupt Flag: Dieses Bit wird von der Hardware gesetzt, wenn ein Interruptereignis, das in Bit 0 und 1 definiert ist, eintritt. Dieses Bit löst noch keinen Interrupt aus! Die Interruptroutine wird nur dann ausgeführt, wenn das Bit 3 ACIE gesetzt ist und global Interrupts erlaubt sind (I-Bit in SREG gesetzt). Das Bit 4 ACI wird wieder gelöscht, wenn die Interruptroutine ausgeführt wurde oder wenn es manuell auf 1! gesetzt wird. Das Bit kann für Abfragen genutzt werden, steuert oder konfiguriert aber nicht den Comparator.&lt;br /&gt;
&lt;br /&gt;
;Bit 3 ACIE: Analog Comparator Interrupt Enable: Ist das Bit auf 1 gesetzt, wird immer ein Interrupt ausgelöst, wenn das Ereignis das in Bit 1 und 0 definiert ist, eintritt.&lt;br /&gt;
&lt;br /&gt;
;Bit 2 ACIC: Analog Comparator Input Capture Enable: Wird das Bit gesetzt, wird der Comparatorausgang intern mit dem Counter 1 verbunden. Es könnten damit z.b. die Anzahl der Vergleiche im Counter1 gezählt werden. Um den Comparator an den Timer1 Input Capture Interrupt zu verbinden, muss im Timerregister das TICIE1 Bit auf 1 gesetzt werden. Der Trigger wird immer dann ausgelöst, wenn das in Bit 1 und 0 definierte Ereignis eintritt.&lt;br /&gt;
&lt;br /&gt;
;Bit 1,0 ACIS1,ACIS0: Analog Comparator Interrupt select: Hier wird definiert, welche Ereignisse einen Interrupt auslösen sollen:&lt;br /&gt;
:* 00 = Interrupt auslösen bei jedem Flankenwechsel&lt;br /&gt;
:* 10 = Interrupt auslösen bei fallender Flanke&lt;br /&gt;
:* 11 = Interrupt auslösen bei steigender Flanke&lt;br /&gt;
&lt;br /&gt;
Werden diese Bit geändert, kann ein Interrupt ausgelöst werden. Soll dies vermieden werden, muss das Bit 3 gelöscht werden.&lt;br /&gt;
&lt;br /&gt;
== ADC (Analog Digital Converter) ==&lt;br /&gt;
&lt;br /&gt;
Der Analog-Digital-Konverter (ADC) wandelt analoge Signale in digitale Werte um, welche vom Controller interpretiert werden können. Einige AVR-Typen haben bereits einen mehrkanaligen Analog-Digital-Konverter eingebaut. Die Feinheit, mit welcher ein analoges Signal aufgelöst werden kann, wird durch die Auflösung des ADC, d.h. durch die Anzahl der verwendeten Bits angegeben. So sind derzeit bspw. 8-Bit- oder 10-Bit-ADC im Einsatz. ADCs, die in AVRs enthalten sind, haben zur Zeit eine maximale Auflösung von 10-Bit.&lt;br /&gt;
&lt;br /&gt;
Ein ADC mit 8 Bit Auflösung kann somit das analoge Signal in Abstufungen von 1/256 des Maximalwertes digitalisieren. Wenn wir nun mal annehmen, wir hätten eine Eingangspannung zwischen 0 und 5 Volt, eine Referenzspannung von 5&amp;amp;nbsp;V und eine Auflösung von 3 Bit, dann könnten&lt;br /&gt;
Intervalle mit den Grenzen 0&amp;amp;nbsp;V, 0.625&amp;amp;nbsp;V, 1.25&amp;amp;nbsp;V, 1.875&amp;amp;nbsp;V, 2.5&amp;amp;nbsp;V, 3.125&amp;amp;nbsp;V, 3.75&amp;amp;nbsp;V, 4.375&amp;amp;nbsp;V, 5&amp;amp;nbsp;V entsprechend folgender Tabelle unterschieden werden:&lt;br /&gt;
&lt;br /&gt;
::{|  class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
! Eingangsspannung am ADC / V || Entsprechender Messwert&lt;br /&gt;
|-&lt;br /&gt;
| 0 – 0.625    || 0&lt;br /&gt;
|-&lt;br /&gt;
| 0.625 – 1.25 || 1&lt;br /&gt;
|-&lt;br /&gt;
| 1.25 – 1.875 || 2&lt;br /&gt;
|-&lt;br /&gt;
| 1.875 – 2.5  || 3&lt;br /&gt;
|-&lt;br /&gt;
| 2.5 – 3.125  || 4&lt;br /&gt;
|-&lt;br /&gt;
| 3.125 – 3.75 || 5&lt;br /&gt;
|-&lt;br /&gt;
| 3.75 – 4.375 || 6&lt;br /&gt;
|-&lt;br /&gt;
| 4.375 – 5    || 7&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Die Angaben sind natürlich nur ungefähr. Je höher nun die Auflösung des Analog-Digital-Konverters ist, also, je mehr Bits er hat, desto genauer kann der jeweilige Wert erfasst werden.&lt;br /&gt;
&lt;br /&gt;
=== Der interne ADC im AVR ===&lt;br /&gt;
&lt;br /&gt;
Oft sind auch mehrere Kanäle verfügbar. Kanäle heißt in diesem Zusammenhang, dass zwar bis zu zehn analoge Eingänge am AVR vorhanden sind, aber nur ein &amp;quot;echter&amp;quot; Analog-Digital-Wandler zur Verfügung steht. Vor der eigentlichen Messung ist also festzulegen, welcher Kanal (&amp;quot;Pin&amp;quot;) mit dem Wandler verbunden und gemessen wird.&lt;br /&gt;
&lt;br /&gt;
Die Umwandlung innerhalb des AVR basiert auf der schrittweisen Näherung. Beim AVR müssen die Pins &#039;&#039;&#039;AGND&#039;&#039;&#039; und &#039;&#039;&#039;AVCC&#039;&#039;&#039; beschaltet werden. Für genaue Messungen sollte AVCC über ein L-C Netzwerk mit VCC verbunden werden, um Spannungsspitzen und -einbrüche vom Analog-Digital-Wandler fernzuhalten. Im Datenblatt findet sich dazu eine Schaltung, die 10µH und 100nF vorsieht.&lt;br /&gt;
&lt;br /&gt;
Das Ergebnis der Analog-Digital-Wandlung wird auf eine Referenzspannung bezogen. Aktuelle AVRs bieten drei Möglichkeiten zur Wahl dieser Spannung:&lt;br /&gt;
&lt;br /&gt;
* Eine externe Referenzspannung von maximal &#039;&#039;&#039;Vcc&#039;&#039;&#039; am Anschlusspin &#039;&#039;&#039;AREF&#039;&#039;&#039;. Die minimale (externe) Referenzspannung darf jedoch nicht beliebig niedrig sein, vgl. dazu das (aktuellste) Datenblatt des verwendeten Controllers. &lt;br /&gt;
&lt;br /&gt;
* Verfügt der AVR über eine interne Referenzspannung, kann diese genutzt werden. Alle aktuellen AVRs mit internem AD-Wandler sollten damit ausgestattet sein (vgl. Datenblatt: 2,56V oder 1,1V je nach Typ). Das Datenblatt gibt auch über die Genauigkeit dieser Spannung Auskunft.&lt;br /&gt;
&lt;br /&gt;
* Es kann die Spannung AVcc als Referenzspannung herangezogen werden&lt;br /&gt;
&lt;br /&gt;
Bei Nutzung von AVcc oder der internen Referenz wird empfohlen, einen Kondensator zwischen dem AREF-Pin und GND anzuordnen. Die Festlegung, welche Spannungsreferenz genutzt wird, erfolgt z.&amp;amp;nbsp;B. beim ATmega16 mit den Bits REFS1/REFS0 im ADMUX-Register. Die zu messende Spannung muss im Bereich zwischen &#039;&#039;&#039;AGND&#039;&#039;&#039; und &#039;&#039;&#039;AREF&#039;&#039;&#039; (egal ob intern oder extern) liegen. &lt;br /&gt;
&lt;br /&gt;
Der &#039;&#039;&#039;ADC&#039;&#039;&#039; kann in zwei verschiedenen Betriebsarten verwendet werden:&lt;br /&gt;
&lt;br /&gt;
; Einfache Wandlung (Single Conversion) : In dieser Betriebsart wird der Wandler bei Bedarf vom Programm angestoßen für jeweils eine Messung.&lt;br /&gt;
&lt;br /&gt;
; Frei laufend (Free Running) : In dieser Betriebsart erfasst der Wandler permanent die anliegende Spannung und schreibt diese in das &#039;&#039;&#039;ADC Data Register&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
==== Die Register des ADC ====&lt;br /&gt;
&lt;br /&gt;
Der &#039;&#039;&#039;ADC&#039;&#039;&#039; verfügt über eigene Register. Im Folgenden die Registerbeschreibung eines  ATMega16, welcher über 8 ADC-Kanäle verfügt. Die Register unterscheiden sich jedoch nicht erheblich von denen anderer AVRs (vgl. Datenblatt).&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;ADCSRA&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;ADC&#039;&#039;&#039; &#039;&#039;&#039;C&#039;&#039;&#039;ontrol and &#039;&#039;&#039;S&#039;&#039;&#039;tatus &#039;&#039;&#039;R&#039;&#039;&#039;egister A.&amp;lt;br /&amp;gt;&lt;br /&gt;
In diesem Register stellen wir ein, wie wir den &#039;&#039;&#039;ADC&#039;&#039;&#039; verwenden möchten.&amp;lt;br /&amp;gt;&lt;br /&gt;
Das Register ist wie folgt aufgebaut:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7|| 6|| 5|| 4|| 3|| 2|| 1|| 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;ADEN&#039;&#039;&#039;|| &#039;&#039;&#039;ADSC&#039;&#039;&#039;|| &#039;&#039;&#039;ADFR&#039;&#039;&#039;|| &#039;&#039;&#039;ADIF&#039;&#039;&#039;|| &#039;&#039;&#039;ADIE&#039;&#039;&#039;|| &#039;&#039;&#039;ADPS2&#039;&#039;&#039;|| &#039;&#039;&#039;ADPS1&#039;&#039;&#039;|| &#039;&#039;&#039;ADPS0&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W|| R/W|| R/W|| R/W|| R/W|| R/W|| R/W|| R/W&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0|| 0|| 0|| 0|| 0|| 0|| 0|| 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ADEN&#039;&#039;&#039; (&#039;&#039;&#039;AD&#039;&#039;&#039;C &#039;&#039;&#039;En&#039;&#039;&#039;able)&lt;br /&gt;
:Dieses Bit muss gesetzt werden, um den &#039;&#039;&#039; ADC&#039;&#039;&#039; überhaupt zu aktivieren. Wenn das Bit nicht gesetzt ist, können die Pins wie normale I/O-Pins verwendet werden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ADSC&#039;&#039;&#039; (&#039;&#039;&#039;AD&#039;&#039;&#039;C &#039;&#039;&#039;S&#039;&#039;&#039;tart &#039;&#039;&#039;C&#039;&#039;&#039;onversion)&lt;br /&gt;
:Mit diesem Bit wird ein Messvorgang gestartet. In der frei laufenden Betriebsart muss das Bit gesetzt werden, um die kontinuierliche Messung zu aktivieren.&lt;br /&gt;
:Wenn das Bit nach dem Setzen des &#039;&#039;&#039;ADEN&#039;&#039;&#039;-Bits zum ersten Mal gesetzt wird, führt der Controller zuerst eine zusätzliche Wandlung und erst dann die eigentliche Wandlung aus. Diese zusätzliche Wandlung wird zu Initialisierungszwecken durchgeführt.&lt;br /&gt;
:Das Bit bleibt nun so lange auf 1, bis die Umwandlung abgeschlossen ist, im Initialisierungsfall entsprechend bis die zweite Umwandlung erfolgt ist und geht danach auf 0.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ADFR&#039;&#039;&#039; (&#039;&#039;&#039;AD&#039;&#039;&#039;C &#039;&#039;&#039;F&#039;&#039;&#039;ree &#039;&#039;&#039;R&#039;&#039;&#039;un select)&lt;br /&gt;
:Mit diesem Bit wird die Betriebsart eingestellt.&lt;br /&gt;
:Ist das Bit auf 1 gesetzt arbeitet der ADC im &amp;quot;Free Running&amp;quot;-Modus. Dabei wird das Datenregister permanent aktualisiert. Ist das Bit hingegen auf 0 gesetzt, macht der ADC nur eine &amp;quot;Single Conversion&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ADIF&#039;&#039;&#039; (&#039;&#039;&#039;AD&#039;&#039;&#039;C &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;F&#039;&#039;&#039;lag)&lt;br /&gt;
:Dieses Bit wird vom &#039;&#039;&#039; ADC&#039;&#039;&#039; gesetzt, sobald eine Umwandlung erfolgt ist und das &#039;&#039;&#039;ADC Data Register&#039;&#039;&#039; aktualisiert wurde. Das Bit wird bei lesendem Zugriff auf &#039;&#039;&#039;ADC(L,H)&#039;&#039;&#039; automatisch (d.h. durch die Hardware) gelöscht.&lt;br /&gt;
:Wenn das &#039;&#039;&#039;ADIE&#039;&#039;&#039; Bit sowie das &#039;&#039;&#039;I-Bit&#039;&#039;&#039; im AVR &#039;&#039;&#039;Statusregister&#039;&#039;&#039; gesetzt ist, wird der &#039;&#039;&#039;ADC Interrupt&#039;&#039;&#039; ausgelöst und die Interrupt-Behandlungsroutine aufgerufen.&lt;br /&gt;
:Das Bit wird automatisch gelöscht, wenn die Interrupt-Behandlungsroutine aufgerufen wird. Es kann jedoch auch gelöscht werden, indem eine logische &#039;&#039;&#039;1&#039;&#039;&#039;! in das Register geschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ADIE&#039;&#039;&#039; (&#039;&#039;&#039;AD&#039;&#039;&#039;C &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;E&#039;&#039;&#039;nable)&lt;br /&gt;
:Wenn dieses Bit gesetzt ist und ebenso das &#039;&#039;&#039; I-Bit&#039;&#039;&#039; im Statusregister &#039;&#039;&#039;SREG&#039;&#039;&#039;, dann wird der &#039;&#039;&#039; ADC-Interrupt&#039;&#039;&#039; aktiviert.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ADPS2...ADPS0&#039;&#039;&#039; (&#039;&#039;&#039;AD&#039;&#039;&#039;C &#039;&#039;&#039;P&#039;&#039;&#039;rescaler &#039;&#039;&#039;S&#039;&#039;&#039;elect Bits)&lt;br /&gt;
:Diese Bits bestimmen den Teilungsfaktor zwischen der Taktfrequenz und dem Eingangstakt des &#039;&#039;&#039;ADC&#039;&#039;&#039;.&lt;br /&gt;
:Der &#039;&#039;&#039;ADC&#039;&#039;&#039; benötigt einen eigenen Takt, welchen er sich selber aus der CPU-Taktfreqenz erzeugt. Der &#039;&#039;&#039;ADC&#039;&#039;&#039;-Takt sollte zwischen 50 und 200kHz liegen.&lt;br /&gt;
:Der Vorteiler muss also so eingestellt werden, dass CPU-Taktfrequenz dividiert durch den Teilungsfaktor einen Wert im Bereich &#039;&#039;&#039;(50-200)kHz&#039;&#039;&#039; ergibt.&lt;br /&gt;
:Bei einer CPU-Taktfrequenz von 4MHz beispielsweise rechnen wir&lt;br /&gt;
&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{matrix}&lt;br /&gt;
TF_{min}=\frac{CLK}{200\,\mathrm{kHz}}=\frac{4000000}{200000}=\mathbf{20}&lt;br /&gt;
\\&lt;br /&gt;
\\&lt;br /&gt;
TF_{max}=\frac{CLK}{50\,\mathrm{kHz}}=\frac{4000000}{50000}=\mathbf{80}&lt;br /&gt;
\end{matrix}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
:Somit kann hier der Teilungsfaktor 32 oder 64 verwendet werden. Im Interesse der schnelleren Wandlungszeit werden wir hier den Faktor 32 einstellen.&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &#039;&#039;&#039;ADPS2&#039;&#039;&#039;|| &#039;&#039;&#039;ADPS1&#039;&#039;&#039;|| &#039;&#039;&#039;ADPS0&#039;&#039;&#039;|| &#039;&#039;&#039;Teilungsfaktor&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| 0|| 0|| 0|| 2&lt;br /&gt;
|-&lt;br /&gt;
| 0|| 0|| 1|| 2&lt;br /&gt;
|-&lt;br /&gt;
| 0|| 1|| 0|| 4&lt;br /&gt;
|-&lt;br /&gt;
| 0|| 1|| 1|| 8&lt;br /&gt;
|-&lt;br /&gt;
| 1|| 0|| 0|| 16&lt;br /&gt;
|-&lt;br /&gt;
| 1|| 0|| 1|| 32&lt;br /&gt;
|-&lt;br /&gt;
| 1|| 1|| 0|| 64&lt;br /&gt;
|-&lt;br /&gt;
| 1|| 1|| 1|| 128&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;ADCL&#039;&#039;&#039;&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;ADCH&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;ADC &#039;&#039;&#039; Data Register&amp;lt;br /&amp;gt;&lt;br /&gt;
Wenn eine Umwandlung abgeschlossen ist, befindet sich der gemessene Wert in&lt;br /&gt;
diesen beiden Registern. Von &#039;&#039;&#039;ADCH&#039;&#039;&#039; werden nur die beiden niederwertigsten Bits verwendet. Es müssen immer beide Register ausgelesen werden, und zwar immer &#039;&#039;&#039;in der Reihenfolge: ADCL, ADCH&#039;&#039;&#039;. &lt;br /&gt;
Der effektive Messwert ergibt sich dann zu:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
x = ADCL;       // mit uint16_t x&lt;br /&gt;
x += (ADCH&amp;lt;&amp;lt;8); // in zwei Zeilen (LSB/MSB-Reihenfolge und&lt;br /&gt;
                // C-Operatorpriorität sichergestellt)&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oder &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
x = ADCW; // je nach AVR auch x = ADC (siehe avr/ioxxx.h)&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;ADMUX&amp;amp;nbsp;&amp;amp;nbsp;&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;AD&#039;&#039;&#039;C &#039;&#039;&#039;Mu&#039;&#039;&#039;ltiple&#039;&#039;&#039;x&#039;&#039;&#039;er Select Register&amp;lt;br /&amp;gt;&lt;br /&gt;
Mit diesem Register wird der zu messende Kanal ausgewählt. Beim 90S8535&lt;br /&gt;
kann jeder Pin von Port A als &#039;&#039;&#039;ADC&#039;&#039;&#039;-Eingang verwendet werden (=8 Kanäle).&amp;lt;br /&amp;gt;&lt;br /&gt;
Das Register ist wie folgt aufgebaut:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7|| 6|| 5|| 4|| 3|| 2|| 1|| 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;REFS1&#039;&#039;&#039;|| &#039;&#039;&#039;REFS0&#039;&#039;&#039;|| &#039;&#039;&#039;ADLAR&#039;&#039;&#039;|| &#039;&#039;&#039;MUX4&#039;&#039;&#039;|| &#039;&#039;&#039;MUX3&#039;&#039;&#039;|| &#039;&#039;&#039;MUX2&#039;&#039;&#039;|| &#039;&#039;&#039;MUX1&#039;&#039;&#039;|| &#039;&#039;&#039;MUX0&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! &#039;&#039;&#039;R/W&#039;&#039;&#039;&lt;br /&gt;
| R/W|| R/W|| R/W|| R/W|| R/W|| R/W|| R/W|| R/W&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0|| 0|| 0|| 0|| 0|| 0|| 0|| 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;REFS1...REFS0&#039;&#039;&#039; (&#039;&#039;&#039;Ref&#039;&#039;&#039;erence&#039;&#039;&#039;S&#039;&#039;&#039;election Bits)&lt;br /&gt;
:Mit diesen Bits kann die Referenzspannung eingestellt werden. Bei der Umstellung sind Wartezeiten zu beachten, bis die ADC-Hardware einsatzfähig ist (Datenblatt und  [http://www.mikrocontroller.net/topic/165513]):&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! &#039;&#039;&#039;REFS1&#039;&#039;&#039;|| &#039;&#039;&#039;REFS0&#039;&#039;&#039;|| &#039;&#039;&#039;Referenzspanung&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
| 0|| 0|| Externes AREF&lt;br /&gt;
|-&lt;br /&gt;
| 0|| 1|| AVCC als Referenz&lt;br /&gt;
|-&lt;br /&gt;
| 1|| 0|| Reserviert&lt;br /&gt;
|-&lt;br /&gt;
| 1|| 1|| Interne 2,56 Volt&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ADLAR&#039;&#039;&#039; (&#039;&#039;&#039;ADC &#039;&#039;&#039; &#039;&#039;&#039;L&#039;&#039;&#039;eft &#039;&#039;&#039;A&#039;&#039;&#039;djust &#039;&#039;&#039;R&#039;&#039;&#039;esult)&lt;br /&gt;
:Das ADLAR Bit verändert das Aussehen des Ergebnisses der AD-Wandlung. Bei einer logischen 1 wird das Ergebnis linksbündig ausgegeben, bei einer 0 rechtsbündig. Eine Änderung in diesem Bit beeinflusst das Ergebnis sofort, ganz egal ob bereits eine Wandlung läuft.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;MUX4...MUX0&#039;&#039;&#039;&lt;br /&gt;
:Mit diesen 5 Bits wird der zu messende Kanal bestimmt. Wenn man einen einfachen 1-kanaligen ADC verwendet wird einfach die entsprechende Pinnummer des Ports in die Bits 0...4 eingeschrieben (je nach Anzahl der Wandler des AVR, bei 8 AD-Kanälen halt nur 0...2).&lt;br /&gt;
:Wenn das Register beschrieben wird, während eine Umwandlung läuft, so wird zuerst die aktuelle Umwandlung auf dem bisherigen Kanal beendet. Dies ist vor allem beim frei laufenden Betrieb zu berücksichtigen.&lt;br /&gt;
&lt;br /&gt;
:Eine Empfehlung ist deswegen diese, dass der frei laufende Betrieb nur bei einem einzelnen zu verwendenden Analogeingang verwendet werden sollte, wenn man sich Probleme bei der Umschalterei ersparen will.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Nutzung des ADC ====&lt;br /&gt;
&lt;br /&gt;
Um den &#039;&#039;&#039; ADC&#039;&#039;&#039; zu aktivieren, müssen wir das &#039;&#039;&#039;ADEN&#039;&#039;&#039;-Bit im &#039;&#039;&#039;ADCSR&#039;&#039;&#039;-Register setzen. Im gleichen Schritt legen wir auch die Betriebsart fest. &lt;br /&gt;
&lt;br /&gt;
Im Folgenden ein kleines Beispiel für den &amp;quot;single conversion&amp;quot;-Mode bei einem ATmega169 und Nutzung der internen Referenzspannung (beim &#039;169 1,1V bei anderen AVRs auch 2,56V, vgl. Datenblatt). D.h. das Eingangssignal darf diese Spannung nicht überschreiten, gegebenenfalls muss es mit einem [[Spannungsteiler]] verringert werden. Das Ergebnis der Routine ist der ADC-Wert, also 0 für 0-Volt und 1023 für V_ref-Volt. Beim Programmstart wir der ADC konfiguriert und aktiviert und dann auf verschiedenen Kanälen die Spannung gemessen. Initialisierung des ADC und die Wandlungen sollte man trennen, denn das Einschalten des ADC und vor allem der Referenzspannung dauert ein paar Dutzend Mikrosekunden. Außerdem ist das erste Ergebnis nach dem Einschalten ungültig und muss verworfen werden.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// Diese Beispiel zeigt die Anwendung des ADC eines ATmega169&lt;br /&gt;
// unter Verwendung der internen Referenzspannung von nominell 1,1V.&lt;br /&gt;
// Zur Anpassung an andere AVR und/oder andere Referenzspannungen&lt;br /&gt;
// siehe Erläuterungen in diesem Tutorial und im Datenblatt&lt;br /&gt;
&lt;br /&gt;
/* ADC initialisieren */&lt;br /&gt;
void ADC_Init(void) {&lt;br /&gt;
&lt;br /&gt;
  uint16_t result;&lt;br /&gt;
&lt;br /&gt;
  // interne Referenzspannung als Refernz für den ADC wählen:&lt;br /&gt;
  ADMUX = (1&amp;lt;&amp;lt;REFS1) | (1&amp;lt;&amp;lt;REFS0);&lt;br /&gt;
  &lt;br /&gt;
  // Bit ADFR (&amp;quot;free running&amp;quot;) in ADCSRA steht beim Einschalten&lt;br /&gt;
  // schon auf 0, also single conversion&lt;br /&gt;
  ADCSRA = (1&amp;lt;&amp;lt;ADPS1) | (1&amp;lt;&amp;lt;ADPS0);     // Frequenzvorteiler&lt;br /&gt;
  ADCSRA |= (1&amp;lt;&amp;lt;ADEN);                  // ADC aktivieren&lt;br /&gt;
&lt;br /&gt;
  /* nach Aktivieren des ADC wird ein &amp;quot;Dummy-Readout&amp;quot; empfohlen, man liest&lt;br /&gt;
     also einen Wert und verwirft diesen, um den ADC &amp;quot;warmlaufen zu lassen&amp;quot; */&lt;br /&gt;
&lt;br /&gt;
  ADCSRA |= (1&amp;lt;&amp;lt;ADSC);                  // eine ADC-Wandlung &lt;br /&gt;
  while (ADCSRA &amp;amp; (1&amp;lt;&amp;lt;ADSC) ) {}        // auf Abschluss der Konvertierung warten&lt;br /&gt;
  /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten&lt;br /&gt;
     Wandlung nicht übernommen. */&lt;br /&gt;
  result = ADCW;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ADC Einzelmessung */&lt;br /&gt;
uint16_t ADC_Read( uint8_t channel )&lt;br /&gt;
{&lt;br /&gt;
  // Kanal waehlen, ohne andere Bits zu beeinflußen&lt;br /&gt;
  ADMUX = (ADMUX &amp;amp; ~(0x1F)) | (channel &amp;amp; 0x1F);&lt;br /&gt;
  ADCSRA |= (1&amp;lt;&amp;lt;ADSC);            // eine Wandlung &amp;quot;single conversion&amp;quot;&lt;br /&gt;
  while (ADCSRA &amp;amp; (1&amp;lt;&amp;lt;ADSC) ) {}  // auf Abschluss der Konvertierung warten&lt;br /&gt;
  return ADCW;                    // ADC auslesen und zurückgeben&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ADC Mehrfachmessung mit Mittelwertbbildung */&lt;br /&gt;
/* beachte: Wertebereich der Summenvariablen */&lt;br /&gt;
uint16_t ADC_Read_Avg( uint8_t channel, uint8_t nsamples )&lt;br /&gt;
{&lt;br /&gt;
  uint32_t sum = 0;&lt;br /&gt;
&lt;br /&gt;
  for (uint8_t i = 0; i &amp;lt; nsamples; ++i ) {&lt;br /&gt;
    sum += ADC_Read( channel );&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
  return (uint16_t)( sum / nsamples );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
/* Beispielaufrufe: */&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  uint16_t adcval;&lt;br /&gt;
  ADC_Init();&lt;br /&gt;
&lt;br /&gt;
  while( 1 ) {&lt;br /&gt;
    adcval = ADC_Read(0);  // Kanal 0&lt;br /&gt;
    // mach was mit adcval&lt;br /&gt;
&lt;br /&gt;
    adcval = ADC_Read_Avg(2, 4);  // Kanal 2, Mittelwert aus 4 Messungen&lt;br /&gt;
    // mach was mit adcval&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Im Beispiel läuft der ADC ständig. Für den Fall, dass man Strom sparen will, z.B. mittels Verwendung des [[Sleep Mode]]s, muss man den ADC nach jeder Messung abschalten und vor der nächsten Messung wieder einschalten, wobei auch dann wieder eine kleine Pause und Anfangswandlung nötig sind.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
Das Löschen des ADIF-Flags sollte, &#039;&#039;&#039;entgegen&#039;&#039;&#039; der [http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_intbits FAQ], mit&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  ADCSRA |= (1&amp;lt;&amp;lt;ADIF);&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
erfolgen. Die Methode in der FAQ eignet sich nur für Register, in denen &#039;&#039;&#039;nur&#039;&#039;&#039; Interrupt-Flags stehen.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Analog-Digital-Wandlung ohne internen ADC ===&lt;br /&gt;
&lt;br /&gt;
==== Messen eines Widerstandes ====&lt;br /&gt;
&lt;br /&gt;
[[Image:Poti.gif|framed|right]]&lt;br /&gt;
Analoge Werte lassen sich ohne Analog-Digital-Wandler auch indirekt ermitteln. Im Folgenden wird die Messung des an einem Potentiometer eingestellten Widerstands anhand der Ladekurve eines Kondensators erläutert. Bei dieser Methode wird nur ein Portpin benötigt, ein Analog-Digital-Wandler oder Analog-Comparator ist nicht erforderlich. Es wird dazu ein Kondensator und der Widerstand (das Potentiometer) in Reihe zwischen Vorsorgungsspannung und Masse/GND geschaltet (sogen. RC-Netzwerk). Zusätzlich wird eine Verbindung der Leitung zwischen Kondensator und Potentiometer zu einem Portpin des Controllers hergestellt. Die folgende Abbildung verdeutlicht die erforderliche Schaltung. &lt;br /&gt;
&lt;br /&gt;
Wird der Portpin des Controllers auf Ausgang konfiguriert (im Beispiel &#039;&#039;DDRD&amp;amp;nbsp;|=&amp;amp;nbsp;(1&amp;lt;&amp;lt;PD2)&#039;&#039;) und dieser Ausgang auf Logisch 1 (&amp;quot;High&amp;quot;, &#039;&#039;PORTD&amp;amp;nbsp;|=&amp;amp;nbsp;(1&amp;lt;&amp;lt;PD2)&#039;&#039;) geschaltet, liegt an beiden &amp;quot;Platten&amp;quot; des Kondensators das gleiche Potential &#039;&#039;&#039;VCC&#039;&#039;&#039; an und der Kondensator somit entladen. (Klingt komisch, mit &#039;&#039;&#039; Vcc&#039;&#039;&#039; entladen, ist aber so, da an beiden Seiten des Kondensators das gleiche Potential anliegt und somit eine Potentialdifferenz von 0V besteht =&amp;gt; Kondensator ist entladen).&lt;br /&gt;
&lt;br /&gt;
Nach einer gewissen Zeit ist der Kondensator entladen und der Portpin wird als Eingang konfiguriert (&#039;&#039;DDRD&amp;amp;nbsp;&amp;amp;=&amp;amp;nbsp;~(1&amp;lt;&amp;lt;PD2); PORTD&amp;amp;nbsp;&amp;amp;=&amp;amp;nbsp;~(1&amp;lt;&amp;lt;PD2)&#039;&#039;), wodurch dieser hochohmig wird. Der Status des Eingangspin (in PIND) ist Logisch 1 (High). Der Kondensator lädt sich jetzt über das Poti auf, dabei steigt der Spannungsabfall über dem Kondensator und derjenige über dem Poti sinkt. Fällt nun der Spannungsabfall über dem Poti unter die Threshold-Spannung des Eingangspins (2/5 Vcc, also ca. 2V), wird das Eingangssignal als LOW erkannt (Bit in PIND wird 0). Die Zeitspanne zwischen der Umschaltung von Entladung auf Aufladung und dem Wechsel des Eingangssignals von High auf Low ist ein Maß für den am Potentiometer eingestellten Widerstand. Zur Zeitmessung kann einer der im Controller vorhandenen Timer genutzt werden. Der 220Ω Widerstand dient dem Schutz des Controllers. Es würde sonst bei Maximaleinstellung des Potentionmeters (hier 0Ω) ein zu hoher Strom fließen, der die Ausgangsstufe des Controllers zerstört. &lt;br /&gt;
&lt;br /&gt;
Mit einem weiteren Eingangspin und ein wenig Software können wir auch eine Kalibrierung realisieren, um den Messwert in einen vernünftigen Bereich (z.B: 0...100 % oder so) umzurechnen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Link 404 =&amp;gt; auskommentiert, mthomas 9.2.2008 &lt;br /&gt;
Ein Beispielprogramm findet sich auf [http://www.mypage.bluewin.ch/ch_schifferle/ Christian Schifferles Web-Seite] im Archiv &#039;&#039;ATMEL.ZIP&#039;&#039;, welches unter den Titel &#039;&#039;Tutorial &amp;quot;Programmieren mit C für Atmel Mikrocontroller&#039;&#039; heruntergeladen werden kann. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== ADC über Komparator ====&lt;br /&gt;
&lt;br /&gt;
[[Image:ADC ueber Komparator.gif|framed|right]]&lt;br /&gt;
Es gibt einen weiteren Weg, eine analoge Spannung mit Hilfe des&lt;br /&gt;
Komparators, welcher in fast jedem AVR integriert ist, zu messen. Siehe dazu&lt;br /&gt;
auch die Application Note AVR400 von Atmel.&lt;br /&gt;
&lt;br /&gt;
Dabei wird das zu messende Signal auf den invertierenden Eingang&lt;br /&gt;
des Komparators geführt. Zusätzlich wird ein Referenzsignal an den nicht&lt;br /&gt;
invertierenden Eingang des Komparators angeschlossen. Das Referenzsignal wird&lt;br /&gt;
hier auch wieder über ein RC-Glied erzeugt, allerdings mit festen Werten für R&lt;br /&gt;
und C.&lt;br /&gt;
&lt;br /&gt;
Das Prinzip der Messung ist nun dem vorhergehenden recht&lt;br /&gt;
ähnlich. Durch Anlegen eines LOW-Pegels an Pin 2 wird der Kondensator zuerst&lt;br /&gt;
einmal entladen. Auch hier muss darauf geachtet werden, dass der Entladevorgang&lt;br /&gt;
genügend lang dauert.&lt;br /&gt;
Nun wird Pin 2 auf HIGH gelegt. Der Kondensator wird geladen. Wenn die Spannung&lt;br /&gt;
über dem Kondensator die am Eingangspin anliegende Spannung erreicht hat,&lt;br /&gt;
schaltet der Komparator durch. Die Zeit, welche benötigt wird, um den&lt;br /&gt;
Kondensator zu laden, kann nun auch wieder als Maß für die Spannung an Pin 1&lt;br /&gt;
herangezogen werden.&lt;br /&gt;
&lt;br /&gt;
Ich habe es mir gespart, diese Schaltung auch aufzubauen, und zwar aus mehreren Gründen:&lt;br /&gt;
&lt;br /&gt;
# 3 Pins notwendig.&lt;br /&gt;
# Genauigkeit vergleichbar mit einfacherer Lösung.&lt;br /&gt;
# War einfach zu faul.&lt;br /&gt;
&lt;br /&gt;
Der Vorteil dieser Schaltung liegt allerdings darin, dass damit direkt Spannungen gemessen werden können.&lt;br /&gt;
&lt;br /&gt;
== DAC (Digital Analog Converter) ==&lt;br /&gt;
&lt;br /&gt;
Mit Hilfe eines Digital-Analog-Konverters (&#039;&#039;&#039;DAC&#039;&#039;&#039;) können wir nun auch Analogsignale ausgeben. Es gibt hier mehrere Verfahren. &amp;lt;!-- Wenn wir beim ADC die Möglichkeit haben, mit externen Komponenten zu operieren, müssen wir bei der DAC-Wandlung mit dem auskommen, was der Controller selber zu bieten hat. --mt: hmm, richtig? verstaendlich? redundant? --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== DAC über mehrere digitale Ausgänge ===&lt;br /&gt;
&lt;br /&gt;
Wenn wir an den Ausgängen des Controllers ein entsprechendes&lt;br /&gt;
Widerstandsnetzwerk aufbauen haben wir die Möglichkeit, durch die Ansteuerung&lt;br /&gt;
der Ausgänge über den Widerständen einen Addierer aufzubauen, mit dessen&lt;br /&gt;
Hilfe wir eine dem Zahlenwert proportionale Spannung erzeugen können. Das&lt;br /&gt;
Schaltbild dazu kann etwa so aussehen:&lt;br /&gt;
&lt;br /&gt;
[[Image:DAC R2R.gif]]&lt;br /&gt;
&lt;br /&gt;
Es sollten selbstverständlich möglichst genaue Widerstände verwendet&lt;br /&gt;
werden, also nicht unbedingt solche mit einer Toleranz von 10% oder mehr.&lt;br /&gt;
Weiterhin empfiehlt es sich, je nach Anwendung den Ausgangsstrom über einen&lt;br /&gt;
Operationsverstärker zu verstärken.&lt;br /&gt;
&lt;br /&gt;
=== PWM (Pulsweitenmodulation) ===&lt;br /&gt;
&lt;br /&gt;
Wir kommen nun zu einem Thema, welches in aller Munde ist, aber viele&lt;br /&gt;
Anwender verstehen nicht ganz, wie [[PWM]] eigentlich funktioniert.&lt;br /&gt;
&lt;br /&gt;
Wie wir alle wissen, ist ein Mikrocontroller ein rein digitales Bauteil.&lt;br /&gt;
Definieren wir einen Pin als Ausgang, dann können wir diesen Ausgang entweder&lt;br /&gt;
auf HIGH setzen, worauf am Ausgang die Versorgungsspannung &#039;&#039;&#039; Vcc&#039;&#039;&#039; anliegt, oder aber wir setzen den Ausgang auf LOW, wonach dann &#039;&#039;&#039; 0V&#039;&#039;&#039; am Ausgang liegt. Was passiert aber nun, wenn wir periodisch mit einer festen Frequenz zwischen HIGH und LOW umschalten? - Richtig, wir erhalten eine Rechteckspannung, wie die folgende Abbildung zeigt:&lt;br /&gt;
&lt;br /&gt;
[[Image:PWM Theorie 1.gif]]&lt;br /&gt;
&lt;br /&gt;
Diese Rechteckspannung hat nun einen arithmetischen Mittelwert, &lt;br /&gt;
der je nach Pulsbreite kleiner oder größer ist.&lt;br /&gt;
&lt;br /&gt;
[[Image:PWM Theorie 2.gif]]&lt;br /&gt;
&lt;br /&gt;
Wenn wir nun diese pulsierende Ausgangsspannung noch über ein RC-Glied filtern/&amp;quot;glätten&amp;quot;, dann haben wir schon eine entsprechende Gleichspannung erzeugt.&lt;br /&gt;
&lt;br /&gt;
Mit den AVRs können wir direkt PWM-Signale erzeugen. &lt;br /&gt;
Dazu dient der 16-Bit Zähler, welcher im sogenannten PWM-Modus betrieben werden kann.&lt;br /&gt;
&lt;br /&gt;
;Hinweis: In den folgenden Überlegungen wird als Controller der 90S2313 vorausgesetzt. Die Theorie ist bei anderen AVR-Controllern vergleichbar, die Pinbelegung allerdings nicht unbedingt, weshalb ein Blick ins entsprechende Datenblatt dringend angeraten wird.&lt;br /&gt;
&lt;br /&gt;
Um den PWM-Modus zu aktivieren, müssen im Timer/Counter1 Control&lt;br /&gt;
Register A TCCR1A die Pulsweiten-Modulatorbits PWM10 bzw. PWM11 entsprechend nachfolgender Tabelle gesetzt werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! PWM11 || PWM10 || Bedeutung&lt;br /&gt;
|- &lt;br /&gt;
| 0 || 0 || PWM-Modus des Timers ist nicht aktiv&lt;br /&gt;
|- &lt;br /&gt;
| 0 || 1 || 8-Bit PWM&lt;br /&gt;
|- &lt;br /&gt;
| 1 || 0 || 9-Bit PWM&lt;br /&gt;
|- &lt;br /&gt;
| 1 || 1 || 10-Bit PWM&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Der Timer/Counter zählt nun permanent von 0 bis zur Obergrenze&lt;br /&gt;
und wieder zurück, er wird also als sogenannter Auf-/Ab Zähler betrieben. &lt;br /&gt;
Die Obergrenze hängt davon ab, ob wir mit 8, 9 oder 10-Bit PWM arbeiten wollen:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Auflösung || Obergrenze || Frequenz&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 8&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 255&lt;br /&gt;
| f&amp;lt;sub&amp;gt;TC1&amp;lt;/sub&amp;gt; / 510&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 9&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 511&lt;br /&gt;
| f&amp;lt;sub&amp;gt;TC1&amp;lt;/sub&amp;gt; / 1022&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 10&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1023&lt;br /&gt;
| f&amp;lt;sub&amp;gt;TC1&amp;lt;/sub&amp;gt; / 2046&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Zusätzlich muss mit den Bits &#039;&#039;&#039;COM1A1&#039;&#039;&#039; und &#039;&#039;&#039;COM1A0&#039;&#039;&#039; desselben&lt;br /&gt;
Registers die gewünschte Ausgabeart des Signals definiert werden:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! COM1A1 || COM1A0 || Bedeutung&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Keine Wirkung, Pin wird nicht geschaltet.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Keine Wirkung, Pin wird nicht geschaltet.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Nicht invertierende PWM.&amp;lt;br /&amp;gt;&lt;br /&gt;
Der Ausgangspin wird gelöscht beim Hochzählen und gesetzt beim&lt;br /&gt;
Herunterzählen.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Invertierende PWM.&amp;lt;br /&amp;gt;&lt;br /&gt;
Der Ausgangspin wird gelöscht beim Herunterzählen und gesetzt beim&lt;br /&gt;
Hochzählen.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Der entsprechende Befehl, um beispielsweise den Timer/Counter als&lt;br /&gt;
nicht invertierenden 10-Bit PWM zu verwenden, heißt dann:&lt;br /&gt;
&lt;br /&gt;
alte Schreibweise (PWMxx wird nicht mehr akzeptiert)&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
TCCR1A = (1&amp;lt;&amp;lt;PWM11)|(1&amp;lt;&amp;lt;PWM10)|(1&amp;lt;&amp;lt;COM1A1);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
neue Schreibweise&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
TCCR1A = (1&amp;lt;&amp;lt;WGM11)|(1&amp;lt;&amp;lt;WGM10)|(1&amp;lt;&amp;lt;COM1A1);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit der Timer/Counter überhaupt läuft, müssen wir im Control&lt;br /&gt;
Register B &#039;&#039;&#039;TCCR1B&#039;&#039;&#039; noch den gewünschten Takt (Vorteiler) einstellen und&lt;br /&gt;
somit auch die Frequenz des &#039;&#039;&#039;PWM&#039;&#039;&#039;-Signals bestimmen.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! CS12 || CS11 || CS10 || Bedeutung&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Stop. Der Timer/Counter wird gestoppt.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| CK&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| CK / 8&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| CK / 64&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| CK / 256&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| CK / 1024&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Externer Pin 1, negative Flanke&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Externer Pin 1, positive Flanke&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Also um einen Takt von CK / 1024 zu generieren, verwenden wir&lt;br /&gt;
folgenden Befehl:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
TCCR1B = (1&amp;lt;&amp;lt;CS12) | (1&amp;lt;&amp;lt;CS10);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Jetzt muss nur noch der Vergleichswert festgelegt werden. Diesen&lt;br /&gt;
schreiben wir in das 16-Bit Timer/Counter Output Compare Register &#039;&#039;&#039;OCR1A&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
OCR1A = xxx;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die folgende Grafik soll den Zusammenhang zwischen dem Vergleichswert und dem generierten &#039;&#039;&#039;PWM&#039;&#039;&#039;-Signal aufzeigen.&lt;br /&gt;
&lt;br /&gt;
[[Image:PWM Theorie 3.gif]]&lt;br /&gt;
&lt;br /&gt;
[[Image:PWM Theorie 4.gif]]&lt;br /&gt;
&lt;br /&gt;
Ach ja, fast hätte ich&#039;s vergessen. Das generierte &#039;&#039;&#039;PWM&#039;&#039;&#039;-Signal&lt;br /&gt;
wird am Output Compare Pin &#039;&#039;&#039;OC1&#039;&#039;&#039; des Timers ausgegeben und leider können wir&lt;br /&gt;
deshalb auch beim AT90S2313 nur ein einzelnes &#039;&#039;&#039;PWM&#039;&#039;&#039;-Signal mit dieser Methode generieren. Andere AVR-Typen verfügen über bis zu vier PWM-Ausgänge. Zu beachten ist außerdem, das wenn der OC Pin aktiviert ist, er nichtmehr wie üblich funktioniert und z.&amp;amp;nbsp;B. nicht einfach über PINx ausgelesen werden kann.&lt;br /&gt;
&lt;br /&gt;
Ein Programm, welches an einem ATmega8 den Fast-PWM Modus verwendet, den Modus 14, könnte so aussehen&lt;br /&gt;
&amp;lt;C&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  // OC1A auf Ausgang&lt;br /&gt;
  DDRB = (1 &amp;lt;&amp;lt; PB1 );  //ATMega8&lt;br /&gt;
  // DDRD = (1 &amp;lt;&amp;lt; PD5 ); //ATMega16&lt;br /&gt;
  //&lt;br /&gt;
  // Timer 1 einstellen&lt;br /&gt;
  //  &lt;br /&gt;
  // Modus 14:&lt;br /&gt;
  //    Fast PWM, Top von ICR1&lt;br /&gt;
  //&lt;br /&gt;
  //    WGM13    WGM12   WGM11    WGM10&lt;br /&gt;
  //      1        1       1        0&lt;br /&gt;
  //&lt;br /&gt;
  //    Timer Vorteiler: 1&lt;br /&gt;
  //     CS12     CS11    CS10&lt;br /&gt;
  //       0        0       1&lt;br /&gt;
  //&lt;br /&gt;
  //  Steuerung des Ausgangsport: Set at BOTTOM, Clear at match&lt;br /&gt;
  //     COM1A1   COM1A0&lt;br /&gt;
  //       1        0&lt;br /&gt;
 &lt;br /&gt;
  TCCR1A = (1&amp;lt;&amp;lt;COM1A1) | (1&amp;lt;&amp;lt;WGM11);&lt;br /&gt;
  TCCR1B = (1&amp;lt;&amp;lt;WGM13) | (1&amp;lt;&amp;lt;WGM12) | (1&amp;lt;&amp;lt;CS10);&lt;br /&gt;
 &lt;br /&gt;
  //  den Endwert (TOP) für den Zähler setzen&lt;br /&gt;
  //  der Zähler zählt bis zu diesem Wert&lt;br /&gt;
&lt;br /&gt;
  ICR1 = 0x6FFF;&lt;br /&gt;
 &lt;br /&gt;
  // der Compare Wert&lt;br /&gt;
  // Wenn der Zähler diesen Wert erreicht, wird mit&lt;br /&gt;
  // obiger Konfiguration der OC1A Ausgang abgeschaltet&lt;br /&gt;
  // Sobald der Zähler wieder bei 0 startet, wird der&lt;br /&gt;
  // Ausgang wieder auf 1 gesetzt&lt;br /&gt;
  //&lt;br /&gt;
  // Durch Verändern dieses Wertes, werden die unterschiedlichen&lt;br /&gt;
  // PWM Werte eingestellt.&lt;br /&gt;
&lt;br /&gt;
  OCR1A = 0x3FFF;&lt;br /&gt;
&lt;br /&gt;
  while (1) {}&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/C&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;PWM-Mode Tabelle aus dem Datenblatt des ATmega8515&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
!Mode || WGM13 || WGM12 || WGM11 || WGM10 || Timer/Counter Mode of Operation&lt;br /&gt;
! TOP|| Update of OCR1x at || TOV1 Flag set on&lt;br /&gt;
|- &lt;br /&gt;
! 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| Normal&lt;br /&gt;
| 0xFFFF&lt;br /&gt;
| Immediate&lt;br /&gt;
| MAX&lt;br /&gt;
|-&lt;br /&gt;
! 1&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| PWM, Phase Correct, 8-Bit&lt;br /&gt;
| 0x00FF&lt;br /&gt;
| TOP&lt;br /&gt;
| BOTTOM&lt;br /&gt;
|- &lt;br /&gt;
! 2&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| PWM, Phase Correct, 9-Bit&lt;br /&gt;
| 0x01FF&lt;br /&gt;
| TOP&lt;br /&gt;
| BOTTOM&lt;br /&gt;
|-&lt;br /&gt;
! 3&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| PWM, Phase Correct, 10-Bit&lt;br /&gt;
| 0x03FF&lt;br /&gt;
| TOP&lt;br /&gt;
| BOTTOM&lt;br /&gt;
|-&lt;br /&gt;
! 4&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| CTC&lt;br /&gt;
| OCR1A&lt;br /&gt;
| Immediate&lt;br /&gt;
| MAX&lt;br /&gt;
|-&lt;br /&gt;
! 5&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| Fast PWM, 8-Bit&lt;br /&gt;
| 0x00FF&lt;br /&gt;
| BOTTOM&lt;br /&gt;
| TOP&lt;br /&gt;
|-&lt;br /&gt;
! 6&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| Fast PWM, 9-Bit&lt;br /&gt;
| 0x01FF&lt;br /&gt;
| BOTTOM&lt;br /&gt;
| TOP&lt;br /&gt;
|-&lt;br /&gt;
! 7&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| Fast PWM, 10-Bit&lt;br /&gt;
| 0x03FF&lt;br /&gt;
| BOTTOM&lt;br /&gt;
| TOP&lt;br /&gt;
|-&lt;br /&gt;
! 8&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| PWM, Phase an Frequency Correct&lt;br /&gt;
| ICR1&lt;br /&gt;
| BOTTOM&lt;br /&gt;
| BOTTOM&lt;br /&gt;
|-    &lt;br /&gt;
! 9&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| PWM, Phase an Frequency Correct&lt;br /&gt;
| OCR1A&lt;br /&gt;
| BOTTOM&lt;br /&gt;
| BOTTOM&lt;br /&gt;
|-&lt;br /&gt;
! 10&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| PWM, Phase Correct&lt;br /&gt;
| ICR1&lt;br /&gt;
| TOP&lt;br /&gt;
| BOTTOM&lt;br /&gt;
|-&lt;br /&gt;
! 11&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| PWM, Phase an Frequency Correct&lt;br /&gt;
| OCR1A&lt;br /&gt;
| TOP&lt;br /&gt;
| BOTTOM&lt;br /&gt;
|-&lt;br /&gt;
! 12&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 0&lt;br /&gt;
| CTC&lt;br /&gt;
| ICR1&lt;br /&gt;
| Immediate&lt;br /&gt;
| MAX&lt;br /&gt;
|-&lt;br /&gt;
! 13&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| Reserved&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
! 14&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 0&lt;br /&gt;
| Fast PWM&lt;br /&gt;
| ICR1&lt;br /&gt;
| BOTTOM&lt;br /&gt;
| TOP&lt;br /&gt;
|-&lt;br /&gt;
! 15&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| 1&lt;br /&gt;
| Fast PWM&lt;br /&gt;
| OCR1A&lt;br /&gt;
| BOTTOM&lt;br /&gt;
| TOP&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Für Details der PWM-Möglichkeiten muss immer das jeweilige Datenblatt des Prozessors konsultiert werden, da sich die unterschiedlichen Prozessoren in ihren Möglichkeiten doch stark unterscheiden. Auch muss man aufpassen, welches zu setzende Bit in welchem Register ist. Auch hier kann es sein, dass gleichnamige Konfigurationsbits in unterschiedlichen Konfigurationsregistern (je nach konkretem Prozessortyp) sitzen.&lt;br /&gt;
&lt;br /&gt;
= Warteschleifen (delay.h) =&lt;br /&gt;
&lt;br /&gt;
Der Programmablauf kann verschiedene Arten von Wartefunktionen erfordern:&lt;br /&gt;
&lt;br /&gt;
* Warten im Sinn von Zeitvertrödeln&lt;br /&gt;
* Warten auf einen bestimmten Zustand an den I/O-Pins&lt;br /&gt;
* Warten auf einen bestimmten Zeitpunkt (siehe Timer)&lt;br /&gt;
* Warten auf einen bestimmten Zählerstand (siehe Counter)&lt;br /&gt;
&lt;br /&gt;
Der einfachste Fall, das Zeitvertrödeln, kann in vielen Fällen und mit großer Genauigkeit anhand der avr-libc Bibliotheksfunktionen _delay_ms() und _delay_us() erledigt werden. Die Bibliotheksfunktionen sind einfachen Zählschleifen (Warteschleifen) vorzuziehen, da leere Zählschleifen ohne besondere Vorkehrungen sonst bei eingeschalteter Optimierung vom avr-gcc-Compiler wegoptimiert werden. Weiterhin sind die Bibliotheksfunktionen bereits darauf vorbereitet, die in F_CPU definierte Taktfrequenz zu verwenden. Außerdem sind die Funktionen der Bibliothek wirklich getestet.&lt;br /&gt;
&lt;br /&gt;
Einfach!? Schon, aber während gewartet wird, macht der µC nichts anderes mehr (abgesehen von möglicherweise auftretenden Interrupts, falls welche aktiviert sind). Die Wartefunktion blockiert den Programmablauf. Möchte man einerseits warten, um z.&amp;amp;nbsp;B. eine LED blinken zu lassen und gleichzeitig andere Aktionen ausführen z.&amp;amp;nbsp;B. weitere LED bedienen, sollten die Timer/Counter des AVR verwendet werden.&lt;br /&gt;
&lt;br /&gt;
Die Bibliotheksfunktionen funktionieren allerdings nur dann korrekt, wenn sie mit zur Übersetzungszeit (beim Compilieren) bekannten konstanten Werten aufgerufen werden. Der Quellcode muss mit eingeschalteter Optimierung übersetzt werden, sonst wird sehr viel Maschinencode erzeugt, und die Wartezeiten stimmen nicht mehr mit dem Parameter überein.&lt;br /&gt;
&lt;br /&gt;
Eine weitere Einschränkung liegt darin, daß sie möglicherweise länger warten, als erwartet, nämlich in dem Fall, daß Interrupts auftreten und die _delay...()-Funktion unterbrechen. Genau genommen warten diese nämlich nicht eine bestimmte Zeit, sondern verbrauchen eine bestimmte Anzahl von Prozessortakten. Die wiederum ist so bemessen, daß ohne Unterbrechung durch Interrupts die gewünschte Wartezeit erreicht wird.&lt;br /&gt;
Wird das Warten aber durch eine oder mehrere ISR unterbrochen, die zusammen 1% Prozessorzeit verbrauchen, dann dauert das Warten etwa 1% länger. Bei 50% Last durch die ISR dauert das Warten doppelt solange wie gewünscht, bei 90% zehnmal solange...&lt;br /&gt;
&lt;br /&gt;
Abhängig von der Version der Bibliothek verhalten sich die Bibliotheksfunktionen etwas unterschiedlich.&lt;br /&gt;
&lt;br /&gt;
== avr-libc Versionen kleiner 1.6 ==&lt;br /&gt;
&lt;br /&gt;
Die Wartezeit der Funktion _delay_ms() ist auf 262,14ms/F_CPU (in MHz) begrenzt, d.h. bei 20 MHz kann man nur max. 13,1ms warten. Die Wartezeit der Funktion _delay_us() ist auf 768us/F_CPU (in MHz) begrenzt, d.h. bei 20 MHz kann man nur max. 38,4µs warten. Längere Wartezeiten müssen dann über einen mehrfachen Aufruf in einer Schleife gelöst werden.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Blinken einer LED an PORTB Pin PB0 im ca. 1s Rhythmus&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert &lt;br /&gt;
   (z.&amp;amp;nbsp;B. durch Übergabe als Parameter zum Compiler innerhalb &lt;br /&gt;
   des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die&lt;br /&gt;
   &amp;quot;nachträgliche&amp;quot; Definition hinweist */&lt;br /&gt;
#warning &amp;quot;F_CPU war noch nicht definiert, wird nun mit 3686400 definiert&amp;quot;&lt;br /&gt;
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */&lt;br /&gt;
#endif&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;     /* in älteren avr-libc Versionen &amp;lt;avr/delay.h&amp;gt; */ &lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
 lange, variable Verzögerungszeit, Einheit in Millisekunden&lt;br /&gt;
&lt;br /&gt;
Die maximale Zeit pro Funktionsaufruf ist begrenzt auf &lt;br /&gt;
262.14 ms / F_CPU in MHz (im Beispiel: &lt;br /&gt;
262.1 / 3.6864 = max. 71 ms) &lt;br /&gt;
&lt;br /&gt;
Daher wird die kleine Warteschleife mehrfach aufgerufen,&lt;br /&gt;
um auf eine längere Wartezeit zu kommen. Die zusätzliche &lt;br /&gt;
Prüfung der Schleifenbedingung lässt die Wartezeit geringfügig&lt;br /&gt;
ungenau werden (macht hier vielleicht 2-3ms aus).&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
void long_delay(uint16_t ms)&lt;br /&gt;
{&lt;br /&gt;
    for(; ms&amp;gt;0; ms--) _delay_ms(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main( void )&lt;br /&gt;
{&lt;br /&gt;
    DDRB = ( 1 &amp;lt;&amp;lt; PB0 );        // PB0 an PORTB als Ausgang setzen&lt;br /&gt;
&lt;br /&gt;
    while( 1 )                  // Endlosschleife&lt;br /&gt;
    {                &lt;br /&gt;
        PORTB ^= ( 1 &amp;lt;&amp;lt; PB0 );  // Toggle PB0 z.&amp;amp;nbsp;B. angeschlossene LED&lt;br /&gt;
        long_delay(1000);       // Eine Sekunde warten...&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== avr-libc Versionen ab 1.6 ==&lt;br /&gt;
&lt;br /&gt;
_delay_ms() kann mit einem Argument bis 6553,5 ms (= 6,5535 Sekunden) benutzt werden. Es ist nicht möglich, eine Variable als Argument zu übergeben. Wird die früher gültige Grenze von 262,14 ms/F_CPU (in MHz) überschritten, so arbeitet _delay_ms() einfach etwas ungenauer und zählt nur noch mit einer Auflösung von 1/10 ms. Eine Verzögerung von 1000,10 ms ließe sich nicht mehr von einer von 1000,19 ms unterscheiden. Ein Verlust, der sich im Allgemeinen verschmerzen lässt. Dem Programmierer wird keine Rückmeldung gegeben, dass die Funktion ggf. gröber arbeitet, d.h. wenn es darauf ankommt, bitte den Parameter wie bisher geschickt wählen.&lt;br /&gt;
&lt;br /&gt;
Die Funktion _delay_us() wurde ebenfalls erweitert. Wenn deren maximal als genau behandelbares Argument überschritten wird, benutzt diese intern _delay_ms(). Damit gelten in diesem Fall die _delay_ms() Einschränkungen.&lt;br /&gt;
&lt;br /&gt;
Beispiel: Blinken einer LED an PORTB Pin PB0 im ca. 1s Rhythmus, avr-libc ab Version 1.6&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
/* Definiere F_CPU, wenn F_CPU nicht bereits vorher definiert &lt;br /&gt;
   (z.B. durch Übergabe als Parameter zum Compiler innerhalb &lt;br /&gt;
   des Makefiles). Zusätzlich Ausgabe einer Warnung, die auf die&lt;br /&gt;
   &amp;quot;nachträgliche&amp;quot; Definition hinweist */&lt;br /&gt;
#warning &amp;quot;F_CPU war noch nicht definiert, wird nun mit 3686400 definiert&amp;quot;&lt;br /&gt;
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */&lt;br /&gt;
#endif&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main( void )&lt;br /&gt;
{&lt;br /&gt;
    DDRB = ( 1 &amp;lt;&amp;lt; PB0 );        // PB0 an PORTB als Ausgang setzen&lt;br /&gt;
&lt;br /&gt;
    while( 1 ) {                // Endlosschleife&lt;br /&gt;
        PORTB ^= ( 1 &amp;lt;&amp;lt; PB0 );  // Toggle PB0 z.B. angeschlossene LED&lt;br /&gt;
        _delay_ms(1000);        // Eine Sekunde +/-1/10000 Sekunde warten...&lt;br /&gt;
                                // funktioniert nicht mit Bibliotheken vor 1.6&lt;br /&gt;
&lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Trick zur Übergabe einer Variablen an _delay_ms():&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
#warning &amp;quot;F_CPU war noch nicht definiert, wird nun mit 3686400 definiert&amp;quot;&lt;br /&gt;
#define F_CPU 3686400UL     /* Quarz mit 3.6864 Mhz */&lt;br /&gt;
#endif&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void sleep ( uint8_t ms )&lt;br /&gt;
{&lt;br /&gt;
    for(; ms &amp;gt; 0; ms--) _delay_ms(1);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main( void )&lt;br /&gt;
{&lt;br /&gt;
    int x = 0;                  // Variable als Wartezeit erstellen&lt;br /&gt;
    DDRB = ( 1 &amp;lt;&amp;lt; PB0 );        // PB0 an PORTB als Ausgang setzen&lt;br /&gt;
&lt;br /&gt;
    while( 1 ) {                // Endlosschleife&lt;br /&gt;
        PORTB ^= ( 1 &amp;lt;&amp;lt; PB0 );  // Toggle PB0 z.B. angeschlossene LED&lt;br /&gt;
        sleep(x); &lt;br /&gt;
        x++;       &lt;br /&gt;
    }&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Die _delay_ms() und die _delay_us aus &#039;&#039;&#039;avr-libc 1.7.0&#039;&#039;&#039; sind fehlerhaft. _delay_ms () läuft 4x schneller als erwartet. Abhilfe ist eine korrigierte Includedatei: [http://www.mikrocontroller.net/topic/196738#1943039]&lt;br /&gt;
&lt;br /&gt;
= Programmieren mit Interrupts =&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:right; margin:2em;&amp;quot;&amp;gt;&lt;br /&gt;
[[Image:Interrupt Programme.gif]]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
Nachdem wir nun alles Wissenswerte für die serielle Programmerstellung&lt;br /&gt;
gelernt haben nehmen wir jetzt ein völlig anderes Thema in Angriff, nämlich&lt;br /&gt;
die Programmierung unter Zuhilfenahme der Interrupts des AVR.&lt;br /&gt;
&lt;br /&gt;
Als erstes wollen wir uns noch einmal den allgemeinen Programmablauf bei der&lt;br /&gt;
Interrupt-Programmierung zu Gemüte führen.&lt;br /&gt;
&lt;br /&gt;
Man sieht, dass die Interruptroutine quasi parallel zum Hauptprogramm&lt;br /&gt;
abläuft. Da wir nur eine CPU haben ist es natürlich keine echte Parallelität,&lt;br /&gt;
sondern das Hauptprogramm wird beim Eintreffen eines Interrupts unterbrochen,&lt;br /&gt;
die Interruptroutine wird ausgeführt und danach erst wieder zum Hauptprogramm&lt;br /&gt;
zurückgekehrt.&lt;br /&gt;
&lt;br /&gt;
Siehe auch&lt;br /&gt;
&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-1-235092.html#new Ausführlicher Thread im Forum]&lt;br /&gt;
* Artikel [[Interrupt]]&lt;br /&gt;
* Artikel [[Multitasking]]&lt;br /&gt;
{{Clear}}&lt;br /&gt;
&lt;br /&gt;
== Anforderungen an Interrupt-Routinen ==&lt;br /&gt;
&lt;br /&gt;
Um unliebsamen Überraschungen vorzubeugen, sollten einige Grundregeln bei der Implementierung der Interruptroutinen beachtet werden. Interruptroutinen sollten möglichst kurz und schnell abarbeitbar sein, daraus folgt:&lt;br /&gt;
&lt;br /&gt;
* Keine umfangreichen Berechnungen innerhalb der Interruptroutine. (*)&lt;br /&gt;
* Keine langen Programmschleifen.&lt;br /&gt;
* Obwohl es möglich ist, während der Abarbeitung einer Interruptroutine andere oder sogar den gleichen Interrupt wieder zuzulassen, wird davon ohne genaue Kenntnis der internen Abläufe dringend abgeraten.&lt;br /&gt;
&lt;br /&gt;
Interruptroutinen (ISRs) sollten also möglichst kurz sein und keine Schleifen mit vielen Durchläufen enthalten. Längere Operationen können meist in einen &amp;quot;Interrupt-Teil&amp;quot; in einer ISR und einen &amp;quot;Arbeitsteil&amp;quot; im Hauptprogramm aufgetrennt werden. Z.B. Speichern des Zustands aller Eingänge im EEPROM in bestimmten Zeitabständen: ISR-Teil: Zeitvergleich (Timer,RTC) mit Logzeit/-intervall. Bei Übereinstimmung ein globales Flag setzen (volatile bei Flag-Deklaration nicht vergessen, s.u.). Dann im Hauptprogramm prüfen, ob das Flag gesetzt ist. Wenn ja: die Daten im EEPROM ablegen und Flag löschen.&lt;br /&gt;
&lt;br /&gt;
(*)&lt;br /&gt;
Hinweis: &lt;br /&gt;
Es gibt allerdings die seltene Situation, dass man gerade eingelesene&lt;br /&gt;
ADC-Werte sofort verarbeiten muss. Besonders dann, wenn man mehrere Werte sehr&lt;br /&gt;
schnell hintereinander bekommt. Dann bleibt einem nichts anderes übrig, als die&lt;br /&gt;
Werte noch in der ISR zu verarbeiten. Kommt aber sehr selten vor und sollte&lt;br /&gt;
durch geeignete Wahl des Systemtaktes bzw. Auswahl des Controllers vermieden werden!&lt;br /&gt;
&lt;br /&gt;
== Interrupt-Quellen ==&lt;br /&gt;
&lt;br /&gt;
Die folgenden Ereignisse können einen Interrupt auf einem AVR AT90S2313 auslösen, wobei die Reihenfolge der Auflistung auch die Priorität der Interrupts aufzeigt.&lt;br /&gt;
&lt;br /&gt;
* Reset&lt;br /&gt;
* Externer Interrupt 0&lt;br /&gt;
* Externer Interrupt 1&lt;br /&gt;
* Timer/Counter 1 Capture Ereignis&lt;br /&gt;
* Timer/Counter 1 Compare Match&lt;br /&gt;
* Timer/Counter 1 Überlauf&lt;br /&gt;
* Timer/Counter 0 Überlauf&lt;br /&gt;
* UART Zeichen empfangen&lt;br /&gt;
* UART Datenregister leer&lt;br /&gt;
* UART Zeichen gesendet&lt;br /&gt;
* Analoger Komparator&lt;br /&gt;
&lt;br /&gt;
Die Anzahl der möglichen Interruptquellen variiert zwischen den verschiedenen Microcontroller-Typen. Im Zweifel hilft ein Blick ins Datenblatt (&amp;quot;Interrupt Vectors&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
== Register ==&lt;br /&gt;
&lt;br /&gt;
Der AT90S2313 verfügt über 2 Register die mit den&lt;br /&gt;
Interrupts zusammen hängen.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;GIMSK&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;G&#039;&#039;&#039;eneral &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;M&#039;&#039;&#039;ask &#039;&#039;&#039;R&#039;&#039;&#039;egister.&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit &lt;br /&gt;
| 7 || 6|| 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;INT1&#039;&#039;&#039; || &#039;&#039;&#039;INT0&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W || R/W || R || R || R || R || R || R&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;INT1&#039;&#039;&#039; (External &#039;&#039;&#039;Int&#039;&#039;&#039;errupt Request &#039;&#039;&#039;1&#039;&#039;&#039; Enable)&lt;br /&gt;
:Wenn dieses Bit gesetzt ist, wird ein Interrupt ausgelöst, wenn am &#039;&#039;&#039;INT1&#039;&#039;&#039;-Pin eine steigende oder fallende (je nach Konfiguration im &#039;&#039;&#039;MCUCR&#039;&#039;&#039;) Flanke erkannt wird.&lt;br /&gt;
:Das Global Enable Interrupt Flag muss selbstverständlich auch gesetzt sein.&lt;br /&gt;
:Der Interrupt wird auch ausgelöst, wenn der Pin als Ausgang geschaltet ist. Auf diese Weise bietet sich die Möglichkeit, Software-Interrupts zu realisieren.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;INT0&#039;&#039;&#039; (External &#039;&#039;&#039;Int&#039;&#039;&#039;errupt Request &#039;&#039;&#039;0&#039;&#039;&#039; Enable)&lt;br /&gt;
:Wenn dieses Bit gesetzt ist, wird ein Interrupt ausgelöst, wenn am &#039;&#039;&#039;INT0&#039;&#039;&#039;-Pin eine steigende oder fallende (je nach Konfiguration im &#039;&#039;&#039;MCUCR&#039;&#039;&#039;) Flanke erkannt wird.&lt;br /&gt;
:Das Global Enable Interrupt Flag muss selbstverständlich auch gesetzt sein.&lt;br /&gt;
:Der Interrupt wird auch ausgelöst, wenn der Pin als Ausgang geschaltet ist. Auf diese Weise bietet sich die Möglichkeit, Software-Interrupts zu realisieren.&lt;br /&gt;
&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;GIFR&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;G&#039;&#039;&#039;eneral &#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;F&#039;&#039;&#039;lag &#039;&#039;&#039;R&#039;&#039;&#039;egister.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;INTF1&#039;&#039;&#039; || &#039;&#039;&#039;INTF0&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039; || &#039;&#039;&#039;-&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R/W || R/W || R || R || R || R || R || R&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;INTF1&#039;&#039;&#039; (External &#039;&#039;&#039;Int&#039;&#039;&#039;errupt Flag &#039;&#039;&#039;1&#039;&#039;&#039;)&lt;br /&gt;
:Dieses Bit wird gesetzt, wenn am &#039;&#039;&#039;INT1&#039;&#039;&#039;-Pin eine Interrupt-Bedingung, entsprechend der Konfiguration, als eingetreten erkannt wird. Wenn das Global Enable Interrupt Flag gesetzt ist, wird die Interruptroutine angesprungen.&lt;br /&gt;
:Das Flag wird automatisch gelöscht, wenn die Interruptroutine beendet ist. Alternativ kann das Flag gelöscht werden, indem der Wert &#039;&#039;&#039;1(!)&#039;&#039;&#039; eingeschrieben wird.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;INTF0&#039;&#039;&#039; (External &#039;&#039;&#039;Int&#039;&#039;&#039;errupt Flag &#039;&#039;&#039;0&#039;&#039;&#039;)&lt;br /&gt;
:Dieses Bit wird gesetzt, wenn am &#039;&#039;&#039;INT0&#039;&#039;&#039;-Pin eine Interrupt-Bedingung, entsprechend der Konfiguration, als eingetreten erkannt wird. Wenn das Global Enable Interrupt Flag gesetzt ist, wird die Interruptroutine angesprungen.&lt;br /&gt;
:Das Flag wird automatisch gelöscht, wenn die Interruptroutine beendet ist. Alternativ kann das Flag gelöscht werden, indem der Wert &#039;&#039;&#039;1(!)&#039;&#039;&#039; eingeschrieben wird.&lt;br /&gt;
|- &lt;br /&gt;
| &#039;&#039;&#039;MCUCR&#039;&#039;&#039;&lt;br /&gt;
| &#039;&#039;&#039;MCU&#039;&#039;&#039; &#039;&#039;&#039;C&#039;&#039;&#039;ontrol &#039;&#039;&#039;R&#039;&#039;&#039;egister.&lt;br /&gt;
&lt;br /&gt;
Das MCU Control Register enthält Kontrollbits für allgemeine MCU-Funktionen.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! Bit&lt;br /&gt;
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|- &lt;br /&gt;
! Name&lt;br /&gt;
| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;-&#039;&#039;&#039;|| &#039;&#039;&#039;SE&#039;&#039;&#039;|| &#039;&#039;&#039;SM&#039;&#039;&#039;|| &#039;&#039;&#039;ISC11&#039;&#039;&#039;|| &#039;&#039;&#039;ISC10&#039;&#039;&#039;|| &#039;&#039;&#039;ISC01&#039;&#039;&#039;|| &#039;&#039;&#039;ISC00&#039;&#039;&#039;&lt;br /&gt;
|- &lt;br /&gt;
! R/W&lt;br /&gt;
| R || R || R/W || R/W || R/W || R/W || R/W || R/W&lt;br /&gt;
|- &lt;br /&gt;
! Initialwert&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SE&#039;&#039;&#039; (&#039;&#039;&#039;S&#039;&#039;&#039;leep &#039;&#039;&#039;E&#039;&#039;&#039;nable)&lt;br /&gt;
:Dieses Bit muss gesetzt sein, um den Controller mit dem &#039;&#039;&#039;SLEEP&#039;&#039;&#039;-Befehl in den Schlafzustand versetzen zu können.&lt;br /&gt;
:Um den Schlafmodus nicht irrtümlich einzuschalten, wird empfohlen, das Bit erst unmittelbar vor Ausführung des &#039;&#039;&#039;SLEEP&#039;&#039;&#039;-Befehls zu setzen.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;SM&#039;&#039;&#039; (&#039;&#039;&#039;S&#039;&#039;&#039;leep &#039;&#039;&#039;M&#039;&#039;&#039;ode)&lt;br /&gt;
:Dieses Bit bestimmt über den Schlafmodus.&lt;br /&gt;
:Ist das Bit gelöscht, so wird der &#039;&#039;&#039;Idle&#039;&#039;&#039;-Modus ausgeführt. Ist das Bit gesetzt, so wird der &#039;&#039;&#039;Power-Down&#039;&#039;&#039;-Modus ausgeführt. (für andere AVR Controller siehe Abschnitt &amp;quot;Sleep-Mode&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ISC11&#039;&#039;&#039;, &#039;&#039;&#039;ISC10&#039;&#039;&#039; (&#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;S&#039;&#039;&#039;ense &#039;&#039;&#039;C&#039;&#039;&#039;ontrol &#039;&#039;&#039;1&#039;&#039;&#039; Bits)&lt;br /&gt;
:Diese beiden Bits bestimmen, ob die steigende oder die fallende Flanke für die Interrupterkennung am &#039;&#039;&#039;INT1&#039;&#039;&#039;-Pin ausgewertet wird.&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! ISC11 || ISC10 || Bedeutung&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Low Level an &#039;&#039;&#039;INT1&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
&lt;br /&gt;
Der Interrupt wird getriggert, solange der Pin auf 0 bleibt.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Reserviert&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Die fallende Flanke an &#039;&#039;&#039;INT1&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Die steigende Flanke an &#039;&#039;&#039;INT1&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ISC01&#039;&#039;&#039;, &#039;&#039;&#039;ISC00&#039;&#039;&#039; (&#039;&#039;&#039;I&#039;&#039;&#039;nterrupt &#039;&#039;&#039;S&#039;&#039;&#039;ense &#039;&#039;&#039;C&#039;&#039;&#039;ontrol &#039;&#039;&#039;0&#039;&#039;&#039; Bits)&lt;br /&gt;
:Diese beiden Bits bestimmen, ob die steigende oder die fallende Flanke für die Interrupterkennung am &#039;&#039;&#039;INT0&#039;&#039;&#039;-Pin ausgewertet wird.&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|- &lt;br /&gt;
! ISC01 || ISC00 || Bedeutung&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Low Level an &#039;&#039;&#039;INT0&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
&lt;br /&gt;
Der Interrupt wird getriggert, solange der Pin auf 0 bleibt.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Reserviert&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0&lt;br /&gt;
| Die fallende Flanke an &#039;&#039;&#039;INT0&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
|- &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1&lt;br /&gt;
| Die steigende Flanke an &#039;&#039;&#039;INT0&#039;&#039;&#039; erzeugt einen Interrupt.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Allgemeines über die Interrupt-Abarbeitung ==&lt;br /&gt;
&lt;br /&gt;
Wenn ein Interrupt eintrifft, wird automatisch das &#039;&#039;&#039;Global Interrupt Enable&#039;&#039;&#039; Bit im Status Register &#039;&#039;&#039;SREG&#039;&#039;&#039; gelöscht und alle weiteren Interrupts unterbunden. Obwohl es möglich ist, zu diesem Zeitpunkt bereits wieder das GIE-bit zu setzen, wird dringend davon abgeraten. Dieses wird nämlich automatisch gesetzt, wenn die Interruptroutine beendet wird. Wenn in der Zwischenzeit weitere Interrupts eintreffen, werden die zugehörigen Interrupt-Bits gesetzt und die Interrupts bei Beendigung der laufenden Interrupt-Routine in der Reihenfolge ihrer Priorität ausgeführt. Dies kann&lt;br /&gt;
eigentlich nur dann zu Problemen führen, wenn ein hoch priorisierter Interrupt ständig und in kurzer Folge auftritt. Dieser sperrt dann möglicherweise alle anderen Interrupts mit niedrigerer Priorität. Dies ist einer der Gründe, weshalb die Interrupt-Routinen sehr kurz gehalten werden sollen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- === Das Status-Register ===&lt;br /&gt;
&lt;br /&gt;
Es gilt auch zu beachten, dass das Status-Register während der Abarbeitung einer Interruptroutine nicht automatisch gesichert wird. Falls notwendig, muss dies vom Programmierer selber vorgesehen werden. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Interrupts mit dem AVR GCC Compiler (WinAVR) ==&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- Selbstverständlich können alle interruptspezifischen Registerzugriffe wie gewohnt über I/O-Adressierung vorgenommen werden. Etwas einfacher geht es jedoch, wenn wir die vom Compiler zur Verfügung gestellten Mittel einsetzen.--&amp;gt;&lt;br /&gt;
Funktionen zur Interrupt-Verarbeitung werden in den Includedateien &#039;&#039;interrupt.h&#039;&#039;  der avr-libc zur Verfügung gestellt (bei älterem Quellcode zusätzlich &#039;&#039;signal.h&#039;&#039;).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// fuer sei(), cli() und ISR():&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Makro &#039;&#039;&#039;sei()&#039;&#039;&#039; schaltet die Interrupts ein. Eigentlich wird nichts anderes gemacht, als das &#039;&#039;&#039;Global Interrupt Enable&#039;&#039;&#039; Bit im Status Register gesetzt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    sei();&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Makro &#039;&#039;&#039;cli()&#039;&#039;&#039; schaltet die Interrupts aus, oder anders gesagt, das &#039;&#039;&#039;Global Interrupt Enable&#039;&#039;&#039; Bit im Status Register wird gelöscht.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    cli();&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Oft steht man vor der Aufgabe, dass eine Codesequenz nicht unterbrochen werden darf. Es liegt dann nahe, zu Beginn dieser Sequenz ein cli() und am Ende ein sei() einzufügen. Dies ist jedoch ungünstig, wenn die Interrupts vor Aufruf der Sequenz deaktiviert waren und danach auch weiterhin deaktiviert bleiben sollen. Ein sei() würde ungeachtet des vorherigen  Zustands die Interrupts aktivieren, was zu unerwünschten Seiteneffekten führen kann. Die aus dem folgenden Beispiel ersichtliche Vorgehensweise ist in solchen Fällen vorzuziehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
#include &amp;lt;inttypes.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
void NichtUnterbrechenBitte(void)&lt;br /&gt;
{&lt;br /&gt;
   uint8_t tmp_sreg;  // temporaerer Speicher fuer das Statusregister&lt;br /&gt;
&lt;br /&gt;
   tmp_sreg = SREG;   // Statusregister (also auch das I-Flag darin) sichern&lt;br /&gt;
   cli();             // Interrupts global deaktivieren&lt;br /&gt;
&lt;br /&gt;
   /* hier &amp;quot;unterbrechnungsfreier&amp;quot; Code */&lt;br /&gt;
&lt;br /&gt;
   /* Beispiel Anfang&lt;br /&gt;
     JTAG-Interface eines ATmega16 per Software deaktivieren &lt;br /&gt;
     und damit die JTAG-Pins an PORTC für &amp;quot;general I/O&amp;quot; nutzbar machen&lt;br /&gt;
     ohne die JTAG-Fuse-Bit zu aendern. Dazu ist eine &amp;quot;timed sequence&amp;quot;&lt;br /&gt;
     einzuhalten (vgl Datenblatt ATmega16, Stand 10/04, S. 229): &lt;br /&gt;
     Das JTD-Bit muss zweimal innerhalb von 4 Taktzyklen geschrieben &lt;br /&gt;
     werden. Ein Interrupt zwischen den beiden Schreibzugriffen wuerde &lt;br /&gt;
     die erforderliche Sequenz &amp;quot;brechen&amp;quot;, das JTAG-Interface bliebe&lt;br /&gt;
     weiterhin aktiv und die IO-Pins weiterhin für JTAG reserviert. */&lt;br /&gt;
&lt;br /&gt;
   MCUCSR |= (1&amp;lt;&amp;lt;JTD);&lt;br /&gt;
   MCUCSR |= (1&amp;lt;&amp;lt;JTD); // 2 mal in Folge ,vgl. Datenblatt fuer mehr Information&lt;br /&gt;
&lt;br /&gt;
   /* Beispiel Ende */&lt;br /&gt;
  &lt;br /&gt;
   SREG = tmp_sreg;     // Status-Register wieder herstellen &lt;br /&gt;
                      // somit auch das I-Flag auf gesicherten Zustand setzen&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void NichtSoGut(void)&lt;br /&gt;
{&lt;br /&gt;
   cli();&lt;br /&gt;
   &lt;br /&gt;
   /* hier &amp;quot;unterbrechnungsfreier&amp;quot; Code */&lt;br /&gt;
   &lt;br /&gt;
   sei();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
   //...&lt;br /&gt;
&lt;br /&gt;
   cli();  &lt;br /&gt;
   // Interrupts global deaktiviert &lt;br /&gt;
&lt;br /&gt;
   NichtUnterbrechenBitte();&lt;br /&gt;
   // auch nach Aufruf der Funktion deaktiviert&lt;br /&gt;
&lt;br /&gt;
   sei();&lt;br /&gt;
   // Interrupts global aktiviert &lt;br /&gt;
&lt;br /&gt;
   NichtUnterbrechenBitte();&lt;br /&gt;
   // weiterhin aktiviert&lt;br /&gt;
   //...&lt;br /&gt;
&lt;br /&gt;
   /* Verdeutlichung der unguenstigen Vorgehensweise mit cli/sei: */&lt;br /&gt;
   cli();  &lt;br /&gt;
   // Interrupts jetzt global deaktiviert &lt;br /&gt;
&lt;br /&gt;
   NichtSoGut();&lt;br /&gt;
   // nach Aufruf der Funktion sind Interrupts global aktiviert &lt;br /&gt;
   // dies ist mglw. ungewollt!&lt;br /&gt;
   //...&lt;br /&gt;
   &lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!-- mt: besser so nicht(?), lieber &amp;quot;datenblattkonform&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font face=&amp;quot;Courier New&amp;quot;&amp;gt;&#039;&#039;&#039;timer_enable_int (unsigned char ints);&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;/font&amp;gt;Schaltet Timerbezogene Interrupts ein bzw. aus.&amp;lt;br /&amp;gt;&lt;br /&gt;
Wenn als Argument &#039;&#039;&#039;ints&#039;&#039;&#039; der Wert 0 übergeben wird so werden alle&lt;br /&gt;
Timerinterrupts ausgeschaltet, ansonsten muss in &#039;&#039;&#039;ints&#039;&#039;&#039; angegeben werden,&lt;br /&gt;
welche Interrupts zu aktivieren sind. Dabei müssen einfach die entsprechend zu&lt;br /&gt;
setzenden Bits definiert werden.&amp;lt;br /&amp;gt;&lt;br /&gt;
Beispiel: &#039;&#039;&#039;&amp;lt;font face=&amp;quot;Courier New&amp;quot;&amp;gt;timer_enable_int (1 &amp;lt;&amp;lt; TOIE1));&amp;lt;br /&amp;gt;&lt;br /&gt;
&amp;lt;/font&amp;gt;&#039;&#039;&#039;Achtung: Wenn ein Timerinterrupt eingeschaltet wird während ein&lt;br /&gt;
anderer Timerinterrupt bereits läuft, dann müssen beide Bits angegeben werden&lt;br /&gt;
sonst wird der andere Timerinterrupt versehentlich ausgeschaltet.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;font face=&amp;quot;Courier New&amp;quot;&amp;gt;&#039;&#039;&#039;enable_external_int (unsigned char ints);&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;&amp;lt;/font&amp;gt;Schaltet die externen Interrupts ein bzw. aus.&amp;lt;br /&amp;gt;&lt;br /&gt;
Wenn als Argument &#039;&#039;&#039;ints&#039;&#039;&#039; der Wert 0 übergeben wird so werden alle externen&lt;br /&gt;
Interrrups ausgeschaltet, ansonsten muss in &#039;&#039;&#039;ints&#039;&#039;&#039; angegeben werden, welche&lt;br /&gt;
Interrupts zu aktivieren sind. Dabei müssen einfach die entsprechend zu&lt;br /&gt;
setzenden Bits definiert werden.&amp;lt;br /&amp;gt;&lt;br /&gt;
Beispiel: &#039;&#039;&#039;&amp;lt;font face=&amp;quot;Courier New&amp;quot;&amp;gt;enable_external_int ((1&amp;lt;&lt;br /&gt;
&amp;lt;/font&amp;gt;&#039;&#039;&#039;Schaltet die externen Interrupts 0 und 1 ein.&lt;br /&gt;
&lt;br /&gt;
Nachdem nun die Interrupts aktiviert sind, braucht es selbstverständlich noch den auszuführenden Code, der ablaufen soll, wenn ein Interrupt eintrifft.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
Zu den aktivierten Interrupts ist eine Funktion zu programmieren, deren Code aufgerufen wird, wenn der betreffende Interrupt auftritt (Interrupt-Handler, Interrupt-Service-Routine). Dazu existiert die Definition (ein Makro) &#039;&#039;&#039;ISR&#039;&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
=== ISR ===&lt;br /&gt;
&lt;br /&gt;
(&#039;&#039;ISR()&#039;&#039; ersetzt bei neueren Versionen der avr-libc &#039;&#039;SIGNAL()&#039;&#039;. SIGNAL sollte nicht mehr genutzt werden, zur Portierung von SIGNAL nach ISR siehe den [[AVR-GCC-Tutorial#Anhang|Anhang]].)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
ISR(Vectorname) /* vormals: SIGNAL(siglabel) dabei Vectorname != siglabel ! */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Mit &#039;&#039;ISR&#039;&#039; wird eine Funktion für die Bearbeitung eines Interrupts eingeleitet. Als Argument muss dabei die Benennung des entsprechenden Interruptvektors angegeben werden. Diese sind in den jeweiligen Includedateien IOxxxx.h zu finden. Die Bezeichnung entspricht dem Namen aus dem Datenblatt, bei dem die Leerzeichen durch Unterstriche ersetzt sind und ein &#039;&#039;_vect&#039;&#039; angehängt ist.&lt;br /&gt;
&lt;br /&gt;
Als Beispiel ein Ausschnitt aus der Datei für den ATmega8 (bei WinAVR Standardinstallation in C:\WinAVR\avr\include\avr\iom8.h) in der neben den aktuellen Namen für &#039;&#039;ISR&#039;&#039; (*_vect) noch die Bezeichnungen für das inzwischen nicht mehr aktuelle &#039;&#039;SIGNAL&#039;&#039; (SIG_*) enthalten sind.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
/* $Id: iom8.h,v 1.13 2005/10/30 22:11:23 joerg_wunsch Exp $ */&lt;br /&gt;
&lt;br /&gt;
/* avr/iom8.h - definitions for ATmega8 */&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
/* Interrupt vectors */&lt;br /&gt;
&lt;br /&gt;
/* External Interrupt Request 0 */&lt;br /&gt;
#define INT0_vect                       _VECTOR(1)&lt;br /&gt;
#define SIG_INTERRUPT0                  _VECTOR(1)&lt;br /&gt;
&lt;br /&gt;
/* External Interrupt Request 1 */&lt;br /&gt;
#define INT1_vect                       _VECTOR(2)&lt;br /&gt;
#define SIG_INTERRUPT1                  _VECTOR(2)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter2 Compare Match */&lt;br /&gt;
#define TIMER2_COMP_vect                _VECTOR(3)&lt;br /&gt;
#define SIG_OUTPUT_COMPARE2             _VECTOR(3)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter2 Overflow */&lt;br /&gt;
#define TIMER2_OVF_vect                 _VECTOR(4)&lt;br /&gt;
#define SIG_OVERFLOW2                   _VECTOR(4)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter1 Capture Event */&lt;br /&gt;
#define TIMER1_CAPT_vect                _VECTOR(5)&lt;br /&gt;
#define SIG_INPUT_CAPTURE1              _VECTOR(5)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter1 Compare Match A */&lt;br /&gt;
#define TIMER1_COMPA_vect               _VECTOR(6)&lt;br /&gt;
#define SIG_OUTPUT_COMPARE1A            _VECTOR(6)&lt;br /&gt;
&lt;br /&gt;
/* Timer/Counter1 Compare Match B */&lt;br /&gt;
#define TIMER1_COMPB_vect               _VECTOR(7)&lt;br /&gt;
#define SIG_OUTPUT_COMPARE1B            _VECTOR(7)&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--Vor Nutzung von SIGNAL muss ebenfalls die Header-Datei signal.h eingebunden werden.--&amp;gt; &lt;br /&gt;
Mögliche Funktionsrümpfe für Interruptfunktionen sind zum Beispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
/* veraltet: #include &amp;lt;avr/signal.h&amp;gt; */&lt;br /&gt;
&lt;br /&gt;
ISR(INT0_vect)       /* veraltet: SIGNAL(SIG_INTERRUPT0) */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER0_OVF_vect) /* veraltet: SIGNAL(SIG_OVERFLOW0) */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
ISR(USART_RXC_vect) /* veraltet: SIGNAL(SIG_UART_RECV) */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt Code */&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// und so weiter und so fort...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Auf die korrekte Schreibweise der Vektorbezeichnung ist zu achten. Der gcc-Compiler prüft erst ab Version 4.x, ob ein Signal/Interrupt der angegebenen Bezeichnung tatsächlich in der Includedatei definiert ist und gibt andernfalls eine Warnung aus. Bei WinAVR (ab 2/2005) wurde die Überprüfung auch in den mitgelieferten Compiler der Version 3.x integriert. Aus dem gcc-Quellcode Version 3.x selbst erstellte Compiler enthalten die Prüfung nicht (vgl. [[AVR-GCC]]). &lt;br /&gt;
&lt;br /&gt;
Während der Ausführung der Funktion sind alle weiteren Interrupts automatisch gesperrt. Beim Verlassen der Funktion werden die Interrupts wieder zugelassen.&lt;br /&gt;
&lt;br /&gt;
Sollte während der Abarbeitung der Interruptroutine ein weiterer Interrupt (gleiche oder andere Interruptquelle) auftreten, so wird das entsprechende Bit im zugeordneten Interrupt Flag Register gesetzt und die entsprechende Interruptroutine automatisch nach dem Beenden der aktuellen Funktion aufgerufen.&lt;br /&gt;
&lt;br /&gt;
Ein Problem ergibt sich eigentlich nur dann, wenn während der Abarbeitung der aktuellen Interruptroutine mehrere gleichartige Interrupts auftreten. Die entsprechende Interruptroutine wird im Nachhinein zwar aufgerufen jedoch wissen wir nicht, ob nun der entsprechende Interrupt einmal, zweimal oder gar noch öfter aufgetreten ist. Deshalb soll hier noch einmal betont werden, dass Interruptroutinen so schnell wie nur irgend möglich wieder verlassen werden sollten.&lt;br /&gt;
&lt;br /&gt;
=== Unterbrechbare Interruptroutinen ===&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Faustregel&amp;quot;: im Zweifel &#039;&#039;&#039;ISR&#039;&#039;&#039;. Die nachfolgend beschriebene Methode nur dann verwenden, wenn man sich über die unterschiedliche Funktionsweise im Klaren ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ISR(XXX,ISR_NOBLOCK) /* veraltet: INTERRUPT(SIG_OVERFLOW0) */&lt;br /&gt;
{&lt;br /&gt;
    /* Interrupt-Code */&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hierbei steht XXX für den oben beschriebenen Namen des Vektors (also z.&amp;amp;nbsp;B. &#039;&#039;TIMER0_OVF_vect&#039;&#039;). Der Unterschied im Vergleich zu einer herkömmlichen ISR ist, dass hier beim Aufrufen der Funktion das &#039;&#039;&#039;Global Enable Interrupt&#039;&#039;&#039; Bit durch Einfügen einer SEI-Anweisung direkt wieder gesetzt und somit alle Interrupts zugelassen werden &amp;amp;ndash; auch XXX-Interrupts. &lt;br /&gt;
&lt;br /&gt;
Bei unsachgemässer Handhabung kann dies zu erheblichen Problemen wie einem Stack-Overflow oder anderen unerwarteten Effekten führen und sollte wirklich nur dann eingesetzt werden, wenn man sich sicher ist, das Ganze auch im Griff zu haben.&lt;br /&gt;
&lt;br /&gt;
Insbesondere sollte möglichst am ISR-Anfang die auslösende IRQ-Quelle deaktiviert und erst am Ende der ISR wieder aktiviert werden. Robuster als die Verwendung einer NOBLOCK-ISR ist daher folgender ISR-Aufbau:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ISR (XXX) &lt;br /&gt;
{&lt;br /&gt;
    // Implementiere die ISR ohne zunaechst weitere IRQs zuzulassen&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;&amp;lt;Dektiviere die XXX-IRQ&amp;gt;&amp;gt;&lt;br /&gt;
&lt;br /&gt;
    // Erlaube alle Interrupts (ausser XXX)&lt;br /&gt;
    sei();&lt;br /&gt;
&lt;br /&gt;
    //... Code ...&lt;br /&gt;
&lt;br /&gt;
    // IRQs global deaktivieren um die XXX-IRQ wieder gefahrlos &lt;br /&gt;
    // aktivieren zu koennen&lt;br /&gt;
    cli();&lt;br /&gt;
&lt;br /&gt;
    &amp;lt;&amp;lt;Aktiviere die XXX-IRQ&amp;gt;&amp;gt;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
Auf diese Weise kann sich die XXX-IRQ nicht selbst unterbrechen, was zu einer Art Endlosschleife führen würde.&lt;br /&gt;
&lt;br /&gt;
Siehe auch: Hinweise in [[AVR-GCC]]&lt;br /&gt;
&lt;br /&gt;
siehe dazu: http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html&lt;br /&gt;
&lt;br /&gt;
== Datenaustausch mit Interrupt-Routinen ==&lt;br /&gt;
&lt;br /&gt;
Variablen, die sowohl in Interrupt-Routinen (ISR = Interrupt Service Routine(s)) als auch vom übrigen Programmcode geschrieben oder gelesen werden, müssen mit einem &#039;&#039;&#039;volatile&#039;&#039;&#039; deklariert werden. Damit wird dem Compiler mitgeteilt, dass der Inhalt der Variablen vor jedem Lesezugriff aus dem Speicher gelesen und nach jedem Schreibzugriff in den Speicher geschrieben wird. Ansonsten könnte der Compiler den Code so optimieren, dass der Wert der Variablen nur in Prozessorregistern zwischengespeichert wird, die nichts von der Änderung woanders mitbekommen.&lt;br /&gt;
&lt;br /&gt;
Zur Veranschaulichung ein Codefragment für eine Tastenentprellung mit Erkennung einer &amp;quot;lange gedrückten&amp;quot; Taste.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
// Schwellwerte&lt;br /&gt;
// Entprellung: &lt;br /&gt;
#define CNTDEBOUNCE 10&lt;br /&gt;
// &amp;quot;lange gedrueckt:&amp;quot;&lt;br /&gt;
#define CNTREPEAT 200&lt;br /&gt;
&lt;br /&gt;
// hier z.&amp;amp;nbsp;B. Taste an Pin2 PortA &amp;quot;active low&amp;quot; = 0 wenn gedrueckt&lt;br /&gt;
#define KEY_PIN  PINA&lt;br /&gt;
#define KEY_PINNO PA2&lt;br /&gt;
&lt;br /&gt;
// beachte: volatile! &lt;br /&gt;
volatile uint8_t gKeyCounter;&lt;br /&gt;
&lt;br /&gt;
// Timer-Compare Interrupt ISR, wird z.B. alle 10ms ausgefuehrt&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
   // hier wird gKeyCounter veraendert. Die übrigen&lt;br /&gt;
   // Programmteile müssen diese Aenderung &amp;quot;sehen&amp;quot;:&lt;br /&gt;
   // volatile -&amp;gt; aktuellen Wert immer in den Speicher schreiben&lt;br /&gt;
   if ( !(KEY_PIN &amp;amp; (1&amp;lt;&amp;lt;KEY_PINNO)) ) {&lt;br /&gt;
      if (gKeyCounter &amp;lt; CNTREPEAT) gKeyCounter++;&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
      gKeyCounter = 0;&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
//...&lt;br /&gt;
    /* hier: Initialisierung der Ports und des Timer-Interrupts */&lt;br /&gt;
//... &lt;br /&gt;
   // hier wird auf gKeyCounter zugegriffen. Dazu muss der in der&lt;br /&gt;
   // ISR geschriebene Wert bekannt sein:&lt;br /&gt;
   // volatile -&amp;gt; aktuellen Wert immer aus dem Speicher lesen&lt;br /&gt;
   if ( gKeyCounter &amp;gt; CNTDEBOUNCE ) { // Taste mind. 10*10 ms &amp;quot;prellfrei&amp;quot;&lt;br /&gt;
       if (gKeyCounter == CNTREPEAT) {&lt;br /&gt;
          /* hier: Code fuer &amp;quot;Taste lange gedrueckt&amp;quot; */&lt;br /&gt;
       }&lt;br /&gt;
       else {&lt;br /&gt;
          /* hier: Code fuer &amp;quot;Taste kurz gedrueckt&amp;quot; */&lt;br /&gt;
       }&lt;br /&gt;
   }&lt;br /&gt;
//...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wird innerhalb einer ISR mehrfach auf eine mit volatile deklarierte Variable zugegriffen, wirkt sich dies ungünstig auf die Verarbeitungsgeschwindigkeit aus, da bei jedem Zugriff mit dem Speicherinhalt abgeglichen wird. Da bei AVR-Controllern &#039;&#039;innerhalb&#039;&#039; einer ISR keine Unterbrechungen zu erwarten sind, bietet es sich an, einen Zwischenspeicher in Form einer lokalen Variable zu verwenden, deren Inhalt zu Beginn und am Ende mit dem der volatile Variable synchronisiert wird. Lokale Variable werden bei eingeschalteter Optimierung mit hoher Wahrscheinlichkeit in Prozessorregistern verwaltet und der Zugriff darauf ist daher nur mit wenigen internen Operationen verbunden. Die ISR aus dem vorherigen Beispiel lässt sich so optimieren:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
   uint8_t tmp_kc;&lt;br /&gt;
&lt;br /&gt;
   tmp_kc = gKeyCounter; // Uebernahme in lokale Arbeitsvariable&lt;br /&gt;
&lt;br /&gt;
   if ( !(KEY_PIN &amp;amp; (1&amp;lt;&amp;lt;KEY_PINNO)) ) {&lt;br /&gt;
      if (tmp_kc &amp;lt; CNTREPEAT) {&lt;br /&gt;
         tmp_kc++;&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
      tmp_kc = 0;&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
   gKeyCounter = tmp_kc; // Zurueckschreiben&lt;br /&gt;
}&lt;br /&gt;
//...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zum Vergleich die Disassemblies (Ausschnitte der &amp;quot;lss-Dateien&amp;quot;, compiliert für ATmega162) im Anschluss. Man erkennt den viermaligen Zugriff auf die Speicheraddresse von &#039;&#039;gKeyCounter&#039;&#039; (hier 0x032A) in der ISR ohne &amp;quot;Cache&amp;quot;-Variable und den zweimaligen Zugriff in der Variante mit Zwischenspeicher. Im Beispiel ist der Vorteil gering, bei komplexeren Routinen kann die Zwischenspeicherung in lokalen Variablen jedoch zu deutlicheren Verbesserungen führen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
     86a:	1f 92       	push	r1&lt;br /&gt;
     86c:	0f 92       	push	r0&lt;br /&gt;
     86e:	0f b6       	in	r0, 0x3f	; 63&lt;br /&gt;
     870:	0f 92       	push	r0&lt;br /&gt;
     872:	11 24       	eor	r1, r1&lt;br /&gt;
     874:	8f 93       	push	r24&lt;br /&gt;
    if ( !(KEY_PIN &amp;amp; (1&amp;lt;&amp;lt;KEY_PINNO)) ) {&lt;br /&gt;
     876:	ca 99       	sbic	0x19, 2	; 25&lt;br /&gt;
     878:	0a c0       	rjmp	.+20     	; 0x88e &amp;lt;__vector_13+0x24&amp;gt;&lt;br /&gt;
      if (gKeyCounter &amp;lt; CNTREPEAT) gKeyCounter++;&lt;br /&gt;
     87a:	80 91 2a 03 	lds	r24, 0x032A&lt;br /&gt;
     87e:	88 3c       	cpi	r24, 0xC8	; 200 &lt;br /&gt;
     880:	40 f4       	brcc	.+16     	; 0x892 &amp;lt;__vector_13+0x28&amp;gt;&lt;br /&gt;
     882:	80 91 2a 03 	lds	r24, 0x032A&lt;br /&gt;
     886:	8f 5f       	subi	r24, 0xFF	; 255&lt;br /&gt;
     888:	80 93 2a 03 	sts	0x032A, r24&lt;br /&gt;
     88c:	02 c0       	rjmp	.+4      	; 0x892 &amp;lt;__vector_13+0x28&amp;gt;&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
      gKeyCounter = 0;&lt;br /&gt;
     88e:	10 92 2a 03 	sts	0x032A, r1&lt;br /&gt;
     892:	8f 91       	pop	r24&lt;br /&gt;
     894:	0f 90       	pop	r0&lt;br /&gt;
     896:	0f be       	out	0x3f, r0	; 63&lt;br /&gt;
     898:	0f 90       	pop	r0&lt;br /&gt;
     89a:	1f 90       	pop	r1&lt;br /&gt;
     89c:	18 95       	reti&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
     86a:	1f 92       	push	r1&lt;br /&gt;
     86c:	0f 92       	push	r0&lt;br /&gt;
     86e:	0f b6       	in	r0, 0x3f	; 63&lt;br /&gt;
     870:	0f 92       	push	r0&lt;br /&gt;
     872:	11 24       	eor	r1, r1&lt;br /&gt;
     874:	8f 93       	push	r24&lt;br /&gt;
   uint8_t tmp_kc;&lt;br /&gt;
 &lt;br /&gt;
   tmp_kc = gKeyCounter;&lt;br /&gt;
     876:	80 91 2a 03 	lds	r24, 0x032A&lt;br /&gt;
 &lt;br /&gt;
   if ( !(KEY_PIN &amp;amp; (1&amp;lt;&amp;lt;KEY_PINNO)) ) {&lt;br /&gt;
     87a:	ca 9b       	sbis	0x19, 2	; 25&lt;br /&gt;
     87c:	02 c0       	rjmp	.+4      	; 0x882 &amp;lt;__vector_13+0x18&amp;gt;&lt;br /&gt;
     87e:	80 e0       	ldi	r24, 0x00	; 0&lt;br /&gt;
     880:	03 c0       	rjmp	.+6      	; 0x888 &amp;lt;__vector_13+0x1e&amp;gt;&lt;br /&gt;
      if (tmp_kc &amp;lt; CNTREPEAT) {&lt;br /&gt;
     882:	88 3c       	cpi	r24, 0xC8	; 200&lt;br /&gt;
     884:	08 f4       	brcc	.+2      	; 0x888 &amp;lt;__vector_13+0x1e&amp;gt;&lt;br /&gt;
         tmp_kc++;&lt;br /&gt;
     886:	8f 5f       	subi	r24, 0xFF	; 255&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
   else {&lt;br /&gt;
      tmp_kc = 0;&lt;br /&gt;
   }&lt;br /&gt;
 &lt;br /&gt;
   gKeyCounter = tmp_kc;&lt;br /&gt;
     888:	80 93 2a 03 	sts	0x032A, r24&lt;br /&gt;
     88c:	8f 91       	pop	r24&lt;br /&gt;
     88e:	0f 90       	pop	r0&lt;br /&gt;
     890:	0f be       	out	0x3f, r0	; 63&lt;br /&gt;
     892:	0f 90       	pop	r0&lt;br /&gt;
     894:	1f 90       	pop	r1&lt;br /&gt;
     896:	18 95       	reti&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== volatile und Pointer ===&lt;br /&gt;
&lt;br /&gt;
Bei &#039;&#039;&#039;volatile&#039;&#039;&#039; in Verbindung mit Pointern ist zu beachten, ob der Pointer selbst oder die Variable, auf die der Pointer zeigt, &#039;&#039;&#039;volatile&#039;&#039;&#039; ist.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
volatile uint8_t *a;   // das Ziel von a ist volatile&lt;br /&gt;
&lt;br /&gt;
uint8_t *volatile a;   // a selbst ist volatile&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Falls der Pointer volatile ist (zweiter Fall im Beispiel), ist zu beachten, dass der Wert des Pointers, also eine Speicheradresse, intern in mehr als einem Byte verwaltet wird. Lese- und Schreibzugriffe im Hauptprogramm (außerhalb von Interrupt-Routinen) sind daher so zu implementieren, dass alle Teilbytes der Adresse konsistent bleiben, vgl. dazu den folgenden Abschnitt.&lt;br /&gt;
&lt;br /&gt;
=== Variablen größer 1 Byte ===&lt;br /&gt;
&lt;br /&gt;
Bei Variablen größer ein Byte, auf die in Interrupt-Routinen und im Hauptprogramm zugegriffen wird, muss darauf geachtet werden, dass die Zugriffe auf die einzelnen Bytes außerhalb der ISR nicht durch einen Interrupt unterbrochen werden. (Allgemeinplatz: AVRs sind 8-bit Controller). Zur Veranschaulichung ein Codefragment:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
volatile uint16_t gMyCounter16bit;&lt;br /&gt;
//...&lt;br /&gt;
ISR(...)&lt;br /&gt;
{&lt;br /&gt;
//...&lt;br /&gt;
   gMyCounter16Bit++;&lt;br /&gt;
//...&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
   uint16_t tmpCnt;&lt;br /&gt;
//...&lt;br /&gt;
   // nicht gut: Mglw. hier ein Fehler, wenn ein Byte von MyCounter &lt;br /&gt;
   // schon in tmpCnt kopiert ist aber vor dem Kopieren des zweiten Bytes &lt;br /&gt;
   // ein Interrupt auftritt, der den Inhalt von MyCounter verändert.&lt;br /&gt;
   tmpCnt = gMyCounter16bit; &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
   // besser: Änderungen &amp;quot;außerhalb&amp;quot; verhindern -&amp;gt; alle &amp;quot;Teilbytes&amp;quot;&lt;br /&gt;
   // bleiben konsistent&lt;br /&gt;
   cli();  // Interrupts deaktivieren&lt;br /&gt;
   tmpCnt = gMyCounter16Bit;&lt;br /&gt;
   sei();  // wieder aktivieren&lt;br /&gt;
&lt;br /&gt;
   // oder: vorheriger Status des globalen Interrupt-Flags bleibt erhalten&lt;br /&gt;
   uint8_t sreg_tmp;&lt;br /&gt;
   sreg_tmp = SREG;    /* Sichern */&lt;br /&gt;
   cli()&lt;br /&gt;
   tmpCnt = gMyCounter16Bit;&lt;br /&gt;
   SREG = sreg_tmp;    /* Wiederherstellen */&lt;br /&gt;
&lt;br /&gt;
   // oder: mehrfach lesen, bis man konsistente Daten hat&lt;br /&gt;
   uint16_t count1 = gMyCounter16Bit;&lt;br /&gt;
   uint16_t count2 = gMyCounter16Bit;&lt;br /&gt;
   while (count1 != count2) {&lt;br /&gt;
       count1 = count2;&lt;br /&gt;
       count2 = gMyCounter16Bit;&lt;br /&gt;
   }&lt;br /&gt;
   tmpCnt = count1;&lt;br /&gt;
//...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Die avr-libc bietet ab Version 1.6.0(?) einige Hilfsfunktionen/Makros, mit der im Beispiel oben gezeigten Funktionalität, die zusätzlich auch sogenannte [http://en.wikipedia.org/wiki/Memory_barrier memory barriers] beinhalten. Diese stehen nach #include &amp;lt;util/atomic.h&amp;gt; zur Verfügung.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
#include &amp;lt;util/atomic.h&amp;gt;&lt;br /&gt;
//...&lt;br /&gt;
&lt;br /&gt;
    // analog zu cli, Zugriff, sei:&lt;br /&gt;
    ATOMIC_BLOCK(ATOMIC_FORCEON) {&lt;br /&gt;
        tmpCnt = gMyCounter16Bit;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
// oder:&lt;br /&gt;
&lt;br /&gt;
    // analog zu Sicherung des SREG, cli, Zugriff und Zurückschreiben des SREG:&lt;br /&gt;
    ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {&lt;br /&gt;
        tmpCnt = gMyCounter16Bit;&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
//...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* siehe auch [http://www.nongnu.org/avr-libc/user-manual/group__util__atomic.html Dokumentation der avr-libc zu atomic.h]&lt;br /&gt;
&lt;br /&gt;
== Interrupt-Routinen und Registerzugriffe ==&lt;br /&gt;
&lt;br /&gt;
Falls Register sowohl im Hauptprogramm als auch in Interrupt-Routinen verändert werden, ist darauf zu achten, dass diese Zugriffe sich nicht überlappen. Nur wenige Anweisungen lassen sich in sogenannte &amp;quot;atomare&amp;quot; Zugriffe übersetzen, die nicht von Interrupt-Routinen unterbrochen werden können. &lt;br /&gt;
&lt;br /&gt;
Zur Veranschaulichung eine Anweisung, bei der ein Bit und im Anschluss drei Bits in einem Register gesetzt werden:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
//...&lt;br /&gt;
	PORTA |= (1&amp;lt;&amp;lt;PA0);&lt;br /&gt;
	&lt;br /&gt;
	PORTA |= (1&amp;lt;&amp;lt;PA2)|(1&amp;lt;&amp;lt;PA3)|(1&amp;lt;&amp;lt;PA4);&lt;br /&gt;
//...&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der Compiler übersetzt diese Anweisungen für einen ATmega128 bei Optimierungsstufe &amp;quot;S&amp;quot; nach:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;div class=&amp;quot;code&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
        PORTA |= (1&amp;lt;&amp;lt;PA0);&lt;br /&gt;
  d2:	d8 9a       	sbi	0x1b, 0	; 27 (a)&lt;br /&gt;
	&lt;br /&gt;
        PORTA |= (1&amp;lt;&amp;lt;PA2)|(1&amp;lt;&amp;lt;PA3)|(1&amp;lt;&amp;lt;PA4);&lt;br /&gt;
  d4:	8b b3       	in	r24, 0x1b	; 27 (b)&lt;br /&gt;
  d6:	8c 61       	ori	r24, 0x1C	; 28 (c)&lt;br /&gt;
  d8:	8b bb       	out	0x1b, r24	; 27 (d)&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Das Setzen des einzelnen Bits wird bei eingeschalteter Optimierung für Register im unteren Speicherbereich in eine einzige Assembler-Anweisung (sbi) übersetzt und ist nicht anfällig für Unterbrechungen durch Interrupts. Die Anweisung zum Setzen von drei Bits wird jedoch in drei abhängige Assembler-Anweisungen übersetzt und bietet damit zwei &amp;quot;Angriffspunkte&amp;quot; für Unterbrechungen. Eine Interrupt-Routine könnte nach dem Laden des Ausgangszustands in den Zwischenspeicher (hier Register 24) den Wert des Registers ändern, z.&amp;amp;nbsp;B. ein Bit löschen. Damit würde der Zwischenspeicher nicht mehr mit dem tatsächlichen Zustand übereinstimmen aber dennoch nach der Bitoperation (hier ori) in das Register zurückgeschrieben. &lt;br /&gt;
&lt;br /&gt;
Beispiel: PORTA sei anfangs 0b00000000. Die erste Anweisung (a) setzt Bit 0, PORTA ist danach 0b00000001. Nun wird im ersten Teil der zweiten Anweisung der Portzustand in ein Register eingelesen (b). Unmittelbar darauf (vor (c)) &amp;quot;feuert&amp;quot; ein Interrupt, in dessen Interrupt-Routine Bit 0 von PORTA gelöscht wird. Nach Verlassen der Interrupt-Routine hat PORTA den Wert 0b00000000. In den beiden noch folgenden Anweisungen des Hauptprogramms wird nun der zwischengespeicherte &amp;quot;alte&amp;quot; Zustand 0b00000001 mit 0b00011100 logisch-oder-verknüft (c) und das Ergebnis 0b00011101 in PortA geschrieben (d). Obwohl zwischenzeitlich Bit 0 gelöscht wurde, ist es nach (d) wieder gesetzt. &lt;br /&gt;
&lt;br /&gt;
Lösungsmöglichkeiten:&lt;br /&gt;
* Register ohne besondere Vorkehrungen nicht in Interruptroutinen &#039;&#039;und&#039;&#039; im Hauptprogramm verändern.&lt;br /&gt;
* Interrupts vor Veränderungen in Registern, die auch in ISRs verändert werden, deaktivieren (&amp;quot;cli&amp;quot;).&lt;br /&gt;
* Bits einzeln löschen oder setzen. sbi und cbi können nicht unterbrochen werden. Vorsicht: nur Register im unteren Speicherbereich sind mittels sbi/cbi ansprechbar. Der Compiler kann nur für diese sbi/cbi-Anweisungen generieren. Für Register außerhalb dieses Adressbereichs (&amp;quot;Memory-Mapped&amp;quot;-Register) werden auch zur Manipulation einzelner Bits abhängige Anweisungen erzeugt (lds,...,sts).&lt;br /&gt;
&lt;br /&gt;
* siehe auch: [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Frequently asked Questions/Fragen Nr. 1 und 8. (Stand: avr-libc Vers. 1.0.4)&lt;br /&gt;
&lt;br /&gt;
== Interruptflags löschen ==&lt;br /&gt;
&lt;br /&gt;
Beim Löschen von Interruptflags haben AVRs eine Besonderheit, die auch im Datenblatt beschrieben ist: Es wird zum Löschen eine 1 in das betreffende Bit geschrieben. &lt;br /&gt;
&lt;br /&gt;
Hinweis: Dazu &#039;&#039;&#039;nicht&#039;&#039;&#039; übliche bitweise VerODERung nehmen, sondern eine direkte Zuweisung machen ([http://www.mikrocontroller.net/topic/171148#1640133 Erklärung]).&lt;br /&gt;
&lt;br /&gt;
== Was macht das Hauptprogramm? ==&lt;br /&gt;
&lt;br /&gt;
Im einfachsten (Ausnahme-)Fall gar nichts mehr. Es ist also durchaus denkbar, ein Programm zu schreiben, welches in der main-Funktion lediglich noch die Interrupts aktiviert und dann in einer Endlosschleife verharrt. Sämtliche Funktionen werden dann in den ISRs abgearbeitet. Diese Vorgehensweise ist jedoch bei den meisten Anwendungen schlecht: man verschenkt eine Verarbeitungsebene und hat außerdem möglicherweise Probleme durch Interruptroutinen, die zu viel Verarbeitungszeit benötigen.&lt;br /&gt;
&lt;br /&gt;
Normalerweise wird man in den Interruptroutinen nur die bei Auftreten des jeweiligen Interruptereignisses unbedingt notwendigen Operationen ausführen lassen. Alle weniger kritischen Aufgaben werden dann im Hauptprogramm abgearbeitet.&lt;br /&gt;
&lt;br /&gt;
* siehe auch: [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/Interrupts and Signals&lt;br /&gt;
&lt;br /&gt;
= Sleep-Modes =&lt;br /&gt;
&lt;br /&gt;
AVR Controller verfügen über eine Reihe von sogenannten [[Sleep Mode |&#039;&#039;Sleep-Modes&#039;&#039;]] (&amp;quot;Schlaf-Modi&amp;quot;). Diese ermöglichen es, Teile des Controllers abzuschalten. Zum Einen kann damit besonders bei Batteriebetrieb Strom gespart werden, zum Anderen können Komponenten des Controllers deaktiviert werden, die die Genauigkeit des Analog-Digital-Wandlers bzw. des Analog-Comparators negativ beeinflussen. Der Controller wird durch Interrupts aus dem Schlaf geweckt. Welche Interrupts den jeweiligen Schlafmodus beenden, ist einer Tabelle im Datenblatt des jeweiligen Controllers zu entnehmen.&lt;br /&gt;
Die Funktionen (eigentlich Makros) der avr-libc stehen nach Einbinden der header-Datei &#039;&#039;sleep.h&#039;&#039; zur Verfügung.&lt;br /&gt;
&lt;br /&gt;
;set_sleep_mode (uint8_t mode): Setzt den Schlafmodus, der bei Aufruf von sleep() aktiviert wird. In sleep.h sind einige Konstanten definiert (z.&amp;amp;nbsp;B. SLEEP_MODE_PWR_DOWN). Die definierten Modi werden jedoch nicht alle von sämtlichten AVR-Controllern unterstützt.&lt;br /&gt;
;sleep_enable(): Aktiviert den gesetzten Schlafmodus, versetzt den Controller aber noch nicht in den Schlafmodus&lt;br /&gt;
;sleep_cpu(): Versetzt den Controller in den Schlafmodus .sleep_cpu wird im Prinzip durch die Assembler-Anweisung &#039;&#039;sleep&#039;&#039; ersetzt.&lt;br /&gt;
;sleep_disable(): Deaktiviert den gesetzten Schlafmodus&lt;br /&gt;
;sleep_mode(): Versetzt den Controller in den mit set_sleep_mode gewählten Schlafmodus. Das Makro entspricht sleep_enable()+sleep_cpu()+sleep_disable(), beinhaltet also nicht die Aktivierung von Interrupts (besser nicht benutzen).&lt;br /&gt;
&lt;br /&gt;
Bei Anwendung von sleep_cpu() müssen Interrupts also bereits freigeben sein (sei()), da der Controller sonst nicht mehr &amp;quot;aufwachen&amp;quot; kann. sleep_mode() ist nicht geeignet für die Verwendung in ISR Interrupt-Service-Routinen, da bei deren Abarbeitung Interrupts global deaktiviert sind und somit auch die möglichen &amp;quot;Aufwachinterrupts&amp;quot;. Abhilfe: stattdessen sleep_enable(), sei(), sleep_cpu(), sleep_disable() und evtl. cli() verwenden (vgl. Dokumentation der avr-libc).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/sleep.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
   while (1) {&lt;br /&gt;
...&lt;br /&gt;
      set_sleep_mode(SLEEP_MODE_PWR_DOWN);&lt;br /&gt;
      sleep_mode();&lt;br /&gt;
   &lt;br /&gt;
      // Code hier wird erst nach Auftreten eines entsprechenden&lt;br /&gt;
      // &amp;quot;Aufwach-Interrupts&amp;quot; verarbeitet&lt;br /&gt;
...&lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In älteren Versionenen der avr-libc wurden nicht alle AVR-Controller durch die sleep-Funktionen richtig angesteuert. Mit avr-libc 1.2.0 wurde die Anzahl der unterstützten Typen jedoch deutlich erweitert. Bei nicht-unterstützten Typen erreicht man die gewünschte Funktionalität durch direkte &amp;quot;[[Bitmanipulation]]&amp;quot; der entsprechenden Register (vgl. Datenblatt) und Aufruf des Sleep-Befehls via Inline-Assembler oder sleep_cpu():&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
   // Sleep-Mode &amp;quot;Power-Save&amp;quot; beim ATmega169 &amp;quot;manuell&amp;quot; aktivieren&lt;br /&gt;
   SMCR = (3&amp;lt;&amp;lt;SM0) | (1&amp;lt;&amp;lt;SE);&lt;br /&gt;
   asm volatile (&amp;quot;sleep&amp;quot;::); // alternativ sleep_cpu() aus sleep.h&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Sleep Modi ==&lt;br /&gt;
Zu beachten ist, dass unterschiedliche Prozessoren aus der AVR Familie unterschiedliche Sleep-Modi unterstützen oder nicht unterstützen. Auskunft über die tatsächlichen Gegebenheiten gibt, wie immer, das zum Prozessor gehörende Datenblatt. Die unterschiedlichen Modi unterscheiden sich dadurch, welche Bereiche des Prozessors abgeschaltet werden. Damit korrespondiert unmittelbar welche Möglichkeiten es gibt, den Prozessor aus den jeweiligen Sleep Modus wieder aufzuwecken.&lt;br /&gt;
&lt;br /&gt;
;Idle Mode (SLEEP_MODE_IDLE): Die CPU kann durch SPI, USART, Analog Comperator, ADC, TWI, Timer, Watchdog und irgendeinen anderen Interrupt wieder aufgeweckt werden.&lt;br /&gt;
&lt;br /&gt;
;ADC Noise Reduction Mode (SLEEP_MODE_ADC): In diesem Modus liegt das Hauptaugenmerk darauf, die CPU soweit stillzulegen, dass der ADC möglichst keine Störungen aus dem inneren der CPU auffangen kann. Aufwachen aus diesem Modus kann ausgelöst werden durch den ADC, externe Interrupts, TWI, Timer und Watchdog.&lt;br /&gt;
&lt;br /&gt;
;Power-Down Mode (SLEEP_MODE_PWR_DOWN): In diesem Modus wird ein externer Oszillator (Quarz, Quarzoszillator) gestoppt. Geweckt werden kann die CPU durch einen externen Level Interrupt, TWI, Watchdog, Brown-Out-Reset&lt;br /&gt;
&lt;br /&gt;
;Power-Save-Mode (SLEEP_MODE_PWR_SAVE): Power-Save ist identisch zu Power-Down mit einer Ausnahme: Ist der Timer 2 auf die Verwendung eines externen Taktes konfiguriert, so läuft dieser Timer auch im Power-Save weiter und kann die CPU mit einem Interrupt aufwecken.&lt;br /&gt;
&lt;br /&gt;
;Standby-Mode (SLEEP_MODE_STANDBY, SLEEP_MODE_EXT_STANDBY): Voraussetzung für den Standby-Modus ist die Verwendung eines Quarzes oder eines Quarzoszillators (also einer externen Taktquelle). Ansonsten ist dieser Modus identisch zum Power-Down Modus. Vorteil dieses Modus ist eine kürzere Aufwachzeit.&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/Power Management and Sleep-Modes&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/96369#832712 Forenbeitrag] zur &amp;quot;Nichtverwendung&amp;quot; von sleep_mode in ISRs.&lt;br /&gt;
&lt;br /&gt;
= Zeiger =&lt;br /&gt;
Zeiger (engl. &#039;&#039;Pointer&#039;&#039;) sind Variablen, die die Adresse von Daten oder Funktionen enthalten und belegen 16 Bits. Die Größe hängt mit dem adressierbaren Speicherbereich zusammen und der GCC reserviert dann den entsprechenden Platz.&lt;br /&gt;
Ggf. ist es also günstiger, Indizes auf Arrays (Listen) zu verwenden, so dass der GCC für die Zeigerarithmetik den erforderlichen RAM nur temporär benötigt.&lt;br /&gt;
&lt;br /&gt;
Siehe auch: [[Zeiger]]&lt;br /&gt;
&lt;br /&gt;
= Speicherzugriffe =&lt;br /&gt;
&lt;br /&gt;
Atmel AVR-Controller verfügen typisch über drei Speicher:&lt;br /&gt;
&lt;br /&gt;
* [[RAM]]: Im RAM (genauer statisches RAM/SRAM) wird vom gcc-Compiler Platz für Variablen reserviert. Auch der Stack befindet sich im RAM. Dieser Speicher ist &amp;quot;flüchtig&amp;quot;, d.h. der Inhalt der Variablen geht beim Ausschalten oder einem Zusammenbruch der Spannungsversorgung verloren.&lt;br /&gt;
&lt;br /&gt;
* Programmspeicher: Ausgeführt als FLASH-Speicher, seitenweise wiederbeschreibbar. Darin ist das Anwendungsprogramm abgelegt.&lt;br /&gt;
&lt;br /&gt;
* [[EEPROM]]: Nichtflüchtiger Speicher, d.h. der einmal geschriebene Inhalt bleibt auch ohne Stromversorgung erhalten. Byte-weise schreib/lesbar. Im EEPROM werden typischerweise gerätespezifische Werte wie z.&amp;amp;nbsp;B. Kalibrierungswerte von Sensoren abgelegt.&lt;br /&gt;
&lt;br /&gt;
Einige AVRs besitzen keinen RAM-Speicher, lediglich die Register können als &amp;quot;Arbeitsvariablen&amp;quot;&lt;br /&gt;
genutzt werden. Da die Anwendung des avr-gcc auf solch &amp;quot;kleinen&amp;quot; Controllern ohnehin selten sinnvoll ist und auch nur bei einigen RAM-losen Typen nach [http://lightner.net/avr/ATtinyAvrGcc.html &amp;quot;Bastelarbeiten&amp;quot;] möglich ist, werden diese Controller hier nicht weiter berücksichtigt. Auch EEPROM-Speicher ist nicht auf allen Typen verfügbar. Generell sollten die nachfolgenden Erläuterungen auf alle ATmega-Controller und die größeren AT90-Typen übertragbar sein. Für die Typen ATtiny2313, ATtiny26 und viele weitere der &amp;quot;ATtiny-Reihe&amp;quot; gelten die Ausführungen ebenfalls.&lt;br /&gt;
&lt;br /&gt;
Siehe auch:&lt;br /&gt;
* [[Binäre Daten zum Programm hinzufügen]]&lt;br /&gt;
== RAM ==&lt;br /&gt;
&lt;br /&gt;
Die Verwaltung des RAM-Speichers erfolgt durch den Compiler, im Regelfall ist beim Zugriff auf Variablen im RAM nichts Besonderes zu beachten. Die Erläuterungen in jedem brauchbaren C-Buch gelten auch für den vom avr-gcc-Compiler erzeugten Code.&lt;br /&gt;
&lt;br /&gt;
Um Speicher dynamisch (während der Laufzeit) zu reservieren, kann &#039;&#039;&#039;malloc()&#039;&#039;&#039; verwendet werden. malloc(size) &amp;quot;alloziert&amp;quot; (~reserviert) einen gewissen Speicherblock mit &#039;&#039;&#039;size&#039;&#039;&#039; Bytes. Ist kein Platz für den neuen Block, wird NULL (0) zurückgegeben.&lt;br /&gt;
&lt;br /&gt;
Wird der angelegte Block zu klein (groß), kann die Größe mit realloc() verändert werden. Den allozierten Speicherbereich kann man mit free() wieder freigeben. Wenn das Freigeben eines Blocks vergessen wird spricht man von einem &amp;quot;Speicherleck&amp;quot; (memory leak).&lt;br /&gt;
&lt;br /&gt;
malloc() legt Speicherblöcke im &#039;&#039;&#039;Heap&#039;&#039;&#039; an, belegt man zuviel Platz, dann wächst der Heap zu weit nach oben und überschreibt den Stack, und der Controller kommt in Teufels Küche. Das kann leider nicht nur passieren wenn man insgesamt zu viel Speicher anfordert, sondern auch wenn man Blöcke unterschiedlicher Größe in ungünstiger Reihenfolge alloziert/freigibt (siehe Artikel [[Heap-Fragmentierung]]). Aus diesem Grund sollte man malloc() auf Mikrocontrollern sehr sparsam (am besten gar nicht) verwenden.&lt;br /&gt;
&lt;br /&gt;
Beispiel zur Verwendung von malloc():&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdlib.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void foo(void) {&lt;br /&gt;
  // neuen speicherbereich anlegen,&lt;br /&gt;
  // platz für 10 uint16&lt;br /&gt;
  uint16_t* pBuffer = malloc(10 * sizeof(uint16_t));&lt;br /&gt;
&lt;br /&gt;
  // darauf zugreifen, als wärs ein gewohnter Buffer&lt;br /&gt;
  pBuffer[2] = 5;&lt;br /&gt;
&lt;br /&gt;
  // Speicher (unbedingt!) wieder freigeben&lt;br /&gt;
  free(pBuffer);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Wenn (wie in obigem Beispiel) dynamischer Speicher nur für die Dauer einer Funktion benötigt und am Ende wieder freigegeben wird, bietet es sich an, statt malloc() &#039;&#039;&#039;alloca()&#039;&#039;&#039; zu verwenden. Der Unterschied zu malloc() ist, dass der Speicher auf dem Stack reserviert wird, und beim Verlassen der Funktion automatisch wieder freigegeben wird. Es kann somit kein Speicherleck und keine Fragmentierung entstehen.&lt;br /&gt;
&lt;br /&gt;
siehe auch:&lt;br /&gt;
* http://www.nongnu.org/avr-libc/user-manual/malloc.html&lt;br /&gt;
&lt;br /&gt;
== Programmspeicher (Flash) ==&lt;br /&gt;
&lt;br /&gt;
Ein Zugriff auf Konstanten im Programmspeicher ist mittels avr-gcc nicht &amp;quot;transparent&amp;quot; möglich. D.h. es sind besondere Zugriffsfunktionen erforderlich, um Daten aus diesem Speicher zu lesen. Grundsätzlich basieren alle Zugriffsfunktionen auf der Assembler-Anweisung lpm (load program memory, bei AVR Controllern mit mehr als 64kB Flash auch elpm). Die Standard-Laufzeitbibliothek des avr-gcc (die avr-libc) stellt diese Funktionen nach Einbinden der Header-Datei pgmspace.h zur Verfügung. Mit diesen Funktionen können einzelne Bytes, Datenworte (16bit) und Datenblöcke gelesen werden. &lt;br /&gt;
&lt;br /&gt;
Deklarationen von Variablen im Flash-Speicher werden durch das &amp;quot;Attribut&amp;quot; PROGMEM ergänzt. Lokale Variablen (eigentlich Konstanten) innerhalb von Funktionen können ebenfalls im Programmspeicher abgelegt werden. Dazu ist bei der Definition jedoch ein &#039;&#039;static&#039;&#039; voranzustellen, da solche &amp;quot;Variablen&amp;quot; nicht auf dem Stack bzw. (bei Optimierung) in Registern verwaltet werden können. Der Compiler &amp;quot;wirft&amp;quot; eine Warnung falls static fehlt.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Byte */&lt;br /&gt;
const uint8_t pgmFooByte PROGMEM = 123;&lt;br /&gt;
&lt;br /&gt;
/* Wort */&lt;br /&gt;
const uint16_t pgmFooWort PROGMEM = 12345;&lt;br /&gt;
&lt;br /&gt;
/* Byte-Array */&lt;br /&gt;
const uint8_t pgmFooByteArray1[] PROGMEM = { 18, 3 ,70 };&lt;br /&gt;
const uint8_t pgmFooByteArray2[] PROGMEM = { 30, 7 ,79 };&lt;br /&gt;
&lt;br /&gt;
/* Zeiger */&lt;br /&gt;
const uint8_t * const pgmPointerToArray1 PROGMEM = pgmFooByteArray1;&lt;br /&gt;
const uint8_t * const pgmPointerArray[] PROGMEM = { pgmFooByteArray1, pgmFooByteArray2 };&lt;br /&gt;
&lt;br /&gt;
void foo(void)&lt;br /&gt;
{&lt;br /&gt;
  static const uint8_t pgmTestByteLocal PROGMEM = 0x55;&lt;br /&gt;
  static const char pgmTestStringLocal[] PROGMEM = &amp;quot;im Flash&amp;quot;;&lt;br /&gt;
  // so nicht (static fehlt) &lt;br /&gt;
  // char pgmTestStringLocalFalsch [] PROGMEM = &amp;quot;so nicht&amp;quot;;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Byte lesen ===&lt;br /&gt;
&lt;br /&gt;
Mit der Funktion pgm_read_byte aus pgmspace.h erfolgt der Zugriff auf die Daten. Parameter der Funktion ist die Adresse des Bytes im Flash-Speicher.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
const uint8_t pgmFooByte PROGMEM = 123;&lt;br /&gt;
const uint8_t pgmFooByteArray1[] PROGMEM = { 18, 3, 70 };&lt;br /&gt;
&lt;br /&gt;
void foo (void)&lt;br /&gt;
    // Wert der Ram-Variablen myByte auf den Wert von pgmFooByte setzen:&lt;br /&gt;
    uint8_t myByte;&lt;br /&gt;
&lt;br /&gt;
    myByte = pgm_read_byte (&amp;amp;pgmFooByte);&lt;br /&gt;
    // myByte hat nun den Wert 123&lt;br /&gt;
&lt;br /&gt;
    // Schleife ueber ein Array aus Byte-Werten im Flash&lt;br /&gt;
    uint8_t i;&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; 3; i++)&lt;br /&gt;
    {&lt;br /&gt;
        myByte = pgm_read_byte (&amp;amp;pgmFooByteArray1[i]);&lt;br /&gt;
        // mach was mit myByte&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Wort lesen ===&lt;br /&gt;
&lt;br /&gt;
Für &amp;quot;einfache&amp;quot; 16-Bit breite Variablen erfolgt der Zugriff analog zum Byte-Beispiel, jedoch mit der Funktion &amp;lt;code&amp;gt;pgm_read_word&amp;lt;/code&amp;gt;:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
const uint16_t pgmFooWort PROGMEM = 12345;&lt;br /&gt;
&lt;br /&gt;
    uint16_t myWord = pgm_read_word (&amp;amp;pgmFooWort);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zeiger auf Werte im Flash sind ebenfalls 16 Bits &amp;quot;groß&amp;quot;.&lt;br /&gt;
Damit ist der mögliche Speicherbereich für &amp;quot;Flash-Konstanten&amp;quot; auf 64kB begrenzt.&amp;lt;ref&amp;gt;Einige avr-libc/pgmspace-Funktionen ermöglichen den Lesezugriff auf den gesamten Flash-Speicher, intern via Assembler Anweisung ELPM. Die Initialisierungswerte des Speicherinhalts jenseits der 64kB-Marke müssen dann jedoch auf anderem Weg angelegt werden, d.h. nicht per PROGMEM; evtl. eigene Section und Linker-Optionen. Alt und nicht ganz korrekt: Die avr-libc pgmspace-Funktionen unterstützen nur die unteren 64kB Flash bei Controllern mit mehr als 64kB.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    const uint8_t *ptrToArray;&lt;br /&gt;
&lt;br /&gt;
    ptrToArray = (const uint8_t*) pgm_read_word (&amp;amp;pgmPointerToArray1);&lt;br /&gt;
    // ptrToArray enthält nun die Startadresse des Byte-Arrays pgmFooByteArray1&lt;br /&gt;
    // Allerdings würde ein direkter Zugriff mit diesem Pointer (z.&amp;amp;nbsp;B. temp=*ptrToArray)&lt;br /&gt;
    // nicht den Inhalt von pgmFooByteArray1[0] liefern, sondern von einer Speicherstelle&lt;br /&gt;
    // im RAM, die die gleiche Adresse hat wie pgmFooByteArray1[0]&lt;br /&gt;
    // Daher muss nun die Funktion pgm_read_byte() benutzt werden, die die in ptrToArray&lt;br /&gt;
    // enthaltene Adresse benutzt und auf das Flash zugreift.&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; 3; i++)&lt;br /&gt;
    {&lt;br /&gt;
        myByte = pgm_read_byte (ptrToArray+i);&lt;br /&gt;
        // mach was mit myByte... (18, 3, 70)&lt;br /&gt;
    }&lt;br /&gt;
&lt;br /&gt;
    ptrToArray = (const uint8_t*) pgm_read_word (&amp;amp;pgmPointerArray[1]);&lt;br /&gt;
    &lt;br /&gt;
    // ptrToArray enthält nun die Adresse des ersten Elements des Byte-Arrays pgmFooByteArray2&lt;br /&gt;
    // da im zweiten Element des Pointer-Arrays pgmPointerArray die Adresse&lt;br /&gt;
    // von pgmFooByteArray2 abgelegt ist&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; 3; i++)&lt;br /&gt;
    {&lt;br /&gt;
        myByte = pgm_read_byte (ptrToArray+i);&lt;br /&gt;
        // mach was mit myByte... (30, 7, 79)&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Block lesen ===&lt;br /&gt;
In den Standard-Flash Funktionen ist keine der pgm_read_xxxx Nomenklatur folgenden Funktion enthalten, die einen kompletten Block ausliest. Die enstprechende Funktion ist eine Variante von memcpy und heißt memcpy_P().&lt;br /&gt;
&lt;br /&gt;
Was diese Funktion im Prinzip macht, ist einfach in einer Schleife pgm_read_byte zu benutzen, um einen Speicherblock von der Quelladresse im Flash an eine Zieladresse im SRAM zu kopieren.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void pgm_read_block( uint8_t* pTarget, const uint8_t* pSource, size_t len )&lt;br /&gt;
{&lt;br /&gt;
  size_t i;&lt;br /&gt;
&lt;br /&gt;
  for( i = 0; i &amp;lt; len; ++i )&lt;br /&gt;
    *pTarget++ = pgm_read_byte( pSource++ );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Damit ist es dann natürlich kein Problem mehr ganze Arrays oder Strukturen aus dem Flash in das SRAM zu übertragen.&lt;br /&gt;
&lt;br /&gt;
=== Strings lesen ===&lt;br /&gt;
Strings sind in C nichts anderes als eine Abfolge von Zeichen. Der prinzipielle Weg ist daher identisch zu &amp;quot;Bytes lesen&amp;quot;, wobei allerdings auf die [http://www.mikrocontroller.net/articles/FAQ#Wie_funktioniert_String-Verarbeitung_in_C.3F Besonderheiten von Strings] wie 0-Terminierung geachtet werden muss, bzw. diese zur Steuerung einer Schleife über die Zeichen im String ausgenutzt werden kann&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
const char pgmString[] PROGMEM = &amp;quot;Hello world&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  char c;&lt;br /&gt;
  const char* addr;&lt;br /&gt;
&lt;br /&gt;
  addr = pgmString;&lt;br /&gt;
  while (c = pgm_read_byte (addr++), c != &#039;\0&#039;)&lt;br /&gt;
  {&lt;br /&gt;
    // mach was mit c&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Zur Unterstützung des Programmierers steht das Repertoir der str-Funktionen auch in jeweils eine Variante zur Verfügung, die mit dem Flash-Speicher arbeiten kann. Die Funktionsnamen tragen den Suffix &amp;lt;tt&amp;gt;_P&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
const char pgmString[] PROGMEM = &amp;quot;Hallo world&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
void foo (void)&lt;br /&gt;
{&lt;br /&gt;
  char string[40];&lt;br /&gt;
&lt;br /&gt;
  strcpy_P (string, pgmString);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Float lesen ===&lt;br /&gt;
&lt;br /&gt;
Auch um floats zu lesen gibt es ein Makro:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
float pgmFloatArray[3] PROGMEM = {1.1, 2.2, 3.3};&lt;br /&gt;
&lt;br /&gt;
void read_float (void)&lt;br /&gt;
{&lt;br /&gt;
   int i;&lt;br /&gt;
   float f;&lt;br /&gt;
&lt;br /&gt;
   for (i=0; i&amp;lt;3; i++) &lt;br /&gt;
   {&lt;br /&gt;
      // entspricht  f = pgmFloatArray[i];&lt;br /&gt;
      f = pgm_read_float (&amp;amp;pgmFloatArray[i]);&lt;br /&gt;
      // mach was mit f &lt;br /&gt;
   }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
TODO: Beispiele für structs und pointer aus Flash auf struct im Flash (menues, state-machines etc.). Eine kleine Einleitung insbesondere auch in Bezug auf die auftretenden Schwierigkeiten liefert [http://www.mail-archive.com/avr-gcc-list@nongnu.org/msg05652.html].&lt;br /&gt;
&lt;br /&gt;
=== Array aus Strings im Flash-Speicher ===&lt;br /&gt;
&lt;br /&gt;
Arrays aus Strings im Flash-Speicher werden in zwei Schritten angelegt: Zuerst die einzelnen Elemente des Arrays und im Anschluss ein Array, in dem die Startaddressen der Strings abgelegt werden. Zum Auslesen wird zuerst die Adresse des i-ten Elements aus dem Array im Flash-Speicher gelesen, die im Anschluss dazu genutzt wird, auf das Element (den String) selbst zuzugreifen.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
const char str1[] PROGMEM = &amp;quot;first_A&amp;quot;;&lt;br /&gt;
const char str2[] PROGMEM = &amp;quot;second_A&amp;quot;;&lt;br /&gt;
const char str3[] PROGMEM = &amp;quot;third_A&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
const char * const strarray1[] PROGMEM = &lt;br /&gt;
{&lt;br /&gt;
   str1,&lt;br /&gt;
   str2,&lt;br /&gt;
   str3&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
static char work[20];&lt;br /&gt;
&lt;br /&gt;
void read_strings (void)&lt;br /&gt;
{&lt;br /&gt;
    size_t i;&lt;br /&gt;
&lt;br /&gt;
    for (i = 0; i &amp;lt; sizeof (strarray1) / sizeof (strarray1[0]); i++)&lt;br /&gt;
    {&lt;br /&gt;
        size_t j, len;&lt;br /&gt;
&lt;br /&gt;
        // setze Pointer auf die Addresse des i-ten Elements des&lt;br /&gt;
        // Flash-Arrays (str1, str2, ...)&lt;br /&gt;
        const char *pstrflash = (const char*) pgm_read_word (&amp;amp;strarray1[i]);&lt;br /&gt;
&lt;br /&gt;
        // kopiere den Inhalt der Zeichenkette von der&lt;br /&gt;
        // in pstrflash abgelegten Adresse in das work-Array&lt;br /&gt;
        // analog zu strcpy( work, strarray1[i]) wenn alles im RAM&lt;br /&gt;
        strcpy_P (work, pstrflash);&lt;br /&gt;
&lt;br /&gt;
        // Gleichbedeutend damit:&lt;br /&gt;
        strcpy_P (work, (const char*) pgm_read_word (&amp;amp;strarray1[i]));&lt;br /&gt;
    &lt;br /&gt;
        // Zeichen-fuer-Zeichen&lt;br /&gt;
        len = strlen_P (&amp;amp;strarray1[i]);&lt;br /&gt;
&lt;br /&gt;
        // &amp;lt;= da auch das Stringende-Zeichen kopiert werden soll&lt;br /&gt;
        for (j = 0; j &amp;lt;= len; j++)&lt;br /&gt;
        {&lt;br /&gt;
            // analog zu work[j] = strarray[i][j] wenn alles im RAM&lt;br /&gt;
            work[i] = (char) pgm_read_byte (pstrflash++);&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Siehe dazu auch die avr-libc FAQ: [http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_rom_array How do I put an array of strings completely in ROM?]&lt;br /&gt;
&lt;br /&gt;
=== Vereinfachung für Zeichenketten (Strings) im Flash ===&lt;br /&gt;
&lt;br /&gt;
Zeichenketten können innerhalb des Quellcodes als &amp;quot;Flash-Konstanten&amp;quot; ausgewiesen werden. Dazu dient das Makro PSTR aus pgmspace.h. Dies erspart die getrennte Deklaration mit PROGMEM-Attribut.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define MAXLEN 30&lt;br /&gt;
&lt;br /&gt;
char StringImFlash[] PROGMEM = &amp;quot;Erwin Lindemann&amp;quot;;&lt;br /&gt;
char StringImRam[MAXLEN];&lt;br /&gt;
&lt;br /&gt;
void read_string (void)&lt;br /&gt;
{&lt;br /&gt;
    strcpy (StringImRam, &amp;quot;Mueller-Luedenscheidt&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
    if (!strncmp_P (StringImRam, StringImFlash, 5))&lt;br /&gt;
    {&lt;br /&gt;
        // mach was, wenn die ersten 5 Zeichen identisch - hier nicht&lt;br /&gt;
    }&lt;br /&gt;
    else&lt;br /&gt;
    {&lt;br /&gt;
        // der Code hier wuerde ausgefuehrt &lt;br /&gt;
    } &lt;br /&gt;
&lt;br /&gt;
    if (!strncmp_P (StringImRam, PSTR(&amp;quot;Mueller-Schmitt&amp;quot;), 5))&lt;br /&gt;
    {&lt;br /&gt;
        // der Code hier wird ausgefuehrt, wenn die ersten &lt;br /&gt;
        // 5 Zeichen uebereinstimmen&lt;br /&gt;
    }&lt;br /&gt;
    else &lt;br /&gt;
    {&lt;br /&gt;
        // wird bei Nicht-Uebereinstimmung ausgefuehrt&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Aber Vorsicht: Ersetzt man zum Beispiel&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// Daten im &amp;quot;Flash&amp;quot;&lt;br /&gt;
const char flashText[] PROGMEM = &amp;quot;mit[]&amp;quot;; &lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
durch&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// Hier wird &amp;quot;mit*&amp;quot; im RAM angelegt und flashPointer&lt;br /&gt;
// enthaelt die Adresse&lt;br /&gt;
const char* const flashPointer PROGMEM = &amp;quot;mit*&amp;quot;;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
dann kann es zu Problemen kommen.&lt;br /&gt;
&lt;br /&gt;
Übergibt man Zeichenketten, die im Flash abglegt sind an eine Funktion – also die Adresse des ersten Zeichens – so muss die Funktion entsprechend programmiert sein. Die Funktion selbst hat keine Möglichkeit zu unterscheiden, ob es sich um eine Flash-Adresse oder ein RAM-Adresse handelt. Die avr-libc und viele andere avr-gcc-Bibliotheken halten sich an die Konvention, dass Namen von Funktionen, die Flash-Adressen erwarten, mit dem Suffix &amp;lt;code&amp;gt;_P&amp;lt;/code&amp;gt; versehen sind.&lt;br /&gt;
&lt;br /&gt;
Eine Funktion, die einen im Flash abgelegten String z.&amp;amp;nbsp;B. an eine UART ausgibt, würde dann so aussehen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
void uart_puts_p (const char *text)&lt;br /&gt;
{&lt;br /&gt;
    char zeichen;&lt;br /&gt;
&lt;br /&gt;
    while ((zeichen = pgm_read_byte (text)))&lt;br /&gt;
    {&lt;br /&gt;
        // so lange, wie mittels pgm_read_byte nicht das Stringende&lt;br /&gt;
        // gelesen wurde: gib dieses Zeichen aus&lt;br /&gt;
&lt;br /&gt;
        uart_putc (Zeichen);&lt;br /&gt;
        text++;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Von einigen Bibliotheken werden Makros definiert, die &amp;quot;automatisch&amp;quot; ein PSTR bei Verwendung einer Funktion einfügen. Ein Blick in den Header-File der Bibliothek zeigt, ob dies der Fall ist. Ein Beispiel aus P. Fleurys lcd-Library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
// Ausschnitt aus dem Header-File lcd.h der &amp;quot;Fleury-LCD-Lib.&amp;quot;&lt;br /&gt;
extern void lcd_puts_p (const char *progmem_s);&lt;br /&gt;
#define lcd_puts_P(__s) lcd_puts_p(PSTR(__s))&lt;br /&gt;
&lt;br /&gt;
// in einer Anwendung&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
#include &amp;lt;string.h&amp;gt;&lt;br /&gt;
#include &amp;quot;lcd.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
const char StringImFlash[] PROGMEM = &amp;quot;Erwin Lindemann&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
void my_write (coid)&lt;br /&gt;
{&lt;br /&gt;
    lcd_puts_p (StringImFlash); &lt;br /&gt;
    lcd_puts_P (&amp;quot;Dr. Kloebner&amp;quot;); &lt;br /&gt;
}&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Flash in der Anwendung schreiben ===&lt;br /&gt;
&lt;br /&gt;
Bei AVRs mit &amp;quot;self-programming&amp;quot;-Option – auch bekannt als [[Bootloader]]-Support – können Teile des Flash-Speichers vom Anwendungsprogramm beschrieben werden. Dies ist nur möglich, wenn die Schreibfunktion in einem besonderen Speicherbereich, der boot-section des Programmspeichers/Flash, abgelegt ist.&lt;br /&gt;
&lt;br /&gt;
Bei einigen kleinen AVRs gibt es keine gesonderte Boot-Section, bei diesen kann der Flashspeicher von jeder Stelle des Programms geschrieben werden. Für Details sei hier auf das jeweilige Controller-Datenblatt und die Erläuterungen zum Modul boot.h der avr-libc verwiesen. Es existieren auch Application-Notes dazu bei atmel.com, die auf avr-gcc-Code übertragbar sind.&lt;br /&gt;
&lt;br /&gt;
Siehe auch: &lt;br /&gt;
* Forumsbeitrag [http://www.mikrocontroller.net/topic/163632#1561622 Daten in Programmspeicher speichern]&lt;br /&gt;
&lt;br /&gt;
=== Warum so kompliziert? ===&lt;br /&gt;
&lt;br /&gt;
Zu dem Thema, warum die Verabeitung von Werten aus dem Flash-Speicher so kompliziert ist, sei hier nur kurz erläutert: Die Harvard-Architektur des AVR weist getrennte Adressräume für Programm(Flash)- und Datenspeicher(RAM) auf. Der C-Standard und der gcc-Compiler sehen keine unterschiedlichen Adressräume vor.&lt;br /&gt;
&lt;br /&gt;
Hat man zum Beispiel eine Funktion string_an_uart(const char* s) und übergibt an diese Funktion die Adresse einer Zeichenkette, z.&amp;amp;nbsp;B. 0x01fe, weiß die Funktion nicht, ob die Adresse auf den Flash-Speicher oder den/das RAM zeigt. Allein aus dem Pointer-Wert, also dem Zahlenwert, kann nicht auf den Ort der Ablage geschlossen werden.&lt;br /&gt;
&lt;br /&gt;
Einige AVR-Compiler bilden die Harvard-Architektur ab, indem sie in einen Pointer nicht nur die Adresse speichern, sondern auch den Ablageort wie &#039;&#039;Flash&#039;&#039; oder &#039;&#039;RAM&#039;&#039;. In einem Aufruf einer Funktion wird dann bei Pointer-Parametern neben der Adresse auch der Speicherbereich, auf den der Pointer zeigt, übergeben. Dies hat jedoch auch Nachteile, denn bei jedem Zugriff über einen Zeiger muss zur &#039;&#039;Laufzeit&#039;&#039; entschieden werden, wie der Zugriff auszuführen ist und entsprechend länglicher und langsamer kann Code ausgeführt werden.&lt;br /&gt;
&lt;br /&gt;
* siehe auch: [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitte Modules/Program Space String Utilities und Abschnitt Modules/Bootloader Support Utilities&lt;br /&gt;
&lt;br /&gt;
== EEPROM ==&lt;br /&gt;
&lt;br /&gt;
Man beachte, dass der EEPROM-Speicher nur eine begrenzte Anzahl von Schreibzugriffen zulässt. Beschreibt man eine EEPROM-Zelle öfter als die im Datenblatt zugesicherte Anzahl (typisch 100.000), wird die Funktion der Zelle nicht mehr garantiert. &lt;br /&gt;
Dies gilt für jede einzelne Zelle. Bei geschickter Programmierung (z.&amp;amp;nbsp;B. Ring-Puffer), bei der die zu beschreibenden Zellen regelmäßig gewechselt werden, kann man eine deutlich höhere Anzahl an Schreibzugriffen, bezogen auf den Gesamtspeicher, erreichen.&lt;br /&gt;
&lt;br /&gt;
Schreib- und Lesezugriffe auf den EEPROM-Speicher erfolgen über die im Modul eeprom.h definierten Funktionen. Mit diesen Funktionen können einzelne Bytes, Datenworte (16bit) und Datenblöcke geschrieben und gelesen werden. &lt;br /&gt;
&lt;br /&gt;
Bei Nutzung des EEPROMs ist zu beachten, dass vor dem Zugriff auf diesen Speicher abgefragt wird, ob der Controller die vorherige EEPROM-Operation abgeschlossen hat. Die avr-libc-Funktionen beinhalten diese Prüfung, man muss sie nicht selbst implementieren. Man sollte auch verhindern, dass der Zugriff durch die Abarbeitung einer Interrupt-Routine unterbrochen wird, da bestimme Befehlsabfolgen vorgegeben sind, die innerhalb weniger Taktzyklen aufeinanderfolgen müssen (&amp;quot;timed sequence&amp;quot;). Auch dies muss bei Nutzung der Funktionen aus der avr-libc/eeprom.h-Datei nicht selbst implementiert werden. Innerhalb der Funktionen werden Interrupts vor der &amp;quot;EEPROM-Sequenz&amp;quot; global deaktiviert und im Anschluss, falls vorher auch schon eingeschaltet, wieder aktiviert.&lt;br /&gt;
&lt;br /&gt;
Um eine Variable im EEPROM anzulegen, stellt die avr-libc das Makro EEMEM zur Verfügung&amp;lt;ref&amp;gt;In älteren Versionen der avr-libc ist EEMEM noch nicht vorhanden, und man kann sich folgendermassen behelfen:&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef EEMEM&lt;br /&gt;
#define EEMEM __attribute__((section (&amp;quot;.eeprom&amp;quot;)))&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/c&amp;gt;&amp;lt;/ref&amp;gt;, das analog zu PROGMEM verwendet wird.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/* Byte */&lt;br /&gt;
uint8_t eeFooByte EEMEM = 123;&lt;br /&gt;
&lt;br /&gt;
/* Wort */&lt;br /&gt;
uint16_t eeFooWord EEMEM = 12345;&lt;br /&gt;
&lt;br /&gt;
/* float */&lt;br /&gt;
float eeFooFloat EEMEM;&lt;br /&gt;
&lt;br /&gt;
/* Byte-Array */&lt;br /&gt;
uint8_t eeFooByteArray1[] EEMEM = { 18, 3, 70 };&lt;br /&gt;
uint8_t eeFooByteArray2[] EEMEM = { 30, 7, 79 };&lt;br /&gt;
&lt;br /&gt;
/* 16-bit unsigned short feld */&lt;br /&gt;
uint16_t eeFooWordArray1[4] EEMEM;&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bytes lesen/schreiben ===&lt;br /&gt;
&lt;br /&gt;
Die avr-libc Funktion zum Lesen eines Bytes heißt eeprom_read_byte. Parameter ist die Adresse des Bytes im EEPROM. Geschrieben wird über die Funktion eeprom_write_byte mit den Parametern Adresse und Inhalt. Anwendungsbeispiel:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#define EEPROM_DEF 0xFF&lt;br /&gt;
&lt;br /&gt;
void eeprom_example (void)&lt;br /&gt;
{&lt;br /&gt;
    uint8_t myByte;&lt;br /&gt;
&lt;br /&gt;
    // myByte lesen (Wert = 123)&lt;br /&gt;
    myByte = eeprom_read_byte (&amp;amp;eeFooByte);&lt;br /&gt;
&lt;br /&gt;
    // der Wert 99 wird im EEPROM an die Adresse der&lt;br /&gt;
    // Variablen eeFooByte geschrieben&lt;br /&gt;
    myByte = 99;&lt;br /&gt;
    eeprom_write_byte(&amp;amp;eeFooByte, myByte); // schreiben&lt;br /&gt;
&lt;br /&gt;
    myByte = eeprom_read_byte (&amp;amp;eeFooByteArray1[1]); &lt;br /&gt;
    // myByte hat nun den Wert 3&lt;br /&gt;
&lt;br /&gt;
    // Beispiel zur &amp;quot;Sicherung&amp;quot; gegen leeres EEPROM nach &amp;quot;Chip Erase&amp;quot;&lt;br /&gt;
    // (z. B. wenn die .eep-Datei nach Programmierung einer neuen Version&lt;br /&gt;
    // des Programms nicht in den EEPROM uebertragen wurde und EESAVE&lt;br /&gt;
    // deaktiviert ist (unprogrammed/1)&lt;br /&gt;
    // &lt;br /&gt;
    // Vorsicht: wenn EESAVE &amp;quot;programmed&amp;quot; ist, hilft diese Sicherung nicht&lt;br /&gt;
    // weiter, da die Speicheraddressen in einem neuen/erweiterten Programm&lt;br /&gt;
    // moeglicherweise verschoben wurden. An der Stelle &amp;amp;eeFooByte steht&lt;br /&gt;
    // dann u.U. der Wert einer anderen Variable aus einer &amp;quot;alten&amp;quot; Version.&lt;br /&gt;
&lt;br /&gt;
    uint8_t fooByteDefault = 222;&lt;br /&gt;
    if ((myByte = eeprom_read_byte (&amp;amp;eeFooByte)) == EEPROM_DEF)&lt;br /&gt;
    {&lt;br /&gt;
        myByte = fooByteDefault;&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Wort lesen/schreiben ===&lt;br /&gt;
&lt;br /&gt;
Schreiben und Lesen von Datenworten erfolgt analog zur Vorgehensweise bei Bytes:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
    // lesen&lt;br /&gt;
    uint16_t myWord = eeprom_read_word (&amp;amp;eeFooWord);&lt;br /&gt;
&lt;br /&gt;
    // schreiben&lt;br /&gt;
    eeprom_write_word (&amp;amp;eeFooWord, 2222);&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Block lesen/schreiben ===&lt;br /&gt;
&lt;br /&gt;
Lesen und Schreiben von Datenblöcken erfolgt über die Funktionen &amp;lt;code&amp;gt;eeprom_read_block()&amp;lt;/code&amp;gt; bzw. &amp;lt;code&amp;gt;eeprom_write_block()&amp;lt;/code&amp;gt;. Die Funktionen erwarten drei Parameter: die Adresse der Quell- bzw. Zieldaten im RAM, die EEPROM-Addresse und die Länge des Datenblocks in Bytes als &amp;lt;code&amp;gt;size_t&amp;lt;/code&amp;gt;.&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
uint8_t  myByteBuffer[3];&lt;br /&gt;
uint16_t myWordBuffer[4];&lt;br /&gt;
&lt;br /&gt;
void eeprom_block_example (void)&lt;br /&gt;
{&lt;br /&gt;
    /* Datenblock aus EEPROM lesen  */&lt;br /&gt;
&lt;br /&gt;
    /* liest 3 Bytes ab der von eeFooByteArray1 definierten EEPROM-Adresse&lt;br /&gt;
       in das RAM-Array myByteBuffer */&lt;br /&gt;
    eeprom_read_block (myByteBuffer, eeFooByteArray1, 3);&lt;br /&gt;
&lt;br /&gt;
    /* dito mit etwas Absicherung betr. der Länge */&lt;br /&gt;
    eeprom_read_block (myByteBuffer, eeFooByteArray1, sizeof(myByteBuffer));&lt;br /&gt;
&lt;br /&gt;
    /* und nun mit 16-Bit Array */&lt;br /&gt;
    eeprom_read_block (myWordBuffer, eeFooWordArray1, sizeof(myWordBuffer));&lt;br /&gt;
&lt;br /&gt;
    /* Datenblock in EEPROM schreiben */&lt;br /&gt;
    eeprom_write_block (myByteBuffer, eeFooByteArray1, sizeof(myByteBuffer));&lt;br /&gt;
    eeprom_write_block (myWordBuffer, eeFooWordArray1, sizeof(myWordBuffer));&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ebenso lassen sich float-Variablen lesen und schreiben:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
float eeFloat EEMEM = 12.34f;&lt;br /&gt;
&lt;br /&gt;
float void eeprom_float_example (float value)&lt;br /&gt;
{&lt;br /&gt;
   /* float in EEPROM schreiben */&lt;br /&gt;
   eeprom_write_float (&amp;amp;eeFloat, value);&lt;br /&gt;
&lt;br /&gt;
   /* float aus EEPROM lesen */&lt;br /&gt;
   return  eeprom_read_float (&amp;amp;eeFloat);&lt;br /&gt;
}&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== EEPROM-Speicherabbild in .eep-Datei ===&lt;br /&gt;
&lt;br /&gt;
Mit den zum Compiler gehörenden Werkzeugen kann der aus den Variablendeklarationen abgeleitete EEPROM-Inhalt in eine Datei geschrieben werden. Die übliche Dateiendung ist .eep, Daten im Intel Hex-Format. Damit können Standardwerte für den EEPROM-Inhalt im Quellcode definiert werden. &lt;br /&gt;
&lt;br /&gt;
Makefiles nach WinAVR/MFile-Vorlage enthalten bereits die notwendigen Einstellungen, siehe dazu die Erläuterungen im [[AVR-GCC-Tutorial/Exkurs Makefiles|Exkurs Makefiles]].&lt;br /&gt;
&lt;br /&gt;
Der Inhalt der eep-Datei muss ebenfalls zum Mikrocontroller übertragen werden, wenn die Initialisierungswerte aus der Deklaration vom Programm erwartet werden. Ansonsten enthält der EEPROM-Speicher nach der Übertragung des Programmers mittels ISP abhängig von der Einstellung der EESAVE-Fuse&amp;lt;ref&amp;gt;vgl. Datenblatt Abschnitt Fuse Bits&amp;lt;/ref&amp;gt; nicht die korrekten Werte:&lt;br /&gt;
; EESAVE = 0 (programmed): Die Daten im EEPROM bleiben erhalten. Werden sie nicht neu geschrieben, so enthält das EEPROM evtl. Daten, die nicht mehr zum Programm passen.&lt;br /&gt;
; EESAVE = 1 (unprogrammed): Beim Programmieren werden die Daten im EEPROM gelöscht, also auf 0xff gesetzt.&lt;br /&gt;
&lt;br /&gt;
Als Sicherung kann man im Programm nochmals die Standardwerte vorhalten, beim Lesen auf 0xFF prüfen und gegebenenfalls einen Standardwert nutzen.&lt;br /&gt;
&lt;br /&gt;
=== Direkter Zugriff auf EEPROM-Adressen ===&lt;br /&gt;
&lt;br /&gt;
Will man direkt auf bestimmte EEPROM Adressen zugreifen, dann sind folgende Funktionen hilfreich, um sich die Typecasts zu ersparen:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// Byte aus dem EEPROM lesen&lt;br /&gt;
uint8_t EEPReadByte(uint16_t addr)&lt;br /&gt;
{&lt;br /&gt;
  return eeprom_read_byte((uint8_t *)addr);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Byte in das EEPROM schreiben&lt;br /&gt;
void EEPWriteByte(uint16_t addr, uint8_t val)&lt;br /&gt;
{&lt;br /&gt;
  eeprom_write_byte((uint8_t *)addr, val);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
oder als Makro:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#define   EEPReadByte(addr)         eeprom_read_byte((uint8_t *)addr)     &lt;br /&gt;
#define   EEPWriteByte(addr, val)   eeprom_write_byte((uint8_t *)addr, val)&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Verwendung:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
EEPWriteByte(0x20, 128);   // Byte an die Adresse 0x20 schreiben&lt;br /&gt;
...&lt;br /&gt;
Val=EEPReadByte(0x20);     // EEPROM-Wert von Adresse 0x20 lesen&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Bekannte Probleme bei den EEPROM-Funktionen ===&lt;br /&gt;
&lt;br /&gt;
Vorsicht: Bei alten Versionen der avr-libc wurden nicht alle AVR Controller  unterstützt. Z.B. bei der avr-libc Version 1.2.3 insbesondere bei AVRs &amp;quot;der neuen Generation&amp;quot; (ATmega48/88/168/169) funktionieren die Funktionen nicht korrekt (Ursache: unterschiedliche Speicheradressen der EEPROM-Register). In neueren Versionen (z.&amp;amp;nbsp;B. avr-libc 1.4.3 aus WinAVR 20050125) wurde die Zahl der unterstüzten Controller deutlich erweitert und eine Methode zur leichten Anpassung an zukünftige Controller eingeführt.&lt;br /&gt;
&lt;br /&gt;
In jedem Datenblatt zu AVR-Controllern mit EEPROM sind kurze Beispielecodes für den Schreib- und Lesezugriff enthalten. Will oder kann man nicht auf die neue Version aktualisieren, kann der dort gezeigte Code auch mit dem avr-gcc (ohne avr-libc/eeprom.h) genutzt werden (&amp;quot;copy/paste&amp;quot;, gegebenfalls Schutz vor Unterbrechnung/Interrupt ergänzen &#039;&#039;uint8_t sreg; sreg=SREG; cli(); [EEPROM-Code] ; SREG=sreg; return;&#039;&#039;, siehe Abschnitt Interrupts). Im Zweifel hilft ein Blick in den vom Compiler erzeugten Assembler-Code (lst/lss-Dateien).&lt;br /&gt;
&lt;br /&gt;
* siehe auch: [http://www.nongnu.org/avr-libc/user-manual/index.html Dokumentation der avr-libc] Abschnitt Modules/EEPROM handling&lt;br /&gt;
&lt;br /&gt;
=== EEPROM Register ===&lt;br /&gt;
Um das EEPROM anzusteuern, sind drei Register von Bedeutung:&lt;br /&gt;
;EEAR: Hier werden die Adressen eingetragen zum Schreiben oder Lesen. Dieses Register unterteilt sich nochmal in EEARH und EEARL, da in einem 8-Bit-Register keine 512 Adressen adressiert werden können.&lt;br /&gt;
;EEDR: Hier werden die Daten eingetragen, die geschrieben werden sollen, bzw. es enthält die gelesenen Daten.&lt;br /&gt;
;EECR: Ist das Kontrollregister für das EEPROM&lt;br /&gt;
&lt;br /&gt;
Das EECR steuert den Zugriff auf das EEPROM und ist wie folgt aufgebaut:&lt;br /&gt;
&lt;br /&gt;
:{| class=&amp;quot;wikitable&amp;quot; style=&amp;quot;text-align:center&amp;quot;&lt;br /&gt;
|+ &#039;&#039;&#039;Aufbau des EECR-Registers&#039;&#039;&#039;&lt;br /&gt;
|-&lt;br /&gt;
!Bit&lt;br /&gt;
| 7 || 6 || 5 || 4 || 3 || 2 || 1 || 0&lt;br /&gt;
|-&lt;br /&gt;
! Name&lt;br /&gt;
| - || - || - ||- || EERIE || EEMWE || EEWE || EERE&lt;br /&gt;
|-&lt;br /&gt;
! Read/Write&lt;br /&gt;
| R || R || R || R || R/W || R/W || R/W || R/W&lt;br /&gt;
|-&lt;br /&gt;
!Init Value&lt;br /&gt;
| 0 || 0 || 0 || 0 || 0 || 0 || 0 || 0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Bedeutung der Bits&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
;Bit 4-7: nicht belegt&lt;br /&gt;
&lt;br /&gt;
;Bit 3 (EERIE): &#039;&#039;EEPROM Ready Interrupt Enable&#039;&#039;: Wenn das Bit gesetzt ist und globale Interrupts erlaubt sind in Register SREG (Bit 7), wird ein Interrupt ausgelöst nach Beendigung des Schreibzyklus (EEPROM Ready Interrupt). Ist einer der beiden Bits 0, wird kein Interrupt ausgelöst.&lt;br /&gt;
&lt;br /&gt;
;Bit 2 EEMWE): &#039;&#039;EEPROM Master Write Enable&#039;&#039;: Dieses Bit bestimmt, dass, wenn EEWE = 1 gesetzt wird (innerhalb von 4 Taktzyklen), das EEPROM beschrieben wird mit den Daten in EEDR bei Adresse EEAR. Wenn EEMWE = 0 ist und EEWE = 1 gesetzt wird, hat das keine Auswirkungen. Der Schreibvorgang wird dann nicht ausgelöst. Nach 4 Taktzyklen wird das Bit EEMWE automatisch wieder auf 0 gesetzt. Dieses Bit löst den Schreibvorgang nicht aus, es dient sozusagen als Sicherungsbit für EEWE.&lt;br /&gt;
&lt;br /&gt;
;Bit 1 (EEWE): &#039;&#039;EEPROM Write Enable&#039;&#039;: Dieses Bit löst den Schreibvorgang aus, wenn es auf 1 gesetzt wird, sofern vorher EEMWE gesetzt wurde und seitdem nicht mehr als 4 Taktzyklen vergangen sind. Wenn der Schreibvorgang abgeschlossen ist, wird dieses Bit automatisch wieder auf 0 gesetzt und, sofern EERIE gesetzt ist, ein Interrupt ausgelöst. Ein Schreibvorgang sieht typischerweise wie folgt aus:&lt;br /&gt;
:# EEPROM-Bereitschaft abwarten (EEWE=0) &lt;br /&gt;
:# Adresse übergeben an EEAR&lt;br /&gt;
:# Daten übergeben an EEDR&lt;br /&gt;
:# Schreibvorgang auslösen in EECR mit Bit EEMWE=1 und EEWE=1&lt;br /&gt;
:# (Optional) Warten, bis Schreibvorgang abgeschlossen ist&lt;br /&gt;
&lt;br /&gt;
;Bit 0 EERE: &#039;&#039;EEPROM Read Enable&#039;&#039;: Wird dieses Bit auf 1 gesetzt wird das EEPROM an der Adresse in EEAR ausgelesen und die Daten in EEDR gespeichert. Das EEPROM kann nicht ausgelesen werden, wenn bereits eine Schreiboperation gestartet wurde. Es ist daher zu empfehlen, die Bereitschaft vorher zu prüfen. Das EEPROM ist lesebereit, wenn das Bit EEWE=0 ist. Ist der Lesevorgang abgeschlossen, wird das Bit wieder auf 0 gesetzt, und das EEPROM ist für neue Lese- und Schreibbefehle wieder bereit. Ein typischer Lesevorgang kann wie folgt aufgebaut sein:&lt;br /&gt;
:# Bereitschaft zum Lesen prüfen (EEWE=0)&lt;br /&gt;
:# Adresse übergeben an EEAR&lt;br /&gt;
:# Lesezyklus auslösen mit EERE = 1&lt;br /&gt;
:# Warten, bis Lesevorgang abgeschlossen EERE = 0&lt;br /&gt;
:# Daten abholen aus EEDR&lt;br /&gt;
&lt;br /&gt;
= Die Nutzung von sprintf und printf =&lt;br /&gt;
&lt;br /&gt;
Um komfortabel, d.h. formatiert, Ausgaben auf ein Display oder die serielle Schnittstelle zu tätigen, bieten sich &#039;&#039;&#039;sprintf&#039;&#039;&#039; oder &#039;&#039;&#039;printf&#039;&#039;&#039; an. Alle *printf-Varianten sind jedoch ziemlich speicherintensiv und der Einsatz in einem Mikrocontroller mit knappem Speicher muss sorgsam abgewogen werden.&lt;br /&gt;
&lt;br /&gt;
Bei &#039;&#039;&#039;sprintf&#039;&#039;&#039; wird die Ausgabe zunächst in einem Puffer vorbereitet und anschließend mit einfachen Funktionen zeichenweise ausgegeben. Es liegt in der Verantwortung des Programmierers, genügend Platz im Puffer für die erwarteten Zeichen bereitzuhalten.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdint.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
// ...&lt;br /&gt;
// nicht dargestellt: Implementierung von uart_puts (vgl. Abschnitt UART)&lt;br /&gt;
// ...&lt;br /&gt;
&lt;br /&gt;
uint16_t counter;&lt;br /&gt;
&lt;br /&gt;
// Ausgabe eines unsigned Integerwertes&lt;br /&gt;
void uart_puti( uint16_t value )&lt;br /&gt;
{&lt;br /&gt;
    uint8_t puffer[20];&lt;br /&gt;
&lt;br /&gt;
    sprintf( puffer, &amp;quot;Zählerstand: %u&amp;quot;, value );&lt;br /&gt;
    uart_puts( puffer );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main()&lt;br /&gt;
{&lt;br /&gt;
  counter = 5;&lt;br /&gt;
&lt;br /&gt;
  uart_puti( counter );&lt;br /&gt;
  uart_puti( 42 );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Eine weitere elegante Möglichkeit besteht darin, den STREAM stdout (Standardausgabe) auf eine eigene Ausgabefunktion umzuleiten. Dazu wird dem Ausgabemechanismus der C-Bibliothek eine neue Ausgabefunktion bekannt gemacht, deren Aufgabe es ist, ein einzelnes Zeichen auszugeben. Wohin die Ausgabe dann tatsächlich stattfindet, ist Sache der Ausgabefunktion. Im Beispiel unten wird auf UART ausgegeben. Alle anderen, höheren Funktionen wie z.&amp;amp;nbsp;B. &#039;&#039;&#039;printf&#039;&#039;&#039;, greifen letztendlich auf diese primitive Ausgabefunktion zurück. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;c&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
void uart_init(void);&lt;br /&gt;
&lt;br /&gt;
// a. Deklaration der primitiven Ausgabefunktion&lt;br /&gt;
int uart_putchar(char c, FILE *stream);&lt;br /&gt;
&lt;br /&gt;
// b. Umleiten der Standardausgabe stdout (Teil 1)&lt;br /&gt;
static FILE mystdout = FDEV_SETUP_STREAM( uart_putchar, NULL, _FDEV_SETUP_WRITE );&lt;br /&gt;
&lt;br /&gt;
// c. Definition der Ausgabefunktion&lt;br /&gt;
int uart_putchar( char c, FILE *stream )&lt;br /&gt;
{&lt;br /&gt;
    if( c == &#039;\n&#039; )&lt;br /&gt;
        uart_putchar( &#039;\r&#039;, stream );&lt;br /&gt;
&lt;br /&gt;
    loop_until_bit_is_set( UCSRA, UDRE );&lt;br /&gt;
    UDR = c;&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void uart_init(void)&lt;br /&gt;
{&lt;br /&gt;
    /* hier µC spezifischen Code zur Initialisierung */&lt;br /&gt;
    /* des UART einfügen... s.o. im AVR-GCC-Tutorial */&lt;br /&gt;
&lt;br /&gt;
    // Beispiel: &lt;br /&gt;
    //&lt;br /&gt;
    // myAVR Board 1.5 mit externem Quarz Q1 3,6864 MHz&lt;br /&gt;
    // 9600 Baud 8N1&lt;br /&gt;
&lt;br /&gt;
#ifndef F_CPU&lt;br /&gt;
#define F_CPU 3686400&lt;br /&gt;
#endif&lt;br /&gt;
#define UART_BAUD_RATE 9600&lt;br /&gt;
&lt;br /&gt;
// Hilfsmakro zur UBRR-Berechnung (&amp;quot;Formel&amp;quot; laut Datenblatt)&lt;br /&gt;
#define UART_UBRR_CALC(BAUD_,FREQ_) ((FREQ_)/((BAUD_)*16L)-1)&lt;br /&gt;
&lt;br /&gt;
    UCSRB |= (1&amp;lt;&amp;lt;TXEN) | (1&amp;lt;&amp;lt;RXEN);    // UART TX und RX einschalten&lt;br /&gt;
    UCSRC |= (1&amp;lt;&amp;lt;URSEL)|(3&amp;lt;&amp;lt;UCSZ0);    // Asynchron 8N1 &lt;br /&gt;
 &lt;br /&gt;
    UBRRH = (uint8_t)( UART_UBRR_CALC( UART_BAUD_RATE, F_CPU ) &amp;gt;&amp;gt; 8 );&lt;br /&gt;
    UBRRL = (uint8_t)UART_UBRR_CALC( UART_BAUD_RATE, F_CPU );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
    int16_t antwort = 42;&lt;br /&gt;
    uart_init();&lt;br /&gt;
&lt;br /&gt;
    // b. Umleiten der Standardausgabe stdout (Teil 2)&lt;br /&gt;
    stdout = &amp;amp;mystdout;&lt;br /&gt;
&lt;br /&gt;
    // Anwendung&lt;br /&gt;
    printf( &amp;quot;Die Antwort ist %d.\n&amp;quot;, antwort );&lt;br /&gt;
    return 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// Quelle: avr-libc-user-manual-1.4.3.pdf, S.74&lt;br /&gt;
//         + Ergänzungen&lt;br /&gt;
&amp;lt;/c&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Sollen Fließkommazahlen ausgegeben werden, muss im Makefile eine andere (größere) Version der [[FAQ#Aktivieren_der_Floating_Point_Version_von_sprintf_beim_WinAVR_mit_AVR-Studio|printflib]] eingebunden werden.&lt;br /&gt;
&lt;br /&gt;
= Anhang =&lt;br /&gt;
&lt;br /&gt;
== Externe Referenzspannung des internen Analog-Digital-Wandlers ==&lt;br /&gt;
&lt;br /&gt;
Die minimale (externe) Referenzspannung des ADC darf nicht beliebig niedrig sein, vgl. dazu das (aktuellste) Datenblatt des verwendeten Controllers. z.&amp;amp;nbsp;B. beim ATMEGA8 darf sie laut Datenblatt (S.245, Tabelle 103, Zeile &amp;quot;VREF&amp;quot;) 2,0V nicht unterschreiten. HINWEIS: diese Information findet sich erst in der letzten Revision (Rev. 2486O-10/04) des Datenblatts.&lt;br /&gt;
&lt;br /&gt;
Meiner &amp;lt;!-- Wer? - es gibt inzwischen x Leute die mehr oder weniger viel in diesem Artikel geschrieben haben --&amp;gt; eigenen Erfahrung nach kann man aber (auf eigene Gefahr und natürlich nicht für Seriengeräte) durchaus noch ein klein wenig weiter heruntergehen, bei dem von mir unter die Lupe genommenen ATMEGA8L (also die Low-Voltage-Variante) funktioniert der ADC bei 5V Betriebsspannung mit bis zu VREF=1,15V hinunter korrekt, ab 1,1V und darunter digitalisiert er jedoch nur noch Blödsinn). Ich würde sicherheitshalber nicht unter 1,5V gehen und bei niedrigeren Betriebsspannungen mag sich die Untergrenze für VREF am Pin AREF ggf. nach oben&#039;&#039;&#039;(!)&#039;&#039;&#039; verschieben.&lt;br /&gt;
&lt;br /&gt;
In der letzten Revision des Datenblatts ist außerdem korrigiert, dass ADC4 und ADC5 sehr wohl 10 Bit Genauigkeit bieten (und nicht bloß 8 Bit, wie in älteren Revisionen irrtümlich angegeben.)&lt;br /&gt;
&lt;br /&gt;
= Anmerkungen =&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= TODO =&lt;br /&gt;
* Aktualisierung Register- und Bitbeschreibungen an aktuelle AVR&lt;br /&gt;
* stdio.h, malloc() &lt;br /&gt;
* &amp;quot;naked&amp;quot;-Funktionen&lt;br /&gt;
* Übersicht zu den C bzw. GCC-predefined Makros (__DATE__, __TIME__,...)&lt;br /&gt;
* Bootloader =&amp;gt; erl. [[AVR Bootloader in C - eine einfache Anleitung]]&lt;br /&gt;
* [http://myweb.msoe.edu/~barnicks/courses/CE-2800/documents/Mixing%20C%20and%20assembly%20language%20programs.pdf Mixing C and assembly language programs] Copyright © 2007 William Barnekow (PDF).&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:avr-gcc Tutorial| ]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Kategorie:AVR-Boards&amp;diff=62733</id>
		<title>Kategorie:AVR-Boards</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Kategorie:AVR-Boards&amp;diff=62733"/>
		<updated>2011-12-24T12:57:00Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: Schützte „Kategorie:AVR-Boards“: Weblink-Spam ([edit=autoconfirmed] (bis 24. März 2012, 12:57 Uhr (UTC)) [move=autoconfirmed] (bis 24. März 2012, 12:57 Uhr (UTC)))&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In dieser Kategorie findest Du selbst entwickelte AVR-Entwicklungsboards und Beschreibungen zu käuflichen AVR-Entwicklungs-Kits.&lt;br /&gt;
&lt;br /&gt;
Siehe dazu auch [[:Kategorie:AVR-Programmer und -Bootloader]]&lt;br /&gt;
&lt;br /&gt;
[[Category:AVR]]&lt;br /&gt;
[[Category:Boards]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Port-Expander_PCF8574&amp;diff=62617</id>
		<title>Port-Expander PCF8574</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Port-Expander_PCF8574&amp;diff=62617"/>
		<updated>2011-12-20T21:34:21Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: Änderungen von 193.36.189.20 (Diskussion) rückgängig gemacht und letzte Version von Andreas wiederhergestellt&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;Autor: Alexander Starke&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=Einleitung=&lt;br /&gt;
&lt;br /&gt;
Einen weiteren nützlichen Baustein am [[I2C]]-Bus stellen Port-Expander dar. Wer schon einmal unter &amp;quot;chronischem Pinmangel&amp;quot; in einer seiner Applikationen gelitten hat, weiss was ich meine.&lt;br /&gt;
&lt;br /&gt;
Meine Wahl ist hier auf den PCF8574 gefallen, einen 8-Bit I/O Expander. Auch in diesem Abschnitt gilt analog zu den anderen über I2C-Bausteine: Falls ihr noch nie etwas mit dem I2C gemacht habt, dann lest euch bitte zuerst die entsprechende Rubrik durch. Danach wird das Verstehen wesentlich einfacher fallen.&lt;br /&gt;
&lt;br /&gt;
=Funktion=&lt;br /&gt;
&lt;br /&gt;
Die Funktionsweise ist schnell beschrieben: Ein seriell an den Baustein gesendeter Wert wird auf dessen Pins parallel ausgegeben. Es gibt drei Adresspins (A0:2), an welchen man die Adresse in Hardware einstellen kann (Pins jeweils auf Masse bzw. Vcc legen). Es können also maximal 2^3 = 8 Bausteine vom Typ PCF8574 und maximal 2^3 = 8 Bausteine vom Typ PCF8574A direkt am Bus betrieben werden. Will man mehr ICs anschliessen ist ein I2C-Multiplexer notwendig (z.&amp;amp;nbsp;B. PCA9544A).&lt;br /&gt;
&lt;br /&gt;
http://www.mikrocontroller.net/mc-project/Pages/Projekte/ICs/Port%20Expander/expander-pins.gif&lt;br /&gt;
&lt;br /&gt;
An den Pins P0:7 kann ein 8 Bit Wert ausgegeben bzw. eingelesen werden. SDA und SCL dienen der Kommunikation über den I²C-Bus. /INT dient dazu, eingehende Daten an den Pins des Bausteins zu signalisieren. Man kann diesen Pin direkt an einen der Pins (externe Interrupts: INT0, INT1) des Mikrocontrollers legen. Da der Expander mit einem Open-Drain Ausgang daher kommt, muss ein Pull-Up gegen Betriebsspannung geschaltet werden. So kann der PCF8574 dem Mikrocontroller ohne den Umweg über den I2C übermitteln, dass sich die Eingangssignale geändert haben. Man kann ihn natürlich auch einfach offen lassen. Die Pins P0:7 können bis zu 25mA aufnehmen, aber nur gegen GND! Denn es handelt sich um [[Ausgangsstufen Logik-ICs|Open Collektor Ausgänge]]. Ausgeben können die IOs nur ca. 100µA über den interen Pull-Up Widerstand (welcher genaugenommen eine [[Konstantstromquelle]] ist). Kurzzeitig kann dieser Pull-Up 1mA liefern, wenn ein Ausgang von LOW auf HIGH schaltet, das verkürzt die Umschaltzeit wesentlich. Der gesamt aufgenommene Strom sollte 200mA nicht überschreiten.&lt;br /&gt;
&lt;br /&gt;
=I²C Kommunikation=&lt;br /&gt;
&lt;br /&gt;
Gestartet wird die Kommunikation durch das Senden der Start-Bedingung gefolgt vom Adressbyte.&lt;br /&gt;
&lt;br /&gt;
Das Adressbyte für den PCF8574:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Bit 7 || Bit 6 || Bit 5 || Bit 4 || Bit 3 || Bit 2 || Bit 1 || Bit 0 || Hexadezimal&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; |  0 &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1 &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0 &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0 &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | A2 &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | A1 &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | A0 &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | R/W &lt;br /&gt;
|| 0x40 + A[2:0]*2 + R/W&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Das Adressbyte für den PCF8574&#039;&#039;&#039;A&#039;&#039;&#039;:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Bit 7 || Bit 6 || Bit 5 || Bit 4 || Bit 3 || Bit 2 || Bit 1 || Bit 0 || Hexadezimal&lt;br /&gt;
|-&lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 0 &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1 &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1 &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | 1 &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | A2 &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | A1 &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | A0 &lt;br /&gt;
| align=&amp;quot;center&amp;quot; | R/W &lt;br /&gt;
|| 0x70 + A[2:0]*2 + R/W&lt;br /&gt;
|}&lt;br /&gt;
Der Adresse (4Bit für die eindeutige Kennung + 3 frei wählbare Bits) folgt das obligatorische R/W-Bit, welches festlegt, ob ein Lese- oder Schreibzugriff ausgeführt werden soll (R/W=0 Schreiben, R/W=1 Lesen).&lt;br /&gt;
&lt;br /&gt;
Wurde ein ACK empfangen, d.h. hat sich ein Slave angesprochen gefühlt, so kann man nun ein Datenbyte senden (R/W=0) oder den Status der Eingänge einlesen (R/W=1), also ein Datenbyte empfangen. Wurde ein Byte gesendet, so bestätigt der Baustein dieses mit ACK. Der Anwender kann nun festlegen, ob er das nächste Byte senden möchte oder ein STOP senden. Wurde ein Byte gelesen, so hat der Master dieses per ACK zu bestätigen, so er denn gleich das nächste empfangen möchte. Ansonsten kann hier das ACK entfallen und ein STOP gesendet werden.&lt;br /&gt;
&lt;br /&gt;
Stellt sich nur noch die Frage: Wie regelt man nun, ob ein Pin als Ein- oder Ausgang arbeiten soll? Soviel gleich vorweg: So etwas wie die Datenrichtungsregister des [[AVR]]s gibt es hier nicht, man muss ohne sie auskommen. Den Ausgangspegel der Pins definiert man über einen Schreibzugriff. Sendet man beispielsweise nach der Adresse gefolgt vom ACK des Bausteins 0xF0, so bedeutet das, dass P0:3 nun L-Pegel haben und P4:7 H-Pegel. Will man einige IOs als Eingänge verwenden, muss man die entsprechenden Ausgänge zunächst auf H-Pegel setzen, da es sich um [[Ausgangsstufen Logik-ICs|Open Collektor Ausgänge]] handelt sind die Ausgänge somit inaktiv. Führt man nun einen Lesezugriff durch, so stehen im gelesenen Byte die Pegel der Pins.&lt;br /&gt;
&lt;br /&gt;
=Anwendung=&lt;br /&gt;
&lt;br /&gt;
Im nachfolgenden Bild sind verschiedene Anwendungen der IOs dargestellt.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PCF8574.png|640px]]&lt;br /&gt;
&lt;br /&gt;
* P0..P3 - Ausgänge für LEDs: Die LEDS sind mit ihrer Anode über einen Vorwiderstand gegen VCC verdrahtet. Eine LED wird eingeschaltet, indem der jeweilige Ausgang auf LOW gesetzt wird (LOW aktive). Es ist &amp;lt;B&amp;gt;NICHT&amp;lt;/B&amp;gt; möglich, die LEDs mit ihrer Kathode gegen GND zu verdrahten, da die Ausgänge vom Typ [[Ausgangsstufen_Logik-ICs#Open_Collector| Open Collector]] sind und nur bei LOW große Ströme schalten können.&lt;br /&gt;
* P4 - Ausgänge für ULN2003 &amp;amp; Co: Hier wird bei HIGH doch schon richtig Strom gebraucht (ca. 1mA). Das kann der IC nicht selber liefern (typisch ca. 100µA). Deshalb wird hier ein relativ niederohmiger Pull-Up Widerstand benötigt.&lt;br /&gt;
* P5 - Ausgänge für Logikbausteine: Nichts besonderes.&lt;br /&gt;
* P6 - Eingänge für Logikbausteine: Der Logikbaustein muss bei LOW bis zu 300µA Strom liefern können, da die internen Pull-Up Widerstände darauf dimensioniert sind und man sie nicht abschalten kann.&lt;br /&gt;
* P7 - Eingänge für Taster: Die internen Pull-up Widerstände sind hier nützlich.&lt;br /&gt;
&lt;br /&gt;
=Software=&lt;br /&gt;
&lt;br /&gt;
Routinen zum Ansteuern des Baustein können hier herunter geladen werden:&lt;br /&gt;
* [http://www.mikrocontroller.net/mc-project/Pages/Projekte/ICs/Port%20Expander/Portexpander%20Beispiel.zip Portexpander Beispiel.zip]&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Anwendung soll ein solcher Expander bei mir natürlich auch finden. Am meisten hat mich beim Anschluss von LCDs immer deren Pin-Hunger im 4-Bit-Modus gestört. Samt der Steuereingänge kostet einen das 7 Pins. Da ein LCD selten viel zu tun hat, sollte die Verwendung eines solchen Bausteines kein Problem darstellen. Um nicht wieder bei Null anzufangen, werde ich einfach die oben erwähnten Low-Level-Routinen in die vielfach bewährte LCD-Bibliothek von Peter Pfleury einbinden. Allerdings hat dieses kleine Projekt momentan noch den Status ToDo.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
[[Category:Mc-project.de]]&lt;br /&gt;
[[Kategorie:Portexpander]]&lt;br /&gt;
[[Kategorie:I2C]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Elektronikversender&amp;diff=62289</id>
		<title>Elektronikversender</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Elektronikversender&amp;diff=62289"/>
		<updated>2011-12-08T19:06:59Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* Elektronikladen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Die Vor- und Nachteile von verschiedenen Elektronik-Versand-Händlern werden relativ häufig im Forum diskutiert. Diese Diskussionen führen nicht selten zu weitestgehend gleichen Ergebnissen. In diesem Artikel sollen daher die Argumente, die für oder gegen einen bestimmten Elektronik-Versender sprechen, zusammengetragen werden. Sobald diese Liste einigermaßen vollständig ist, würde dies sicher einige Diskussions-Threads und/oder Flame-Wars überflüssig machen.&lt;br /&gt;
&lt;br /&gt;
Diese Liste erhebt keinerlei Anspruch auf Vollständigkeit, d.h. wenn ihr einen Versender kennt, der hier noch nicht aufgeführt ist, dann nennt wenigstens die URL und den Namen. Den Rest können auch andere besorgen, die den Versender ebenfalls kennen!&lt;br /&gt;
&lt;br /&gt;
Bitte ergänzt nur allgemeine Sachen (z.&amp;amp;nbsp;B. &amp;quot;liefert immer vollständig&amp;quot;, &amp;quot;günstig&amp;quot; oder &amp;quot;große Auswahl&amp;quot;), aber nicht Sachen wie &amp;quot;mein ATMega 128 hatte verbogene Beine&amp;quot;! Bitte auch die alphabetische Sortierung beibehalten!&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Diese Seite kann nur von angemeldeten Benutzern bearbeitet werden!&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Liste der Versender ==&lt;br /&gt;
&lt;br /&gt;
=== Amidon ===&lt;br /&gt;
Homepage: http://www.amidon.de&lt;br /&gt;
&lt;br /&gt;
* Sehr großes Sortiment, vorallem für seltene Bauteile, z.&amp;amp;nbsp;B. Dioden&lt;br /&gt;
&lt;br /&gt;
=== AATiS ===&lt;br /&gt;
Homepage: http://www.aatis.de&lt;br /&gt;
&lt;br /&gt;
* Arbeitskreis Amateurfunk und Technik in der Schule e.V.&lt;br /&gt;
* Bausätze speziell auch für Elektronik-Anfänger, Schüler&lt;br /&gt;
* Literatur, Seminare für Lehrer &lt;br /&gt;
&lt;br /&gt;
=== Actron ===&lt;br /&gt;
Homepage: http://www.actron.de&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;kein&#039;&#039;&#039; Online-Shop!&lt;br /&gt;
* alphanumerische LCDs und Graphikdisplays in großer Auswahl, auch mit Touchscreens&lt;br /&gt;
* für gewerbliche Kunden: etwas verhandeln schadet nie&lt;br /&gt;
* bei kleinen Stückzahlen nicht ganz billig&lt;br /&gt;
* liefern sehr schnell und stets zuverlässig&lt;br /&gt;
&lt;br /&gt;
=== Adapterprofi ===&lt;br /&gt;
Homepage: http://www.adapterprofi.de&lt;br /&gt;
&lt;br /&gt;
* Bauteile, Gehäuse, Netzteile&lt;br /&gt;
* Viele unterschiedliche HF-Adapter&lt;br /&gt;
&lt;br /&gt;
=== AK Modul Bus Computer GmbH ===&lt;br /&gt;
Homepage: http://www.ak-modul-bus.com/stat/produkte.html&lt;br /&gt;
&lt;br /&gt;
* Interfaces, Messmodule, Funktionsmodelle, Experimentiersysteme&lt;br /&gt;
* Entwicklungssysteme, Baugruppen, Elektor, Zubehör, Bauelemente&lt;br /&gt;
* Software, Lernpakete, Bücher, Sonderposten&lt;br /&gt;
&lt;br /&gt;
=== Allpax ===&lt;br /&gt;
Homepage: http://www.allpax.de&lt;br /&gt;
&lt;br /&gt;
* Liefert auch an Privathaushalte&lt;br /&gt;
* Keine Elektronik an sich, aber ggf. nützliches Zubehör: Größeres, übersichtliches Sortiment an ESD-Beuteln und -Folien, offen und mit Zippverschluss, Pink Poly und Metallisiert (High Shield). Preislich über Farnell, dafür findet man sofort, was man sucht...&lt;br /&gt;
* außerdem Ultraschallreiniger, Waagen und Folienschweißgeräte, sowie viel Fachfremdes&lt;br /&gt;
* Versandkosten: 8,33€ nach Deutschland, diverse EU-Länder 17,85€, Schweiz 34,51€; Versandkostenfrei in D ab 178,50€&lt;br /&gt;
* Gewährt scheinbar auch Privatkunden die Zahlung per Rechnung; bei Bankeinzug 2% Rabatt, bei Vorkasse und Abholung 3%&lt;br /&gt;
&lt;br /&gt;
=== AME-Engineering ===&lt;br /&gt;
Homepage: http://www.ame-engineering.de&lt;br /&gt;
&lt;br /&gt;
* Hochfrequenz-Spezialitäten, Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Andy&#039;s Funkladen ===&lt;br /&gt;
Homepage: http://www.andyfunk.de&lt;br /&gt;
&lt;br /&gt;
* Alles für Amateur- und CB-Funk&lt;br /&gt;
* Bauteile und Gehäuse&lt;br /&gt;
&lt;br /&gt;
=== Atlantis Shop 24 ===&lt;br /&gt;
Homepage: http://www.atlantis-shop24.de&lt;br /&gt;
&lt;br /&gt;
* Elektronik nur ein kleiner Teil des Angebotes. Ansonsten eher Drogerie bzw. Haushaltsbedarf&lt;br /&gt;
&lt;br /&gt;
=== Atzert-Elektronik Versand ===&lt;br /&gt;
Homepage: http://www.atzert-elektronik.de&lt;br /&gt;
&lt;br /&gt;
Früher &#039;&#039;EFB-Electronic Versand&#039;&#039;, davor &#039;&#039;MEGAKICK Electronic Stores&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
* Mindestens schon der dritte Name und die dritte Webseite für den Endkunden-Versand von [[Elektronikversender#ETT|ETT]]. ETT liefert sonst nur an gewerbliche Kunden.&lt;br /&gt;
* Ladengeschäfte in Bielefeld, Braunschweig, Bremen, Hamburg und Berlin. &lt;br /&gt;
* Die Preise schwanken im Vergleich zu anderen Anbietern, welche ebenfalls ETT-importierte Produkte führen, mal nach oben, mal nach unten.&lt;br /&gt;
&lt;br /&gt;
=== Bassenberg Elektronik ===&lt;br /&gt;
Homepage: http://www.bassenberg.de&lt;br /&gt;
&lt;br /&gt;
* Ladengeschäfte in Braunschweig und Neumünster&lt;br /&gt;
* Beschafft auch nicht mehr gelistete und abgekündigte Bauteile&lt;br /&gt;
* Liefert auch an Privat&lt;br /&gt;
&lt;br /&gt;
=== Batronix ===&lt;br /&gt;
Homepage: http://www.batronix.com&lt;br /&gt;
* Grosses Sortiment an Geräten&lt;br /&gt;
* Bausätze für Microcontroller-Applikationen&lt;br /&gt;
* Liefert auch an Privat&lt;br /&gt;
&lt;br /&gt;
=== BAZ Spezialantennen ===&lt;br /&gt;
Homepage: http://www.spezialantennen.de&lt;br /&gt;
&lt;br /&gt;
* Antennen für Amateurfunk, ISM, WLAN usw.&lt;br /&gt;
&lt;br /&gt;
=== Bfi-Optilas ===&lt;br /&gt;
Homepage: http://www.bfioptilas.de&lt;br /&gt;
&lt;br /&gt;
* Kein Onlineshop&lt;br /&gt;
* spezialisierter Distributor für Hochfrequenzhalbleiter und Optik&lt;br /&gt;
&lt;br /&gt;
=== BG-Electronics.de ===&lt;br /&gt;
Homepage: http://www.bg-electronics.de&lt;br /&gt;
&lt;br /&gt;
* Online Shop für aktive und passive elektronische Bauelememte&lt;br /&gt;
* günstige Preise&lt;br /&gt;
* alle Artikel ab Lager lieferbar, daher kurze Wartezeiten&lt;br /&gt;
* weltweiter Versand&lt;br /&gt;
* zahlreiche Mengenrabatte&lt;br /&gt;
* viele Ersatzteile aus dem Audio-, CarHiFi und TV-Bereich&lt;br /&gt;
&lt;br /&gt;
=== B &amp;amp; M electronics ===&lt;br /&gt;
Homepage: http://www.bmelectronics.de&lt;br /&gt;
&lt;br /&gt;
* Bauteile, Platinen und Baugruppen für Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Box73 ===&lt;br /&gt;
Homepage: http://www.box73.de&lt;br /&gt;
&lt;br /&gt;
Onlineshop des Funkamateur.&lt;br /&gt;
&lt;br /&gt;
* Bauteile, Bausätze, Literatur aus dem Amateurfunkbereich&lt;br /&gt;
* Preise sind O.K.&lt;br /&gt;
* Bestellungen werden nur Di und Do bearbeitet&lt;br /&gt;
* Ab 50 EUR bei Bankeinzug portofrei.&lt;br /&gt;
&lt;br /&gt;
=== Bürklin OHG ===&lt;br /&gt;
Homepage: http://www.buerklin.com&lt;br /&gt;
&lt;br /&gt;
* große Auswahl, hohe Verfügbarkeit&lt;br /&gt;
* sehr schneller Versand&lt;br /&gt;
* Ladengeschäft in München&lt;br /&gt;
* &amp;lt;s&amp;gt;nur an gewerbliche Abnehmer (lt. AGB), private Abnehmer können dennoch im Ladengeschäft einkaufen&amp;lt;br&amp;gt;Angeblich versendet Bürklin seit November 2010 auch an Privatpersonen. Allerdings verlangt Bürklin weiterhin in Adressformularen die Eingabe eines Firmennamens &amp;lt;br&amp;gt;Geben Sie einen Wert in das Feld &amp;quot;Firma&amp;quot; ein.&amp;lt;br&amp;gt;Daher ist diese Information eher mit Vorsicht zu genießen.&amp;lt;/s&amp;gt;&amp;lt;br&amp;gt;Mittlerweile muss man auch keinen Firmennamen mehr eingeben. Die AGB wurde ebenfalls angepasst.&lt;br /&gt;
* 35 EUR Mindestbestellwert, darunter 7 EUR Bearbeitungskosten (incl. MWSt)&lt;br /&gt;
&lt;br /&gt;
=== CBsoft, s.r.o. (ltd.) ===&lt;br /&gt;
*Homepage: http://www.jjtubes.eu/&lt;br /&gt;
* Firma in der Slowakei&lt;br /&gt;
* Verkauft Röhren der Firma JJ&lt;br /&gt;
* englischsprachig&lt;br /&gt;
* Zahlungsmöglichkeiten in € mit Paypal und Kreditkarte&lt;br /&gt;
&lt;br /&gt;
=== chiptrade.com ===&lt;br /&gt;
Homepage: http://www.chiptrade.com&lt;br /&gt;
* kein Onlineshop!&lt;br /&gt;
* Produkte von: Trinamic Motion Control, Datasphere/BlueSerial, connectBlue, Tectus RFID, Korenix, CentiPad, eye2m und Televideo&lt;br /&gt;
&lt;br /&gt;
=== ConeleK Electronic ===&lt;br /&gt;
Homepage: http://www.conelek.com&lt;br /&gt;
&lt;br /&gt;
* Sehr kleines Bauteileangebot (Röhren, Röhrensockel)&lt;br /&gt;
* Elektronik-Laborbedarf, insbesondere Nachfüllpackungen mit Steckbrett-Drahtbrücken&lt;br /&gt;
* Werkzeug für Elektronik&lt;br /&gt;
* Stromversorgungen&lt;br /&gt;
* Versand an Privat&lt;br /&gt;
* Versandkosten bis 25kg, Vorkasse 5,90€ (Stand 04/2008)&lt;br /&gt;
&lt;br /&gt;
=== Conrad ===&lt;br /&gt;
Homepage: http://www.conrad.de und http://www.business.conrad.de&lt;br /&gt;
&lt;br /&gt;
* großes Angebot (für Bauteile den &amp;quot;Business&amp;quot;-Katalog beachten, der Hauptkatalog ist dahingehend etwas &amp;quot;dünn&amp;quot;) (Anm.: Bauteile, die nur im Business-Katalog aufgeführt sind, sind in Ladengeschäften nur über Sonderbestellung zu bekommen, d.h. dort in aller Regel nicht vorrätig.)&lt;br /&gt;
* Positiv: Wirklich jedes Bauteil kann einzeln gekauft werden und wird nicht in dämlichen Verpackungseinheiten verkauft, so wie es bei den meisten anderen Elektronik-Lieferanten der Fall ist. Dies ist vor Allem für den Prototypenbau sehr hilfreich.&lt;br /&gt;
* relativ teuer jedoch bis zu 10% Rabatt für Schulen (bei genügend Umsatz)&lt;br /&gt;
* 21 Ladengeschäfte in Deutschland, fünf in Österreich&lt;br /&gt;
* positiv: Bei Business-Kunden wird der Rechnungsbetrag erst nach 14 Tagen abgebucht.&lt;br /&gt;
* haben einen (teuren) 24 Std. Lieferservice für Notfälle - Conrad garantiert aber nicht 100%ig für die Einhaltung der 24 Stunden. Bei Nichteinhaltung gibt es kein Geld zurück.&lt;br /&gt;
* Verfügbarkeit in Filialen kann Online überprüft werden.&lt;br /&gt;
* Verfügbarkeit in Filialen kann über zentale Rufnummer erfragt werden. Abholung bestellter Ware in Filialen möglich, aber trotzdem gleiche Versandkosten.&lt;br /&gt;
&amp;lt;!-- &lt;br /&gt;
Vorerst Auskommentiert - Subjektiv/Einzelerfahrung, veraltete Informationen (Filialen)&lt;br /&gt;
* Mit jeder Bestellung erhält man zusätzlich Werbung von unseriösen Firmen, wo Gewinne versprochen werden und man sich in Wirklichkeit für irgendwelche Abos verpflichtet. Wenn man bei Conrad anruft und sie zur Rede stellt, erhält man die Antwort, dass diese Werbung anscheinend aus Versehen hineingerutscht ist. So ein Zufall.&lt;br /&gt;
* sehr kulant bei Umtäuschen&lt;br /&gt;
* versuchen bei Rückgaben einen Teil oder den gesamten Betrag einzubehalten (schon mehrfach vorgekommen)&lt;br /&gt;
* Schlampig verpackte Artikel. ICs sind nicht Antistatik-Konform verpackt.&lt;br /&gt;
* Die Filiale München / Tal hat keine Telefonnummer mehr in den Verzeichnissen, anscheinend sind Kundenanfragen dort zu &amp;quot;lästig&amp;quot;. (Kommentar: andere Filialen auch nicht, wird nur noch über eine Sammelnummer über ein Callcenter abgewickelt. Die Ladenbestellung wird dann vom Callcenter per eMail an die Filiale weitergeleitet.)&lt;br /&gt;
* die Ladengeschäfte haben nicht das gesamte Programm vor Ort, man kann jedoch in den Geschäften anrufen und die Verfügbarkeit anfragen, evtl. sogar Teile für ein paar Stunden &amp;quot;zurücklegen lassen&amp;quot; (von Geschäft zu Geschäft verschieden).&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== csd-electronics ===&lt;br /&gt;
Homepage: [http://www.csd-electronics.de csd-electronics.de]&lt;br /&gt;
&lt;br /&gt;
* ATMEL, ICs, Passive und Mechanische Bauteile, Platinen- und Lötzubehör, u.a.&lt;br /&gt;
* günstig&lt;br /&gt;
* Mengenrabatte für fast jedes Produkt&lt;br /&gt;
* Versand innerhalb Deutschlands pauschal 3,59€ (ab 100 EUR versandkostenfrei)&lt;br /&gt;
* Versand EU-weit ab 6,95 EUR&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* schnelle Lieferung, sofern die Artikel auf Lager sind, versandkostenfreie Nachlieferung&lt;br /&gt;
* Bauelemente, die nicht im Shop angeboten werden, können auf Anfrage beschafft werden.&lt;br /&gt;
* Zahlung bei Vorkasse(2% Skonto), Bankabbuchung, Kreditkarte, PayPal&lt;br /&gt;
* Ist man bereits Kunde, kann man &amp;quot;auf Rechnung&amp;quot; (Zahlung innerhalb von 21 Tagen) bestellen.&lt;br /&gt;
* haben ein Forum, in dem man sich zu Sammelbestellungen organisieren kann und auch allgemeine Fragen stellen kann -zur Zeit (05/2008) offline-&lt;br /&gt;
&lt;br /&gt;
=== dad24 ===&lt;br /&gt;
Homepage, Shop: http://dad24.eu&lt;br /&gt;
E-Bay Shop:     http://stores.ebay.de/Shop-dad24&lt;br /&gt;
&lt;br /&gt;
* Unterschiedliche Preise in den beiden Shops&lt;br /&gt;
* Kleiner, nicht sonderlich schöner Onlineshop (dad24.eu)&lt;br /&gt;
* Kleines Angebot. Lupenleuchten, Lötstationen, Labornetzgeräte, Messgeräte, etc. aus dem unteren Preissegment&lt;br /&gt;
* Jede Woche eine neue &amp;quot;Kategorie der Woche&amp;quot; auf dad24.eu. Produkte aus der Kategorie werden erst im Warenkorb mit einem Rabatt angezeigt, der auch gewährt wird.&lt;br /&gt;
&lt;br /&gt;
=== Darisus ===&lt;br /&gt;
Homepage: http://www.darisus.de&lt;br /&gt;
&lt;br /&gt;
* kompetente Beratung&lt;br /&gt;
* liefert sehr zuverlässig, in Notfällen auch Express&lt;br /&gt;
* Versand innerhalb Deutschlands ab 4,50 EUR&lt;br /&gt;
* Hat auch eine gute Auswahl an CPLDs und einige FPGAs diverser Hersteller&lt;br /&gt;
&lt;br /&gt;
=== DES - Der Elektroniker-Shop ===&lt;br /&gt;
Homepage: http://www.DerElektronikerShop.de&lt;br /&gt;
&lt;br /&gt;
* Bauteile&lt;br /&gt;
* Bauteilsätze der [http://www.DieElektronikerseite.de Elektronikerseite]&lt;br /&gt;
* Verkauf des BasicBeetle und Zubehör von [http://www.DieProjektseite.de der Projektseite]&lt;br /&gt;
* Ständig wachsendes Angebot&lt;br /&gt;
* Auch einige SMD-Bauteile verfügbar&lt;br /&gt;
* Kein Mindestbestellwert&lt;br /&gt;
* Versandkosten ab 3,50 EUR (Österreich/Europa ab 4,00 Eur)&lt;br /&gt;
* Versand auch nach Österreich (Europa auf Anfrage)&lt;br /&gt;
* Zahlung per Vorkasse&lt;br /&gt;
* Lieferzeit 1-3 Tage bei Verfügbarkeit&lt;br /&gt;
* PrePaid-Konto möglich&lt;br /&gt;
* Lieferungen auch an Privat&lt;br /&gt;
&lt;br /&gt;
=== Digi-Key ===&lt;br /&gt;
(tlw.) deutsche Homepage: http://de.digikey.com&lt;br /&gt;
&lt;br /&gt;
* optisch nicht besonders ansprechende, aber durchaus sehr funktionelle Website&lt;br /&gt;
* beheimatet in den USA, ein Logistikbüro gibt es in den Niederlanden&lt;br /&gt;
* kostenloser Versand ab 65&amp;amp;#8364;, darunter 18&amp;amp;#8364; Versandkosten&lt;br /&gt;
* macht merkwürdige Plausibilitäts-Checks: wenn man privat über ihrem Dollar Limit (z.B. 400 Dollar bestellt) kommt sofort die Rückfrage nach Firmenname und Firmenadresse&lt;br /&gt;
* Rückfragen nach dem Verwendungszweck kommen ebenfalls schon bei der Bestellung bei bestimmten Bauteilen die der Exportkontrolle unterliegen&lt;br /&gt;
* Versand direkt aus den USA, dafür sehr flott mit UPS Express (in rund zwei bis drei Tagen da)&lt;br /&gt;
* riesiges Angebot, gewissermaßen ein Distributor der auch Kleinmengen an Privatpersonen liefert, entscheidend ist, dass der Hersteller des Produkts geführt wird&lt;br /&gt;
* kein anderer Anbieter, bietet so viele verschiedene passive Bauteile in kleinen Stückzahlen, z.&amp;amp;nbsp;B. SMD Widerstände in Bauform 01005 bis 2512 meist in verschiedenen Toleranzklassen und von verschiedenen Herstellern&lt;br /&gt;
* alle Bauteile mit Herstellerangabe, Digikey kauft ausschließlich direkt vom Hersteller&lt;br /&gt;
* Preise sind auf der deutschen Website in Euro inklusive etwaigem Zoll angegeben, allerdings ohne Mehrwertsteuer, die korrekt abgerechnet wird (d.h. man zahlt bei Versand nach Österreich 20% Mwst., nach Deutschland m.W.n. 19%)&lt;br /&gt;
* Meistens deutlich teurer als Reichelt, doch häufig die beste Anlaufstelle für Privatkunden wenn es um Spezialbauteile geht, und der Hersteller sich im Programm von Digikey befindet&lt;br /&gt;
&amp;lt;!-- * wesentlich teurer als Reichelt, dafür jeder Artikel mit Herstellerangabe&lt;br /&gt;
=&amp;gt; &amp;quot;wesentlich&amp;quot; etwas zu pauschal (vgl. STK500 etc. selbst bei den verglw. hohen Versandkosten) - mt --&amp;gt;&lt;br /&gt;
* Zu beachten ist auch noch folgendes, um unliebsame zusatzkosten zu vermeiden: http://www.mikrocontroller.net/topic/90943#new. &#039;&#039;Anmerkung dazu: Digikey hat wohl zum 1.4.2011 den Versand umgestellt und importiert nun selbst. Zusatzkosten durch Verzollung sollten dann nicht mehr anfallen.&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
=== Display Electronics ===&lt;br /&gt;
&lt;br /&gt;
Homepage: http://www.distel.co.uk&lt;br /&gt;
&lt;br /&gt;
* In England&lt;br /&gt;
* Webseite = Augenkrebs &lt;br /&gt;
* Online-Shop versteckt hinter dem Search-Button auf der Homepage&lt;br /&gt;
* Restposten aller Art&lt;br /&gt;
* Mindestbestellwert 10 GBP&lt;br /&gt;
&lt;br /&gt;
=== eHaJo ===&lt;br /&gt;
Homepage: http://www.eHaJo.de&lt;br /&gt;
&lt;br /&gt;
* Bausätze &lt;br /&gt;
* Lötübungen&lt;br /&gt;
* AVR-ISP-Stick&lt;br /&gt;
&lt;br /&gt;
=== Eisch-Kafka-Electronic ===&lt;br /&gt;
Homepage: http://www.eisch-electronic.de&lt;br /&gt;
 &lt;br /&gt;
* Hochfrequenz Bausätze und Bauteile für Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== EleConT ===&lt;br /&gt;
Homepage: http://www.elecont.de/shop/&lt;br /&gt;
&lt;br /&gt;
* Carrierboards für gebräuchliche AVR&lt;br /&gt;
&lt;br /&gt;
=== Electropuces ===&lt;br /&gt;
Homepage: http://perso.wanadoo.fr/electropuces/&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte aus Nantes, Frankreich  (teilweise engl. Menü)&lt;br /&gt;
&lt;br /&gt;
=== Electronic Search ===&lt;br /&gt;
&lt;br /&gt;
Homepage: http://www.electronic-search.de&lt;br /&gt;
&lt;br /&gt;
* Keine Mindestbestellmenge&lt;br /&gt;
* Verkauf auch an Privat/Bastler&lt;br /&gt;
* Fast alle Preise im Online-Shop nur &amp;quot;auf Anfrage&amp;quot;, und nicht im Shop angegeben.&lt;br /&gt;
&lt;br /&gt;
=== electronicpool Rheinstetten ===&lt;br /&gt;
Homepage: http://www.electronicpool.de&lt;br /&gt;
&lt;br /&gt;
* abgekündigte oder schwer beschaffbare elektronische Bauteile&lt;br /&gt;
&lt;br /&gt;
=== Elektronikladen ===&lt;br /&gt;
Homepage: http://www.elektronikladen.de&lt;br /&gt;
&lt;br /&gt;
* Spezialist für Mikrokontroller&lt;br /&gt;
* Entwicklungssysteme, keine Einzelbauteile&lt;br /&gt;
* entsprechende Literatur und Software&lt;br /&gt;
* &amp;quot;Kein Verkauf an Endverbraucher i.S.d. §13 BGB&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Elektronik-Kompendium ===&lt;br /&gt;
Homepage: http://www.elektronik-kompendium.de&lt;br /&gt;
&lt;br /&gt;
* Bausätze diverser Schaltungen (mit Anleitung und Funktionsbeschreibung)&lt;br /&gt;
* erspart lästiges Suchen in anderen Shops&lt;br /&gt;
* kurze Lieferzeiten&lt;br /&gt;
* günstiger Versand&lt;br /&gt;
&lt;br /&gt;
=== Elk Tronic ===&lt;br /&gt;
Homepage: http://www.elk-tronic.de&lt;br /&gt;
&lt;br /&gt;
* kleines Lieferprogramm Adapterplatinen (SMD -&amp;gt; 2,54mm-Raster) und Programmieradapter&lt;br /&gt;
* günstige Preise und Versandspesen&lt;br /&gt;
&lt;br /&gt;
=== Ellmitron ===&lt;br /&gt;
Homepage: http://www.ellmitron.de/&lt;br /&gt;
Katalog: http://www.ellmitron.de/katalog.pdf&lt;br /&gt;
&lt;br /&gt;
Lehrmittel, Kleinbausätze vor allem für Schüler, Experimentierkästen&lt;br /&gt;
&lt;br /&gt;
=== Elpro Darmstadt ===&lt;br /&gt;
Homepage: http://www.elpro.org&lt;br /&gt;
&lt;br /&gt;
* Kein Mindestbestellwert, aber hohe Versandkosten für kleine Bestellungen. Stand September 2008:&lt;br /&gt;
** Bis 15€: 9,95€ Versandkosten&lt;br /&gt;
** Von €15 bis €75: 5,95€ Versandkosten&lt;br /&gt;
** Von €75 bis €200: 4,49€ Versandkosten&lt;br /&gt;
** Ab €200: Versandkostenfrei&lt;br /&gt;
* Große Auswahl an Mikrocontrollern&lt;br /&gt;
* Sehr große Auswahl an Schaltnetzteilen von Meanwell (geschlossen, offen, auf PCB lötbar, DIN-Schiene)&lt;br /&gt;
* Merkwürdig zu bedienende Shopsoftware, ständig klappt was auf und zu und wird irgendwas nachgeladen. Braucht JavaScript&lt;br /&gt;
* Keine AGBs online. Da Preisangaben ohne MwSt. richtet sich das Angebot vermutlich nicht an Endverbraucher (werden aber beliefert)&lt;br /&gt;
* Bearbeitungszeit (bis Warenausgang) 2-3 Tage.&lt;br /&gt;
* Versand bisher mit DHL&lt;br /&gt;
* gute bis sehr gute Verpackung&lt;br /&gt;
&lt;br /&gt;
=== Eltrix ===&lt;br /&gt;
Homepage: http://eltrix.de/Starteltrix.htm&lt;br /&gt;
&lt;br /&gt;
*  Verbrauchsmaterial, Tipps und Tricks fürs Leiterplattenherstellen und Löten&lt;br /&gt;
&lt;br /&gt;
=== ELV ===&lt;br /&gt;
Homepage: http://www.elv.de&lt;br /&gt;
&lt;br /&gt;
* nicht sehr große Auswahl an Einzelteilen&lt;br /&gt;
* riesiges Angebot an Zubehör für Hobbyisten&lt;br /&gt;
* viele z.T. pfiffige Eigenentwicklungen, Bausätze (auch zum Download auf der Website verfügbar)&lt;br /&gt;
* sonst Sortiment ähnlich Conrad, nicht billig&lt;br /&gt;
* im Allgemeinen nicht billig, merkwürdigerweise sind manche Artikel aber die günstigsten auf dem Markt&lt;br /&gt;
* mühsamer Onlinekatalog&lt;br /&gt;
* Immer mal wieder Fehllieferungen und Wartezeiten (zumindest in die Schweiz). Service erreichte in 3 Fällen nicht das inserierte Niveau.&lt;br /&gt;
* Versandkosten innerhalb Deutschland 4,5&amp;amp;#8364;, ab 150&amp;amp;#8364; Bestellwert versandkostenfrei&lt;br /&gt;
* nicht abwählbare Versandversicherung, die 0,85% des Bestellwertes kostet&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
Erklärte am 31. August 2010 &amp;quot;... den Betrieb bis auf weiteres zu schließen.&amp;quot; &lt;br /&gt;
=== Embedit Mikrocontrollertechnik ===&lt;br /&gt;
Online Shop: http://shop.embedit.de&lt;br /&gt;
&lt;br /&gt;
* Gute Auswahl an AVR Controllern, aber nur aktuelle Typen, keine AT90Sxxxx. Teilweise exotische Typen wie MLF Gehäuse&lt;br /&gt;
* Atmel und Philips SmartARM Controller&lt;br /&gt;
* Module und Boards mit AVR Controllern&lt;br /&gt;
* Zubehör von Atmel wie STK500 oder AVRISP mkII&lt;br /&gt;
* Diverse aktive und passive Elektronikteile, ständig neue Teile&lt;br /&gt;
* Mechanikteile wie Zahnräder, Steckverbinder usw.&lt;br /&gt;
* Lieferzeit 1-4 Tage, je nachdem wie man zahlt (hab aber auch schon ne Vorauskasse innerhalb eines Tages per Expressbrief bekommen, zuvorkommender Service)&lt;br /&gt;
* Versandkosten ab 3,95 &amp;amp;#8364;, versicherter Versand, Vorauskasse und Nachnahme&lt;br /&gt;
* Keine Versandkosten ab 50 &amp;amp;#8364; Warenwert innerhalb Deutschlands, bei Zahlung per Vorauskasse und Lieferung per Hermes&lt;br /&gt;
* Lieferung in viele EU-Länder&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== ETT - Electronic Toys Trading  ===&lt;br /&gt;
Homepage: http://www.ett-online.de&lt;br /&gt;
&lt;br /&gt;
* Großhandel nur für Gewerbekunden.&lt;br /&gt;
* Zweitshop [[Elektronikversender#Atzert-Elektronik_Versand|Atzert-Elektronik Versand]] (früher EFB-Electronic Versand, davor Megakick Electronic-Stores) für Endkunden.&lt;br /&gt;
* Ladengeschäft in Braunschweig für jedermann. Weitere Atzert Ladengeschäfte in Bielefeld, Bremen, Hamburg und Berlin.&lt;br /&gt;
* Eigentümer der Marken McCHECK®, McPower®, McVoice® und anderer, unter denen ETT importierte Messgeräte, Labornetzteile, usw. an Großkunden und Händler vertreibt. Diese sind unter oben genannten Marken dann in vielen Shops anderer Firmen für Endkunden zu finden, nicht nur bei Atzert. Preisvergleiche lohnen.&lt;br /&gt;
&lt;br /&gt;
=== Ettinger GmbH ===&lt;br /&gt;
Homepage: http://www.ettinger.de&lt;br /&gt;
&lt;br /&gt;
* Für gewerbliche Kunden&lt;br /&gt;
* Mechanische Komponenten (Gehäuse, Abstandshalter, Drehknöpfe, usw.)&lt;br /&gt;
* LEDs&lt;br /&gt;
* Gewöhnungsbedürftiger Online-Shop&lt;br /&gt;
&lt;br /&gt;
=== EVE ===&lt;br /&gt;
Homepage: http://www.eve.de&lt;br /&gt;
&lt;br /&gt;
* Zitat aus den AGBs:&lt;br /&gt;
::&#039;&#039;&amp;quot;Zu Bestellungen im Rahmen des Online-Handels sind nur durch uns autorisierte, d. h. zugelassene Käufer berechtigt. Wir gewähren nach erfolgreicher Zertifizierung – ohne hierzu verpflichtet zu sein – dem jeweiligen Käufer das nicht übertragbare, nicht exklusive Recht im Rahmen des Online-Handels Bestellungen uns gegenüber “auszubringen”.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
:Dies darf man wohl getrost als Hinweis ansehen, dass Endverbraucher als Kunden nicht gewünscht sind.&lt;br /&gt;
* Versandhaus für elektronische Artikel in Emsdetten&lt;br /&gt;
* machen auch Kabelkonfektion&lt;br /&gt;
* Pb-freie Artikel markiert&lt;br /&gt;
&lt;br /&gt;
=== Farnell ===&lt;br /&gt;
Homepage: http://www.farnell.de&lt;br /&gt;
&lt;br /&gt;
* liefert nur an gewerbliche Abnehmer, Ausnahme sind Studenten und HTL-Schüler (Österreich, Farnell.at). Nachweis wird verlangt (Gewerbeschein oder Immatrikulation).&lt;br /&gt;
* Lieferungen an Privat:&lt;br /&gt;
:* Schweiz: Farnell Schweiz beliefert auch Privatkunden.&lt;br /&gt;
:* Deutschland: Über den Reseller [[#HBE_-_Heinz_B.C3.BCchner_Elektronik.2C_Messtechnik.2C_med._Elektronik_e.K.|HBE]] kann man Produkte aus dem Farnell-Sortiment zu bestellen.&lt;br /&gt;
:* Österreich: [[#Technik-Welt / Industrieshop.at|Technik-Welt / Industrieshop.at]]&lt;br /&gt;
* große Auswahl&lt;br /&gt;
* 12% Rabatt für Studenten und Lehreinrichtungen&lt;br /&gt;
* sehr schneller Versand, Ware ist in 99% aller Fälle am nächsten Tag da (UPS), fehlende Positionen werden relativ rasch versandkostenfrei nachgeliefert&lt;br /&gt;
* Versandkosten: Bestellung bis 49,99&amp;amp;#8364;: 7,95&amp;amp;#8364;;   50,- bis 149,99&amp;amp;#8364;: 5,95&amp;amp;#8364;;   ab EUR 150,- versandkostenfrei&lt;br /&gt;
* hat nach eigenen Aussagen umfangreichstes Sortiment an RoHS-konformen Bauteilen mit Suchfunktion im WWW&lt;br /&gt;
* leistungsfähige parametrische Suchfunktion / teils aber völlig nutzlos, da den Artikeln massenweise Tags fehlen, weswegen die Suchergebnisse unnötig eingeschränkt werden&lt;br /&gt;
* Datenblätter für die meisten Bauteile online&lt;br /&gt;
* Internetpräsenz fällt nachts oft aus (Hinweis auf angebliche geplante Wartungsarbeiten)&lt;br /&gt;
* Sortierfunktion wird bei der Suche ständig zurückgesetzt, im Warenkorb ist überhaupt keine sinnvolle Sortierung möglich&lt;br /&gt;
* Eigenwillige Preispolitik: Einiges sehr günstig, Anderes total überteuert&lt;br /&gt;
&lt;br /&gt;
=== Fibra-Brandt Zweibrücken ===&lt;br /&gt;
Homepage: http://www.fibra-brandt.com&lt;br /&gt;
&lt;br /&gt;
* lagert tausende veraltete und schwer zu findende elektronische Bauteile&lt;br /&gt;
* Halbleiter, IC&#039;s, Transistoren, Spulen und Kondensatoren.&lt;br /&gt;
* Sonderbeschaffung von abgekündigten Halbleitern.&lt;br /&gt;
&lt;br /&gt;
=== Fischer DK2FD ===&lt;br /&gt;
Homepage: http://www.dfe-online.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen für Hochfrequenzmesstechnik und Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Funkamateur Online-Shop ===&lt;br /&gt;
&lt;br /&gt;
Siehe [[Elektronikversender#Box73]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Futurelec ===&lt;br /&gt;
Homepage: http://www.futurlec.com&lt;br /&gt;
&lt;br /&gt;
* günstiger Versender aus Übersee&lt;br /&gt;
* viele Stamp-Boards&lt;br /&gt;
* LED Matrix-Module&lt;br /&gt;
&lt;br /&gt;
=== Geist Electronic-Versand GmbH ===&lt;br /&gt;
Homepage: http://www.geist-electronic.de&lt;br /&gt;
&lt;br /&gt;
* Liefern Bauteile für Elektor-Projekte&lt;br /&gt;
* D-78054 Villingen-Schwenningen&lt;br /&gt;
* Versandkosten: 5.40€&lt;br /&gt;
&lt;br /&gt;
=== Giga-Tech ===&lt;br /&gt;
Homepage: http://www.giga-tech.de&lt;br /&gt;
&lt;br /&gt;
* Spezialitäten für Hochfrequenz / Amateurfunk&lt;br /&gt;
* 68542 Heddesheim&lt;br /&gt;
&lt;br /&gt;
=== Grummes Elektronik ===&lt;br /&gt;
Homepage: http://www.grummes.de&lt;br /&gt;
&lt;br /&gt;
* Elektronikversender /CNC-Fräsmaschinen / Schrittmotorsteuerungen / Bauteile&lt;br /&gt;
&lt;br /&gt;
=== Glyn (GLYNshop) ===&lt;br /&gt;
Homepage: https://www.glynshop.com/erp/welcome.do&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;B2B Shop&amp;quot; = nicht für Privatkunden&lt;br /&gt;
* Microcontroller, Evaluation Boards, TFT-Displays, LC-Displays, Memory Cards u.a.&lt;br /&gt;
&lt;br /&gt;
=== Hallmanns Elektronik ===&lt;br /&gt;
Homepage: http://www.hallmanns.com &amp;lt;br&amp;gt;&lt;br /&gt;
Adresse: Bruno Hallmanns, Weierstraße 41, 52349 Düren&lt;br /&gt;
&lt;br /&gt;
* Elektronikhändler mit Ladenlokal und Versand&lt;br /&gt;
* Ladentypisches Sortiment (Bauteile, Geräte, PC, Funk, Hifi...)&lt;br /&gt;
&lt;br /&gt;
=== Hari Seligenstadt ===&lt;br /&gt;
Homepage: http://www.hari-ham.com&lt;br /&gt;
&lt;br /&gt;
* Bausätze, Ringkerne, Geräte für Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== HBE - Heinz Büchner Elektronik, Messtechnik, med. Elektronik e.K. ===&lt;br /&gt;
Homepage: http://www.hbe-shop.de/katalog/&lt;br /&gt;
&lt;br /&gt;
* Bezeichnet sich als &#039;&#039;[[#Farnell|Farnell]] Fachhändler&#039;&#039;, bei dem nichtgewerbliche Kunden aus dem Farnell-Sortiment bestellen können.&lt;br /&gt;
* Preise für Farnell-Produkte normalerweise Farnell Netto-Preis + MwSt.&lt;br /&gt;
* Mindestbestellwert 25,- € (netto), Mindermengenzuschlag 5,- € (Stand 06/2010)&lt;br /&gt;
* Versandkosten 4,75 € (netto), ab 75,- € (netto) versandkostenfrei (Stand 06/2010)&lt;br /&gt;
&lt;br /&gt;
=== Heho-Elektronik ===&lt;br /&gt;
Homepage: http://www.heho-elektronik.de&lt;br /&gt;
* Halbleiter / Bauteile, Sortimente, Handy - Akkus, VELLEMAN - Bausätze&lt;br /&gt;
* Aktuelles Angebot, Ladegeräte / Akkuladegeräte, Blei - Akkus&lt;br /&gt;
* Spannungswandler, Audio / Video / USB - Kabel, Netzwerk - Kabel&lt;br /&gt;
* 1-2 Arbeitstage für Waren ab Lager&lt;br /&gt;
* Porto + Verpackung pauschal Euro 4,50&lt;br /&gt;
* Mindestbestellwert von &amp;amp;#8364; 10,00&lt;br /&gt;
&lt;br /&gt;
=== Hinkel ===&lt;br /&gt;
Homepage: http://www.hinkel-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Von der Webseite &amp;quot;Unser Angebot richtet sich an Schulen, Behörden, Handel, Handwerk und Industrie.&amp;quot;&lt;br /&gt;
* Batterien&lt;br /&gt;
* Knopfzellen, spezielle KZH, die man sonst lang sucht, findet man hier&lt;br /&gt;
* Mindestbestellwert von 20&amp;amp;#8364;&lt;br /&gt;
* Standardversand innerhalb Deutschlands 5,80&amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== HN Electronic Components GmbH &amp;amp; Co. KG / Netzteilshop ===&lt;br /&gt;
Homepage gewerbliche Kunden: http://www.hn-electronic.de/homed/framed.html &amp;lt;br /&amp;gt;&lt;br /&gt;
Homepage Endkunden: http://www.netzteilshop.com/hnshop.html&lt;br /&gt;
&lt;br /&gt;
* Netzteile aller Art&lt;br /&gt;
* Lieferung an Endkunden nur per UPS Nachnahme.&lt;br /&gt;
* Mindestbestellmenge für Endkunden 25 €&lt;br /&gt;
&lt;br /&gt;
=== HW-Electronics ===&lt;br /&gt;
Homepage: http://www.hw-electronics.de &amp;lt;br&amp;gt;&lt;br /&gt;
Homepage EU: http://hw-electronics.eu/&lt;br /&gt;
&lt;br /&gt;
* Tauch- und Sprühätzanlagen&lt;br /&gt;
* Entwicklungsgeräte&lt;br /&gt;
* Belichtungsgeräte, Materialsätze zum Selbstbau von Belichtungsgeräten&lt;br /&gt;
&lt;br /&gt;
=== ID-Elektronik ===&lt;br /&gt;
Homepage: http://www.id-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Amateurfunk-Baugruppen&lt;br /&gt;
&lt;br /&gt;
=== IT-WNS ===&lt;br /&gt;
Homepage: http://www.it-wns.de&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Bauteile, Platinen, Bausätze&amp;quot; insbesondere mit ATMEGA und ENC28J60&lt;br /&gt;
* Bausätze zu Projekten aus dem Forum, z.&amp;amp;nbsp;B. USBprog, ChipBasic, Mikro-Webserver, Transistortester u.v.a.m.&lt;br /&gt;
* Atmega32/644 Experimentiersystem als Bausatz mit vielen Zusatzmodul-Bausätzen&lt;br /&gt;
* SD-Slots, RFID, Bluetooth-Module, AVR Mikrocontroller uvam.&lt;br /&gt;
* Bauelemente, die nicht im Shop angeboten werden, können auf Anfrage (Kontaktformular) beschafft werden &lt;br /&gt;
* günstige Preise und Versandkosten ab 1,90EUR, kein Mindestbestellwert&lt;br /&gt;
* schneller Versand, sofern die Artikel auf Lager sind, versandkostenfreie Nachlieferung&lt;br /&gt;
&lt;br /&gt;
=== Kabelscheune ===&lt;br /&gt;
Homepage: http://www.kabelscheune.de&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Direktversand von Elektromaterial und Multimediaprodukten&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== Kelemen ===&lt;br /&gt;
Homepage: http://www.kelemenantennen.de/Kelemen-Shop/&lt;br /&gt;
&lt;br /&gt;
* Messgeräte, Antennen und Zubehör für den Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Kessler ===&lt;br /&gt;
Homepage: http://www.kessler-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* im Preis-Leistungsverhältnis mit Reichelt zu vergleichen (sprich: günstig)&lt;br /&gt;
* Sortiment kleiner als Reichelt und mit gewissen Abweichungen (z. B. andere FPGA und RAMs)&lt;br /&gt;
* oft lange Lieferzeiten&lt;br /&gt;
* Versandkosten innerhalb Deutschlands 4,95&amp;amp;#8364; bei Bankeinzug und 6,90&amp;amp;#8364; bei Nachnahme plus Nachnahmegebühren&lt;br /&gt;
* Der Download-Katalog ist von 2002! Online aktueller&lt;br /&gt;
&lt;br /&gt;
=== Klein-Electronic ===&lt;br /&gt;
Homepage: http://www.klein-electronic.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen zur Video- und 2,4GHz-Sendetechnik&lt;br /&gt;
&lt;br /&gt;
=== Konni-Antennen ===&lt;br /&gt;
Homepage: http://www.konni-antennen.de&lt;br /&gt;
&lt;br /&gt;
* Antennen für TV, Amateurfunk&lt;br /&gt;
* Zubehör, Einzelteile&lt;br /&gt;
&lt;br /&gt;
=== Köditz Nachrichtentechnik ===&lt;br /&gt;
Homepage: http://www.koeditz-nachrichtentechnik.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen und Bauteile für Amateurfunk und TV-Satellitenempfang&lt;br /&gt;
&lt;br /&gt;
=== Kuhne DB6NT ===&lt;br /&gt;
Homepage: http://www.kuhne-electronic.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen und Bausätze für Mikrowellenamateure&lt;br /&gt;
&lt;br /&gt;
=== LEDSEE Electronics ===&lt;br /&gt;
Homepage: http://www.ledsee.com&lt;br /&gt;
&lt;br /&gt;
* LEDs, LCDs, diverses&lt;br /&gt;
* Lieferung direkt aus China, daher sehr günstig und lange Lieferzeiten&lt;br /&gt;
&lt;br /&gt;
=== LED Microtechnics LTD ===&lt;br /&gt;
Homepage: http://www.ledmeile.de&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;LED Shop und Lampentechnik&amp;quot;&lt;br /&gt;
&lt;br /&gt;
=== LED-Tech LED-Shop ===&lt;br /&gt;
Homepage: http://www.led-tech.de&lt;br /&gt;
&lt;br /&gt;
* viele verschiedene LEDs zu sehr guten (meist den günstigsten) Preisen&lt;br /&gt;
* vor allem auf High-Power-LEDs spezialisiert&lt;br /&gt;
* viele verschiedene Treiber für High-Power-LEDs&lt;br /&gt;
* kostenloser Versand&lt;br /&gt;
* haben ein eigenes, sehr umfangreiches Forum&lt;br /&gt;
&lt;br /&gt;
=== Lieske Elektronik ===&lt;br /&gt;
Homepage: http://www.lieske-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* liefert nur an Geschäftskunden&lt;br /&gt;
&lt;br /&gt;
=== LUMITRONIX LEDs-Shop ===&lt;br /&gt;
Homepage: http://www.leds.de&lt;br /&gt;
&lt;br /&gt;
* alles rund um LEDs (auch Zubehör und Lektüre)&lt;br /&gt;
* neben Standard-LEDs auch SMD- und SuperFlux-LEDs&lt;br /&gt;
&lt;br /&gt;
=== Marsch Elektronik, M. Schlimper ===&lt;br /&gt;
Homepage: http://www.marsch-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Online Shop für aktive und passive Bauelemente&lt;br /&gt;
* Versandkosten ab Euro 1,60&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* liefert nur innerhalb Deutschlands&lt;br /&gt;
* nicht gelistete Artikel können angefragt werden und werden meist auch beschafft&lt;br /&gt;
&lt;br /&gt;
=== Mein-Daarle ===&lt;br /&gt;
Homepage: http://www.mein-st-arnual.de/shop/saarbruecken/artikellisteL.html&lt;br /&gt;
&lt;br /&gt;
* Teileliste eines &amp;quot;Händlers aus Saarbrücken&amp;quot; (wahrscheinl.: Frank Skowronek ESS Elektronik Service), &amp;quot;bis sein Onlineshop ans Netz gehen kann&amp;quot;&lt;br /&gt;
* derzeit (4/2011) kein Onlineshop, Kontakt über Formular&lt;br /&gt;
&lt;br /&gt;
=== Micromaus ===&lt;br /&gt;
Homepage: http://www.micromaus.de&lt;br /&gt;
&lt;br /&gt;
* Sensoren&lt;br /&gt;
* Mikrokontroller&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
&lt;br /&gt;
=== Microcontroller-Starterkits ===&lt;br /&gt;
Homepage: http://www.microcontroller-starterkits.de&lt;br /&gt;
&lt;br /&gt;
* Bauteile: CAN, Ethernet, Mikrokontroller AVR und ARM, Linearregler 1,8V 3,3V 5V in SOT223&lt;br /&gt;
* Leerplatinen, Bausätze&lt;br /&gt;
* günstig&lt;br /&gt;
* Abholung in Hattingen möglich&lt;br /&gt;
* Versandkosten innerhalb Deutschlands ab 2,50&amp;amp;#8364;&lt;br /&gt;
* keine Kreditkartenzahlung möglich&lt;br /&gt;
&lt;br /&gt;
=== Mikrocontroller.net ===&lt;br /&gt;
Homepage: http://shop.mikrocontroller.net&lt;br /&gt;
&lt;br /&gt;
* Starterkits, Development Boards und Zubehör für AVR, AVR32, ARM und MSP430&lt;br /&gt;
&lt;br /&gt;
=== Mira Nürnberg ===&lt;br /&gt;
Homepage: http://www.mira-electronic.de&lt;br /&gt;
&lt;br /&gt;
* SMD-Bauteile, SMD-Sortimentboxen&lt;br /&gt;
* Verkauf und Preisangaben nur für Gewerbetreibende&lt;br /&gt;
&lt;br /&gt;
=== Karl Müller EME Messtechnik ===&lt;br /&gt;
Homepage: http://www.eme-hf-technik.de&lt;br /&gt;
&lt;br /&gt;
* Hochfrequenz-Messtechnik, HF-Komponenten&lt;br /&gt;
&lt;br /&gt;
=== Mouser ===&lt;br /&gt;
Homepage: http://de.mouser.com&lt;br /&gt;
&lt;br /&gt;
* Liefert an Privat&lt;br /&gt;
* Zügige Lieferung mit FedEx aus den USA&lt;br /&gt;
* Keine Halbleiter von Linear, National und Analog&lt;br /&gt;
&lt;br /&gt;
=== MS-Elektronik ===&lt;br /&gt;
Homepage: http://www.ms-elektronik.info&lt;br /&gt;
&lt;br /&gt;
* Liefert an Privat&lt;br /&gt;
* Zügige Lieferung&lt;br /&gt;
* Gute Qualität&lt;br /&gt;
* Viel in Richtung Audio&lt;br /&gt;
* Große Auswahl an Elkos -&amp;gt; kleine Preise&lt;br /&gt;
* kein allzu großes Sortiment&lt;br /&gt;
&lt;br /&gt;
=== Mütron ===&lt;br /&gt;
Homepage: http://www.muetronshop.de&lt;br /&gt;
&lt;br /&gt;
* Keine Privatkunden&lt;br /&gt;
&lt;br /&gt;
=== myAVR Shop ===&lt;br /&gt;
Hompage http://shop.myavr.de&lt;br /&gt;
&lt;br /&gt;
* Kleine Auswahl, aber die angebotene Ware ist sehr preiswert (meist preiswerter als bei Reichelt)&lt;br /&gt;
* Zügige Lieferung (1-2 Werktage)&lt;br /&gt;
* Diverse Zahlungsmöglichkeiten: Rechnung, Vorkasse, Lastschrift, Kreditkarte, PayPal&lt;br /&gt;
* Kein Mindestbestellwert&lt;br /&gt;
* Sehr günstige Versandkosten ab 1,95 Eur&lt;br /&gt;
* Mengenrabatt ab 10 gleichen Artikeln&lt;br /&gt;
&lt;br /&gt;
=== Neuhold-Elektronik ===&lt;br /&gt;
Homepage: http://www.neuhold-elektronik.at &amp;lt;br&amp;gt;&lt;br /&gt;
Shop: http://www.neuhold-elektronik.at/catshop/default.php?language=de&lt;br /&gt;
&lt;br /&gt;
* preiswerte Schnäppchen&lt;br /&gt;
* regelmäßig aktualisierte Angebotsliste herunterladbar&lt;br /&gt;
* Ab 60,- EUR versandkostenfrei in Österreich&lt;br /&gt;
&lt;br /&gt;
=== Octamex ===&lt;br /&gt;
Homepage: http://www.octamex.de&lt;br /&gt;
&lt;br /&gt;
* preiswerte Leiterplattenchemie &lt;br /&gt;
* Chemisch Zinn&lt;br /&gt;
* Ätzmittel Natriumpersulfat, Eisen-III-Chlorid&lt;br /&gt;
* Entwickler positiv und negativ&lt;br /&gt;
* Lötstopp-Laminat, Tentingresist, Bestückungsdruck&lt;br /&gt;
* Bungard Basismaterial in 0,5mm 1,0mm 1,5mm Dicke und 18µm, 35µm, 70µm Kupfer&lt;br /&gt;
* Bungard Alucorex für 19&amp;quot; Frontplatten&lt;br /&gt;
* Gehäuse aller Art&lt;br /&gt;
* Quarze in Industriequalität&lt;br /&gt;
* aktive und passive Halbleiter (Widerstände, Kondensatoren, Transistoren, Logik-ICs etc.)&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* Lieferung auch ins Ausland&lt;br /&gt;
* Versandkosten ab 2,55EUR&lt;br /&gt;
* Liefert nur gegen Vorkasse, ausser für Bestandskunden, die schon häufig bestellt haben&lt;br /&gt;
* Zahlung mit EC-Pay oder Kreditkarte nur gegen erheblichen Aufschlag (bis zu 5%)&lt;br /&gt;
&lt;br /&gt;
=== Online Batterien ===&lt;br /&gt;
Homepage: http://www.online-batterien.de&lt;br /&gt;
&lt;br /&gt;
* Allerlei günstige Batterien &amp;amp; Akkus vieler Marken&lt;br /&gt;
* z.&amp;amp;nbsp;B. &#039;&#039;&#039;40 Stk.&#039;&#039;&#039; DURACELL PLUS LR6 AA 11,59€ (Jan 2010)&lt;br /&gt;
* Beleuchtungsartikel&lt;br /&gt;
* USV&lt;br /&gt;
* Versand ab 3,90€&lt;br /&gt;
&lt;br /&gt;
=== Oppermann ===&lt;br /&gt;
Homepage: http://www.oppermann-electronic.de&lt;br /&gt;
&lt;br /&gt;
* Restposten, auch HF Bauteile&lt;br /&gt;
* auch Privatkunden&lt;br /&gt;
* Lieferung nach üblicher Zeit&lt;br /&gt;
&lt;br /&gt;
=== PCB-Soldering ===&lt;br /&gt;
&lt;br /&gt;
Homepage, Online-Shop: http://www.pcb-soldering.co.uk&lt;br /&gt;
eBay: http://www.allendale-stores.co.uk&lt;br /&gt;
Firmen-Homepage: http://www.allendale-elec.co.uk&lt;br /&gt;
&lt;br /&gt;
* [http://www.aoyue.com/en/products.asp Aoyue] Lötstationen und preiswertes Zubehör (Lötspitzen) für diese. Bei Aoyue-Zubehör bessere Preise (Stand 10/2008) als [[#WilTec_Wildanger_Technik_GmbH|WilTec]]&lt;br /&gt;
* Schnelle Lieferung&lt;br /&gt;
* Dank [http://www.zoll.de/b0_zoll_und_steuern/a0_zoelle/a1_grundlage_zollrecht/b0_zollgebiet/index.html EU Binnenmarkt] nur britische Mehrwertsteuer (VAT), kein Zoll, keine [http://www.zoll.de/b0_zoll_und_steuern/a3_einfuhrumsatzsteuer/index.html Einfuhrumsatzsteuer] fällig.&lt;br /&gt;
* Zwei von drei E-Mails wurden nicht beantwortet&lt;br /&gt;
* Versandart wurde eigenmächtig von &amp;quot;Standard&amp;quot; auf teureres &amp;quot;Signed for&amp;quot; (Einschreiben) geändert&lt;br /&gt;
&lt;br /&gt;
=== Pollin Electronic ===&lt;br /&gt;
Homepage: http://www.pollin.de&lt;br /&gt;
&lt;br /&gt;
* Günstige Restposten aller Art (z.&amp;amp;nbsp;B. &amp;quot;250 g verschiedene ICs&amp;quot; u.dgl.)&lt;br /&gt;
* Produktkategorien:&lt;br /&gt;
** Computer und Zubehör&lt;br /&gt;
** Telefone und Zubehör&lt;br /&gt;
** Antennentechnik&lt;br /&gt;
** HiFi/Car-HiFi/Video/TV&lt;br /&gt;
** Stromversorgung&lt;br /&gt;
** Lichttechnik&lt;br /&gt;
** Messtechnik / Uhren&lt;br /&gt;
** Haustechnik&lt;br /&gt;
** Werkstatt&lt;br /&gt;
** Bauelemente&lt;br /&gt;
** KFZ- und Zweirad&lt;br /&gt;
** Motoren&lt;br /&gt;
** Bausätze&lt;br /&gt;
** Fundgrube&lt;br /&gt;
* Produkte teils schnell ausverkauft &lt;br /&gt;
* Qualität schwankend. Man kann gute Schnäppchen machen aber auch reinfallen. Umtausch ist dann aber problemlos.&lt;br /&gt;
* Es wird öfters von sorgloser Verpackung berichtet, trotz Verpackungspauschale von 0,85 % des Warenwerts (empfindliche und schwere Produkte besser nicht zusammen bestellen). Reklamationen bei Beschädigungen werden freundlich behandelt.&lt;br /&gt;
* Lieferzeit i.d.r. 2-3 Werktage / knappe Woche bei neuer Sonderliste&lt;br /&gt;
* Ladengeschäft in 85104 Pförring&lt;br /&gt;
* Versandkosten  innerhalb Deutschlands 4,50 &amp;amp;#8364; (ab 150&amp;amp;#8364; versandkostenfrei); dazu 0,85 % Verpackungspauschale&lt;br /&gt;
* Zahlung per Nachnahme (+2,50 €) oder Bankeinzug (keine Kreditkarte, keine Überweisung)&lt;br /&gt;
&lt;br /&gt;
=== proma / Isel ===&lt;br /&gt;
Homepage: http://www.proma-technologie.com/deutsch/rundum_l/proma_fs_1.html&lt;br /&gt;
&lt;br /&gt;
* fotobeschichtete Leiterplatten Platinenfrästechnik&lt;br /&gt;
* Chemikalien für die Platinenherstellung: Ätzmittel, Flussmittel für Lötanlagen, etc.&lt;br /&gt;
* Profilgehäuse, u.a. von Conrad und Reichelt vertrieben&lt;br /&gt;
&lt;br /&gt;
=== QRP-project ===&lt;br /&gt;
Homepage: http://www.qrpshop.de/sitemap.htm&lt;br /&gt;
* Bausätze vor allem einfache Kurzwellen-Funkgeräte&lt;br /&gt;
&lt;br /&gt;
=== Reichelt ===&lt;br /&gt;
Homepage: http://www.reichelt.de&lt;br /&gt;
&lt;br /&gt;
* relativ große Auswahl, aber nicht viele &amp;quot;brandaktuelle&amp;quot; Bauteile&lt;br /&gt;
* wenn man höflich fragt, liefern sie ganz selten auch Bauteile, die nicht im Katalog stehen zu &amp;quot;normalen&amp;quot; Preisen (vorausgesetzt der Hersteller ist im Sortiment), z.&amp;amp;nbsp;B. Xilinx XC2S50, aber meist erhält man die Antwort, dass der Artikel nicht im Sortiment ist, obwohl auf der Homepage unter Service extra ein Punkt angeführt ist: &amp;quot;Ich benötige einen Artikel, der nicht im Programm ist&amp;quot;&lt;br /&gt;
* reagiert aber teilweise auch auf Anregungen, neue Produkte in das Angebot aufzunehmen; siehe dazu auch den Artikel [[Reichelt-Wishlist]]&lt;br /&gt;
* liefert schnell und vollständig; wenn etwas ausnahmsweise nicht verfügbar ist, dann liefern sie es auf eigene Kosten nach, wenn der Artikel in absehbarer Zeit wieder vorrätig ist (selbst wenn er nur 0,20€ wert ist).&lt;br /&gt;
* lässt einen dennoch manchmal warten, wenn ein Artikel nicht lieferbar ist! Daher bei der Bestellung immer darauf hinweisen, dass man auch eine Teillieferung akzeptiert. (Laut Auskunft dauert das länger, besser nach der Inet-Bestellung anrufen und nicht lieferbare Teile aus der Bestellung streichen lassen)&lt;br /&gt;
* Lieferzeiten normalerweise 2 - 4 Arbeitstage&lt;br /&gt;
* niedrige Preise (aber unbedingt Qualität des Artikel checken)&lt;br /&gt;
* Versandkosten 5,60€ (Deutschland); 10€ Österreich; Schweiz 16€; EU 15 - 19€;&lt;br /&gt;
* 10€ Mindestbestellwert für alle Länder&lt;br /&gt;
* auch in die Schweiz sehr guter Service&lt;br /&gt;
* holt sich auch ohne Erlaubnis Bankauskünfte bei großen Bestellungen ein&lt;br /&gt;
&lt;br /&gt;
=== RFW Elektronik ===&lt;br /&gt;
Homepage: http://www.rfw-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* HF Bauelemente&lt;br /&gt;
&lt;br /&gt;
=== Ribu ===&lt;br /&gt;
Homepage: http://www.ribu.at&lt;br /&gt;
&lt;br /&gt;
* Sehr guter Elektronikversand in Österreich mit zahlreichen Entwicklungsboards und zahlreichen Elektroniklösungen.&lt;br /&gt;
* Liefert sehr schnell und hat eine ausgezeichnete Beratung. &lt;br /&gt;
* Online-Shop ist sehr übersichtlich und einfach zu bedienen.&lt;br /&gt;
* Lieferstatusanzeige für alle Artikel. Bei Auslaufartikeln ist sogar die noch verfügbare Stückzahl sichbar.&lt;br /&gt;
* Günstige Sonderangebote&lt;br /&gt;
* innerhalb Österreichs 4,90&amp;amp;#8364; Versandkosten, ab 80,- keine Versandkosten&lt;br /&gt;
* ausserhalb Österreichs 13&amp;amp;#8364; Versandkosten, ab 225&amp;amp;#8364; versandkostenfrei&lt;br /&gt;
* liefert auch an Privatkunden&lt;br /&gt;
* Mindestbestellwert innerhalb Österreichs 10&amp;amp;#8364;, ausserhalb 30&amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== Richardson Electronic ===&lt;br /&gt;
Homepage: http://www.rell.com/international/index.asp?ID=GE&lt;br /&gt;
&lt;br /&gt;
* Hochfrequenz-Halbleiter, HF-Röhren,&lt;br /&gt;
&lt;br /&gt;
=== Riedl Elektronik ===&lt;br /&gt;
Homepage: http://www.riedl-electronic.at&lt;br /&gt;
&lt;br /&gt;
* großes Angebot v.a. ICs und Trafos&lt;br /&gt;
* recht günstig&lt;br /&gt;
* Rabatt für Schüler/Student&lt;br /&gt;
* Versand nach AT: 3,95€ bis 1kg, ab 100€ frei Haus&lt;br /&gt;
* Versand AT über 1kg sowie Ausland: Nach Aufwand (wird nicht direkt angezeigt)&lt;br /&gt;
&lt;br /&gt;
=== RLX COMPONENTS s.r.o. ===&lt;br /&gt;
Homepage: http://www.rlx.sk&lt;br /&gt;
&lt;br /&gt;
* Man spricht Deutsch&lt;br /&gt;
* Messgeräte, Mikrocontroller-Boards, Bauelemente&lt;br /&gt;
&lt;br /&gt;
=== RM Computertechnik GmbH ===&lt;br /&gt;
Homepage: http://www.rm-computertechnik.de&lt;br /&gt;
&lt;br /&gt;
* Kerngeschäft ist PC-Technik, aber auch großes Sortiment an Kabeln, Litzen und Steckverbindern&lt;br /&gt;
* handelt auch mit einigen Bauelementen, wie LED&#039;s&lt;br /&gt;
&lt;br /&gt;
=== Robotikhardware===&lt;br /&gt;
Homepage: http://www.robotikhardware.de&lt;br /&gt;
&lt;br /&gt;
* Microcontroller&lt;br /&gt;
* Entwicklungsboards&lt;br /&gt;
* Sensoren&lt;br /&gt;
* Robotik-Zubehör&lt;br /&gt;
* günstiges Angebote für Hobby-Elektroniker&lt;br /&gt;
* auch einzelne Platinen&lt;br /&gt;
&lt;br /&gt;
=== Benno Rößle Elektronik ===&lt;br /&gt;
Homepage: http://www.roessle-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Masten, Antennen, Befestigungsmat.,Zubehör, Geräte, Anpassteile, HF-Stecker&lt;br /&gt;
&lt;br /&gt;
=== RS Components ===&lt;br /&gt;
Homepage: http://www.rsonline.de&lt;br /&gt;
&lt;br /&gt;
* lt. AGB nur an gewerbliche Abnehmer, fragt bei Internetbestellungen aber nicht nach. Anm.: mitlerweile machen sie es doch.&lt;br /&gt;
* gute Auswahl insbesondere an &amp;quot;mechanischen Bauteilen&amp;quot;&lt;br /&gt;
* gute Verfügbarkeit&lt;br /&gt;
* sehr schneller Versand, Ware ist in 99% aller Fälle am nächsten Tag da (GP)&lt;br /&gt;
* Preise wurden angepasst, gute Preis/Leistung&lt;br /&gt;
* Preis im Onlineshop sind ohne MwSt angegeben&lt;br /&gt;
* Bei Onlinekauf ist der Versand kostenfrei, ohne Mindesbestellwert.&lt;br /&gt;
* Notify-Me Service für Produktabkündigung&lt;br /&gt;
* Auch größere Stückzahlen über Allied möglich&lt;br /&gt;
* Relativ große Auswahl an Sortimenten (Widerstände, Kondensatoren), Einzelteile können teilweise nachgekauft werden&lt;br /&gt;
* Verfügbarkeitsanzeige im Internet ist ziemlich hilfreich&lt;br /&gt;
* Nützliche Tipps zum Thema RoHS&lt;br /&gt;
&lt;br /&gt;
=== Sander Elektronik ===&lt;br /&gt;
Homepage: http://www.sander-electronic.de&lt;br /&gt;
&lt;br /&gt;
* beliefert auch Privatkunden, Bankeinzug möglich&lt;br /&gt;
* ähnlich Segor ein Berliner Versender&lt;br /&gt;
* Hier findet man manche [[MSP430]], die es sonst nicht in kleinen Stückzahlen gibt&lt;br /&gt;
* Herr Sander ist sehr kompetent und selbst Autor von Fachartikeln&lt;br /&gt;
* selbst abgekündigte Halbleiter können noch beschafft werden&lt;br /&gt;
* Bezahlung auch mit Kreditkarte möglich&lt;br /&gt;
* Versandkosten innerhalb Deutschlands ab 3,35&amp;amp;#8364;, innerhalb Europas ab 6&amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== Sasco Holz ===&lt;br /&gt;
Homepage: http://www.sasco.de&lt;br /&gt;
&lt;br /&gt;
* Wie Spoerle eine Tochter von Arrow. &lt;br /&gt;
* Distributor für Analog Devices... &lt;br /&gt;
* Liefert wie Spoerle und Arrow in Deutschland nicht an Privatkunden.&lt;br /&gt;
&lt;br /&gt;
=== Sat-Schneider ===&lt;br /&gt;
Homepage: http://www.sat-schneider.de&lt;br /&gt;
* Bauteile, Ersatzteile  Online-Shop&lt;br /&gt;
* Baugruppen zum Empfang des Digitalen Kurzwellenrundfunks DRM&lt;br /&gt;
&lt;br /&gt;
=== Otto Schubert GmbH ===&lt;br /&gt;
Homepage: http://www.schubert-gehaeuse.de&lt;br /&gt;
&lt;br /&gt;
* Kein Online-Shop. Bestellungen nur per Telefon, Fax oder E-Mail &lt;br /&gt;
* Weissblechgehäuse, Gerätegehäuse, wetterfeste Gehäuse&lt;br /&gt;
* Drehkondensatoren&lt;br /&gt;
* Sonderanfertigungen&lt;br /&gt;
&lt;br /&gt;
=== Schramm-Software ===&lt;br /&gt;
Homepage: http://www.schramm-software.de/bausatz/&lt;br /&gt;
* Online-Shop, bietet Elektronik-Bausätze mit Mikrocontrollern&lt;br /&gt;
* Bausätze als Lehrmaterial geeignet, da ausführliches Begleitheft mitgeliefert wird (Aufbauanleitung, Schaltung, Controllerprogramm, Experimente...)&lt;br /&gt;
* bisher nur ein relativ kleines Sortiment, soll ergänzt werden&lt;br /&gt;
* Versandkosten innerhalb Deutschlands 2,50 &amp;amp;#8364;, innerhalb der EU 3,50 &amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== Schukat elektronic ===&lt;br /&gt;
Homepage: http://www.schukat.de&lt;br /&gt;
&lt;br /&gt;
* liefert nicht an privaten Endverbraucher&lt;br /&gt;
* einfache und passiver Bauteile oft nur in großen Mindeststückzahlen&lt;br /&gt;
* ICs teilweise recht preiswert (vor allem bei mehr als 1 Stück, z.&amp;amp;nbsp;B. auch AVR)&lt;br /&gt;
* LCDs sehr preiswert und auch als Einzelstücke&lt;br /&gt;
* aktuelle Preise und Verfügbarkeit im Internet (aber nur nach Anmeldung -jetzt nicht mehr bei kleinen Stückzahlen), ebenso Bilder von Gehäusefootprints u.dgl.&lt;br /&gt;
* Abholung in Monheim am Rhein nach Vereinbarung möglich&lt;br /&gt;
* Versandkosten innerhalb Deutschlands ab 5&amp;amp;#8364; (bis 10kg!)&lt;br /&gt;
&lt;br /&gt;
=== Schuricht ===&lt;br /&gt;
Homepage: http://www.schuricht.de&lt;br /&gt;
&lt;br /&gt;
* deutscher Ableger der Distrelec- (Elektronik) und Disdata-Gruppe (Computertechnik)&lt;br /&gt;
* Liefert auch an Privatkunden (getrennte AGBs für gewerbliche und Privatkunden, Lieferung an Privat per Nachnahme: Versandkosten ab 6,54€ plus 4,76€ Nachnahmegebühr).&lt;br /&gt;
** Online-Bestellung von Privatkunde scheiterte daran, dass die  Onlineshop-Bestellformulare nur für gewerbliche Kunden ausgelegt sind und der Onlineshop Bestellungen ohne Firmenangaben nicht annimmt oder gar mit einer internen Fehlermeldung quittierte.&lt;br /&gt;
**Online Bestellung mit &amp;quot;Privat&amp;quot; als Firmenangabe funktionierte einwandfrei.&lt;br /&gt;
**Telefonische Bestellung von Privat funktioniert. Nette, freundliche Behandlung am Telefon, kein Callcenter. Versprochener Rückruf erfolgte mit gewünschten Informationen. Neben Nachnahme wurde für einen relativ teuren Artikel persönliche Abholung angeboten. Angegebene Lieferfrist wurde leicht unterschritten.&lt;br /&gt;
* Papierkatalog über 2000 Seiten, durchgehend farbig, nur für Geschäftskunden erhältlich.&lt;br /&gt;
* Ziemlich teuer&lt;br /&gt;
&lt;br /&gt;
=== Schuro Elektronik GmbH ===&lt;br /&gt;
Homepage: http://www.schuro.de&lt;br /&gt;
&lt;br /&gt;
* Elektronische Bauelemente und Bauteile für den Audio- und Lautsprecherbau (Kondensatoren, Spulen u.dgl.)&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* Versandkosten innerhalb Deutschlands gewichtsabhängig ab 5,75&amp;amp;#8364;&lt;br /&gt;
&lt;br /&gt;
=== Segor-electronics ===&lt;br /&gt;
Homepage: http://www.segor.de&lt;br /&gt;
&lt;br /&gt;
* Spezialist für Halbleiter, die ansonsten für nicht-gewerbliche Abnehmer nur schwer erhältlich sind (Preise dahingehend &amp;quot;angemessen&amp;quot;)&lt;br /&gt;
* auch Privatkunden gerne gesehen&lt;br /&gt;
* Ladengeschäft in Berlin&lt;br /&gt;
* kein Mindestbestellwert bei Versand innerhalb der EU&lt;br /&gt;
&lt;br /&gt;
=== SE Spezial-Electronic AG ===&lt;br /&gt;
Homepage: http://www.spezial.de&lt;br /&gt;
&lt;br /&gt;
* Distributor&lt;br /&gt;
* Laut AGB auch Verkauf an Privat.&lt;br /&gt;
* Große Verpackungseinheiten/Mindestbestellmengen pro Bauteil&lt;br /&gt;
* Versandkosten pauschal 9,- €  (Deutschland) (Stand 08/2008)&lt;br /&gt;
&lt;br /&gt;
=== Shortec Electronics ===&lt;br /&gt;
Homepage: http://www.shortec.com&lt;br /&gt;
&lt;br /&gt;
* Unabhängiger Distributor von elektronischen und elektromechanischen Bauelementen aller Hersteller.&lt;br /&gt;
&lt;br /&gt;
=== Small Control Shop ===&lt;br /&gt;
Homepage: http://www.small-control.de&lt;br /&gt;
&lt;br /&gt;
* &amp;quot;Bernd Walter Computer Technology&amp;quot;&lt;br /&gt;
* kleines Lieferprogramm aber ein paar interessante Produkte&lt;br /&gt;
&lt;br /&gt;
=== SMG Diffusion - F1GE ===&lt;br /&gt;
Homepage: http://www.smgdiffusion.com&lt;br /&gt;
( Seite nur französisch )&lt;br /&gt;
&lt;br /&gt;
* Videotechnik, &lt;br /&gt;
* 1,2 GHz / 2,4GHz Module&lt;br /&gt;
* Gebraucht-Messgeräte HP, Tek, Philips  u.a.&lt;br /&gt;
* GHz-Halbleiter&lt;br /&gt;
* Koax-Adapter&lt;br /&gt;
* Antennen&lt;br /&gt;
&lt;br /&gt;
=== Spoerle ===&lt;br /&gt;
Homepage: http://www.spoerle.de&lt;br /&gt;
&lt;br /&gt;
* Früher eine Tochterfirma von Arror. Mittlerweile komplett in Arrow aufgegangen, Webseite leitet auf Arrow um.&lt;br /&gt;
* Aus dem Webshop: &amp;quot;Unser Angebot richtet sich nur an Kaufleute und nicht an Verbraucher.&amp;quot;&lt;br /&gt;
* Wenn es wirklich über Arrow sein muss, dann kann man es als Privatperson bei Arrow Electronics North American Components http://www.arrownac.com/ versuchen, die sich normalerweise nicht weigern ihre Produkte zu verkaufen. Allerdings muss man mit großen Mindestmengen (z.&amp;amp;nbsp;B. BC547 in Schritten von 2000 Stück) und hohen Kosten rechnen.&lt;br /&gt;
:Zu den Kosten gehören zum Beispiel ein mehrfacher Mindermengenzuschlag (&#039;&#039;$10 handling charge will be added to each line item less than $30&#039;&#039;), eine satte &#039;&#039;handling and energy fee of $10.22&#039;&#039; (mehr als 10x zu hoch wie die vergleichbare Gebühr für amerikanische Besteller), hohe Versandkosten (ab $20 nach Deutschland). Dazu kommen die üblichen Kosten für den Import aus dem Ausland (Einfuhrumsatzsteuer, Kreditkartengebühr, ...)&lt;br /&gt;
&lt;br /&gt;
=== SR-Systems ===&lt;br /&gt;
Homepage: http://www.sr-systems.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen für Digital-TV, Sende- und Empfangstechnik&lt;br /&gt;
* DVB-S, DVB-T&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Strixner&amp;amp;Holzinger ===&lt;br /&gt;
Homepage: http://www.sh-halbleiter.de&lt;br /&gt;
&lt;br /&gt;
* Ladengeschäft in München&lt;br /&gt;
* Versand &lt;br /&gt;
* riesiges Angebot an Halbleiter, auch schwer beschaffbare&lt;br /&gt;
* Online-Shop&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== TAUTEC-ELECTRONICS ===&lt;br /&gt;
Homepage: http://www.tautec-electronics.de&lt;br /&gt;
&lt;br /&gt;
* Online Shop für aktive elektronische Bauelemente&lt;br /&gt;
* günstige Preise (Vorsicht, Preisangaben enthalten keine Mehrwertsteuer) aber Mindestbestellwert 100 Euro&lt;br /&gt;
* alle Artikel ab Lager lieferbar, daher kurze Wartezeiten&lt;br /&gt;
* weltweiter Versand&lt;br /&gt;
* zahlreiche Mengenrabatte&lt;br /&gt;
* viele Ersatzteile aus dem Audio-, Car-HiFi und TV-Bereich&lt;br /&gt;
&lt;br /&gt;
=== TCB-Versand ===&lt;br /&gt;
Homepage: http://www.tcb-versand.de&lt;br /&gt;
&lt;br /&gt;
* insbesondere für Modellbauer ein sehr interresantes Sortiment&lt;br /&gt;
* Stecker,Kabel etc. recht günstig und kleine Mengen abnehmbar &lt;br /&gt;
* Lieferung normal zwischen 1 und 3 Tage&lt;br /&gt;
* leider nur Online-Shop&lt;br /&gt;
&lt;br /&gt;
=== Tec-Shop (Wolfgang Rompel Elektronik) ===&lt;br /&gt;
Homepage: http://www.tec-shop.de www.tec-shop.de&lt;br /&gt;
&lt;br /&gt;
* Kleines, aber ausgesuchtes Sortiment&lt;br /&gt;
* Interessantes Angebot an Sensoren&lt;br /&gt;
&lt;br /&gt;
=== Technik-Welt / Industrieshop.at ===&lt;br /&gt;
Homepage: http://www.industrieshop.at&lt;br /&gt;
&lt;br /&gt;
* Laut Homepage richtet man sich &amp;quot;an den industriellen Kunden&amp;quot;. Laut AGB sieht man das jedoch nicht so eng, Zitat:&lt;br /&gt;
:: &#039;&#039;TW schließt online Verträge nur mit Kunden ab, die natürliche oder juristischen Personen sind, die ihren Wohnsitz oder Sitz in Österreich, einem Mitgliedsstaat der Europäischen Union (EU25) oder der Schweiz haben.&#039;&#039;&lt;br /&gt;
* [[#Farnell|Farnell]] Teile&lt;br /&gt;
* In Österreich&lt;br /&gt;
* Schnelle Lieferung (2 Tage)&lt;br /&gt;
&lt;br /&gt;
=== TIGAL KG ===&lt;br /&gt;
Homepage: http://www.tigal.com&lt;br /&gt;
&lt;br /&gt;
* Boards und Tools für Embedded-Elektronik&lt;br /&gt;
* In Österreich &lt;br /&gt;
* Versandkosten ab € 7,00 in Österreich, ab € 10,00 nach Deutschland.&lt;br /&gt;
* Preisangaben ohne MWSt. Für Privatkunden kommen 20% österreichische Mehrwertsteuer hinzu.&lt;br /&gt;
* U.a. ZeroLogic Logik-Analysatoren.&lt;br /&gt;
&lt;br /&gt;
=== TME (Transfer Multisort Elektronik) ===&lt;br /&gt;
Homepage: [http://www.tme.pl/index.phtml?lang=de www.tme.pl]&lt;br /&gt;
&lt;br /&gt;
* Firmensitz in Łódź, Polen&lt;br /&gt;
* Zahlungsabwicklung über deutsches Konto&lt;br /&gt;
* als Privatkunde: Mehrwertsteuer beachten (22%)&lt;br /&gt;
* sehr großes günstiges SMD Sortiment&lt;br /&gt;
&lt;br /&gt;
=== Trade-Shop / AIR Electronics GmbH ===&lt;br /&gt;
Homepage: http://www.trade-shop.de&lt;br /&gt;
&lt;br /&gt;
* Trotz knackiger Sprüche auf der englischen Version der Webseite (&amp;quot;Electronic Components Superstore&amp;quot;) eher kleines Angebot elektronischer Bauteile&lt;br /&gt;
* 20 Euro Mindestbestellmenge (Stand Februar 2008)&lt;br /&gt;
* ab 6,90 Euro Versandkosten (Deutschland, bis 1kg)  (Stand Februar 2008)&lt;br /&gt;
&lt;br /&gt;
=== Trenkenchu &amp;amp; Stadler GbR ===&lt;br /&gt;
Homepage: http://www.ts-audio.de&lt;br /&gt;
&lt;br /&gt;
* die meisten Artikel sind deutlich teurer als der Marktpreis, nur bei exotischen Bauelementen kann man durchaus ein Schnäppchen machen&lt;br /&gt;
&lt;br /&gt;
=== TV-Ersatzteile ===&lt;br /&gt;
Homepage: http://www.tversatzteile.de&lt;br /&gt;
&lt;br /&gt;
* TV-, Audio-, Video-Ersatzteile, Aktive / Passive Bauteile&lt;br /&gt;
* Fernbedienungen Haushaltstechnik&lt;br /&gt;
&lt;br /&gt;
=== UKW-Berichte ===&lt;br /&gt;
Homepage: http://www.ukw-berichte.de&lt;br /&gt;
&lt;br /&gt;
* Antennen, Bauteile, Bausätze, Literatur für Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Voelkner ===&lt;br /&gt;
Homepage: Kein Link, entsprechend der Vorgabe des Betreibers der Voelkner Webseite im Impressum:&lt;br /&gt;
&amp;lt;i&amp;gt;&amp;lt;blockquote&amp;gt;voelkner - direkt günstiger&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
wird produziert und betreut von&amp;lt;br/&amp;gt;&lt;br /&gt;
Re-In Retail International GmbH &amp;lt;br/&amp;gt;&lt;br /&gt;
...&amp;lt;br/&amp;gt;&lt;br /&gt;
Eine Verlinkung auf die Website der Firma Re-In Retail International GmbH bedarf einer schriftlichen Genehmigung. &amp;lt;/blockquote&amp;gt;&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Großer Teil des Conrad-Programms, identische Nummern, identische Aufkleber auf der Ware, Preise identisch oder nur ein paar Cent abweichend&lt;br /&gt;
* Versandkosten Deutschland: 4,95€; ab 25€ Warenwert und Sofortüberweisung.de versandkostenfrei / Versandkosten-Flatrate für 15€ pro Jahr&lt;br /&gt;
* Versandkosten EU: 9,95€&lt;br /&gt;
* Möglichkeit der Versandkostenflatrate (D): Einmalig 9,95€ / gültig für ein Jahr&lt;br /&gt;
* Legt jeder Bestellung gleich wieder einen Gutschein über 5€ bei MBW 25€ bei (Flat nur bei häufigen, kleinen Bestellungen sinnvoll); außerdem kommt etwa alle 2-3 Monate selbiger Gutschein + versandkostenfreie Lieferung per Mail, ebenfalls MBW 25€&lt;br /&gt;
* Verpackungsqualität wechselnd, mal brauchbar, mal eher Pollin-Niveau. Selbst kleine Bestellungen, die gefahrlos per Brief/Großbrief verschickt werden könnten werden in einem großen Paket versendet.&lt;br /&gt;
&lt;br /&gt;
=== VOTI Webshop ===&lt;br /&gt;
Homepage: http://www.voti.nl/shop/catalog.html&lt;br /&gt;
&lt;br /&gt;
* relativ kleines Lieferprogramm&lt;br /&gt;
* einige interessante Restposten (Surplus)&lt;br /&gt;
&amp;lt;!-- nicht mehr: * verkauft auch VID/PID-Paare für USB-Applikationen --&amp;gt;&lt;br /&gt;
* Sitz in Amersfoort, Niederlande&lt;br /&gt;
&lt;br /&gt;
=== Walter elektronik ===&lt;br /&gt;
Homepage: http://www.walter-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Bauteile, Röhren&lt;br /&gt;
&lt;br /&gt;
=== Watterott electronic GmbH===&lt;br /&gt;
Homepage: http://www.watterott.com&lt;br /&gt;
&lt;br /&gt;
* Distributor für Arduino, BeagleBoard, FriendlyARM, Pololu, Seeed Studio, Solarbotics, SparkFun...vollständige [http://www.watterott.net/about#distri Liste hier]&lt;br /&gt;
* Entwicklungskits von Atmel, Luminary Micro, Microchip, Raisonance, TI&lt;br /&gt;
* Spezialbauteile von Davicom, FTDI, VLSI, WIZnet&lt;br /&gt;
* Bungard Basismaterial + Chemie&lt;br /&gt;
* kein Mindestbestellwert&lt;br /&gt;
* Zahlung: Vorkasse, Sofortüberweisung, PayPal, Nachnahme, Kreditkarte (Visa/Mastercard), Rechnung (nur gewerbliche Kunden)&lt;br /&gt;
* Versandkosten Dtl. (UPS): &lt;br /&gt;
** bis  25 EUR Warenwert: 3,50 Euro&lt;br /&gt;
** bis  50 EUR Warenwert: 2,90 Euro&lt;br /&gt;
** bis 150 EUR Warenwert: 2,00 Euro&lt;br /&gt;
** ab  150 EUR Warenwert: versandkostenfrei&lt;br /&gt;
* Versandkosten EU (UPS): &lt;br /&gt;
** bis 150 EUR Warenwert: 10,00 Euro&lt;br /&gt;
** bis 250 EUR Warenwert:  8,90 Euro&lt;br /&gt;
** bis 500 EUR Warenwert:  7,00 Euro&lt;br /&gt;
** ab  500 EUR Warenwert:  versandkostenfrei&lt;br /&gt;
* Schneller, entgegenkommender Service&lt;br /&gt;
&lt;br /&gt;
=== Westfalia ===&lt;br /&gt;
Homepage Deutschland: http://www.westfalia.de&lt;br /&gt;
Homepage Österreich: http://www.westfalia-versand.at&lt;br /&gt;
&lt;br /&gt;
* Vor 85 Jahren in Hagen, Westfalen gegründet&lt;br /&gt;
* Elektronik nur ein kleiner Teil des Angebotes. Eher insgesamt Haushalts-, Werkstätten-, Agrar- und Gartenbedarf&lt;br /&gt;
* Elektroniksortiment stark schwankend. Momentan (Juni 2008) wenig Auswahl.&lt;br /&gt;
* Mindestbestellwert 18 €, bei Neukundenbestellungen mit Prämienanforderungen (wenig wertiges Geschenk) sogar 50 €.&lt;br /&gt;
* 4,95&amp;amp;#8364; Versandkosten, ab 150&amp;amp;#8364; Bestellwert versandkostenfrei&lt;br /&gt;
* Transportversicherung wird zusätzlich mit einem Zuschlag von 0,8% des Warenwertes berechnet.&lt;br /&gt;
* Einmalige Bestellung führte zu jahrelanger Zusendung von Werbung für Westfalia-Angeboten mit Gewinnspielen (Glücksnummern, Rubbellose, Glücksschlüssel, etc.)&lt;br /&gt;
* Verpackung ähnlich &amp;quot;sorgfältig&amp;quot; wie bei [[#Pollin_Electronic|Pollin Electronic]]. Übergroße Kartons, wenig Verpackungsmaterial, schweres Teil (Labornetzgerät) flog lose im Karton herum und zertrümmerte andere Ware.&lt;br /&gt;
&lt;br /&gt;
=== WilTec Wildanger Technik GmbH ===&lt;br /&gt;
Homepage: http://shop.wiltec.info&lt;br /&gt;
&lt;br /&gt;
* Aoyue Lötgeräte (Heißluft, Löten, Entlöten), Netzteile, Werkzeuge&lt;br /&gt;
* Aoyue Zubehör (Lötspitzen, Heißluftdüsen), Ersatzteile&lt;br /&gt;
* Andere, nicht Elektronik-Angebote, wie KFZ-Tuningteile&lt;br /&gt;
* Versand. Bei Voranmeldung auch Lagerverkauf.&lt;br /&gt;
&lt;br /&gt;
=== Wüstens frag-jan-zuerst ===&lt;br /&gt;
Homepage: http://www.die-wuestens.de/dindex.htm&lt;br /&gt;
&lt;br /&gt;
* Röhrentechnik&lt;br /&gt;
* Hochspannungs-Spezialteile&lt;br /&gt;
&lt;br /&gt;
=== WIMO ===&lt;br /&gt;
Homepage: http://www.wimo.de&lt;br /&gt;
&lt;br /&gt;
* Große Auswahl an Amateurfunktechnik&lt;br /&gt;
&lt;br /&gt;
=== Zech DG0VE ===&lt;br /&gt;
Homepage: http://www.dg0ve.de&lt;br /&gt;
&lt;br /&gt;
* Baugruppen für Amateurfunk&lt;br /&gt;
&lt;br /&gt;
=== Diverse ===&lt;br /&gt;
* http://www.chip-flip.com - Europäisches Bauelementesuchsystem, franchised Lieferantensuche, Datenblätter und viele nützliche Informationen&lt;br /&gt;
* http://www.ecomponents-store.com/ Elektronische Bauelemente kaufen - Hier finden Sie eine große Auswahl an elektronischen und elektromechanischen Bauelementen von über 40 Herstellern.&lt;br /&gt;
* http://www.franchised-distributors.eu/ - Finden Sie Vertragsdistributoren von über 800 Halbleiterherstellern für elektronische und elektromechanische Bauelemente.&lt;br /&gt;
&lt;br /&gt;
TODO: elektronik-fundgrube&lt;br /&gt;
&lt;br /&gt;
==Messgeräte ==&lt;br /&gt;
=== Neue Messgeräte ===&lt;br /&gt;
&lt;br /&gt;
Viele der oben genannten Elektronikversender verkaufen auch Messgeräte. Darüber hinaus gibt es diverse Versender, die sich hauptsächlich oder ausschließlich auf Messgeräte spezialisiert haben. Allerdings verkaufen viele davon nicht an Privat.&lt;br /&gt;
&lt;br /&gt;
==== CalPlus GmbH ====&lt;br /&gt;
Homepage: http://www.calplus.de &amp;lt;br /&amp;gt;&lt;br /&gt;
Shop: http://www.scopeshop.de&lt;br /&gt;
&lt;br /&gt;
==== Cosinus ComputerMesstechnik ====&lt;br /&gt;
Homepage: http://www.cosinus.de&lt;br /&gt;
&lt;br /&gt;
* Nicht an Privat&lt;br /&gt;
&lt;br /&gt;
==== dataTec ====&lt;br /&gt;
Homepage: http://www.datatec.de&lt;br /&gt;
&lt;br /&gt;
* Große Auswahl&lt;br /&gt;
* Nicht an Privat&lt;br /&gt;
&lt;br /&gt;
==== Donald4646 ====&lt;br /&gt;
Homepage: http://www.donald4646.co.uk&lt;br /&gt;
&lt;br /&gt;
* In Schottland&lt;br /&gt;
* Als eBay-Shop gestartet&lt;br /&gt;
* Einfache, No-Name und Billigmarken (z.&amp;amp;nbsp;B. Oszilloskope)&lt;br /&gt;
&lt;br /&gt;
==== Elektronik-Kontor Messtechnik GmbH ====&lt;br /&gt;
Homepage: http://www.ekomess.de&lt;br /&gt;
&lt;br /&gt;
==== Meilhaus Electronic GmbH ====&lt;br /&gt;
Homepage: http://www.meilhaus.de&lt;br /&gt;
&lt;br /&gt;
* Diverse Markenhersteller&lt;br /&gt;
* Eigenmarken&lt;br /&gt;
&lt;br /&gt;
==== PinSonne-Elektronik ====&lt;br /&gt;
Homepage: http://www.pinsonne-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* Onlineshop&lt;br /&gt;
* Sehr kleines Sortiment&lt;br /&gt;
* UNI-T, RIGOL und andere asiatische Firmen&lt;br /&gt;
&lt;br /&gt;
==== PK elektronik Poppe GmbH ====&lt;br /&gt;
Homepage: http://www.pk-elektronik.de&lt;br /&gt;
&lt;br /&gt;
* U.a. Fluke Distributor.&lt;br /&gt;
&lt;br /&gt;
====Präzitronic Hennig / Messgeräte Chemnitz====&lt;br /&gt;
Homepage: http://www.messgeraete-chemnitz.de&lt;br /&gt;
&lt;br /&gt;
* Owon&lt;br /&gt;
* Selbst übersetzte deutsche Owon-Handbücher&lt;br /&gt;
* Fluke&lt;br /&gt;
* Zusätzlich kleines Angebot an Gebrauchtgeräten&lt;br /&gt;
&lt;br /&gt;
==== ScopeShop Hamburg ====&lt;br /&gt;
&lt;br /&gt;
* Von CalPlus übernommen, siehe [[#CalPlus_GmbH|CalPlus]]&lt;br /&gt;
&lt;br /&gt;
==== SI Scientific Instruments GmbH ====&lt;br /&gt;
Homepage: http://www.si-scientific.de (Onlineshop) &amp;lt;br /&amp;gt;&lt;br /&gt;
Homepage: http://www.si-gmbh.de (komplettes Programm)&lt;br /&gt;
&lt;br /&gt;
* Onlineshop auf si-scientific.de&lt;br /&gt;
* Akzeptiert PayPal&lt;br /&gt;
 &lt;br /&gt;
==== SKY Messtechnik GmbH ====&lt;br /&gt;
Homepage: http://www.sky-messtechnik.de&lt;br /&gt;
&lt;br /&gt;
* Kein Onlineshop (E-Mail oder Telefon)&lt;br /&gt;
&lt;br /&gt;
==== TESTEC ====&lt;br /&gt;
Homepage: http://www.testec.info&lt;br /&gt;
&lt;br /&gt;
* Tastköpfe-Hersteller&lt;br /&gt;
* Hameg Vertriebspartner&lt;br /&gt;
* B+K Precision Generalimporteur&lt;br /&gt;
&lt;br /&gt;
==== Zeitech ====&lt;br /&gt;
Homepage: http://zeitech.eu/shop/&lt;br /&gt;
&lt;br /&gt;
* Diverses (Rigol, Owon, etc.)&lt;br /&gt;
&lt;br /&gt;
=== Gebrauchte Messgeräte ===&lt;br /&gt;
&lt;br /&gt;
Dieser Abschnitt enthält Anbieter bei denen gebrauchte Messgeräte erhältlich sind.&lt;br /&gt;
&lt;br /&gt;
==== Astro Electronic ====&lt;br /&gt;
Homepage: http://www.astro-electronic.de&lt;br /&gt;
&lt;br /&gt;
==== eumex GmbH ====&lt;br /&gt;
Homepage: http://www.eumes.com/pub/de/&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
&lt;br /&gt;
==== HTB-Elektronik ====&lt;br /&gt;
Homepage: http://www.htb-elektronik.com&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
&lt;br /&gt;
==== IX Instrumex ====&lt;br /&gt;
Homepage: http://www.instrumex.de/index.cgi?User:LANGUAGE=de&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
&lt;br /&gt;
==== Christoph Lüders MessTechnik ====&lt;br /&gt;
Homepage: http://www.CLMT.de &amp;lt;br&amp;gt;&lt;br /&gt;
Online-Shop: http://www.shop-016.de/shop-CLMT.html &amp;lt;br&amp;gt;&lt;br /&gt;
eBay: http://myworld.ebay.de/c_h_r/&lt;br /&gt;
&lt;br /&gt;
* Hat 2010 die Restbestände von Förtig übernommen&lt;br /&gt;
&lt;br /&gt;
==== mbmt Messtechnik ====&lt;br /&gt;
Homepage: http://www.mbmt.com&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
* Verkauf nur an Gewerbetreibende&lt;br /&gt;
&lt;br /&gt;
==== Rosenkranz Elektronik ====&lt;br /&gt;
Homepage: http://www.rosenkranz-elektronik.de&amp;lt;br&amp;gt;&lt;br /&gt;
eBay Shop: http://stores.ebay.de/Rosenkranz-Elektronik-GmbH-Shop&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
* Auch auf eBay zu finden&lt;br /&gt;
&lt;br /&gt;
==== Helmut-Singer-Elektronik ====&lt;br /&gt;
Homepage: http://www.helmut-singer.de&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
* Verkauf auch an Privat&lt;br /&gt;
* An den meisten Samstagen im Jahr auch Lagerverkauf, sonst Versand&lt;br /&gt;
&lt;br /&gt;
==== Sphere ====&lt;br /&gt;
Homepage: http://www.sphere.bc.ca&amp;lt;br&amp;gt;&lt;br /&gt;
Messgeräte und Ersatzteile: http://www.sphere.bc.ca/test/index.html&lt;br /&gt;
&lt;br /&gt;
* Gebrauchte Messgeräte&lt;br /&gt;
* Ersatzteile&lt;br /&gt;
** Besonders bekannt für Tektronix-Ersatzteile&lt;br /&gt;
&lt;br /&gt;
==== Tektronix TekSelect ====&lt;br /&gt;
Homepage: http://www.tek.com/Measurement/tekselect/&lt;br /&gt;
&lt;br /&gt;
* Tektronix verkauft selber gebrauchte und überarbeitete Tektronix-Messgeräte unter dem Label &#039;&#039;TekSelect&#039;&#039;.&lt;br /&gt;
* Original Tektronix-Garantie&lt;br /&gt;
* Der Bestellvorgang nervt, man muss Kontaktaufnahme durch einen &amp;quot;Representative&amp;quot; erbeten.&lt;br /&gt;
&lt;br /&gt;
== Siehe auch ==&lt;br /&gt;
* [[Platinenhersteller]]&lt;br /&gt;
* [[Lokale Elektroniklieferanten]]&lt;br /&gt;
* [[Eisenwarenversender]]&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
&lt;br /&gt;
* http://www.xs4all.nl/~ganswijk/chipdir/ Suche nach integrierten Schaltkreisen&lt;br /&gt;
* http://www.alldatasheet.com                Datenblätter&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Bauteile|!]]&lt;br /&gt;
[[Kategorie:Lieferanten]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Linksammlung&amp;diff=62286</id>
		<title>Linksammlung</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Linksammlung&amp;diff=62286"/>
		<updated>2011-12-08T16:35:10Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* Ungewöhnliche Basteleien (Hacks) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Auf dieser Seite werden Links zu anderen interessanten Mikrocontroller- und Elektronikseiten gesammelt.&lt;br /&gt;
&#039;&#039;&#039;&lt;br /&gt;
Die alte Linkseite findet man [http://www.mikrocontroller.net/en/links hier].&lt;br /&gt;
&lt;br /&gt;
Hinzufügen von Links:&lt;br /&gt;
# [http://www.mikrocontroller.net/wikisoftware/index.php?title=Linksammlung&amp;amp;action=edit Bearbeiten] anklicken&lt;br /&gt;
# Link unter der entsprechenden Kategorie eintragen&lt;br /&gt;
# &amp;quot;Artikel speichern&amp;quot; klicken&lt;br /&gt;
&lt;br /&gt;
== Suchen &amp;amp; Finden ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;Verkauf einem hungrigen Mann einen Fisch und du hast ein Geschäft gemacht, bring ihm das Angeln bei und du hast einen Kunden verloren! (asmo)&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* [http://www.supplyframe.com/ SupplyFrame] - Datasheet and Electronic Spec Search Engine&lt;br /&gt;
* [http://www.globalspec.com/ GlobalSpec] - The Engineering Search Engine&lt;br /&gt;
* [http://www.alldatasheet.com/ alldatasheet] - Datasheet Search&lt;br /&gt;
* [http://www.datasheetarchive.com/ datasheetarchive] - Datasheet Search&lt;br /&gt;
* [http://www.datasheetcatalog.com/ datasheetcatalog] - Datasheet Search&lt;br /&gt;
* [http://www.msarnoff.org/chipdb/ ChipDB] - Pinouts von gängigen µCs.&lt;br /&gt;
&amp;lt;!-- SPAM&lt;br /&gt;
* [http://www.TechTour.net] - Angebote und Technische Beratung von mehreren Anbietern gleichzeitig einholen. Von der Elektronik Entwicklung über Leiterplatten Bestückung, von Leiterplatten über Folientastaturen, Gehäusen bis zur Kabelkonfektion.&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== [[AVR]] ==&lt;br /&gt;
&lt;br /&gt;
=== Herstellerseiten ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.atmel.com/products/avr/ Atmel.com] Herstellerseiten&lt;br /&gt;
* [http://www.atmel.com/dyn/products/product_whatchanged.asp?category_id=163&amp;amp;family_id=607 Atmel.com updates] Liste der letzten Änderungen in Datenblättern und Beispielcode für AVR(8) und AVR32&lt;br /&gt;
* [http://www.msc-ge.com/de/produkte/elekom/mc/atmel/avr_start.html AVR Produktinfos] AVR Infos vom Atmel Distributor MSC Vertriebs GmbH&lt;br /&gt;
&lt;br /&gt;
=== Information (Foren, Mailinglisten, Linksammlungen) ===&lt;br /&gt;
* [http://progforum.com Batronix Elektronik Forum] Gut besuchtes Forum für allgemeine Elektronik, Mikrocontroller und Programmierung&lt;br /&gt;
* [http://www.avrfreaks.net/ AVR Freaks] AVR Forum, Samples, Tutorials, User-Projekte, GCC für AVR (Registrierung empfohlen)&lt;br /&gt;
* [http://avr-asm.tripod.com Atmel AVR ASM Site]&lt;br /&gt;
* [http://www.mikrocontroller.net Mikrocontroller.net] - AVR Tutorials, Examples, LINKS, Forum (D)&lt;br /&gt;
&amp;lt;!-- offline 4/2010&lt;br /&gt;
* [http://www.openavr.org/ Openavr.org] &amp;quot;central repository of information for the various open source tools available for the development of software for Atmel&#039;s AVR family of 8-bit RISC microcontrollers&amp;quot;&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!-- offline 4/2010&lt;br /&gt;
* [http://www.omegav.ntnu.no/avr/resources.php3 Omega V&#039;s AVR Resource List]&lt;br /&gt;
* [http://www.omegav.ntnu.no/avr/newresources.php3 Omega V&#039;s AVR NEW Resource List]&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* [http://www.ipass.net/hammill/newavr.htm Atmel AVR Embedded Microcontroller Resources]&lt;br /&gt;
* [http://members.tripod.com/Stelios_Cellar/AVR/AVR%20Info.html Stelios Cellar Atmel AVR Info Page] - Samples, Links&lt;br /&gt;
* [http://www.elektronik-projekt.de Elektronik Projekt] - Hauptthemen sind AVR und Roboter&lt;br /&gt;
&amp;lt;!-- offline 4/2010&lt;br /&gt;
* [http://www.microschematic.com/ AVR Microcontroller inside] (nett gemacht, Engl. Seite am 07-09-2008 nicht erreichbar)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&amp;lt;!-- offline 4/2010&lt;br /&gt;
* [http://electrons.psychogenic.com/avr/ Intro To AVR Microcontrollers] (noch(?) sehr wenig Information)&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* [http://popularmicrocontrollers.com/ AVR Microcontrollers] - A web site about AVR microcontrollers&lt;br /&gt;
&amp;lt;!-- Dieser Unterabschnitt ist für AVR. Für PIC gibt es einen eigenen Unterabschnitt weiter unten. --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Entwicklungswerkzeuge (Compiler/Assembler/Debugger/Tools/Libraries) ===&lt;br /&gt;
&lt;br /&gt;
==== C ====&lt;br /&gt;
* [http://sourceforge.net/projects/winavr WinAVR] (pronounced &amp;quot;whenever&amp;quot;) is a suite of executable, open source software development tools for the Atmel AVR series [for the] Windows platform&amp;quot; (includes GNU GCC) &lt;br /&gt;
* [http://sourceforge.net/projects/kontrollerlab KontrollerLab] is a free GPL open-source development environment based on KDE, using the avr-gcc, UISP and AVRDUDE&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/ avr-libc] avr-gcc&#039;s &amp;quot;standard&amp;quot;-library&lt;br /&gt;
&amp;lt;!-- * [http://hubbard.engr.scu.edu/embedded/avr/avrlib/ Procyon AVRlib] a lot of device drivers and Visual-Studio link for avr-gcc --&amp;gt;&lt;br /&gt;
* [http://hubbard.engr.scu.edu/embedded/avr/avrlib/ Procyon AVRlib] a lot of device drivers and Visual-Studio link for avr-gcc&lt;br /&gt;
* [http://rod.info/avr.html rod.info on AVR] esp. for AVR GNU development tools setup under Linux&lt;br /&gt;
* [http://www.sisy.de SiSy AVR] - graphische Entwicklungsumgebung mit C/C++ Codegenerierung aus Struktogrammen und Klassendiagrammen&lt;br /&gt;
* [http://shop.embedit.de/product__206.php AtmanAVR C/C++ IDE]&lt;br /&gt;
* [http://www.iar.com IAR Embedded Workbench]&lt;br /&gt;
* [http://www.hpinfotech.com CodeVisionAVR] C-Compiler für AVRs mit Terminal&lt;br /&gt;
* [http://www.myAVR.de myAVRWorkpad] kompakte Entwicklungsumgebung für AVRs mit Terminal&lt;br /&gt;
* [http://www.amctools.com/vmlab.htm VMLab] komplette IDE mit Debugger und Simulator (auch Peripheriehardware)&lt;br /&gt;
* [http://www.forestmoon.com/Software/AvrIoDesigner/ AVR IO Designer] is a utility to generate initialization source code in C/C++ for the various devices, ports and registers of Atmel AVR processors. The intent is to allow the user to explore the devices specific to a selected processor and experiment with settings thru a user interface that assists in understanding the complexities involved. The user can also assign custom variable names to PORT IO pins thereby keeping track of the IO resources in use. These names are emitted in the generated code for use in the user’s program. (Windows .NET 2.0 erforderlich)&lt;br /&gt;
* [http://www.piconomic.co.za/avrlib/index.html Piconomic AVRLIB] is a collection of firmware for Atmel AVR microcontrollers. The aim is to share source code, experience and expertise (in the eye of the beholder) with the community of engineers, scientists and enthusiasts.&lt;br /&gt;
* [http://www.imagecraft.com/devtools_AVR.html Imagecraft] Der ICCAVR C Compiler fuer AVR von Imagecraft.&lt;br /&gt;
&lt;br /&gt;
==== Assembler ====&lt;br /&gt;
&lt;br /&gt;
* [http://avr-asm.tripod.com Atmel AVR ASM Site]&lt;br /&gt;
* [http://www.tavrasm.org/ tavrasm] - Toms Linux (Atmel) AVR Assembler&lt;br /&gt;
* [http://www.avr-asm-tutorial.net/gavrasm/index_de.html gavrasm] - Gerds Linux/Win/DOS AVR Assembler &lt;br /&gt;
* [http://avra.sourceforge.net/ avra] - avra ATMEL AVR Assembler für Linux, FreeBSD, AmigaOS und Win32&lt;br /&gt;
* [http://algrom.net/english.html Algorithm Builder] - graphische Makro-Assembler Entwicklungsumgebung&lt;br /&gt;
* [http://www.sisy.de SiSy AVR] - graphische Entwicklungsumgebung mit Assembler Codegenerierung aus Programmablaufplänen&lt;br /&gt;
* [http://www.sbprojects.com/sbasm/sbasm.htm SB-Assembler] - Freeware Cross-Assembler unter DOS. (6502, 6800, 6801, 6804, 6805, 6809, 68HC08, 68HC11, Z8, Z80, Z180, 8080, 8085, 8021, 8041, 8048, 8051, AVR, PIC1684,...)&lt;br /&gt;
* [http://www.myAVR.de myAVRWorkpad] kompakte Entwicklungsumgebung für AVRs mit Terminal&lt;br /&gt;
* [http://john.ccac.rwth-aachen.de:8000/as/ Macro Assembler AS] - AS is a portable macro cross assembler for a variety of microprocessors and -controllers&lt;br /&gt;
* [http://shop-pdp.kent.edu/ashtml/asxxxx.htm ASxxxx Cross Assemblers] - The ASxxxx assemblers are a series of microprocessor assemblers written in the C programming language. (1802, S2650, C/MP, MSP430, 61860, 6500, 6800(6802/6808), 6801(6803/HD6303), 6804, 6805, 68HC(S)08, 6809, 68HC11, 68HC(S)12, 68HC16, 740, 8048(8041/8022/8021) 8051, 8085(8080), DS8xCxxx, AVR, Z80, F2MC8L/FX, GameBoy(Z80), H8/3xx, Cypress PSoC(M8C), PIC, Rabbit 2000/3000, Z8, Z80(HD64180)) linux &amp;amp; windows, source code&lt;br /&gt;
&lt;br /&gt;
==== Disassembler ====&lt;br /&gt;
&lt;br /&gt;
* [http://www.datarescue.com/idabase/ IDA-Pro] -Disassembler und Debugger für fast alle bekannten Prozessoren. Evaluation Version verfügbar. Tagline: &#039;&#039;The most advanced tool for Hostile Code Analysis, Vulnerability and Software Reverse Engineering&#039;&#039;&lt;br /&gt;
* [http://www.jassenbaum.de/ja-tools/ ReAVR] - Disassembler und ACXutility Binary Tool&lt;br /&gt;
* [http://www.visi.com/~dwinker/revava/ revava] - Disassembler&lt;br /&gt;
* [http://dev.frozeneskimo.com/software_projects/vavrdisasm vAVRdisasm] - Free AVR Disassembler&lt;br /&gt;
* [http://www.johannes-bauer.com/mcus/avrdisas/ avrdisas] - AVR Mikrocontroller Disassembler für Linux (und Win32)&lt;br /&gt;
&amp;lt;!-- * [http://biew.sourceforge.net/en/biew.html BVIEW] is multiplatform portable viewer of binary files with built-in editor in binary, hexadecimal and disassembler modes. It includes &#039;&#039;&#039;AVR&#039;&#039;&#039;/Java/i86-i386-AMD64/ARM-XScale/PPC64 disassemblers, russian codepages convertor, full preview of formats - MZ, NE, PE, NLM, coff32, elf partial - a.out, LE, LX, PharLap; code navigator and more over. (GPL) - 404, 6.9.2010 --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== BASIC ====&lt;br /&gt;
* [http://www.mcselec.com/bascom-avr.htm Bascom AVR]&lt;br /&gt;
* [http://www.fastavr.com FastAVR] - und mit &#039;ASM&#039; Ausgabe, Nokia3310 LCD Unterstützung&lt;br /&gt;
* [http://www.nettypes.de/mbasic mikrocontrollerBASIC Freeware] - mit Simulator für ATmega32, ATmega128 und C-CONTROL.&lt;br /&gt;
* [http://www.mikroe.com/en/compilers/mikrobasic/avr/ mikroBasic] - Comprehensive, stand-alone Basic compiler for AVR microcontrollers&lt;br /&gt;
* [http://home.arcor.de/EDAconsult/Page3/index.html?c~3.1 MCS BASIC-52] - Original-Übersetzung 1988 INTEL MCS BASIC-52 USERS MANUAL 220 Seiten frei Download als PDF&lt;br /&gt;
* [http://www.DieProjektseite.de Beetle-Basic] Leistungsfähiges Basic-Betriebssystem im AVR.&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/AVR_BASIC AVR_BASIC] Open Source Freeware: Minimalistischer Basic-Interpreter  im AVR.&lt;br /&gt;
* [http://gcbasic.sourceforge.net/ Great Cow BASIC] &amp;quot;Open Source BASIC programming tools for Microchip PIC and Atmel AVR microcontrollers&amp;quot;&lt;br /&gt;
&lt;br /&gt;
==== Pascal ====&lt;br /&gt;
* [http://www.e-lab.de AVRco Pascal Compiler] - AVR Pascal Compiler mit umfangreicher Funktionslibrary&lt;br /&gt;
* [http://www.mikroe.com/en/compilers/mikropascal/avr/ mikroPascal] - Comprehensive, stand-alone Pascal compiler for AVR microcontrollers&lt;br /&gt;
&lt;br /&gt;
==== Forth ====&lt;br /&gt;
* [http://www.robo-forth.de www.robo-forth.de] - AVR Forth Compiler mit umfangreicher Funktionslibrary für Servos, Motore und Sensoren&lt;br /&gt;
* [http://amforth.sourceforge.net/ amforth] - Forth for Atmel ATmega micro controllers von Matthias Trute. [http://www.mikrocontroller.net/topic/55807#430816 Diskussion]&lt;br /&gt;
&lt;br /&gt;
==== Java ====&lt;br /&gt;
* [http://www.harbaum.org/till/nanovm NanoVM] - Java VM für AVR-Mikrocontroller ([[NanoVM|deutsches Wiki]])&lt;br /&gt;
* [http://www.fam-frenz.de/stefan/compiler.html SJC] - Java-Compiler (erzeugt AVR-Maschinencode) für AVR-Mikrocontroller ([[SJC]])&lt;br /&gt;
&lt;br /&gt;
==== Ada ====&lt;br /&gt;
* [http://avr-ada.sourceforge.net/ AVR-Ada] - Ada Compiler innerhalb von GCC (GNAT) für AVR.  Enthält eine kleine Laufzeitbibliothek ohne Tasking und ohne Exceptions. [http://www.mikrocontroller.net/topic/168823#1614208]&lt;br /&gt;
&lt;br /&gt;
==== Virgil ====&lt;br /&gt;
* [http://compilers.cs.ucla.edu/virgil/index.html The Virgil Programming Language] is designed for building robust, flexible, and scalable software systems on embedded hardware platforms. Virgil builds on ideas from object-oriented, statically typed languages like Java, providing a clean, consistent source language. Its compiler system provides an efficient implementation for resource-constrained environments.&lt;br /&gt;
&lt;br /&gt;
==== LabVIEW ====&lt;br /&gt;
* http://www.ni.com/embedded/ Informationen zu LabVIEW, der graphischen Entwicklungsumgebung von National Instruments&lt;br /&gt;
* http://www.labviewforum.de/ Deutsches Labview-Forum&lt;br /&gt;
* [http://web.me.com/iklln6/automation/LabVIEW.html Communicating Arduino--&amp;gt;LabVIEW]&lt;br /&gt;
&lt;br /&gt;
==== Python ====&lt;br /&gt;
* [http://code.google.com/p/python-on-a-chip/ python-on-a-chip] (pymite). There are two sample projects in the source tree.  One for an 8-bit Atmel ATmega103 (but any AVR/ATmega with 4 KB RAM or more will do) and one for the 32-bit Atmel AT91SAM7S64 running on the AT91SAM7S-EK evaluation board. (GPL Lizenz)&lt;br /&gt;
&lt;br /&gt;
==== Openeye ====&lt;br /&gt;
&lt;br /&gt;
* OpenEye ist eine Kombination aus PC-Programm (Windows, Delphi) und einer Monitor-Routine im AVR. Die Daten aus dem AVR werden mit RS232 übertragen und können fürs Debuggen der laufenden Anwendung benutzt werden. OpenEye wurde vom User Martin Vogel (oldmax) geschrieben [http://www.mikrocontroller.net/topic/143144#1326244].&lt;br /&gt;
&lt;br /&gt;
==== Modkit ====&lt;br /&gt;
&lt;br /&gt;
[http://blog.modk.it/ Modkit] is a new kind of graphical programming environment that makes programming things in the physical world as easy as dragging and dropping little virtual code blocks in a web browser.. Heavily inspired by the Scratch programming environment (from MIT Media Lab&#039;s Lifelong Kindergarten Group), Modkit enables anyone including kids, artists and inventors to build with electronic kits and components including motors, sensors, lights, sound and the popular Arduino and Arduino compatible development boards... (Text vom Makezine)&lt;br /&gt;
&lt;br /&gt;
=== Tutorials und Beispiele ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.meinemullemaus.de/elektronik/avr_workshop/index.html AVR Mikrocontroller] Einfühung in AVR Mikrocontroller mit Nachbau des Spiels &amp;quot;Senso&amp;quot;.&lt;br /&gt;
* [http://www.avrbeginners.net AVRBeginners.net] Beginners Guides to AVRs&lt;br /&gt;
* [http://www.wikidorf.de/reintechnisch/Inhalt/AVRProjekt-9V-LED-Lampe reintechnisch.de] AVR Tutorial: 9V-LED-Lampe&lt;br /&gt;
* [http://www.schaltungsforum.de Das Schaltungsforum] ist eine Seite für Anfänger und Profis welche ständig mit Tutorials erweitert wird. Stellt Eure Projekte online. Die Seite befindet noch im Aufbau und Eure Mithilfe ist erwünscht.&lt;br /&gt;
* [http://www.mikrocontrollerspielwiese.de mikrocontrollerspielwiese.de] ist eine Seite, die an Anfänger gerichtet ist und Experimente und fertige Projekte komplett mit Code und Eagle-Dokumenten zur Verfügung stellt.&lt;br /&gt;
* [http://www.elo-web.de/elo/mikrocontroller-und-programmierung/avr-anwendungen ELO-AVR-Anwendungen] bietet eine wachsende Sammlung kleinerer AVR-Projekte, überwiegend für die ATTiny-Serie.&lt;br /&gt;
* [http://www.schramm-software.de/tipps/ AVR-Tipps] Programmier-Tipps und AVR-Experimente.&lt;br /&gt;
* [http://www.uwe-kerwien.de/pll/pll-synthesizer.htm PLL-Synthesizer Tutorial] kleines praxisorientiertes PLL-Tutorial zur Funktion, Reparatur und Steuerung einer PLL-Schaltung mit AVR ATtiny2313 über 3-Leiter-Bus&lt;br /&gt;
* Arduino&lt;br /&gt;
** [http://tronixstuff.wordpress.com/tutorials/ t r o n i x s t u f f] - Arduino Tutorials (engl.)&lt;br /&gt;
** [http://www.earthshinedesign.co.uk/ASKManual/Site/ASKManual.html The Complete Beginners Guide to the Arduino]&lt;br /&gt;
** [http://www.codeproject.com/KB/system/ArduinoVB.aspx Arduino with Visual Basic] by Carl Morey auf codeproject.com&lt;br /&gt;
&lt;br /&gt;
==== C ====&lt;br /&gt;
* [[AVR-GCC-Tutorial]]&lt;br /&gt;
* [http://www.smileymicros.com/QuickStartGuide.pdf Quick Start Guide for using the WinAVR Compiler with ATMEL&#039;s AVR Butterfly] ([http://www.smileymicros.com www.smileymicros.com], PDF)&lt;br /&gt;
* [http://www.avrtutor.com/tutorial/thermo/contents.htm avrtutor] - an attempt to provide a real tutorial for the ATMEL AVR microcontrollers.&lt;br /&gt;
* [http://www.sparkfun.com/commerce/present.php?p=BEE-1-PowerSupply Spark Fun Electronics] - Beginning Embedded Electronics (Atmega8, englisch)&lt;br /&gt;
* [http://metku.net/index.html?path=articles/microcontroller-part-1/index_eng metku.net] - How to get started with microcontrollers (ATtiny45, Steckbrett)&lt;br /&gt;
* [http://www.stromflo.de/dokuwiki/doku.php?id=xmega-c-tutorial XMEGA-C-Tutorial] - Tutorial über Atxmega&lt;br /&gt;
&lt;br /&gt;
==== Assembler ====&lt;br /&gt;
* [http://avr-asm.tripod.com Atmel AVR ASM Site]&lt;br /&gt;
* [http://www.avr-asm-tutorial.net Atmel AVR Microcontroller Assembler Tutorial] (D)&lt;br /&gt;
* [[AVR-Studio]]&lt;br /&gt;
&lt;br /&gt;
==== Bascom ====&lt;br /&gt;
* [http://www.mcselec.com/ MCS Elektronik] BASCOM AVR Demo zum Download&lt;br /&gt;
&lt;br /&gt;
==== Pascal ====&lt;br /&gt;
* [http://www.elektronik-projekt.de/content/download/avrco_tut2.pdf AVRco Pascal Tutorial] - von Markus&lt;br /&gt;
* [http://www.ibrtses.com/embedded/avr.html ein paar Seiten zum AVR] (ASM und Pascal) von ibrt&lt;br /&gt;
&lt;br /&gt;
==== Ada ====&lt;br /&gt;
* [http://sourceforge.net/apps/mediawiki/avr-ada/index.php?title=Tutorial AVR-Ada Tutorial]&lt;br /&gt;
&lt;br /&gt;
=== Hardware (Prototypen-Platinen-Boards etc.) ===&lt;br /&gt;
&lt;br /&gt;
* [http://retrodan.tripod.com Atmel AVR Butterfly Site]&lt;br /&gt;
* [http://www.kanda.com Kanda] Starter Kits and Development Tools for different Microcontrollers&lt;br /&gt;
* [http://www.dontronics.com Dontronics] Starter Kits and Development Tools for different Microcontrollers, Linkpages for AVR and PIC&lt;br /&gt;
* [http://www.mikrocontroller.com mikrocontroller.com] u.a. Platine AVR-Ctrl, AVR-Webserver (D)&lt;br /&gt;
* [http://mikrocontroller.cco-ev.de/eng/ AVR webserver] RTL8019, 3COM (E) &lt;br /&gt;
* [http://www.microcontroller-starterkits.de Microcontroller-Starterkits] Starter Kits for different Microcontrollers (D)&lt;br /&gt;
* [http://www.olimex.com Olimex Ltd.] DevelopmentBoards and Tools&lt;br /&gt;
* [http://www.krause-robotik.de Krause Robotik] Controller Boards &amp;amp; Zubehör&lt;br /&gt;
* [http://www.robotikhardware.de robotikhardware.de] Controller Boards&lt;br /&gt;
* [http://www.embedded-it.de/microcontroller/microcontroller-module.php Embedded-IT] USB Module auf AVR Basis sowie Ethernut kompatible Embedded Ethernet Mikrocontroller Boards für Industrie und Hobby auf ARM mit Nut/OS Betriebssystem&lt;br /&gt;
* [http://www.ssv-embedded.de SSV Embedded Systems] 32-bit Mikrocontrollermodule und -boards, Starter Kits etc.&lt;br /&gt;
* [http://shop.embedit.de/browse_002_21__.php Embedit] Mikrocontrollermodule und -boards&lt;br /&gt;
* [http://www.display3000.com Display3000] Farbdisplays, Mikrocontrollermodule und -boards mit TFT-Farbdisplays; Experimentierplatinen und Ansteuerplatinen für TFT Farbdisplays&lt;br /&gt;
* [http://www.myavr.de myAVR] Einsteigerboards und Zubehör&lt;br /&gt;
* [http://www.siphec.com/ SIPHEC] Development Boards für AVR, MSP430, USB&lt;br /&gt;
* [http://www.pollin.de/shop/shop.php?cf=detail.php&amp;amp;pg=OA==&amp;amp;a=MTY5OTgxOTk=&amp;amp;w=OTk4OTY4&amp;amp;ts=0 ATMEL Evaluations-Board Bausatz] ([http://www.pollin.de/shop/downloads/D810038B.PDF PDF]) und [http://www.pollin.de/shop/shop.php?cf=detail.php&amp;amp;pg=OA==&amp;amp;a=MzU5OTgxOTk=&amp;amp;w=OTk4OTY4&amp;amp;ts=0 ATMEL Funk-Evaluations-Board Bausatz] ([http://www.pollin.de/shop/downloads/D810046B.PDF PDF]) von Pollin&lt;br /&gt;
* [http://www.lochraster.org/etherrape/ Etherrape] Atmaga 644 mit Ethernet und TCP/IP als Bausatz.&lt;br /&gt;
* [http://www.ic-board.de/index.php?cat=c4_Programmer.html AVR Programmieradapter],[http://www.ic-board.de/index.php?cat=c3_Funkmodule.html ZigBee-ready Funkmodule/Funk-USB-Sticks] und [http://www.ic-board.de/index.php?cat=c13_ICradio-Bundles.html Funk Starterkits] von In-Circuit&lt;br /&gt;
* [http://www.ic-board.de/index.php?cat=c2_ICnova-Module.html AVR32 AP7000 Linux Board] mit 2xEthernet, TFT, Audio, SDCARD, USB-Host/Devive, Funk...&lt;br /&gt;
* [http://www.das-labor.org/wiki/Laborboard Das Laborboard] von das-labor.org (DIY)&lt;br /&gt;
* [http://six.media.mit.edu:8080/6 number six] - Open Source Design, Atmega32. Alle Pins sind auf eine 2x20 Pol Wannenstiftleiste herausgeführt.&lt;br /&gt;
* http://www.maares.de/tools USB Memory Stick am AVR Butterfly. AVR Butterfly Trägerplatine zum Anschluß von VDRIVE, VMUSIC, RFM12.&lt;br /&gt;
* [http://www.wiring.org.co/ Wiring] is an open source programming environment and electronics i/o board for exploring the electronic arts, tangible media, teaching and learning computer programming and prototyping with electronics.&lt;br /&gt;
* [http://www.chip45.com/ chip45] Atmel AVR Module und Boards mit USB, RS232/485, CAN, Ethernet, Funkmodule, sowie ISP Programmieradapter.&lt;br /&gt;
* [http://www.rakers.de/catalog Dr. Rakers] &amp;lt;b&amp;gt;AVR Boards und Experimentierplatinen&amp;lt;/b&amp;gt; mit USB, Ethernet, RS232, CAN, LCD etc. in hochwertiger Qualität zu günstigen Preisen.&lt;br /&gt;
* [http://nibo.nicai-systems.de Roboterbausatz Nibo] - autonomer &amp;lt;b&amp;gt;Roboter&amp;lt;/b&amp;gt; mit einem ATmega128 und einem ATmega88&lt;br /&gt;
* [http://www.aevum-mechatronik.de Modularis] - AVR Mikrocontroller-Boards (z.T. mit Zusatz-Speicher und USB) die über Flachbandkabel erweitert werden können. Es gibt bis jetzt Zubehör-Module mit Taster, Motor H-Brücke, XBee und Winkelsensor.&lt;br /&gt;
* [http://www.schramm-software.de/bausatz/ Schramm-Software] - AVR Mikrocontroller-Bausätze&lt;br /&gt;
* [http://www.alvidi.de/ Alvidi] - Headerboards mit AVR &amp;amp; AVR32 Controllern&lt;br /&gt;
* [http://www.steitec.net/ Steinert Technologies] - Thailändischer Anbieter von Mikrocontroller Boards (AVR, ARM7, ARM9, PIC, dsPIC, PSoC, uvm.)&lt;br /&gt;
* Arduino&lt;br /&gt;
** [http://www.arduino.cc/ Arduino] Homepage&lt;br /&gt;
** [http://www.freeduino.org/ Freeduino.org] - Riesige Linksammlung zu dem &#039;&#039;&#039;Ardunio&#039;&#039;&#039;(R) AVR-Board (Kit) und dessen Clones und Mutanten (DIY oder Kit)&lt;br /&gt;
** [http://www.freeduino.de/ freeduino.de] - Anleitungen und Tutorials, Arduino Wiki, Blog, Tools in Deutsch&lt;br /&gt;
** [http://shieldlist.org/ Arduino Shield List]&lt;br /&gt;
* [http://www.fritzing.org Fritzing] nützliches Programm für viele Betriebsysteme zur Unterstützung eines Brettboard-Aufbaus(ungetestet).&lt;br /&gt;
* [http://www.specialprint.eu Specialprint] InkjetDruck für den digitalen Direktdruck von Ätzmasken, Lötstoppmasken, Frontplatten, Kennzeichnungen&lt;br /&gt;
* [http://www.onlinesteuerung.de Onlinesteuerung.de] USB Bausatz. Technische Geräte per PC, Browser, Netzwerk, Ethernet, TCP/IP, Internet, Excel, Timer oder Sensoren schalten.&lt;br /&gt;
* [http://8devices.com/product/3/wi-fi-4-things Carambola WiFi module] Open hardware Linux friendly (OpenWRT) WiFi 802.11n OEM module&lt;br /&gt;
* [http://www.atxmega-board.de ATxMegaBoard und ATxMegaStick] Entwicklungsboards, zum Einstig in die Welt der ATxMegas&lt;br /&gt;
&lt;br /&gt;
=== Programmierhard- und Software ===&lt;br /&gt;
* [http://www.obdev.at/products/avrusb/avrdoper.html AVR-Doper] Einfach nachzubauender, STK500-kompatibler Programmer mit USB-Anschluss. Beherrscht auch HVSP, nicht jedoch HVPP. Open Source.&lt;br /&gt;
* [http://www.bsdhome.com/avrdude/ AVRDUDE] AVR ISP-Programmerierwerkzeug für Unix/Linux/BSD und Windows. Kommandozeile [http://sourceforge.net/projects/avrdude-gui/ (oder mit GUI)], AVR Butterfly-Unterstützung&lt;br /&gt;
* [http://www.lancos.com/prog.html PonyProg] neben AVR für diverse seriell programmierbare Bauteile (Grafische Nutzeroberfläche und Kommandozeile), siehe auch [[Pony-Prog Tutorial]]&lt;br /&gt;
* [http://savannah.nongnu.org/projects/uisp/ uisp] AVR ISP-Programmierwerkzeug für Unix/Linux/BSD und Windows (Kommandozeile)&lt;br /&gt;
* [http://www.myplace.nu/avr/yaap/ yaap]&lt;br /&gt;
* [http://www.xs4all.nl/~sbolt/e-index.html SP12]&lt;br /&gt;
* [http://www.mikrocontroller-projekte.de/Mikrocontroller/AVR-Prog/AVR-Programmer.html AVR910 kompatibler Programmer] mit aktueller, beschleunigter Firmware.&lt;br /&gt;
* [http://www.der-hammer.info/hvprog STK500 kompatibler Programmer] als Nachbauprojekt. Siehe auch [[STK500]]&lt;br /&gt;
* [http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=73&amp;amp;products_id=41 Preiswerter Standard ISP (STK200 kompatibel)]&lt;br /&gt;
*  [http://www.siwawi.arubi.uni-kl.de/avr_projects/evertool/ Evertool] kombinierter ISP &amp;amp; [[JTAG]] Programmer (kompatibel zum &amp;quot;original&amp;quot; Atmel AVRISP und Atmel JTAGICE) &lt;br /&gt;
* [http://www.olimex.com Olimex] (Bulgarischer Anbieter) Kostengünstig&lt;br /&gt;
* [http://www.avr-projekte.de/isp.htm AVR910-USB Programmer] incl. USB-Modul und USB-&amp;gt;Seriell Wandler&lt;br /&gt;
*[http://www.fischl.de/usbasp/ USBasp] &amp;amp;#8211; USB-Programmer bestehend aus ATmega8 (kein spezieller USB-Chip notwendig)&lt;br /&gt;
* [http://home.arcor.de/bernhard.michelis Amadeus-USB] - Highspeed-Programmer für PIC18, PIC24, dsPIC30, PIC32, dsPIC33 und AVR. Bietet auch Möglichkeiten zur Fehlersuche.&lt;br /&gt;
* [http://www.e-dsp.com Signalgenerator] - Signalgenerator software&lt;br /&gt;
* [http://www.piketec.com/products/tpt.php Time Partition Testing (TPT)] - Test-, und Testauswertewerkzeug für eingebettete Systeme&lt;br /&gt;
* [http://shop.myavr.de/Programmer.htm?sp=artlist_kat.sp.php&amp;amp;katID=16 mySmartUSB] - USB Programmer (ab 15€) kombiniert auch mit USB-UART-Bridge, STK500v2/AVR910/AVR911 kompatibel, ISP HV-seriell, HV-parallel&lt;br /&gt;
* [http://www.shop.robotikhardware.de/shop/catalog/product_info.php?cPath=73&amp;amp;products_id=161 USB-Programmer für Bascom Programmierer]&lt;br /&gt;
* [http://www.virtualserialport.com/ Virtual Serial Port] Software for serial port communication and null-modem emulation&lt;br /&gt;
* [http://www.ic-board.de/index.php?cat=c4_Programmer.html AVR Programmieradapter und JTAGICE MKII]&lt;br /&gt;
* [http://www.helmix.at/hapsim/index.htm HAPSIM graphischer Simulator ] zu graphischen Simulation von Tasten /LED /LCD und Terminal in AVR Studio Freeware !!!&lt;br /&gt;
* [http://www.ic-board.de/index.php?cat=c4_Programmer.html AVR Programmieradapter und JTAGICE MKII]&lt;br /&gt;
* [http://www.myavr.de/download.php?suchwort=ProgTool myAVR ProgTool] nette Programmieroberfläche (free)&lt;br /&gt;
* [http://b9.com/elect/avr/kavrcalc/ KAVRCalc] is a free calculator to assist in programming AVR microcontrollers (Baudrate, Watchdog, Timer, ...)&lt;br /&gt;
* [http://www.chip45.com/CrispAVR-USB CrispAVR-USB] STK500 V2 kompatibler ISP Adapter mit USB Schnittstelle für Atmel AVR Mikrocontroller (1,8V-5,5V).&lt;br /&gt;
* [http://ucom-ir.nicai-systems.de UCOM-IR] - Programmieradapter mit USB Schnittstelle (AT90USB162) und IR-Sender/Empfänger, STK500 V2 kompatibel&lt;br /&gt;
* [http://www.anagate.de/products/programmers.htm AnaGate Programmer] Serielle Programmer mit LAN-Anschluss für I2C und SPI inkl. Programmier-API für Windows/Linux (Shop)&lt;br /&gt;
&lt;br /&gt;
=== Projekte und Quellcodebibliotheken ===&lt;br /&gt;
&lt;br /&gt;
====Bibliotheken====&lt;br /&gt;
* [http://www.nongnu.org/avr-libc/ AVR Libc]&lt;br /&gt;
* [http://hubbard.engr.scu.edu/embedded/avr/avrlib/docs/html/index.html Procyon AVRlib]&lt;br /&gt;
* [http://homepage.hispeed.ch/peterfleury Peter Fleury&#039;s Pages] - UART / LCD (HD44780) / I²C (TWI)/ AVR-GCC Bibliotheken, STK500v2 Bootloader&lt;br /&gt;
*[http://sourceforge.net/projects/avrfix  Fixed Point Library Based on ISO/IEC Standard DTR 18037 for Atmel AVR microcontrollers, u.a. Cordic-Algorithmen] und [http://www.enti.it.uc3m.es/wises07/presentations/session2/05%20-%20Fixed%20Point%20Library%20According%20to%20ISOIEC%20Standard%20DTR%2018037%20for%20Atmel%20AVR%20ProcessorsWISES07-fixedpointlibrary%20-%20Elmenreich.pdf  Kurzbeschreibung dazu als Powerpoint-PDF TU Wien Febr. 2007]&lt;br /&gt;
&lt;br /&gt;
==== Betriebssysteme &amp;amp; Co. ====&lt;br /&gt;
* [http://www.tinyos.net/ TinyOS] - Komponentenbasiertes Betriebssystem für Sensorknoten. Bringt eigene C-ähnliche Hochsprache nesC mit.&lt;br /&gt;
* [http://www.chris.obyrne.com/yavrtos/ YAVRTOS] - Yet Another Atmel® AVR® Real-Time Operating System von Chris O&#039;Byrne (C, Atmega32, GPL3 Lizenz)&lt;br /&gt;
* [http://www.freertos.org/ FreeRTOS] is a portable, open source, mini Real Time Kernel - a free to download and royalty free RTOS that can be used in commercial applications. (AVR, MSP430, PIC, ARM7, ...)&lt;br /&gt;
* [http://www.barello.net/avrx/index.htm AvrX Real Time Kernel] (IAR ASM oder IAR/GCC C, GPL2 Lizenz)&lt;br /&gt;
* [http://scmrtos.sourceforge.net/ scmRTOS] - Single-Chip Microcontroller Real-Time Operating System (C++, AVR, MSP430, Blackfin, ARM7, FR (Fujitsu, [http://www.opensource.org/licenses/mit-license.php MIT Lizenz]).&lt;br /&gt;
* [http://www.circuitcellar.com/avr2004/DA3650.html csRTOS] - cooperative single-stack RTOS aus dem Circuit Cellar AVR 2004 Design Contest.  [http://www.avrfreaks.net/index.php?module=Freaks%20Academy&amp;amp;func=viewItem&amp;amp;item_id=987&amp;amp;item_type=project csRTOS port to ATmega32] und [http://www.avrfreaks.net/index.php?name=PNphpBB2&amp;amp;file=viewtopic&amp;amp;t=50743&amp;amp;start=all&amp;amp;postdays=0&amp;amp;postorder=asc Diskussion] auf www.avrfreaks.net führte zur Weiterentwicklung als [http://www.mtcnet.net/~henryvm/4AvrOS/ 4AvrOS] - cooperative scheduler&lt;br /&gt;
* [http://www.avrfreaks.net/index.php?module=Freaks%20Academy&amp;amp;func=viewItem&amp;amp;item_type=project&amp;amp;item_id=230 OPEX] - freeware cooperative scheduler with lots of calendar and I/O functions von Steve Childress (Download auf www.avrfreaks.net ggf. Registrierung notwendig)&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/12176#79672 Scheduler] von Peter Dannegger&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/25087#186454 RTC-Scheduler] von ape&lt;br /&gt;
* [http://www.sics.se/~adam/pt/ Protothreads] - Lightweight, Stackless Threads in C (open source BSD-style license)&lt;br /&gt;
* [http://www.micrium.com/products/rtos/kernel/rtos.html uC/OS-II] is a real time operating system developed by Jean J. Labrosse. You can obtain the source code for the OS by buying Labrosse&#039;s excellent book &#039;&#039;MicroC/OS-II The Real-Time Kernel (2nd edition)&#039;&#039;. [http://www.ee.lut.fi/staff/Julius.Luukko/ucos-ii/avr/index.shtml Port for AVR (gcc 3.x)] and [http://www.myplace.nu/avr/ucos/index.htm AVR (gcc 2.x)].&lt;br /&gt;
* [http://freshmeat.net/projects/qp/ QP] is a lightweight, portable framework/RTOS for embedded systems (ARM, Cortex-M3, 8051, AVR, MSP430, M16C, HC08, NiosII, and x86). GPL (und kommerzielle Lizenz verfügbar)&lt;br /&gt;
* [http://www.femtoos.org/ Femto OS] von  Ruud Vlaming ist ein preemptives Betriebssystem für die kleinsten Mikrocontroller aus der AVR Serie bis ca. 16 KB ROM und 1 KB RAM. Spezielle Targets sind: ATtiny861/461/261. Geschrieben in C. Freie Software, GPLv3. Artikel in Elektor Februar 2010 &lt;br /&gt;
* [http://www.projects-lab.com/?p=344 kaOS] is a real-time, multithreaded, preemptive operating system for the ATmega32 microcontroller, which loads and executes programs from a Secure Digital or MMC card. Authors Nicholas Clark &amp;amp; Adam Liechty. (Circuit Cellar AVR Wettbewerb 2006)&lt;br /&gt;
* [http://helium.sourceforge.net/ Helium] is a minimalistic real-time kernel for the HC(S)08 core by Freescale and Atmel AVR.&lt;br /&gt;
* [http://dev.bertos.org/ BeRTOS] is a completely free, open source, real time operating system (RTOS) suitable for embedded platforms. Runs on many microprocessors and microcontrollers, ranging from 8 bits to 32 bits CPUs and even PCs.&lt;br /&gt;
* [http://funkos.sourceforge.net/ funkos] Targets: AVR, XMEGA, MSP430, Cortex M3, Open Source&lt;br /&gt;
* Vergleich zwischen [http://antipastohw.blogspot.com/2009/11/4-operating-systems-for-arduino.html 4 Operating Systems for the Arduino] auf [http://antipastohw.blogspot.com Liquidware Antipasto]&lt;br /&gt;
** &#039;&#039;&#039;DuinOS&#039;&#039;&#039; by RobotGroup (FreeRTOS Portierung)&lt;br /&gt;
** [http://www.skewworks.com/pyxis/ Pyxis OS] by ArduinoWill&lt;br /&gt;
** &#039;&#039;&#039;ArduinoMacOS&#039;&#039;&#039; by Mark&lt;br /&gt;
** &#039;&#039;&#039;TaOS&#039;&#039;&#039; by Ziplock&lt;br /&gt;
* [http://atomthreads.com/ Atomthreads] is a free, lightweight, portable, real-time scheduler for embedded systems. (BSD Lizenz)&lt;br /&gt;
* [http://www.shift-right.com/xmk/ XMK] (eXtreme Minimal Kernel) ist ein freies Echtzeitbetriebssystem für Mikrocontroller (AVR, H8, R8C, M16C).&lt;br /&gt;
* [http://irtos.sourceforge.net/index.html.en iRTOS] is an free Real Time Operating System. The iRTOS kernel is free to download and use under the terms of LGPL. It can be used in commercial applications. iRTOS is designed for tiny 8 bit microconroller chips with little RAM usage. OS can be installed also in 16 and 32 bit processor units.&lt;br /&gt;
* [http://sites.google.com/site/cocoosorg/avr-projects/home cocoOS] is a cooperative task scheduler, based on coroutines and it is written in C. (STK500, Atmega16)&lt;br /&gt;
* [http://www.DieProjektseite.de BasicBeetle] Basic-Betriebssystem im AVR&lt;br /&gt;
* Shells für Arduino:&lt;br /&gt;
** [http://biot.com/arsh/ ARSH]&lt;br /&gt;
** [http://www.battledroids.net/downloads/avrsh.html AVRSH]&lt;br /&gt;
** [http://bitlash.net/wiki/start BITLASH]&lt;br /&gt;
** [http://sourceforge.net/projects/fruitshell/ FRUITSHELL]&lt;br /&gt;
** [http://www.gisvold.co.uk/~gisvold/drupal/node/1484 BREAKFAST]&lt;br /&gt;
* [http://nootropicdesign.com/toolduino/ toolduino] is a simple software tool that lets you easily interact with your Arduino hardware so you can test the circuits you create. Toolduino is written in the [http://processing.org/ Processing] languange and is available for Windows, Mac OS X, and Linux. Toolduino uses the the [http://www.arduino.cc/playground/Interfacing/Processing Arduino library for Processing] to communicate with an Arduino board so you can manipulate output pins and read inputs. The Arduino must be running the [http://firmata.org/wiki/Main_Page Firmata] firmware that comes with the Arduino IDE. (LGPL)&lt;br /&gt;
* [http://www.mueller-torres.de/avr.php MOPS] - A small C and Assembly based operating system for the ATMEL AVR® 8-Bit RISC controller family.&lt;br /&gt;
* [http://www.hk-businessconsulting.de/rts.htm RTS(Realtime Tasking System)] - Betriebssystemkern mit Echtzeiteigenschaften, Lizenz: EUPL V. 1.1&lt;br /&gt;
&lt;br /&gt;
==== Projektsammlungen ====&lt;br /&gt;
&lt;br /&gt;
* [http://www.DieProjektseite.de Die Elektronik-Projektseite und Heimat des BasicBeetle] Hauptthema ist der BasicBeetle. Ein modularer, leistungsfähiger, in Basic programmierbarer Mikrorechner speziell für Steuerungen. Mit vielen Programmen, Tiipps und Tricks, Informationen...&lt;br /&gt;
* [http://www.Happy-Micro.de Happy-Micro.de] Die Internetsite für Hobbyelektroniker, Mikrocontroller-Anwender, Programmierer und alle, die Spaß an Computern und Elektronik haben. Bei Happy-Micro.de steht der Spaß am Entwickeln von Programmen und Schaltungen im Vordergrund. Jeder Benutzer hat die Möglichkeit auch als Autor mitzumachen und seine Schaltungen oder Programme zu veröffentlichen. Freier Bilderdownload für die eigene Homepage. &#039;&#039;(Seite wurde geschlossen!)&#039;&#039;&lt;br /&gt;
* [http://iwenzo.de Elektronik und Informationen] Wissenswertes aus der Unterhaltungselektronik..&lt;br /&gt;
* [http://instruct1.cit.cornell.edu/courses/ee476/FinalProjects/ Cornell University ECE 476 Microcontroller Design Final Projects] &lt;br /&gt;
* [http://www.serasidis.gr/ Serasidis Vasilis&#039; AVRsite] u.a. GLCD, SMS, PAL&lt;br /&gt;
* [http://www.riccibitti.com Alberto Ricci Bitti] u.a. PAL Video-Interface&lt;br /&gt;
* [http://www.ulrichradig.de Mikrocontroller and more] AVR - Projekte (Ethernet, LCD, Relaiskarte usw.) und mehr&lt;br /&gt;
* [http://home.arcor.de/burkhard-john/index.html Burkhard John] (D)&lt;br /&gt;
* [http://www.avrprojects.net/ AVRmicrocontrollerprojects] u.a. Text-LCD, Schrittmotor, Thermometer&lt;br /&gt;
* [http://hem.bredband.net/robinstridh/ Robin Stridh] Rotor-Anzeige, Video-Interface&lt;br /&gt;
* [http://www.dertien.dds.nl/content/avrprojects.html dertien.dds.nl AVR-Projects]&lt;br /&gt;
* [http://www.microsps.com MicroSPS.com] Grafische Programmierung des AVR mit EAGLE&lt;br /&gt;
* [http://www.h-mpeg.de h-mpeg Festplatten mp3 Player] IDE Ansteuerung, IDE Filesystem, LCD Ansteuerung etc. in 8K Code. Quelltext unter GPL&lt;br /&gt;
* [http://www.embedtronics.com/ embedtronics.com]&lt;br /&gt;
* [http://www.siwawi.arubi.uni-kl.de/avr_projects  M. Thomas&#039; AVR Projekte] untern Anderem AVR Butterfly avr-gcc-port, DB101 gcc-port, BC100 gcc-port, Bootloader, Programmier- und Debughardware, Software-UART, DS1820-Lib., experimentelle avrdude-Versionen, AVR und CAN mit MCP2515 &amp;lt;!-- Vorsicht &amp;quot;Eigenwerbung&amp;quot; --&amp;gt;&lt;br /&gt;
* [http://www.mictronics.de Michaels Electronic Projects] AVR Projekte (EN) - ua. Sony/Becker CD/MD Wechsler Emulator, RDS-Decoder, GPS Infos, OBD J1850 VPW Interface, USB&amp;lt;&amp;gt;CAN Bus Interface. Informationen zu CD Wechsler Protokollen. MP3stick - MP3 Player mit ATmega128, color LCD, SD/MMC Karte und VS1011b&lt;br /&gt;
* [http://www.stahlbucht.de/elektronik/node13/ node13] modulares AVR 8515 Projekt: eine Controller-Platine, an die sich weitere Ein-Ausgabemodule (Tastenfeld, LEDs, LCD-Modul) anschliessen lassen&lt;br /&gt;
* [http://www.mikrocontroller-projekte.de www.mikrocontroller-projekte.de] Diverse Projekte mit AVR Controllern. AVR910 Programmer, Testboard und Modellbauelektronik&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2 Roboternetz-Mikrocontroller Projekte.de] Diverse Projekte mit AVR und anderen Controllern, insbesondere im Bereich Robotik&lt;br /&gt;
* [http://www.avr-projekte.de AVR-Projekte.de] Belichtungstimer, FT232RL Schaltungen,LED-Fading über Fernbedienung, HD44780-LCD über USB und Seriell, AVR910-USB Programmer, Basteleien: Ätzmaschine,Kompressor.&lt;br /&gt;
* [http://openeeg.sourceforge.net/ openeeg.sourceforge.net] Das OpenEEG Projekt befasst sich mit der Entwicklung eines preiswerten Elektro-Enzephalographie (EEG) Geräts und dessen freier Steuersoftware zur Messung elektrischer Gehirnströme. Sein µPC-Herz ist ein AT90S4433 bzw. ein ATmega8. Ziel sind auch verschiedene EEG Anwendungen z.&amp;amp;nbsp;B. im Bereich mentaler Trainingsmethoden (Neurofeedback).&lt;br /&gt;
* [http://www.amateurfunkbasteln.de/ www.amateurfunkbasteln.de] Seite von Michael Wöste (DL1DMW) u.a. CPU-Board mit AT89C2051, AT89C4051 oder AVR AT90S2313, CPU-Board mit Atmel AT90S8535, Experimentierplatine mit ATmega103, Programmer für AT89C2051/AT89C4051, 32-Kanal-Logik-Analysator bis 40 MHz (Entwurf von David L. Jones)&lt;br /&gt;
* [http://www.atmel.com/dyn/products/app_notes.asp?family_id=607 Atmel - AVR 8-Bit RISC - Application Notes] Anwendungshinweise und Beispiele vom Hersteller&lt;br /&gt;
* [http://www.projects.cappels.org/ Dick Cappels&#039; Project Pages]&lt;br /&gt;
* [http://see-by-touch.sourceforge.net/index.html SeebyTouch - Blinden-Seh-Ersatzsystem] Computerbilder fühlen durch ein einfaches Gerät (Bauanleitung) und freier Software (für 10 Betriebssysteme) - eine neue Erfahrung für alle&lt;br /&gt;
* [http://www.loetstelle.net www.loetstelle.net] Verschiedene kleinere AVR-Projekte rund um LEDs, z.&amp;amp;nbsp;B. RGB Dimmer, Moodlight. Diverse Elektronikprojekte und Grundlagen&lt;br /&gt;
* [http://www.dietmar-weisser.de Selbstbauprojekte Elektronik] kleine Sammlung von Elektronikprojekten zum Thema Leiterplattenfertigung, Hochfrequenztechnik und Mikrocontroller.&lt;br /&gt;
* [http://www.myplace.nu/avr/ Jesper&#039;s AVR pages] Yampp MP3 Player, Yaap Programmer, DDS mit 2313+R2R, Gitarrentuner, Frequenzzähler.&lt;br /&gt;
* [http://www.microsyl.com/ MicroSyl MCU] MP3 Player, MegaLoad, HCLoad, Propeller Clock, Freq Meter, BarCode Reader, Door Bell, OneWire Lib, Text LCD Lib, Graph LCD Lib, Nokia LCD Lib, Led Sign with MMC MemoryCard, Intercom&lt;br /&gt;
* [http://www.jeroen.homeunix.net/ http://www.jeroen.homeunix.net/] Aufbau eines elektronischen Rouletts auf basis eines AVRs&lt;br /&gt;
* [http://thomaspfeifer.net thomaspfeifer.net] Reflow-Ofen, Laminator-Temperaturregelung, USB-Atmel-Programmer, SMD-Tricks u.v.m.&lt;br /&gt;
* [http://www.scienceprog.com Scienceprog - embedded theory and projects] - AVR, ARM theory and projects&lt;br /&gt;
* [http://www.iuse.org Hausautomatisierung] - CAN-Bus mit ATmega32-Controllern und Bedienfeldern, Admin-Tools zum Updaten via CAN, Traffic Dumper etc.&lt;br /&gt;
* [http://www.myevertool.de AVRSAM] - AT91SAM7S Header Board annährend 100% Pinkompatibel zu den folgenden AVR Mikrocontroller: AT90S8535 / ATMEGA8535 / ATMEGA16 / ATMEGA32&lt;br /&gt;
* [http://members.aon.at/hausbus Hausbus Home] - Hausbus-Projekt unter Verwendung von ATmega8, ATtiny13 und ATmega128&lt;br /&gt;
* [http://www.thomas-wedemeyer.de/elektronik/AVR/avr-dcf-clock.html AVR-DCF-Clock] - DCF-Uhr mit bunter LED-Anzeige - ATmega8&lt;br /&gt;
* [http://www.grasbon.de/genuhr.html GenuhR] - DCF-Funkuhr / Wecker/ Timer mit LED-Punktmatrixanzeige. Das Projekt beschreibt den Aufbau des kompletten Gerätes beginnend beim Schaltplan bis hin zur Montage in ein Gehäuse.&lt;br /&gt;
* [http://www.avrguide.com/ AVR Projektsammlung] bei www.avrguide.com&lt;br /&gt;
* AVR Synth http://www.elby-designs.com/avrsynth/avrsyn-about.htm http://www.jarek-synth.strona.pl/&lt;br /&gt;
* [http://elm-chan.org/he_e.html Electronic Lives Manufacturing] - Aufbauten in Fädeldrahttechnik, tlw. auf Japanisch, aber mit englischen Sourcecodes&lt;br /&gt;
* AVR Synthesizer http://www.avrx.se/&lt;br /&gt;
* [http://www.wedis-basteleck.de/ Wedis-Basteleck] - Modellbahn DCC-Servo-Zubehördecoder DCC Servo Decoder mit ATmega8 / Servo Differenzierbaugruppe für Modellbau&lt;br /&gt;
* http://web.archive.org/web/20050415222337/http://www.hebel23.de/ RDS RADIO: ATMega32, TEA5757, T6963C, TDA7330B in C&lt;br /&gt;
* [http://www.gasenzer.dk Analog/Digital and MPU Eletronic Projects] PAL/VGA Terminal, CallerID, Ethernet, Wireless Bridge, LPC2214, AT91RM9200, Sony Unilink Controlled Wireless MP3 Player.&lt;br /&gt;
* [http://www.circuitcellar.com/avr2004/ Circuit Cellar AVR Design Contest 2004] mit Projektbeschreibungen&lt;br /&gt;
* [http://www.circuitcellar.com/avr2006/ Circuit Cellar AVR Design Contest 2006] mit Projektbeschreibungen&lt;br /&gt;
* [http://www.heesch.net/microcontroller.aspx/ Homepage von Stefan Heesch] - AVR Mikrokontroller Projekte, z.B. WLAN und AVR, netzwerkgesteuertes RGB Licht, IDE-Interface, DS1821 Thermometer, Morse-Dekoder u.a.&lt;br /&gt;
* [http://www.schaltungsforum.de Das Schaltungsforum] ist eine Seite für Anfänger und Profis welche ständig mit Tutorials erweitert wird. Stellt Eure Projekte online. Die Seite befindet noch im Aufbau und Eure Mithilfe ist erwünscht.&lt;br /&gt;
* [http://avrprojekte.de/] Viele Projekte mit LEDs(LED-Matrixen) und AVRs&lt;br /&gt;
* [http://arduino.milkcrate.com.au/ little-scale&#039;s arduino page]&lt;br /&gt;
* [http://www.sebastianweidmann.de www.sebastianweidmann.de] Grundlagen zum Thema Platinen ätzen, Bohren, Durchkontaktierungen und Projekte Tipps/Tricks mit Atmel AVR Microcontrollern&lt;br /&gt;
*[http://www.jtronics.de/elektronik-avr.html Junghans Electronic Page] u.a Nokia 3310 LCD Ansteuerung in &amp;quot;C&amp;quot;(aktualisiert 2010), TWI/USI, Quadcopter&lt;br /&gt;
* [http://www.familie-finke.com/ http://www.familie-finke.com/] Die Website von Thomas Finke mit diversen Elektronikprojekten, wie z.B. STK-LAN (AVR im Netzwerk mit HTTPD, SNMP,...), UV-LED-Belichter, HPGL-Plotter.&lt;br /&gt;
* [http://phil-zone.de/ Philips Projektsammlung] Elektronik Projekte (µC,CMOS,Analog,...), Tutorials und nützliche Online-Tools&lt;br /&gt;
* [http://www.iuac.res.in/~elab/phoenix/index.html Phoenix] allows you to develop science experiments  by connecting  sensor / control elements to a computer and access them through software. The project was started by Inter University Accelerator Centre, with the objective of improving the laboratory facilities at Indian Universities, and growing with the support of the user community. Phoenix depends heavily on Python language. The data acquisition, analysis and writing simulation programs to teach science and computation. The hardware design is freely available. The project is based on Free Software tools and the code is distributed under GNU GPL. (Atmega16)&lt;br /&gt;
* [http://code.google.com/p/usb-pwm-generator/ USB PWM Generator] Low Cost PWM Generator, über USB Programmierbar. 1Hz - 120khz Duty Cycle 1 - 99 %.&lt;br /&gt;
&lt;br /&gt;
==== Schnittstellen ====&lt;br /&gt;
===== TCP/IP =====&lt;br /&gt;
* Kostengünstige und schnelle WLAN Anbindung an Mikrocontroller mit Wiz610wi. Bezugsquelle inkl. praktischer Adapterplatine bei: [http://www.shop.display3000.com/elektronikmodule/ethernet-wlan/index.html Display3000]&lt;br /&gt;
* [http://www.laskater.com/projects/uipAVR.htm TCP/IP Stack für AVR] mit Realtek RTL8019AS oder Axis AX88796 Netzwerk-Chips (open source für avr-gcc und Imagecraft). Passende Hardware in [http://www.edtp.com/ diesem online-shop]&lt;br /&gt;
* [http://www.ethernut.de Ethernut] - AVR based Hardware with Ethernet-Interface, Multithreading OS, Software and Hardwaredesign is free&lt;br /&gt;
* [http://www.embedded-it.de/microcontroller/eNet-sam7X.php eNet-sam7X] Embedded Ethernet Modul im DIL64 Format mit kompletten OpenSource Board Support Packake auf Ethernut / Nut/OS Basis. Industrie geeignet&lt;br /&gt;
* [http://www.ethersex.de/index.php/Feature_Liste Ethersex] - Trotz des bescheuerten Namens sehr empfehlenswert. Viele flexibel einbindbare Module für diverse Hardware.&lt;br /&gt;
* [http://wiki.neo-guerillaz.de OpenMCP] Bekanntes Board auf Basis des ATmega2561 und ENC28j60. Läuft auch auf dem AVR-NETIO und dem myAVR.&lt;br /&gt;
* [http://www.cesko.host.sk/IgorPlugUDP/IgorPlug-UDP%20(AVR)_eng.htm IgorPlug-UDP AVR] - Ethernet &amp;amp; UDP/IP in Software implementiert&lt;br /&gt;
* [http://members.home.nl/bzijlstra/software/examples/RTL8019as.htm] RTL8019 Bascom&lt;br /&gt;
* [http://members.home.nl/bzijlstra/software/examples/RTL8019as.htm AVR und RTL8019]&lt;br /&gt;
* [http://avr.auctionant.de/avr-ip-webcam AVR IP Webcam] &lt;br /&gt;
* http://mikrocontroller.cco-ev.de/de/webcam.php&lt;br /&gt;
* [http://avr.auctionant.de/avrETH1/ avrETH1 - Webserver mit enc28j60 und Webcam-Support]&lt;br /&gt;
* [http://www.sics.se/~adam/uip/ uIP-Stack, Teil des Contiki OS]&lt;br /&gt;
* [http://www.sics.se/~adam/lwip/ LwIP-Stack]&lt;br /&gt;
* [http://www.harbaum.org/till/spi2cf/ WLAN-Implementierung auf Basis einer PRISM-CF-Karte und uIP]&lt;br /&gt;
* http://www.circuitcellar.com/AVR2006/winners/DE/AT2581.htm MEGA128(CAN) PCMCIA&lt;br /&gt;
* [http://www.ic-board.de/index.php?cat=c2_ICnova-Module.html AVR32 AP7000 Linux Board] mit 2xEthernet, TFT, Audio, SDCARD, USB-Host/Devive, Funk...&lt;br /&gt;
* [https://berlin.ccc.de/wiki/AVR-Board_mit_Ethernet AVR-Board mit Ethernet mit dem ENC28J60 von Microchip]&lt;br /&gt;
* [http://www.roland-riegel.de/mega-eth/ AVR-Ethernet-Board mit extra SRAM, SD/MMC, USB und zugehöriger Software]&lt;br /&gt;
&lt;br /&gt;
===== CAN =====&lt;br /&gt;
* [http://www.canathome.de/ Can@Home] - CAN als &amp;quot;Installationsbus&amp;quot;, u.a. mit AVRs (D)&lt;br /&gt;
* [http://www.iuse.org/ www.iuse.org] - Hausautomatisierung auf CAN Basis&lt;br /&gt;
* [http://www.port.de/ www.port.de] - Professionelle CAN/CANopen Entwicklungswerkzeuge&lt;br /&gt;
* [http://can-wiki.info CAN-WIKI] - spezielle Wiki Site für CAN bus (Englisch)&lt;br /&gt;
* [[CAN-Bus]] - Eintrag in diesem Wiki&lt;br /&gt;
* [[CAN als Hausbus]] - Eintrag in diesem Wiki&lt;br /&gt;
* [http://www.canhack.de/ www.canhack.de] - Ein Forum, dass sich mit dem CAN bus im Auto beschäftigt&lt;br /&gt;
* [http://www.edevices.lt/  www.edevices.lt ] - USB2CAN inexpensive USB to CAN bus converter&lt;br /&gt;
&lt;br /&gt;
===== USB =====&lt;br /&gt;
* [http://www.embedded-it.de/microcontroller/microcontroller-module.php eUSB-162 und eUSB-LCD] - At90USB162 basiertes universelles USB Prototypen / Mikrocontroller Modul und USB Terminal Interface für HD44780 kompatible LCDs auf Basis der Lufa Library&lt;br /&gt;
* [http://www.cesko.host.sk/IgorPlugUSB/IgorPlug-USB%20(AVR)_eng.htm Igor-Plug] - USB Device interface in AVR Firmware - no extra Interface IC needed, read the License&lt;br /&gt;
* [http://www.obdev.at/products/vusb/index-de.html V-USB] &amp;amp;#8211; USB-Implementation in C nach gleichem Prinzip wie Igor-Plug, aber einfacher zu verwenden, GPL-ähnliche Lizenz (Nutzung des Projekts &#039;&#039;erfordert&#039;&#039; Veröffentlichung), englisch kommentierter Code&lt;br /&gt;
* [http://www.xs4all.nl/~dicks/avr/usbtiny/ USBTiny] &amp;amp;#8211; weitere Software-USB-Implementierung in C; sehr ähnlich AVR-USB; steht aber unter GPL; relativ wenige Beispiele&lt;br /&gt;
* MJoy USB Joystick Controller on AVR ATmega8&lt;br /&gt;
* [http://www.ime.jku.at/tusb/ TUSB3210-Controller, HID, LIBUSB] Ein Projektseminar, in dem es darum ging, die USB-Schnittstelle des TUSB3210 zu aktivieren und die Daten eines ADC an den PC zu senden. USB-Implementierung für µC und PC.&lt;br /&gt;
* [http://www.b-redemann.de Steuern und Messen mit USB - FT232, 245 und 2232] Das aktuelle Buch zu den USB-Controllern von FTDI. Viele Beispielprogramme in C, zwei Projektbeschreibungen: I²C-Bus mit LM75A und ein Web-Projekt. Bauteilesatz und USB-Modul mit dem FT2232 zum schnellen Einstieg in die Thematik. Buch / Teilesatz über Segor oder dieser Seite erhältlich.&lt;br /&gt;
* [http://www.eltima.com/products/usb-over-ethernet/ USB to Ethernet Connector] - Share your USB devices via LAN/Internet&lt;br /&gt;
* [http://www.ixbat.de Viele kleine USB Projekte] Rund um die Bibliothek usbn2mc http://usbn2mc.berlios.de. Dies ist eine einfache Bibliothek für den USBN9604/03 von National Semiconductor&lt;br /&gt;
* [http://www.rahand.eu Mega8D12] - Schritt für Schritt zum virtuellen COM-Port. Ein Einsteiger-Tutorial zur CDC-Klasse mit Schaltung und Firmware (ATmega8 und PDIUSBD12).&lt;br /&gt;
* http://www.maares.de/tools USB_ISO: Isolierter Schnittstellenwandler USB auf RS232 (TTL) mit FT232RL und ADUM1402. Galvanische Trennung für das Zielsystem.&lt;br /&gt;
* [http://www.embedded24.net USB HID Host Treiber] - USB HID Treiber DLL für Windows (Demo Projekte für Visual Studio 2010 C++, C# und VB).&lt;br /&gt;
&lt;br /&gt;
===== DMX512 =====&lt;br /&gt;
* [http://Dworkin-DMX.de Konverter RS232 zum DMX512] Steuerung DMX-fähigen Geräten mit einem PC. Es gibt Low cost Variante zum selber basteln.&lt;br /&gt;
* [http://www.hoelscher-hi.de/hendrik/light/profile.htm Hennes Sites] Bauanleitungen für DMX-Dimmerpacks, DMX-Switchpacks, PWM-Controller, ... Tutorial für Senden und Empfangen von DMX-Daten mit AVRs.&lt;br /&gt;
* [http://www.lj-skinny-development.de/lj2000/ DMX Lichtanlage im Selbstbau] Projekt für den Selbstbau einer kompletten Lichtanlage zur Steuerung über DMX. Projekt beinhaltet alles was man für den Betrieb einer eigenen Lichtanlage benötigt (Mischpult, Steuersoftware, Dimmer, Scanner mit Iris, Shutter-Dimmer, 2 rotierenden Goborädern, 2 Farbrädern, CMY-Farbmischeinheit, Prisma, Fokus ...).&lt;br /&gt;
* [http://digital-enlightenment.de Digital Enlightenment ]Verschiedene DMX-Selbstbauprojekte&lt;br /&gt;
&lt;br /&gt;
===== PS2 =====&lt;br /&gt;
* [http://www.avrfreaks.net/index.php?module=Freaks%20Academy&amp;amp;func=viewItem&amp;amp;item_id=1086&amp;amp;item_type=project&amp;amp;timestamp=2007-09-04%2018:34:41 PC keyboard to an AVR]&lt;br /&gt;
&lt;br /&gt;
===== LANC =====&lt;br /&gt;
* [http://dsc.ijs.si/3dlancmaster/ 3D LANC Master from Damir Vrancic] is a device which keeps in synchronisation some of Sony camcorders by using LANC (CONTROL-L, ACC) protocol. (Open Hardware + Open Source, Atmega8).&lt;br /&gt;
* [http://jochendony.homeip.net/content/view/22/26/ LANC Lib] for AVRGCC. Read and write LANC commands.&lt;br /&gt;
* [http://blog.makezine.com/archive/2008/12/controlling_sony_camcorders_with_th.html Controlling Sony camcorders with the Arduino]&lt;br /&gt;
&lt;br /&gt;
===== MMC/SD-Card =====&lt;br /&gt;
* [http://www.roland-riegel.de/sd-reader/index.html MMC/SD card reader example application] von Roland Riegel (Atmega8, Atmega168 für FAT16)&lt;br /&gt;
* [http://www.captain.at/electronic-atmega-mmc.php MMC Flash] bzw.  [http://www.captain.at/electronic-atmega-sd-card.php SD Flash ] Memory Extension für Atmegas von Captain. (Atmega16, Atmega32)&lt;br /&gt;
* http://arm.hsz-t.ch MMC, SD, SDHC Kartentreiber für ARM7 Mikrocontroller&lt;br /&gt;
* [http://www.mikrocontroller.net/articles/FAT32 Wiki und FAT16/32 Bibliothek für atmega]&lt;br /&gt;
&lt;br /&gt;
==== LC-Displays ====&lt;br /&gt;
&lt;br /&gt;
===== Text (character-mode) HD44870 =====&lt;br /&gt;
* [http://jump.to/fleury P.Fleury]&lt;br /&gt;
* avrfreaks Projekt 59 (Chris E.) und andere&lt;br /&gt;
* Procyon avrlib v. Pascal Slang (GPL)&lt;br /&gt;
* Bray&lt;br /&gt;
* [http://www.sprut.de/electronic/lcd/index.htm Spruts LCD-Seite]&lt;br /&gt;
* [http://elm-chan.org/docs/lcd/lcd3v.html Standard-LCD auf 3V betreiben (eng)]&lt;br /&gt;
* [http://www.harbaum.org/till/lcd2usb LCD2USB, LCD mit AVR am USB betreiben]&lt;br /&gt;
* [http://www.simon-brenner.ch/projekte/lcd-display 4x40 LCD Projekt, Microchip]&lt;br /&gt;
&lt;br /&gt;
===== Grafik T6963C etc. =====&lt;br /&gt;
&lt;br /&gt;
* http://www.holger-klabunde.de/avr/avrboard.htm#t6963&lt;br /&gt;
* [[Projekt T6963-LCD-Ansteuerung]] nur PC, keine Änderung seit Juli 2006&lt;br /&gt;
* avrfreaks.net - TOSHIBA_LCD_T6963C, AVR Graphics&lt;br /&gt;
* http://www.mikrocontroller.net/topic/48456 C&lt;br /&gt;
* http://www.mikrocontroller.net/topic/54563 C&lt;br /&gt;
* http://www.mikrocontroller.net/topic/48584 ASM&lt;br /&gt;
* [http://passworld.co.jp/ForumMSP430/viewtopic.php?t=47 Grafik LCDs] - 128 x 112 Grayscale für MSP430 und andere uCs.&lt;br /&gt;
* http://www.display3000.com/ Farb-TFT-Module inkl. Mikrocontroller (ATMega128; ATMega2561 und AT90CAN128)&lt;br /&gt;
* [http://www.tklinux.de/sed1330.html SED1330 an ATMega]. Library für SED 1330 controller an ATmega&lt;br /&gt;
In der Codesammlung gibt es auch für andere Controller was.&lt;br /&gt;
&lt;br /&gt;
===== Siemens S55/C60 =====&lt;br /&gt;
* [http://www.module.ro/siemens_lcd.html S55-Display Pinbelegung]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/22643 Forumbeitrag]&lt;br /&gt;
&lt;br /&gt;
===== Siemens S65/M65/CX65 =====&lt;br /&gt;
* [http://www.superkranz.de/christian/S65_Display/DisplayIndex.html S65-Display] vom Siemens S65/M65/CX65, 132x176 Pixel, 65536 Farben, günstig als Ersatzteil zu bekommen.&lt;br /&gt;
&lt;br /&gt;
===== Nokia 3210/3310 =====&lt;br /&gt;
* [http://www.jtronics.de/elektronik-avr/lcd-display-nokia3310 Bibliothek für Nokia 3310 Lcd Ansteuerung in &amp;quot;C&amp;quot; von http://www.jtronics.de - sehr gut (aktualisiert 2010)]&lt;br /&gt;
* [http://www.microsyl.com MicroSyl.Com]&lt;br /&gt;
&amp;lt;!-- * [http://www.microsyl.com/nokialcd/shematic.gif Belegung] --&amp;gt;&lt;br /&gt;
* [http://www.deramon.de/nokia3310lcd.php Deramon.de]&lt;br /&gt;
&amp;lt;!-- [[Bild:Beispiel.jpg]] --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===== Nokia 6100 LCD =====&lt;br /&gt;
&amp;lt;!-- * [http://www.apetech.de/article.php?artId=3&amp;amp;nnId=12 Nokia 6100 LCD Library] für Nokia-Displays 132x132 Pixel, 4096 Farben mit Philips Controller (bei eBay ziemlich preiswert zu ersteigern) --&amp;gt;&lt;br /&gt;
* [http://www.myplace.nu/mp3/download/download.php Yampp 7 Software Download Seite]: Archiv &amp;quot;yampp-7 with colour LCD firmware&amp;quot; enthält avr-gcc/avr-as Routinen für 6100-LCDs mit Philips- oder Epson-Controller (nicht direkt eine &amp;quot;Library&amp;quot;)&lt;br /&gt;
*[http://www.e-dsp.com/controlling-a-color-graphic-lcd-epson-s1d15g10-controller-with-an-atmel-avr-atmega32l/ S1D15G10]: Routine code für den Epson S1D15G10 Controller&lt;br /&gt;
*[http://thomaspfeifer.net/nokia_6100_display.htm Nokia 6100 Display am AVR] Anzeige von RGB-Bildern (für avr-gcc)&lt;br /&gt;
*[http://www.optixx.org/ www.optixx.org] Code zur Ansteuerung von Philips und Epson&lt;br /&gt;
*[http://www.zipfelmaus.com/nokia6100lcd_en/ http://www.zipfelmaus.com/nokia6100lcd_en/] --&amp;gt; unter Download: Tool zum Konvertieren von BMPs in h-Files zum Ausgeben auf dem Display&lt;br /&gt;
&lt;br /&gt;
===== KS0108 =====&lt;br /&gt;
* [http://hubbard.engr.scu.edu/embedded/avr/avrlib Procyon avrlib (GPL)]&lt;br /&gt;
* avrfreaks UP&lt;br /&gt;
* apetech.de nicht mehr erreichbar http://www.mikrocontroller.net/topic/68316&lt;br /&gt;
&lt;br /&gt;
====GPS====&lt;br /&gt;
* http://www.holger-klabunde.de/avr/avrboard.htm#GPSdisplay GPS-Daten auf LCD&lt;br /&gt;
* [http://www.geoclub.de/forum57.html www.geoclub.de] - Elektronik beim Geocaching&lt;br /&gt;
* [http://passworld.co.jp/ForumMSP430/viewtopic.php?t=22 passworld.co.jp] - Do It Yourself GPS&lt;br /&gt;
&lt;br /&gt;
== [[8051|8051 / MCS51]] ==&lt;br /&gt;
* [http://mcu8051ide.sourceforge.net/ MCU 8051 IDE] - MCU 8051 IDE is a new modern graphical IDE for microcontrollers based on 8051. MCU 8051 IDE is noncommercial open-source software for Linux.&lt;br /&gt;
* [http://www.rakers.de/catalog Dr. Rakers] Entwicklungssystem mit C-Compiler, BASIC-Compiler und Makroassembler für alle 8051-Mikrocontroller (80C552, 80C515(C), 80C537). Auch für Hobbyisten bezahlbar.&lt;br /&gt;
* [http://www.progshop.com/versand/software/prog-studio/index.html Prog-Studio] - Moderne Assembler Entwicklungsumgebung für 8051 Mikrocontroller mit Debugger, Edit &amp;amp; Continue, Code-Folding, Intelli-Sense, Monitorung und mehr&lt;br /&gt;
* [http://www.yCModule.de yCModule: µController-Systeme] - Preisgünstige µController-Module, ISP-Programmiertools und Applikationsboards&lt;br /&gt;
* [http://www.erikbuchmann.de/ Erik Buchmanns Mikrocontroller-Seite] - Assemblerkurs und mehrere Projekte&lt;br /&gt;
* [http://www.holger-klabunde.de/projects/8051.htm Experimentierboard für 8051 Controller] von Holger Klabunde.&lt;br /&gt;
* [http://www.woe.de.vu/ World Of Electronics] - Projekte mit den 8051-Controllern von Atmel&lt;br /&gt;
* [http://www.thomas-wedemeyer.de/elektronik/8051/8051.html Controllerplatine mit SAB80C535]&lt;br /&gt;
* [http://www.maxim.ph.tc Selbstbau-Programmer] für 2051er&lt;br /&gt;
* [http://www.nomad.ee/micros/8052bas.html 8052 BASIC Projects] - IDE-Interface&lt;br /&gt;
* [http://home.t-online.de/home/s.holst/sh51/index.html Mikrokontroller sh51] Schaltplan für 80C535-Board&lt;br /&gt;
* 8051-Makroassembler [http://plit.de/asem-51/ ASEM-51] (Freeware)&lt;br /&gt;
* [http://sdcc.sourceforge.net/ SDCC - Small Device C Compiler] - freier ANSI-C compiler für Intel 8051, Maxim DS80C390 und Zilog Z80 kompatible Controller.&lt;br /&gt;
* [http://sdccokr.dl9sec.de/ The SDCC Open Knowledge Resource]&lt;br /&gt;
* [http://www.wickenhaeuser.de/ Wickenhäuser C Compiler] - Preisgünstiger C Compiler&lt;br /&gt;
* [http://home.tiscali.cz:8080/~cz056018/lanc_a.htm LANC-Remote] Projekt von Ji&amp;amp;#345;í &amp;amp;#352;mach zur Steuerung von Videorekordern oder Camcordern über das Control-L (LANC) Protokoll mit Hilfe eines AT89C2051.&lt;br /&gt;
* [http://www.microcontroller-starterkits.de Microcontroller-Starterkits] Starter-Kits für verschiedene Microcontroller (D) preisgünstige Platinen (ab 12,95 Euro für AT89S8252). Beim uC-Dualboard : Das Board ist nutzbar mit AVR-Controllern und 8051-Controllern!&lt;br /&gt;
* [http://turbo51.com Turbo51 - Free Pascal compiler for 8051]&lt;br /&gt;
* [http://self8051.de/ self8051.de] - Dein Nachschlagewerk - Befehlsreferenz, Eigenschaften, Derivate&lt;br /&gt;
* [http://cmon51.sourceforge.net/ CMON51] - freier Onboard Monitor und Debugger, anpassbar an unterschiedliche 8051 kompatible Mikrocontroller&lt;br /&gt;
* [http://et-tutorials.de/632/kostenloser-mikrocontroller-kurs/ Mikrocontroller Video Tutorial] Video-Tutorial für Einsteiger (C-Kurs + Einführung 8051)&lt;br /&gt;
&lt;br /&gt;
== MSP430 ==&lt;br /&gt;
* [http://www.mikekohn.net/micro/naken430asm_msp430_assembler.php naken430msp] -   MSP430 Assembler von Michael Kohn (GPL)&lt;br /&gt;
* [http://www.mathar.com MSP430 Tutorials] - Tutorials, Anleitungen und viele Beispielprojekte mit dem MSP430-Mikrocontroller&lt;br /&gt;
* [http://www.student-zw.fh-kl.de/~stwi0001/imp/msp430/pwm430/index.htm Pulsweitenmodulation mit dem MSP430] - sehr ausführliche Einführung&lt;br /&gt;
* [http://www.thomas-wedemeyer.de/elektronik/msp430/msp430.html Kleine Projekte mit dem MSP430] - Schaltplan und Layout zu einem MSP430F149-Board und einem ADXL-G-Sensor mit MSP430&lt;br /&gt;
* [http://tinymicros.com/embedded/MSP430/ The MSP430 Bugspray Database] - umfangreiche Datenbank für Bugs in MSP430-Controllern&lt;br /&gt;
* [http://msp430.info MSP430.info] - Portalseite für MSP430; Info, Projekte (MIDI, USB)&lt;br /&gt;
* [http://groups.yahoo.com/group/msp430 Yahoo group MSP430] - lebhaftes Forum mit vielen MSP430-Experten&lt;br /&gt;
* [http://homepage.hispeed.ch/py430/mspgcc/ mps430-gdb und Eclipse] - Eine Anleitung von Chris Liechti&lt;br /&gt;
* [http://passworld.co.jp/ForumMSP430 Forum MSP430] - Projekte mit MSP430 (GPS, BlueTooth usw...)&lt;br /&gt;
* TI Design-Wettbewerb: http://www.designmsp430.com/View.aspx (Dateien liegen evtl. in /projects/) [2011-01-24: redirect zum TI Wiki, Projekte nicht mehr vorhanden]&lt;br /&gt;
* [http://www.sics.se/project/mspsim MSPsim] - a Java-based simulator of MSP430 sensor network platforms (BSD License (revised))&lt;br /&gt;
* [http://develissimo.net/de/msp430entwicklung MSPGCC + Eclipse + msp430-gdbproxy / Linux / Debian / Ubuntu] - Anleitung / Tutorial zur Installation der MSPGCC Toolchain + Eclipse + msp430-gdbproxy für Linux / Debian / Ubuntu Lang=Deutsch und Englisch&lt;br /&gt;
* [http://travisgoodspeed.blogspot.com/ Travis Goodspeed&#039;s Blog] - Home of the [http://goodfet.sourceforge.net/ GoodFET] Programmer&lt;br /&gt;
* [http://www.43oh.com/ Four-Three-Oh!]&lt;br /&gt;
&lt;br /&gt;
=== MSP430 Launchpad ===&lt;br /&gt;
* [http://processors.wiki.ti.com/index.php/MSP430_LaunchPad_(MSP-EXP430G2)?DCMP=launchpad&amp;amp;HQS=Other+OT+launchpadwiki MSP430 LaunchPad Wiki] bei TI&lt;br /&gt;
* [http://hackaday.com/2010/08/11/how-to-launchpad-programming-with-linux/ How-to: Launchpad programming with Linux] auf hackaday.com&lt;br /&gt;
* [http://springuin.nl/en/articles/launchpadwindows TI Launchpad programming and debugging with Open Source tools on Windows] (Eclipse, MSPGCC4, Insight, msp430-gdbproxy)&lt;br /&gt;
* [http://osx-launchpad.blogspot.com/ MSP430 LaunchPad toolchain for Mac OS X]&lt;br /&gt;
&lt;br /&gt;
=== EZ430 Chronos ===&lt;br /&gt;
* [http://processors.wiki.ti.com/index.php/EZ430-Chronos?DCMP=Chronos&amp;amp;HQS=Other+OT+chronoswiki EZ Chronos Wiki] bei TI&lt;br /&gt;
&lt;br /&gt;
== ARM ==&lt;br /&gt;
&lt;br /&gt;
=== Herstellerseiten ===&lt;br /&gt;
* [http://www.arm.com ARM] - Entwickler des ARM-Prozessorkerns (kein Hersteller von ICs)&lt;br /&gt;
* [http://infocenter.arm.com ARM Infocenter] Sammlung Technischer Informationen&lt;br /&gt;
&lt;br /&gt;
* [http://www.analog.com/ Analog Devices] ADuC7xxx ARM7TDMI Serie unter &#039;&#039;Analog Microcontrollers&#039;&#039;&lt;br /&gt;
* [http://www.atmel.com/products/AT91/ Atmel AT91 Startseite]&lt;br /&gt;
* [http://www.at91.com AT91.COM] - Atmel ARM Informationsseite (Forum, Beispielcodes etc.)&lt;br /&gt;
* [http://www.cirrus.com/en/products/pro/techs/T7.html Cirrus Logic]&lt;br /&gt;
* [http://www.energymicro.com/ Energy Micro] EFM32 mit Cortex M3 Kern&lt;br /&gt;
* [http://www.freescale.com/mac7100 Freescale MAC7100]&lt;br /&gt;
* [http://www.hilscher.com Hilscher netX] (ARM926 core)&lt;br /&gt;
* [http://www.intel.com/design/intelxscale/ Intel XSCALE Startseite], siehe auch [http://www.marvell.com/ Marvell]&lt;br /&gt;
* [http://www.luminarymicro.com/ Luminiary Micro (TI)] Controller mit Cortex M3 core&lt;br /&gt;
* [http://www.standardics.nxp.com/microcontrollers/ NXP (ehemals Philips) Microcontroller Startseite] für sämtliche Mikrocontroller (ARM7, ARM9, Cortex-M0, -M3, MCS51 etc.), neben LPC2000, LPC3000 auch die LH7xxxx BlueStreak-Serie (ehemals Sharp Microelectronics)&lt;br /&gt;
* [http://www.lpc2000.com lpc2000.com] Infoseite für NXP (ex. Philips) LPC1700 Cortex-M3 basierende Typen, LPC2000, ARM7 basierende Typen und LPC3000, ARM9 basierende Typen. Auch andere Cortex-M3 Bausteine sind erfasst&lt;br /&gt;
* [http://www.okisemi.com/eu/1.Products/ARM32bit.html OKI ARM-Controller Startseite]&lt;br /&gt;
* [http://www.samsung.com/Products/Semiconductor/ Samsung] ARM7/9 unter &#039;&#039;Mobile SoC&#039;&#039;&lt;br /&gt;
* [http://mcu.st.com/mcu/ STMicroelectronics (ST) Microcontroller Startseite] u.a. STR7, STR9, STM32 Support-Forum&lt;br /&gt;
* [http://www.ti.com/ Texas Instruments] TMS470 ARM7TDMI Serie&lt;br /&gt;
* [http://www.toshiba.com/taec/ Toshiba] Controller mit ARM9 und Cortex-M3 core&lt;br /&gt;
&lt;br /&gt;
=== Information (Foren, Mailinglisten, Linksammlungen) ===&lt;br /&gt;
* [http://www.neko.ne.jp/~freewing/cpu/arm_olimex/ Freewing Linksammlung] zu den NXP (ex. Philips) LPC-ARM7-Controllern (Assemblerbeispiele u.a. für Nokia 3310-GLCD)&lt;br /&gt;
* [http://www.open-research.org.uk/ARMuC ARM Microcontroller Wiki]&lt;br /&gt;
* [http://arm.hsz-t.ch arm.hsz-t.ch] Einfühung in ARM7 Mikrocontroller und uClinux.&lt;br /&gt;
* [http://tech.groups.yahoo.com/group/ADuC7000/ ADuC7000 Yahoo-Group]&lt;br /&gt;
* [http://www.at91.com AT91 Forum] (Atmel Rousset)&lt;br /&gt;
* [http://tech.groups.yahoo.com/group/AT91SAM/ AT91SAM Yahoo-Group]&lt;br /&gt;
* [http://en.mikrocontroller.net/forum/17 arm-elf-gcc WinARM Forum] (auch für Yagarto)&lt;br /&gt;
* [http://www.codesourcery.com/archives/arm-gnu/maillist.html Sourcery G++ Lite Edition User Forum/Mailing-List]&lt;br /&gt;
* [http://tech.groups.yahoo.com/group/gnuarm/ GNUARM Yahoo-Group]&lt;br /&gt;
* [http://www.keil.com/forum/ Keil/ARM Forum]&lt;br /&gt;
* [http://groups.yahoo.com/group/lpc2000/ LPC2000 Yahoo-Group]&lt;br /&gt;
* [http://www.mcu-related.com MCU related] Neuigkeiten zu MCUs, überwiegend ARM / Cortex-M3 basierend mit Vergleichen von RTOS und anderen Entwicklungstools&lt;br /&gt;
* [http://forum.sparkfun.com/ Sparkfun Foren]&lt;br /&gt;
* [http://mcu.st.com/mcu/modules.php?name=Splatt_Forums STMicroelectronis Forum]&lt;br /&gt;
* [http://www.stm32circle.com/ Forum for STM32 moderated by Raisonance] Sehr viele Beispielprogramme in Source fuer STM32 und den Primer2 von Raisonance&lt;br /&gt;
&lt;br /&gt;
=== Entwicklungswerkzeuge (Compiler/Assembler/Debugger/Tools) ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.st-angliamicro.com/software.asp Anglia Idealist IDE und Anglia Toolchain] GNU toolchain für Win32-hosts inkl. Beispielen für STR7, STR9 und STM32. IDE kostenlos aber registrierungspflichtig&lt;br /&gt;
* [http://atollic.com/ attolic] TrueSTUDIO&lt;br /&gt;
* [http://www.codesourcery.com/gnu_toolchains/ Codesourcery] GNU Toolchains für ARM (Hosts: Linux, MS Windows, Solaris; Targets: &amp;quot;bare-metal&amp;quot;, arm-linux, SybianOS)&lt;br /&gt;
* [http://devkitpro.org/ devkitPro/devkitARM] GNU-Toolchain für MS-Windows &amp;quot;Hosts&amp;quot;. Vor allem auf GBA abgestimmt aber auch für andere ARM-Controller geeignet&lt;br /&gt;
* [http://www.ghs.com/ Green Hills Software]&lt;br /&gt;
* [http://www.hitex.de Hitex] IDE für diverse Compiler, Debugger&lt;br /&gt;
* [http://www.iar.com IAR] Embedded Workbench, kommerzielle IDE/Compiler, codegrößenbeschränkte Evaluierungsversion verfügbar&lt;br /&gt;
* [http://www.isystem.com/ iSYSTEM] Integrated Development Environment, USB/JTAG interface, OnChip Emulation and Trace&lt;br /&gt;
* [http://www.keil.com Keil/ARM MDK-ARM] kommerzielle IDE/Compiler, unterstützt zwei Compiler (ARM RealView, GNU/gcc), codegrößenbeschränkte Evaluierungsversion verfügbar (IDE/Compiler unbeschränkt für GNU), guter Debugger, sehr guter Simulator, Simulator und Debugger in der Evaluierungsversion auch bei Nutzung der GNU-Toolchain mit Größenbeschränkung&lt;br /&gt;
* [http://mct.de/download.html#free MCT Demoversion C-Compiler für ARM und 68k] ARM C-Compiler basiert auf GCC laut Herstellerinformation jedoch mit Codegrößenbeschränkung &amp;lt;!-- etwas ungewöhnlich: Codegrößenbeschränkung bei GNU-Toolchain --&amp;gt;&lt;br /&gt;
* [http://www.mpeforth.com www.mpeforth.com] - A free Forth system with 125 page manual for all Philips LPC2xxx CPUs with at least 64k Flash and 16k RAM and cystal frequency of 10, 12, or 14.7456 MHz. &lt;br /&gt;
* [http://www.raisonance.com/ Raisonance] Ride, RKit-ARM&lt;br /&gt;
* [http://www.rowley.co.uk/ Rowley] Kommerzielle IDE für GNU-Compiler, eigene libc (nicht newlib), Debugger (inkl. gutem Support für Wiggler)&lt;br /&gt;
* [http://h-storm.tantos.homedns.org/gcc_arm.htm Tantos gcc for ARM Targets] eine weitere ARM-GNU-Toolchain für MS-Windows &amp;quot;Hosts&amp;quot; &lt;br /&gt;
* [http://www.yagarto.de Yagarto] GNU arm-eabi-Toolchain, Eclipse, OpenOCD für Win32 inkl. Setup&lt;br /&gt;
* [http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/index.html#winarm WinARM] eine an WinAVR angelehnte Sammlung von Entwicklungswerkzeugen (binutils, arm-elf-gcc, newlib, &#039;&#039;newlib-lpc&#039;&#039;, Programmers Notepad, &#039;&#039;Beispiel-Makefiles und Beispielcode&#039;&#039;) für alle ARM-Controller. Beispiele für Philips LPC2000 und Atmel AT91SAM7S (ARM7TDMI) u.a.&lt;br /&gt;
* [http://rtlab.tekproj.bth.se/wiki/index.php/Dissy#Architecture_support Dissy] is a disassembler for Linux and UNIX which supports multiple architectures and allows easy navigation through the code. Dissy is implemented in Python and uses objdump for disassembling files.&lt;br /&gt;
* [http://www.sinelabore.com sinelaboreRT] - generiert leicht lesbaren C-Code aus einer Zustandsmaschine. Die Generierung berücksichtig speziell die Bedürfnisse eingebetteter Echtzeitsysteme.&lt;br /&gt;
* http://arm.hsz-t.ch Entwicklungsumgebung für ARM7 Mikrocontroller basierend auf der Knoppix CD. Keine Harddisk installation nötig für uClinux.&lt;br /&gt;
&lt;br /&gt;
* [http://openocd.berlios.de/web/ OpenOCD] Open On-Chip Debugger: Schnittstelle (&amp;quot;gdb-Server&amp;quot;) zwischen verschiedenen JTAG-Interfaces (u.a. auf FTDI2232-Basis, &amp;quot;Wiggler&amp;quot;-ParPort und andere) und GNU-debugger (gdb/Insight-gdb) Flash-Programmierfunktion für LPC2k, AT91SAM7S, LM3S, STM32 und viele andere interne und externe Flashspeicher (Open Source, GPL, unter anderem auf MS Windows und Linux lauffähig)&lt;br /&gt;
* [http://macraigor.com/full_gnu.htm OCDLibRemote] Schnittstelle zwischen WIGGLER-kompatibler JTAG Hardware und dem GNU-Debugger (gdb)&lt;br /&gt;
* [http://gdb-jtag-arm.sourceforge.net/ GDB-JTAG-ARM] GDB JTAG Tools&lt;br /&gt;
* [http://jtagpack.sourceforge.net/ JTAG-Pack] GDB JTAG Tools&lt;br /&gt;
* [http://www.hjtag.com H-JTAG] RDI-Interface für Wiggler, Flash-Funktionen für diverse interne und externe Speicher&lt;br /&gt;
* [http://www.clibb.de/ lpc21isp] Flashutility für LPC21xx, ISP via &amp;quot;Bootloader&amp;quot; (&amp;quot;multiplattform&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
*[http://www.abatron.ch Abatron] BDI1000 &amp;amp; BDI2000, On-Chip Debuggers für ARM, 68k, Coldfire uvm.&lt;br /&gt;
* [http://www.amontec.com Amontec] JTAGkey, JTAGkey2(P): JTAG-Adapter auf Basis des FTDI2232(H) &lt;br /&gt;
* [http://www.hjtag.com/product_intro.html H-JTAG USB Emulator]&lt;br /&gt;
* [http://www.keil.com Keil/ARM ULINK/ULINK2/ULINK-ME] JTAG-Adapter, USB-Anschluss, wird von Keil uVision unterstützt, ULINK2 teilw. auch von Codesourcery G++ (lt. Hestellerangaben)&lt;br /&gt;
* [http://www.kristech.eu Kristech] USB-Scarab, JTAG Adapter, kommt mit eigener Debugger-UI, kompatibel zu Olimex&lt;br /&gt;
* [http://www.lauterbach.de Lauterbach] TRACE32 JTAG-Adapter, USB und Ethernet-Anschluss, eigene Software&lt;br /&gt;
* [http://www.olimex.com Olimex] JTAG-Adapter: Wiggler-Nachbau (ParPort) und  Adapter auf Basis des FTDI2232 (USB)&lt;br /&gt;
* [http://www.ronetix.at/peedi.html Ronetix Peedi]&lt;br /&gt;
* [http://www.segger.de Segger J-Link] JTAG-Adapter, USB-Anschluss, unterstützt z.&amp;amp;nbsp;B. von IAR, Keil uVision (via RDI) (OEM: IAR J-Link, SAM-ICE)&lt;br /&gt;
* [http://www.signalyzer.com/ Signalyzer] Signalyzer Tool, u.a. JTAG-Adapter auf Basis des FTDI2232&lt;br /&gt;
* [http://www.simonqian.com/en/Versaloon/index.html Simon Qians Versaloon]&lt;br /&gt;
&lt;br /&gt;
=== Tutorials und Beispiele ===&lt;br /&gt;
* [http://www.dreamislife.com/arm/ LPC210x ARM7 Microcontroller Tutorial] - Assembler-Beispiele (arm-elf-as) für das Olimex LPC-MT-Board (Philips LPC2106 ARM7TDMI)&lt;br /&gt;
* [http://re-eject.gbadev.org/index.php gcc-Assembler für ARM] - Befehlsübersicht&lt;br /&gt;
* [http://patater.com/gbaguy/gbaasm.htm GBA ASM Tutorial] - ARM7 Assembler Tutorial mit arm-elf-as (&amp;quot;gcc&amp;quot;) (Allgemein und GBA)&lt;br /&gt;
* [http://www.robsite.de/daten/tutorials/devgba/gba_asm1.html GBA Assembler Tutorial] - ARM7TDMI, Schwerpunkt auf GBA&lt;br /&gt;
* [http://www.sparkfun.com/tutorial/ARM/ARM_Cross_Development_with_Eclipse.pdf Eclipse+CDT+gnuarm-Tutorial]&lt;br /&gt;
* [http://mct.de/download/armsamples/map.html Beispiele in C, für ARM7-Controller von Philips und ADI]&lt;br /&gt;
* [http://www.embedded.com/design/opensource/201802580 Embedded.com: Building Bare-Metal ARM Systems with GNU] Teil 10, Links zu den Teilen 1-9 auf der Seite&lt;br /&gt;
* [http://www.sparkfun.com/datasheets/DevTools/SAM7/at91sam7%20serial%20communications.pdf AT91SAM7 Serial Communications] von James P. Lynch (PDF, www.sparkfun.com)&lt;br /&gt;
* [http://www.kaczurba.pl/aduc ADuC7000 Tutorial] von Witold Kaczurba (www.kaczurba.pl)&lt;br /&gt;
&lt;br /&gt;
=== Projekte und Quellcodebibliotheken ===&lt;br /&gt;
* [http://hubbard.engr.scu.edu/embedded/arm/armlib/ Procyon ARMlib-LPC2100] - Treiber, Beispiele (Lizenz: GPL, kaum weiterentwickelt)&lt;br /&gt;
* [http://www.standardics.nxp.com/support/documents/?type=software NXP BlueStreak] Code für LH7xxxx (ehemals Sharp)&lt;br /&gt;
* [http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/index.html M. Thomas&#039; ARM Projekte] &amp;quot;Projectvorlagen&amp;quot; für AT91SAM7 und LPC2000 mit GNU-Toolchain Einsteiger-Projekte für AT91SAM7, LPC2000, ADuC7000 u.a. (u.a. Blinky, UART, Interrupt, C++, GLCD mit KS0108, DS18x20, DCF77, Anpassungen von FAT16/32-Libraries) &amp;lt;!-- noch mehr &amp;quot;Eigenwerbung&amp;quot; --&amp;gt;&lt;br /&gt;
* [http://mcu.st.com/ STMicro] Treiber und Beispiel für STR7, STR9 und STM32&lt;br /&gt;
* [http://wiki.sikken.nl/index.php?title=LPCUSB LPCUSB] - Open-source [[USB]] stack for the built-in USB controller in LPC214x microcontrollers von Bertrik Sikken. [http://lpcusb.cvs.sourceforge.net/lpcusb/host/benchmark/main.c?revision=1.2&amp;amp;view=markup Sample code]&lt;br /&gt;
* [http://www.olimex.com Olimex] Einige Beispiele auf den &amp;quot;Produktseiten&amp;quot; der ARM Boards.&lt;br /&gt;
* [[ARM MP3/AAC Player]]&lt;br /&gt;
* [http://www.jcwren.com/arm/ J.C. Wrens Beispielprojekt] für LPC214x&lt;br /&gt;
* [http://www.keil.com/download/list/arm.htm Beispiele von Keil] abgestimmt auf deren Boards und Realview-Toolchain, Portierung auf andere Boards und Compiler relativ einfach, Lizenz beachten.&lt;br /&gt;
* [http://www.luminarymicro.com/ Luminary Micro Driverlib] für Stellaris Cortex-M3&lt;br /&gt;
* [http://r2d2.stefanm.com/gps-tracker.html GPS-Tracker] mit Navigation auf LPC2103-Basis (Complier: GCC)&lt;br /&gt;
* [http://elua.berlios.de elua] Lua für ARM-controller&lt;br /&gt;
* [http://freemodbus.berlios.de/ FreeMODBUS] &amp;quot;A Modbus ASCII/RTU and TCP implementation&amp;quot; (für STR71x, AT91SAM7, LPC214x, auch: AVR, MSP430 u.a.)&lt;br /&gt;
* [http://bettyhacks.com BettyHacks] Freie Firmware für die &amp;quot;interaktive TV-Fernbedienung&amp;quot; betty-tv (ARM7tdmi, 2MB Flash, 160 x 128 Pixel 2 bit LCD, CC1100, IR, Lautsprecher,..)&lt;br /&gt;
&lt;br /&gt;
=== Betriebssysteme ===&lt;br /&gt;
* [http://agnix.sourceforge.net/ Agnix]&lt;br /&gt;
* [http://www.bertos.org/ BeRTOS] is a completely free, open source, real time operating system (RTOS) suitable for embedded platforms. Runs on many microprocessors and microcontrollers, ranging from 8 bits to 32 bits CPUs and even PCs. &lt;br /&gt;
* [http://chibios.sourceforge.net/ ChibiOS/RT]&lt;br /&gt;
* [http://www.stm32circle.com/resources/upgrade.php Circle-OS for STM32] Kostenloses OS, sehr klein mit Basisfunktionen fuer STM32&lt;br /&gt;
* [http://coocox.org/ CoOS]&lt;br /&gt;
* [http://sources.redhat.com/ecos/ eCos] - &amp;quot;Real-Time-Operating-System&amp;quot; o.a. auch für ARM7&lt;br /&gt;
* [http://www.freertos.org/ FreeRTOS (.org!)] - &amp;quot;Real-Time-Kernel&amp;quot; unter anderem für ARM7 (LPC2xxx) auch AVR, MSP430, &#039;51er&lt;br /&gt;
* [http://sourceforge.net/projects/funkos/ FunkOS]&lt;br /&gt;
* [http://l4ka.org/ L4Ka]&lt;br /&gt;
* [http://www.toradex.com/colibri_downloads/Linux/readme.txt Linux 2.4.29 für Toradex Colibri] basierend auf Intel XScale PXA270&lt;br /&gt;
* [http://www.linux4sam.org Linux4SAM] Informationen, Anleitungen und Code zur Anwendung von Linux auf AT91SAM9xxx&lt;br /&gt;
* [http://www.freertos.com/ NicheTask] (URL ist www.freertos.com aber hat nichts mit FreeRTOS(.org) zu tun)&lt;br /&gt;
* [http://www.ethernut.de/en/software/index.html Nut/OS] Echtzeitbetriebssystem für Mikrocontroller (ARM, AVR, AVR32, Cortex M3 u.A). Multitasking und vollständiger TCP/IP Stack inklusive. Leicht zu erlernen und viele Beispiele&lt;br /&gt;
* [http://nuttx.sourceforge.net/ NuttX RTOS] (ARM7TDMI port for TI TMS320C5471 also called a C5471 or TMS320DM180).&lt;br /&gt;
* [http://www.phoenix-rtos.org/ Phoenix-RTOS]&lt;br /&gt;
* [http://picoos.sourceforge.net/ PicoOS]&lt;br /&gt;
* [http://prex.sourceforge.net Prex] is a portable real-time operating system for embedded systems. The small, reliable, and low power kernel is written in the C language based on microkernel design. The file system, Unix process, and networking features are provided by user mode tasks. (ARM, i386, geplant: MIPS, PowerPC, Hitachi-SH und Win32)&lt;br /&gt;
* [http://www.rtems.org/ RTEMS]&lt;br /&gt;
* [http://code.google.com/p/rt-thread/ rt-thread]&lt;br /&gt;
* [http://sourceforge.net/projects/scmrtos/ scmRTOS]&lt;br /&gt;
* [http://www.tnkernel.com/downloads.html TNKernel] - &amp;quot;Real-Time-Kernel&amp;quot; TNKernel ist ein kompakter und sehr schneller Echtzeitkernel unter anderem für ARM7 (Philips LPC2106/LPC21XX/LPC22xx, Samsung S3C44B0X, Atmel AT91SAM7S128, STMicroelectronics STR711FR2)&lt;br /&gt;
* [http://www.ucos-ii.com/ uC/OS-II RTOS]&lt;br /&gt;
&lt;br /&gt;
=== Hardware (Prototypen-Platinen etc.) ===&lt;br /&gt;
&amp;lt;!-- Veralteter Link; Shop verkauft &amp;quot;nichts&amp;quot; mehr * [http://www.knif-elektronik.de/index.php/cPath/27/category/industrie-module-/-bausaetze.html/ KNIF-elektronik] Preisgünstige Industriemodule und Bausätze z.B GPS, W-Lan, Kamera,Bluetooth uvm. --&amp;gt;&lt;br /&gt;
&amp;lt;!-- Ist KEIN ARM-Board, falsche Rubrik! * [http://www.chip45.com/ chip45] Atmel AVR Module und Boards mit USB, RS232/485, CAN, Ethernet, Funkmodule, sowie ISP Programmieradapter --&amp;gt;&lt;br /&gt;
* [http://www.armkits.com/ Embest] Philips, Samsung und Atmel ARM Boards und Module, JTAG-Hard- und Software&lt;br /&gt;
* [http://www.waveplayer.de/ Embedded-Waveplayer] mit ARM7-Prozessor EP7309 (MIDI- und RS232-Steuerung)&lt;br /&gt;
* [http://www.embeddedartists.com/ Embedded Artists] bietet verschiedene preisgünstige Platinen (ab 25 Euro für LPC213x Familie)&lt;br /&gt;
* [http://www.embedded-it.de/microcontroller/microcontroller-module.php Embedded-IT] eNet-sam7X: Ethernut kompatible Embedded Ethernet Mikrocontroller Boards für Industrie und Hobby auf ARM mit Nut/OS Betriebssystem sowie USB Module auf AVR Basis&lt;br /&gt;
* [http://www.hiteg.com Hiteg] SAMSUNG und Intel XScale basierende boards. (Deutsches Unternehmen in China)&lt;br /&gt;
* [http://www.hitex.de/ Hitex] Starter-Kits für Philips LPC2000, ST STR7, Atmel AT91M&lt;br /&gt;
* [http://www.iar.com/ IAR] Starter-Kits für Atmel, Oki, Philips, ST und TI &lt;br /&gt;
* [http://www.ic-board.de/index.php?cat=c12_ICswift-Module.html ic-board.de] Kommunikationsplattform auf Basis des AT91SAM7X256 mit Ethernet, USB, CAN und Funk Schnittstellen&lt;br /&gt;
* [http://www.keil.com/ Keil] Philips LPC2000 und ST STR7/9 Boards und Starter-Kits&lt;br /&gt;
* [http://www.lpctools.com/ LPCTools] bietet verschiedene Starter Kits für die LPC2000-Familie&lt;br /&gt;
* [http://www.makingthings.com/ MakingThings] Make Controller Kit (AT91SAM7X256)&lt;br /&gt;
* [http://mct.de/index.html MCT Paul und Scherer] Starterkits für ARM7 (NXP LPC2000, ADI ADUC7000)&lt;br /&gt;
* [http://shop.mikrocontroller.net Mikrocontroller.net Shop] Platinen mit AT91SAM7, LPC2xxx, JTAG&lt;br /&gt;
* [http://www.microcontroller-starterkits.de Microcontroller-Starterkits] Starter-Kits für verschiedene Microcontroller (D) preisgünstige Platinen (ab 12,95 Euro für LPC2129 und 2194) sowie Entwicklungsboard komplett bestückt&lt;br /&gt;
* [http://stores.ebay.de/Micro-Research Micro-Research] Development- und Header-Boards für LPC2000 und ADuC7000&lt;br /&gt;
* [http://www.olimex.com Olimex] Bulgarischer Anbieter günstiger ARM Prototypen- und Header-Boards (LPC2000, STR7, AT91SAM, ADI, TI, OKI u.a.)&lt;br /&gt;
* [http://www.propox.com/?lang=en Propox]&lt;br /&gt;
* [http://www.mcu-raisonance.com/~primer-starter-kits__microcontrollers__tool~tool__T018:4enfvamuxbtp.html Primer2 from Raisonance] Focus auf STM32 mit sehr grossem Forum im STM32circle&lt;br /&gt;
* [http://www.revely.com/ Revely] Evaluations- und Demo-Boards mit Sharp ARM Controllern. Teilweise mit SVGA-Anschluss.&lt;br /&gt;
* [http://www.skpang.co.uk/catalog/index.php SKPang electronics] Entwicklungsboards für diverse ARM7/9 (UK)&lt;br /&gt;
* [http://www.dilnetpc.com SSV Embedded Systems] bietet verschiedene Starter Kits für die verschiedenen DIL/NetPC u.a. (A)DNP/9200 SBC mit AT91RM9200&lt;br /&gt;
* [http://www.taskit.de taskit] [https://www.ledato.de/shop_content.php?coID=10 Development- und Header-Boards für AT91SAM7S/X], AT91RM9200, AT91SAM9&lt;br /&gt;
* [http://www.toradex.com/e/products.html Toradex] Colibri: Intel XScale PXA270 DevKit (Schweiz)&lt;br /&gt;
&lt;br /&gt;
== [[PIC]] ==&lt;br /&gt;
&lt;br /&gt;
=== Herstellerseiten ===&lt;br /&gt;
* [http://www.microchip.com Microchip] Hersteller der PIC Microcontroller&lt;br /&gt;
* [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en010014&amp;amp;part=SW006011 Microchip C18 Student Edition] - die &amp;quot;Student Edition&amp;quot; des Microchip C18 C Compilers für die PIC18 Serie ist kostenlos verfügbar.&lt;br /&gt;
* [http://www.powercontact.de Elektronikentwicklung von Systemtechnik LEBER] Offizieller Microchip Design Partner für professionelles Microcontroller Design und Hersteller von Leistungsstellern, Thyristorstellern und Halbleiterelais...&lt;br /&gt;
&lt;br /&gt;
=== Entwicklungstools / Tutorials / Foren  ===&lt;br /&gt;
* [http://www.osterer.co.at www.osterer.co.at] Entwicklungs-Board mit integrierten Programmer/Debugger für PIC18F4550.&lt;br /&gt;
* [http://www.martins-elektronikwelt.tk www.martins-elektronikwelt.tk] ICD1-Debugger-Nachbau im Kleinstformat u. SMD Technik (so groß wie eine halbe Scheckkarte).&lt;br /&gt;
* [http://www.sprut.de/electronic/pic/index.htm PIC-Microchip-Controller (www.sprut.de)] Diese Seite soll dem Anfänger die ersten Schritte in die Welt der Microcontroller der Firma Microchip erleichtern. Betrachtet werden die 14-Bit-Controller der Serien PIC16Fxxx bzw PIC12Fxxx.&lt;br /&gt;
* [http://pic-projekte.de/ PIC-Projekte.de] Tutorials (u.a. für PIC C) und Projekte mit erklärten Codesnipseln (geeignet für Anfänger), [http://pic-projekte.de/phpBB3/ deutschsprachiges PIC Forum]&lt;br /&gt;
* [http://www.fernando-heitor.de PIC: Programmierung in CCS (www.fernando-heitor.de)] Dies ist eine weitere Seite, die dem Anfänger, der sich mit PICs beschäftigt, auf die Beine hilft. Sie befasst sich hauptsächlich mit dem CCS-Compiler und hat dazu ein sehr gutes Tutorial. Ausserdem bietet die Seite ein Forum speziell für PIC Mikrocontroller.&lt;br /&gt;
* [http://www.cc5x.de CC5X] Programmierkurs für PIC-Mikrocontroller in C (CC5X Compiler)] Programmierkurs mit Beispielen und Schaltplänen, fertige Hardware- und Softwarelösungen. In diesem Kurs sind auch einige Unterprogramme detailliert erklärt.&lt;br /&gt;
* [http://www.microchipc.com/ MicrochipC.com] Programmieren von PIC-Microcontrollern mit C. (Enthält auch Links und Bootloader für diverse PICs.)&lt;br /&gt;
* [http://www.amodio.biz/projects/PIC10BaseT/index.html Internetworking with Microchip Microcontrollers - PIC18F4620+ENC28J60]&lt;br /&gt;
* [http://pic18fusb.online.fr/wiki/wikka.php?wakka=WikiHome Wiki about Microchip USB PIC] (PIC18F2550, PIC18F4550...)&lt;br /&gt;
* [http://members.aon.at/electronics/pic/picpgm/index.html PICPgm - A free and simple PIC Development Programmer Software for Windows and Linux] Einfacher PIC Programmer für Windows und Linux. Unterstützt eine Vielzahl von PIC-Chips und wird ständig erweitert. Derzeit können PIC10F, PIC12F, PIC16F, PIC18F, PIC24H  sowie dsPIC30F und dsPIC33F programmiert werden.&lt;br /&gt;
* [http://www.stolz.de.be InCircuit-Programmer und -Debugger (www.stolz.de.be)] Einfacher Nachbau des Microchip ICD2s. Zum Programmieren und Debuggen.&lt;br /&gt;
* [http://www.winpicprog.co.uk WinPicProg] Programmer und Tutorials für Anfänger von Nigel Goodwin (Englisch)&lt;br /&gt;
* [http://usbpicprog.org/ usbpicprog], an open source Microchip PIC programmer for the USB port. A wxWidgets based (cross platform) application to communicate with the usbpicprog hardware / firmware. This application is known to function well on Linux, Windows (XP or later) and Macosx.&lt;br /&gt;
* [http://www.tigal.com EasyPIC3, EasyPIC4, Easy8051A, EasyAVR, Easy-was-weiss-ich (www.tigal.com)] - Distributor für Produkte von [http://www.mikroelektronika.co.yu mikroelektronika] und weiteren Herstellern&lt;br /&gt;
*[http://www.pro-zukunft.de Pro Zukunft] Evaluation-Board für PIC16F84A, hands-on-training und Print-Lehrgang. Für Schulen, Ausbildungsbetriebe &amp;amp; Hobbyelektroniker.&lt;br /&gt;
* [http://www.wselektronik.at www.wselektronik.at] Bausatz für &amp;quot;Full Speed ICD2&amp;quot; (USB2.0, Debugger, Programmer) oder Fertiggerät erhältlich.&lt;br /&gt;
* [http://www.uchobby.com/index.php/2008/04/19/pic-development-linux-style/ How to setup for PIC microcontroller development on Linux] von Steven Moughan&lt;br /&gt;
* [http://www.dattalo.com/gnupic/gpsim.html#docs gpsim] is a full-featured software simulator for Microchip PIC microcontrollers distributed under the GNU General Public License.&lt;br /&gt;
* [http://www.mtoussaint.de/yapide.html YaPIDE] aims to be a fully featured Microchip PIC simulator for Linux (and probably other UNIXes). YaPIDE is a GUI only application. If you need a commandline based PIC simulator there is the excellent &#039;&#039;&#039;gpsim&#039;&#039;&#039;. The simulator kernel currently supports the PIC 16F628.&lt;br /&gt;
* [http://piklab.sourceforge.net/ Piklab] is an integrated development environment for applications based on Microchip PIC and dsPIC microcontrollers similar to the MPLAB environment. It integrates with several compiler and assembler toolchains (like gputils, sdcc, c18) and with the simulator &#039;&#039;&#039;gpsim&#039;&#039;&#039;. It supports the most common programmers (serial, parallel, ICD2, Pickit2, PicStart+) and debuggers (ICD2).&lt;br /&gt;
* [http://dev.frozeneskimo.com/software_projects:vpicdisasm vPICdisasm] is a Microchip PIC Mid-Range family firmware disassembler. This single-pass disassembler can read Intel HEX and Motorola S-Record formatted files containing valid PIC firmware. (GPL)&lt;br /&gt;
* [http://pikdev.free.fr/ PiKdev] is a simple graphic IDE for the development of PIC-based applications. It currently supports assembly language. C language is also supported for PIC 18 devices. PiKdev is developed in C++ under Linux and is based on the KDE environment.&lt;br /&gt;
* [http://www.yenka.com/en/Yenka_PICs/ Yenka PICs] lets you write routines using simple flowcharts, and test them on-screen, before using them to program real PIC or PICAXE chips. To help spread the news about Yenka, we&#039;re offering free copies of Yenka PICs for use at home or school.&lt;br /&gt;
* [http://gcbasic.sourceforge.net/ Great Cow BASIC] &amp;quot;Open Source BASIC programming tools for Microchip PIC and Atmel AVR microcontrollers&amp;quot;&lt;br /&gt;
* [http://openprog.altervista.org/OP_eng.html Open Programmer] - An open source [[USB]] programmer for [[PIC]] micros, [[I2C]]-[[SPI]]-MicroWire [[EEPROM]]s, some ATMEL [[AVR]] micros, generic I2C/SPI devices and (soon) other devices. Can work as [[ICD]] debugger.&lt;br /&gt;
&lt;br /&gt;
=== Projektsammlungen/Einzelprojekte ===&lt;br /&gt;
* [http://www.martins-elektronikwelt.tk www.martins-elektronikwelt.tk] Viele Projekte mit den PIC Mikrocontrollern, u.a. SMS-Schaltzentrale, SD/MMC-FAT32-MP3-Player, Lichtschranken, Funk-Wetterempfänger, PS/2 am PIC usw.&lt;br /&gt;
* [http://www.Firmware-On-Demand.com Firmware-On-Demand] Umfangreiche Firmware-Bibliothek. &lt;br /&gt;
* [http://pic-projekte.de/hd44780_c18.html XLCD Librarie] Anleitung zum Ansteuern des HD44780 unter Verwendung der C18 XLCD Librarie&lt;br /&gt;
* [http://www.rentron.com www.rentron.com] Anfänger-taugliche Projekte für PIC und [[8051]] von Reynolds Electronics (Englisch)&lt;br /&gt;
* [http://www.circuitcellar.com/microchip2007/ Microchip 16-Bit Embedded Control 2007 Design Contest] bei [http://www.circuitcellar.com/ Circuit cellar]&lt;br /&gt;
* [http://mondo-technology.com/ Mondo Technologiy] Grosse Ansammlung von PIC-Projekten, u.a. SuperProbe: Logic Probe,(Auf der linken Seite ganz oben) Logic pulser, Frequency Counter, Event Counter, Voltmeter, Diode Junction Voltage, Capacitance Measurement, Inductance Measurement, Signal Generator, Video Patern, Serial Ascii, Midi Note, R/C Servo, Square Wave, Pseudo Random Number, ir38, PWM in einem... (PIC16F870)&lt;br /&gt;
* [http://micrognurtos.sourceforge.net uGNU/RTOS] is a microcontroller-targeted serial real time operating system. It has been ported to USART capable Microchip PIC16 devices. It supports I/O operations and some internal registry operations. The user can interact with the chip through the RS-232 serial cable and a shell. The user can type a small list of commands and see the results on the chip&#039;s outputs. (LGPL)&lt;br /&gt;
* [http://pic-projekte.de www.PIC-Projekte.de] Hier finden sich einige interessante Projekte mit PIC Mikrocontrollern (z.B. Anleitung zum Ansteuern eines HD44780 komp. LCD von eA, Ansteuern eines KS0107/8 Controllers in ASM mit PIC) sowie Erklärungen zu den dazugehörigen Programmabschnitten. Außerdem gibt es eine Anleitung zum Herrstellen von Platinen. Besuchen Sie das [http://pic-projekte.de/phpBB3/index.php PIC-Forum] und diskutieren Sie mit bei spannenden Themen. Wenn Sie Fragen zu PIC µC der Firma Micochip haben, dann sind Sie hier richtig aufgehoben!&lt;br /&gt;
* [http://pic16f628a.blogspot.com/ Experiments with PIC16F628A] - PIC Programming in C&lt;br /&gt;
&amp;lt;!-- * [http://www.picguide.org PIC Guide] Eine große Sammlung von PIC-Projekten für den Anfänger 6.9.2010: nur cPanel Standard Seite --&amp;gt;&lt;br /&gt;
*Stevy&#039;s Homepage http://stevy.bplaced.com Pic Projekte die in C geschriebn wurden z.B 3D Engine, Grafik Display Ansteuerungen, Oszilloskip usw&lt;br /&gt;
* [http://www.simon-brenner.ch/projekte/rgb-led-stripe RGB Stripe mit 16bit Bus, realisiert mit PIC12F629]&lt;br /&gt;
* [http://scifi.pages.at/drakesoft/aulem_mypong/ Spiel PONG] auf einer 16x16 LED Matrix mit Ton, realisiert auf einem AVR.&lt;br /&gt;
* [http://hackinglab.org/ Pinguino Webpage] und [http://wiki.pinguino.cc/index.php/Main_Page Pinguino Wiki] ist ein Arduino-ähnliches Open Source und Open Hardware Projekt für 8-Bit (PIC18F2550, PIC18F4550) Mikrocontroller.&lt;br /&gt;
&lt;br /&gt;
== [[Z8]] ==&lt;br /&gt;
* [http://groups.yahoo.com/group/z8encore/ Yahoo! Groups : z8encore] Yahoo-Gruppe, die sich mit den Z8 Encore! Mikrocontrollern beschäftigt (Anmeldung bei Yahoo erforderlich).&lt;br /&gt;
* [[Zilog Encore Experimentierplatine]] (Z8F6421 Familie mit DIP-40 Gehäuse)&lt;br /&gt;
*[http://www.thpeter.net Zilog Projekte] (Ein Z8Encore und ZNEO Projekt und viele Tips zum Programmieren und Debuggen)&lt;br /&gt;
&amp;lt;!-- * [http://www.z8micro.com/forum/ Z8 Encore! Microcontroller Discussion Forum - Dedicated to the ZiLOG Z8 Encore! Microcontroller] Ein der Z8 Encore!-Mikrocontrollerfamilie gewidmetes Diskussionsforum (in Englisch). - Link tot 6.9.2010 --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Programmierbare Logik ([[CPLD]]/[[FPGA]]/[[GAL]]) ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.opencores.org/ OpenCores.org], VHDL Sourcen&lt;br /&gt;
* [http://www.fpga4fun.com/ fpga4fun], umfangreiche Seite mit Einführung und Beispielen, berücksichtigt Xilinx &amp;amp; Altera&lt;br /&gt;
* [http://opencollector.org/history/freecore/ Freecore], unter &#039;Module library&#039; gibt&#039;s einige freie Designs&lt;br /&gt;
* [http://www.cmosexod.com/ CMOSExod], Designs unter &#039;Free IP&#039;&lt;br /&gt;
* [https://digilent.us/ Digilent], Hersteller verschiedener FPGA/CPLD-Boards (u.a. Xilinx Spartan Starter Kit)&lt;br /&gt;
* [http://www.terasic.com.tw/cgi-bin/page/archive.pl?Language=English&amp;amp;CategoryNo=39 Terasic], Anbieter von Altera FPGA-Boards&lt;br /&gt;
* [http://shop.trenz-electronic.de/catalog/ Trenz Elektronik], verkauft verschiedene FPGA/CPLD-Boards&lt;br /&gt;
* [http://www.xess.com/index.html XESS], Anbieter von FPGA-Boards (Xilinx), unter Support gibts es eine Menge Beispiele&lt;br /&gt;
* [http://members.optushome.com.au/jekent/FPGA.htm Private Seite von John Kent], enthält eine Menge Links und auch einige Designs&lt;br /&gt;
* [http://www.openpicide.org openPICIDE], Picoblaze IDE für Windows, Linux und Mac&lt;br /&gt;
* [http://www.mediatronix.com/Tools.htm Mediatronix tools], Picoblaze und DSP tools&lt;br /&gt;
* [http://www.ixo.de/info/usb_jtag/ ixo.de usbjtag] - USB-JTAG Adapter, fast kompatibel zu Altera USB-Blaster, wahlweise basierend auf FT245+CPLD oder Cypress FX2 Controller&lt;br /&gt;
* [http://www.fpgacpu.org/links.html FPGA CPU Links]&lt;br /&gt;
* [http://www.fpga-forum.com/wbb Forum mit allgemeinen Diskussionen zum Thema FPGA und FAQ&#039;s speziell zu den Cesys FPGA Karten]&lt;br /&gt;
* [http://www.cesys.biz Online Shop für Cesys FPGA Karten]&lt;br /&gt;
&lt;br /&gt;
== DSP ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.tetrix-systems.de/embedded.html combined embedded Linux-DSP Solutions]&lt;br /&gt;
* [http://open.neurostechnology.com/node/1020 TI c54x DSP  Compilertools (ohne Debugger)] frei für Open Source Projekte.&lt;br /&gt;
&lt;br /&gt;
== Wettbewerbe (Contests) == &lt;br /&gt;
&lt;br /&gt;
Verschiedene Hersteller veranstalten zur Promotion ihrer Produkte Designwettbewerbe, aus denen teilweise komplette Projektunterlagen hervorgehen (Schaltung, Source).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2011&#039;&#039;&#039;&lt;br /&gt;
*[http://www.555contest.com 555 Contest]&lt;br /&gt;
*[http://www.circuitcellar.com/nxpmbeddesignchallenge/ NXP and ARM/mbed challenge]&lt;br /&gt;
*[http://www.ebv.com/en/products/stm32-design-contest.html STM32 Design Contest] von EBV Elektronik und STMicroelectronics&lt;br /&gt;
* [http://www.renesasrulz.com/community/rx-contest The RX MCU Design Contest] und die Top 3 im [http://www.eevblog.com/2011/06/05/eevblog-174-renesas-rx-design-contest-winners/ Video] bei Dave Jones auf EEVBlog.com&lt;br /&gt;
* [http://www.cypress.com/?id=3298 ARM Cortex-M3 PSoC® 5 Design Challenge]&lt;br /&gt;
* [http://www.instructables.com/contest/micro/ SparkFun Microcontroller Contest] bis 13.02.2011&lt;br /&gt;
* [http://www.elektroniknet.de/bauelemente/news/article/27963/0/Wer_entwickelt_die_beste_Anwendung_mit_dem_EFM32/ EFM32 Design-Wettbewerb] von Elektronik, Avnet-Memec und Energy Micro&lt;br /&gt;
* [http://www.freescale.com/webapp/sps/site/overview.jsp?code=KINETIS_MAKEIT_CHALLENGE&amp;amp;tid=vanKINETIS_MAKEIT_CHALLENGE Make It Challenge: Kinetis MCUs] von Freescale&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2010&#039;&#039;&#039;&lt;br /&gt;
* [http://www.schmartboard.com/index.asp?page=mcu_2010 SchmartBoard 2010 MCU Challenge]&lt;br /&gt;
* [http://www.digilentinc.com/showcase/contests/designcontest.cfm?ContestID=6 Digilent Design Contest 2010]&lt;br /&gt;
* [http://www.parallax.com/go/holidaychallenge Parallax &amp;amp; iGen Student LED Holiday Challenge]&lt;br /&gt;
* [http://www.embeddedspark.com/upcomingchallenge/ The embeddedSPARK 2010 SUMMER Challenge]&lt;br /&gt;
* [http://www.libelium.com/tienda/catalog/contest.php?language=en Libelium Arduino Open Hardware Contest]&lt;br /&gt;
* [http://www.circuitcellar.com/designstellaris2010/index.html Texas Instruments DesignStellaris 2010]&lt;br /&gt;
* [http://www.wizwiki.net/main/ iMCU Design Contest] (WIZnet)&lt;br /&gt;
* [http://www.elo-web.de/elo/entwicklung-und-projekte/ping-pong/elo-programmierwettbewerb-2010 ELO-Programmierwettbewerb 2010] (Atmega8, PingPong-Platine, 31.3.10)&lt;br /&gt;
* [http://www.lpc1100challenge.com/ NXP LPC1100 Design Challenge] (Cortex-M0 based LPC1100)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2009&#039;&#039;&#039;&lt;br /&gt;
* [http://arduinofun.com/blog/2009/11/01/fun-with-arduino-contest/ Fun with Arduino Contest]&lt;br /&gt;
* [https://www.xmos.com/challenge/ XMOS Challenge]&lt;br /&gt;
* [http://www.designmsp430.com/ Design MSP430 Ultra-Low Power Challenge]&lt;br /&gt;
* [http://makezine.com/halloweencontest/ Make: Halloween Contest 2009], sponsored by Microchip Technology!&lt;br /&gt;
* [http://www.bricogeek.com/contest/let-arduino-play/resultados.php Let Arduino Play Contest]&lt;br /&gt;
* [http://www.dlpdesign.com/designcontest/ DLP Design DLP-232PC Design Contest]&lt;br /&gt;
* [http://www.libelium.com/tienda/catalog/contest.php Arduino contest by Libelium]&lt;br /&gt;
* [http://www.expli.de/wettbewerb/coole-avr-microcontroller-elektronik-ideen/ EXPLI Elektronik Wettbewerb]: Die coolsten Elektronik Projekte &amp;amp; AVR Microcontroller Anleitungen&lt;br /&gt;
* [http://www.stm32circle.com/projects/contest.php STM32 Primer2 Design Competition 2009]&lt;br /&gt;
* [http://www.parallax.com/Resources/ApplicationsContests/Contests/200910PropellerContest/tabid/846/Default.aspx 2009/2010 Propeller Design Contest]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2008&#039;&#039;&#039;&lt;br /&gt;
* [http://www.parallax.com/tabid/720/Default.aspx Propeller Design Contest]&lt;br /&gt;
* [http://www.psocidcindia.com/index.php PSoC Innovator Design Challenge India 2008]&lt;br /&gt;
* [http://www.mypic32.com Microchip PIC32 Design Challenge]&lt;br /&gt;
* [http://contest.renesasinteractive.com/ HEW Target Server Design Contest 2008]&lt;br /&gt;
* [http://www.stm32circle.com/projects/result_contest_2008.php STM32 Primer Design Competition 2008]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2007&#039;&#039;&#039;&lt;br /&gt;
* [http://www.circuitcellar.com/wiznet/index.html WIZnet iEthernet Design Contest 2007] &lt;br /&gt;
* [http://www.circuitcellar.com/microchip2007/ Microchip 16-Bit Embedded Control 2007 Design Contest]&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2006&#039;&#039;&#039;&lt;br /&gt;
* [http://www.designmsp430.com/View.aspx 2006 MSP430 eZ Design Contest] &lt;br /&gt;
* [http://www.luminarymicro.com/DesignStellaris2006 Luminary Micro DesignStellaris2006]&lt;br /&gt;
* [http://www.circuitcellar.com/avr2006/ Atmel AVR Design Contest 2006] &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2005&#039;&#039;&#039;&lt;br /&gt;
* [http://www.jandspromotions.com/philips2005/index.htm Philips ARM Design Contest 2005] (LPC213x)&lt;br /&gt;
* [http://www.circuitcellar.com/renesas2005m16c/index.htm Renesas M16C Design Contest 2005]&lt;br /&gt;
* [http://www.edn.com/article/CA516007.html Cornelius van Drebbel&#039;s Mad Design Contest] (NEC)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2004&#039;&#039;&#039;&lt;br /&gt;
* [http://www.circuitcellar.com/avr2004/ Atmel AVR 2004 Design Contest]&lt;br /&gt;
* [http://www.circuitcellar.com/psoc2004/ PSoC High Integration Challenge 2004]&lt;br /&gt;
* [http://www.jandspromotions.com/zilog2004/ Zilog 2004 Flash Nets Cash Design Contest] (eZ80Acclaim!)&lt;br /&gt;
* [http://www.jandspromotions.com/wirelesschallenge/index.html 2004 Freescale Wireless Design Challenge] (MC13191/92/93 RF Transceivers, [[Meshnetics Zigbee|ZigBee]])&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2003&#039;&#039;&#039;&lt;br /&gt;
* [http://www.circuitcellar.com/fi2003/ MOTOROLA FLASH INNOVATION 2003 DESIGN CONTEST] (Motorola HC08)&lt;br /&gt;
* [http://www.circuitcellar.com/renesas/ Renesas H8 Design 2003 Contest]&lt;br /&gt;
* [http://www.jandspromotions.com/zilog2003/ ZiLOG Flash for Cash Z8 Encore®! International Design Contest]&lt;br /&gt;
* [http://www.jandspromotions.com/efield203/index.htm 2003 Motorola E-Field Sensor Contest] (MC33794)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2002&#039;&#039;&#039;&lt;br /&gt;
* [http://www.circuitcellar.com/flash2002/ Mad Dash for Flash Cash] (Microchip, PIC)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;2001&#039;&#039;&#039;&lt;br /&gt;
* [http://www.circuitcellar.com/dl2001/ Atmel &#039;Design Logic 2001&#039; Design Contest]&lt;br /&gt;
* [http://www.circuitcellar.com/msp430/ MSP430 Design Contest]&lt;br /&gt;
&lt;br /&gt;
== Interfaces &amp;amp; Protokolle ==&lt;br /&gt;
Siehe auch [[Linksammlung#Schnittstellen]]&lt;br /&gt;
&lt;br /&gt;
=== Infrarot (IR) ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.sbprojects.com/knowledge/ir/index.php Übersicht IR-Protokolle] von San Bergmans (engl.): ITT, JVC, NEC, Nokia NRC17, Sharp, Sony SIRC, Philips RC-5, RC-6, RC-MM, RECS80, RCA, X-Sat&lt;br /&gt;
* [http://www.vishay.com/docs/80071/dataform.pdf Data formats for IR controls (PDF)] von Vishay.&lt;br /&gt;
* [http://www.ostan.cz/IR_protocol_analyzer/ IR protocol analyzer] (Freeware)&lt;br /&gt;
&lt;br /&gt;
=== Parallelport ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.projects-lab.com/?p=1139 ECPMON] - ECP Parallel Port Monitor ([[M16C]]/62P) &lt;br /&gt;
&lt;br /&gt;
=== iPod ===&lt;br /&gt;
* [http://ipodlinux.org/IPod_to_T%26A_remotecontrol_adapter IPod to T&amp;amp;A remotecontrol adapter] ([[PIC]]-Projekt)(Link defect)&lt;br /&gt;
* http://jasongarr.wordpress.com/project-pages/ipod-clickwheel-hack/&lt;br /&gt;
&lt;br /&gt;
=== [[RFID]] ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.alexanderguthmann.de/RFIDemulator.html RFIDemulator] - Beschreibung eines RFIDemulators zum klonen von Tags&lt;br /&gt;
* [http://www.mwjournal.com/journal/article.asp?HH_ID=AR_905 Radio Frequency Identification: Evolution of Transponder Circuit Design] - Übersichtsartikel aus dem Microwave Journal&lt;br /&gt;
* [http://www.foebud.org/rfid Die StopRFID-Seiten des FoeBuD e.V.]&lt;br /&gt;
* [http://www.rfzone.org/free-rf-ebooks/ PDF-Bücher (englisch) ]- Bücher über RF, Antennen und elektromagnetische Wellen.&lt;br /&gt;
&lt;br /&gt;
* http://cq.cx/proxmark3.pl Jonathan Westhues RFID Leser/Schreiber/Cloner&lt;br /&gt;
&lt;br /&gt;
http://www.message_bocracco.com/&lt;br /&gt;
&lt;br /&gt;
==== ~ 125 kHz ====&lt;br /&gt;
&lt;br /&gt;
*[http://t4f.org/en/projects/open-rfid-tag Open RFID Tag]&lt;br /&gt;
&lt;br /&gt;
==== 13,56 MHz RFID ====&lt;br /&gt;
* [http://www.openpcd.org/ OpenPCD - a free 13.56MHz RFID reader design] for Proximity Coupling Devices (PCD) based on 13,56MHz communication. This device is able to screen informations from Proximity Integrated Circuit Cards (PICC) conforming to vendor-independent standards such as ISO 14443, ISO 15693 as well as proprietary protocols such as Mifare Classic. (AT91SAM7S128 [[ARM]] Projekt)&lt;br /&gt;
* [http://www.rf-dump.org/ RFDump] is a backend GPL tool to directly interoperate with any RFID ISO-Reader to make the contents stored on RFID tags accessible. (Linux)&lt;br /&gt;
&lt;br /&gt;
==== 2,4 GHz RFID ====&lt;br /&gt;
* [http://www.openbeacon.org/ OpenBeacon] - a free active 2.4GHz beacon design. (Reader: USB oder Ethernet; Tags: RF_Chip: NRF24L01, PIC16F684)&lt;br /&gt;
&lt;br /&gt;
=== [[DMX512]] ===&lt;br /&gt;
* [http://www.soundlight.de/techtips/dmx512/dmx512.htm DMX-512 - was ist das?] Eine Übersicht von SOUNDLIGHT.&lt;br /&gt;
* [http://dworkin-dmx.de/ USB DMX Interface] Bausatz /Fertiggerät USB DMX Interface  &lt;br /&gt;
* [http://www.oksidizer.com/electronic/spp2dmx/index_en.html OksiD DMX 3/1 is a Standard Parallel Port DMX 512 interface for IBM compatible PCs]. Drei Output Universe und ein Input Universe (Universe = 512 channels). Open project. All source code and schematics are available for free. &lt;br /&gt;
* [http://www.usbdmx.com/usb_dmx_interface.html USB DMX Interface revision 1.3] - opto isolated, bus powered, DMX512 from/to [[USB]]interface with both in and out universes. Cheap and simple to build.&lt;br /&gt;
* [http://www.dmx512-online.com/ Ujjal&#039;s DMX512 Seite]&lt;br /&gt;
* [http://llg.cubic.org/dmx4linux/ DMX4Linux 2.6] - A DMX device driver package for Linux (incl. hardware schematics with TI [[MSP430]])&lt;br /&gt;
&lt;br /&gt;
=== Verschiedenes ===&lt;br /&gt;
* [http://www.taelektroakustik.de/deu/index.htm T&amp;amp;A Kommandos] - &#039;&#039;&#039;RC&#039;&#039;&#039; und &#039;&#039;&#039;RCII&#039;&#039;&#039; Kommandoset der Philips PRONTO Familie zur Steuerung von Audiogeräten. Dokumentation siehe unter Downloads.&lt;br /&gt;
* [http://www.marjorie.de/ps2/ps2_protocol.htm Das PS/2 Maus und PS/2- oder AT-Tastatur-Protokoll] (Original auf [http://www.computer-engineering.org/])&lt;br /&gt;
* [http://www.hth.com/snap/ S.N.A.P - Scaleable Node Address Protocol]. S.N.A.P is an free and open network protocol. The protocol was primary developed for PLM-24 based home automation and control systems but it is a generic protocol and not limited to this. S.N.A.P can be used in any type of applications where an easy to learn and light weighted network protocol is needed.&lt;br /&gt;
* [http://www.ulrichradig.de/home/index.php/avr/avr_-_rc PPM / PWM Encoder/Decoder für R/C Funkfernsteuerungen] von Ulrich Radig (AVR, C)&lt;br /&gt;
* [http://www.national.com/analog/interface/lvds_owners_manual LVDS Owner&#039;s Manual - 4th Edition] von National Semiconductor&lt;br /&gt;
* [http://www.mictronics.de/?page=becker Becker Unilink]&lt;br /&gt;
* [http://users.ntplx.net/~andrew/sony/unilink/ Sony UniLink]&lt;br /&gt;
* [http://www.vending.org/technology/MDB_Version_4.pdf Multi-Drop Bus / Internal Communication Protocol (MDB / ICP)]&lt;br /&gt;
&lt;br /&gt;
== Elektronikversender‎ ==&lt;br /&gt;
&lt;br /&gt;
siehe [[Elektronikversender‎]]&lt;br /&gt;
&lt;br /&gt;
== Leiterplattenhersteller ==&lt;br /&gt;
&lt;br /&gt;
siehe [[Platinenhersteller]]&lt;br /&gt;
&lt;br /&gt;
== Schulungen (Online) ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.esacademy.com/myacademy/ www.esacademy.com] (engl.) - C, CAN, I²C, BlueTooth, PWM, USB, 51LPC, ARM (Einführung)&lt;br /&gt;
* [http://www.elprak.ch Elektronik in der Praxis] Präsentationen zu verschiedenen Themen der Elektronik in der Praxis. Lötvideo, das den zeitlichen Ablauf beim Löten anschaulich darstellt.&lt;br /&gt;
* [http://www.national.com/onlineseminar/ www.national.com] - Amplifiers, Audio, Data Acquisition, Die Products, Displays, Interface, Microcontrollers, Military/Aerospace, Power, Thermal Management, Wireless&lt;br /&gt;
* [http://www.circuitrework.com Circuit Technology Center] - Surgeon grade rework and repair, by the book and guaranteed. Deeplink: [http://www.circuitrework.com/guides/guides.shtml Guides]&lt;br /&gt;
* [http://www.onlinetutorials.de/index.htm onlinetutorials.de] - Linksammlung zu Tutorials für höhere Programmiersprachen ([[HLL]]) wie C, C++, Java, BASIC, Perl, PHP, ...&lt;br /&gt;
* [http://www.awce.com/classroom/ AWCE Interactive Classroom] - Embedded Systems (Using the APP-IV with GCC, Getting Started with the PIC 18F Family), Electronics (CLARC/HBSIG DSP Study Group, Basic Circuits), RoadMap to Programmable Logic&lt;br /&gt;
* [http://www.ibiblio.org/kuphaldt/socratic/ Socratic Electronics] (englisch)&lt;br /&gt;
* [http://www.embedded.com/design/multicore/201200638;jsessionid=4T1T0OZQW4PFSQSNDLRSKH0CJUNN2JVN?printable=true The basics of programming embedded processors] von Wayne Wolf. Neun Artikel bei embedded.com (englisch)&lt;br /&gt;
* [http://webcast.berkeley.edu/course_details.php?seriesid=1906978507 EE 42/EE 100 Introduction to Digital Electronics] - Webcast, Spring 2008 (englisch)&lt;br /&gt;
* [http://freevideolectures.com freevideolectures.com] - Webcasts zu  naturwissenschaftlichen Theman (englisch)&lt;br /&gt;
* [http://www.circuitsage.com/ Circuit Sage], a complete source of information to help you design circuits fast. (Linksammlung zu Software, Artikeln Büchern und Websites)&lt;br /&gt;
* [http://www.DieElektronikerseite.de Die Elektronikerseite] Umfangreiche Sammlung von kleinen Lehrgängen und Schaltungen. Ideal für Anfänger aber auch für Fortgeschrittene&lt;br /&gt;
* [http://homepages.internet.lu/absolute3/tronic/ 3D Virtual Development] - Sammlung von vielen Grundschaltungen im Bereich Oszillator, Operationsverstärker, Empfangstechnik. Vereinzelt in Englisch.&lt;br /&gt;
* [http://cws.gtc.edu/programs/objects/electronics.htm Learning Objects for Electronics] des Engineering Tech Wing of Gateway Technical College (Flash erforderlich)&lt;br /&gt;
* [http://ecee.colorado.edu/~bart/book/book/title.htm Principles of Semiconductor Devices] von Bart Van Zeghbroeck&lt;br /&gt;
* [http://itp.nyu.edu/physcomp/Intro/HomePage Introduction to Physical Computing] ([[AVR]], Arduino)&lt;br /&gt;
&lt;br /&gt;
== Skripte ==&lt;br /&gt;
&lt;br /&gt;
* [http://www.janson-soft.de/skripte/index.html Linksammlung von Volker Lange-Janson]&lt;br /&gt;
* [http://wwwex.physik.uni-ulm.de/lehre/physikalischeelektronik/phys_elektr/phys_elektr.html Physikalische Elektronik und Messtechnik] von Othmar Marti und Dr. Alfred Plettl, Universität Ulm&lt;br /&gt;
* [http://openbookproject.net//electricCircuits/index.htm Lessons in Electric Circuits I-VI] von Tony R. Kuphaldt&lt;br /&gt;
&lt;br /&gt;
== Messequipment ==&lt;br /&gt;
* [http://www.filmetrics.com  Filmetrics Inc.] (Filmetrics manufactures affordable thin-film measurement instruments capable of measuring thin films from 3nm to 0.5mm in thickness.)&lt;br /&gt;
* [http://www.pce-instruments.com  PCE Instruments] (Entwicklung und Produktion für Prüfgeräte und Waagen.)&lt;br /&gt;
=== Logikanalyse ===&lt;br /&gt;
* [http://www.pctestinstruments.com Intronix LogicPort], Günstiger, aber sehr leistungsfähiger Logikanalysator mit USB-Anschluß an PC (34Ch, 500MHz Timing, 34 x 2kSa mit Kompression, ca. 295 Euro [http://www.shop.display3000.com/elektronik/messgeraete/index.html hier])&lt;br /&gt;
* Zeroplus LAP-Cxxxx (Familie von LA&#039;s mit unterschiedlichen Daten, 32kBit...2MBit, 16ch oder 32ch, 100MHz..200MHz, Preise von 90,-...1100,- Euro, zu kaufen [http://www.tigal.com/products_category.asp?cid=96 hier])&lt;br /&gt;
* [http://www.tech-tools.com/dv_main.htm TechTools DigiView], Günstiger Logikanalysator mit USB-Anschluß an PC (18Ch, 100MHz Timing, 128kSa mit Kompression,  [http://elmicro.com/de/digiview.html ca. 430Euro])&lt;br /&gt;
* [http://www.tribalmicro.com/logic_an/ Tribalmicro], PC hosted LA (32ch, 40MHz Timing, 128kSa, ca. 1700$)&lt;br /&gt;
* [http://www.nci-usa.com/frame_products_overview.htm NCI GoLogic], Logikanalysator mit USB-Anschluß an PC (34 oder 72Ch, 500MHz Timing, 1 oder 2MSa, ca. 3000..5500$)&lt;br /&gt;
* [http://www.tek.com/products/logic_analyzers/index.html Tektronix], Verschiedene Geräte, standalone oder modular (ab 34ch, 2GHz Timing, ab 512kSa, gut und teuer)&lt;br /&gt;
* [http://www.home.agilent.com/DEger/nav/-536902443.0/pc.html Agilent], Verschiedene Geräte, standalone, modular oder PC-hosted (ab 34ch, ab 800MHz timing, ab 256kSa, gut und teuer)&lt;br /&gt;
* [http://www.sump.org/projects/analyzer/ Sumps LA], günstiges Projekt für einen LA basierend auf einem Digilent Spartan Board (32ch, 100MHz Timing, 256kSa, Kosten Digilent Board ca. 100$ + Versand/Zoll)&lt;br /&gt;
* [http://www.meilhaus.de/produkte/usb-mobile-messtechnik/?user_produkte%5BPATTR%5D=HPG_3-UPG1_3-UPG2_2&amp;amp;user_produkte%5BPR%5D=8&amp;amp;cHash=2c8edb93e2 Meilhaus Electronic - MEphisto Scope UM203] Robustes, mobiles 16 bit Kombi-Instrument 7 Mess-Geräte in einem! (ab 348€)&lt;br /&gt;
* [http://www.hacker-messtechnik.de/13722/59001.html TravelLogic TL2x36], Logikanalysator zum Anschluß an PC über USB, (36ch, 4GHz timing, 200MHz state, Speicher bis 72MBit, Preis ab ca. 500,- netto)&lt;br /&gt;
* [http://www.inovaflex.de/index.html Bus und Logic Analyzer] 100MHz Samplerate und integrierten SPI, I²C, CAN Interpreter, erweiterbar als Oszilloskop&lt;br /&gt;
* [http://www.saleae.com/logic/ logic] - Logik-Analyzer mit 8 Kanälen, mit Software zur Analyse von SPI, I2C, UART, etc... (ca 150$ + Versand/Zoll)&lt;br /&gt;
* [http://www.deditec.de/de/logikanalysatoren/prod/usb-logi-500.html DEDITEC USB-LOGI-500], kostengünstiges Einsteigermodell mit USB-Anschluß und dazugehöriger Software Logi+ (36Ch, Abtastrate 500MHz, 4096 Samples Speichertiefe/Kanal,  ca. 236 Euro)&lt;br /&gt;
&lt;br /&gt;
* Eine Übersicht über verschiedene Selbstbauprojekte: [[Logic_Analyzer]]&lt;br /&gt;
&lt;br /&gt;
* [http://www.timing-diagrams.com TimingAnalyzer] can be used to easily draw timing diagrams and perform timing analysis to find faults in digital logic systems. Written in Java, it runs on any platform that supports the Java Run-time Environment, JRE1.6.0 or Java Development Kit JDK1.6.0 or newer.&lt;br /&gt;
&lt;br /&gt;
=== Oszilloskope ===&lt;br /&gt;
&lt;br /&gt;
siehe die separate [http://www.mikrocontroller.net/articles/Oszilloskop Seite] zum Thema&lt;br /&gt;
&lt;br /&gt;
=== Generatoren ===&lt;br /&gt;
[http://www.meilhaus.de/produkte/mess-und-steuer-karten/?user_produkte%5BPR%5D=23&amp;amp;cHash=64a269a3c6 Meilhaus Electronic - ME-6x00] Waveform-Generator - potentialfrei isolierte 16 bit Analog-Ausgabe-Karte (ab EUR 1138,00)&lt;br /&gt;
&lt;br /&gt;
=== Handbücher für Messgeräte ===&lt;br /&gt;
Für ältere kommerzielle Messgeräte sind viele Handbücher im Web als PDF verfügbar. Hier eine Linkliste für den &amp;lt;u&amp;gt;kostenlosen&amp;lt;/u&amp;gt; Download:&lt;br /&gt;
* [http://www.ko4bb.com/cgi-bin/manuals.pl KO4BB Didier Juges]&lt;br /&gt;
* [http://bama.edebris.com/manuals/ BAMA-Edebris (mirror)]&lt;br /&gt;
* [http://www2.faculty.sbc.edu/kgrimm/boatanchor/index.htm BAMA Originalseite K4XL]&lt;br /&gt;
* [http://www.to-way.com/teqman.html to-way.com (K7MLR)]&lt;br /&gt;
* [ftp://ftp.bluefeathertech.com/pub/electronics/testgear/ Bluefeathertech FTP-Server]&lt;br /&gt;
* [http://www.bitsavers.org/ Bitsavers, vor allem Computermanuals und Software]&lt;br /&gt;
* [https://www.logsa.army.mil/etms/online.cfm Handbücher der US-Army (-&amp;gt;&amp;quot;i accept&amp;quot; -&amp;gt; &amp;quot;Enter the site&amp;quot; -&amp;gt; Suchbegriff z.B &amp;quot;Analyzer&amp;quot; in &amp;quot;Pub Title Text&amp;quot; eingeben -&amp;gt; search)]&lt;br /&gt;
* [http://www.eserviceinfo.com/browse.php eserviceinfo.com]&lt;br /&gt;
* [http://www.one-electron.com/FC_TestEquipment.html one-electron.com]&lt;br /&gt;
* [http://manoman.sqhill.com/ manoman]&lt;br /&gt;
* [http://www.nostalgiaair.org/ Nostalgia Air schematics, manuals, tube data]&lt;br /&gt;
* [http://pages.cthome.net/fwc/ Freds sehr alte (vor allem Militärelektronik-) Geräteliteratur, Röhrentechnik] und hier [http://pages.cthome.net/fwc/TO-DOC.HTM Übersicht zur Nummerierung der Militärhandbücher]&lt;br /&gt;
* [http://www.hpmemory.org/ressources/resrc_home.htm HP-Memory.org, alte Applications und HP-Journals]&lt;br /&gt;
* [http://www.ebaman.com/index.php/home Ebaman Registrierung per e-Mail erforderlich]&lt;br /&gt;
&lt;br /&gt;
Eine [http://www.slack.com/elec.html Linksammlung zu Messgeräten], sehr ausführlich&lt;br /&gt;
&lt;br /&gt;
== Vermischtes == &lt;br /&gt;
&lt;br /&gt;
=== Foren ===&lt;br /&gt;
* [http://forum.sparkfun.com/ Spark Fun Electronics] MicroController Ideas and Support (Englisch) ([[AVR]], [[PIC]], [[MSP]], [[ARM]], OpenOCD)&lt;br /&gt;
* [http://www.edaboard.com/ EDAboard.com] International Electronics Forum Center (Englisch)&lt;br /&gt;
* [http://stsboard.de STS Reparatur Forum] Forum für Radio und Fernsehtechniker&lt;br /&gt;
* [http://formu.iwenzo.de Elektronik Reparatur Forum] Informationselektroniker Reparatur Forum&lt;br /&gt;
* [http://www.elektrikforum.de Elektrik-Forum] Forum zum Thema Elektroinstallationen&lt;br /&gt;
* [http://www.eeweb.com/electronics-forum/ Electronics Forum] Electrical Engineering Community Forum (Englisch)&lt;br /&gt;
&lt;br /&gt;
=== Videocasts und Podcasts ===&lt;br /&gt;
&lt;br /&gt;
* [http://www.eevblog.com/ EEVblog] Electronics Engineering Video Blog von David L. Jones (englisch). &#039;&#039;Anm.: David ist Australier und das hört man. An die Sprechweise kann man sich aber gewöhnen. Und nicht erschrecken, wenn öfter mal ein drastisches Fourletterword auftaucht!&#039;&#039;&lt;br /&gt;
* [http://www.theamphour.com/ The Amp Hour] Podcast mit Chris Gammell und David Jones (englisch)&lt;br /&gt;
&lt;br /&gt;
=== Projektsammlungen ===&lt;br /&gt;
Meist in Englisch. &lt;br /&gt;
* [http://circuitscout.com/ Circuit Scout] - Online Suchmaschine&lt;br /&gt;
* [http://www.epanorama.net ePanorama.net]&lt;br /&gt;
&amp;lt;!-- offline 4/2010&lt;br /&gt;
* [http://www.commlinx.info Electronic Schematics] from CommLinx Solutions Pty Ltd&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* [http://www.discovercircuits.com Discover Circuits] a collection of 25000+ electronic circuits or schematics&lt;br /&gt;
* [http://www.next.gr/ Next] Electronic Circuit Database&lt;br /&gt;
* [http://www.beyondlogic.org/ BeyondLogic.org] Diverse Mikrocontroller und Interfacing Projekte&lt;br /&gt;
* [http://www.uoguelph.ca/~antoon/circ/circuits.htm Circuits for the Hobbyist] by VA3AVR&lt;br /&gt;
* [http://www.stefpro.de/ StefPro.de] Diverse Projekte und Datenblattsammlung nach Kategorien, Microcontroller, Digital und Analog... Sowie Tutorial &amp;quot;Grundlagen der Bestückung von Platinen&amp;quot; und anderes Wissen&lt;br /&gt;
* [http://www.schaltplaene-online.de/ www.schaltplaene-online.de] Umfangreiche Linksammlung zu Schaltplänen aller Art&lt;br /&gt;
* [http://www.halloweenmonsterlist.info/ MoNsTeRlIsT of Halloween Projects]&lt;br /&gt;
* [http://www.open-innovation-projects.org Open Innovation Projects] - Sammlung von offenen Projekten zu physischen Produkten, darunter etliche Mikrocontroller-Projekte. Man kann selber Projekte hinzufügen.&lt;br /&gt;
&lt;br /&gt;
=== Referenzen, Beschreibungen, Standards ===&lt;br /&gt;
* Extraseite: [[Datenblätter]]&lt;br /&gt;
* [http://www.technick.net Technik.Net] Pinouts, Circuits and Guides&lt;br /&gt;
* [http://pinouts.ru/ pinout.ru] und [http://www.hardwarebook.info/ hardwarebook.info] - Online handbooks of hardware pinouts, cables schemes and connectors layouts&lt;br /&gt;
* [http://www.networktechinc.com/technote.html Keyboard, Monitor &amp;amp; Mouse Pinouts] for PC, SUN, MAC, USB, FireWire, RS232, Digital Flat Panel and EVC configurations&lt;br /&gt;
* [http://www.q1.fcen.uba.ar/materias/iqi/joygus/tvgames.html Special joysticks used in TV games]&lt;br /&gt;
* [http://microsym.com/editor/assets/intelhex.pdf Intel-Hex-Format (PDF)]&lt;br /&gt;
* [http://home.teleport.com/~brainy/fat32.htm FAT32 Structure Information] - Written by Jack Dobiash&lt;br /&gt;
* [http://www.pjrc.com/tech/8051/ide/fat32.html Understanding FAT32 Filesystems] mit Beispielen (engl.)&lt;br /&gt;
* [http://www.rev-ed.co.uk/docs/picaxe_manual3.pdf Microcontroller Interfacing Circuits] - Revolution Education Ltd.&lt;br /&gt;
* [http://www.digchip.com/application-notes/ Datenbank für &#039;&#039;Application Notes&#039;&#039;] bei www.digchip.com&lt;br /&gt;
* [http://www.pavouk.org/hw/lamp/en_index.html#bigluz20w Compact Fluorescent Lamp (CFL)], Schaltungen von Energiesparlampen&lt;br /&gt;
&lt;br /&gt;
=== Online-Bücher ===&lt;br /&gt;
* [http://www.allaboutcircuits.com/ All About Circuits] - Series of online textbooks covering electricity and electronics. The information provided is great for both students and hobbyists who are looking to expand their knowledge in this field. (Englisch)&lt;br /&gt;
* http://www.computer-books.us/ - überwiegend zu höheren Programmiersprachen. Englisch.&lt;br /&gt;
* [http://www.vias.org/feee/index.html FEEE - Fundamentals of Electrical Engineering and Electronics]&lt;br /&gt;
* [http://www.nrbook.com/a/bookcpdf.php Numerical Recipes in C, Second Edition (1992)]&lt;br /&gt;
* [http://www.specamotor.de/freebook.php Electrical drives for precision engineering designs]  Prof.dr.ir. Compter&lt;br /&gt;
* [http://www.joretronik.de/Web_NT_Buch/Vorwort/Vorwort.html Das neue InterNetzteil- und Konverter-Handbuch] Dipl.-Ing. Jörg Rehrmann&lt;br /&gt;
&lt;br /&gt;
=== Bedienungsanleitungen / Manuals ===&lt;br /&gt;
* [http://bama.edebris.com/manuals/ BAMA Archiv] &lt;br /&gt;
* [http://www.big-list.com/ Big-List.com] - This is a directory of over 600 dealers in used high technology equipment. Most deal in used electronic test equipment or semiconductor production equipment. Included are dealers in related high technology items, rental companies, equipment auction sites, test equipment manual dealers, foreign (non-U.S.) used equipment dealers, cal labs, and repair services.&lt;br /&gt;
&lt;br /&gt;
=== Ungewöhnliche Basteleien (Hacks) ===&lt;br /&gt;
Auf eigene Gefahr und nicht immer ganz ernst... Meist in Englisch. &lt;br /&gt;
&lt;br /&gt;
* Metablogs (tägliche News)&lt;br /&gt;
** [http://www.makezine.com/ Makezine]&lt;br /&gt;
** [http://www.hackaday.com/ Hack a Day]&lt;br /&gt;
** [http://www.hackedgadgets.com/ HackedGadgets]&lt;br /&gt;
** [http://www.hacknmod.com/ Hack N&#039; Mod]&lt;br /&gt;
** [http://zedomax.com/blog/category/diy/ Zedomax DIY]&lt;br /&gt;
** [http://digital-diy.com Digital-DIY]&lt;br /&gt;
** [http://dangerousprototypes.com Dangerous Prototypes]&lt;br /&gt;
&lt;br /&gt;
* Foren&lt;br /&gt;
** [http://www.fingers-welt.de/home.htm Fingers elektrische Welt]&lt;br /&gt;
** [http://forum.hackedgadgets.com/ HackedGadgets Forum]&lt;br /&gt;
** [http://stsboard.de Reparatur Forum]&lt;br /&gt;
&amp;lt;!--&lt;br /&gt;
domain expired&lt;br /&gt;
** [http://camerahacking.com camerahacking Forum]&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Projektsammlungen&lt;br /&gt;
** Final Projects der Kurse [http://people.ece.cornell.edu/land/courses/ece4760/FinalProjects/ ECE4760] (Designing with Microcontrollers) und [http://people.ece.cornell.edu/land/courses/ece5760/FinalProjects/ ECE5760] (Advanced Microcontrollers) an der Cornell University &lt;br /&gt;
** [http://www.coolcircuit.com/gadgets/ Cool Circuit]&lt;br /&gt;
** [http://www.electronics-lab.com/blog/ Electronics-Lab.com Blog]&lt;br /&gt;
&lt;br /&gt;
* DIY-Anleitungen&lt;br /&gt;
** [http://www.instructables.com/ instructables]&lt;br /&gt;
** [http://www.scitoys.com/ Scitoys] You Can Make With Your Kids&lt;br /&gt;
&lt;br /&gt;
* Mix&lt;br /&gt;
** [http://www.evilmadscientist.com Evil Mad Scientist Laboratories] - u.a. The Flying Spaghetti Monster, on toast ;-)&lt;br /&gt;
** [http://home.earthlink.net/~lenyr/index.html Spark, Bang, Buzz and Other Good Stuff] ([http://www.sparkbangbuzz.com Neue Sachen])&lt;br /&gt;
** [http://www.electricstuff.co.uk/ Mike&#039;s Electric Stuff] - Antique Glass, Tesla coils and high-voltage stuff, Lasers&lt;br /&gt;
** [http://electricity.pbwiki.com/ DHS electricity]&lt;br /&gt;
** [http://www.elephantstaircase.com/wiki/index.php?title=Main_Page Elephant Staircase]&lt;br /&gt;
** [http://mycpu.eu Eine selbstgebaute CPU aus TTL-Gattern]&lt;br /&gt;
** [http://www.knollep.de/ Knolles Bauanleitungen]&lt;br /&gt;
** [http://www.ikalogic.com/index.php ikalogic.com]&lt;br /&gt;
** [http://www.electronicsinfoline.com/ Electronics Infoline]&lt;br /&gt;
** [http://www.uchobby.com/ uC Hobby]&lt;br /&gt;
** [http://elettrolinux.com elettrolinux] - Elektronik und Linux (engl.)&lt;br /&gt;
** [http://electronicfox.at.tf/ electronicfox] - Verschiedene Projekte mit [[AVR]], Fernbedienungen und deren Aufbau sowie Decoder und alten ICs aus dem Recyclinghof&lt;br /&gt;
** [http://www.techfocusmedia.net/archives/fresh-bytes/ Fresh Bytes von Techfocusmedia]&lt;br /&gt;
&lt;br /&gt;
=== Zeitschriften über Elektronik und µC ===&lt;br /&gt;
* [http://www.eue24.net/ E&amp;amp;E Faszination Elektronik] - Magazin für Elektronik-Entwickler und Elektronik-Interessierte&lt;br /&gt;
* [http://www.embedded.com embedded.com] - Hauptaugenmerk auf die Philosophie drumherum&lt;br /&gt;
* [http://www.siliconchip.com.au/ Silicon Chip] - Freie Artikel unter &#039;&#039;Free Preview&#039;&#039;&lt;br /&gt;
* [http://www.circuitcellar.com/ Circuit Cellar] - Freie Artikel unter &#039;&#039;Digital Library&#039;&#039;&lt;br /&gt;
* [http://www.elektronikpraxis.vogel.de/themen/hardwareentwicklung/mikrocontrollerprozessoren/ Elektronikpraxis - Das professionelle Elektronikmagazin]&lt;br /&gt;
* [http://www.funkamateur.de/ FUNKAMATEUR] - Elektronik, Amateurfunk, CB-Funk u. v. a. m.&lt;br /&gt;
* [http://www.edn.com/ EDN] (etwas schwer zu finden, aber lesenswert: die [http://www.edn.com/channel/Design_Ideas.php Design Ideas] und das [http://www.edn.com/archive/ Archiv der Druckausgaben])&lt;br /&gt;
* [http://www.franzis.de/elo-das-magazin ELO - Das Magazin] für Elektronik-Einsteiger&lt;br /&gt;
* [http://techonline.com/ TechOnline]&lt;br /&gt;
* [http://www.elektor.de/ Elektor] &lt;br /&gt;
* [http://www.techbriefs.com/tech-briefs/electronics-techbriefs NASA Tech Briefs] - Electronics &amp;amp; Computers&lt;br /&gt;
* [http://et.nmsu.edu/~etti/ Technology Interface Journal]&lt;br /&gt;
* [http://dev.emcelettronica.com/ Your Electronics Open Source]&lt;br /&gt;
* [http://www.element-14.com element14.com] is an information portal and community specifically built for electronic design engineers.&lt;br /&gt;
* [http://www.itwissen.info ITWissen.info] (gutes Lexikon)&lt;br /&gt;
* [http://www.nutsvolts.com Nuts&#039;n&#039;Volts] Amerikanisches Elektronikmagazin mit Online Blog&lt;br /&gt;
* [http://de.rs-online.com/web/generalDisplay.html?id=eTech eTech] von RS Online&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Temperatursensor&amp;diff=62035</id>
		<title>Temperatursensor</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Temperatursensor&amp;diff=62035"/>
		<updated>2011-11-28T19:12:10Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* ADT7310 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Will man mit einem [[Mikrocontroller]] Temperaturen messen, dann braucht man&lt;br /&gt;
* einen [[Sensor]], der die Temperatur z.&amp;amp;nbsp;B. in eine Spannung oder einen Strom umsetzt&lt;br /&gt;
* einen [[ADC | AD-Wandler]], der das Signal digitalisiert. Der kann auf dem Sensor oder dem Mikrocontroller integriert sein.&lt;br /&gt;
&lt;br /&gt;
Temperatursensoren gibt es nun in allen möglichen Varianten. Vom temperaturabhängigen [[Widerstand]] bis zum fertig abgeglichenen All-in-one-Bauteil mit digitalem Ausgang. Wie bei allen Sensoren sollte man auch hier genau hinschauen und [[Auflösung und Genauigkeit]] unterscheiden.&lt;br /&gt;
&lt;br /&gt;
== Analoge Temperatursensoren ==&lt;br /&gt;
&lt;br /&gt;
=== PT100 ===&lt;br /&gt;
&lt;br /&gt;
Unter einem PT100 versteht man einen Platinwiderstand, der bei 0°C einen Widerstand von 100Ω hat.&lt;br /&gt;
Platinwiderstände sind temperaturabhängige Widerstände mit hoher Wiederholgenauigkeit und Konstanz[http://de.wikipedia.org/wiki/Konstante].  Wegen der relativ geringen Widerstandsänderung von nur ca. 0,4Ω pro Grad ist etwas mehr Schaltungsaufwand erforderlich als bei anderen Sensoren. Genauere Formeln zur Temperaturbestimmung gibt es u.a. bei der [http://de.wikipedia.org/wiki/Pt100 Wikipedia]. Ein Schaltplan findet sich bei der [http://www.heise.de/ct/artikel/Sensibelchen-289608.html c&#039;t].&lt;br /&gt;
&lt;br /&gt;
Die Sensoren gibt es auch mit anderen Widerstandswerten, z.&amp;amp;nbsp;B. mit 1000&amp;amp;Omega; und heißen dann entsprechend PT1000.&lt;br /&gt;
&lt;br /&gt;
Vorteil:&lt;br /&gt;
* genormt&lt;br /&gt;
* großer Meßbereich&lt;br /&gt;
* hohe Linearität&lt;br /&gt;
* hohe Wiederholgenauigkeit&lt;br /&gt;
* einfach austauschbar&lt;br /&gt;
&lt;br /&gt;
Nachteil:&lt;br /&gt;
* relativ teuer (bei segor.de ab 3,80&amp;amp;euro;)&lt;br /&gt;
* brauchen aufwendigere Auswerteschaltung&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://www.heise.de/ct/04/22/236/ c&#039;t-Artikel: Mikrocontroller-Programmierung: Timer, Sensoren und Drehgeber (mit PT100 Schaltung)]&lt;br /&gt;
* [http://pdfserv.maxim-ic.com/en/an/AN3450.pdf Maxim AN3450 Positive Analog Feedback Compensates PT100 Transducer]&lt;br /&gt;
&lt;br /&gt;
=== NTC/PTC ===&lt;br /&gt;
&lt;br /&gt;
NTC und PTC sind temperaturabhängige Widerstände.&lt;br /&gt;
&lt;br /&gt;
* NTC (engl. &#039;&#039;&#039;N&#039;&#039;&#039;egative &#039;&#039;&#039;T&#039;&#039;&#039;emperature &#039;&#039;&#039;C&#039;&#039;&#039;oefficient, Heißleiter), hat bei hohen Temperaturen seinen niedrigsten Widerstand, z.&amp;amp;nbsp;B. Silizium&lt;br /&gt;
* PTC (engl. &#039;&#039;&#039;P&#039;&#039;&#039;ositive &#039;&#039;&#039;T&#039;&#039;&#039;emperature &#039;&#039;&#039;C&#039;&#039;&#039;oefficient, Kaltleiter), hat bei niedrigen Temperaturen seinen geringsten Widerstand, z.&amp;amp;nbsp;B. Glühlampe&lt;br /&gt;
&lt;br /&gt;
Um den Widerstandswert zu messen schaltet man sie mit einem normalen Widerstand oder einer [[Konstantstromquelle]] in Reihe zu einem [[Spannungsteiler]] und misst den Spannungsabfall. Eine Beispielschaltung findet sich [http://www.mathar.com/msp_thermo1.html hier].&lt;br /&gt;
&lt;br /&gt;
Vorteil:&lt;br /&gt;
* billig (z.B. [http://www.reichelt.de/?ARTICLE=9594 KTY81-110] bei Reichelt  ~0,60&amp;amp;euro;)&lt;br /&gt;
&lt;br /&gt;
Nachteil:&lt;br /&gt;
* müssen für höhere Genauigkeiten abgeglichen werden&lt;br /&gt;
* brauchen A/D-Wandler&lt;br /&gt;
* sind nichtlinear&lt;br /&gt;
&lt;br /&gt;
Beispiele:&lt;br /&gt;
* KTY10-5&lt;br /&gt;
* KTY13-6&lt;br /&gt;
* KTY81-121&lt;br /&gt;
* KTY81-122&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://www.sprut.de/electronic/temeratur/temp.htm Temperaturabhängige Stromquelle und NTC/PTC inclusive Linearisierung]&lt;br /&gt;
*[http://www.umnicom.de/Elektronik/Mikrokontroller/Atmel/AtFan/AtFan.html#2.2.2 Berechnung des Linearisierungswiderstandes für gewünschten Temperaturbereich] der fällt sonst immer vom Himmel&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/208587#2065880 KTY 10-5 Formelprobleme]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/225563 Codesammlung: Beispiel mit 0,5°C Auflösung]&lt;br /&gt;
&lt;br /&gt;
=== LMx35 ===&lt;br /&gt;
&lt;br /&gt;
Eine IC-Familie, die pro Kelvin Temperaturänderung ihre Ausgangsspannung um 10&amp;amp;nbsp;mV ändert. Die ICs gibt es in verschiedenen Genauigkeiten und Temperaturbereichen mit den Bezeichnungen LM135(A), LM235(A) und LM335(A). Der günstigste ist der LM335 mit einem Temperaturbereich von −40 … +100°C.&lt;br /&gt;
In verschiedenen Bauformen erhältlich. Beispielschaltungen finden sich im [http://www.national.com/ds.cgi/LM/LM135.pdf Datenblatt] und [http://www.suessbrich.info/elek/elektherm1.html hier]&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* hat auch ohne Kalibrierung eine Genauigkeit von einem Grad (bei 25°C)&lt;br /&gt;
* relativ billig (LM335 bei Reichelt ab 0,50&amp;amp;nbsp;€)&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* benötigt A/D-Wandler&lt;br /&gt;
* bei längerer Anschlussleitung störanfällig&lt;br /&gt;
&lt;br /&gt;
=== LM334 ===&lt;br /&gt;
&lt;br /&gt;
Ein IC ähnlich dem LM335 mit dem Unterschied, dass der durch das IC fließende Strom proportional von der Temperatur abhängt. Mit einer einfachen Schaltung aus nur zwei Widerständen kann man dann den Strom in einer Weise wandeln, dass pro Kelvin eine Spannungsänderung von 10mV ausgegeben wird. Da die Strom-Spannungswandlung auf der Platine (und damit nahe am AD-Wandler) stattfindet und die Übertragung des Messwerts durch einen Strom stattfindet, sind Störungen durch Netzbrumm etc. viel geringer als beim LM335&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
&amp;lt;!-- * hat auch ohne Kalibrierung eine Genauigkeit von einem Grad (bei 25°C) &lt;br /&gt;
Laut Datenblatt +-3°C&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* relativ billig ([http://www.reichelt.de/?ARTICLE=10468 Reichelt 0,54 &amp;amp;euro;])&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* benötigt A/D-Wandler&lt;br /&gt;
* Bereich 0°C-70°C&lt;br /&gt;
&lt;br /&gt;
Ähnliche ICs:&lt;br /&gt;
* AD592 (Ausgangsstrom 1µA pro Kelvin, absolute Temperatur) [http://www.reichelt.de/?ARTICLE=3825 Reichelt: 3,75 €], Conrad 174912 8,50 &amp;amp;euro;&lt;br /&gt;
&lt;br /&gt;
=== SMT160-30 ===&lt;br /&gt;
&lt;br /&gt;
Ist ein Zwischending zwischen Digital und Analog. Sein Ausgangssignal ist ein digitales PWM-Signal, zu dessen Messung man am besten den Input-Capture-Eingang eines Mikrocontrollers verwendet. Man kann ihn also wie einen analogen Sensor nur indirekt auslesen, anstatt über einen AD-Wandler hier über einen Timer.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* Digitales PWM-Signal ist unempfindlich gegen Störeinflüsse&lt;br /&gt;
* gibt es in SO8, TO18, TO92 und &amp;lt;b&amp;gt;TO220&amp;lt;/b&amp;gt;, gut befestigbar, z.B am Kühlkörper&lt;br /&gt;
* linear&lt;br /&gt;
* kein Abgleich nötig&lt;br /&gt;
&lt;br /&gt;
Nachteile (viele):&lt;br /&gt;
* benötigt Timer&lt;br /&gt;
* jittert extrem, genaue Messungen nur über Mittelung / Filterung möglich&lt;br /&gt;
* nicht nur das PWM-Verhältnis, sondern auf die Frequenz ist temp-abhängig (1-4kHz)&lt;br /&gt;
* teuer (Farnell 10,90&amp;amp;euro; +16%, Conrad 9,xx&amp;amp;euro; , www.hy-line.de ??).&lt;br /&gt;
* TO92 Gehäuse ist günstiger, dafür weniger genau&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* http://www.hy-line.de/co/sensor-tec/hersteller/smartec/smt-160-30/index.html&lt;br /&gt;
&lt;br /&gt;
=== Thermoelement ===&lt;br /&gt;
&lt;br /&gt;
Ein Thermoelement besteht im einfachsten Fall aus zwei ungleichen Metallendrähten, die an einem Punkt miteinander verbunden sind und bei dem die Verbindungsstelle einer anderen Temperatur ausgesetzt ist als die offenen Enden der Drähte. An den offenen Enden der Drähten entsteht eine Spannung (Thermospannung). Dieser Effekt wurde 1821 von Thomas Seebeck entdeckt ([http://de.wikipedia.org/wiki/Seebeck-Effekt Seebeck-Effekt] bei Wikipedia). Eine weitere Anwendung ist der thermoelektrische Generator (&amp;quot;Thermogenerator&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Vorteil:&lt;br /&gt;
* über einen sehr weiten Temperaturbereich einsetzbar&lt;br /&gt;
&lt;br /&gt;
Nachteil:&lt;br /&gt;
* die sehr geringen Temperaturspannungen im Mikrovoltbereich benötigen eine sehr gute Auswertelektronik (guter Analogteil + AD-Wandler).&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://digital.ni.com/worldwide/germany.nsf/web/all/7A4F02BAEFEC22AC802567F6003E0D6E  Temperaturmessung mit Thermoelementen] - Eine Einführung von David Potter (deutsche Überarbeitung: G.Sinkovic) (inkl. Erläuterung der Kaltstellenkompensation)&lt;br /&gt;
* [http://www.sensorwell.at/fileadmin/templates/images/data_sheets/temperatur_messtechnik.pdf Warum Thermoelemente Relativtemperaturen messen! oder Was ist eine Kaltstelle?] - Technische Information von www.sensorwell.at (PDF, ca. 600kB)&lt;br /&gt;
&lt;br /&gt;
== Digitale Temperatursensoren ==&lt;br /&gt;
&lt;br /&gt;
=== DS1621 ===&lt;br /&gt;
&lt;br /&gt;
Der DS1621 ist Temperatursensor und A/D-Wandler in einem. Er gibt seine Daten per [[I²C]]-[[Bus]] aus. Ein Schaltplan für einen elektronischen Thermometer mit diesem IC findet sich [http://www.myplace.nu/avr/thermo/ hier].&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* bereits kalibriert&lt;br /&gt;
* kein A/D-Wandler nötig&lt;br /&gt;
* da I²C ein Bus ist, kann man mehrere DS1621 und andere I²C-Bausteine zusammen anschließen und braucht dafür trotzdem nur zwei I/O-Ports.&lt;br /&gt;
* Messbereich -55°C to +125°C &lt;br /&gt;
* Genauigkeit +-0,5°C&lt;br /&gt;
* Auflösung besser 0,01°C, wenn man die beiden Zählerregister (Count-Remain und Count-per-C) auswertet&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* teuer (Segor 5,80&amp;amp;euro;; RS 3,95&amp;amp;euro;; Conrad 5,22&amp;amp;euro;)&lt;br /&gt;
* obwohl die meisten Register [[Speicher#NVRAM | nichtflüchtig]] sind, kann man ihn nicht als Stand-Alone-Thermostat einsetzen, da er erst nach einem Start-Conversion-Befehl zu messen beginnt.&lt;br /&gt;
&lt;br /&gt;
Nachfolger:&lt;br /&gt;
* DS1631, DS1631A (Auto-Start-&amp;gt; Stand-Alone-Thermostat), DS1731&lt;br /&gt;
* weitere Stand-Alone-Thermostaten: DS1821, DS1629&lt;br /&gt;
&lt;br /&gt;
=== LM75 ===&lt;br /&gt;
&lt;br /&gt;
Der LM75 ist so ähnlich wie der DS1621, allerdings nur in SMD erhältlich und nicht so genau. Er ist aber öfters mal auf PC-Mainboards zu finden, so dass man beim Schlachten eines solchen günstig an einen Temperatursensor kommen kann. Eine Beispiel Schaltplan mit einem ATmega8 findet man [http://www.ucblog.de/2010/09/mikrocontroller-thermometer-schaltplan/ hier]&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* bereits kalibriert&lt;br /&gt;
* kein A/D-Wandler nötig&lt;br /&gt;
* I²C-Bus Ausgang&lt;br /&gt;
* billiger als DS1621 (Reichelt 1,45 &amp;amp;euro;; RS 3V: 3,75&amp;amp;euro;; 5V: 2,72&amp;amp;euro;)&lt;br /&gt;
* Auflösung +-0,5°C&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* nur im SMD-Gehäuse erhältlich&lt;br /&gt;
* relativ ungenau (+-2°C), kann man jedoch kalibrieren / kompensieren&lt;br /&gt;
&lt;br /&gt;
Kompatible Typen:&lt;br /&gt;
* AD7415ART&lt;br /&gt;
* DS7505S+&lt;br /&gt;
&lt;br /&gt;
=== LM76 ===&lt;br /&gt;
&lt;br /&gt;
Der LM76 ähnlich dem LM75, bietet aber eine 8-fach höhere Auflösung und eine Genauigkeit von 0.5 bzw. 1°C.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* höhere Auflösung&lt;br /&gt;
* höhere Genauigkeit&lt;br /&gt;
&lt;br /&gt;
Nachteil:&lt;br /&gt;
* schwerer zu beschaffen&lt;br /&gt;
&lt;br /&gt;
=== TMP175 / TMP75 ===&lt;br /&gt;
&lt;br /&gt;
Ähnelt dem LM75 stark! Temperatursensor von Texas Instruments.&lt;br /&gt;
&lt;br /&gt;
=== DS18S20 / DS18B20 ===&lt;br /&gt;
&lt;br /&gt;
Der DS18S20 (Nachfolger des DS1820) und DS18B20 sind scheinbar Temperatursensoren und A/D-Wandler in einem. Wenn man genauer hinschaut, stellt man fest, dass es sich um direktwandelnde Sensoren handelt. Die Temperatur wird ohne Umweg über eine analoge Zwischengröße (Spannung oder Strom) in ein digitales Signal überführt.&lt;br /&gt;
&lt;br /&gt;
Die Datenkommunikation erfolgt über ein 1-Wire-Interface, wodurch man am [[Mikrocontroller]] mit nur einem einzigen I/O-Pin auskommen kann. Außerdem beherrschen sie die parasitäre Stromversorgung, d.h., man braucht für Daten und Stromversorgung zusammen nur zwei Leitungen.&lt;br /&gt;
&lt;br /&gt;
Beim DS18B20 sind Auflösungen von 9, 10, 11 und 12 Bits konfigurierbar. Je kleiner die Auflösung, desto kürzer ist die Messzeit. Der DS18S20 hat eine feste Auflösung von 12 Bits, wobei die unteren 3 Bits aufwändiger auszuwerten sind als beim DS18B20. Der DS18S20 ist als Ersatz für den DS1820 gedacht. Der Hersteller empfiehlt den DS18B20 für Neuentwicklungen.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* bereits kalibriert&lt;br /&gt;
* Genauigkeit +-0,5°C&lt;br /&gt;
* 1-Wire-Ausgang&lt;br /&gt;
&lt;br /&gt;
Nachteil:&lt;br /&gt;
* relativ teuer: Reichelt: 2,50&amp;amp;euro; / CSD: 1,85&amp;amp;euro; / Conrad 5,08&amp;amp;euro;&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://pdfserv.maxim-ic.com/en/ds/DS18S20.pdf Datenblatt DS18S20] &lt;br /&gt;
* [http://pdfserv.maxim-ic.com/en/ds/DS18B20.pdf Datenblatt DS18B20]&lt;br /&gt;
* [http://www.maxim-ic.com/app-notes/index.mvp/id/4377 Vergleich DS18B20 &amp;lt;-&amp;gt; DS18S20]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/6505 Code zur Ansteuerung (ASM ATTiny12)]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/14792 Code zur Ansteuerung (AVR-GCC)]&lt;br /&gt;
* [http://gandalf.arubi.uni-kl.de/avr_projects/tempsensor/ Code zur Ansteuerung mit CRC-Prüfung (AVR-GCC)]&lt;br /&gt;
* [http://chaokhun.kmitl.ac.th/~kswichit/avrthermo/avrthermo.html LED-Thermometer mit AT90S2313 (C)]&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-4-248219.html Webserver zur Ansteuerung von bis zu 63 Bausteinen]&lt;br /&gt;
* [http://www.teslabs.com/openplayer/docs/docs/other/ds18b20_pre1.pdf PDF Anleitung zur Beschaltung und Programmierung (C)]&lt;br /&gt;
*[http://www.digitemp.com/building.shtml Anleitung Sensorfühleraufbau (DigiTemp)]&lt;br /&gt;
* http://www.mikrocontroller.net/topic/14792 &lt;br /&gt;
* http://www.mikrocontroller.net/topic/232156 (Timing der parasitären Versorgung)&lt;br /&gt;
&lt;br /&gt;
=== DS1822 ===&lt;br /&gt;
&lt;br /&gt;
Ähnlich wie DS18S20, aber weniger genau (+-2°) und in großen Stückzahlen billiger. Wegen der geringeren Verbreitung kommt der Preisvorteil aber bei Einzelstücken nicht beim Kunden an. So kostet er bei Reichelt mit 3,50&amp;amp;euro; mehr als der DS18S20.&lt;br /&gt;
&lt;br /&gt;
=== DS1921 / DS1922 ===&lt;br /&gt;
&lt;br /&gt;
Sind wie die DS1821 1-wire-Sensoren mit zusätzlicher Logging-Funktion.&lt;br /&gt;
Im iButton-Gehäuse befindet sich eine Lithium-Zelle, eine RTC, CMOS-RAM und der Temp-Sensor. Nach umfangreicher Progammierung startet der Button seine Mission (Aufzeichnung des Temperaturverlaufs).&lt;br /&gt;
Gibt es auch mit zusätzlicher Feuchtemessung (DS1923).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== TSic ===&lt;br /&gt;
&lt;br /&gt;
Die TSic Sensoren werden baugleich von 3 Herstellern angeboten:&lt;br /&gt;
* ZMD ([http://www.zmd.biz/temp.php?group=temp&amp;amp;content=products Homepage]) ([http://tarr.uspto.gov/servlet/tarr?regser=serial&amp;amp;entry=78673282 Trademark])&lt;br /&gt;
* IST AG ([http://www.ist-ag.com/eh/ist-ag/de/home.nsf/contentview/8F5D32432CAC53C2C1257405003C2433 Homepage])&lt;br /&gt;
* Hygrosens ([http://www.hygrosens.de/english/shop/list.html?tx_ttproducts_pi1%5Bcat%5D=11&amp;amp;cHash=dcd89b823b Homepage])&lt;br /&gt;
&lt;br /&gt;
Die TSic Sensoren ([http://www.zmd.biz/pdf/ZMD%20TSic%20Data%20Sheet%20V3%207.pdf Datenblatt]) geben ihre Temperaturmessdaten automatisch in einem festen Intervall aus. Daher muss der Host nur warten bis die nächsten Messdaten rausgeschickt werden. Die TSic Sensoren die es im freien Handel gibt, geben ihre Messdaten alle 100ms (10Hz) aus. &lt;br /&gt;
Zur Übertragung wird das [http://www.zmd.biz/pdf/IST_TSic_ZACwire_V2.3%20Digital%20Output_17-Oct-06.pdf ZACwire] Protokoll benutzt. Es handelt sich um eine einfach zwei Byte Übertragung per Manchester-Code. Diese zwei Byte repräsentieren den digital gewandelten Temperaturwert. Im Gegensatz zu Sensoren wie den DS18xxx von Dallas muss dieser Wert aber erst auf einen dezimalen Wert umgerechnet werden. &lt;br /&gt;
Die Sensoren kommen mit 3 Pins aus (VCC, GND, Dout).&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* Bereits kalibriert&lt;br /&gt;
* Verschiedene Genauigkeiten lieferbar&lt;br /&gt;
* Sehr einfaches Kommunikationsprotokoll&lt;br /&gt;
* Geringer Stromverbrauch&lt;br /&gt;
* Hochgenau: bis zu +/- 0.1°C (TSic 50x)&lt;br /&gt;
&lt;br /&gt;
Nachteil:&lt;br /&gt;
* Recht teuer (Reichelt: 4,70&amp;amp;euro; für den TSic206)&lt;br /&gt;
* Nur ein Sensor an einem I/O nutzbar (Kein Bussystem)&lt;br /&gt;
&lt;br /&gt;
Achtung! &lt;br /&gt;
Die TSic Sensoren gibt es auch als Version mit analog Ausgang. Bei der Typenbezeichnung gibt die 3. Stelle an ob es sich um die analog- oder Digitalversion handelt (1 = analog, 6 = digital). &lt;br /&gt;
Der TSic201 ist also analog, wärend der TSic206 ein digitaler ist.&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/45573#347765 Ansatz zum Empfang der Daten]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/225554# Beispiel mit Strobe ohne Interrupt]&lt;br /&gt;
* [http://ethersex.de/index.php/Zacwire Fertige Ansteuerung durch AVR in Ethersex]&lt;br /&gt;
* [http://www.zmd.biz/temp.php?group=temp&amp;amp;content=products Herstellerseite mit Datenblättern und FAQ]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/82087 Diskussion mit Beispielcode (MSP430, AVR, PIC) blockierend]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/144424#1367539 C++ Interrupt]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/88847 noch mehr C, problematisch Interrupt]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/151791#1426974 C für ATmega8]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/159149#1510455 auch problematisch]&lt;br /&gt;
* [http://www.sinc.sunysb.edu/Stu/maman/ESE_381.htm Projekt mit tsic sensor, evtl. code]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/188462#1837622 fertiger Code zum Einlesen des Zacwire-Protokolls für PIC in ASM]&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=55103 RN: Bascom]&lt;br /&gt;
* [http://www.mikrocontroller.net/search?query=tsic* Suche in den Foren]&lt;br /&gt;
* [http://www.avr-projekte.de/tinyclock.htm TSIC206 Thermometer mit Uhr und Kalender. Komplette Bauanleitung mit ASM Quellcode für AT-Tiny2313]&lt;br /&gt;
&lt;br /&gt;
=== SHT1x/SHT7x ===&lt;br /&gt;
&lt;br /&gt;
Der SHT1x/SHT7x (SHT10, SHT11, SHT15, STH71, SHT75) sind kombinierte Temperatur- und Feuchtesensoren von [http://www.sensirion.com Sensirion]. Sie unterscheiden sich in Bauform und Genauigkeit.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* digitale Schnittstelle mit einfacher [[I²C]]-&#039;&#039;ähnlicher&#039;&#039; Ansteuerung&lt;br /&gt;
* keine Kalibrierung notwendig&lt;br /&gt;
* Beispielcode (C, MC51) auf der Sensirion-Seite verfügbar (relativ leicht portierbar)&lt;br /&gt;
* interne Heizelemente (Funktionsprüfung, &amp;quot;rauhe&amp;quot; Umgebung)&lt;br /&gt;
* Spannungsmonitor (&amp;quot;Battery fail&amp;quot;)&lt;br /&gt;
* sehr hohe Genauigkeit&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* kann nicht am [[I²C]] Bus betrieben werden, theoretisch gleiche Clockleitung möglich, fixe Adresse&lt;br /&gt;
* relativ teuer (Farnell 18,60&amp;amp;euro;)(SHT11 bei CSD 14€)&lt;br /&gt;
&lt;br /&gt;
[http://www.sensirion.com/en/01_humidity_sensors/00_humidity_sensors.htm Übersicht] der Temperatur- /Feutchtigkeitssensoren von Sensirion.&lt;br /&gt;
&lt;br /&gt;
=== SHT21 ===&lt;br /&gt;
&lt;br /&gt;
[http://www.sensirion.com Sensirion] bietet auch den SHT21 Feuchtigkeits- und Temperatursensor an, welcher wesentlich genauer ist.&lt;br /&gt;
    &lt;br /&gt;
Vorteile:&lt;br /&gt;
* I2C digital, PWM and SDM/analog Volt Ausgabe&lt;br /&gt;
* Maximal 5 Messungen/s @ 14bit&lt;br /&gt;
* Temperaturbereich von -40 – +125°C&lt;br /&gt;
* Feuchtigkeit mit einer Genauigkeit von +-3%RH&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
*  teuer (Farnell 23 €, Segor 29 €)&lt;br /&gt;
* nur als SMD-Package&lt;br /&gt;
&lt;br /&gt;
Application Notes und Datenblätter findet man [http://www.sensirion.com/en/01_humidity_sensors/10_Overview.htm hier].&lt;br /&gt;
&lt;br /&gt;
=== ADT7310 ===&lt;br /&gt;
&lt;br /&gt;
Der ADT7310 von [http://www.analog.com/en/sensors/digital-temperature-sensors/adt7310/products/product.html Analog Devices] besitzt eine Auflösung von 16 Bit und eine Genauigkeit von ±0.5°C im Bereich von −40°C bis +105°C.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* Ansteuerung per [[SPI]] (für [[I2C]] siehe [http://www.analog.com/en/sensors/digital-temperature-sensors/adt7410/products/product.html ADT7410])&lt;br /&gt;
* keine Kalibrierung notwendig&lt;br /&gt;
* hohe [[Auflösung und Genauigkeit]]&lt;br /&gt;
* programmierbarer [[Interrupt]]ausgang für Unter- und Übertemperatur&lt;br /&gt;
* relativ günstig (ca. 3€ bei Digi-Key, Stand 12/2011)&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* TBD&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Sensorik]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Temperatursensor&amp;diff=62034</id>
		<title>Temperatursensor</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Temperatursensor&amp;diff=62034"/>
		<updated>2011-11-28T19:07:16Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* Thermoelement */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Will man mit einem [[Mikrocontroller]] Temperaturen messen, dann braucht man&lt;br /&gt;
* einen [[Sensor]], der die Temperatur z.&amp;amp;nbsp;B. in eine Spannung oder einen Strom umsetzt&lt;br /&gt;
* einen [[ADC | AD-Wandler]], der das Signal digitalisiert. Der kann auf dem Sensor oder dem Mikrocontroller integriert sein.&lt;br /&gt;
&lt;br /&gt;
Temperatursensoren gibt es nun in allen möglichen Varianten. Vom temperaturabhängigen [[Widerstand]] bis zum fertig abgeglichenen All-in-one-Bauteil mit digitalem Ausgang. Wie bei allen Sensoren sollte man auch hier genau hinschauen und [[Auflösung und Genauigkeit]] unterscheiden.&lt;br /&gt;
&lt;br /&gt;
== Analoge Temperatursensoren ==&lt;br /&gt;
&lt;br /&gt;
=== PT100 ===&lt;br /&gt;
&lt;br /&gt;
Unter einem PT100 versteht man einen Platinwiderstand, der bei 0°C einen Widerstand von 100Ω hat.&lt;br /&gt;
Platinwiderstände sind temperaturabhängige Widerstände mit hoher Wiederholgenauigkeit und Konstanz[http://de.wikipedia.org/wiki/Konstante].  Wegen der relativ geringen Widerstandsänderung von nur ca. 0,4Ω pro Grad ist etwas mehr Schaltungsaufwand erforderlich als bei anderen Sensoren. Genauere Formeln zur Temperaturbestimmung gibt es u.a. bei der [http://de.wikipedia.org/wiki/Pt100 Wikipedia]. Ein Schaltplan findet sich bei der [http://www.heise.de/ct/artikel/Sensibelchen-289608.html c&#039;t].&lt;br /&gt;
&lt;br /&gt;
Die Sensoren gibt es auch mit anderen Widerstandswerten, z.&amp;amp;nbsp;B. mit 1000&amp;amp;Omega; und heißen dann entsprechend PT1000.&lt;br /&gt;
&lt;br /&gt;
Vorteil:&lt;br /&gt;
* genormt&lt;br /&gt;
* großer Meßbereich&lt;br /&gt;
* hohe Linearität&lt;br /&gt;
* hohe Wiederholgenauigkeit&lt;br /&gt;
* einfach austauschbar&lt;br /&gt;
&lt;br /&gt;
Nachteil:&lt;br /&gt;
* relativ teuer (bei segor.de ab 3,80&amp;amp;euro;)&lt;br /&gt;
* brauchen aufwendigere Auswerteschaltung&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://www.heise.de/ct/04/22/236/ c&#039;t-Artikel: Mikrocontroller-Programmierung: Timer, Sensoren und Drehgeber (mit PT100 Schaltung)]&lt;br /&gt;
* [http://pdfserv.maxim-ic.com/en/an/AN3450.pdf Maxim AN3450 Positive Analog Feedback Compensates PT100 Transducer]&lt;br /&gt;
&lt;br /&gt;
=== NTC/PTC ===&lt;br /&gt;
&lt;br /&gt;
NTC und PTC sind temperaturabhängige Widerstände.&lt;br /&gt;
&lt;br /&gt;
* NTC (engl. &#039;&#039;&#039;N&#039;&#039;&#039;egative &#039;&#039;&#039;T&#039;&#039;&#039;emperature &#039;&#039;&#039;C&#039;&#039;&#039;oefficient, Heißleiter), hat bei hohen Temperaturen seinen niedrigsten Widerstand, z.&amp;amp;nbsp;B. Silizium&lt;br /&gt;
* PTC (engl. &#039;&#039;&#039;P&#039;&#039;&#039;ositive &#039;&#039;&#039;T&#039;&#039;&#039;emperature &#039;&#039;&#039;C&#039;&#039;&#039;oefficient, Kaltleiter), hat bei niedrigen Temperaturen seinen geringsten Widerstand, z.&amp;amp;nbsp;B. Glühlampe&lt;br /&gt;
&lt;br /&gt;
Um den Widerstandswert zu messen schaltet man sie mit einem normalen Widerstand oder einer [[Konstantstromquelle]] in Reihe zu einem [[Spannungsteiler]] und misst den Spannungsabfall. Eine Beispielschaltung findet sich [http://www.mathar.com/msp_thermo1.html hier].&lt;br /&gt;
&lt;br /&gt;
Vorteil:&lt;br /&gt;
* billig (z.B. [http://www.reichelt.de/?ARTICLE=9594 KTY81-110] bei Reichelt  ~0,60&amp;amp;euro;)&lt;br /&gt;
&lt;br /&gt;
Nachteil:&lt;br /&gt;
* müssen für höhere Genauigkeiten abgeglichen werden&lt;br /&gt;
* brauchen A/D-Wandler&lt;br /&gt;
* sind nichtlinear&lt;br /&gt;
&lt;br /&gt;
Beispiele:&lt;br /&gt;
* KTY10-5&lt;br /&gt;
* KTY13-6&lt;br /&gt;
* KTY81-121&lt;br /&gt;
* KTY81-122&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://www.sprut.de/electronic/temeratur/temp.htm Temperaturabhängige Stromquelle und NTC/PTC inclusive Linearisierung]&lt;br /&gt;
*[http://www.umnicom.de/Elektronik/Mikrokontroller/Atmel/AtFan/AtFan.html#2.2.2 Berechnung des Linearisierungswiderstandes für gewünschten Temperaturbereich] der fällt sonst immer vom Himmel&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/208587#2065880 KTY 10-5 Formelprobleme]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/225563 Codesammlung: Beispiel mit 0,5°C Auflösung]&lt;br /&gt;
&lt;br /&gt;
=== LMx35 ===&lt;br /&gt;
&lt;br /&gt;
Eine IC-Familie, die pro Kelvin Temperaturänderung ihre Ausgangsspannung um 10&amp;amp;nbsp;mV ändert. Die ICs gibt es in verschiedenen Genauigkeiten und Temperaturbereichen mit den Bezeichnungen LM135(A), LM235(A) und LM335(A). Der günstigste ist der LM335 mit einem Temperaturbereich von −40 … +100°C.&lt;br /&gt;
In verschiedenen Bauformen erhältlich. Beispielschaltungen finden sich im [http://www.national.com/ds.cgi/LM/LM135.pdf Datenblatt] und [http://www.suessbrich.info/elek/elektherm1.html hier]&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* hat auch ohne Kalibrierung eine Genauigkeit von einem Grad (bei 25°C)&lt;br /&gt;
* relativ billig (LM335 bei Reichelt ab 0,50&amp;amp;nbsp;€)&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* benötigt A/D-Wandler&lt;br /&gt;
* bei längerer Anschlussleitung störanfällig&lt;br /&gt;
&lt;br /&gt;
=== LM334 ===&lt;br /&gt;
&lt;br /&gt;
Ein IC ähnlich dem LM335 mit dem Unterschied, dass der durch das IC fließende Strom proportional von der Temperatur abhängt. Mit einer einfachen Schaltung aus nur zwei Widerständen kann man dann den Strom in einer Weise wandeln, dass pro Kelvin eine Spannungsänderung von 10mV ausgegeben wird. Da die Strom-Spannungswandlung auf der Platine (und damit nahe am AD-Wandler) stattfindet und die Übertragung des Messwerts durch einen Strom stattfindet, sind Störungen durch Netzbrumm etc. viel geringer als beim LM335&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
&amp;lt;!-- * hat auch ohne Kalibrierung eine Genauigkeit von einem Grad (bei 25°C) &lt;br /&gt;
Laut Datenblatt +-3°C&lt;br /&gt;
--&amp;gt;&lt;br /&gt;
* relativ billig ([http://www.reichelt.de/?ARTICLE=10468 Reichelt 0,54 &amp;amp;euro;])&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* benötigt A/D-Wandler&lt;br /&gt;
* Bereich 0°C-70°C&lt;br /&gt;
&lt;br /&gt;
Ähnliche ICs:&lt;br /&gt;
* AD592 (Ausgangsstrom 1µA pro Kelvin, absolute Temperatur) [http://www.reichelt.de/?ARTICLE=3825 Reichelt: 3,75 €], Conrad 174912 8,50 &amp;amp;euro;&lt;br /&gt;
&lt;br /&gt;
=== SMT160-30 ===&lt;br /&gt;
&lt;br /&gt;
Ist ein Zwischending zwischen Digital und Analog. Sein Ausgangssignal ist ein digitales PWM-Signal, zu dessen Messung man am besten den Input-Capture-Eingang eines Mikrocontrollers verwendet. Man kann ihn also wie einen analogen Sensor nur indirekt auslesen, anstatt über einen AD-Wandler hier über einen Timer.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* Digitales PWM-Signal ist unempfindlich gegen Störeinflüsse&lt;br /&gt;
* gibt es in SO8, TO18, TO92 und &amp;lt;b&amp;gt;TO220&amp;lt;/b&amp;gt;, gut befestigbar, z.B am Kühlkörper&lt;br /&gt;
* linear&lt;br /&gt;
* kein Abgleich nötig&lt;br /&gt;
&lt;br /&gt;
Nachteile (viele):&lt;br /&gt;
* benötigt Timer&lt;br /&gt;
* jittert extrem, genaue Messungen nur über Mittelung / Filterung möglich&lt;br /&gt;
* nicht nur das PWM-Verhältnis, sondern auf die Frequenz ist temp-abhängig (1-4kHz)&lt;br /&gt;
* teuer (Farnell 10,90&amp;amp;euro; +16%, Conrad 9,xx&amp;amp;euro; , www.hy-line.de ??).&lt;br /&gt;
* TO92 Gehäuse ist günstiger, dafür weniger genau&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* http://www.hy-line.de/co/sensor-tec/hersteller/smartec/smt-160-30/index.html&lt;br /&gt;
&lt;br /&gt;
=== Thermoelement ===&lt;br /&gt;
&lt;br /&gt;
Ein Thermoelement besteht im einfachsten Fall aus zwei ungleichen Metallendrähten, die an einem Punkt miteinander verbunden sind und bei dem die Verbindungsstelle einer anderen Temperatur ausgesetzt ist als die offenen Enden der Drähte. An den offenen Enden der Drähten entsteht eine Spannung (Thermospannung). Dieser Effekt wurde 1821 von Thomas Seebeck entdeckt ([http://de.wikipedia.org/wiki/Seebeck-Effekt Seebeck-Effekt] bei Wikipedia). Eine weitere Anwendung ist der thermoelektrische Generator (&amp;quot;Thermogenerator&amp;quot;).&lt;br /&gt;
&lt;br /&gt;
Vorteil:&lt;br /&gt;
* über einen sehr weiten Temperaturbereich einsetzbar&lt;br /&gt;
&lt;br /&gt;
Nachteil:&lt;br /&gt;
* die sehr geringen Temperaturspannungen im Mikrovoltbereich benötigen eine sehr gute Auswertelektronik (guter Analogteil + AD-Wandler).&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://digital.ni.com/worldwide/germany.nsf/web/all/7A4F02BAEFEC22AC802567F6003E0D6E  Temperaturmessung mit Thermoelementen] - Eine Einführung von David Potter (deutsche Überarbeitung: G.Sinkovic) (inkl. Erläuterung der Kaltstellenkompensation)&lt;br /&gt;
* [http://www.sensorwell.at/fileadmin/templates/images/data_sheets/temperatur_messtechnik.pdf Warum Thermoelemente Relativtemperaturen messen! oder Was ist eine Kaltstelle?] - Technische Information von www.sensorwell.at (PDF, ca. 600kB)&lt;br /&gt;
&lt;br /&gt;
== Digitale Temperatursensoren ==&lt;br /&gt;
&lt;br /&gt;
=== DS1621 ===&lt;br /&gt;
&lt;br /&gt;
Der DS1621 ist Temperatursensor und A/D-Wandler in einem. Er gibt seine Daten per [[I²C]]-[[Bus]] aus. Ein Schaltplan für einen elektronischen Thermometer mit diesem IC findet sich [http://www.myplace.nu/avr/thermo/ hier].&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* bereits kalibriert&lt;br /&gt;
* kein A/D-Wandler nötig&lt;br /&gt;
* da I²C ein Bus ist, kann man mehrere DS1621 und andere I²C-Bausteine zusammen anschließen und braucht dafür trotzdem nur zwei I/O-Ports.&lt;br /&gt;
* Messbereich -55°C to +125°C &lt;br /&gt;
* Genauigkeit +-0,5°C&lt;br /&gt;
* Auflösung besser 0,01°C, wenn man die beiden Zählerregister (Count-Remain und Count-per-C) auswertet&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* teuer (Segor 5,80&amp;amp;euro;; RS 3,95&amp;amp;euro;; Conrad 5,22&amp;amp;euro;)&lt;br /&gt;
* obwohl die meisten Register [[Speicher#NVRAM | nichtflüchtig]] sind, kann man ihn nicht als Stand-Alone-Thermostat einsetzen, da er erst nach einem Start-Conversion-Befehl zu messen beginnt.&lt;br /&gt;
&lt;br /&gt;
Nachfolger:&lt;br /&gt;
* DS1631, DS1631A (Auto-Start-&amp;gt; Stand-Alone-Thermostat), DS1731&lt;br /&gt;
* weitere Stand-Alone-Thermostaten: DS1821, DS1629&lt;br /&gt;
&lt;br /&gt;
=== LM75 ===&lt;br /&gt;
&lt;br /&gt;
Der LM75 ist so ähnlich wie der DS1621, allerdings nur in SMD erhältlich und nicht so genau. Er ist aber öfters mal auf PC-Mainboards zu finden, so dass man beim Schlachten eines solchen günstig an einen Temperatursensor kommen kann. Eine Beispiel Schaltplan mit einem ATmega8 findet man [http://www.ucblog.de/2010/09/mikrocontroller-thermometer-schaltplan/ hier]&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* bereits kalibriert&lt;br /&gt;
* kein A/D-Wandler nötig&lt;br /&gt;
* I²C-Bus Ausgang&lt;br /&gt;
* billiger als DS1621 (Reichelt 1,45 &amp;amp;euro;; RS 3V: 3,75&amp;amp;euro;; 5V: 2,72&amp;amp;euro;)&lt;br /&gt;
* Auflösung +-0,5°C&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* nur im SMD-Gehäuse erhältlich&lt;br /&gt;
* relativ ungenau (+-2°C), kann man jedoch kalibrieren / kompensieren&lt;br /&gt;
&lt;br /&gt;
Kompatible Typen:&lt;br /&gt;
* AD7415ART&lt;br /&gt;
* DS7505S+&lt;br /&gt;
&lt;br /&gt;
=== LM76 ===&lt;br /&gt;
&lt;br /&gt;
Der LM76 ähnlich dem LM75, bietet aber eine 8-fach höhere Auflösung und eine Genauigkeit von 0.5 bzw. 1°C.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* höhere Auflösung&lt;br /&gt;
* höhere Genauigkeit&lt;br /&gt;
&lt;br /&gt;
Nachteil:&lt;br /&gt;
* schwerer zu beschaffen&lt;br /&gt;
&lt;br /&gt;
=== TMP175 / TMP75 ===&lt;br /&gt;
&lt;br /&gt;
Ähnelt dem LM75 stark! Temperatursensor von Texas Instruments.&lt;br /&gt;
&lt;br /&gt;
=== DS18S20 / DS18B20 ===&lt;br /&gt;
&lt;br /&gt;
Der DS18S20 (Nachfolger des DS1820) und DS18B20 sind scheinbar Temperatursensoren und A/D-Wandler in einem. Wenn man genauer hinschaut, stellt man fest, dass es sich um direktwandelnde Sensoren handelt. Die Temperatur wird ohne Umweg über eine analoge Zwischengröße (Spannung oder Strom) in ein digitales Signal überführt.&lt;br /&gt;
&lt;br /&gt;
Die Datenkommunikation erfolgt über ein 1-Wire-Interface, wodurch man am [[Mikrocontroller]] mit nur einem einzigen I/O-Pin auskommen kann. Außerdem beherrschen sie die parasitäre Stromversorgung, d.h., man braucht für Daten und Stromversorgung zusammen nur zwei Leitungen.&lt;br /&gt;
&lt;br /&gt;
Beim DS18B20 sind Auflösungen von 9, 10, 11 und 12 Bits konfigurierbar. Je kleiner die Auflösung, desto kürzer ist die Messzeit. Der DS18S20 hat eine feste Auflösung von 12 Bits, wobei die unteren 3 Bits aufwändiger auszuwerten sind als beim DS18B20. Der DS18S20 ist als Ersatz für den DS1820 gedacht. Der Hersteller empfiehlt den DS18B20 für Neuentwicklungen.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* bereits kalibriert&lt;br /&gt;
* Genauigkeit +-0,5°C&lt;br /&gt;
* 1-Wire-Ausgang&lt;br /&gt;
&lt;br /&gt;
Nachteil:&lt;br /&gt;
* relativ teuer: Reichelt: 2,50&amp;amp;euro; / CSD: 1,85&amp;amp;euro; / Conrad 5,08&amp;amp;euro;&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://pdfserv.maxim-ic.com/en/ds/DS18S20.pdf Datenblatt DS18S20] &lt;br /&gt;
* [http://pdfserv.maxim-ic.com/en/ds/DS18B20.pdf Datenblatt DS18B20]&lt;br /&gt;
* [http://www.maxim-ic.com/app-notes/index.mvp/id/4377 Vergleich DS18B20 &amp;lt;-&amp;gt; DS18S20]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/6505 Code zur Ansteuerung (ASM ATTiny12)]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/14792 Code zur Ansteuerung (AVR-GCC)]&lt;br /&gt;
* [http://gandalf.arubi.uni-kl.de/avr_projects/tempsensor/ Code zur Ansteuerung mit CRC-Prüfung (AVR-GCC)]&lt;br /&gt;
* [http://chaokhun.kmitl.ac.th/~kswichit/avrthermo/avrthermo.html LED-Thermometer mit AT90S2313 (C)]&lt;br /&gt;
* [http://www.mikrocontroller.net/forum/read-4-248219.html Webserver zur Ansteuerung von bis zu 63 Bausteinen]&lt;br /&gt;
* [http://www.teslabs.com/openplayer/docs/docs/other/ds18b20_pre1.pdf PDF Anleitung zur Beschaltung und Programmierung (C)]&lt;br /&gt;
*[http://www.digitemp.com/building.shtml Anleitung Sensorfühleraufbau (DigiTemp)]&lt;br /&gt;
* http://www.mikrocontroller.net/topic/14792 &lt;br /&gt;
* http://www.mikrocontroller.net/topic/232156 (Timing der parasitären Versorgung)&lt;br /&gt;
&lt;br /&gt;
=== DS1822 ===&lt;br /&gt;
&lt;br /&gt;
Ähnlich wie DS18S20, aber weniger genau (+-2°) und in großen Stückzahlen billiger. Wegen der geringeren Verbreitung kommt der Preisvorteil aber bei Einzelstücken nicht beim Kunden an. So kostet er bei Reichelt mit 3,50&amp;amp;euro; mehr als der DS18S20.&lt;br /&gt;
&lt;br /&gt;
=== DS1921 / DS1922 ===&lt;br /&gt;
&lt;br /&gt;
Sind wie die DS1821 1-wire-Sensoren mit zusätzlicher Logging-Funktion.&lt;br /&gt;
Im iButton-Gehäuse befindet sich eine Lithium-Zelle, eine RTC, CMOS-RAM und der Temp-Sensor. Nach umfangreicher Progammierung startet der Button seine Mission (Aufzeichnung des Temperaturverlaufs).&lt;br /&gt;
Gibt es auch mit zusätzlicher Feuchtemessung (DS1923).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== TSic ===&lt;br /&gt;
&lt;br /&gt;
Die TSic Sensoren werden baugleich von 3 Herstellern angeboten:&lt;br /&gt;
* ZMD ([http://www.zmd.biz/temp.php?group=temp&amp;amp;content=products Homepage]) ([http://tarr.uspto.gov/servlet/tarr?regser=serial&amp;amp;entry=78673282 Trademark])&lt;br /&gt;
* IST AG ([http://www.ist-ag.com/eh/ist-ag/de/home.nsf/contentview/8F5D32432CAC53C2C1257405003C2433 Homepage])&lt;br /&gt;
* Hygrosens ([http://www.hygrosens.de/english/shop/list.html?tx_ttproducts_pi1%5Bcat%5D=11&amp;amp;cHash=dcd89b823b Homepage])&lt;br /&gt;
&lt;br /&gt;
Die TSic Sensoren ([http://www.zmd.biz/pdf/ZMD%20TSic%20Data%20Sheet%20V3%207.pdf Datenblatt]) geben ihre Temperaturmessdaten automatisch in einem festen Intervall aus. Daher muss der Host nur warten bis die nächsten Messdaten rausgeschickt werden. Die TSic Sensoren die es im freien Handel gibt, geben ihre Messdaten alle 100ms (10Hz) aus. &lt;br /&gt;
Zur Übertragung wird das [http://www.zmd.biz/pdf/IST_TSic_ZACwire_V2.3%20Digital%20Output_17-Oct-06.pdf ZACwire] Protokoll benutzt. Es handelt sich um eine einfach zwei Byte Übertragung per Manchester-Code. Diese zwei Byte repräsentieren den digital gewandelten Temperaturwert. Im Gegensatz zu Sensoren wie den DS18xxx von Dallas muss dieser Wert aber erst auf einen dezimalen Wert umgerechnet werden. &lt;br /&gt;
Die Sensoren kommen mit 3 Pins aus (VCC, GND, Dout).&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* Bereits kalibriert&lt;br /&gt;
* Verschiedene Genauigkeiten lieferbar&lt;br /&gt;
* Sehr einfaches Kommunikationsprotokoll&lt;br /&gt;
* Geringer Stromverbrauch&lt;br /&gt;
* Hochgenau: bis zu +/- 0.1°C (TSic 50x)&lt;br /&gt;
&lt;br /&gt;
Nachteil:&lt;br /&gt;
* Recht teuer (Reichelt: 4,70&amp;amp;euro; für den TSic206)&lt;br /&gt;
* Nur ein Sensor an einem I/O nutzbar (Kein Bussystem)&lt;br /&gt;
&lt;br /&gt;
Achtung! &lt;br /&gt;
Die TSic Sensoren gibt es auch als Version mit analog Ausgang. Bei der Typenbezeichnung gibt die 3. Stelle an ob es sich um die analog- oder Digitalversion handelt (1 = analog, 6 = digital). &lt;br /&gt;
Der TSic201 ist also analog, wärend der TSic206 ein digitaler ist.&lt;br /&gt;
&lt;br /&gt;
Links:&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/45573#347765 Ansatz zum Empfang der Daten]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/225554# Beispiel mit Strobe ohne Interrupt]&lt;br /&gt;
* [http://ethersex.de/index.php/Zacwire Fertige Ansteuerung durch AVR in Ethersex]&lt;br /&gt;
* [http://www.zmd.biz/temp.php?group=temp&amp;amp;content=products Herstellerseite mit Datenblättern und FAQ]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/82087 Diskussion mit Beispielcode (MSP430, AVR, PIC) blockierend]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/144424#1367539 C++ Interrupt]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/88847 noch mehr C, problematisch Interrupt]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/151791#1426974 C für ATmega8]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/159149#1510455 auch problematisch]&lt;br /&gt;
* [http://www.sinc.sunysb.edu/Stu/maman/ESE_381.htm Projekt mit tsic sensor, evtl. code]&lt;br /&gt;
* [http://www.mikrocontroller.net/topic/188462#1837622 fertiger Code zum Einlesen des Zacwire-Protokolls für PIC in ASM]&lt;br /&gt;
* [http://www.roboternetz.de/phpBB2/zeigebeitrag.php?t=55103 RN: Bascom]&lt;br /&gt;
* [http://www.mikrocontroller.net/search?query=tsic* Suche in den Foren]&lt;br /&gt;
* [http://www.avr-projekte.de/tinyclock.htm TSIC206 Thermometer mit Uhr und Kalender. Komplette Bauanleitung mit ASM Quellcode für AT-Tiny2313]&lt;br /&gt;
&lt;br /&gt;
=== SHT1x/SHT7x ===&lt;br /&gt;
&lt;br /&gt;
Der SHT1x/SHT7x (SHT10, SHT11, SHT15, STH71, SHT75) sind kombinierte Temperatur- und Feuchtesensoren von [http://www.sensirion.com Sensirion]. Sie unterscheiden sich in Bauform und Genauigkeit.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* digitale Schnittstelle mit einfacher [[I²C]]-&#039;&#039;ähnlicher&#039;&#039; Ansteuerung&lt;br /&gt;
* keine Kalibrierung notwendig&lt;br /&gt;
* Beispielcode (C, MC51) auf der Sensirion-Seite verfügbar (relativ leicht portierbar)&lt;br /&gt;
* interne Heizelemente (Funktionsprüfung, &amp;quot;rauhe&amp;quot; Umgebung)&lt;br /&gt;
* Spannungsmonitor (&amp;quot;Battery fail&amp;quot;)&lt;br /&gt;
* sehr hohe Genauigkeit&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* kann nicht am [[I²C]] Bus betrieben werden, theoretisch gleiche Clockleitung möglich, fixe Adresse&lt;br /&gt;
* relativ teuer (Farnell 18,60&amp;amp;euro;)(SHT11 bei CSD 14€)&lt;br /&gt;
&lt;br /&gt;
[http://www.sensirion.com/en/01_humidity_sensors/00_humidity_sensors.htm Übersicht] der Temperatur- /Feutchtigkeitssensoren von Sensirion.&lt;br /&gt;
&lt;br /&gt;
=== SHT21 ===&lt;br /&gt;
&lt;br /&gt;
[http://www.sensirion.com Sensirion] bietet auch den SHT21 Feuchtigkeits- und Temperatursensor an, welcher wesentlich genauer ist.&lt;br /&gt;
    &lt;br /&gt;
Vorteile:&lt;br /&gt;
* I2C digital, PWM and SDM/analog Volt Ausgabe&lt;br /&gt;
* Maximal 5 Messungen/s @ 14bit&lt;br /&gt;
* Temperaturbereich von -40 – +125°C&lt;br /&gt;
* Feuchtigkeit mit einer Genauigkeit von +-3%RH&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
*  teuer (Farnell 23 €, Segor 29 €)&lt;br /&gt;
* nur als SMD-Package&lt;br /&gt;
&lt;br /&gt;
Application Notes und Datenblätter findet man [http://www.sensirion.com/en/01_humidity_sensors/10_Overview.htm hier].&lt;br /&gt;
&lt;br /&gt;
=== ADT7310 ===&lt;br /&gt;
&lt;br /&gt;
Der ADT7310 von [http://www.analog.com/en/sensors/digital-temperature-sensors/adt7310/products/product.html Analog Devices] besitzt eine Auflösung von 16 Bit und eine Genauigkeit von ±0.5°C im Bereich von −40°C bis +105°C.&lt;br /&gt;
&lt;br /&gt;
Vorteile:&lt;br /&gt;
* Ansteuerung per [[SPI]] (für [[I2C]] siehe [http://www.analog.com/en/sensors/digital-temperature-sensors/adt7410/products/product.html ADT7410])&lt;br /&gt;
* keine Kalibrierung notwendig&lt;br /&gt;
* hohe [[Auflösung und Genauigkeit]]&lt;br /&gt;
* programmierbarer [[Interrupt]]ausgang für Unter- und Übertemperatur&lt;br /&gt;
&lt;br /&gt;
Nachteile:&lt;br /&gt;
* zur Zeit noch schlecht erhältlich (z.B. bei Digikey für 3,15$)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Category:Sensorik]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=MOSFET-%C3%9Cbersicht&amp;diff=61905</id>
		<title>MOSFET-Übersicht</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=MOSFET-%C3%9Cbersicht&amp;diff=61905"/>
		<updated>2011-11-22T20:27:53Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: /* Weblinks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Im Forum wird immer wieder gefragt, welchen Mosfet-Transistor man für ein Projekt einsetzen sollte. Und wo man die herbekommt. Deshalb soll hier eine Übersicht mit gängigen Mosfet-Transistoren entstehen, wo auch die Bezugsquellen angegeben sind. Bezugsquellen sollten nach Möglichkeit solche sein, die auch für den privaten Bastler in Frage kommen.&lt;br /&gt;
&lt;br /&gt;
Der Thread zum Thema: http://www.mikrocontroller.net/topic/41588&lt;br /&gt;
&lt;br /&gt;
siehe auch : [[Transistor-Übersicht]] - [[Dioden-Übersicht]] - [[Standardbauelemente]]&lt;br /&gt;
&lt;br /&gt;
== P-Kanal MOSFET==&lt;br /&gt;
&lt;br /&gt;
{| {{Tabelle}} border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;pkanalmosfets&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#eeeeee&amp;quot;&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Package&lt;br /&gt;
! Hersteller&lt;br /&gt;
! U&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;/V&lt;br /&gt;
! U&amp;lt;sub&amp;gt;DS&amp;lt;/sub&amp;gt;/V&lt;br /&gt;
! I&amp;lt;sub&amp;gt;D&amp;lt;/sub&amp;gt;/A&lt;br /&gt;
! P/W&lt;br /&gt;
! R&amp;lt;sub&amp;gt;DS,on&amp;lt;/sub&amp;gt;/mOhm&lt;br /&gt;
! Bemerkung&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Einzelpreis&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BS250 BS250]&lt;br /&gt;
| TO-92/SOT-23&lt;br /&gt;
| Siliconix&lt;br /&gt;
| 4,0&lt;br /&gt;
| 60&lt;br /&gt;
| 0,12&lt;br /&gt;
| 0,35&lt;br /&gt;
| 10000&lt;br /&gt;
| -&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Buerklin|Bü]]&lt;br /&gt;
| 0,32 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BSH205 BSH205]&lt;br /&gt;
| SOT23&lt;br /&gt;
| Phi&lt;br /&gt;
| 1,0&lt;br /&gt;
| 12&lt;br /&gt;
| 0,75&lt;br /&gt;
| 0,4&lt;br /&gt;
| 500&lt;br /&gt;
| kleine Gatekapazität (3.8nC)&lt;br /&gt;
| [[Elektronikversender#csd-electronics|csd]] (a.A.)&lt;br /&gt;
| 0,30 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/SI2301 SI2301]&lt;br /&gt;
| SOT23&lt;br /&gt;
| Vishay&lt;br /&gt;
| 1,5&lt;br /&gt;
| 20&lt;br /&gt;
| 2,0&lt;br /&gt;
| 0,7&lt;br /&gt;
| 150&lt;br /&gt;
| kleine Gatekapazität (typ 4.5nC)&lt;br /&gt;
| [[Elektronikversender#farnell|farnell]]&lt;br /&gt;
| 0,30 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRLML6302  IRLML6302PBF]&lt;br /&gt;
| SOT23&lt;br /&gt;
| IRF&lt;br /&gt;
| 1,5&lt;br /&gt;
| 20&lt;br /&gt;
| 0,75&lt;br /&gt;
| 0,54&lt;br /&gt;
| 600&lt;br /&gt;
| ähnlich BSH205&lt;br /&gt;
| [[Elektronikversender#csd-electronics|csd]],[[Elektronikversender#Buerklin|Bü]]&lt;br /&gt;
| 0,18 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BSS83 BSS83P]&lt;br /&gt;
| SOT23&lt;br /&gt;
| Inf&lt;br /&gt;
| 3,0&lt;br /&gt;
| 60&lt;br /&gt;
| 0,33&lt;br /&gt;
| 0,35&lt;br /&gt;
| 2000&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,11 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BSS84 BSS84]&lt;br /&gt;
| SOT23&lt;br /&gt;
| Fairchild,NXP&lt;br /&gt;
| 2,0&lt;br /&gt;
| 50&lt;br /&gt;
| 0,13&lt;br /&gt;
| 0,35&lt;br /&gt;
| 10000&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Farnell|Fa]]&lt;br /&gt;
| 0,28 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BSS83 BSS83]&lt;br /&gt;
| TO-97, SOT23&lt;br /&gt;
| Phi&lt;br /&gt;
| 3,0&lt;br /&gt;
| 50&lt;br /&gt;
| 0,13&lt;br /&gt;
| 0,35&lt;br /&gt;
| 10000&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]],[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,07 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BSS110 BSS110]&lt;br /&gt;
| TO-97, SOT23&lt;br /&gt;
| Phi&lt;br /&gt;
| 3,0&lt;br /&gt;
| 50&lt;br /&gt;
| 0,17&lt;br /&gt;
| 0,35&lt;br /&gt;
| 10000&lt;br /&gt;
| -&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/PMV65XP PMV65XP]&lt;br /&gt;
| SOT23&lt;br /&gt;
| Phi&lt;br /&gt;
| 1,4&lt;br /&gt;
| 20&lt;br /&gt;
| 3,9&lt;br /&gt;
| ?&lt;br /&gt;
| 76&lt;br /&gt;
| grosser ID für Bauform&lt;br /&gt;
| [[Elektronikversender#Spoerle|Spo]], [[Elektronikversender#RS_Components|RS]]&lt;br /&gt;
| 0,10 € (3000er-Rolle)&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF4905S IRF4905S]&lt;br /&gt;
| D2Pack&lt;br /&gt;
| irf&lt;br /&gt;
| 4,0&lt;br /&gt;
| 55&lt;br /&gt;
| 64&lt;br /&gt;
| 3,8&lt;br /&gt;
| 20&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 2,60 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF4905 IRF4905]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 4,0&lt;br /&gt;
| 55&lt;br /&gt;
| 74&lt;br /&gt;
| 3,8&lt;br /&gt;
| 20&lt;br /&gt;
| -&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,93 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF5210S IRF5210S]&lt;br /&gt;
| D2Pack&lt;br /&gt;
| irf&lt;br /&gt;
| 10,0&lt;br /&gt;
| 100&lt;br /&gt;
| 40&lt;br /&gt;
| ?&lt;br /&gt;
| 60&lt;br /&gt;
| -&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1,25 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7104 IRF7104]&lt;br /&gt;
| SO-8&lt;br /&gt;
| irf&lt;br /&gt;
| 3,0&lt;br /&gt;
| 20&lt;br /&gt;
| 2,3&lt;br /&gt;
| 2,0&lt;br /&gt;
| 250&lt;br /&gt;
| 2 FETs im Gehäuse&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,36 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7205 IRF7205]&lt;br /&gt;
| SO-8&lt;br /&gt;
| irf&lt;br /&gt;
| 3,0&lt;br /&gt;
| 30&lt;br /&gt;
| 4,6&lt;br /&gt;
| 2,5&lt;br /&gt;
| 70&lt;br /&gt;
| ?&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]] &lt;br /&gt;
| 0,34 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/FDC604P FDC604P]&lt;br /&gt;
| SuperSOT-6&lt;br /&gt;
| Fairchild&lt;br /&gt;
| 1,5&lt;br /&gt;
| 20&lt;br /&gt;
| 5,5&lt;br /&gt;
| 0,8-1,6&lt;br /&gt;
| 33&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#csd-electronics|csd]] (a.A.)&lt;br /&gt;
| 0,70 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/NDS0610 NDS0610]&lt;br /&gt;
| SOT-23&lt;br /&gt;
| Fairchild&lt;br /&gt;
| 1,8&lt;br /&gt;
| 60&lt;br /&gt;
| 0,12&lt;br /&gt;
| 0,36&lt;br /&gt;
| 10000&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#csd-electronics|csd]]&lt;br /&gt;
| 0,07 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF5305 IRF5305]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 3,0&lt;br /&gt;
| 55&lt;br /&gt;
| 31&lt;br /&gt;
| 110&lt;br /&gt;
| 60&lt;br /&gt;
| -&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,59 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/NDS352P NDS352P]&lt;br /&gt;
| SOT23&lt;br /&gt;
| Fairchild&lt;br /&gt;
| 4,5&lt;br /&gt;
| 20&lt;br /&gt;
| 0,85&lt;br /&gt;
| 0,5&lt;br /&gt;
| 500&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0,76 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://crio.mib.infn.it/wig/electronics/Componenti/Siemens/MOS%20Transistor/BSP171.pdf BSP171]&lt;br /&gt;
| SOT-223&lt;br /&gt;
| Siemens&lt;br /&gt;
| 1,4&lt;br /&gt;
| 60&lt;br /&gt;
| 1,7&lt;br /&gt;
| 1,8&lt;br /&gt;
| 350&lt;br /&gt;
| -&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,51 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRFD9014 IRFD9014]&lt;br /&gt;
| HEXDIP/DIP4&lt;br /&gt;
| irf&lt;br /&gt;
| 2,0&lt;br /&gt;
| 60&lt;br /&gt;
| 1,1&lt;br /&gt;
| 1,3&lt;br /&gt;
| 500&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0,65 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRFD9024 IRFD9024]&lt;br /&gt;
| HEXDIP/DIP4&lt;br /&gt;
| irf&lt;br /&gt;
| 2,0&lt;br /&gt;
| 60&lt;br /&gt;
| 1,6&lt;br /&gt;
| 1,3&lt;br /&gt;
| 280&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]],[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,50 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7416 IRF7416]&lt;br /&gt;
| SO-8&lt;br /&gt;
| irf&lt;br /&gt;
| 1,0&lt;br /&gt;
| 30&lt;br /&gt;
| 10&lt;br /&gt;
| 2,5&lt;br /&gt;
| 20&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]],[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,60 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/SUP75P03 SUP75P03-007]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| VISHAY&lt;br /&gt;
| 3,0&lt;br /&gt;
| 30&lt;br /&gt;
| 75&lt;br /&gt;
| 187&lt;br /&gt;
| 7&lt;br /&gt;
| -&lt;br /&gt;
| nessel-elektronik.de&lt;br /&gt;
| 2,30 €&lt;br /&gt;
|-&lt;br /&gt;
| IRF4905&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 3,0&lt;br /&gt;
| 55&lt;br /&gt;
| 74&lt;br /&gt;
| 200&lt;br /&gt;
| 20&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]],[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1,20 €&lt;br /&gt;
|-&lt;br /&gt;
| IRF7220&lt;br /&gt;
| SO-8&lt;br /&gt;
| irf&lt;br /&gt;
| 0,6&lt;br /&gt;
| 14&lt;br /&gt;
| 11&lt;br /&gt;
| 2,5&lt;br /&gt;
| 8,2&lt;br /&gt;
| spezifiziert ab 2,5V Vgs, Qg=84nC&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]], [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,58 €&lt;br /&gt;
|-&lt;br /&gt;
| IRF7410&lt;br /&gt;
| SO-8&lt;br /&gt;
| irf&lt;br /&gt;
| 0,4...0,9&lt;br /&gt;
| 12&lt;br /&gt;
| 16&lt;br /&gt;
| 2,5&lt;br /&gt;
| 7&lt;br /&gt;
| spezifiziert ab 1,8V Vgs, Qg=91nC &lt;br /&gt;
| [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 2,03 €&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
(Tabelle mit Click im Kopfbereich sortierbar; a.A. = Auf Anfrage)&lt;br /&gt;
&lt;br /&gt;
== N-Kanal MOSFET==&lt;br /&gt;
&lt;br /&gt;
{| {{Tabelle}} class=&amp;quot;sortable&amp;quot; id=&amp;quot;nkanalmosfets&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#eeeeee&amp;quot;&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Package&lt;br /&gt;
! Hersteller&lt;br /&gt;
! U&amp;lt;sub&amp;gt;GS(th)&amp;lt;/sub&amp;gt;/V&lt;br /&gt;
! U&amp;lt;sub&amp;gt;DS&amp;lt;/sub&amp;gt;/V&lt;br /&gt;
! I&amp;lt;sub&amp;gt;D&amp;lt;/sub&amp;gt;/A&lt;br /&gt;
! P/W&lt;br /&gt;
! R&amp;lt;sub&amp;gt;DS,on&amp;lt;/sub&amp;gt;/mOhm&lt;br /&gt;
! Bemerkung&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Preis/EUR&lt;br /&gt;
|-&lt;br /&gt;
| IRFP 4310Z &lt;br /&gt;
| TO-247AC&lt;br /&gt;
| irf&lt;br /&gt;
| 2-4&lt;br /&gt;
| 100&lt;br /&gt;
| 120&lt;br /&gt;
| 280&lt;br /&gt;
| 4.8&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1.80&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRFP450 IRFP450]&lt;br /&gt;
| TO-247&lt;br /&gt;
| irf&lt;br /&gt;
| 3&lt;br /&gt;
| 500&lt;br /&gt;
| 14&lt;br /&gt;
| 190&lt;br /&gt;
| 400&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1.20&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF530 IRF530]&lt;br /&gt;
| TO-220&lt;br /&gt;
| irf&lt;br /&gt;
| 2.9&lt;br /&gt;
| 100&lt;br /&gt;
| 16&lt;br /&gt;
| 94&lt;br /&gt;
| 160&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.44&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRL3103 IRL3103]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 1.0&lt;br /&gt;
| 30&lt;br /&gt;
| 64&lt;br /&gt;
| 94&lt;br /&gt;
| 12&lt;br /&gt;
| Qg=33nC (!)&lt;br /&gt;
| [[Elektronikversender#Segor-electronics|Seg]]&lt;br /&gt;
| 0.95&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF730A IRF730A]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0&lt;br /&gt;
| 400&lt;br /&gt;
| 5.5&lt;br /&gt;
| 74&lt;br /&gt;
| 1000&lt;br /&gt;
| Qg=22nC (!)&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.54&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRFP064 IRFP064]&lt;br /&gt;
| TO-247AC&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0&lt;br /&gt;
| 60&lt;br /&gt;
| 70&lt;br /&gt;
| 300&lt;br /&gt;
| 9&lt;br /&gt;
| Qg=190 nC&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1.65&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF3205 IRF3205]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0&lt;br /&gt;
| 55&lt;br /&gt;
| 110&lt;br /&gt;
| 200&lt;br /&gt;
| 8&lt;br /&gt;
|&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1.10&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRL3803 IRL3803]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 1.0&lt;br /&gt;
| 30&lt;br /&gt;
| 140&lt;br /&gt;
| 200&lt;br /&gt;
| 6&lt;br /&gt;
| Qg=140nC&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.96&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF540 IRF540]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 3&lt;br /&gt;
| 100&lt;br /&gt;
| 28&lt;br /&gt;
| 150&lt;br /&gt;
| 77&lt;br /&gt;
|&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Kessler|Kes]]&lt;br /&gt;
| 0.52&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7401 IRF7401]&lt;br /&gt;
| SO-8&lt;br /&gt;
| irf&lt;br /&gt;
| 2.7&lt;br /&gt;
| 20&lt;br /&gt;
| 8.7&lt;br /&gt;
| 2.0&lt;br /&gt;
| 22&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.565&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7403 IRF7403]&lt;br /&gt;
| SO-8&lt;br /&gt;
| irf&lt;br /&gt;
| 4.85&lt;br /&gt;
| 30&lt;br /&gt;
| 8.5&lt;br /&gt;
| 2.5&lt;br /&gt;
| 22&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.42&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7413 IRF7413]&lt;br /&gt;
| SO-8&lt;br /&gt;
| irf&lt;br /&gt;
| 3.0&lt;br /&gt;
| 30&lt;br /&gt;
| 13.0&lt;br /&gt;
| 2.5&lt;br /&gt;
| 11&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Kessler|Kes]]&lt;br /&gt;
| 0.41&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BUZ11 BUZ11]&lt;br /&gt;
| TO-220&lt;br /&gt;
| ST&lt;br /&gt;
| 5.0&lt;br /&gt;
| 50&lt;br /&gt;
| 33.0&lt;br /&gt;
| 90.0&lt;br /&gt;
| 30&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.50&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BS170 BS170]&lt;br /&gt;
| TO-92&lt;br /&gt;
| gs&lt;br /&gt;
| 2.0&lt;br /&gt;
| 60&lt;br /&gt;
| 0.3&lt;br /&gt;
| 0.83&lt;br /&gt;
| 5000&lt;br /&gt;
|&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.13&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BSN20 BSN20]&lt;br /&gt;
| SOT-23&lt;br /&gt;
| gs&lt;br /&gt;
| 1.8&lt;br /&gt;
| 50&lt;br /&gt;
| 0.18&lt;br /&gt;
| 0.35&lt;br /&gt;
| 6000&lt;br /&gt;
|&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.092&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BSS138 BSS138]&lt;br /&gt;
| SOT-23&lt;br /&gt;
| div&lt;br /&gt;
| 0.8-1.6&lt;br /&gt;
| 50&lt;br /&gt;
| 0.22&lt;br /&gt;
| 0.36&lt;br /&gt;
| 2000&lt;br /&gt;
| Rds=1,4-3,6Ω je nach Hersteller&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.06&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BSS123 BSS123]&lt;br /&gt;
| SOT-23&lt;br /&gt;
| div&lt;br /&gt;
| 0.8-1.6&lt;br /&gt;
| 100&lt;br /&gt;
| 0.17&lt;br /&gt;
| 0.36&lt;br /&gt;
| 10000 @ 4,5V&lt;br /&gt;
| [http://www.fairchildsemi.com/ds/BS/BSS123.pdf Datenblatt]&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.06&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRFP2907 IRFP2907]&lt;br /&gt;
| TO-247AC&lt;br /&gt;
| irf&lt;br /&gt;
| 4.0&lt;br /&gt;
| 75&lt;br /&gt;
| 209&lt;br /&gt;
| 470&lt;br /&gt;
| 4.5&lt;br /&gt;
|&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 4.70&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/2N7000 2N7000]&lt;br /&gt;
| TO-92&lt;br /&gt;
| ON&lt;br /&gt;
| 3.0&lt;br /&gt;
| 60&lt;br /&gt;
| 0.2&lt;br /&gt;
| 0.35&lt;br /&gt;
| 5000&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Kessler|Kes]]&lt;br /&gt;
| 0.13&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BS107 BS107]&lt;br /&gt;
| TO-92&lt;br /&gt;
| ON, Phi&lt;br /&gt;
| 3.0&lt;br /&gt;
| 200&lt;br /&gt;
| 0.25&lt;br /&gt;
| 0.35&lt;br /&gt;
| 6400/14000&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.18&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BS108 BS108]&lt;br /&gt;
| TO-92&lt;br /&gt;
| ON, Phi&lt;br /&gt;
| 2.0&lt;br /&gt;
| 200&lt;br /&gt;
| 0.25&lt;br /&gt;
| 0.35&lt;br /&gt;
| 8000&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.14&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BUK100 BUK100]&lt;br /&gt;
| TO-220&lt;br /&gt;
| Phi&lt;br /&gt;
| 3.0&lt;br /&gt;
| 50&lt;br /&gt;
| 13.5&lt;br /&gt;
| 40&lt;br /&gt;
| 125&lt;br /&gt;
| Overload-Protection, ESD-Protection&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1.40&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRL3705N IRL3705N]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0&lt;br /&gt;
| 55&lt;br /&gt;
| 89&lt;br /&gt;
| 170&lt;br /&gt;
| 10&lt;br /&gt;
| Qg=98nC&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1.20&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BUZ72 BUZ72A]&lt;br /&gt;
| TO-220&lt;br /&gt;
| Infineon&lt;br /&gt;
| 4.0&lt;br /&gt;
| 100&lt;br /&gt;
| 9.0&lt;br /&gt;
| 40&lt;br /&gt;
| 250&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.45&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRLZ34N IRLZ34N]&lt;br /&gt;
| TO-220&lt;br /&gt;
| irf&lt;br /&gt;
| 2.5&lt;br /&gt;
| 55&lt;br /&gt;
| 30&lt;br /&gt;
| 68&lt;br /&gt;
| 35&lt;br /&gt;
| Logic-Level&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.42&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRLML2502 IRLML2502]&lt;br /&gt;
| SOT23&lt;br /&gt;
| irf&lt;br /&gt;
| 1.2&lt;br /&gt;
| 20&lt;br /&gt;
| 4.2&lt;br /&gt;
| 1&lt;br /&gt;
| 45&lt;br /&gt;
| Logic-Level&lt;br /&gt;
| [[Elektronikversender#csd-electronics|csd]] [[Elektronikversender#Reichelt|Rei (neu)]]&lt;br /&gt;
| 0.21&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF1404 IRF1404]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 4.0&lt;br /&gt;
| 40&lt;br /&gt;
| 202&lt;br /&gt;
| 333&lt;br /&gt;
| 4&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1.65&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRL1004 IRL1004]&lt;br /&gt;
| TO-220&lt;br /&gt;
| irf&lt;br /&gt;
| 2.7&lt;br /&gt;
| 40&lt;br /&gt;
| 130&lt;br /&gt;
| 200&lt;br /&gt;
| 6.5&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1.25&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRL530 IRL530]&lt;br /&gt;
| TO220, D2Pack&lt;br /&gt;
| irf&lt;br /&gt;
| 2&lt;br /&gt;
| 100&lt;br /&gt;
| 15.0&lt;br /&gt;
| 88&lt;br /&gt;
| 160&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.51&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF830 IRF830]&lt;br /&gt;
| TO220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0-4.5   &lt;br /&gt;
| 500&lt;br /&gt;
| 5.0&lt;br /&gt;
| 74&lt;br /&gt;
| 1400&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Kessler|Kes]]&lt;br /&gt;
| 0.57&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF840 IRF840]&lt;br /&gt;
| TO220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0-4.0   &lt;br /&gt;
| 500&lt;br /&gt;
| 8.0&lt;br /&gt;
| 125&lt;br /&gt;
| 850&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.57&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/FDC645N FDC645N]&lt;br /&gt;
| SuperSOT-6&lt;br /&gt;
| Fairchild&lt;br /&gt;
| 1.5&lt;br /&gt;
| 30&lt;br /&gt;
| 5.5&lt;br /&gt;
| 0.8/1.6&lt;br /&gt;
| 30&lt;br /&gt;
| -&lt;br /&gt;
| [[Elektronikversender#csd-electronics|csd]] (a.A.), Far&lt;br /&gt;
| 0.7&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BSP297 BSP297]&lt;br /&gt;
| SOT-223&lt;br /&gt;
| Siemens/Infineon&lt;br /&gt;
| 0.8-2.4&lt;br /&gt;
| 200&lt;br /&gt;
| 0.65&lt;br /&gt;
| 1.8&lt;br /&gt;
| 6000&lt;br /&gt;
| 200V UDS, SMT und LL (seltene Kombi)&lt;br /&gt;
| [[Elektronikversender#Farnell|Far]], [[Elektronikversender#Schuricht|Schu]], [[Elektronikversender#RS_Components|RS]]&lt;br /&gt;
| 0.56&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7455 IRF7455]&lt;br /&gt;
| SO-8&lt;br /&gt;
| irf&lt;br /&gt;
| 4.5&lt;br /&gt;
| 30&lt;br /&gt;
| 15&lt;br /&gt;
| 2.5&lt;br /&gt;
| 7.5&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Kessler|Kes]]&lt;br /&gt;
| 1.04&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/SI4442DY SI4442DY]&lt;br /&gt;
| SO-8&lt;br /&gt;
| vis&lt;br /&gt;
| 2.5&lt;br /&gt;
| 30&lt;br /&gt;
| 22&lt;br /&gt;
| 2.5&lt;br /&gt;
| 5/4.5V&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Kessler|Kes]]&lt;br /&gt;
| 1.64&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRLU2905 IRLU2905]&lt;br /&gt;
| TO251, DPack&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0&lt;br /&gt;
| 55&lt;br /&gt;
| 42&lt;br /&gt;
| 110&lt;br /&gt;
| 27&lt;br /&gt;
| Logic-Level&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.72&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRFD014 IRFD014]&lt;br /&gt;
| HEXDIP/DIP4&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0-4.0&lt;br /&gt;
| 60&lt;br /&gt;
| 1.7&lt;br /&gt;
| 1.3&lt;br /&gt;
| 200&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Conrad|Con]],[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.52&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRFD024 IRFD024]&lt;br /&gt;
| HEXDIP/DIP4&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0-4.0&lt;br /&gt;
| 60&lt;br /&gt;
| 2.5&lt;br /&gt;
| 1.3&lt;br /&gt;
| 100&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Conrad|Con]],[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.54&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRLD024 IRLD024]&lt;br /&gt;
| HEXDIP/DIP4&lt;br /&gt;
| irf&lt;br /&gt;
| 1.0-2.0&lt;br /&gt;
| 60&lt;br /&gt;
| 2.5&lt;br /&gt;
| 1.3&lt;br /&gt;
| 100&lt;br /&gt;
| Logic-Level&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]],[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.47&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRLU3717 IRLU3717]&lt;br /&gt;
| I-Pak&lt;br /&gt;
| irf&lt;br /&gt;
| 2.0&lt;br /&gt;
| 20&lt;br /&gt;
| 120&lt;br /&gt;
| 1.5/89&lt;br /&gt;
| 4&lt;br /&gt;
| Qg=21nC&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]],[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.86&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRFP3703 IRFP3703]&lt;br /&gt;
| TO-247AC&lt;br /&gt;
| irf&lt;br /&gt;
| 4.0&lt;br /&gt;
| 30&lt;br /&gt;
| 210&lt;br /&gt;
| 230&lt;br /&gt;
| 2.8&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 5.08&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF3710 IRF3710]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 5&lt;br /&gt;
| 100&lt;br /&gt;
| 57&lt;br /&gt;
| 200&lt;br /&gt;
| 23&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0.83&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRLR7843 IRLR7843]&lt;br /&gt;
| D-Pack&lt;br /&gt;
| irf&lt;br /&gt;
| 2.3&lt;br /&gt;
| 30&lt;br /&gt;
| 164&lt;br /&gt;
| 140&lt;br /&gt;
| 3.3&lt;br /&gt;
| Qg: 34nC, Rds_on bei GS=4.5V: max. 4.0mOhm&lt;br /&gt;
| [http://www.flymotec.de/]&lt;br /&gt;
| 0.70&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF1010N IRF1010N]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 4&lt;br /&gt;
| 55&lt;br /&gt;
| 85&lt;br /&gt;
| 180&lt;br /&gt;
| 11&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0.83&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF1010Z IRF1010Z]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 4&lt;br /&gt;
| 55&lt;br /&gt;
| 75&lt;br /&gt;
| 140&lt;br /&gt;
| 7.5&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 1.20&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRLIZ44N IRLIZ44N]&lt;br /&gt;
| TO-220-Fullpak &lt;br /&gt;
| irf&lt;br /&gt;
| 1.0 - 2.0&lt;br /&gt;
| 55&lt;br /&gt;
| 30&lt;br /&gt;
| 45&lt;br /&gt;
| 25&lt;br /&gt;
| Logic Level&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0.80&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRLU024N IRLU024N]&lt;br /&gt;
| TO-251AA&lt;br /&gt;
| irf&lt;br /&gt;
| 1.0 - 2.0&lt;br /&gt;
| 55&lt;br /&gt;
| 17&lt;br /&gt;
| 45&lt;br /&gt;
| 80&lt;br /&gt;
| Logic Level, Q&amp;lt;sub&amp;gt;g&amp;lt;/sub&amp;gt;=15 nC (!)&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0.40&lt;br /&gt;
|-&lt;br /&gt;
| IRFZ48N&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 3&lt;br /&gt;
| 55&lt;br /&gt;
| 64&lt;br /&gt;
| 130&lt;br /&gt;
| 14&lt;br /&gt;
| &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]],[[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0.60&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.irf.com/product-info/datasheets/data/irl2505.pdf IRL2505]&lt;br /&gt;
| TO-220AB&lt;br /&gt;
| irf&lt;br /&gt;
| 2,5&lt;br /&gt;
| 55&lt;br /&gt;
| 104&lt;br /&gt;
| &lt;br /&gt;
| 8&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| IRF7607&lt;br /&gt;
| &lt;br /&gt;
| irf&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| IRF3708&lt;br /&gt;
| &lt;br /&gt;
| irf&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
(Tabelle mit Click im Kopfbereich sortierbar, a.A.=Auf Anfrage)&lt;br /&gt;
&lt;br /&gt;
== N-Kanal J-FET==&lt;br /&gt;
&lt;br /&gt;
{| {{Tabelle}} border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;fetpaare&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#eeeeee&amp;quot;&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Package&lt;br /&gt;
! Hersteller&lt;br /&gt;
! U&amp;lt;sub&amp;gt;GS(co)&amp;lt;/sub&amp;gt;/V&lt;br /&gt;
! U&amp;lt;sub&amp;gt;DS&amp;lt;/sub&amp;gt;/V&lt;br /&gt;
! I&amp;lt;sub&amp;gt;D(max)&amp;lt;/sub&amp;gt;/mA&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Einzelpreis&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BF245 BF245A]&lt;br /&gt;
| TO-92&lt;br /&gt;
| diverse&lt;br /&gt;
| -2,2&lt;br /&gt;
| 30&lt;br /&gt;
| 6,5&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,15 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BF245 BF245B]&lt;br /&gt;
| TO-92&lt;br /&gt;
| diverse&lt;br /&gt;
| -3,8&lt;br /&gt;
| 30&lt;br /&gt;
| 15&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,15 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BF245 BF245C]&lt;br /&gt;
| TO-92&lt;br /&gt;
| diverse&lt;br /&gt;
| -7,5&lt;br /&gt;
| 30&lt;br /&gt;
| 25&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,15 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BF246 BF246A]&lt;br /&gt;
| TO-92&lt;br /&gt;
| diverse&lt;br /&gt;
| -4&lt;br /&gt;
| 25&lt;br /&gt;
| 80&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,15 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BF246 BF246B]&lt;br /&gt;
| TO-92&lt;br /&gt;
| diverse&lt;br /&gt;
| -7&lt;br /&gt;
| 25&lt;br /&gt;
| 140&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,17 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BF246 BF246C]&lt;br /&gt;
| TO-92&lt;br /&gt;
| diverse&lt;br /&gt;
| -12&lt;br /&gt;
| 25&lt;br /&gt;
| 250&lt;br /&gt;
| ??&lt;br /&gt;
| ??&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BF511 BF511]&lt;br /&gt;
| SOT-23&lt;br /&gt;
| diverse&lt;br /&gt;
| -1,5&lt;br /&gt;
| 20&lt;br /&gt;
| 7&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,36 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BFR30 BFR30]&lt;br /&gt;
| SOT-23&lt;br /&gt;
| diverse&lt;br /&gt;
| -4&lt;br /&gt;
| 25&lt;br /&gt;
| 10&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/BFR31 BFR31]&lt;br /&gt;
| SOT-23&lt;br /&gt;
| diverse&lt;br /&gt;
| -2&lt;br /&gt;
| 25&lt;br /&gt;
| 5&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/MMBF4416 MMBF4416]&lt;br /&gt;
| SOT-23&lt;br /&gt;
| Fairchild&lt;br /&gt;
| -5,5&lt;br /&gt;
| 15&lt;br /&gt;
| 5&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0,52 €&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
(Tabelle mit Click im Kopfbereich sortierbar)&lt;br /&gt;
&lt;br /&gt;
== FET-Paare ==&lt;br /&gt;
&lt;br /&gt;
{| {{Tabelle}} border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;fetpaare&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#eeeeee&amp;quot;&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Package&lt;br /&gt;
! Hersteller&lt;br /&gt;
! UGS/V&lt;br /&gt;
! UDS/V&lt;br /&gt;
! ID/A&lt;br /&gt;
! P/W&lt;br /&gt;
! RDSon/mOhm&lt;br /&gt;
! Bemerkung&lt;br /&gt;
! Lieferant&lt;br /&gt;
! Einzelpreis&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7389 IRF7389]&lt;br /&gt;
| SO-8&lt;br /&gt;
| IRF&lt;br /&gt;
| 3,0&lt;br /&gt;
| 30&lt;br /&gt;
| 7,3/-5,3&lt;br /&gt;
| 2,0&lt;br /&gt;
| 29/58&lt;br /&gt;
| P+N&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,56 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7501 IRF7501]&lt;br /&gt;
| micro8&lt;br /&gt;
| IRF&lt;br /&gt;
| 2,7&lt;br /&gt;
| 20&lt;br /&gt;
| 2,4&lt;br /&gt;
| ?&lt;br /&gt;
| 135 @4,5V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;&lt;br /&gt;
| 2*N&lt;br /&gt;
| [[Elektronikversender#Kessler|Kessler]], [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 1,64 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7506 IRF7506]&lt;br /&gt;
| micro8&lt;br /&gt;
| IRF&lt;br /&gt;
| 4,5&lt;br /&gt;
| 30&lt;br /&gt;
| 1,7&lt;br /&gt;
| ?&lt;br /&gt;
| 270 @10V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;&lt;br /&gt;
| 2*P&lt;br /&gt;
| [[Elektronikversender#Kessler|Kessler]], [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0,56 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7103 IRF7103]&lt;br /&gt;
| SO-8&lt;br /&gt;
| IRF&lt;br /&gt;
| 4,5&lt;br /&gt;
| 50&lt;br /&gt;
| 2,3&lt;br /&gt;
| 2&lt;br /&gt;
| 130 @10V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;&lt;br /&gt;
| 2*N&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]], [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0,32 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7104 IRF7104]&lt;br /&gt;
| SO-8&lt;br /&gt;
| IRF&lt;br /&gt;
| 4,5&lt;br /&gt;
| 20&lt;br /&gt;
| 2,3&lt;br /&gt;
| 2&lt;br /&gt;
| 250 @10V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;&lt;br /&gt;
| 2*P&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,32 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7316 IRF7316]&lt;br /&gt;
| SO-8&lt;br /&gt;
| IRF&lt;br /&gt;
| 4,5&lt;br /&gt;
| 30&lt;br /&gt;
| 4,9&lt;br /&gt;
| ?&lt;br /&gt;
| 58 @10V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;&lt;br /&gt;
| 2*P&lt;br /&gt;
|[[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,49 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRF7313 IRF7313]&lt;br /&gt;
| SO-8&lt;br /&gt;
| IRF&lt;br /&gt;
| 4,5&lt;br /&gt;
| 30&lt;br /&gt;
| 6,5&lt;br /&gt;
| ?&lt;br /&gt;
| 46 @4.5V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;&lt;br /&gt;
| 2*N&lt;br /&gt;
| [[Elektronikversender#Kessler|Kessler]], [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 0,66 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/FDD8424H FDD8424H]&lt;br /&gt;
| Dual DPAK4L&lt;br /&gt;
| Fairchild&lt;br /&gt;
| &lt;br /&gt;
| 40&lt;br /&gt;
| 9/-6,5&lt;br /&gt;
| 3&lt;br /&gt;
| 24/54 @10V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt; &amp;lt;br&amp;gt; 30/70 @4,5V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;&lt;br /&gt;
| P+N&lt;br /&gt;
| [[Elektronikversender#Digi-Key|Digi-Key]] &lt;br /&gt;
| 0,73 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/SUD50NP04-94 SUD50NP04-94]&lt;br /&gt;
| TO252-4L DPAK4L&lt;br /&gt;
| Vishay&lt;br /&gt;
| 2&lt;br /&gt;
| 40 &lt;br /&gt;
| 8&lt;br /&gt;
| 8?&lt;br /&gt;
| 41/53 @10V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt; &amp;lt;br&amp;gt; 45/72 @4,5V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;&lt;br /&gt;
| P+N&lt;br /&gt;
| [[Elektronikversender#Farnell|Farnell]]&lt;br /&gt;
| 0,56 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IRFI4024H-117P IRFI4024H-117P]&lt;br /&gt;
| TO-220-5&lt;br /&gt;
| IRF&lt;br /&gt;
| 2&lt;br /&gt;
| 55&lt;br /&gt;
| 11&lt;br /&gt;
| 14&lt;br /&gt;
| 50 @10V&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt;&lt;br /&gt;
| 2*N&lt;br /&gt;
| [[Elektronikversender#Reichelt|Reichelt]]&lt;br /&gt;
| 2,10 €&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
(Tabelle mit Click im Kopfbereich sortierbar)&lt;br /&gt;
&lt;br /&gt;
== MOSFET-Treiber ==&lt;br /&gt;
* Detaillierte [[Treiber]]-Dimensionierung&lt;br /&gt;
{| {{Tabelle}} border=&amp;quot;1&amp;quot; class=&amp;quot;sortable&amp;quot; id=&amp;quot;fettreiber&amp;quot;&lt;br /&gt;
|- style=&amp;quot;background-color:#eeeeee&amp;quot;&lt;br /&gt;
! Bezeichnung&lt;br /&gt;
! Bemerkung&lt;br /&gt;
! Lieferant / Datenblatt&lt;br /&gt;
! Einzelpreis&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2101 IR2101]&lt;br /&gt;
| High &amp;amp; Low-Side Driver, 130/270mA, 600V, 3,3V Logikeingang, DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 2,30 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2104 IR2104]&lt;br /&gt;
| Half Bridge Driver, 130/270mA, 600V, 3,3V Logikeingang, DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 2,00 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2110 IR2110]&lt;br /&gt;
| High &amp;amp; Low-Side Driver, 2A, 500V, 3,3V Logikeingang, DIL14/SO16&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 1,55 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2111 IR2111]&lt;br /&gt;
| Half Bridge Driver 200/430mA, 600V, 10-20V CMOS Eingang, DIL8/SO8, maximale Kriechwege&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 1,10 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2112 IR2112]&lt;br /&gt;
| High &amp;amp; Low-Side Driver, 200/420mA, 600V, 3,3V Logikeingang, DIL14/SO16&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 1,45 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2113 IR2113]&lt;br /&gt;
| High &amp;amp; Low-Side Driver, 2A, 600V,  3,3V Logikeingang, DIL14/SO16&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 1,85 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2117 IR2117]&lt;br /&gt;
| Single High Side Driver, 200/420mA, 600V, 10-20V CMOS Eingang, DIL8/SO8, maximale Kriechwege&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 1,20 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2121 IR2121]&lt;br /&gt;
| Low Side Driver, 1A/2A, 2,5V Logikeingang, Strombegrenzung, DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 2,15 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2125 IR2125]&lt;br /&gt;
| Single Channel High Side Driver, 1A/2A, 500V, 2,5V Logikeingang, Strombegrenzung, maximale Kriechwege, DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 4,20 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2127 IR2127]&lt;br /&gt;
| Single Channel High Side Driver, 200/420mA, 3,3V Logikeingang, DIL8/SO8, maximale Kriechwege, Fehlerausgang&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 2,40 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2130 IR2130]&lt;br /&gt;
| 3-Phase Bridge Driver, 200/420mA, 600V, 2,5V Logikeingang, DIL28/SO28&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 2,50 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2151 IR2151]&lt;br /&gt;
| Self Oscillating Half Bridge Driver, 100/210mA, 600V, DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 2,50 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2153 IR2153]&lt;br /&gt;
| Self Oscillating Half Bridge Driver, 100/210mA, 600V, DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 1,20 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2155 IR2155]&lt;br /&gt;
| Self Oscillating Half Bridge Driver, 210/420mA, 600V, DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 3,50 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2181 IR2181]&lt;br /&gt;
| High &amp;amp; Low-Side Driver, 1.4A/1.8A, 600V, 3,3V Logikeingang, DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 2,10 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2183 IR2183]&lt;br /&gt;
| Half Bridge Driver, 1.4A/1.8A, 600V, 3,3V Logikeingang, DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 4,00 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2184 IR2184]&lt;br /&gt;
| Half Bridge Driver, 1.4A/1.8A, 600V, 3,3V Logikeingang, DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]] [[Elektronikversender#Conrad|Con]] &lt;br /&gt;
| 3,20 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/IR2136 IR2136]&lt;br /&gt;
| 3 Phase Driver, 120/250mA, 600V, 3,3V Logikeingang, DIP28/SOIC28,&lt;br /&gt;
| [[Elektronikversender#Conrad|Con]]&lt;br /&gt;
| 1,80 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/ICL7667 ICL7667]&lt;br /&gt;
| Dual Power MOSFET Driver, 4.5-15V, 7Ω, 3,3V Logikeingang, DIL8/SO8 &lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 2,00 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/HIP4081A HIP4081A]&lt;br /&gt;
| Full Bridge Driver, 80V 2,5A, DIP20/SOIC20&lt;br /&gt;
| [[Elektronikversender#Farnell|Far]]&lt;br /&gt;
| 8,00 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/HIP4082 HIP4082]&lt;br /&gt;
| Full Bridge Driver, 80V, 1,2A DIP16/SOIC16&lt;br /&gt;
| [[Elektronikversender#Farnell|Far]] [[Elektronikversender#Farnell|Far]]&lt;br /&gt;
| 6,20 €&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/HIP4083 HIP4083]&lt;br /&gt;
| 3 Phase High side N-channel MOSFET driver, 80V, 0,3A, DIP16/SOIC16&lt;br /&gt;
| [[Elektronikversender#Farnell|Far]]&lt;br /&gt;
| 4,80 €&lt;br /&gt;
&amp;lt;!-- ohne Preis und Lieferant&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/HIP4084 HIP4084]&lt;br /&gt;
| 4 Phase Driver, 80V, 0,5A, DIP28/SOIC28&lt;br /&gt;
| &lt;br /&gt;
| &lt;br /&gt;
--&amp;gt;&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.mikrocontroller.net/part/HIP4086 HIP4086]&lt;br /&gt;
| 3 Phase Driver, 80V, 0.5A, DIP24/SOIC24&lt;br /&gt;
| [[Elektronikversender#Farnell|Far]]&lt;br /&gt;
| 8,00 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/TC4451 TC4451/TC4452]&lt;br /&gt;
| High Speed MOSFET Driver, 12A peak, 2,5A DC, 4,5-18V, DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Farnell|Far]]&lt;br /&gt;
| 3,00 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/LM5104 LM5104]&lt;br /&gt;
| Half Bridge Driver, 1,6/1,8A, 100V, 2,5V Logikeingang, SO8/LLP10 &lt;br /&gt;
| [[Elektronikversender#RS_Components|RS]]&lt;br /&gt;
| 3,20 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/MCP1407 MCP1407-E/P]&lt;br /&gt;
| High Speed MOSFET Driver, 6A peak, 1,3A DC, 4,5-18V, DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 0,95 €&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.mikrocontroller.net/part/MAX626 MAX626]&lt;br /&gt;
| Dual Power MOSFET drivers, inverting, 4,5-18 V, DIL8/SO8&lt;br /&gt;
| [[Elektronikversender#Reichelt|Rei]]&lt;br /&gt;
| 3,40 €&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Anmerkungen ==&lt;br /&gt;
* U&amp;lt;sub&amp;gt;GS&amp;lt;/sub&amp;gt; - minimale Gatespannung, bei welcher der MOSFET zu leiten anfängt (100µA..1mA, nicht genormt). Zur vollständigen Durchschaltung bei maximalem Strom braucht es höhere Spannungen.&lt;br /&gt;
* Logic Level - FET schaltet bei niedrigen Gatespannungen von typisch 4,5V (z.&amp;amp;nbsp;B. CMOS Logikpegel) hinreichend durch. Normale MOSFETs brauchen hierfür typisch 10V.&lt;br /&gt;
* U&amp;lt;sub&amp;gt;GS(co)&amp;lt;/sub&amp;gt; - Gate Source Cut Off Spannung, bei welcher der Drainstrom I&amp;lt;sub&amp;gt;D&amp;lt;/sub&amp;gt; eines JFETs praktisch Null ist. Die Messbedingung ist jedoch nicht genormt (0,5nA..200µA).&lt;br /&gt;
* N-Kanal MOSFETs mit niedrigem R&amp;lt;sub&amp;gt;DS,On&amp;lt;/sub&amp;gt; sind technologisch einfacher herzustellen als P-Kanal MOSFETs. Deshalb gibt es bei P-Kanal keine so große Auswahl und oft werden Schaltungen angestrebt, in denen ausschließlich N-Kanal MOSFETs verwendet werden. Es gibt spezielle Treiberbausteine, die über eine Ladungspumpe für entsprechend hohe Gatespannung auch für die High-Side N-Fets sorgen (&amp;quot;Bootstrap Circuits&amp;quot;, siehe Artikel [[Treiber]]).&lt;br /&gt;
* Bei der Dimensionierung ist zu beachten, dass die Stromangabe im allgemeinen für 25°C gilt. Geht man davon aus, dass der MOSFET mit maximal zulässigem Strom betrieben wird und mit passend dimensioniertem [[Kühlkörper]] ausgestattet ist, so beträgt die Sperrschichttemperatur bis zu 150°C, folglich gilt z.&amp;amp;nbsp;B. für den IRF540 nicht mehr 28A, sondern nur noch ca. 12-15A.&lt;br /&gt;
* Restströme sind auch stark von der Temperatur abhängig. Bei höherer Temperatur nehmen die Restströme exponentiell zu. So können bei 100°C durchaus 100 µA zwischen Source und Drain auch im gesperrten Zustand fließen. Bei 25°C ist dieser Reststrom meist bei 1µA spezifiziert. Real sind es meist weniger.&lt;br /&gt;
* Die Gate-Charge-Werte (s. Datenblatt) bestimmen, wie schnell das Gate beim Schalten umgeladen werden kann. Auch wenn MOSFETs stromlos den durchgeschalteten Zustand halten können, braucht man während des Umschaltvorganges einen Strom, der das Gate umlädt (ähnlich wie ein Kondensator). Je höher dieser Strom, um so schneller ist der Umschaltvorgang und um so geringer die Verlustleistung während dieser Phase. Leistungs-MOSFETs können bei höheren Frequenzen (&amp;gt;1KHz) oft nur mit höheren Gateströmen von 0,1A-2A sinnvoll geschaltet werden. Man kann das Gate also nicht direkt an einen Digitalpin anschließen. Man braucht einen [[MOSFET-Übersicht#MOSFET-Treiber | MOSFET-Treiber]]. Manche MOSFETs haben eine sehr geringe Total Gate Charge (z.&amp;amp;nbsp;B. 4-10nC). Diese können in gewissen Grenzen recht gut direkt an digitalen [[Ausgangsstufen Logik-ICs | Logikausgängen]] betrieben werden. Zur Abschätzung kann man sich merken: Wenn man das Gate eines MOSFETs mit einer Eingangskapazität von 1nF (~10nC) in 100ns auf 10V aufladen will, braucht man dazu 100mA.&lt;br /&gt;
&lt;br /&gt;
== Lieferantenübersicht ==&lt;br /&gt;
* [[Elektronikversender#Reichelt|Rei]]&amp;lt;nowiki&amp;gt;chelt&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* [[Elektronikversender#Conrad|Con]]&amp;lt;nowiki&amp;gt;rad&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* [[Elektronikversender#Kessler|Kes]]&amp;lt;nowiki&amp;gt;sler&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* [[Elektronikversender#csd-electronics|csd]]&amp;lt;nowiki&amp;gt;-electronics&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* [[Elektronikversender#Farnell|Far]]&amp;lt;nowiki&amp;gt;nell&amp;lt;/nowiki&amp;gt; (nur gewerbliche Kunden oder Studenten)&lt;br /&gt;
* HBE-Shop (FARNELL-Fachhändler, auch als nichtgewerblicher Kunde)&lt;br /&gt;
* [[Elektronikversender#Schuricht|Schu]]&amp;lt;nowiki&amp;gt;richt&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
* [[Elektronikversender#RS_Components|RS]]&lt;br /&gt;
* [[Elektronikversender#Spoerle|Spo]]&amp;lt;nowiki&amp;gt;erle&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Herstellerübersicht ==&lt;br /&gt;
* [irf] [http://www.irf.com International Rectifier]&lt;br /&gt;
* [Siliconix] [http://www.vishay.com/company/brands/siliconix/ Vishay Siliconix]&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
* [[FET]]&lt;br /&gt;
* [[IGBT]]&lt;br /&gt;
* [[Treiber]]&lt;br /&gt;
* [[H-Brücken Übersicht]]&lt;br /&gt;
&lt;br /&gt;
== Weblinks ==&lt;br /&gt;
* [http://www.sprut.de/electronic/switch/nkanal/nkanal.html N-Kanal MOSFET leicht erklärt bei sprut.de]&lt;br /&gt;
* [http://www.sprut.de/electronic/switch/pkanal/pkanal.html P-Kanal MOSFET leicht erklärt bei sprut.de]&lt;br /&gt;
* [http://elektronik-kompendium.de/sites/bau/0510161.htm MOSFET im ElKo]&lt;br /&gt;
* [http://elektronik-kompendium.de/public/schaerer/battoff.htm Abschaltverzögerung beim ElKo]&lt;br /&gt;
* [http://elektronik-kompendium.de/sites/bau/0207011.htm FET beim ElKo]&lt;br /&gt;
* [http://de.wikipedia.org/wiki/Mosfet MOSFET bei Wikipedia]&lt;br /&gt;
&amp;lt;!-- * [http://www.irf.com/product-info/auto/autogdic.html IR21xx Familienvergleich] --&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Parametrische Suche beim Hersteller ==&lt;br /&gt;
* [http://www.infineon.com/cms/de/product/channel.html?channel=db3a304319c6f18c011a14e5341b25f1 Infineon]&lt;br /&gt;
* [http://www.nxp.com/#/ps/ps=%5Bi%3D48014%5D%7Cpp%3D%5Bt%3Dpfp%2Ci%3D48014%5D NXP standard Mosfets]&lt;br /&gt;
* [http://www.onsemi.com/PowerSolutions/parametrics.do?id=809&amp;amp;lctn=home ONsemi]&lt;br /&gt;
* [http://www.diodes.com/zetex/?ztx=3.0/3-3-1@tcatid~7 Diodes (vormals Zetex)]&lt;br /&gt;
* [http://www.irf.com/product-info/hexfet/ IRF]&lt;br /&gt;
* [http://www.vishay.com/mosfets/ Vishay]&lt;br /&gt;
&lt;br /&gt;
[[Category:Bauteile]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Kategorie:Boards&amp;diff=61727</id>
		<title>Kategorie:Boards</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Kategorie:Boards&amp;diff=61727"/>
		<updated>2011-11-19T16:03:37Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: Schützte „Kategorie:Boards“ ([edit=autoconfirmed] (bis 19. Februar 2012, 16:03 Uhr (UTC)) [move=autoconfirmed] (bis 19. Februar 2012, 16:03 Uhr (UTC)))&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Kategorie:!Hauptkategorie]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=Kategorie:ARM-Boards&amp;diff=61398</id>
		<title>Kategorie:ARM-Boards</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=Kategorie:ARM-Boards&amp;diff=61398"/>
		<updated>2011-11-02T20:38:24Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: Schützte „Kategorie:ARM-Boards“: scheinbare Vorarbeit zum Spammen ([edit=autoconfirmed] (unbeschränkt) [move=autoconfirmed] (unbeschränkt))&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Kategorie:ARM|B]]&lt;br /&gt;
[[Kategorie:Boards]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
	<entry>
		<id>https://www.mikrocontroller.net/index.php?title=MP2103-Stick:_Ein_Mini-Mikrocontroller-Board_mit_USB_und_bis_zu_4MB_Datenspeicher&amp;diff=61376</id>
		<title>MP2103-Stick: Ein Mini-Mikrocontroller-Board mit USB und bis zu 4MB Datenspeicher</title>
		<link rel="alternate" type="text/html" href="https://www.mikrocontroller.net/index.php?title=MP2103-Stick:_Ein_Mini-Mikrocontroller-Board_mit_USB_und_bis_zu_4MB_Datenspeicher&amp;diff=61376"/>
		<updated>2011-11-01T08:17:30Z</updated>

		<summary type="html">&lt;p&gt;Mthomas: Schützte „MP2103-Stick: Ein Mini-Mikrocontroller-Board mit USB und bis zu 4MB Datenspeicher“: Weblink-Spam ([edit=autoconfirmed] (unbeschränkt) [move=autoconfirmed] (unbeschränkt))&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&#039;&#039;von Mario Pieschel&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Einleitung ==&lt;br /&gt;
&lt;br /&gt;
Der MP2103-Stick ist ein kleines Arm7-Mikrocontroller-Board, welches sehr einfach und damit sehr billig gehalten wurde. Jeglicher Schnickschnack wurde weggelassen und möglichst viele Pins des Mikrocontrollers zu den beiden Steckverbindern geführt. Als Mikrocontroller kommt der LPC2103 von NXP zum Einsatz. Viele Mikrocontroller-Anwendungen sind als Stand-Alone-Anwendungen konzipiert – der MP2103-Stick nicht!!! Er soll mehr als Interface-Baustein für den PC gesehen werden.&lt;br /&gt;
Anwendungsbereiche sehe ich überall dort, wo irgendetwas mit dem PC elektrisch verbunden werden soll, was sich sonst nicht mit diesem über die herkömmlichen PC-Schnittstellen verbinden lässt. Da der LPC2103 über eine mannigfaltige Peripherie verfügt  (digitale Ein/Ausgänge,  ADC,  Timer, I2C, SPI/SSP, PWM, RTC), sehe ich fast keine Grenzen in seinem Einsatzspektrum. Überall wo der PC steuern, regeln und/oder messen soll, könnte der MP2103-Stick zum Einsatz kommen. Die Daten feuern vom und zum PC mit einer Datenübertragungsgeschwindigkeit von fast bis zu 1 Megabit pro Sekunde! Für eventuelle Kalibrierdaten oder andere individuelle Daten für das zu betreibende Gerät steht ein bis zu 4 Megabyte großer Datenspeicher zur Verfügung. Für den MP2103-Stick wird kein spezielles Programmiergerät benötigt – er wird einfach an einen USB-Anschluss eines PCs angeschlossen und das war’s. An ein bestimmtes Betriebssystem des Ziel-PCs ist man ebenfalls nicht gebunden, da für den eingesetzten USB-Baustein (FT232) Treiber für alle gängigen Betriebssysteme vom Hersteller FTDI-Chip angeboten werden.&lt;br /&gt;
&lt;br /&gt;
[http://www.mikrocontroller.net/articles/MP32F103-Stick:_Ein_Mini-Mikrocontroller-Board_mit_USB_und_bis_zu_4MB_Datenspeicher LINK: MP-Stick mit ARM Cortex-M3 (STM32F103CBT6)]&lt;br /&gt;
&lt;br /&gt;
[[Bild:MP2103Stick.jpg]]&lt;br /&gt;
&lt;br /&gt;
== Funktionsmodell des MP2103-Stick ==&lt;br /&gt;
&lt;br /&gt;
[[Bild:MP2103 Model.PNG]]&lt;br /&gt;
&lt;br /&gt;
[http://www.nxp.com/acrobat_download/datasheets/LPC2101_02_03_2.pdf LINK: Datasheet vom LPC2103]&lt;br /&gt;
&lt;br /&gt;
[http://www.nxp.com/acrobat/usermanuals/UM10161_2.pdf LINK: Usermanual vom LPC2103]&lt;br /&gt;
&lt;br /&gt;
[http://www.nxp.com/acrobat/erratasheets/ES_LPC2103_4.pdf LINK: Erratasheet vom LPC2103]&lt;br /&gt;
&lt;br /&gt;
[http://atmel.com/dyn/products/devices.asp?family_id=616#1802 LINK: Datasheet und Anwendung vom AT45DBxxx]&lt;br /&gt;
&lt;br /&gt;
== Schaltungsbeschreibung ==&lt;br /&gt;
&lt;br /&gt;
Die Schaltung des MP2103-Sticks gliedert sich in fünf Funktionsgruppen.&lt;br /&gt;
&lt;br /&gt;
1.	Dem Mikrocontroller LPC2103 von NXP (IC3) mit seiner Grundbeschaltung (dem so genannten Hühnerfutter), den beiden Quarzen (Q2: 14,7456MHz und Q1: 32,768kHz), dem Anschluss für eine Real-Time-Clock-Batterie und den beiden Anschlussleisten CON1 und CON2 für externe Elektronik.&lt;br /&gt;
&lt;br /&gt;
2.	Dem USB-IC FT232RL (IC4) mit Hühnerfutter und der USB-Buchse.&lt;br /&gt;
&lt;br /&gt;
3.	Dem 4 Megabyte großen Datenspeicher AT45DB321 von Atmel (IC2) mit Hühnerfutter.&lt;br /&gt;
Es sind auch die kleineren Varianten z.&amp;amp;nbsp;B. AT45DB161 (2MB) und AT45DB081 (1MB) möglich. Der AT45DB642 (8MB) hat leider ein anderes Gehäuse - Das Löten geht dann nur mit etwas Geschick.&lt;br /&gt;
&lt;br /&gt;
4.	Der Reset-Automatik für Normalbetrieb und Programmiermodus mit Signal-LED (die Schaltung oben rechts).&lt;br /&gt;
&lt;br /&gt;
5.	And last but not least die Mikrocontroller-Core-Spannungsversorgungsschaltung von 1,8 Volt mit LM317D oben links.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Schaltplan ==&lt;br /&gt;
&lt;br /&gt;
[[Media:MP2103stick_schematic.GIF|LINK: Schaltplan gesamt]]&lt;br /&gt;
&lt;br /&gt;
[[Bild:MP2103stick_schematic_LPC2103.GIF]]&lt;br /&gt;
&lt;br /&gt;
[[Bild:MP2103stick_schematic_USB.GIF]]&lt;br /&gt;
&lt;br /&gt;
[[Bild:MP2103stick_schematic_AT45DBxxx.GIF]]&lt;br /&gt;
&lt;br /&gt;
[[Bild:MP2103stick_schematic_RESET.GIF]]&lt;br /&gt;
&lt;br /&gt;
[[Bild:MP2103stick_schematic_LM317.GIF]]&lt;br /&gt;
&lt;br /&gt;
Der Mikrocontroller benötigt vier Betriebsspannungen:&lt;br /&gt;
&lt;br /&gt;
–	VDD1.8, für den Core an Pin 5 (1,8 Volt)&lt;br /&gt;
&lt;br /&gt;
–	VDD3.3, für dessen Peripherie an Pin 17 und 40 (3,3 Volt)&lt;br /&gt;
&lt;br /&gt;
–	VDDA, für die analogen Komponenten an Pin 42 (3,3 Volt)&lt;br /&gt;
&lt;br /&gt;
–	VBAT, für die Real Time Clock an Pin 4 (3,3 Volt)&lt;br /&gt;
&lt;br /&gt;
Die Core-Spannung wird mit dem LM317 erzeugt und mit den Widerständen R1 und R2 fest eingestellt. Die 3,3 Volt werden im FT232RL erzeugt. VDDA wird über den Widerstand R10 von VDD3.3 bezogen. VBAT wird über die Diode D2 von VDD3.3 oder von einer externen Backup-Batterie versorgt. Die Kondensatoren an den Versorgungsspannungen dienen der Entkopplung von Störsignalen und damit dem sicheren Betrieb des LPC2103. R1! und R2! mit je Null Ohm in den beiden Spannungsversorgungsleitungen VDD1.8 und VDD3.3 dienen dem Schutz des Mikrocontrollers bei Inbetriebnahme des MP2103-Sticks. Sie sollten erst ganz zum Schluss eingelötet werden – erst wenn alle Spannungen überprüft und OK sind.&lt;br /&gt;
Dem Mikrocontroller wird mit dem Quarz Q2 (14,7456 MHz Grundton) sozusagen das Leben eingehaucht. Er erzeugt den Takt für den LPC2103. Durch den Multiplier in diesem kann das System mit bis zu 4 x 14,7456MHz = 58,9824MHz betrieben werden. Der krumme Wert von 14,7456MHz ist einzig und allein für die Kommunikation zum PC über die UART0 und USB von Nöten. Q1 ist ein normaler Uhren-Quarz mit 32KHz für die interne Echtzeituhr.&lt;br /&gt;
An CON1 und CON2 gehen fast alle Pins des Mikrocontrollers. CON1 und CON2 sind im Raster 2,54mm auf der Leiterplatte angeordnet, so dass eine Lochraster-Leiterplatte auf den Stick gesteckt werden kann.&lt;br /&gt;
Die Kommunikation mit einem PC/Labtop erfolgt mit dem seriellen Port UART0 des LPC2103 (Pin 13 und 14)  über den USB-zu-seriell-Umsetzer FT232RL (IC4). Dort gehen die beiden Signale (Leitungen) RXD und TXD gekreuzt an die Pins 1 und 5. Die beiden Handshake-Signale RTS und DTR sind über den Dip-Schalter S2 mit der Reset-Automatik oben rechts verbunden. Die beiden Datenleitungen USBDM (Pin 16) und USBDP (Pin 15) sind direkt mit der USB-B-Buchse (Pin 2 und 3) verbunden. VDD (5 Volt) kommt von Pin 1 der USB-B-Buchse über L1 (Entstörung) und geht an Pin 20 von IC4 und an Pin 16 von CON2 zur Außenwelt. Aus Sicherheitsgründen sind die 3.3 Volt nicht nach außen geführt. Wenn man auf seiner externen Schaltung 3,3 Volt benötigt, kann man dieses sehr einfach mit einem weiteren LM317 mit angepassten Widerständen bewerkstelligen.&lt;br /&gt;
Die Reset-Automatik oben rechts im Schaltplan sorgt bei geöffnetem Dip-Schalter S2 und nicht gestecktem Jumper auf BSL_HAND (BSL = Bootstrap Loader: Urlader) für ein ordnungsgemäßes Starten des Mikrocontrollers im Normalbetrieb. LED1 kann dann in einem Programm als Signallampe benutzt werden. Wird der Jumper BSL_HAND gesteckt geht der Mikrocontroller sofort nach einem Reset-Impuls an Pin 6 in den Bootloader-Modus. Es kann sofort eine Firmware (das Anwenderprogramm) mit einer Programmer-Software hochgeladen werden. Damit man nicht immer bei der Softwareentwicklung diesen Jumper ständig stecken und abziehen muss,  gibt es noch die Programmier-Automatik mittels der beiden Handshake-Leitungen RTS und DTR. Eine Programmer-Software kann diese beiden Leitungen der RS232-Schnittstelle schalten und damit den Mikrocontroller gezielt in den Bootloader-Modus bringen, die Firmware übertragen und anschließend das Programm starten. Der MP2103-Stick muss bei der Softwareentwicklung nicht angefasst werden. Alles geschieht vom PC aus. Im endgültigen Normalbetrieb müssen S2 offen und BSL_HAND nicht gesteckt sein. In welchen Modus der Mikrocontroller geschaltet werden soll entscheidet der Signalpegel an Pin 44 des LPC2103 bei einem Reset-Impuls. High = Normalbetrieb, Low = Bootloader.&lt;br /&gt;
Sehr einfach gestaltet sich die Beschaltung des externen seriellen Flash-Speichers IC2. &lt;br /&gt;
Es können die ICs AT45DB321D-SU (4MB), AT45DB161D-SU (2MB) oder AT45DB081D-SU (1MB) eingelötet werden.  Dieser ist mit der SPI des LPC2103 verbunden. Wichtig ist R3! Er wird nur bestückt wenn der Speicher schreibgeschützt sein soll.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Eagle-Files ==&lt;br /&gt;
&lt;br /&gt;
[[Media:MP2103Stick_v1.0.zip‎|LINK: MP2103Stick_v1.0.zip‎]]&lt;br /&gt;
&lt;br /&gt;
== Mechanische Realisierung ==&lt;br /&gt;
&lt;br /&gt;
Die Leiterplatte sollte von einem Leiterplattenhersteller gefertigt werden. Ich habe die Erfahrung gemacht, dass Anbieter mit Preis-Berechnungen auf Quadratdezimeter-Basis egal mit welchem Inhalt die günstigsten sind. Wichtig ist, dass die Leiterplatten mit Durchkontaktierungen gefertigt werden. Aus Erfahrung rate ich die Leiterplatten mit Lötstopplack fertigen zu lassen. Einfach die Datei „MP03Stick_v1.0.brd“ dem Hersteller schicken.&lt;br /&gt;
&lt;br /&gt;
Board top:&lt;br /&gt;
&lt;br /&gt;
[[Bild:MP03Stick_board_top_klein.GIF]]&lt;br /&gt;
&lt;br /&gt;
Board bottom:&lt;br /&gt;
&lt;br /&gt;
[[Bild:MP03Stick_board_bottom_klein.GIF]]&lt;br /&gt;
&lt;br /&gt;
Stueckliste:&lt;br /&gt;
&lt;br /&gt;
[[Bild:MP2103Stick_Stueckliste.PNG]]&lt;br /&gt;
&lt;br /&gt;
== Bestückung der Leiterplatte ==&lt;br /&gt;
&lt;br /&gt;
Elektronische Bauteile sind durch elektrostatische Ladungen gefährdet. Deshalb ab jetzt mit ESD-Armband und ESD-Unterlage arbeiten!!!&lt;br /&gt;
Beim Arbeiten mit den kleinen Bauteilen hilft auf jeden Fall ein Briefmarken-Lupen-Headset oder ein Stereo-Mikroskop mit Verstärkungsfaktor 10 (bei ebey ca. 200,- €).&lt;br /&gt;
Zuerst die beiden großen ICs, IC3 (LPC2103) und IC4 (FT232RL), bestücken. Da es sich um ziemlich kleine und mit hoher Pin-Anzahl versehene elektronische Bauteile handelt, empfehle ich folgende Vorgehensweise: Die Lötpads auf der Leiterplatte für das entsprechende IC reichlich mit dem Lötkolben und Lötzinn (&amp;lt;= 0,5 mm Durchmesser) verzinnen. Die Lötpads sollten glänzen und um ca. 0,1 bis 0,2 mm erhaben sein. Nun die Leiterplatte mit handelsüblichem Brennspiritus reinigen. Jetzt das IC mit ein wenig Klebstoff auf der Leiterplatte fixieren. Ich nehme dafür handelsüblichen Klebestift (Pr…-Stift). Eine kleine Messerspitze voll vom Klebestift auf die Mitte der IC-Position auf die Leiterplatte auftragen, das IC auf die Leiterplatte aufsetzen und positionieren. Es darf auf keinen Fall Klebstoff bis zu den Lötanschlüssen des ICs quellen. Erst mit dem Festlöten beginnen, wenn das IC korrekt auf den Lötpads sitzt und etwas angetrocknet ist. Ab jetzt wird nicht mehr mit Lötzinn gearbeitet – dieses am besten so weit wie möglich weglegen. Die Kapillarwirkung der IC-Anschlüsse ist viel zu groß, diese würden eine weitere Zugabe von Lötzinn sofort dieses zwischen die Lötpins ziehen und damit für reichlich Kurzschlüsse sorgen. Ab jetzt wird nur noch mit Flussmittel gearbeitet, entweder handelsübliches Flux oder Kolofonium (in Brennspiritus aufgelöst) nehmen. Ist das IC korrekt positioniert und fixiert mit dem Festlöten beginnen. Jeden einzelnen IC-Anschluss mit dem heißen Lötkolben und wenig Druck in Richtung Leiterplatte anlöten. Wichtig ist wirklich, sich damit Zeit zu lassen und darauf zu achten, dass das Lötzinn richtig fließt. Sollte bei einem der hier beschriebenen Arbeitsschritte etwas schief gehen, unbedingt die Arbeiten abbrechen, alles reinigen und von Anfang beginnen. Sind IC3 und IC4 erfolgreich auf die Leiterplatte gelötet können alle anderen Bauteile bestückt und gelötet werden. Wichtig: „R1!“, „R2!“ und „R3!“ nicht bestücken!!! Die voll bestückte Leiterplatte gründlich mit Brennspiritus und einem kleinen Pinsel reinigen. Die Leiterplatte wegen der Buchsen und Schalter/Taster nicht im Reinigungsmittel baden. Das Reinigungsmittel nicht abtrocknen lassen sondern mit Druckluft entfernen. Es werden so unschöne Flecken vermieden. Sollte der Stick in rauer Umgebung betrieben werden ist das Lackieren mit farblosem Leiterplattenlack sinnvoll.&lt;br /&gt;
&lt;br /&gt;
== Optische Prüfung ==&lt;br /&gt;
&lt;br /&gt;
Jetzt sollte eine ausgiebige Fehlersuche auf Kurzschlüsse, kalte Lötstellen, Verpolung von Bauteilen und richtiger Bestückung erfolgen. Entweder mit einer großen Lupe oder einem Stereo-Mikroskop mit Vergrößerungsfaktor 10.&lt;br /&gt;
	&lt;br /&gt;
Alle weiteren Arbeitsschritt erst nach vollständiger Trocknung des Stick durchführen.&lt;br /&gt;
&lt;br /&gt;
== Elektrische Inbetriebnahme ==&lt;br /&gt;
&lt;br /&gt;
Für erste Tests ist es am Besten den Stick mit einem Strom geregelten Netzteil über die USB-Buchse (Pin1 +5V, Pin4 Masse) zu verbinden; den Strom auf 50 mA begrenzen und 5 Volt einstellen. Nach Einschalten sollte ein Strom von ca. 10 bis 20 mA fließen und die anliegende Spannung weiterhin 5 Volt betragen. Bricht die Spannung zusammen auf keinen Fall die Strombegrenzung erhöhen sondern auf Kurzschlusssuche gehen. Fließt zu wenig Strom oder keiner kalte Lötstellen suchen. Ist kein Netzteil vorhanden, einfach drei kleine billige Knopfzellen á 1,5 Volt in Reihe schalten und den Strom mit einem Multimeter messen. Stimmt der Strom und liegen die 5 Volt an, die Spannungen an den Testpunkten TP1 bis TP4 überprüfen. Bezugspunkt ist TPM (Masse). Folgende Spannungen sollten gemessen werden:&lt;br /&gt;
&lt;br /&gt;
TP1 = 1,8 Volt&lt;br /&gt;
&lt;br /&gt;
TP2 = 3,3 Volt&lt;br /&gt;
&lt;br /&gt;
TP3 = 5 Volt (oder 4,5V bei der Variante mit den drei 1,5V Knopfzellen)&lt;br /&gt;
&lt;br /&gt;
TP4 = 3,3 Volt&lt;br /&gt;
&lt;br /&gt;
Wenn diese Spannungen OK sind kann der Stick an den PC/Notebook über ein USB-Kabel angeschlossen werden. Nun sollte das Betriebssystem (Windows, für WinCE, Linux und Mac weiß ich es nicht) melden, dass neue Hardware erkannt wurde. Jetzt kann der Treiber für den FT232RL installiert werden. Den Treiber (Virtual COM Port, VCP) von der [http://ftdichip.com Herstellerseite] downloaden – die Vorgehensweise ist dort ausführlich beschrieben. Nach erfolgreicher Installation des Treibers sollte im Hardwaremanager ein neuer COMx-Port zu sehen sein. Die COM-Nummer sollte man sich merken. Windows registriert für jede USB-Schnittstelle eine andere COM-Port-Nummer, was zu Verwirrung beim Umstecken führen kann. Damit sind aber auch mehrere Sticks anschließbar.&lt;br /&gt;
&lt;br /&gt;
[http://ftdichip.com/Drivers/VCP.htm LINK: die Treiber für den FT232RL]&lt;br /&gt;
&lt;br /&gt;
[http://ftdichip.com/Documents/InstallGuides.htm LINK: Driver Installation Guides]&lt;br /&gt;
&lt;br /&gt;
Sind alle Tests und Arbeitsschritte bis hier OK können die beiden Widerstände „R1!“ und „R2!“ eingelötet werden um den Mikrocontroller mit Strom zu versorgen. Es sollte ein Strom zwischen 20 und 40 mA fließen, wenn nicht: Fehlersuche nach Kurzschlüssen, kalten Lötstellen, verpolten Bauteilen und falscher Bestückung. Sind die beiden Dip-Schalter von S2 offen (nicht auf ON) und der Jumper BSL_Hand gezogen sollte die LED leuchten.&lt;br /&gt;
&lt;br /&gt;
== Firmware Upload ==&lt;br /&gt;
&lt;br /&gt;
Zum Hochladen der Firmware benötigt man das Programm Flash-Magic-Tool.&lt;br /&gt;
&lt;br /&gt;
[http://www.flashmagictool.com/ LINK: Flash Magig Tool]&lt;br /&gt;
&lt;br /&gt;
Die Einstellungen sind folgende:&lt;br /&gt;
&lt;br /&gt;
Unter „Step 1 - Communications“:&lt;br /&gt;
&lt;br /&gt;
Com Port:	der COMx-Port, an dem der MP2103-Stick angeschlossen ist. Im Hardwaremanager nachsehen!&lt;br /&gt;
&lt;br /&gt;
Baud Rate: 115200&lt;br /&gt;
&lt;br /&gt;
Device: LPC2103&lt;br /&gt;
&lt;br /&gt;
Interface: None (ISP) &lt;br /&gt;
&lt;br /&gt;
Oscillator Freq. (MHz): 14.7456&lt;br /&gt;
&lt;br /&gt;
Unter „Step 2 - Erase“:&lt;br /&gt;
&lt;br /&gt;
Ein Hägchen hinter: „Erase all Flash+Code Rd Prot“&lt;br /&gt;
&lt;br /&gt;
Ùnter „Step 3 – Hex File“:&lt;br /&gt;
&lt;br /&gt;
Das Hex-File, welches hochgeladen werden soll.&lt;br /&gt;
&lt;br /&gt;
Unter „Step 4 – Options“:&lt;br /&gt;
&lt;br /&gt;
Hinter „Verify after programming“&lt;br /&gt;
&lt;br /&gt;
Unter Adanced Options im Formular „Hardware Options“ ein Häckchen hinter „Use DTR and RTS to control RTS and P0.14“&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Bild:FlashMagicFlashen.GIF]]&lt;br /&gt;
&lt;br /&gt;
[[Bild:FlashMagicAdvanstOption.GIF]]&lt;br /&gt;
&lt;br /&gt;
Jetzt am Besten erst einmal testen, ob sich der Mikrocontroller meldet. Die beiden Dip-Schalter von S2 müssen auf „ON“ stehen und Jumper „BSL_HAND“ muss gezogen sein. Flash Magic starten, die Einstellungen wie oben und in der Menüleiste „ISP“ den Menüpunk „Read Device Signatur“ anwählen. Der Mikrocontroller muss in dem sich öffnenden Fenster die Divice-ID und die Bootloaderversion liefern. Meldet Magic Flash einen Fehler: Fehlersuche. :O(&lt;br /&gt;
&lt;br /&gt;
[[Bild:FlashMagicReadDeviceSegnature.GIF]]&lt;br /&gt;
&lt;br /&gt;
[[Bild:FlashMagicDeviceSignature.GIF]]&lt;br /&gt;
&lt;br /&gt;
Den Firmware-Upload startet man mit dem Button &amp;quot;Start&amp;quot; unter &amp;quot;Step 5 - Start!&amp;quot; im Falsh Magic. &lt;br /&gt;
&lt;br /&gt;
Ein weiteres Flash-Tool ist das „LPC2000 Flash Utility“ von Philips, welches leider nicht mehr weiterentwickelt wird. Es ist aber in der Auswahl der COM-Ports begrenzt (COM1 bis COM5). Im Geräte-Manager von Windows müssen bei Bedarf Änderungen an der COM-Port-Nummerierung vorgenommen werden. Bis auf diesen Makel ist dieses Tool schnell und unkompliziert.&lt;br /&gt;
&lt;br /&gt;
[http://www.lpctools.com/downloads/LPC2000%20Flash%20ISP%20Utility%20v2.2.3.zip LINK: LPC2000 Flash Utility]&lt;br /&gt;
&lt;br /&gt;
[[Bild:MP2103Stick_LPC2000Flasher.PNG]]&lt;br /&gt;
&lt;br /&gt;
== Testprojekt ==&lt;br /&gt;
&lt;br /&gt;
Hier ein kleines Testprogramm als Basis für eigene Projekte.&lt;br /&gt;
Es lässt die LED blinken und kommuniziert über die serielle Schnittstelle.&lt;br /&gt;
&lt;br /&gt;
[[Media:MP2103-Stick_Test.zip‎|LINK: MP2103-Stick_Test.zip‎]]&lt;br /&gt;
&lt;br /&gt;
Einstellungen im Hyperterminal:&lt;br /&gt;
&lt;br /&gt;
Baud Rate (Bits pro Sekunde): 921600&lt;br /&gt;
&lt;br /&gt;
Einstellungen/Emulation: ANSI&lt;br /&gt;
&lt;br /&gt;
Die genauen Einstellungen befinden sich im Projekt unter MP2103-Stick_921600_baud.ht.&lt;br /&gt;
 &lt;br /&gt;
[[Bild:MP2103_Terminal.GIF]]&lt;br /&gt;
&lt;br /&gt;
Compiliert wird das Projekt mit WinARM oder Yagarto.&lt;br /&gt;
&lt;br /&gt;
[http://www.siwawi.arubi.uni-kl.de/avr_projects/arm_projects/ LINK: WinARM]&lt;br /&gt;
&lt;br /&gt;
[http://www.yagarto.de/ LINK: Yagarto]&lt;br /&gt;
&lt;br /&gt;
== Compiler und IDE (neu) ==&lt;br /&gt;
&lt;br /&gt;
Die Integrierte Entwicklungsumgebung  von Raisonance, Ride7 und RKit-ARM, umfasst einen voll funktionsfähigen und Code unbegrenzten GNU C/C++-Compiler und das Raisonance Integrated Development Environment (RIDE). Über eine grafische Benutzeroberfläche wird die Bedienung der Softwareentwicklungs-Tools (Compiler, Assembler, Linker und Simulator) ermöglicht. Für die Softwareentwicklung und Kompilierung vom C-Source-Code bis hin zum endgültigen HEX-File besteht keine Codegrößenbegrenzung, lediglich das Debugging ist bis 32kByte begrenzt. Das ist aber hier nicht von Belang, da mit dem Bootloader des Mikrocontrollers geflasht wird.&lt;br /&gt;
&lt;br /&gt;
[[Bild:MP2103Stick_Ripe7.PNG]]&lt;br /&gt;
&lt;br /&gt;
Auf der Page von Raisonance.com anmelden und die Files &amp;quot;RKit-ARM&amp;quot; (GCC) und &amp;quot;Ride7&amp;quot; (IDE) downloaden und installieren. Zuerst RKit-ARM dann Ride7. Der Umgang mit diesen Programmen ist super einfach - keine Rumquälerei mit Makefiles und solcherlei Teufelszeug - alles ist bereits Mundgerecht von Raisonance zugeschneidert. Sehr empfehlenswert! Ride7 ist eigentlich nicht für den LPC2103 ausgelegt, aber mit ein wenig Überredungskunst geht dieses auch.&lt;br /&gt;
&lt;br /&gt;
[http://www.mcu-raisonance.com/mcu_downloads.html LINK: Compiler und IDE Ride7 von Raisonance.com]&lt;br /&gt;
&lt;br /&gt;
[http://www.mcu-raisonance.com/tzr/scripts/downloader2.php?filename=T020/file/d8/cd/4datj7g5d1wr&amp;amp;mime=application/pdf&amp;amp;originalname=GettingStartedARM_Ride7.pdf LINK: Getting Started with ARM &amp;amp; Ride7 User manual]&lt;br /&gt;
&lt;br /&gt;
Und wie einfach alles ist zeigt dieses Beipiel-Projekt:&lt;br /&gt;
&lt;br /&gt;
[[Media:MP2103Stick_Hello_World.zip|LINK: Hello-World-Projekt mit Ride7]]&lt;br /&gt;
&lt;br /&gt;
Da in Ride7 kein serielles Upload-Tool für den MP2103-Stick integriert ist, kann zum Hochladen der Firmware (Hello_World.hex) „LPC2000 Flash Utility“ von Philips oder Flash-Magic genommen werden.&lt;br /&gt;
&lt;br /&gt;
== Fazit ==&lt;br /&gt;
&lt;br /&gt;
Es wurde ein kleines Arm7-Mikrocontroller-Board mit beachtlichen Leistungsmerkmalen und sehr geringen Herstellungskosten vorgestellt.&lt;br /&gt;
&lt;br /&gt;
32-Bit-Mikrocontroller 14,7456 bis 58,9824 MHz&lt;br /&gt;
&lt;br /&gt;
32 kByte Flash-ROM&lt;br /&gt;
&lt;br /&gt;
8 kByte RAM&lt;br /&gt;
&lt;br /&gt;
bis zu 4MByte Flash-Datenspeicher&lt;br /&gt;
&lt;br /&gt;
jeder Menge Peripherie&lt;br /&gt;
&lt;br /&gt;
Es kann als Standard-Interface-Modul für den PC eingesetzt werden. Es ist so konzipiert, dass es in ein Gehäuse eingebaut und mit vier M2-Schrauben befestigt werden kann. Auf den beiden Wannensteckerleisten CON1 und CON2 kann ein Tochterboard über zwei 16-polige Pfostenbuchsenleisten mit individueller Elektronik aufgesteckt werden (conrad.de Artikel-Nr.: 738501-62).&lt;br /&gt;
&lt;br /&gt;
Ich stelle mir folgende Einsatzbeispiele vor:&lt;br /&gt;
&lt;br /&gt;
Interface für einen Roboter&lt;br /&gt;
&lt;br /&gt;
Logik-Analysator&lt;br /&gt;
&lt;br /&gt;
Datenlogger für analoge Signale&lt;br /&gt;
&lt;br /&gt;
Oszilloskop&lt;br /&gt;
&lt;br /&gt;
Einsatz in Computer gesteuerten Messgeräten&lt;br /&gt;
&lt;br /&gt;
CNC-Maschinen&lt;br /&gt;
&lt;br /&gt;
usw.&lt;br /&gt;
&lt;br /&gt;
Überall, wo ein Interface für den PC benötigt wird, kann der MP2103-Stick eingesetzt werden. Im Stick laufen nur die Treiber für die Peripherie und eine Transport-Routine für die Rohdaten vom und zum PC - die eigentliche Software läuft auf dem PC.&lt;br /&gt;
&lt;br /&gt;
Übrigens:&lt;br /&gt;
&lt;br /&gt;
Der Board-Computer der Mondlandefähre von Apollo 11, der [http://www.ibiblio.org/apollo/ &amp;quot;Apollo Guidance Computer&amp;quot;], hatte einen 16-Bit-Computer mit 2,048 MHz, 72 kByte ROM und 4 kByte RAM.&lt;br /&gt;
&lt;br /&gt;
[[Category:ARM-Boards]]&lt;br /&gt;
[[Category:USB]]&lt;/div&gt;</summary>
		<author><name>Mthomas</name></author>
	</entry>
</feed>