I need to use pin4 RA5/MCLR/VPP on a 16F88 as an I/0 pin and
not MCLR. I've looked through the datasheet and on the
internet but can't seem to find the code to do this. I'm
using basic not asm.
Bit 5 in the config word must be cleared. In your config word statements you would put "_MCLRE_OFF" when programming in assembly.
However, the MCLR pin only functions as an input only when set for digital I/O. It cannot be used as an output. This is set at the hardware level...there's no way to "trick" it in software or anything like that.
I need 7 output ports to drive a 7 segment display and
I see RA6 is only an input.
I'm using RB0 as an external interrupt and I will need
2 more interrupt ports later. So does that mean that
I have to divide up my 7 outputs between ports A&B?
That would make for ugly software.
I need 7 output ports to drive a 7 segment display and
I see RA6 is only an input.
I'm using RB0 as an external interrupt and I will need
2 more interrupt ports later. So does that mean that
I have to divide up my 7 outputs between ports A&B?
That would make for ugly software.
Have you considered using a serial shift register to drive the LED display? You can use the USART pins on the PIC to send the display data via serial to the shift register, and the shift register will have an 8 bit parallel output (8 pins...1 for each data bit) that can drive the display. This way you're only using one pin on the PIC to send the data, but using the SSR to directly drive it.
Jon,
I'm very new to microcontrollers so this an approach I'm
not familiar with. I'll read up on the USART function.
The shift register would be a separate device.. right?
Incidently I've been through Rhonert park many times on
the way to Santa Rosa. Nice place.
Edit, if you need three interrupt pins then you'll have to use PortB change interrupt. To work out which pin changed and in which direction is a little tricky but can be done. I have posted an example somewhere in asm but it should be easy to convert. Which compiler are you using?
Jon,
I'm very new to microcontrollers so this an approach I'm
not familiar with. I'll read up on the USART function.
The shift register would be a separate device.. right?
Incidently I've been through Rhonert park many times on
the way to Santa Rosa. Nice place.
Yes the shift register chip is a separate device. The PIC would drive its "data input" via serial interface.
I've only been coding PICs since September so you can say I'm new to them as well. I kinda started digital electronics at that time but have been doing analog electronics for about 20 years so for me the hardware side of things was simple. Just a matter of learning assembly code for me...which is much easier than you think. Much easier than BASIC when it comes to PICs I must say.
Why use a second chip? It sounds like the 16F88 will do the job anyway but if not then switch to the 28 pin 16F883. There's only about 50c difference in price and the 16F883 is the cheaper one. Go figure.
I built a programming board(soldered connections) and only
installed an 18 pin socket. So I'm stuck with the 16F88
for now.
I have an external interrupt working on RB0. It's a 60HZ
signal comming from the AC line through a 1K resistor and
a 5.1v zener diode to ground. I count interrupts in my ISR
routine to get a 1HZ signal. Since RBO is a Schmitt trigger
input it works fine for blinking an LED.
Now I need 2 more external interrupts. I have gotten a
change-on-state working on RB6 but I can't seem to stop
the mismatch condition by reading PORTB.
Here's part of my ISR routine:
dim pb as byte
sub procedure Interrupt
if INTCON.RBIF = 1 then 'change on RB4-RB7 ?
pb = PORTB 'read port b to clear the mismatch
INTCON.RBIF = 0 'clear the Interrupt flag
pb = PORTB 'read port b to clear the mismatch
PORTB.6 = 1 'PORTB.6 high
return
end if
As you can see I'm trying to read PORTB a couple of times
but it doesn't seem to work.
Also I can't figure out how to distinguish which PORTB pin 4-7
caused the mismatch interrupt. Pommie I couldn't find your
example.
I can write in asm but I'm teaching this to an 11 year old
who knows basic and assembly might be overwelming for him.
It's a 60HZ signal comming from the AC line through a 1K resistor and a 5.1v zener diode to ground. I count interrupts in my ISR routine to get a 1HZ signal. Since RBO is a Schmitt trigger input it works fine for blinking an LED.
To poll individual bits it will probably be something like
Code:
if PORTB.RB4 = 1
//Button 1 code here
if PORTB.RB5 = 1
//Button 2 code here
if PORTB.RB6 = 1
//Button 3 code here
if PORTB.RB7 = 1
//Button 4 code here
Gobbledok:
Thanks for the polling code. I should have been able to figure
that out myself.
I changed my ISR routine so I no longer have the "return"
command but I still can't cancel the mismatch condition.
Maybe I'm not reading PORTB right.
Pommie:
Looks like you may be right about the I/O status of the PORTA
pins on the 16F88 although on page 1 of the datasheet there is
a pin diagram for 18 pin PDIPS that indicates that RA5 and RA7
are inputs only and RA6 is only output. This is in conflict
with the pin diagram on page 2 which agrees with you.
Anyone have any ideas why I can't cancel the mismatch condition.
That should clear the mismatch unless b6 is set to input.
To work out which bit changed you need to keep the previous state. You then XOR with the previous state to get pins that have changed and then AND with current state to get new highs.
Pseudo code,
Code:
byte previous, changed, newLows, newHighs
ISR pb=PORTB
INTCON.RBIF = 0
changed = pb XOR previous
newHighs = changed AND pb
newLows = changed AND previous
previous = pb
'to check if B6 went low check newlows.6 = 1
'to check if B4 went high check newHighs.6 = 1
This code will catch all changes, even if two bits change at the same time and in different directions.
Note that the code only reads portb once, this is important if you don't want to miss transitions.
Edit, if you can't clear the mismatch, can you post the asm that is generated.
You replied while I was posting and I just had another thought. Do you have a pin (B4-B7) that is open circuit and set to input? If so it will pick up noise and cause continual interrupts and it will cause the problem you describe.
Pommie:
I kind of have the change state interrupt working.
After I added your code suggestions it still didn't
work but once I hung my scope probe on RB4 it works.
The probe is 100MHZ passive. In X1 mode the input
resistance is 1M and the capacaitance is 85-115pf.
The internal pull ups were turned off so I tried turning
them on. Didn't help.
Only RB0, RB4 and RB5 are inputs.
The other thing that's strange is if I don't define RB5
as input nothing works. And when RB5 is an input my code
detects a change on RB5 even though I'm not checking for it.
Here's the ISR routine:
dim pb as byte
dim previousPB as byte
dim changed as byte
dim wentHigh as byte
dim wentLow as byte
sub procedure Interrupt
'first check for Changed State Interrupt
if INTCON.RBIF = 1 then
pb = PORTB 'read portb
INTCON.RBIF = 0 'clear the Interrupt flag
changed = pb XOR previousPB 'get any/all changes
wentHigh = changed AND pb 'get any changes from low to high
wentLow = changed AND previousPB 'get any changes from high to low
previousPB = pb 'remember the current portb states
'now check if RB4 changed state
if changed.4 = 1 then
'RB4 has changed so check for high of low going edge
if wentHigh.4 then
PORTB.6 = NOT PORTB.6 'invert portb.6
end if
i = 0 'clear software Interrupt counter for RB0
end if
CMOS rules state that all input lines MUST have a pullup resistor on them. If you don't have pull up resistors on them, the pins will be in an undefined state when nothing is hooked up to them.