You are on page 1of 91

B.

amil ZDEN Serkan TARIN


Department of Mechanical Engineering
Middle East Technical University
ME407
Microcontrollers & Arduino
Seminar
Note: This material is adopted from
Dr. Kokus ME 461 Lecture Notes
2
Outline
Development Procedure
Hardware
Software
Preprocessor Commands
Arduino Example Functions
Serial Port
Digital I/O Ports
Motor Drive (Step, Servo)
ADC
PWM
Misc. functions
ME407 Microcontrollers&Arduino
Seminar
3
Hardware Test / Development
Procedure

Build the basic PIC circuit on the breadboard.
Keep everything tidy.
Make sure to keep all leads as short as possible.
Pay attention to electrolytic capacitors:
Their polarities are marked on their packages.

Before powering up, double-check all connections
and voltage polarities.
Connect your circuit to the serial port of your computer.

ME407 Microcontrollers&Arduino
Seminar
4
Hardware Test / Development
Procedure
Make sure that the power supply is disconnected
from your circuit and turn the power supply on and
make sure that voltage is set around 7-9 Volts.

Turn the power supply off, connect your circuit on,
and turn the supply back on.

Keep your eye on the current indicator, and if you
suspect that the circuit draws too much current,
immediately turn the supply off.

Make sure to check the supply voltage of the
PICmicro: V
dd
= 4.5V to 5.5V (at most).
ME407 Microcontrollers&Arduino
Seminar
Programming PIC via
Programmer
Basic
Code
*.bas
PIC Basic
Compiler
compile
Program the PIC
PC
RS232
Parallel port
USB
PIC
PIC Programmer
Hex Code
*.hex
download
PIC Programmer
Software
5 ME407 Microcontrollers&Arduino
Seminar
6
Programming PIC via
Bootloader
C
Code
*.c file
PIC
Compiler
compile
Download program
to the PIC
PC
RS232
PIC with bootloader
previously programmed
Hex Code
*.hex
download
PIC Programmer
Software
a. b. koku METU ME
Lectures
ME407 Microcontrollers&Arduino
Seminar
Booting the Loader
By default the bootloader
runs at each program start

If the a download attempt is
detected, the program is
read from the PC and loaded
into the PICs program area,
and it will be executed

If no download attempt is
detected, last loaded
program will be executed.
7
Program Memory
Free Memory
User Program
Bootloader code
ME407 Microcontrollers&Arduino
Seminar
8
CCS C Compiler
The CCS C compiler, which is developed by
Customer Computer Services (CCS), supports
almost all devices you can find in the market:
PIC12x
PIC16x
PIC18x
Compiler is quite compatible with ANSI C.
Quality of compiled code is very good.
The optimizer does a good job in compressing the
code.
ME407 Microcontrollers&Arduino
Seminar
Bit / Byte
ME407 Microcontrollers&Arduino
Seminar
9
10
CCS C
Data types used in CCS C:
int1 and short defines a 1-bit number
int8 or int defines an 8-bit number (byte)
int16 and long defines a 16-bit number
int32 defines a 32-bit number
char defines a 8-bit character
float defines a 32-bit floating point number
ME407 Microcontrollers&Arduino
Seminar
Analog / Digital
ME407 Microcontrollers&Arduino
Seminar
11
ARDUINO Uno General View
ME407 Microcontrollers&Arduino
Seminar
12
Microcontroller ATmega328
Operating Voltage 5V
Input Voltage (recommended) 7-12V
Input Voltage (limits) 6-20V
Digital I/O Pins 14 (of which 6 provide PWM output)
Analog Input Pins 6
DC Current per I/O Pin 40 mA
DC Current for 3.3V Pin 50 mA
Flash Memory
32 KB (ATmega328) of which 0.5 KB used
by bootloader
SRAM 2 KB (ATmega328)
EEPROM 1 KB (ATmega328)
Clock Speed 16 MHz
ARDUINO Uno Power
ME407 Microcontrollers&Arduino
Seminar
13
The Arduino Uno can be powered via the USB connection or with an external power
supply

VIN. The input voltage to the Arduino board when it's using an external power
source (as opposed to 5 volts from the USB connection or other regulated power
source). You can supply voltage through this pin, or, if supplying voltage via the
power jack, access it through this pin.

5V. This pin outputs a regulated 5V from the regulator on the board. The board can
be supplied with power either from the DC power jack (7 - 12V), the USB connector
(5V), or the VIN pin of the board (7-12V). Supplying voltage via the 5V or 3.3V pins
bypasses the regulator, and can damage your board. We don't advise it.

3V3. A 3.3 volt supply generated by the on-board regulator. Maximum current draw
is 50 mA.

GND. Ground pins.

ARDUINO Uno I/O
ME407 Microcontrollers&Arduino
Seminar
14
Each of the 14 digital pins on the Uno can be used as an input or output,
using pinMode(), digitalWrite(), and digitalRead()functions. They operate
at 5 volts. Each pin can provide or receive a maximum of 40 mA.

Serial: 0 (RX) and 1 (TX). Used to receive (RX) and transmit (TX) TTL serial data.
These pins are connected to the corresponding pins of the ATmega8U2 USB-to-
TTL Serial chip.

External Interrupts: 2 and 3. These pins can be configured to trigger an interrupt
on a low value, a rising or falling edge, or a change in value. See
the attachInterrupt() function for details.

PWM: 3, 5, 6, 9, 10, and 11. Provide 8-bit PWM output with
the analogWrite() function.

