What is a microcontroller?

Started by R.G., February 25, 2006, 07:12:06 PM

Previous topic - Next topic

R.G.

Let's start simple.

What is a microcontroller (uC)?

It is a full computer, with program memory, data memory, digital decision making engine, and various things that would be called input/output or I/O in any other computer - like the one you're sitting at.

The computer you're sitting at is fundamentally different from the uC though - it's a Harvard architecture instead of a Von Neumann architecture.

... er... what???

The computer you're sitting at has an internal organization of processing (digital decision making) and memory that was first described by John Von Neumann. It has a huge clot of Random Access Memory (that is, you can randomly access any location at any time) which stores both programs and data. The programs are viewed as just another (albeit very special) kind of data, and can be put anywhere in memory, as can any data. This makes the machine very, very flexible. Any part of memory can be used for programs or data at any time, and it can be reprogrammed on the fly. Memory is just one huge chalkboard that can be erased and rewritten at any time, for any purpose.

Harvard architecture was developed - no, not by Mr. Harvard! - at Harvard University, where they thought that programs as opposed to data were special enough to be written only in special program memory. The data that the programs operated on were to be written to data memory, and could never get into program memory. In fact, many versions of Harvard architecture machines the program memory CAN'T be rewritten on the fly.

There's good an bad in both. Von Neumann's architecture won at the general purpose computing game, and all modern computers in the sense of starting and running a flexible set of programs are Von Neumann based. But Harvard architecture won the microcontroller race. Think about it - do you want your car's engine controller to get a virus? Or would you rather it run the same way, first time, every time? The Harvard architecture is fundamentally immune to having data contaminate the control program, so it acts almost like hard-wired logic, but with the advantage of being able to tell the same chip to do many different things, depending on whether you want to run a kitchen blender or an altitude delay fuse in an artillery shell.

So - all modern uC's have a program memory that is different from the data memory.
The data memory holds only those values you are looking at for the moment, and which may change while the program runs. This may be a large number if you're fingers-and-toes based, but it is trivial compared to the amount of data memory in even old, slow, stupid PCs. Some uC's have only 63 data memory bytes - and that's enough for many applications.

The program memory is big, though, comparatively. Most uC's have 1K to many K of program memory. Again, that sounds trivial when you're running a personal computer with half a billion bytes of RAM, but how complicated do you want your blender to act? The big deal is, program memory is separate from data memory.

You write the program memory with your program, and when the machine's power comes on, it starts executing it, and never stops - until it hits a bug or your program tells it to, anyway.

The processing, program memory and data memory sit isolated from the outside world by a network of switches that start, stop, redirect, and enable digital bits into and out of the purely digital portion of the chip. The outside world only sees the external parts - that being the actual pins of the physical package. For instance, a very common beginner version of the PIC has an 18 pin package. The pins are connected inside to latches (i.e. memory flip flops), output drivers, and the onboard I/O devices. The I/O devices include timers, counters, A/D converters, comparators, PWM generators, interrupt generators, clocks, etc. There is a very important part of the programming of any uC that sets up the mapping (that is, the connection paths) between pins, which is all the world can see, and the internal I/O, and then on to the processing/memory.

It is one of the wonders of uC's that the digital pins may be used very flexibly. They are usually assigned a pin direction - that is, an input or an output; they can be either, or may be flipped back and forth between input for one operation and output for another. They are also assigned to the I/O modules in the chip, such as assigning pin 6 to the input to the internal counter, or pin 8 to the "external interrupt".

In your programming, you have to decide which pins do what in your external circuit; you also have to use the datasheets of the uC chips to figure out which pins CAN do that, as unfortunately only certain pins can connect to certain I/O modules, and which pins are purely digital I/O, and are manipulated directly by the processing engine.

So there are effectively four layers to a uC: the inner-most layer of the processing engine, with program and data memory; the internal I/O modules, which can do specific jobs independently of the processing engine; the interconnect or mapping layer which sets up what I/O is active, what pieces connect to what, and which pins go where; and finally the pins themselves, which talk to the outside world.

