Announcement

Collapse
No announcement yet.

The uController demystified

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • The uController demystified

    This first post is a table of contents with links to the uController intros.
    Please don't post here, as this thread is intended for intros only, so it can be a fast lookup reference.

    For questions / comments, please post in this thread:

    http://www.energeticforum.com/renewa...html#post80463

    Please scroll down for the table of contents.

    Foreword

    For many the the inner workings of a micro controller is close to black magic.

    In the following posts I will attempt to demystify what's going on.

    I will do a basic introduction here, and suggest some pages to read in the data sheet or application notes.

    Data sheet for the ATtiny84:
    http://www.atmel.com/dyn/resources/p...ts/doc8006.pdf

    This way the subject will be divided in digestible slices, so all can join in.

    The intros will cover general info about uControllers AND offer hands-on training.

    To what use is theory, if it is never put to work ?

    I'm also aware that many are hesitant to try making SW, so the first intros will focus on how to make the SUI (Simple User Interface) PCB, and the SPS (Simple Power Stage).

    I have tied to keep the cost low, so it is affordable for many to make.

    It will be shown how simple it is to program a binary file into the uController.

    When the HW has been soldered, programmed and tested, the you will be ready to do a range of experiments, without having to bother how to design the electronics.
    By use of a LCD display and some buttons, you can change the parameters of the experiment application, e.g. frequencies and pulse widths.

    I am also aware many may from prejudice say, "the PCBs has surface mounted components, that is too difficult for me".

    I am sure that if you think this way, then you will never be able to make a PCB set, as you would never even get started.
    But if you follow my instructions with an open mind, you can. Mind over matter


    Table Of Contents:


    Intros:

    #1 What is a byte, how do you count and calculate ? The basic properties.
    http://www.energeticforum.com/renewa...html#post80465

    #2 List of HW development tools. What do you need ?
    http://www.energeticforum.com/renewa...html#post80661

    #3 uC PORT pin Input/Output basics.
    http://www.energeticforum.com/renewa...html#post81262

    #4 - uC memories.
    http://www.energeticforum.com/renewa...html#post81699

    #5 [Pending] Using the timer for PWM output.

    Eric
    Last edited by Tecstatic; 01-20-2010, 02:35 AM. Reason: Added intro #4

  • #2

    Intro #1 - The basic properties.


    The PC you use now to read this, is probably a 32-bit microprocessor, while the AVR family uControllers are all 8-bit.

    But what is a Byte ? A byte is 8 bits, and a bit is represented by a voltage level, here < 1.5V is a logic "0", while
    > 3V is a logic "1", valid for a 5 V Vcc. The voltage between 1.5V and 3V only occurs shortly while switching logic level.
    This is how you should interpret a logic voltage on a uC pin.

    Chapter 20 in the data sheets defines the electrical properties of the micro controller.

    As there are only two possible states of a bit in a computer, it is also called a digital computer, (opposite to analog).

    The reason it is called a micro controller and not a microprocessor is that it contains all necessary stuff in one IC, FLASH memory, EEPROM memory, RAM memory, timers with PWM outputs, communication, ADC converter and more.

    This will be explained in the following intro posts.


    Some Byte properties:


    So a Byte consists of 8 digital digits.

    In the decimal number system we count 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 and then 0 with one added to next digit: 10.

    We increase the number till we reach the base (10) minus 1 (9), then we add 1 to the next digit and start with zero again.

    A digital number has the base 2, so counting to 17 is like this

    Code:
    base-2, base-16, base-10 
    
    00000	0		0		
    00001	1		1
    00010	2		2
    00011	3		3
    00100	4		4
    00101	5		5
    00110	6		6
    00111	7		7
    01000	8		8
    01001	9		9
    01010	A		10
    01011	B		11
    01100	C		12
    01101	D		13
    01110	E		14
    01111	F		15
    10000  10		16
    10001  11		17
    
    As seen a base 16 number is represented by 4 bits, 
    so 1 Byte is represented by 2 base-16 digits
    
    
    Some simple digital calculations:
    
    
    1-complement:  To take the 1-complement of a digital number, 
    simply invert all bits.
    
    1100->0011
    
    2-complement: to take the 2-complement of a number, 
    take the one complement and add 1
    
    0001->1110->1111
    Taking the 2-complement of a number is the same as changing the sign, here from 1 to -1.

    We can interpret the 8 bits as an unsigned number (all >=0 ) or signed (both - and + numbers). I use the type U08 for the unsigned 8 bits and I08 for the signed 8 bits.

    so
    U08 represents the numbers 0..255.
    I08 represents the numbers -128..127

    So if I declare a variable to be used for some computing,

    U08 x;
    I08 y;

    Then x can be assigned a number in the range 0..255.
    Y can be assigned a number in the range -128..127


    Besides the above calculations, also AND, OR, EXCLUSIVE OR can be calculated, some examples:

    Code:
        11011111
    AND 00100101
    is  00000101
    
        10011111
    OR  00100101
    is  10111111
    
        11011110
    EOR 00100100
    is  11111010
    In words:

    AND: If the same bit position in the two bytes both are "1" the the result is "1", else it is "0".

    OR: If a bit is set in one of the two bytes the result is "1" else "0".

    EOR: If a bit position in the two bytes are not the same, the result is "1", else it is "0"

    There are more bit manipulating instructions which greatly supports both calculations and I/O to/from the port pins of the uC.

    Also addition, subtraction and multiplication can be done by the assembler instructions of the uC.

    The above has 1-cycle instructions to be calculated, except the multiplication, which is 2 cycles.
    A clock cycle at 20MHz clock is 50ns. Quite nice for a 2$ device

    There is no division instruction. Division is done by a small program of several instructions.

    This concludes intro #1.

    Eric
    Last edited by Tecstatic; 01-11-2010, 11:00 PM.

    Comment


    • #3

      INTRO #2, List of HW development tools.


      Tools needed to assemble the SUI + SPS PCBs:
      • Temperature controlled solder iron with 0.8mm tip.
        Fine solder 0.3mm.
        "Ordinary" 0.7mm solder.
        Solder wick (desolder).
        Pincet for holding the components during soldering.
        Young eyes, alternatively lamp with magnifying glass, or head mounted magnifying glasses (my favourite).

        A 12V battery or 12V DC power supply.
        A voltmeter.
        a logic "pencil" where a sound indicates logic "0" and "1". (nice to have)
        An oscilloscope. (nice to have)

      And of cause the bare board PCBs and components:
      1 to 3 hours to assemble (solder on the components).


      Tools needed to program the uC:

      One of two programmers is needed:

      1 ATMEL AVRISP programmer or compatible clone, cost down to 20-40$, you can also build one yourself, search the net.
      2 ATMEL AVR Dragon, cost approx. 80$

      Search string "AVRISP" or "AVR Dragon".

      If you never expect to do changes in a source program and need to debug, buy #1.

      If you would like also to make some changes to a program and need to debug the changes, buy #2

      At this cost level I will not give links where to buy, as package and postage can be a large percentage of the cost, if you don't buy locally.
      Sometimes there are really good bargains on eBay for the display and also the simple programmer.

      Remember the ready to program binaries allow you to change the parameters interactively using the SUI, e.g. frequencies, pulse widths.

      In addition you need a PC, a USB cable and the "avrdude" or "avarice" programs installed, more on this subject later.

      Just to get the idea of what to do for programming the uC chip:
      • 1 Connect the 6-wire flat cable between the programmer and the SPS ISP (In System Programming) connector.
        2 Connect the programmer to the PC using the USB cable.
        3 Download the binary file for your application, e.g. sm.bin
        4 Apply 12V to the SPS input power connector
        5 In a command window issue the command: avrdude <options> sm.bin or avarice <options> sm.bin
        6 Wait less than 30 seconds, and the uC has been erased, programmed and verified.

      Then according to an application schematic, you connect your experiment to the SPS PCB, set the jumpers correctly.

      Now apply power and use the SUI to tune your experiment.

      You can always download and program one of the other application binary files (as they become available) for doing other experiments.

      This concludes intro #2.

      Eric

      Comment


      • #4
        Intro #3 - uC PORT pin Input/Output basics


        Intro #3 - uC PORT pin Input/Output basics



        Electric properties of the AVR uC port.


        The AVR family is special regarding the port pin drive capability.

        Many other controllers can sink/source 4mA per pin, and have a few "high current" pins driving 8mA.

        The AVR port pins can all sink/source 20mA (absolute maximum rating 40mA), there is a limitation though, the sum of the port pin currets is not allowed to exeed 200mA.

        This high current drive capability can eliminate use of external buffers in many cases.


        Logic functionality of the AVR port:


        Any ordinary port pin on a member of the avr family can be configured like this:
        • High impedance input.
        • High impedance input with an internal 100kohm pull-up resistor.

        • Output with sink/source capability.
        • Output with sink only capability. (like open collector)

        • Output with source only capability.


        How to setup the ports


        The AVR micro controller has 32 8-bit working registers named r0..r31.

        And it has 3 registers to control a port, lets use PORTA as an example.
        • DDRA

        • PINA

        • PORTA


        PINA is an input register which present the logic levels on the pins of PORT a sampled by the processor clock.

        Regardless of a port is configured as input or output PINA allways reflects the sampled port pin logic state.

        This means that the instant level at the port pins are latched into the PINA register by the uC I/O clock.

        So if you write an assembler instruction to read the pins of port A into r0, you write in assembler

        Code:
        IN	r0,PINA
        
        or in C++
        
        U08 my_input;
        
        my_input = PINA;
        But wait, as it can be both input and output, it must be configured to be input first.

        For that we have the data direction register DDRA:

        If all bits in the DDRA is 0, then all pins are inputs.
        If all bits in the DDRA is 1, then all pins are outputs.


        So if DDRA = 0x01 that means all pins are input except PA0.

        Note the 2 new notations:

        0x01 is the way we write the value of an 8-bit value in hexadecimal (base 16), in base 2 it is 0000 0001.

        The port pins are named with the port name and a number, so the pins of port A is named PA7..PA0.

        Note: Never leave an input pin floating, tie it with the internal 100kohm resistor if unconnected. Floating inputs can (will) result in oscillations increasing the current consumption of the uC.


        The last control register is named PORTA.

        It has a special function for the input pins: If a input pin must have the 100kohm internal pull-up resistor, then the PORTA bit must be set.

        So if we want PA7 to have pull-up, the we can write 0x80 to PORTA (1000 0000).


        Setting ordinary output with sink/source for PA0 we write

        Code:
           DDRA  = 0x01; // set port A pin 0 as output 
           PORTA = 0x00; // sets logic level "0" on PA0
           PORTA = 0x01; // sets logic level "1" on PA0
        Note: "//" makes the rest of that line a comment

        But wait a minute, we just configured PA7 to have pullup, and now we wrote bit 7 as "0" so PA7 no longer has pull-up, thats no good.

        But luckily we have our logic operations we can put to use, so instead we write:

        Code:
           DDRA  = DDRA  | 0x01; // set port A pin 0 as output 	
           PORTA = PORTA & 0xFE; // sets logic level "0" on PA0
           PORTA = PORTA | 0x01; // sets logic level "1" on PA0
        Note:
        "&" is the AND operator
        "|" is the OR operator


        Writing in C++ we are a bit lazy and write it this way:

        Code:
           DDRA  |= 0x01;  // set port A pin 0 as output 
           PORTA &= ~0x01; // sets logic level "0" on PA0
           PORTA |= 0x01;  // sets logic level "1" on PA0
        Note the "~" is the 1-complement operator (inverts all bits) so 0xFE is equal to ~0x01.

        This way we only touch PA0 and let the remaining pins keep their values unchanged.



        Using a port pin (PA0) as "open collector"


        Code:
           DDRA  &= ~0x01; // set port A pin 0 as input 
           PORTA &= ~0x01; // prepares for logic level "0" on PA0
        
           DDRA |= 0x01;  // sets logic level "0" on PA0, "open collector transistor on"
           DDRA &= ~0x01; // sets logic level "1" on PA0, "open collector transistor off" 
                          //   assuming external pull up resistor.
        In the second line we actually enable the internal 100kohm resistor. But choosing lower impedances, this is insignificant.


        Using a port pin (PA0) as "open source"


        Code:
           DDRA  &= ~0x01;// set port A pin 0 as input 
           PORTA |= 0x01; // prepares for logic level "1" on PA0
        
           DDRA |= 0x01;  // sets logic level "1" on PA0, "open source transistor on" 
           DDRA &= ~0x01; // sets logic level "1" on PA0, "open source transistor off"
                          //   assuming external pull down resistor.
        In the last two examples we either operate in input mode, so an external resistor determines the pin level.
        Or we set the port as output thus letting the pre-set value in PORTA determine the PA0 pin value.

        Besides this basic port functionality, most port pins can instead be used for special functions for the internal peripherals, e.g as a PWM output pin or maybe as a UART input pin. more about that in a later intro.

        For further reading, read chapter 10, "IO ports" in the data sheet, 14 pages with illustrations.

        Other more advanced uC has configurable switching speed. The switching speed can then be reduced so radio interference can be reduced.

        Designing the PCB right, many PCBs can without cabinet fulfill the authorities limits on noise emissions, but usually this requires 4 or 4+ layer PCBs

        This concludes intro #3.

        For questions / comments:
        http://www.energeticforum.com/renewa...html#post80463

        Eric

        Comment


        • #5
          Intro #4 - uC memories.


          Intro #4 - uC memories.


          Note: The first post in this thread is kept up to date with a table of contents and links.


          The AVR family of micro controllers has FLASH program memory from 1Kbyte (1024 Bytes = 512 16-bit words) up to 384KByte. But this is just numbers, how can you relate to this ?

          Let me say you have to program at least a week to fill 16KByte of program memory, excluding the standard libraries. maybe you can spend 2 months to do that.

          Don't worry about this, as I (and maybe others) intend to do the programming work of some of the basic applications, so you just have to download a binary file and program the uC in less than 5 minutes.

          The tiny84 has space for 4096 16-bit instructions.
          A programmer can typically make 20 tested and OK statements per day, just assuming a statement has 10 instructions on average, that accounts for 10 days of fully effective programming work.

          So using up the program memory of a 384 KByte uC requires a lot of programming work, maybe unless you use it for data tables.

          The RAM range is from 32 Bytes RAM to 32KByte RAM.

          The EEPROM is from 0 byte to 4KBytes.

          Now the different type og memory is discussed:


          FLASH memory for program storage.


          The instructions for executions are stored in FLASH memory.

          This memory keeps its contents without supply voltage for a very long time, maybe more than 20 years.

          The FLASH memory can be reprogrammed approx. 10.000 times. then it wears down. but that is a lot of reprogramming. Imagine your programming work is so that you as an average program the uC for each 10 minutes. Then it would take approx. 1 work year to wear the uC FLASH memory down.

          When compiling a source program, the compiler and linker prepares a binary file to load into the FLASH memory. This is the binary file I have mentioned before.

          You can also put data into the program memory this way:

          Code:
          // a simple array of byte data stored in FLASH memory
          #include <progmem.h>
          
          U08 my_constant_data[ 4 ] PROGMEM = { 2, 4, 8, 10 };

          EEPROM memory for data storage.


          The EEPROM memory (Electrically Erasable Programmable Read Only Memory) has the same property of being non-volatile like the FLASH memory. In addition it can accept 100.000 writes before wearing down, 10 times more than FLASH.

          The EEPROM is typically used for individual setup data and maybe data as a result of some adaptive algorithm.

          Code:
          // a simple array of byte data stored in EEPROM memory
          #include <eeprom.h>
          
          U08 my_constant_data[ 4 ] EEMEM = { 2, 4, 8, 10 };

          RAM memory for storing variables in the running program.


          Unlike the FLASH and EEPROM memories the RAM (Random Access Memory) is volatile, it looses the data when power is lost.

          But it has the ability of a virtually unlimited number of write cycles without wearing down.

          The uC has two RAM areas: the 32 internal working registers and the data RAM.

          The working registers are fast:

          Code:
             ADD r0,r1   // Add r1 to r0 and store the result in r0, 1 clock cycle
          When e.g. the tiny84 runs at 20MHz, one cycle is 50ns.

          In that time r0 and r1 are read and presented to the ALU (Arithmetic Logic Unit) which adds the numbers and writes the result back to r0. All in one cycle.

          Moving data from the data RAM to the working registers typically takes 2 cycles.

          A typical program executes 15 to 18E6 instructions per second (18.000.000), not bad for a $2 IC.

          Writing a program like this:

          Code:
          U08 my_ram_data[ 4 ] = { 2, 4, 8, 10 };
          The data is stored in RAM, so be careful with this, as large amounts of data uses up the RAM space leaving too little for the program. Remember to use PROGMEM like shown above.

          The tiny 84 Memories:
          8Kbytes of program memory
          512 bytes of EEPROM
          512 bytes of RAM
          32 bytes of working registers.

          For further reading about the memories, read the data sheet chapter 5 (9 pages).

          This concludes intro #4.

          Please don't post in this thread, for questions / comments use:
          http://www.energeticforum.com/renewa...html#post80463

          Eric

          Comment

          Working...
          X