ME407 Microcontrollers&Arduino
Seminar
15
ARDUINO Uno I/O
The Uno has 6 analog inputs, labeled A0 through A5, each of which
provide 10 bits of resolution (i.e. 1024 different values). By default they
measure from ground to 5 volts, though is it possible to change the upper
end of their range using the AREF pin and the analogReference()
function
Getting Started with ARDUINO
1 | Get an Arduino board and USB cable
2 | Download the Arduino environment (http://arduino.cc/en/Main/Software)
3 | Connect the board
4 | Install the drivers
5 | Launch the Arduino application
6 | Open your code
7 | Select your board
8 | Select your serial port
9 | Upload the program

ME407 Microcontrollers&Arduino
Seminar
16
Getting Started with ARDUINO
ME407 Microcontrollers&Arduino
Seminar
17
4 | Install the drivers
Plug in your board and wait for Windows to begin it's driver installation
process. After a few moments, the process will fail, despite its best efforts
Click on the Start Menu, and open up the Control Panel.
While in the Control Panel, navigate to System and Security. Next, click on
System. Once the System window is up, open the Device Manager.
Look under Ports (COM & LPT). You should see an open port named
"Arduino UNO (COMxx)"
Right click on the "Arduino UNO (COmxx)" port and choose the "Update
Driver Software" option.
Next, choose the "Browse my computer for Driver software" option.
Finally, navigate to and select the Uno's driver file,
named "ArduinoUNO.inf", located in the "Drivers" folder of the Arduino
Software download (not the "FTDI USB Drivers" sub-directory).
Windows will finish up the driver installation from there.
If needed step by step installation link: http://arduino.cc/en/Guide/UnoDriversWindowsXP
Getting Started with ARDUINO
ME407 Microcontrollers&Arduino
Seminar
18
5 | Launch the Arduino application
6 | Open your code
Getting Started with ARDUINO
ME407 Microcontrollers&Arduino
Seminar
19
7 | Select your board
Getting Started with ARDUINO
ME407 Microcontrollers&Arduino
Seminar
20
8 | Select your serial port
Getting Started with ARDUINO
ME407 Microcontrollers&Arduino
Seminar
21
9 | Upload the program
Simply click the "Upload" button in the environment. Wait a few seconds - you
should see the RX and TX leds on the board flashing. If the upload is
successful, the message "Done uploading." will appear in the status bar.
For more information visit http://arduino.cc/en/Guide/Windows
Other Arduinos
ME407 Microcontrollers&Arduino
Seminar
22
Arduino Mega 2560
Arduino Motor Shield
Arduino Micro
Arduino WiFi Shield
Arduino Proto Shield
Arduino Libraries
ME407 Microcontrollers&Arduino
Seminar
23
Standard Libraries
EEPROM - reading and writing to "permanent" storage
Ethernet - for connecting to the internet using the Arduino Ethernet Shield
Firmata - for communicating with applications on the computer using a standard
serial protocol.
LiquidCrystal - for controlling liquid crystal displays (LCDs)
SD - for reading and writing SD cards
Servo - for controlling servo motors
SPI - for communicating with devices using the Serial Peripheral Interface (SPI) Bus
Arduino Libraries
ME407 Microcontrollers&Arduino
Seminar
24
SoftwareSerial - for serial communication on any digital pins. Version 1.0 and
later of Arduino incorporate Mikal Hart's NewSoftSerial library as SoftwareSerial.
Stepper - for controlling stepper motors
WiFi - for connecting to the internet using the Arduino WiFi shield
Wire - Two Wire Interface (TWI/I2C) for sending and receiving data over a net of
devices or sensors.

More info at: http://arduino.cc/en/Reference/Libraries
References: http://arduino.cc/en/Reference/HomePage
Arduino Code Basics
ME407 Microcontrollers&Arduino
Seminar
25
The setup() function is called when a sketch starts. Use it to initialize variables,
pin modes, start using libraries, etc. The setup function will only run once, after
each powerup or reset of the Arduino board.
loop() function does precisely what its name suggests, and loops consecutively,
allowing your program to change and respond as it runs. Code in
the loop() section of your sketch is used to actively control the Arduino board.

void setup() {
// put your setup code here, to run once:
}
void loop() {
// put your main code here, to run repeatedly:
}

Arduino Code Basics
ME407 Microcontrollers&Arduino
Seminar
26
const int buttonPin = 3;

// setup initializes serial and the button pin
void setup() {
Serial.begin(9600);
pinMode(buttonPin, INPUT);
}

// loop checks the button pin each time,
// and will send serial if it is pressed
void loop() {
if (digitalRead(buttonPin) == HIGH)
Serial.write('H');
else
Serial.write('L');
delay(1000);
}
Arduino Code Examples -1
ME407 Microcontrollers&Arduino
Seminar
27
To build the circuit, attach a 220-ohm resistor to pin 13. Then
attach the long leg of an LED (the positive leg, called the
anode) to the resistor. Attach the short leg (the negative leg,
called the cathode) to ground.
http://fritzing.org/
/ *
Bl i nk
Tur ns on an LED on f or one second, t hen
of f f or one second, r epeat edl y.

Thi s exampl e code i s i n t he publ i c
domai n.
*/

/ / Pi n 13 has an LED connect ed on most
Ar dui no boar ds.
/ / gi ve i t a name:
i nt l ed = 13;

Arduino Code Examples -1


ME407 Microcontrollers&Arduino
Seminar
28
/ / t he set up r out i ne r uns once when you pr ess r eset :
voi d set up( ) {
/ / i ni t i al i ze t he di gi t al pi n as an out put .
pi nMode( l ed, OUTPUT) ;
}

/ / t he l oop r out i ne r uns over and over agai n
f or ever :
voi d l oop( ) {
di gi t al Wr i t e( l ed, HI GH) ; / / t ur n t he LED on
( HI GH i s t he vol t age l evel )
del ay( 1000) ; / / wai t f or a second
di gi t al Wr i t e( l ed, LOW) ; / / t ur n t he LED of f by
maki ng t he vol t age LOW
del ay( 1000) ; / / wai t f or a second
}
Arduino Code Examples -2
ME407 Microcontrollers&Arduino
Seminar
29
Anal og Read Seri al
This example shows you how to read analog input
from the physical world using a potentiometer (10k
ohm)
The Arduino has a circuit inside called an analog-to-
digital converter that reads this changing voltage
and converts it to a number between 0 and 1023.
In between, analogRead() returns a number between
0 and 1023 that is proportional to the amount of
voltage being applied to the pin.

Arduino Code Examples -2
ME407 Microcontrollers&Arduino
Seminar
30
Anal ogReadSer i al
Reads an anal og i nput on pi n 0, pr i nt s t he r esul t t o t he ser i al moni t or .
At t ach t he cent er pi n of a pot ent i omet er t o pi n A0, and t he out si de pi ns t o
+5V and gr ound.

Thi s exampl e code i s i n t he publ i c domai n.
*/

/ / t he set up r out i ne r uns once when you pr ess r eset :
voi d set up( ) {
/ / i ni t i al i ze ser i al communi cat i on at 9600 bi t s per second:
Ser i al . begi n( 9600) ;
}

/ / t he l oop r out i ne r uns over and over agai n f or ever :
voi d l oop( ) {
/ / r ead t he i nput on anal og pi n 0:
i nt sensor Val ue =anal ogRead( A0) ;
/ / pr i nt out t he val ue you r ead:
Ser i al . pr i nt l n( sensor Val ue) ;
del ay( 1) ; / / del ay i n bet ween r eads f or st abi l i t y
}
Arduino Code Examples - 3
ME407 Microcontrollers&Arduino
Seminar
31
Fading
Demonstrates the use of analog output (Pulse Width Modulation (PWM)) to fade
an LED. PWM is a technique for getting an analog-like behavior from a digital
output by switching it off and on very fast.
Code

/ *
Fadi ng

Thi s exampl e shows how t o f ade an LED usi ng t he
anal ogWr i t e( ) f unct i on.

The ci r cui t :
* LED at t ached f r omdi gi t al pi n 9 t o gr ound.

*/
Arduino Code Examples - 3
ME407 Microcontrollers&Arduino
Seminar
32
i nt l edPi n = 9; / / LED connect ed t o di gi t al pi n 9

voi d set up( ) {
/ / not hi ng happens i n set up
}

voi d l oop( ) {
/ / f ade i n f r ommi n t o max i n i ncr ement s of 5 poi nt s:
f or ( i nt f adeVal ue = 0 ; f adeVal ue <= 255; f adeVal ue +=5) {
/ / set s t he val ue ( r ange f r om0 t o 255) :
anal ogWr i t e( l edPi n, f adeVal ue) ;
/ / wai t f or 30 mi l l i seconds t o see t he di mmi ng ef f ect
del ay( 30) ;
}

/ / f ade out f r ommax t o mi n i n i ncr ement s of 5 poi nt s:
f or ( i nt f adeVal ue = 255 ; f adeVal ue >= 0; f adeVal ue - =5) {
/ / set s t he val ue ( r ange f r om0 t o 255) :
anal ogWr i t e( l edPi n, f adeVal ue) ;
/ / wai t f or 30 mi l l i seconds t o see t he di mmi ng ef f ect
del ay( 30) ;
}
}
Arduino Code Examples - 3
ME407 Microcontrollers&Arduino
Seminar
33
Pulse Width Modulation, or PWM, is a technique for getting analog results
with digital means. Digital control is used to create a square wave, a signal
switched between on and off. This on-off pattern can simulate voltages in
between full on (5 Volts) and off (0 Volts) by changing the portion of the time
the signal spends on versus the time that the signal spends off.
Arduino Code Examples - 3
ME407 Microcontrollers&Arduino
Seminar
34
Arduino's PWM frequency at about 500Hz,
the green lines would measure
2 milliseconds each.
A call to analogWrite() is on a scale of 0 -
255, such that analogWrite(255) requests
a 100% duty cycle (always on), and
analogWrite(127) is a 50% duty cycle (on
half the time) for example.
Arduino Code Examples - 4
ME407 Microcontrollers&Arduino
Seminar
35
Stepper motors, due to their unique design, can be controlled to a high degree
of accuracy without any feedback mechanisms. The shaft of a stepper, mounted
with a series of magnets, is controlled by a series of electromagnetic coils that
are charged positively and negatively in a specific sequence, precisely moving it
forward or backward in small "steps".
Arduino Code Examples - 4
ME407 Microcontrollers&Arduino
Seminar
36
Unipolar Stepper Circuit
Arduino Code Examples - 4
ME407 Microcontrollers&Arduino
Seminar
37
Code
/ *
* Mot or Knob
*
* A st epper mot or f ol l ows t he t ur ns of a pot ent i omet er
* ( or ot her sensor ) on anal og i nput 0.
*/

#i ncl ude <St epper . h>

/ / change t hi s t o t he number of st eps on your mot or
#def i ne STEPS 100

/ / cr eat e an i nst ance of t he st epper cl ass, speci f yi ng
/ / t he number of st eps of t he mot or and t he pi ns i t ' s
/ / at t ached t o
St epper st epper ( STEPS, 8, 9, 10, 11) ;

/ / t he pr evi ous r eadi ng f r omt he anal og i nput
i nt pr evi ous = 0;

Arduino Code Examples - 4


ME407 Microcontrollers&Arduino
Seminar
38
voi d set up( )
{
/ / set t he speed of t he mot or t o 30 RPMs
st epper . set Speed( 30) ;
}

voi d l oop( )
{
/ / get t he sensor val ue
i nt val = anal ogRead( 0) ;

/ / move a number of st eps equal t o t he change i n t he
/ / sensor r eadi ng
st epper . st ep( val - pr evi ous) ;

/ / r emember t he pr evi ous val ue of t he sensor
pr evi ous = val ;
}
QUESTIONS
ME407 Microcontrollers&Arduino
Seminar
39
Motor Drive
ME407 Microcontrollers&Arduino
Seminar
40
H-Bridge ile ift ynl motor kontrol
Where to Buy
www.arduino.cc (Italy)
www.roboweb.net (Turkey)
www.sparkfun.com (USA)
www.robotshop.com (Canada,USA)
www.robotus.net (Turkey)

ME407 Microcontrollers&Arduino
Seminar
41

Bit, byte vs kavramlar
Alabilecekleri siteler

ME407 Microcontrollers&Arduino
Seminar
42
43
Generic CCS C Program
A generic C program for PICmicro constitutes
Preprocessor commands / directives:
Hardware Information
PICMicro type, clock frequency, etc.
Configuration of PICMicro
Configuration (mode) bits
Parameters of peripheral units
Compiler options and other declarations
Optimization option
Program starting address, file register declarations, etc.
Main program
Initialization of peripheral units
Calling built-in functions for the initialized units
ME407 Microcontrollers&Arduino
Seminar
44
Preprocessor Commands
#i ncl ude <16F877A. h>specifies the header file for PIC16F877A:
Includes constants and relevant hardware definitions
#use del ay( cl ock = . . . ) informs the compiler about the clock
frequency (in Hz). This information is crucial for delay functions.
#use RS232( opt i ons) designates the parameters of the serial-
port communication protocol.
#i ncl ude <16F877A. h>
#f uses HS, NOWDT, NOPROTECT, NOLVP
#use del ay( cl ock=20000000)
#use r s232( baud=57600, xmi t =PI N_C6, r cv=PI N_C7)
#or g 0x1F00, 0x1FFF {}
#opt 9
Following directives will frequently appear in our programs:
ME407 Microcontrollers&Arduino
Seminar
45
Preprocessor Commands (Contd)
#f uses opt i ons tells the compiler about the configuration and
operating mode of the device:
HS option defines the oscillator type as high-speed resonator (>> 4MHz).
Other oscillator options are
XT (standard crystal with a typical. freq. of 4MHz)
LP (low power oscillator)
RC (resistor-capacitor oscillator)
NOWDT tells the compiler that no Watch Dog Timer is utilized.
A safety measure in case the execution of the your program gets out of hand!
NOPROTECT specifies that flash memory is NOT protected:
Resident program could be read/decompiled/reviewed without authorization.
NOLVP informs the compiler that no low voltage programming is to be
allowed on this device.
ME407 Microcontrollers&Arduino
Seminar
46
Preprocessor Commands (Contd)
#or g st ar t addr , f i nal addr {}
reserves memory in flash memory (ROM).
#or g 0x1F00, 0x1FFF{} reserves the last 255-word
of the ROM for the bootloader (a.k.a. operating
system program of your PICmicro).
#opt opt i on tells the compiler optimization
level of your code:
0: lowest
9: highest (leads to the most-efficient compiled code)
ME407 Microcontrollers&Arduino
Seminar
47
CCS C Functions
CCS C built-in functions covered:
Serial port (RS-232 / UART)
Digital (discrete) I/O ports
A/D converter
Pulse width modulator
Counters/timers
Interrupts
Timer interrupts
External interrupt
Miscellaneous functions
ME407 Microcontrollers&Arduino
Seminar
48
Digital I/O Functions
Digital I/O forms the basis of a microcontrollers
operation:
Users can define any pin of a microcontroller as
digital output and control its logic state (LS) at will:
If LS is set to 1 5V is applied to that pin.
If LS is set to 0 Output pin is pulled to ground.
A pin can be defined as input and its current logic
state can be read arbitrarily:
If LS is read as 1 5V is being applied to the pin.
If LS is read as 0 Output pin is grounded.
ME407 Microcontrollers&Arduino
Seminar
49
Digital Output Functions
CCS C provides a number of output functions:
out put _hi gh( PI N_X#) applies 5V to PIN_X#:
# is a (bit) number between 0 and (usually) 7.
X is the port name (A, B, ..., G).
out put _l ow( PI N_X#) applies 0V to the output pin.
out put _bi t ( PI N_X#, st at e) applies either 5V or
0V to the pin depending on the state specified.
out put _X( val ue) applies a set of voltages to all
pins of port X depending on the given logic states.
ME407 Microcontrollers&Arduino
Seminar
50
Digital Input Functions
Here are some digital input functions of CCS C:
i nput ( PI N_X#) returns the logic state of PIN_X#:
5V 1 (High LS)
0V 0 (Low LS)
i nput _X( ) returns the entire logic states of port X.
Type of digital I/O can be specified through the
following preprocessor commands:
#use st andar d_i o( X) (in effect, if omitted)
#use f i xed_i o( X_out put s = PI N_X#, PI N_X#, . . . )
#use f ast _i o( X) (we shall prefer this one!)
ME407 Microcontrollers&Arduino
Seminar
51
Digital I/O Functions (Contd)
When #use f ast _i o( X) is used, the compiler
performs digital I/O without (re)programming the
direction register (TRISX).

User must ensure TRISX is set correctly via
set _t r i s_X( st at e) :
Bits of byte state correspond to directions of the pins of port
X.
If bit is 1, that pin is defined as (1)nput.
Otherwise, it is an (0)utput pin.
ME407 Microcontrollers&Arduino
Seminar
52
Notes on Digital I/O
Digital I/O pins are shared by other peripheral
units (CCP, ADC, UART, etc.).
Shared pins are multiplexed.
If a peripheral unit is activated, the PICmicro does not
allow users to employ the corresponding pins as
digital I/O.
Any digital I/O operation on those pins will have no effect!

It is advisable to define the unused pins of a
particular port as inputs.
High-impedance
ME407 Microcontrollers&Arduino
Seminar
53
Delay Functions
CCS C includes three functions for delaying the
execution of a program at various points:
del ay_us( val ue) creates a delay of (value1s)
del ay_ms( val ue) creates a delay of (value1ms)
del ay_cycl es( val ue) creates a delay of value
instruction cycles where each instruction cycle is 4
oscillator cycles.
To utilize these functions, the clock speed must
be specified:
#use del ay( cl ock = . . . )
ME407 Microcontrollers&Arduino
Seminar
54
Example Digital I/O
RB0
470 O
RB1
10 kO
V
dd
= 5V
Button
LED
Write a C program for a
PIC16F877A interfacing with
a push button that toggles the
shown LED as the button
gets to be depressed.
Solution:
In this exercise, the PICmicro turns into a simple toggle flip/flop
driving a LED. LED and the button are connected to the
PI N_B0 (output: 0) and PI N_B1 (input: 1) respectively. Assuming that
no other elements are connected to PORTB, port-pin directions
are simply set by
set _t r i s_b( 0xFE) (remaining pins are defined as inputs!)
- Note that 0xFE (hex) = 0b11111110 (bin) = 254 (dec)
ME407 Microcontrollers&Arduino
Seminar
55
Example Digital I/O
#i ncl ude <16F877A. h>
#f uses HS, NOWDT, NOPROTECT, NOLVP
#use del ay( cl ock=20000000)
#use r s232( baud=19200, xmi t =PI N_C6, r cv=PI N_C7)
#use f ast _i o( B) / * t r i s_b must be set pr oper l y! */
#or g 0x1F00, 0x1FFF {}
#opt 9

voi d mai n( ) {
i nt 1 Q = 0;
set _t r i s_b( 254) ; / * onl y PI N_B0 i s def i ned as out put */
pr i nt f ( " Pr ogr amst ar t s. . . \ n\ r " ) ;

whi l e( TRUE) { / * i nf i ni t e l oop */
i f ( ! i nput ( PI N_B1) ) { / * when swi t ch i s depr essed. . . */
Q = ! Q; / * . . . t oggl e LED st at e */
del ay_ms( 200) ; / * . . . wai t f or 0. 2s t o de- bounce */
out put _bi t ( PI N_B0, Q) ; }; / * . . . out put LED st at e */
}
}
ME407 Microcontrollers&Arduino
Seminar
56
Accessing RAM Directly
CCS C allows direct access to the RAM including the
(file) registers like PORTX:
#byt e t ag = addr ess associates the byte at the specified
address with the given tag.
#bi t t ag = addr ess. n associates the n
th
bit of byte residing
at the specified address with the given tag.
While accessing PORTX registers, one must set the
directions of each pin correctly via set _t r i s_X( st at e)
function.
Some useful addresses (refer to the datasheet) are
PORTA = 0x05, PORTB = 0x06
PORTC = 0x07, PORTD = 0x08
ME407 Microcontrollers&Arduino
Seminar
57
Example 2b Digital I/O
#i ncl ude <16F877A. h>
#f uses HS, NOWDT, NOPROTECT, NOLVP
#use del ay( cl ock=20000000)
#use r s232( baud=19200, xmi t =PI N_C6, r cv=PI N_C7)
#use f ast _i o( B) / * t r i s_b must be set pr oper l y! */
#or g 0x1F00, 0x1FFF {}
#opt 9

#byt e PORTB = 0x06 / * cont r ol r egi st er f or Por t B */
#bi t SW= PORTB. 1 / * RB1 i s connect ed t o swi t ch */
#bi t LED = PORTB. 0 / * RB0 dr i ves a LED */

voi d mai n( ) {
i nt 1 Q = 0;
set _t r i s_b( 254) ; / * onl y RB0 i s def i ned as out put */
pr i nt f ( " Pr ogr amst ar t s. . . \ n\ r " ) ;
whi l e( TRUE) { / * i nf i ni t e l oop */
i f ( ! SW) { / * when swi t ch i s depr essed. . . */
Q = ! Q; / * . . . t oggl e LED st at e */
del ay_ms( 200) ; / * . . . wai t f or 0. 2s t o de- bounce */
LED = Q; }; / * . . . out put LED st at e */
}
}
ME407 Microcontrollers&Arduino
Seminar
58
Serial Port Functions
In CCS C, there are 14 functions related to serial port
communication.

Some of them are carried over from standard C:
pr i nt f ( st r i ng) outputs a string of characters over serial port.
get c( ) awaits a character coming from the serial port.
put c( char ) sends the specified character over the serial port.

#use r s232( opt i ons) directive setting RS-232
parameters must preceed these functions.
ME407 Microcontrollers&Arduino
Seminar
59
Example Serial Port
#i ncl ude <16F877A. h> / * PI CMi cr o Model : 16F877A */
#f uses HS, NOWDT, NOPROTECT, NOLVP / * Devi ce conf i gur at i on */
#use del ay( cl ock=20000000) / * CLK f r equency: 20MHz */
#use r s232( baud=19200, xmi t =PI N_C6, r cv=PI N_C7) / * RS- 232 par amet er s */
#or g 0x1F00, 0x1FFF {} / * Reser ve memor y i n ROM */
#opt 9 / * Compi l er opt . l evel ( max) */

voi d mai n( ) {
char c;
l ong nc = 0;
pr i nt f ( *** PI C Typewr i t er ***\ n\ r " ) ;
do{
c = get c( ) ; / * Get a char act er f r omPC */
put c( c) ; / * Send i t back t o PC */
nc++; / * Count char s */
i f ( nc == 13) pr i nt f ( "\ n" ) ; / * Li ne f eed */
} whi l e ( c! =0x11) ; / * Echo unt i l ct r l - Q */
pr i nt f ( " \ n\ r No. of char act er s: %l d\ n\ r ", nc) ;
whi l e( TRUE) ; / * I nf i ni t e l oop */
}
As an illustration of these functions, let us write a simple C program
which turns the serial port monitor (siow) into a typewriter:
ME407 Microcontrollers&Arduino
Seminar
60
A/D Conversion
PIC16F877A employ a 10-bit ADC unit with 8 multiplexed channels.
Pins RA0 to RA7 (PORTA) can be defined as inputs of this unit.
A/D conversion has the following steps:
Initialization of ADC unit
Selecting an ADC channel
Reading ADC result for that channel
CCS C offers the following functions for initialization:
set up_adc_por t s( ALL_ANALOG) sets all the pins as analog voltage
inputs.
Take a look at 16F877A.h file for other input configurations.
set up_adc( opt i on) sets the clock source for ADC. The options are:
ADC_OFF turns off ADC unit.
ADC_CLOCK_DI V_n sets the ADC clock period as T
ADC
= n*T
CLK
where n
e {2, 4, 8, 16, 32, 64}
ADC_CLOCK_I NTERNAL sets the ADC clock source as its internal RC
oscillator.
ME407 Microcontrollers&Arduino
Seminar
61
A/D Conversion (Contd)
The following functions are utilized to select a
ADC channel and to read the result:
set _adc_channel ( n) selects the pin RAn as the
input channel.
r ead_ADC( ) returns the 10-bit result.
One must wait at least 10 to 20 s before
reading the result.
ADC unit can generate an interrupt when a
conversion is done.
A useful feature for time-sensitive apps.
ME407 Microcontrollers&Arduino
Seminar
62
Example 3 ADC
470 O
a
b
c
d
e
f
g
K
470 O
LS 5015-20
RC4
RC5
RC3
RD0
RD1
RD3
RD2
V
dd
= 5V
20 kO
(pot.)
470 O
RA0
AN0
a
b
c
d
e
f
g
Consider a PIC16F877A connected to a seven segment display (SSD)
along with a 20kO potentiometer as illustrated. Write a C program such
that the PIC shows the applied voltage at RA0 pin as a hexadecimal
number (0 F) on the SSD. Furthermore, hex. numbers 0 and F must
blink on the display while the PIC is to send the strings low and high
respectively over the RS-232.
ME407 Microcontrollers&Arduino
Seminar
63
Example 3 SSD Function
Let us develop a function which will generate the desired bit patterns on ports
C and D so as to display hex. numbers on SSD. The table below illustrates
the characters vs. the corresponding bit patterns for the SSD segments:
Pin Seg 0 1 2 3 4 5 6 7 8 9 A b c d E F
RC5 b 1 1 1 1 1 0 0 1 1 1 1 0 0 1 0 0
RC4 a 1 0 1 1 0 1 1 1 1 1 1 0 0 0 1 1
RC3 c 1 1 0 1 1 1 1 1 1 1 1 1 0 1 0 0
RD3 f 1 0 0 0 1 1 1 1 1 1 1 1 0 0 1 1
RD2 g 0 0 1 1 1 1 1 0 1 1 1 1 1 1 1 1
RD1 e 1 0 1 0 0 0 1 0 1 0 1 1 1 1 1 1
RD0 d 1 0 1 1 0 1 1 0 1 1 0 1 1 1 1 0
Data: 123 80 103 117 92 61 63 120 127 125 126 31 7 87 47 46
In this table, 1 denotes that the LED on that particular segment is on. A byte
(data) for each character can be formed using the following representation:
RD0 RD1 RD2 RD3 RC3 RC4 RC5 0 SSD Data:
MSB LSB
One can extract bit patterns
for each port when SSD Data
of a character is specified.
ME407 Microcontrollers&Arduino
Seminar
64
Example 3 C Code
#i ncl ude <16F877A. h>
#devi ce ADC=10 / * devi ce has 10- bi t ADC */
#f uses HS, NOWDT, NOPROTECT, NOLVP
#use del ay( cl ock=20000000)
#use r s232( baud=19200, xmi t =PI N_C6, r cv=PI N_C7)
#use f ast _i o( C)
#use f ast _i o( D)
#or g 0x1F00, 0x1FFF {}
#opt 9

voi d ss_di sp( i nt num) { / * seven segment di spl ay r out i ne */
/ /
/ / Due t o t hi s def i ni t i on, di sp_dat a now r esi des i n ROM!
/ /
byt e const SSDat a[ 16] = {123, 80, 103, 117, 92, 61, 63, 120,
127, 125, 126, 31, 7, 87, 47, 46};
i f ( num< 16) {
out put _c( ( SSDat a[ num] & 240) >>1) ;
out put _d( SSDat a[ num] & 15) ;
}
}
ME407 Microcontrollers&Arduino
Seminar
65
Example 3 C Code (Contd)
voi d mai n( ) {
l ong adval ;
set _t r i s_c( 128) ; set _t r i s_d( 0) ; / * def i ne I / O pi ns f i r st */
out put _c( 0) ; out put _d( 0) ; / * cl ear di spl ay */
set up_por t _a( ALL_ANALOG) ; / * set up ADC */
set up_adc( ADC_CLOCK_I NTERNAL) ;
set _adc_channel ( 0) ;
pr i nt f ( " Pr ogr amst ar t s. . . \ n\ r " ) ;
whi l e( TRUE) {
del ay_us( 200) ; / * make sur e ADC i s r eady */
adval = r ead_ADC( ) ; / * r ead 10- bi t r esul t */
ss_di sp( adval >>6) ; / * di spl ay ( adval / 64) */
i f ( adval <64 | | adval >960) { / * t oo hi gh or t oo l ow? */
i f ( adval <64) pr i nt f ( " Low\ n\ r " ) ;
i f ( adval >960) pr i nt f ( " Hi gh\ n\ r " ) ;
del ay_ms( 200) ; / * bl i nk t he number . . . */
out put _c( 0) ; out put _d( 0) ; / * . . . on t he di spl ay */
del ay_ms( 200) ;
}
}
}
ME407 Microcontrollers&Arduino
Seminar
66
Example 4 PWM
470 O
a
b
c
d
e
f
g
K
470 O
LS 5015-20
RC4
RC5
RC3
RD0
RD1
RD3
RD2
V
dd
= 5V
20 kO
(pot.)
470 O
RA0
RC2
470 O
CCP1
AN0
Consider a PIC16F877A connected to a SSD along with a 20kO pot. Write a
C program such that the PICMicro shows the applied voltage at RA0 pin as a
Hex. number (0 F) on the SSD. Furthermore, it is to adjust the brightness of the
LED (connected to the pin of CCP1) via PWM as the the voltage on RA0 varies.
ME407 Microcontrollers&Arduino
Seminar
67
Example 4 PWM
voi d mai n( ) {
l ong adval ;
set _t r i s_c( 128) ; set _t r i s_d( 0) ; / * def i ne I / O pi ns f i r st */
out put _c( 0) ; out put _d( 0) ; / * cl r 7- segment di spl ay */

set up_ccp1( CCP_PWM) ; / * conf i gur e CCP1 as PWM */
set up_t i mer _2( T2_DI V_BY_1, 255, 1) ; / * PWM f r equency: ~20kHz */

set up_por t _a( AN0) ; / * onl y AN0 i s used her e! */
set up_adc( ADC_CLOCK_DI V_2) ; / * T_AD = 2*T_CLK */
set _adc_channel ( 0) ;

pr i nt f ( " Pr ogr amst ar t s. . . \ n\ r " ) ;
whi l e( TRUE) {
del ay_us( 200) ;
adval = r ead_ADC( ) ; / * r ead 10- bi t r esul t */
set _pwm1_dut y( adval ) ; / * d( %) = 100*adval / 1024 */
ss_di sp( adval >>6) ; / * di spl ay ( adval / 64) */
}
}
ME407 Microcontrollers&Arduino
Seminar
68
Counters / Timers
PIC16F877A has three on-board counters:
Timer0: 8-bit timer/counter with pre-scaler
Timer1: 16-bit timer/counter with pre-scaler
Timer2: 8-bit timer/counter with pre- & post-
scalers.
Since Timer2 is used to set the period of
PWM, only Timer0 and Timer1 will be
taken into consideration for counting
external events.
ME407 Microcontrollers&Arduino
Seminar
69
Counter0 / Timer0
set up_count er s( sour ce, pr escal er ) sets up timer0 or real-
time clock/counter (RTCC):
sour ce indicates what drives the RTCC:
RTCC_I NTERNAL: internal clock @ 20MHz / 4
RTCC_EXT_L_TO_H: the positive edge of external clock at RA4/T0CK1 pin.
RTCC_EXT_H_TO_L: the negative edge of external clock.
pr escal er may be one of these constants:
RTCC_DI V_n: divides the clock frequency by n e {1, 2, 4, ..., 256}.
For instance, if RTCC_DIV_4 is chosen, the RTCC will register one count for every
4-pulse of its clock input.
set _t i mer 0( val ue) sets the initial count value of timer0.
get _t i mer 0( ) returns the count value of timer0.
All timers count up.
When a timer0 reaches 255, it will flip over to 0 and continue counting.
ME407 Microcontrollers&Arduino
Seminar
70
RTCC/Timer0 Model
Timer Interrupt
Internal
PICmicro
Clock
Internal
PICmicro
Clock
External
Frequency
Source
External
Frequency
Source
Frequency
Divider
Frequency
Divider
8-bit
Counter
8-bit
Counter
set _t i mer 0( val ue)
RTCC_DI V_1
RTCC_DI V_2
RTCC_DI V_4
RTCC_DI V_8
RTCC_DI V_16
RTCC_DI V_32
RTCC_DI V_64
RTCC_DI V_128
RTCC_DI V_256
get _t i mer 0( )
a
b
c
RA4
a: RTCC_I NTERNAL
b: RTCC_EXT_L_TO_H
c: RTCC_EXT_H_TO_L
(20 MHz / 4)
ME407 Microcontrollers&Arduino
Seminar
71
Counter1 / Timer1
set up_t i mer _1( mode) sets up (16-bit) timer1:
mode values may be:
T1_DI SABLED: timer1 is disabled.
T1_I NTERNAL: internal clock (@ 20MHz / 4) drives timer1.
T1_EXTERNAL: external clock at RC0/T1CK1 pin drives timer1.
T1_EXTERNAL_SYNC: external clock is to be synchronized with the
internal one (called synchronous counting).
T1_DI V_BY_n: divides the source frequency by n e {1, 2, 4, 8}.
Logical OR may be applied to constants from different groups.
set _t i mer 1( val ue) sets the initial count value of
timer1.
get _t i mer 1( ) returns the count value of timer1.
ME407 Microcontrollers&Arduino
Seminar
72
Timer 1 Model
Timer Interrupt
Internal
PICmicro
Clock
Internal
PICmicro
Clock
External
Frequency
Source
External
Frequency
Source
Frequency
Divider
Frequency
Divider
8-bit
Counter
8-bit
Counter
set _t i mer 1( val ue)
T1_DI V_BY_1
T1_DI V_BY_2
T1_DI V_BY_4
T1_DI V_BY_8
get _t i mer 1( )
a
b RC0/T1CK1
a: T1_I NTERNAL
b: T1_EXTERNAL or
T1_EXT_SYNCH
(20 MHz / 4)
D
CLK
Q
a: T1_I NTERNAL or
T1_EXTERNAL
b: T1_EXT_SYNCH
a
b
D-F/F
ME407 Microcontrollers&Arduino
Seminar
73
Example 5 - Counters
Consider the circuit shown. Write a C program for the PICmicro such that
it will send the counterX (X = 0 or 1) values to the serial port monitor (PC)
over the serial port whenever the pushbutton is depressed.
+
RA4
Timer0
RC0 Timer1
1
CD40106B
2
OR
20 kO
100 F
V
dd
(Pin 14) = 5V
V
ss
(Pin 7) = GND
RB1
10 kO
V
dd
= 5V
Button
Example 6 ME407 Microcontrollers&Arduino
Seminar
74
Example 5a Timer0
#i ncl ude <16F877A. h>
#f uses HS, NOWDT, NOPROTECT, NOLVP
#use del ay( cl ock=20000000)
#use r s232( baud=19200, xmi t =PI N_C6, r cv=PI N_C7)
#use f ast _i o( B)
#or g 0x1F00, 0x1FFF {}
#opt 9
#bi t SW= 0x06. 1 / * RB1 i s t he swi t ch i nput */

voi d mai n( ) {
i nt count ;
set _t r i s_b( 255) ; / * Al l pi ns ar e i nput s */
set up_count er s( RTCC_EXT_L_TO_H, RTCC_DI V_1) ; / * Set up RTCC */
set _t i mer 0( 0) ; / * I . C. = 0 */
whi l e( TRUE) {
count = get _t i mer 0( ) ; / * Read ct r 0 */
i f ( ! SW) { / * When SWi s depr essed. . . */
pr i nt f ( " Count er 0 = %u\ n\ r " , count ) ; / * . . . send i t out ! */
del ay_ms( 200) ; }; / * Wai t 200 ms t o debounce */
}
}
ME407 Microcontrollers&Arduino
Seminar
75
Example 5b Timer1
#i ncl ude <16F877A. h>
#f uses HS, NOWDT, NOPROTECT, NOLVP
#use del ay( cl ock=20000000)
#use r s232( baud=19200, xmi t =PI N_C6, r cv=PI N_C7)
#use f ast _i o( B)
#or g 0x1F00, 0x1FFF {}
#opt 9
#bi t SW= 0x06. 1 / * RB1 i s t he swi t ch i nput */

voi d mai n( ) {
l ong count ;
set _t r i s_b( 255) ; / * Al l pi ns ar e i nput s */
set up_t i mer _1( T1_EXTERNAL| T1_DI V_BY_1) ; / * Set up Ti mer 1 */
set _t i mer 1( 0) ; / * I . C. = 0 */
whi l e( TRUE) {
count = get _t i mer 1( ) ; / * Read ct r 1 */
i f ( ! SW) { / * When SWi s depr essed. . . */
pr i nt f ( " Count er 1 = %l u\ n\ r " , count ) ; / * . . . send i t out ! */
del ay_ms( 200) ; }; / * Wai t 200 ms t o debounce */
}
}
ME407 Microcontrollers&Arduino
Seminar
76
Interrupts
Microcontrollers deals with time-sensitive or randomly occurring
events through interrupts.
Periheral units usually generate such signals.
They tell the processor that a special event has taken place.
Whenever an interrupt occurs, the processor invokes an interrupt
service routine (ISR) handling the corresponding situation.
After the execution of an ISR, the microcontroller resumes its normal
operation.
The generic procedure for ISR is as follows:
Disable interrupts: This ensures that no other interrupt messes up with
the service.
Service routines
Clear its interrupt flag (a bit in an interrupt control register) when done:
This informs the processor that the interrupt is handled and the ISR is
ready for a new interrupt.
Enable interrupts
Return from ISR: Restores the original state of MCU and resumes the
main course.
ME407 Microcontrollers&Arduino
Seminar
77
Interrupt Functions
In CCS C, ISRs (interrupt-handler functions) are marked up via a compiler
directive:
#I NT_XXXX where XXXX stands for the type of interrupt.
The interrupt service procedures are embedded inside this function.
Interrupts must be enabled at the beginning of main function:
enabl e_i nt er r upt s( I NT_XXXX) sets the interrupt enable flag at the given
level.
enabl e_i nt er r upt s( GLOBAL) enables all interrupts.
Other relevant built-in functions are
di sabl e_i nt er r upt s( I NT_XXXX)
di sabl e_i nt er r upt s( GLOBAL)
cl ear _i nt er r upt ( I NT_XXXX) clears the interrupt flag at the given level.
Interrupts available in PIC 16F877A are
External interrupt (INT_EXT)
Timer interrupts (INT_RTCC, INT_TIMER1)
Change on (Port B) pin interrupt (INT_RB)
A/D conversion complete interrupt (INT_AD)
Serial port interrupts (INT_RDA, INT_TBE)
And more...
}
of major
interest
ME407 Microcontrollers&Arduino
Seminar
78
Timer Interrupts
Timer0 (RTCC) and Timer1 are frequently used to generate
(precise) periodic interrupts for timing-sensitive applications like
digital control systems!
When RTCC or Timer1 counter overflows, it generates an interrupt.
Once the timer is set up in the main function, its interrupt is enabled.
Timers are set up such that the internal clock drives their counters.
The functions discussed in previous section are employed for this
purpose:
Timer0 (or RTCC):
set up_count er s( RTCC_I NTERNAL, RTCC_DI V_n)
Prescaler: n e {1, 2, 4, 8, ..., 256}
Timer1:
set up_t i mer _1( T1_I NTERNAL| T1_DI V_BY_n)
Prescaler: n e {1, 2, 4, 8}
ME407 Microcontrollers&Arduino
Seminar
79
Timer Interrupts (Contd)
In control applications, the ISR is used to
implement the control algorithm.
The frequency of interrupt is essentially the
sampling frequency!
The timerX interrupt frequency can be
calculated using the following expressions:
] [
2
10 5
) 1 ( 8
6
Hz
n
f
X
timerX
+

=
where the timer index X is 0 or 1 while
n e {1, 2, 4, ...} is the prescaler.
ME407 Microcontrollers&Arduino
Seminar
80
Timer Interrupts (Contd)
One can precisely set the desired interrupt frequency (f
d
)
[Hz] by selecting the initial value (m
0
) of timerX:
)
`

=
+
d
X
f n
m
6
) 1 ( 8
0
10 5
int 2
Hence, at the beginning of ISR, the counter value is set
to m
0
using set _t i mer X( m
0
) . As an illustration, let
us calculate the initial counter value for timer0 (with
RTCC_DI V_128 option: n = 128) if f
d
= 750 Hz:
204 52 256
750 128
10 5
int 2
6
) 0 1 ( 8
0
= =
)
`

=
+
m
ME407 Microcontrollers&Arduino
Seminar
81
Example 6a Timer0 Interrupt
As an example, we shall revisit Example 5.
Instead of connecting an external clock to the
timer0, we shall utilize PICmicros internal clock
@ 5 Mhz to generate timer0 interrupt.
ISR is to count up each-time it is invoked.
As in the previous case, we would like to send
count values to the serial port monitor (PC) over
the serial port whenever the pushbutton is
pressed.
ME407 Microcontrollers&Arduino
Seminar
82
Example 6a - C program
/ /
/ / Pr epr ocessor di r ect i ves ar e same as Exampl e 5a
/ /
l ong count = 0; / * Gl obal var i abl e */

#I NT_RTCC / * I SR f or t i mer 0- over f l ow i nt er r upt */
voi d i sr ( ) {count ++; }

voi d mai n( ) {
set _t r i s_b( 255) ; / * Al l pi ns of Por t B ar e i nput s */
set up_count er s( RTCC_I NTERNAL, RTCC_DI V_256) ; / * Set up RTCC */
set _t i mer 0( 0) ; / * I . C. = 0 */
enabl e_i nt er r upt s( I NT_RTCC) ; / * Enabl e i nt er r upt s */
enabl e_i nt er r upt s( GLOBAL) ;
whi l e( TRUE) {
i f ( ! SW) { / * When SWi s depr essed. . . */
pr i nt f ( " Count er = %l u\ n\ r " , count ) ; / * . . . send i t out ! */
del ay_ms( 200) ; }; / * Wai t 200 ms t o debounce */
}
}
ME407 Microcontrollers&Arduino
Seminar
83
External Interrupt
PIC16F877A allows the use of a single external
interrupt (INT_EXT):
External (interrupt) source must be connected to
RB0/INT pin.
Before enabling the external interrupt, the type
of clock edge triggering intrerupt should be
specified:
ext _i nt _edge( L_TO_H) denotes the positive edge
of the clock triggers the interrupt.
ext _i nt _edge( H_TO_L) denotes the negative
edge of the clock triggers the interrupt.
ME407 Microcontrollers&Arduino
Seminar
84
Example 6b External Interrupt
In this example, the external clock is to be coupled to RB0/INT pin. We will
write a C program for the PICmicro such that it will count the pulses of
external clock and will send out counter values to the serial port monitor (PC)
whenever the pushbutton is depressed.
+
RB0/INT
1
CD40106B
2
20 kO
100 F
V
dd
(14) = 5V
V
ss
(7) = GND
RB1
10 kO
V
dd
= 5V
Button
ME407 Microcontrollers&Arduino
Seminar
85
Example 6b External Interrupt
/ /
/ / Pr epr ocessor di r ect i ves ar e same as Exampl e 5a
/ /
l ong count = 0; / * Gl obal var i abl e */

#I NT_EXT / * I SR f or ext er nal B0 i nt er r upt */
voi d i sr ( ) {count ++; }

voi d mai n( ) {
set _t r i s_b( 255) ; / * Al l pi ns of Por t B ar e i nput s */

ext _i nt _edge( L_TO_H) ; / * I nt er r upt on ( +) edge */
enabl e_i nt er r upt s( I NT_EXT) ; / * Enabl e i nt er r upt s */
enabl e_i nt er r upt s( GLOBAL) ;
whi l e( TRUE) {
i f ( ! SW) { / * When SWi s depr essed. . . */
pr i nt f ( " Count er = %l u\ n\ r " , count ) ; / * . . . send i t out ! */
del ay_ms( 200) ; }; / * Wai t 200 ms t o debounce */
}
}
ME407 Microcontrollers&Arduino
Seminar
86
Pin-change Interrupt
In 16F877A, pin change interrupt (INT_RB) is
used to detect the logic state changes at pin
RB7-RB4.
If there is any change in these four inputs,
PICmicro generates an interrupt.
This interrupt is intended for keyboard wake-up
Microchip does not recommend the utilization of this interrupt
for any other applications.
Any read or write to Port B (say RB3-RB0) clears the
mismatch condition.
ME407 Microcontrollers&Arduino
Seminar
87
Example 6c Pin Change Interrupt
In this exercise, we would like to develop a C program for PICmicro so that the
microcontroller measures the input frequency (Hz) of the external clock at RB7
and transmits that information through the serial port. Note that for testing
purposes, a LED coupled to RB1 pin gets toggled whenever a pin-change
interrupt is generated.
RB1
470 O
+
RB7
1
CD40106B
2
20 kO
100 F
V
dd
(14) = 5V
V
ss
(7) = GND
ME407 Microcontrollers&Arduino
Seminar
88
Example 6c RB Change Interrupt
#i ncl ude <16F877A. h>
#f uses HS, NOWDT, NOPROTECT, NOLVP
#use del ay( cl ock=20000000)
#use r s232( baud=19200, xmi t =PI N_C6, r cv=PI N_C7)
#or g 0x1F00, 0x1FFF {}
#use f ast _i o( B)
#opt 9
#bi t LED = 0x06. 1 / * RB1 dr i ves a LED */

i nt count = 0; / * Gl obal var i abl es */
shor t Q = 0;

#I NT_RB / * RB Change I SR */
voi d i sr ( ) {
count ++; / * Count changes */
Q = ! Q; / * Toggl e LED */
LED = Q; / * must R/ Wt o Por t B bef or e cl ear i ng RBI F */
cl ear _i nt er r upt ( I NT_RB) ; / * Cl ear RBI F */
}
ME407 Microcontrollers&Arduino
Seminar
89
Example 6c (Contd)
voi d mai n( ) {
i nt f r eq = 0, f r eq_ol d;

set _t r i s_b( 253) ; / * Onl y RB1 i s out put */
por t _b_pul l ups( TRUE) ; / * I nt er nal pul l - ups act i vat ed */

enabl e_i nt er r upt s( I NT_RB) ; / * Enabl e i nt er r upt s */
enabl e_i nt er r upt s( GLOBAL) ;

whi l e( TRUE) {
f r eq_ol d = f r eq; / * Cal cul at e f r equency */
f r eq = count ; count = 0;
i f ( f r eq! =f r eq_ol d) pr i nt f ( " Fr equency = %d [ Hz] \ r " , f r eq) ;
del ay_ms( 1000) ; / * Sampl i ng per i od i s 1s */
}
}
ME407 Microcontrollers&Arduino
Seminar
90
EEPROM Commands
PIC 16F877A incorporate 256-byte non-volatile
memory.
The user can access EEPROM through the
following built-in functions of CCS C:
r ead_eepr om( addr ess) reads a byte from the
EEPROM at the specified address (8-bit).
The address ranges between 0 and 255 for PIC 16F877A.
wr i t e_eepr om( addr ess, val ue) writes a byte
(value) to EEPROM at the specified address.
This function takes several milliseconds to execute.
ME407 Microcontrollers&Arduino
Seminar
91
Watch Dog Timer (WDT)
The WDT function is to monitor the computer system whether work
normally.
Otherwise, it will have some measures to fix up the system.
The main reason of the WDT is that software sometimes got lost:
Enter infinite loops
Unexpected (conditional) branching puts the routine to go crazy.
The WDT unique intention is to reset the machine if certain
programmable timer expires. Therefore properly operating"
software should "reset" WDT before it does!
For instance, if you program the WDT to 1 second, you should reset the
WDT timer before that happens.
If a routine gets lost, the WDT will reset your machine in one
second, so not much is wasted.
ME407 Microcontrollers&Arduino
Seminar

You might also like