Done properly, you can define which pins do which external function, how they are connected to which I/O's internally, and what the control program does with those inputs/outputs.

Questions?

R.G.

In response to the questions in the forum - PCB Layout for Musical Effects is available from The Book Patch. Search "PCB Layout" and it ought to appear.

bioroids

It's pretty clear for me, I think. You explained the Von Newman/Harvard stuff much better than my teachers at the university ...

So I/O pins don't have a fixed function per se, you have to assign them to the internal modules you need for the particular program? Are there specific assembler instructions for making the conections, or how do you do to set them? Finally, this is the way uC in general work or only PICs?

Thanks a lot!

Miguel
Eramos tan pobres!

The Tone God

Quote from: bioroids on February 25, 2006, 08:32:33 PM
So I/O pins don't have a fixed function per se, you have to assign them to the internal modules you need for the particular program?

Most modern uC's pins can be general I/O pins meaning high/low output/input. Some older processors have pins that can only do one or the other. Also some processors will some times not allow a pin to be one function due to hardware/functional limitation. For example the reset pin of a uC will not be capable of being an output as it always need to be an input in case a hardware reset has to be initiated. Be aware by reading the datasheet to be sure.

Along with general I/O most processors have extra features like A/D, PWM, bus drivers, etc. Usually these extra hardware features when enabled are tied to a specific pin and cannot be moved around.

Quote from: bioroids on February 25, 2006, 08:32:33 PM
Are there specific assembler instructions for making the connections, or how do you do to set them?

Inside a uC is a set of control registries. Think of these as switches that control various functions of the processor. One of the registries will be control the data direction of the I/O pins.

Quote from: bioroids on February 25, 2006, 08:32:33 PM
Finally, this is the way uC in general work or only PICs?

This applies to most uC PICs and AVRs included.

Andrew

Peter Snowberg

Very nice descriptions R.G. 8)

Quote from: bioroids
So I/O pins don't have a fixed function per se, you have to assign them to the internal modules you need for the particular program?

It depends on the chip  you are talking about. Many microcontrollers have wonderful internal peripherals like serial interfaces or A/D converters. These chips generally give you the choice of using the internal peripheral, or using the pin as a general I/O pin which may be used as input, output, or a combination of the two. When you have to communicate with another device by manually making pins high or low and manually checking other pins, the process is called "bit banging".

With a chip like the early PIC16C57, there were no internal peripherials and you have to do all I/O under program control. You can emulate a lot of hardware when you have the resources of a PIC or other RISC microcontroller.  


Quote from: bioroids
Are there specific assembler instructions for making the connections, or how do you do to set them?

Once you solder the pin to other hardware, you define the pin functions in your program. In the start of your program is usually where you tell the chip which pins are inputs and which are outputs. Many chips include a selectable "pull-up" resistor that will make sure a pin with nothing connected is set to a 1. That makes adding something like a pushbutton really easy. Connect the pin to the switch and connect the other side of the switch to ground. Turn on the pull-up and the input will read 1 unless the button is pressed.

Reading a pin is a matter of loading data from an address, just like you were reading a value out of memory.

Writing to an I/O pin is the same. The physical pin is mapped to a bit of memory somewhere and you store a 0 or a 1 there depending on whether you want ground or V+ to appear on that pin.

Most chips have instructions that test or manipulate a single bit without disturbing the rest of the bits in that byte.


Quote from: bioroids
Finally, this is the way uC in general work or only PICs?
The most common chips at this point are probably the PIC, AVR, ARM, and 8051 families.

The 8051 is a holdover from the world of poor design of  the 1970s. For some reason it gained market force which is somewhat sad. I really hate coding for this chip. This is really the first microcontroller to make it big. It had a little brother called to 8048 which was just as bad, but it ended up running zillions of keyboards around the world. New versions have come along from lots of companies with all kinds of improvements, but these chips are from the days of pre-RISC. These are more like Von-Neumann architecture chips. The program is unchangeable but it shares the same memory space with the data memory.

