Sunteți pe pagina 1din 22

PICadilly 12F675

A Dilly of a Wee PIC


by Ian Burn

Contents:

1. Introduction
2. What is the 12F675 ?
3. Front-end setup
4. Blink!
5. Making Music
6. In Circuit Serial Programming (ICSP)
7. Analog to Digital Converters (ADCs)
8. Sleeping
9. Interrupt on Change
10. Lost Calibration Code
11. Feedback and Acknowledgements

Page 1
Page 1
Page 2
Page 3 - 4
Page 5 - 6
Page 7- 9
Page 10-14
Page 15
Page 16-20
Page 21
Page 22

1. Introduction
I have been using the PIC12F675 for the past three years. During that time I have made many
mistakes, sometimes more than once. These notes were prepared to assist me in future applications
using this small but mighty microcontroller. Hopefully you will also find them useful.
Be sure to check the PIC12F629/12F675 datasheet at Microchip for detailed information.
(See: www.microchip.com)
All of my source code is written for Micro Engineering Labs PIC Basic Pro (PBP) Compiler and the
chip is programmed using MELabs EPIC Plus Programmer.

2. What is the 12F675?


It in a very versatile 8 pin microcontroller of the Microchip PIC. Some of the features include:

1024 x 14 bit words of programmable memory


64 x 8 bytes of data memory
128 x 8 bytes of EEPROM data memory
A built-in RC oscillator operating at 4 MHz (no resonator or crystal required)
5 ports that can be either inputs or outputs
1 port that can be an input or the MCLR (master clear pin)
4 ports can be used as Analog to Digital Converters (ADCs)
ADC reference voltage can be set or the supply voltage used
Operates from 2.0 to 5.5 VDC with a low current - very low SLEEP current
Each port can sink/source 25 mA up to a total of 125 mA
Individual programmable weak pull-up resistors for each port
Price - about $2 each

The only serious limitations are the number of ports and amount of memory.
Ian Burn
1

January 31, 2005

V5.0

12F675 Pin-out
Vdd = +2.0 to 5.5 VDC
Vss = power ground
GP0 to GP5 are the six GPIO ports with all but GPIO.3 (pin 4) being either inputs or
outputs. GPIO.3 can be either an input port or MCLR port.

3. Front-End Setup
As with most PICs, a number of initial setting must be placed at the beginning of the program.
With some PICs, such as the 16F84, one can write a simple program to blink a LED by using all the
default settings and no front-end statements are required. Not so with the 12F675.
The following lines of code are used in many of my 12F675 projects and are described as follows:
ansel=0
cmcon=7

Sets the ADC inputs as digital when not using the ADCs.
Turns the comparator OFF when using ports digitally

These two statements are critical to digital operation such as the flashing LEDs.
Next one would normally configure the GPIO ports as either inputs or outputs. GPIO.3 (pin 4) is the
MCRL pin or can be used as an input BUT not as an output. If used as an input, MCLR must be
turned OFF in the configuration line below. If it is turned ON, it must have an external pull-up resistor
of 4.7k to 10k. You would also likely want a reset button connecting the MCLR pin to ground (Vss)
via a 100 ohm resistor.
TRISIO =%000000 is the binary equivalent of TRISIO=0 which sets all ports as outputs
The Compiler seems to sense that GPIO.3 must be an input and adjusts for this incorrect code.
If all the ports except GPIO.3 are going to be outputs, a preferred code would be:
TRISIO=%001000 which is the binary equivalent of TRISIO=8
If all ports except GPIO.0 are inputs, for example, you would use either
TRISIO=%111110 or TRISIO=62

Ian Burn

January 31, 2005

V5.0

Setting the 12F675 configuration codes (sometimes called fuses) can be done at the programmer or,
for most settings, by way of an @DEVICE statement in the code.
For example:
@ Device PIC12F675,WDT_ON,PWRT_ON,PROTECT_OFF,MCLR_ON,BOD_OFF
This defines the PIC as a 12F675
The watchdog timer (WDT) is turned ON (usually only OFF if using the @SLEEP command as
the WDT keeps waking up the PIC)
Power-on reset (PWRT) is turned ON
Code protect (PROTECT) is turned OFF
MCLR is turned on so an external pull-up resistor is needed
Brown out detect (BOD) is turned OFF (this reduces sleep current)
Other front-end statements will be introduced as required.

