Home ==> Micro beginner ==> 2. LED on

Lecture 2: Switch a LED on

2.0 Overview

  1. Introduction
  2. Components and mounting
  3. Programming

2.1 Introduction

The first gigantic microcontroller program switches a light emitting diode LED on. We learn here how a program looks like, how it is assembled (translated to the controller's binary language), what comes out of the assembling process and how this is transferred to the controller. We learn much about LEDs and I/O pins and their manipulation.

2.1.1 LEDs

LEDs send light, if current flows through them. So far so good. In a certain area "the more current the more light" applies, but this area is rather limited. There, more current does not emit more light but produces more heat. In the area with small current of a few milli-amperes (mA) the increase in emitted light is the highest, at high currents the increase is not visible any more. The human eye and its sensitivity is anything else but linear so that we cannot really see and realize "more light" and "even more light".

LED voltage Electrically spoken a light emitting diode is a somewhat strange component because its resistance is not constant and diminishes with increasing current (nearly down to zero). That is the reason why LEDs have to be operated with a limited current because they are not able to regulate the current via their resistance. This limited current can be provided by a resistor or an electronic current regulator based on semiconductors.

LED current The value of current limiting resistors can be calculated applying Ohm's law. R = U / I says that the current I increases with the voltage applied linearly. The voltage on the resistor UR is the difference between the operating voltage (e.g. 5 V) and the voltage of the LED ULED (at a given current). At 5.0 V and a LED voltage of 2.1 V the voltage on the resistor is 5.0 - 2.1 = 2.9 V. For a current of 10 mA the resistor should be R = 2.9 / 0.010 = 290 Ohms.

Controller pins as in- and output

Port pins Port internals The controller ATtiny13 has 8 pins of which five can be used as port pins. Those are named PB0 to PB4. Each of those port pins is controlled by two bits in two internal storage places. Those storage places are named DDRB (data direction register port B) and PORTB (data output register port B). The logical state of the port pin can be read via PINB (input register B). Why the port names start with B and not with A is ATMEL's secret. Why they named those storages "registers" is to confuse you a little bit with other internals named registers.

Each of the port pins can be switched to four states (in the following for port pin PB0):
  1. Output driver off (DDB0 = 0), pull-up resistor off (PORTB0 = 0). In this mode the port pin can be used as a high-resistance input pin. The logical state of the pin can be read in PINB0.
  2. Output driver off (DDB0 = 0), pull-up resistor on (PORTB0 = 1). In this mode a resistor of approximately 50 k ties the voltage on the open input pin to the operating voltage of the controller. Externally a switch or push button can overwrite this and pull the input voltage down to zero volts (Ground, GND), the bit PINB0 reflects this level change.
  3. Output driver on (DDB0 = 1), output bit zero (PORTB0 = 0). The pin now is on a very low voltage near the negative operating voltage. The pin can pull down currents of up to 50 mA, with the pin voltage slightly increasing with current.
  4. Output driver on (DDB0 = 1), output bit one (PORTB0 = 1). The pin is on a high voltage slightly below the operating voltage. The pin can drive up to about 30 mA, with slightly decreasing pin voltage.

2.1.2 Controller pins as output

The task to switch on a LED with one of the controller pins can be resolved in two ways:
  1. The pin is configured as output and the output bit in PORTB is set to one. In that case the LED (with its anode) and the resistor are connected to the pin and the cathode side goes to GND. The pin is high and provides current ("source").
  2. The pin is configured as output and the output bit is cleared pulling the output pin to GND. Now the cathode of the LED points to the pin and the resistor is connected with the operating voltage (%quot;sink".
Both cases are different in that, in the first case, the output bit is high, in the second case it is low.
Source and Sink Here both opportunities are shown with the respective voltages at 4.8 V. The output driver transistors of the AVR show a slightly higher voltage difference when soucing. At 10 mA and nearly 5 V operating voltage the difference is not very significant, but increases at higher output currents and smaller operating voltages. Please consult the electrical characteristics chapter in the device databook in those cases.

All outputs can be short-circuited without any damage. If several pins are simultaneously short-circuited, trhe maximum heat power of the AVR can be exceeded. If more than approximately 30 mA have to be driven, consider an external transistor driver.

Home Top Introduction Hardware Programming

2.2 Hardware

LED on port To switch the LED on, the cathode of the LED is connected to PB0 and via a resistor of 220 Ohms to the positive operating voltage. The sink option is selected here, if the output pin is low the LED is on.

The formula to calculate the LED current is also given. The 4.8 V are the battery pack voltage, the 2.1 V the conducting state voltage of the LED (at approx. 10 mA current) and the 0.2 V is the AVR driver voltage in sink mode (at approximately 10 mA and 4.8  operating voltage). Larger currents make no sense because the increase in emitted light cannot be seen. Only if a larger LED is used a higher current is appropriate.

The other parts of the circuit remain the same as in the previous lecture. PB0 is used for two purposes now: for driving the LED and as MISO in the ISP programming mode. That does not cause any conflicts (higher currents might conflict with the ISP programmer!).

Home Top Introduction Hardware Programming

2.3 Components and mounting

2.3.1 Components


LED This is a 5 mm standard-LED. The longer pin is the anode. If mounted in reverse mode: the diode has a Zener voltage break-through at around 16 V.

The 220 Ohm resistor

Resistor 220 Ohm These are two different types of resistors of 220 Ohm. The upper is a carbon film resistor with 5% accuracy, the lower a metal film type with 1% tolerance.

2.3.2 The hardware

LED hardware The mounting of the hardware requires that the cathode of the LED is connected with PB0 (pin 5) of the ATtiny13. The anode is tied to the neighboring empty comlumn. From there the 220 Ohm resistor goes to the plus bar. That is it.

Even under power: nothing happens. The reason is that a native ATtiny13 switches off all his port pins. To switch those ports on, program code has to be executed.

Home Top Introduction Hardware Programming

2.4 Programming

2.4.1 Program storage

To animate the ATtiny13 he has to be programmed. In this case with the two hexdecimal words 9AB8 and 98C0. In binary language (which the controller natively speaks) this corresponds to 1001.1010.1011.1000 and 1001.1000.1100.0000. The useful place for those 32 bits, four bytes or two words is at the beginning of its program storage area (flash), on addresses 0000 and 0001. If you buy a new device (or if you erase the flash area) there is nothing useful there. As a storage cannot be empty (there is always something there), it is filled with hexadecimal FFFF in all those cells. Factually the controller reads the FFFFs, decodes those and executes them. But with the result to do nothing. The same operation happens, if he reads a 0000 from its flash: doing nothing. This operation is called "NOP" or "No operation". NOP by the way is a mnemonic representation for the binary 0000.0000.0000.0000 or hexadecimal 0000. All things that the controller can do (execute instructions) have such a mnemonic, as we will see later on.

The program storage or flash memory of the ATtiny13 has 1024 bytes, into which 512 instruction words fit. That sounds not very large, but in assembler this is a large bunch. Our most complicated program will have several tens of instruction words, and in douzends of projects I never reached the limit of the flash. My stepper motor application had only 141 instruction words, and this has to perform complex timing, counting and AD conversion tasks in parallel. One does definitely not need more if you avoid ineffective C style programming.

2.4.2 Source code

Because binary codes such as 9AB8 and 98C0 are not easy to remember understandable representations have been defined that are easier to remember. In this language the software engineer writes the two lines

	sbi DDRB,DDB0

into a textfile (commented source code file here). From these two lines the assembler, a translation program, generates the two instruction words 9AB8 and 98C0 for the controller.

The abbreviations sbi and cbi are not understandable either, but if you write
	SBI: Set bit DDB0 in I/O port DDB0, the data direction bit of pin
          PB0 (DDB0), to one.
	Clear bit PORTB0 in I/O port PORTB, the data bit of pin PB0, to
That sounds more understandable. With that background knowledge the mnemonics SBI and CBI are memorable.

In assembler, as with the windows filesystem, upper and lower letters are not discriminated. That gives us the opportunity to signal the type of symbols by our own. In the above formulation instructions are in lower letters, symbols in upper letters.

Each line in the source code (e.g. "sbi DDRB,DDB0") is exactly one instruction of the controller. Only those instructions that the central processing unit (CPU) of the controller physically masters have a representing mnemonic. This is specific for assembler: it depends completely from the abilities of the controller. While in other languages instructions can be generated and named by the author (such as subroutines or functions), no such ability is given in assembler. Each line is exactly one physical operation of the controller.

That is the reason why assembler instructions differ only minorly with different dialects. What the CPU understands and handles is not so different. Each CPU can add two binary numbers. In each assembler dialect the mnemonic for this might be different, but the basic processing is virtually the same. Those that have learned AVR assembler might well switch to PIC assembler. All that is to be learned are the slightly different mnemonics (and specific abilities of the CPU). The principle, one mnemonic translates to one CPU operation, remains the same.

2.4.3 To assemble

In the code line "sbi DDRB,DDB0" the type of "sbi" stands for an instruction while "DDRB" and "DDB0" are parameters for this instruction. The first parameter is the data direction port of port B, the second is the bit position in that port to be set to one. The device data handbook for the ATtiny13 says about this:

Port register
DDRB therefore translates to port number 17 (hexadecimal, that is 23 decimal). DDB0 translates to hexadecimal 0 or bit 0. Both parameters stand for numbers. We do not need to remember those numbers if we use the symbol names DDRB and DDB0 instead. Avoid to learn and use the numbers, because in a different device some of those numbers might be different from those in an ATtiny13.

The ports DDRB and PORTB are listed in the device databook as follows:

R/W means that those bits can be read (R) and written (W). The "initial Value" means that this bit will be cleared (0) or set (1) during the reset sequence of the controller.

2.4.4 Writing source code

Notepad with code To write assembler source code one needs a simple text editor. No special software, just an editor that writes ASCII chars to a file. Such as Notepad (under windows, see picture to the left) or KWrite (under linux KDE). And name this text file "somehow.asm", to just better remember what is written in there and for which purpose. Please do not use a textwriter such as Word or OpenOffice to write source code, those do not store plain text and are confusing the assembler with formatting informations.

Studio project Those who want it more comfortable write the source code in the editor window of ATMEL's studio (here: older version 4). First we open a new project, select the name of the project and the source code file and its location.

Studio device Then we select the simulation platform and the device (irrelevant in this case).

Studio source In the editor window to the right we type in the source code.

Lines with a semicolon are comments that are ignored by the assembler. They are only useful for the human reader.

The directive .INCLUDE "tn13def.inc" reads in a file where all symbol representations of numbers for the device type ATtiny13 are defined, in our case the ports DDRB and PORTB and the port bits DDB0 and PORTB0. If we would skip this line, the assembler does not know these symbols and error messages would result. The combination of the directives ".NOLIST" and ".LIST" switches the output in the listing off and on so that the include does not produce output in the listfile. If you leave these two lines out you can see in the listing all symbols that are defined for the ATtiny13.

To ease the recognition the editor of the Studio uses different colors for instructions, parameters, directives and comments. This is called syntax-highlighting.

2.4.5 To assemble

There are many ways to assemble these source code files. Many assemblers are available, I recommend my own command line version, gavrasm. It is available here for download, versions for windows and linux as well as the source code written in fpc-Pascal is available.

gavrasm With gavrasm open a windows command line or a linux bash shell and type two commands. The first command, "cd path to source file", is necessary to introduce the path where the source code file is located. The second command, "[path to gavrasm\]gavrasm.exe -seb source.asm" calls gavrasm to assemble the source code file.

gavrasm done This shows the assembler at work. Finally it comes out with "No errors" and one warning. The warning is that gavrasm knows all symbols of all AVR devices internally and does not read the file "tn13def.inc". That makes this assembler independant from the def.inc files of ATMEL, and it works under Linux or MacOS or whatever operating system. Only gavrasm provides this service. So you can finally ignore the warning.

If you have to assemble the same source code file over and over again it is useful to place these two call into a batch file that can be started by clicking on it. This provides such an example batch file for windows.

Assembling stages gavrasm produced two new files after succesful completion: a listing and a hex file. The files are of the same name as the source but have different extensions: ".lst" and ".hex". Both are simple text files and can be viewed with any simple text editor. The hex file can be used to program the controller's flash memory.

Listing This is the assembler listing. It shows that the sbi instruction translates to hex 9AB8 at address 000000 and cbi to 98C0 at address 000001. The list of symbols in the lower part of the listing (switched on with the -s parameter on the command line) says that only one symbol is defined: the ATtiny13 with a T type is defined once (column nDef), is once used (column nUsed) and has an internal value of decimal 18. Other types of symbols (registers, constants) etc. would occur here if defined and used. This symbol table is only provided by gavrasm, no other assembler has that.

Listing on With the Studio the creation of the listing has to be switched actively on because it is disabled by default.

Hex-Code This is the generated hex code in readable form, in Intel hex format. This provides the naked code with addresses, bytewise coded instruction words and a check byte on each line. We do not have to care about this file, it works with every programmer.

2.4.6 To write the hex code to the program flash storage

Programmer window To transfer the hex file's content to the controller, one has to start the Studio, open the tools section and select "Autoconnect" there. In the tab "Main" we assure that the controller is accessible and of the correct device type. The we go to the tab "Program". There we select the "Input Hex File" by clicking on the small square to the right of the input field. The button "Program" initiates the programming.

The LED is on After some on and off of the LED (the programming pulses) the LED is permanently on. The two code lines finally work and do what they are supposed to do.

Home Top Introduction Hardware Programming

©2017 by http://www.avr-asm-tutorial.net