PICs were the first RISC-like microcontrollers. RISC is short for Reduced Instruction Set Computer and the basic idea is that you can do lots of little things quickly and easily while complex things take more effort and are slower. RISC chips reduce the amount of silicon used and up the speed by huge amounts. This is what those Harvard egg-heads dreamed up. It's a very cleaver idea and it ended up winning the uC race as R.G.> pointed out.

AVRs are also Harvard RISC family architecture chips. They were designed to be really quick and to run compiled C programs very efficiently. These chips came along later and have a number of advances included in comparison to the early PICs. AVRs come in a very wide range of sizes and have wonderful capabilities.

The ARM is the newest microcontroller family of the three, but the ARM architecture has been around in the form of RISC microprocessors for over 20 years. In England there was a company called Acorn Computers that made machines based on the 6502 which is just a wonderful 8 bit microprocessor. They wanted a more advanced processor to move into the 16 bit world but nobody had a 16 bit chip with the efficiency of friendliness of the 6502, so Acorn set out to design one. By 1985 they had a fantastic design running but it never took off as a desktop CPU. It was however great for lots of other embedded tasks because it was low power and fast. They continued to refine them as the 80s went on. Apple computer was making lots of 6502 machines for many years too and they also had interest in a fast chip with 6502 like characteristics. In 1990 Acorn spun off the project as a new company called "Advanced RISC Machines". They put out the ARM610 which was at the heart of Apple's Newton PDA, and they kept advancing the design. The next step in the architecture was called the ARM7. An extension to the ARM7 architecture is called ARM7TDMI, or ARM Thumb for short. This extension allows 16 bit program code to make use of what would normally be 32 bit instructions while saving lots of program space. The ARM Thumb is at the heart of a lot of higher end embedded uses. It's a dual-core ARM7 that powers the iPod.



As a side note, John Von Neumann also brought us cellular automata, pieces of quantum mechanics, math used for financial modeling, and he co-invented the concept of implosion for atomic weapons which he then helped to implement with the design of the explosive lens system.  http://en.wikipedia.org/wiki/John_von_Neumann
Eschew paradigm obfuscation

R.G.

QuoteSo I/O pins don't have a fixed function per se, you have to assign them to the internal modules you need for the particular program?
Most I/O pins on most uCs have multiple functions which are selectable by writing to the internal control switches. The pins can be assigned to be input, output, or the input to one or more peripherals if the design is such that that peripheral works on that pin. The assignments can be changed on the fly, although that gets into some tricky programming to do.

Pin 6 may be part of I/O port B (in the PIC, since I'm doing this from my own internal memory...), or may be assigned to the external interrupt, or may be part of either the internal synchronous serial port or asynchronous serial port. It can only do one of these at a time.

This leads to a point worth making. Your thinking in programming is often dominated by whatever you have least of. In uCs, you tend to be very, very limited in the number of external signals you can use because the number of pins is limited. Thinking long and hard about how to do things with fewer pins is generally the order of the day because the innards are often faster and more capable than you need, but you need just one more signal pin. So the elegant, efficient use of pins is paramount. They're assignable to a greater or lesser extent depending on which chip you use. So assign them wisely.


QuoteIt depends on the chip  you are talking about.
It does, very. The onboard I/O modules usually have a certain pin or pins that do their functions to the outside world if and only if (1) you have that I/O subsection enabled and properly set up inside the chip by means of your programming and (2) you have set the outside pin direction to the correct direction.

By way of example, the PIC family has members with eight to ten bit A/D modules. These modules may have a multiplexerfront end on them so they can read and convert several inputs. However, to read any analog voltage at a pin at all, you must (a) internally enable (turn on) the A/D converter (2) set the I/O pin to "input" direction and (3) have external circuitry carrying in the analog voltage of interest. Further, the number of pins which may be used as inputs varies from family member to member, and there are internal settings which control whether one, two, or more pins are analog inputs. This is all highly specific to the chip you're actually using.

Other I/O devices can only use one predetermined pin for their function; the external interrupt pin on the 18pin PICs is pin 6, no ifs, ands or buts. And external interrupts only work if you set the bit in the register to turn them on internally, and set the pin direction to input so the pin can sense what the outside world is doing.

Again - many layers. There is the internal processing core, a layer of I/O devices that may or may not be enabled, and may or may not be connected to "their" I/O pin, and then the pin direction to be set.
QuoteWith a chip like the early PIC16C57, there were no internal peripherials and you have to do all I/O under program control.
Dead correct. It was the early experiences with such chips that made designers figure out that integrated peripherals were Really Clever things to do. And they've been picked up by most (all? don't know.) modern uCs.