4. Blink!
The standard test for successfully programming any PIC is to blink a LED.
This circuit uses three AA batteries
for a 4.5 volt supply. A 0.1 mfd
capacitor is connected between
pins 1 and 8 as close as possible
to the pins.
DONT omit this capacitor!

BAT1

4V5

C1
0.1

The MCLR pin is pulled high via the


10k resistor and can be pulled low to
reset the PIC with the button and the
100 ohm resistor.
Microchip recommend the 100 ohm
resistor on the MCLR pin to Vss.

U1
1

R1

10k
4

Vdd/+

Vss/Gnd

GP5

GP0/AN0

GP4/AN3

GP1/AN1

GP3/MCLR

GP2/AN2

R2

1k

D2

LED

PIC12F675

The LED is connected between GPIO.0


and Vss via a 1 k resistor resulting in
about 3 mA of LED current. the
maximum allowable current is 25 mA.

R3
SW1

The LED could be reversed and


connected to the Vdd (+4.5V) in which
case the LED would come on when
GPIO.0 went LOW.

Ian Burn

100

Blinking LED with RESET

January 31, 2005

V5.0

The PIC BasicPro code to blink the LED when using the MCLR RESET is as follows:
Blinking a LED with a PIC 12F675
January 25, 2005
The LED will blink 10 times then turn off until the PIC is reset
Front-end setup
@ Device PIC12F675,WDT_ON,PWRT_ON,PROTECT_OFF,MCLR_ON,BOD_OFF
this statement is explained under item 3. above
ANSEL=0
Sets the ADC inputs as digital when not using the ADCs.
CMCON=7
Turns the comparator OFF when using ports digitally
TRISIO=8
All ports are outputs except MCLR - if a port is not used, set it as an output
Define Variables
LED VAR GPIO.0
x VAR BYTE

sets the GPIO.0 port as LED


x is a counter and will not have a value larger than 255

Set initial values


LED=0

ensures that LED is off at the beginning

Program
FOR x = 1 to 10
LED = 1
PAUSE 500
LED = 0
PAUSE 500
NEXT x
END

Program will repeat statements between here and next x 10 times


Turns on LED. Could also use HIGH LED but uses a bit more memory
Pause 500 milliseconds
Turns off LED
Pause 500 milliseconds
if x is not = 10, returns to FOR x = 1 to 10 statement
ends the program. The reset button will start it at the beginning.

The same result would occur if the MCLR was turned OFF and R1, R3 and SW1 were omitted.
GPIO.3 then becomes an input port.
I connect the GPIO.3 port to ground or to Vdd if I am not using it as in input, otherwise it will pick up
noise and prevents a deep SLEEP if using this command.
The configuration line would become:
@ Device PIC12F675,WDT_ON,PWRT_ON,PROTECT_OFF,MCLR_OFF,BOD_OFF

The LED will only blink the 10 times and


cannot be reset except by removing the power.
BAT2

4V5

Once the power is removed, it may be necessary


to discharge C1 to turn off the PIC. To ensure
a reset.

C1
0.1
U2
1

Vdd/+

Vss/Gnd

GP5

GP0/AN0

GP4/AN3

GP1/AN1

GP3/MCLR

GP2/AN2

R2

Blinking LED
without RESET

1k

D1

LED

PIC12F675

Ian Burn

January 31, 2005

V5.0

