CPU Support Devices Programming Intel
CPU Support Devices Programming Intel
CPU Support Devices Programming Intel
Intel 8254
• Compatible with All Intel and Most other Microprocessors
• Handles Inputs from DC to 10 MHz
8 MHz 8254
10 MHz 8254-2
• Single a 5V Supply
system design.
Functional Description
• After the desired delay, the 8254 will interrupt the CPU.
are:
• Event-counter
• Digital one-shot
Protothreads are extremely lightweight stackless threads designed for severely memory constrained
systems, such as small embedded systems or wireless sensor network nodes. Protothreads provide
linear code execution for event-driven systems implemented in C. Protothreads can be used with or
without an underlying operating system to provide blocking event-handlers. Protothreads provide
sequential flow of control without complex state machines or full multi-threading.
Protothreading is a way of performing what would normally be a multitasking operation on (doing two
or more things at once or at different intervals) on an Arduino. In other words, it's "multithreaded"! But
hold on there Sparky, the Arduino is a single-core chip with procedural code, so true multithreading is
impossible. Why though? How is protothreading any different?
To understand protothreading properly, we first need to understand why it's NOT really multithreading.
Remember back in the day when Intel was selling us this new "Hyperthreading" thing on Pentium
processors? No? You weren't born yet? Well time for a history lesson then, son! Hyperthreading is a
technology Intel employs to make a single core on a processor "act" like it's two cores, or two cores
"act" like they're 4 cores, etc. But why, and how is that relevant to Arduino? The answer is cycles.
Both Microcontrollers and CPUs do work in "cycles". How fast they do them (how many in a second) is
the clock rate. You've seen a CPU's Ghz rating, and you probably know it relates to how fast it is. The
more Ghz, the better, right? but why? Because that's the number of cycles per second a processor can
achieve (without overheating and catching on fire - really!).
If you're a datasheet nerd, you might know that the Arduino Uno's microprocessor chip, the Atmel
ATMega328P, runs at 16Mhz out of the box. It's capable of 20Mhz, but is dialed back so it won't mess up
things like writing data to memory (or, you know, catch fire). 16Mhz means every second, your Arduino
is processing 16,000,000 cycles, aka doing 16 million pieces of work. Now, these are NOT lines of code -
that'd be blazingly fast and Arduino is relatively slow. These are processor instructions such as moving
data in and out of registers. Going lower level than this overview get's fairly technical so I'll leave that as
an exercise to the reader, but that's the gist :)
So, if we can only go so fast on a core before the best chip available catches fire, are we stuck at that
speed forever? Is that the fastest we can do work? As it turns out, no! Enter multicore CPUs, and
multithreading. On a computer CPU, multithreaded applications are two separate processes that work in
parallel to one another on different cores of a CPU. These processes interact to get work done together,
but don't necessarily split the work evenly as you might assume. There is typically a main process /
"thread" that functions as a manager of the other threads, and then one or more worker threads it
manages, which each might do specific tasks. A good example is Chrome. Chrome is the manager of all
your web page tabs (threads), but because chrome is multithreaded, each tab is its' own little program.
That means not only can it run faster if you have several cores to distribute each tab across, it also has
other benefits like not crashing the entire browser when one tab crashes. This is the first reason
Protothreading is not multithreading - we only have one core to work with on an MCU, so traditional
multithreading is straight up impossible. We need to manage work on only a single core, but still do
multiple things at once. We need protothreading.
INTERRUPTS
interrupts()
[Interrupts]
Description
Re-enables interrupts (after they’ve been disabled by nointerrupts(). Interrupts allow certain important
tasks to happen in the background and are enabled by default. Some functions will not work while
interrupts are disabled, and incoming communication may be ignored. Interrupts can slightly disrupt the
timing of code, however, and may be disabled for particularly critical sections of code.
Syntax
interrupts()
Parameters
Nothing
Returns
Nothing
Example Code
void setup() {}
void loop()
noInterrupts();
interrupts();
TIMER
delay()
[Time]
Description
Pauses the program for the amount of time (in milliseconds) specified as parameter. (There are 1000
milliseconds in a second.)
Syntax
delay(ms)
Parameters
Returns
Nothing
Example Code
The code pauses the program for one second before toggling the output pin.
void setup()
void loop()
}
Notes and Warnings
While it is easy to create a blinking LED with the delay() function, and many sketches use short delays for
such tasks as switch debouncing, the use of delay() in a sketch has significant drawbacks. No other
reading of sensors, mathematical calculations, or pin manipulation can go on during the delay function,
so in effect, it brings most other activity to a halt. For alternative approaches to controlling timing see
the millis() function and the sketch sited below. More knowledgeable programmers usually avoid the
use of delay() for timing of events longer than 10’s of milliseconds unless the Arduino sketch is very
simple.
Certain things do go on while the delay() function is controlling the Atmega chip however, because the
delay function does not disable interrupts. Serial communication that appears at the RX pin is recorded,
PWM (analogWrite) values and pin states are maintained, and interrupts will work as they should.
delayMicroseconds()
[Time]
Description
Pauses the program for the amount of time (in microseconds) specified as parameter. There are a
thousand microseconds in a millisecond, and a million microseconds in a second.
Currently, the largest value that will produce an accurate delay is 16383. This could change in future
Arduino releases. For delays longer than a few thousand microseconds, you should use delay() instead.
Syntax
delayMicroseconds(us)
Parameters
Returns
Nothing
Example Code
The code configures pin number 8 to work as an output pin. It sends a train of pulses of approximately
100 microseconds period. The approximation is due to execution of the other instructions in the code.
void setup()
void loop()
This function works very accurately in the range 3 microseconds and up. We cannot assure that
delayMicroseconds will perform precisely for smaller delay-times.
micros()
[Time]
Description
Returns the number of microseconds since the Arduino board began running the current program. This
number will overflow (go back to zero), after approximately 70 minutes. On 16 MHz Arduino boards (e.g.
Duemilanove and Nano), this function has a resolution of four microseconds (i.e. the value returned is
always a multiple of four). On 8 MHz Arduino boards (e.g. the LilyPad), this function has a resolution of
eight microseconds.
Syntax
time = micros()
Parameters
Nothing
Returns
Returns the number of microseconds since the Arduino board began running the current
program.(unsigned long)
Example Code
The code returns the number of microseconds since the Arduino board began.
void setup(){
Serial.begin(9600);
void loop(){
Serial.print("Time: ");
time = micros();
There are 1,000 microseconds in a millisecond and 1,000,000 microseconds in a second. millis()
[Time]
Description
Returns the number of milliseconds since the Arduino board began running the current program. This
number will overflow (go back to zero), after approximately 50 days.
Syntax
time = millis()
Parameters
Nothing
Returns
Example Code
The code reads the milllisecond since the Arduino board began.
Serial.begin(9600);
void loop(){
Serial.print("Time: ");
time = millis();
Please note that the return value for millis() is an unsigned long, logic errors may occur if a programmer
tries to do arithmetic with smaller data types such as int’s. Even signed long may encounter errors as its
maximum value is half that of its unsigned counterpart.
GPIO
Analog Input Pins
A description of the analog input pins on an Arduino chip
(ATmega8, ATmega168, ATmega328P, or ATmega1280).
A/D converter
The ATmega controllers used for the Arduino contain an onboard 6 channel (8 channels
on the Mini and Nano, 16 on the Mega) analog-to-digital (A/D) converter. The converter
has 10 bit resolution, returning integers from 0 to 1023. While the main function of the
analog pins for most Arduino users is to read analog sensors, the analog pins also have all
the functionality of general purpose input/output (GPIO) pins (the same as digital pins 0 -
13).
Consequently, if a user needs more general purpose input output pins, and all the analog
pins are not in use, the analog pins may be used for GPIO.
Pin mapping
The analog pins can be used identically to the digital pins, using the aliases A0 (for
analog input 0), A1, etc. For example, the code would look like this to set analog pin 0 to
an output, and to set it HIGH:
pinMode(A0, OUTPUT);
digitalWrite(A0, HIGH);
Pull-up resistors
The analog pins also have pull-up resistors, which work identically to pull-up resistors on
the digital pins. They are enabled by issuing a command such as
Be aware however that turning on a pull-up will affect the values reported by
analogRead().
The ATmega datasheet also cautions against switching analog pins in close temporal
proximity to making A/D readings (analogRead) on other analog pins. This can cause
electrical noise and introduce jitter in the analog system. It may be desirable, after
manipulating analog pins (in digital mode), to add a short delay before using
analogRead() to read other analog pins.
Soruces:github.com,arduino.cc,stackexchange.com.intel.com