It seems obvious to me that in the future the assignability of pins will be enhanced. The advantage is too great. While the typical device today can't remap any I/O pin to any internal connection, I think that someday they will - if we keep using uCs anyway. The advantage is huge. Today we live with some assignabilty and some special cases.

QuoteOnce you solder the pin to other hardware, you define the pin functions in your program.
Yes, in simple use. No in more sophisicated use. For instance, I have a function I dreamed up where I use the same pin to read a footswitch and to drive an LED that indicates the state of the internal latch that represents the footswitch. I actually flip the pin from output (driving the LED) to input (reading the switch) and back to output (driving the LED) fast enough that it appears to humans that the footswitch controlls the LED, when they're actually on the same pin. In fact, the LED looks like the footswitch is an alternate action, when in fact it's a momentary type. But that's not the kind of stuff beginners should do. It took me an afternoon to get that to work right.

In the larger sense, yes, once you solder a pin to external parts, you have restricted the range of things it can do. You may flip all of its programmable inside connections around, using the same pin for digital I/O and analog input, for instance, if the outside circuitry is such that it cooperates. But the outside circuitry does limit what the pin can do.
QuoteThe 8051 is a holdover from the world of poor design of  the 1970s. For some reason it gained market force which is somewhat sad.
As I remember those dark, dizzy days, the 8051 was a cheaper subvariant of the 8080; I know that's where the high order address latch comes from. The first microprocessor on a chip was the 4004, barely more sophisticated than the 555; then the 8008, and its upgrade, the 8080; at the same time, the 6502 was born and begat Apple. Shortly afterward, the 8086 got into the IBM PC, and the world changed. Apple refused to open its architecture, and what was probably a much more sensible platform got left in the dust while Bill Gates got rich... oh, sorry, I'm raving.

The 8051 is truly an ugly, dark, twisted thing to program. It's the most available monument to how far people will go to NOT give up the microprocessor they've used before.
Quote
Reading a pin is a matter of loading data from an address, just like you were reading a value out of memory.
Writing to an I/O pin is the same. The physical pin is mapped to a bit of memory somewhere and you store a 0 or a 1 there depending on whether you want ground or V+ to appear on that pin.
Most chips have instructions that test or manipulate a single bit without disturbing the rest of the bits in that byte.
Dead correct.


R.G.

In response to the questions in the forum - PCB Layout for Musical Effects is available from The Book Patch. Search "PCB Layout" and it ought to appear.

SeanCostello

Quote from: Peter Snowberg on February 25, 2006, 09:25:43 PM

[PICs]... It's a very cleaver idea and it ended up winning the uC race as R.G.> pointed out.

Really? I thought that about half of all uCs out there were 8051-derived.

Quote from: Peter Snowberg on February 25, 2006, 09:25:43 PM
The ARM Thumb is at the heart of a lot of higher end embedded uses. It's a dual-core ARM7 that powers the iPod.