5. Making Music
I have had a lot of fun making music with PICs. This is a case where the 12F675 is a bit limiting
because of its memory size but one or two tunes are possible.
One application was to blink the nose of a reindeer that played the tune, Rudolph the Red Nosed
Reindeer. Others have included musical clocks and door chimes.
Although the PIC cannot get the exact audio frequency for musical notes, it can come quite close.
The key command used is:
SOUND pin, [tone #, tone duration, tone #, tone duration, ..]
pin is the port used to put out the sound [I usually define the port such as: MPIN VAR GPIO.1]
tone # is a value between 0 and 127 with 0 being silence (127 is about 10,000 Hz)
tone duration is the length of the tone in 12 millisecond increments
The following tables can be used to equate tone # values to approximate musical notes:

Tone #
1
6
13
20
26
31
37
42
47
51
56
60
64
67
71
74
77
80
83
85

Note
Ds2
E2
F2
Fs2
G2
Gs2
A2
As2
B2
C3
Cs3
D3
Ds3
E3
F3
Fs3
G3
Gs3
A3
As3

Tone #
88
90
92
94
96
98
99
101
102
104
105
107
108
109
110
111
112
113
114
115

Note
B3
C4
Middle C
Cs4
D4
Ds4
E4
F4
Fs4
G4
Gs4
A4
As4
B4
C5
Cs5
D5
Ds5
E5
F5
Fs5 missing
G5

For example: E2 is the musical note E in the second octave.


Ds3 is the musical note D sharp in the third octave.
To convert this information into a musical tune takes a bit of patience.

Ian Burn

January 31, 2005

V5.0

I did find one problem when using the 12F675 for music.
When using the 12F675s internal oscillator (may not be significant) and operating at lower voltages (3
to 4.5) distortion of the higher notes can occur if the coupling capacitor is 10 mfd. This may also be a
function of the speaker used. By dropping the
cap to 3.3 mfd the problem was eliminated
3 AA BATTERIES
and it worked down to 3V.
In the Sound Example circuit the 12F675 is
normally in SLEEP mode and draws less
than 1 microamp. SW1 operates the RESET
on the MCLR pin and wakes up the PIC,
starting the music.

The @SLEEP command is used in this


program and is explained later on in
Section 8

R1
10k

4V5

C2

U1

0.1

Vdd/+

Vss/Gnd

GP5

GP0/AN0

GP4/AN3

GP1/AN1

C1
4

GP3/MCLR

GP2/AN2

3.3 mfd

PIC12F675

This short tune is Shave and a Haircut.


I have programmed a number of full length
songs but it does a fair bit of time.

SPEAKER

SW1

R2

8 Ohms

100

A Sound Example
'A Sound Example - January 27, 2005
The tune, Shave and a Haircut is played and then the 12F675 goes to sleep toconserve the batteries
sleep current is less than I microamp
MCLR reset is used to wake up the 12F675
Front-end Seup
@ Device PIC12F675,WDT_OFF,PWRT_OFF,PROTECT_OFF,MCLR_ON,BOD_OFF
sets configurations
ADCON0=0
'no ADC used
ANSEL=0
'no ADC input - IMPORTANT if using ports in digital mode
CMCON=7
' turns off comparator function - IMPORTANT if using ports in digital mode
TRISIO= 8
Sets GPIO.3 as input, all others as outputs. Equivalent to TRISIO =%001000
Define variables
MPIN VAR GPIO.2
y VAR BYTE

'music pin set as GPIO.2


adjustable time delay between notes

Program
START:
y=4
set delay between notes = 4 x 12 mSec = 28 mSec
Sound MPIN, [109,40,0,y,102,20,0,y,102,20,0,y,105,40,0,y,102,20,0,y,0,40,108,40,0,y,109,40,0,y]
@ SLEEP
assembler sleep forever command
Pause 100
give PIC time to wakeup
GOTO START
End

music

171 words

Ian Burn

January 31, 2005

V5.0

HINT: If memory space becomes critical, you can save a few words by using
LED=0 and LED=1
each use 1 word of memory
instead of:
Low LED and High LED each use 3 words of memory

HINT: Constantly moving a PIC between a test circuit breadboard and the chip
programmer can lead to pin damage. One way to minimize this damage is to
mount the PIC in a machine pin socket and move the complete unit back and
forth. I know, you do that already!!

6. In Circuit Serial Programming (ICSP)


I have experimented with this method of programming and have found some things that work and
some that dont. The following is based on experience with the PIC12F675 and MeLabs EPIC Plus
Programmer although I expect most points will be directly transferable to other PICs and other
programmers.
Advantages of ICSP
The advantage of ICSP in circuit development is that you do not have to continually transfer the PIC
to the programmer every time you make a software change.

What is ICSP?
ICSP, as I have been using it, is the normal high voltage programming usually done with the PIC
mounted in the programmer only in this case it is left in the circuit with the other components attached.
Five lines run from the programmer to the PIC and associated circuit. These are:
+5VDC (Vdd)
Ground (Vss)
Data line
Clock line
Vpp/MCLR programming line
Ideally one would have a jack mounted on the circuit board or breadboard that would accept the 5
lines via a plug and cable connected to the programmer. This allows the programming lines to be
easily removed while the program is running.

Design requirements
The Microchip data sheet indicates that the external circuitry connected to the CLOCK , DATA and
MCLR ports must be done via a resistor so as not to load down the programming voltages. Similarly
the capacitance on these ports must be limited for the same reason.
Ian Burn

January 31, 2005

V5.0

I have found that R1 and R2 can be as low


as 470 ohms thus allowing the driving of
LEDs from the CLOCK and DATA ports.

To normal circuit

PIC

Connections
from Programmer

If a PIC is used that is set up for an internal


MCLR resistor (MCLR OFF), R3 can be
omitted unless it is used as an input port.

Vdd (+5V)

Vdd (+5V)

Vss (gnd)

Vss (gnd)

Programmer current limitations

Clock

Clock

Data

Data

Vpp

MCLR/Vpp

Normally the supply voltage to the


breadboard or end product circuit board
is removed during the ICSP process.

R1

R2

R3
10k

Vdd

To normal circuit

Since the +5VDC from the programmer


is feeding the PIC and since this lead on
Basic ICSP Connections
the PIC is connected to other components,
the programmer will have to be able to supply enough current to operate the overall circuit. There are
ways around this if it is a problem.

Testing ICSP - Things that work and things that dont.


I used the internal RC oscillator and the internal and turned the MCLR OFF.
Diodes D1 and D2 allowed me to have both the programmer and the circuit activated at the same time
even though I was using 4.5 volts to operate the circuit and 5 volts from the programmer.
C2

D2

+4.5 VDC

0.1

U1
1

D4
DIODE

D3

LED

Vss/Gnd

GP5

GP0/AN0

D1 LED
2

D5
LED

Vdd/+

R2 470

D6 LED
3

GP4/AN3

GP1/AN1

GP3/MCLR

GP2/AN2

R3 470

C1 3.3 mfd

DIODE
R1
470

SPEAKER

PIC12F675
R4
470

8 Ohms

GND

Vdd

VPP

Vcc

Data Clock

PROGRAMMER

2k

Testing ICSP with the 12F675


Testing ISCP with the 12F675

Ian Burn

January 31, 2005

V5.0

I was able to blink LEDs D1, D4 and D5 and have a tone at the speaker. I was even able to leave the
programmer connected and send in new programming data to the 12F675 with the circuit under power.
But as soon as LED D6 was added I ran into trouble if the programmer was connected and I tried to
run the circuit. Within the EPIC Programmer there is an effective resistance of 2K between the
CLOCK and DATA lines such that the outputs from the PIC at these two ports were effectively
connected together causing the LEDs to interfere with each other. This problem is obviously
eliminated by disconnecting the programmer lines when the circuit is operating.
I also could NOT get the PIC to sleep properly with the programmer connected.
I next tried to use the external MCLR resistor (MCLR=ON) and found that I could not run the circuit
with the programmer Vpp/MCLR line left connected.
The best practice is to disconnect the programmer once the programming has been completed.
Again, a convenient plug/jack would be helpful.

Ian Burn

January 31, 2005

V5.0

7. Analog to Digital Converters (ADCs)


The 12F675 has four ADC inputs, AN0 - AN3 (check the pin numbers on page 2. )
The output from the ADC converter will be a number between 0 and 1023 representing the lower and
upper voltage limits.
The input voltage must not exceed the Vdd-Vss range. The upper voltage limit can be set at Vdd or to
a Vref+ voltage less than Vdd.
In the example below, the Upper limit of the input is set at Vdd and would give a value of 1023. If
Vref+ was used and was set at 1.5 VDC, then 1.5 V would equal a value of 1023 and 0 V = a zero
ADC value. When Vref+ is used, it is applied to pin6 (see pin out on Page 3)
All ADC inputs must use a common upper limit of
either Vdd or Vref+. They cannot be set individually
on the 12F675.

BAT1

4V5

C1

U1

0.1

The 12F675 does not offer a Vref- option.


1

To use one or more of the four ADC inputs,


a number of parameters must be set.

Vdd/+

R1

Since it is a 10 bit ADC use:

Vss/Gnd

GP5

GP0/AN0

GP4/AN3

GP1/AN1

GP3/MCLR

GP2/AN2

10k
4

DEFINE ADC_BITS 10
PIC12F675

Use the internal clock and set:


DEFINE ADC_CLOCK3
ADC Input at AN3, GPIO.4
(Input range Vss to Vdd)

Sample timing is set by:


DEFINE ADC_SAMPLEUS 50

BAT1

For detailed explanations of these statements,


please refer to the Microchip PIC12F629/675
Datasheet.

Vref+

Assuming that the Comparator function is not


being used, it must be turned off:

R1

4V5

C1

U1

0.1

Vdd/+

Vss/Gnd

GP5

GP0/AN0

GP4/AN3

GP1/AN1

10k
4

CMCON=7

GP3/MCLR

GP2/AN2

Vref+

PIC12F675

ADC Input at AN3, GPIO.4


(Input range Vss to Vref+)
It is next necessary to set the ADCON0, ANSEL and TRISIO registers
Ian Burn

10

January 31, 2005

V5.0

From Microchips PIC12F629/675 Datasheet - Page 41

ADCON selects the output format, the reference voltage and which ADC inputs you wish to use.
In the example that follows we want the following:
Right justified output therefore
BIT 7 = 1
Reference voltage at Vdd therefore BIT 6 = 0
Bit 5 and 4 are not used and set at 0
One ADC input, GPIO.4 is used (AN3) therefore
BIT 3 = 1
BIT 2 = 1
The ADC input will start right away and always be on therefore
BIT 1 = 1
BIT 0 = 1
This results in an ADCON0=10001111 for the 8 bits but this must be expressed as a decimal number
which is 143, therefore
ADCON0=143

Ian Burn

11

January 31, 2005

V5.0

From Microchips PIC12F629/675 Datasheet - Page 42

The ANSEL register is used to set the timing and to set the ADC pin.
In the example that follows, timing was set at Fosc/2 (see Microchip Datasheet for details) therefore:
BIT 7 = 0 Unimplemented
BIT 6 = 0
BIT 5 = 0
BIT 4 = 0
We are selecting GPIO.4 or AN3 for the ADC input line, therefore:
BIT 3 = 1
BIT 2 = 0
BIT 1 = 0
BIT 0 = 0
ANSEL = 00001000
ANSEL=8

Ian Burn

12

January 31, 2005

V5.0

TRISIO Setting the input/output pins


In our example it is necessary to set all pins as outputs except for GPIO.4 and the MCLR or GPIO.3.
GPIO.4 will be the ADC, input pin
TRISIO=%011000

or TRISIO=24

The previous ADC circuits are fine except it would be useful to have some form of output.
The following example will use a variable voltage input into AN3 (GPIO.4) with the range being
between ground and the supply voltage, Vss and Vdd. This will provide ADC values from 0 to 1023.
The outputs will be a LED that turns on if ADC is above 500 and sound ranging from note values of
1 to 120, corresponding to ADC values of 0 to 1023.
The MCLR will be turned OFF, making GPIO.3 an input. To prevent noise entering this un-used port,
it will be connected to Vss.

3 AA BATTERIES

4V5

C2

U1
1

0.1

Vdd/+

Vss/Gnd

GP5

GP0/AN0

GP4/AN3

GP1/AN1

GP3/MCLR

GP2/AN2

D1
2

R1

R2
470

10k

LED

SPEAKER

C1
4

3.3 mf d

PIC12F675

8 Ohms

ADC Example with Audio Frequency Output Proportional to Input Voltage

Ian Burn

13

January 31, 2005

V5.0

'ADC Example #1
'A variable voltage is applied to AN3, GPIO.4 The range will be Vss to Vdd
'The LED will come on if the ADC value equals or exceeds 500
'Sound output, a 120 mSec beep, will have a frequency proportional to the input voltage.
'A #120 tone is used at the top end as the higher audio frequencies sometimes distort
'depending upon the speaker. A 0.001 mfd cap across the speaker may allow use of up to #127
'Front-end setup
@ Device PIC12F675,WDT_ON,PWRT_ON,PROTECT_OFF,MCLR_OFF,BOD_OFF
'sets configuration
ADCON0=143
'set AN3 ON ie GPIO.4
ANSEL=8
'sets Fosc/2 and GPIO.4 [AN3] as ADC input
CMCON=7
'turns off comparator function
TRISIO=%011000
'sets GPIO.4 as in input and all others as outputs could also use TRISIO=24
DEFINE OSCCAL_1K 1
DEFINE ADC_BITS 10
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50

' Set OSCCAL for 1K device - calibrates the internal oscillator - not really needed here
'ADC settings
'ADC settings
'ADC settings

Define variables
RDG VAR WORD
MPIN VAR GPIO.2
LED VAR GPIO.0
TONE VAR WORD

'ADC reading from AN3


'Music pin output to speaker
'LED output
'tone value for the sound command

'Initial settings
LED=0
'Program
START:
LED=0
ADCIN 3, RDG
Pause 100
IF RDG =>500 Then LED=1
TONE = 1+(rdg/10)*119/102

Sound MPIN,[TONE,20]
GoTo START
End

reset LED to off at the beginning of each program cycle


'get voltage reading from AN3 and place ADC value in 'RDG'
allow time for ADC calculation
'turn on LED if ADC value is equal to or larger than 500
'converts ADC value to a 'TONE' value of 1 to 120
'necessary to divide by 10 to avoid 65535 word limit
'ADC of 0 = tone of 1, ADC of 1023 = tone of 120
'provides a tone proportional to input voltage. Duration =20x12=120 mSec

'277 words

HINT: ADC circuits frequently have a voltage divider across the battery, constantly
drawing current. Depending upon how often ADC readings are needed, you can
conserve battery life by supplying the ADC reference voltage from an unused port.
Make the port high just prior to taking an ADC reading then return it to low when
finished. You will still be using the Vdd as reference, not the Vref+ option.
For example a thermistor used in a divider to monitor a deepfreeze temperature may
require a reading every 10 minutes - no need to be drawing current all the time.

Ian Burn

14

January 31, 2005

V5.0

8. Sleeping
Many of my 12F675 circuits operate on 3 AAA or AA batteries. If the circuits operate continuously
there is often an opportunity to have the PIC SLEEP during a major part of its operating cycle.
The typical sleep current for the 12F675 is less than 1 microamp. I am not sure how much less as my
meters dont go low enough, but the current will be close to the shelf life of the battery!
The two SLEEP commands that I use are:
@SLEEP

and

SLEEP period

@SLEEP is an assembler sleep instruction which puts the PIC to sleep until it is awakened by:
the watchdog timer because you forgot to turn it off!!
an interrupt (eg interrupt on change)
a reset of the MCLR if it is used
A Pause 100 after the @SLEEP command allows time for the PIC to wakeup
SLEEP period is a PBP Compiler statement where period is the number of seconds between 1 and
65535 - a range of from 1 second to 18.2 hours. Longer periods have to be accomplished by using
loops. (eg for x= 1 to 10; SLEEP 64800; next x .= 18 hours x 10 =180 hours). This command uses
the watchdog timer which must be turned ON, unlike the @SLEEP command.
Many things can influence the sleep current, including:
Brown out detection - turn off to minimize sleep current ie BOD_OFF in the configuration
Set all unused ports as outputs. If GPIO.3 is not used as MCLR, connect to either Vss or Vdd
Tie the unused ports to Vdd using the internal weak pull-up (see page 19)
If using the POT command, set the POT port low before going to sleep, bring high on
awakening
Turn off the ADC reference voltage by using the statement : VRCON=0
turn off watchdog timer is using @SLEEP ie WDT_OFF in configuration
input data must not be changing.

HINT: Continually changing data entering an INPUT port will prevent the 12F765
from reaching minimum SLEEP current. Depending upon the input circuitry, you might
convert the port in question to an OUTPUT during the SLEEP part of the program. Be
sure to change it back to an INPUT on awakening. eg TRISIO.4=0..then..TRISIO.4=1

Ian Burn

15

January 31, 2005

V5.0

9. Interrupt-on-Change
A useful way to wake up a sleeping PIC is by using an interrupt-on-change.
For example if a battery powered 12F675 is meant to start some sequence of outputs after receiving an
incoming pulse, it is likely a good idea for it to be in SLEEP mode until the pulse arrives.
The Interrupt-on-Change (IOC) can be set for either a positive or negative going pulse and can be
allocated to any GPIO pins by setting the IOCB Register . The GPIE variable must be set in the
INCON Register and the falling edge option
is set in the OPTION Register.
+

BAT1

4V5

Heres how to do it.


C1 0.1

First lets assume we have a project where


a switch closure, SW1, causes a LED, D1,
to flash 10 times. A very simple objective.

U1
1

R2

GPIO.3 and 4 will be set as inputs and


GPIO.3 is not used and will be connected
to Vdd.

Vdd/+

Vss/Gnd

GP5

GP0/AN0

GP4/AN3

GP1/AN1

10k
3

R2 will hold GPIO.4 high until SW1 closes.


The interrupt on change at GPIO.4 will
be negative going.

GP3/MCLR

GP2/AN2

R1
1k
D1

PIC12F675
SW1

The next step is to tell the IOCB Register


which ports are using the IOC function.

Interrupt on Change

From Microchips PIC12F629/675 Datasheet - Page 20

Using the information above, we will set IOCB= 00010000 or


Ian Burn

16

IOCB = 16
January 31, 2005

V5.0

Next we have to set the Interrupt Control Register, INTCON

Question - will SLEEP 65535 wake up with interrupt on change?

From Microchips PIC12F629/675 Datasheet - Page 13

We arent dealing with a lot of the information here. We only need to enable the GPIE variable.
Bit 7 = 0
Bit 6, 5 and 4 = 0
Bit 3 = 1
Bit 2 and 1 = 0
Bit 0 = 0

Must be 0 in this application


Not used in this case
Must Enable GPIE
Not used in this case
Initially set at 0 and again just before @SLEEP

Therefore INTCON = 00001000 or

Ian Burn

INTCON = 8

17

or you could use INTCON.3=1

January 31, 2005

V5.0

One other key item is to turn off the GPIF, Bit 0, of INTCON just prior to the @SLEEP command.
This can be done by using INTCON.0=0

'Example of Interrupt on Change


'It will then blink a LED times and go back to sleep

January 26, 2005

From Microchips PIC12F629/675 Datasheet - Page 12

Two items of interest are in this register - Bit 6 and Bit 7 both of which need to set at 0
by using:
OPTIONS_REG.6=0
OPTIONS_REG.7=0

This set interrupt on the falling edge of the pulse.


This enable the weak pull up resistors needed to stabilize the
unused ports

However, all the bits could be set at 0 without a problem so we could also use:
OPTION_REG=0

Ian Burn

18

January 31, 2005

V5.0

From Microchips PIC12F629/675 Datasheet - Page 12

GPIO ports 1, 2 and 5 are not used and can be tied to Vdd using the weak pull-up resistors
therefore WPU=%00100110 or WPU = 38

After all this nonsense, here is the program!


'Example of Interrupt on Change
January 26, 2005
'A change from Vdd to Vss on GPIO.4 will cause the 12F675 to wake up
'It will then blink a LED times and go back to sleep
'Front end setup
@ Device PIC12F675,WDT_OFF,PWRT_ON,PROTECT_OFF,MCLR_OFF,BOD_OFF 'sets configuration
TRISIO=24
'sets GPIO.3 and GPIO.4 as inputs and all others as outputs (or %00011000)
CMCON=7
'turns off comparator function
ADCON0=0
'no ADC - doesn't seem necessary but may be a good idea
ANSEL=0
'no ADC input - IMPORTANT if using ports in digital mode
VRCON=0
'turns off voltage reference to minimize sleep current
INTCON=8
Enables port change interrupt ie GPIE
IOCB=16
'sets GPIO.4 for Interrupt on change
OPTION_REG.6=0
'INT on falling edge
OPTION_REG.7=0
'00000000 WPU enabled,
WPU=38
'00100110 = 38 set unused ports 1,2 and 5 tied to weak pull-up resistors
'Define Variables
wakeup VAR GPIO.4
LED VAR GPIO.0
x VAR BYTE

'input, interrupt on change.


'LED output

'Initial settings
LED=0

Ian Burn

19

January 31, 2005

V5.0

'Program
START:
INTCON.0=0
Pause 100
@ Sleep
Pause 100
For x= 1 TO 10
LED=1
Pause 300
LED=0
Pause 300
Next x
GoTo start
End
'90 Words

HINT: When building a circuit with a sleep component, removing the power from the
circuit doesnt necessarily turn off the PIC. The charged 0.1 mfd bypass capacitor can
keep a sleeping PIC operating for awhile after the power is removed. To be sure it has
reset, short out Vdd to Vss once the power is removed.
The other option is to use the MCLR with a reset button.

HINT: Using the internal weak pull-up resistors can eliminate external pull-up resistor
on switched inputs.

Ian Burn

20

January 31, 2005

V5.0

10. Lost Calibration code


In the last flash memory slot of a new 12F675 there is a calibration code that is placed during chip
manufacture. The code has a hex value of 34xx where the xx part varies from chip to chip. This code
is retrieved using the DEFINE OSCCAL_1K 1 statement. The last two hex digits, xx, of the code
are then placed in the OSCCAL register and the chips internal oscillator is adjusted to operate at
4 MHz.
If serial data, for example, is not being sent by the 12F675 then an exact 4 MHz may not be necessary
and the DEFINE statement can be omitted.
It is possible to erase the calibration code, in which case the DEFINE OSCCAL_1K 1 command
finds nothing to forward to the OSCCAL register and the chip will not operate.
If you do erase the calibration code, you have three options:

Use the 12F675 in applications where timing isnt critical and omit the
DEFINE OSCCAL_1K 1 statement.

IF you know the last two hex digits of the calibration code you can insert them directly
into the OSCCAL register using:
OSCCAL=$xx
For example if the code is 34a8, use:
OSCCAL=$a8
DO NOT use the DEFINE OSCCAL_1K 1 statement as there is no calibration code to read
and then transfer to the OSCCAL register.

If you DO NOT know the calibration code (as in my case, with two 12F675's!!!)
use OSSCAL $80 as a starting point. (do not use DEFINE OSCCAL_1K 1 )
Connect a scope or frequency counter to Pin 3 (GPIO.4/OSC2/CLKOUT).
When programming the chip, set the Oscillator Configuration to "INTRC Clockout".
This must be done within the programmer software not the @DEVICE codes.
You will get a square wave at 1/4 of the oscillators frequency ie 1 MHz on Pin 3
Here are my results:
OSSCAL= $80
OSSCAL= $90
OSSCAL= $85
OSSCAL= $89
OSSCAL= $8c
OSSCAL= $8d

Freq=966 kHz
Freq=1001 kHz
Freq=977 kHz
Freq=991 kHz
Freq=998 kHz
Freq=1000 kHz

I have now labeled this PIC as an "8d" and will use


OSSCAL= $8d when I need accurate timing!
INTRC Signal
There is obviously some merit in recording the calibration number on the back of each 12F675
chip!

Ian Burn

21

January 31, 2005

V5.0

11. Feedback and Acknowledgements


If you have found this useful and/or have any suggestions, please let me know:
Ian Burn
Edmonton, Alberta, Canada
ianburn@shaw.ca

Special thanks to Melinda Burn and Angus Cameron in assisting with PDF conversions and
editing suggestions.

Ian Burn

22

January 31, 2005

V5.0