View previous topic :: View next topic |
Author |
Message |
GUest1 Guest
|
Problem with MCLR on 12F509 |
Posted: Sat Jan 19, 2008 12:19 pm |
|
|
Hi
I have written this small demo program
Code: |
#include "12F509.h"
//#use fast_io(B)
#fuses INTRC,NOWDT,NOPROTECT,NOMCLR
#use delay(clock=4000000)
#define set_options(value) {#ASM \
MOVLW value \
OPTION \
#ENDASM}
#define ON 1
#define OFF 0
#define FIRE pin_b0 //ouput
#define ONOFF pin_b3 //input
#define ADJUST pin_b1 //input
#define LED pin_b2 //output
#define DEBOUNCE_TIME 100 //20ms debounce time
#define ENABLEPULLUPS (0)
#define DISABLEPULLUPS (128)
unsigned char debounce_ONOFF (void);
void main(void)
{
/******************************************************************************
Initilisation
******************************************************************************/
boolean out = OFF; //The output bit
boolean onoffbutton; //On Off button
SETUP_TIMER_0(RTCC_DIV_1 | ENABLEPULLUPS); //Work around to enable pullups
set_options(0x80); // Allow use of GP2 for i/o
/******************************************************************************
Main
******************************************************************************/
while(1)
{
onoffbutton = debounce_ONOFF(); //read button
delay_ms(100);
out ^= 0x01;
output_bit (FIRE,out); //Toggle output
output_bit (LED,out); //Toggle output
}
}
unsigned char debounce_ONOFF ()
{
if (!input(ONOFF))
{
delay_ms(DEBOUNCE_TIME);
if (!input(ONOFF)) return 1;
}
return 0;
}
|
I would expect the LED to toggle at a rate of 100ms + 100 ms ( debounce time + delay_ms)
However when I run it toggles at 100ms
When I press my button (a switch to ground off GP3) the toggle time then becomes 200ms.
I was wondering if this is something to do with the MCLR function(GP3 alternate function) but I cant understand why it behaves like this. |
|
|
Guest
|
|
Posted: Sat Jan 19, 2008 12:28 pm |
|
|
sorry, should read more easily
Code: |
#include "12F509.h"
#fuses INTRC,NOWDT,NOPROTECT,NOMCLR
#use delay(clock=4000000)
#define set_options(value) {#ASM \
MOVLW value \
OPTION \
#ENDASM}
#define ON 1
#define OFF 0
#define FIRE pin_b0 //ouput
#define ONOFF pin_b3 //input
#define ADJUST pin_b1 //input
#define LED pin_b2 //output
#define DEBOUNCE_TIME 100 //20ms debounce time
#define ENABLEPULLUPS (0)
#define DISABLEPULLUPS (128)
unsigned char debounce_ONOFF (void);
void main(void)
{
/******************************************************************************
Initilisation
******************************************************************************/
boolean out = OFF; //The output bit
boolean onoffbutton; //On Off button
SETUP_TIMER_0(RTCC_DIV_1 | ENABLEPULLUPS); //Work around to enable pullups
set_options(0x80); // Allow use of GP2 for i/o
/******************************************************************************
Main
******************************************************************************/
while(1)
{
onoffbutton = debounce_ONOFF(); //read button
delay_ms(100);
out ^= 0x01;
output_bit (FIRE,out); //Toggle output
output_bit (LED,out); //Toggle output
}
}
unsigned char debounce_ONOFF ()
{
if (!input(ONOFF))
{
delay_ms(DEBOUNCE_TIME);
if (!input(ONOFF)) return 1;
}
return 0;
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Jan 19, 2008 12:45 pm |
|
|
The OPTION register controls the pre-scaler for TIMER0.
You have two functions that write to the OPTION register:
Quote: |
SETUP_TIMER_0(RTCC_DIV_1 | ENABLEPULLUPS);
set_options(0x80); |
Look at the .LST file (it's in your project directory). It shows the ASM
code generator by the compiler. You can see that both functions are
writing to the OPTION register, and that the set_options() function is
over-writing the value of 0x08 with a new value of 0x80. It's taking
the pre-scaler away from Timer0 and assigning it to the Watchdog Timer.
This is explained in the 12F509 data sheet, in the section on the OPTION
register.
Code: |
.... SETUP_TIMER_0(RTCC_DIV_1 | ENABLEPULLUPS);
0003: MOVLW 08
0004: OPTION
....
.... set_options(0x80);
0005: MOVLW 80
0006: OPTION |
The reason you originally added the set_options() function was because
you were not using the setup_timer_0() in your program, and you wanted
a way to set the OPTION register. But now, you have modified your
program to add a call to setup_timer_0(), which does configure the
OPTION register.
Solution: Delete the line that calls set_options(0x80). You don't need
it anymore. Or at least, comment it out, and add a note that it's not
needed as long as setup_timer_0() is being used.
Also, you could use a consistent screen name. Previously you were stewc
but now you're "guest1". |
|
|
stewc Guest
|
|
Posted: Sat Jan 19, 2008 1:09 pm |
|
|
Hi
Yes, that all makes sense. I included the line
to enable pullups, I am not using the TMR0
I tried commenting out the line you said and it made no difference. Even tried it with the options set to 80, still the same.
It appears that when I pull GP3 to ground the program runs correctly - but this is undesirable as I have an input switch in GP3.
I could use another pin but I want to get the the bottom of it. I must have some fuses/settings wrong but I cant see where . AAARRGG!!
(username ok now) |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Jan 19, 2008 1:17 pm |
|
|
Quote: | I am not using the TMR0 |
I can see that now. I jumped on the timer0 issue because I knew that
both of the functions were changing the OPTION register. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sun Jan 20, 2008 12:01 am |
|
|
Quote: | I would expect the LED to toggle at a rate of 100ms + 100 ms
(debounce time + delay_ms). However when I run it toggles at 100ms.
When I press my button (a switch to ground off GP3) the toggle time then becomes 200ms. |
I converted your program to run on a 16F877, and it runs exactly the
same way. That's the way it should run. There is a 100 ms delay in
the while() loop all the time. Optionally, there is another 100 ms
delay added to it if you hold down the pushbutton.
In your code below, you test the "ONOFF" pin to see if it's low.
If it is, then you execute the code inside the braces, which includes
the debounce delay.
Quote: | unsigned char debounce_ONOFF ()
{
if (!input(ONOFF))
{
delay_ms(DEBOUNCE_TIME);
if (!input(ONOFF)) return 1;
}
return 0;
} |
|
|
|
stewc Guest
|
|
Posted: Sun Jan 20, 2008 5:44 am |
|
|
ah yes, i see that now. i thought it would always run the debounce routine but its in a conditional statement
thanks |
|
|
|