Fairly OT: I remember back in the year 2000, when my company (Staccato Systems at the time) was doing work for a small company called Portal Player. Portal Player was based around the idea of having hardware MP3 decoders, which I thought was stupid, as your personal computer didn't need acceleration for these files, and who would want a portable MP3 decoder? Portal Player went on to create the custom ARM7-based chipset that powers every iPod. So, the moral of the story is, I have horrible business instincts.

I think that I might have designed some of the EQ presets for the iPod, though. Our company wrote fixed point EQ code for Portal Player, and I voiced up the EQ presets for the code we delivered (you know - "Pop," "Classical," "Hip-Hop"). Does anyone use the EQ on those things?

Sean Costello

bioroids

Wow, those are very enlightening replies. Now I got more questions  :icon_rolleyes:

When a I/O pin is set for example as a simple output, not assigned to any peripheral module, it outputs a value corresponding to a certain I/O register, right?

Is this a digital value (hi/low state depending if the register is 0 or 1) or an analog value (the register is 8-bit so it can range from 0 to 255, then the output pin has a voltage proportional to this number)?

That was a silly question... checking the datasheet for ATtiny13 seems like the output is digital, as it has six pins that form a 6-bit I/O port (port B), so I assume each pin can have just high/low value. So, for example, to output an LFO waveform I would have to use the six pins connected to a DAC. Now I can use just 4 or 5 of these pins right, freeing the rest for other functions?

Then some of these pins can be used as inputs to a 4-channel ADC. Now it seems obvious that the input to an ADC has to be analog, so I could have any of these inputs hooked to a pot acting as a voltage divider, and obtain in some I/O register a value proportional to the voltage at the pot's wiper. If the ADC is four channel it means 4 independent A/D conversions, so I could have up to 4 controlling potentiometers? Of course, I couldn't use the same ports as outputs unless I use some tricky programming as R.G. did with the momentary footswitch/led thing.

Does this ramblings make any sense?

Thanks!

Miguel
Eramos tan pobres!

Peter Snowberg

Good questions.

QuoteWhen a I/O pin is set for example as a simple output, not assigned to any peripheral module, it outputs a value corresponding to a certain I/O register, right?

Correct.


QuoteIs this a digital value (hi/low state depending if the register is 0 or 1) or an analog value...

It's digital. Each bit can only be in the state of 0 or 1. There are chips with internal D/A converters, but they're not anywhere near as common as chips with A/Ds.


Quotechecking the datasheet for ATtiny13 seems like the output is digital, as it has six pins that form a 6-bit I/O port (port B), so I assume each pin can have just high/low value. So, for example, to output an LFO waveform I would have to use the six pins connected to a DAC. Now I can use just 4 or 5 of these pins right, freeing the rest for other functions?

There are multiple ways to do D/A. If you have lots of extra pins you can make what's called a "resistor ladder" D/A which is cheap, but you need lots of pins and a good amount of circuit board space. Another way to add D/A is with PWM or Pulse Width Modulation. The idea there is that you can output a very high frequency digital signal with a duty cycle that changes instead of a variable analog voltage. Once you run that PWM signal through a little low-pass filtering (often a single resistor and cap) you get an analog value. The downside of PWM is that it can add noise to the rest of the circuit and it can't make signals that change very quickly because of the time constant of the RC filter. The final way is to use an outboard DAC chip. TI makes zillions of DACs and most of them connect via 2 to 4 wires, a couple of which can be used for talking to multiple chips. The communications between the uC and DAC are in digital, much like the serial port on a computer talking to a modem. The standard interface protocols are called I2C (pronounced eye-squared-see) which was from Philips and SPI from Motorola. They are also known generically as 2-wire and 3-wire interfaces. It takes more effort to work with these external chips, but uCs are fast and they don't care. :)


