PDA

View Full Version : PIC16F676 troubles



keithv
- 27th May 2015, 21:27
I've chosen the 16F676 for size and cost and it also has an ADC which I also need. I need to use all the I/Os and I need to use PORTA.3 (MCLR) as a digital input to be used with a button. The "big" program isn't working so I've broken it down into smaller parts to make sure everything is working correctly. Below is the code to use the button to toggle an LED on and off. The start up works and the button turns the LED on, but only one time. Once the LED is toggled on for the first time, it gets stuck. What am I doing wrong?




#config
__CONFIG _CP_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF
#endconfig


TRISA = 001000


LED var PORTA.1
PUSHBUTTON var PORTA.3


'***********************start up just to make sure LED is working**************************
led = 1
pause 100
led = 0
pause 100
led = 1
pause 100
led = 0
'************************************************* **************************************
main:


if PUSHBUTTON = 0 then

toggle led
pause 25

endif

goto main
end

Dave
- 27th May 2015, 22:17
Well actually, If you were to put a scope on the led pin you should see it toggling with a period of 50 Milliseconds while the push button is being pressed. I assume you have a pullup resistor connected to +5 volts and the Porta.3 pin?

keithv
- 27th May 2015, 22:50
I see your point. But the flaw in the code is not the underlying problem. It should flicker while the button is held down. And then land on ON or OFF 50:50, right? I changed the pause to 1000 and it's still the same. Yes, I have the a 10k pull up resistor to Vdd. Does the config section look correct? For some reason, the TRIS reg didn't cut and past completely. It should be

TRISA = %11001000

Does that look correct?
Do I need to do something with the C registry?

Tabsoft
- 27th May 2015, 23:21
I don't see where you are configuring the analog select register ANSEL.
By not explicitly setting the value of this register the PIC is using the default value, which might be enabling some pins as analog.

Check the Datasheet to verify how you want them set and make sure you add the appropriate ANSEL = xxx statement to the beginning of your program.

That may be causing you a problem.
I have found it is usually a good idea to check and set the registers for all of the hardware modules.

Might be worth checking.

keithv
- 27th May 2015, 23:57
I've tried several things with the registers, but no luck. I've also added a sub to make it behave the way it should:




#config
__CONFIG _CP_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT& _MCLRE_OFF
#endconfig

ADCON1 = %00000000
ANSEL = %00000100
CMCON = 0

TRISA = %11001100
TRISC = %00000000

LED var PORTA.1
PUSHBUTTON var PORTA.3


led = 1
pause 100
led = 0
pause 100
led = 1
pause 100
led = 0

main:

if PUSHBUTTON = 0 then
toggle LED
pause 25
gosub buttonrelease
pause 25
endif

goto main
end

buttonrelease:

do until PUSHBUTTON = 1
pause 10
loop

return



It still does the same thing. The LED flashes on power up. The button works once. And then it locks up. And I've tried several other "lower level" ways of making the LED toggle instead of the TOGGLE statement. It's always the same. Here's something interesting, though. If I change the code to just make the LED come on when the button is pressed instead of trying to toggle it like so:




main:

if PUSHBUTTON = 0 then
LED = 1
elseif PUSHBUTTON = 1 then
LED = 0
endif

goto main
end



Everything works perfectly! So I'm assuming the problem isn't with the MCLR pin or the registries. Do I need to define the oscillator?

Tabsoft
- 28th May 2015, 01:51
I think the issue is the Comparator module is still turned on.

Your CMCON = 0 sets the comparator to Reset with RA0 and RA1 connected to the Comparator module.
Have a look at the DS Figure 6-2 which shows the possible 8 modes of the comparator.
You should try setting CMCON = %00000111

keithv
- 28th May 2015, 20:47
That did the trick. Thanks, Tabsoft!

Tabsoft
- 28th May 2015, 23:03
Good deal.

I suspect with the Comparator module set to 000 whenever you perform a Toggle command this actually reads the port then writes the new value to it. This issue is that the port will always read 0 when it is configured in Reset mode.