Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

CPU Support Devices Programming Intel

You are on page 1of 15

CPU support devices programming

Intel 8254
• Compatible with All Intel and Most other Microprocessors
• Handles Inputs from DC to 10 MHz

8 MHz 8254

10 MHz 8254-2

• Status Read-Back Command

• Six Programmable Counter Modes

• Three Independent 16-Bit Counters

• Binary or BCD Counting

• Single a 5V Supply

• Standard Temperature Range

• The Intel 8254 is a counter/timer device designed to solve

the common timing control problems in microcomputer

system design.

• It provides three independent 16-bit counters, each capable

of handling clock inputs up to 10 MHz.

• All modes are software programmable. The 8254 is a

superset of the 8253.

• The 8254 uses HMOS technology and comes in a 24-pin

plastic or CERDIP package


fig.1 pin config

Fig2 block diagram

Functional Description

• The 8254 is a programmable interval timer/counter

designed for use with Intel microcomputer systems.

• It is a general purpose, multi-timing element that can be

treated as an array of I/O ports in the system software.


• The 8254 solves one of the most common problems in any

microcomputer system, the generation of accurate time

delays under software control. Instead of setting up timing

loops in software, the programmer configures the 8254 to

match his requirements and programs one of the counters

for the desired delay.

• After the desired delay, the 8254 will interrupt the CPU.

Software overhead is minimal and variable length delays

can easily be accommodated.

• Some of the other counter/timer functions common to

microcomputers which can be implemented with the 8254

are:

• Real time clock

• Event-counter

• Digital one-shot

• Programmable rate generator


• Square wave generator
• Binary rate multiplier
• Complex waveform generator
• Complex motor controller
This is an Arduino Compatible board. ... The Arduino Uno is
a microcontroller board based on the ATmega328 (datasheet).
It has 14 digital input/output pins (of which 6 can be used as
PWM outputs), 6 analog inputs, a 16 MHz ceramic resonator, a
USB connection, a power jack, an ICSP header, and a reset
button.
You can not run multi threads on an arduino.

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.

How to "Multithread" an Arduino (Protothreading Tutorial

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?

"Real" Multithreading vs Protothreading

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.

Ok, how is Protothreading different then?

Protothreading is very simillar to that Hyperthreading thing I mentioned, to an extent. Hyperthreading


would emulate a second core and literally divide the work one core is doing by pretending to be two
virtual cores. This worked because they really existed on the same core and thus shared the same
resource space. Since the arduino MCU doesn't support hyperthreading, we're not able to do that here.
Protothreading is similar, except that in place of CPU cycles and instructions, we can break work down
by the 'loops' or 'lines' of code being executed by our sketch. As you might imagine, if we're doing more
stuff, loops would take longer, so each project will have vastly different 'loops per second'. There are
different implementations of protothreading, and the one I use here is admittedly probably shoddy, but
it works. Basically, each loop we don't have other work to do, we do some less-demanding or less-
frequent work in the main loop (or nothing at all). When we're not busy, we're checking to see if it's
time to do one of those other pieces of work yet. If so, we branch off and go do it. It's important to note
that actions that are "blocking", meaning they must complete all at once without interruption and thus
tie up the MCU for a period of time (such as reading data off an SD card and a few other tasks) will still
block other protothreads from occurring "on time", but for simple things like two loops going at once
performing quick actions like variable changes or changing output values, it will work superbly. This is
more or less what we'll be doing here. Some MCUs support a real-time operating system (RTOS) that can
provide more hyperthreading-like multitasking abilities which can help mitigate problems caused by
"blocking" tasks.

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

The code enables Interrupts.

void setup() {}

void loop()

noInterrupts();

// critical, time-sensitive code here

interrupts();

// other code here

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

ms: the number of milliseconds to pause (unsigned long)

Returns

Nothing

Example Code

The code pauses the program for one second before toggling the output pin.

int ledPin = 13; // LED connected to digital pin 13

void setup()

pinMode(ledPin, OUTPUT); // sets the digital pin as output

void loop()

digitalWrite(ledPin, HIGH); // sets the LED on

delay(1000); // waits for a second

digitalWrite(ledPin, LOW); // sets the LED off

delay(1000); // waits for a second

}
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

us: the number of microseconds to pause (unsigned int)

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.

int outPin = 8; // digital pin 8

void setup()

pinMode(outPin, OUTPUT); // sets the digital pin as output

void loop()

digitalWrite(outPin, HIGH); // sets the pin on

delayMicroseconds(50); // pauses for 50 microseconds

digitalWrite(outPin, LOW); // sets the pin off

delayMicroseconds(50); // pauses for 50 microseconds

Notes and Warnings

This function works very accurately in the range 3 microseconds and up. We cannot assure that
delayMicroseconds will perform precisely for smaller delay-times.

As of Arduino 0018, delayMicroseconds() no longer disables interrupts.

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.

unsigned long time;

void setup(){

Serial.begin(9600);

void loop(){

Serial.print("Time: ");
time = micros();

Serial.println(time); //prints time since program started

delay(1000); // wait a second so as not to send massive amounts of data

Notes and Warnings

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

Number of milliseconds since the program started (unsigned long)

Example Code

The code reads the milllisecond since the Arduino board began.

unsigned long time;


void setup(){

Serial.begin(9600);

void loop(){

Serial.print("Time: ");

time = millis();

Serial.println(time); //prints time since program started

delay(1000); // wait a second so as not to send massive amounts of data

Notes and Warnings

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

pinMode(A0, INPUT_PULLUP); // set pull-up on analog pin 0

Be aware however that turning on a pull-up will affect the values reported by
analogRead().

Details and Caveats


The analogRead command will not work correctly if a pin has been previously set to an
output, so if this is the case, set it back to an input before using analogRead. Similarly if
the pin has been set to HIGH as an output, the pull-up resistor will be set, when switched
back to an input.

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

You might also like