QuoteThen some of these pins can be used as inputs to a 4-channel ADC. Now it seems obvious that the input to an ADC has to be analog, so I could have any of these inputs hooked to a pot acting as a voltage divider, and obtain in some I/O register a value proportional to the voltage at the pot's wiper. If the ADC is four channel it means 4 independent A/D conversions, so I could have up to 4 controlling potentiometers? Of course, I couldn't use the same ports as outputs unless I use some tricky programming as R.G. did with the momentary footswitch/led thing.

Correct. If you have more analog sources than A/D pins and you also have left-over digital pins, you can use those digital pins to drive a MUX like the 4051 which will give you 8 analog inputs by using a single analog input on the uC and three digital outputs. There are a bunch of MUX chips out there and squeezing the most functions into the least space is a standard part of embedded systems engineering.


You have great questions, Miguel. 8)
Eschew paradigm obfuscation

bioroids

Thanks Peter!

I'm trying to digest all this and the ATtiny13 datasheet. Right now I'm a little dizzy but when I get my hands on the code and the programmer all the pieces should take its place like in a tetris game ;).

So, if I understand correctly the state on the I/O pins correspond to a BIT on the I/O register, not a byte. It is not clear still why would I want 64 bytes of I/O memory if one byte is more than enough for that. Probably it would have to do with the peripheral functions.

Thanks again

Miguel
Eramos tan pobres!

Peter Snowberg

Quote from: bioroids
So, if I understand correctly the state on the I/O pins correspond to a BIT on the I/O register, not a byte. It is not clear still why would I want 64 bytes of I/O memory if one byte is more than enough for that. Probably it would have to do with the peripheral functions.

The ATtiny13 has 64 bytes of RAM for general use, 64 bytes of EEPROM, and 32 registers which are like bytes of RAM, but they're used for passing data around inside your programs. The 64 memory locations that control I/O are separate from these other memory spaces.

Look at page 157 of the datasheet:
http://www.atmel.com/dyn/resources/prod_documents/doc2535.pdf

The registers that control the pins are mapped from 0x14 to 0x18.  :icon_biggrin:

Eschew paradigm obfuscation

bioroids

You are right ;)

So the I/O registers includes all sort of configuration bits and CPU flags, only a few of those make sense to me now (but that's ok). I suppose this is where you set the behaviour of the peripherals, as T.T.G. explained.

The confusing part is that, even if they are physically separated, the general purpose registers, the I/O registers and the SRAM memory form a unified logical memory map. So, when accessing the I/O port you refer to the I/O register 0x18, but you can also refer to it as memory address 0x38. (I would have put the I/O at location 0x00 instead of the general purpose registers).

But this was supposed to be a more general thread. This is referring to the AVR stuff. I suppose PICs may be (or may be not) organized differently.

Thanks again

Miguel
Eramos tan pobres!

phaeton

I was reluctant at first to even consider getting involved with the DSP stuff.

After reading this thread (and a few others) I gotta say this stuff is so damn cool! :icon_mrgreen:  The way you guys (the "mentors", as usual, we all know who I'm talking about) lay it all out like this, it's pretty easy eat up.  It's not quite as complicated as I thought it might be.

The only unfortunate thing is that as I muse and let my imagination ramble, I'm coming up with all kinds of uses and projects for uCs that aren't in the least bit guitar/audio/amplification related.

Good? Bad? Ugly?  Who knows.

Thanks, regardless.  :D
Stark Raving Mad Scientist

R.G.

I personally love PICs. I view them as my personal Christmas chips.

If I want a countdown timer - grab a $2.00 PIC. If I want an elapsed time meter? PIC. If I want a device to count how many times and for how long my air conditioner runs and what the outdoor temperature is when it cycles - yep, PIC.

If I want  an hours-on meter and number of cycles counter for my well pump - you guessed already.

Really, about anything that you can define well enough to do that the PIC has enough raw speed to do only costs a few hours of programming. It won't do digital delays or native DSP - yet...
R.G.

In response to the questions in the forum - PCB Layout for Musical Effects is available from The Book Patch. Search "PCB Layout" and it ought to appear.