|
|
View previous topic :: View next topic |
Author |
Message |
phased
Joined: 03 Oct 2006 Posts: 17
|
Waking up a PIC16F505... |
Posted: Tue Oct 17, 2006 11:38 pm |
|
|
Being a newbie is difficult, not because I don't know much, but because I don't even know enough to easily ask for help.
I've come to the conclusion that I'd REALLY like to see a piece of code that might demonstrate how the PIC16F505 is supposed to wakeup on a pin change.
I'm starting to see that this chip may not have interrupts. I'm probably wrong.
The ccs example, ex_wakup.c, seems to rely on them to wakup on a pin change. Hence, my frustration.
Many thanks to those that help.
Phased. |
|
|
Ttelmah Guest
|
|
Posted: Wed Oct 18, 2006 4:19 am |
|
|
Unfortunately, the examples, should perhaps carry with them a warning, that some specific PICs behave differently. A few of the smaller/older PICs, can only effectively 'reset' on a wakeup event, and some other individual PICs, have special 'wakeup' behaviour.
In the case of the 505, the chip has not got any interrupt support, but has the 'pin change' component of the interrupt circuit present, but wired directly to trigger a wakeup instead. Like the older chips, this causes a reset, rather than a program continuation.
The keys to using 'wakeup' on this chip, are:
1) At the start of the program, read the status register. If bit 7 is set, then this was a wakeup from sleep on pin change.
2) Read the port. You must do this before trying to sleep, to reset the
'pin change' latch. Beware though, that because the default in CCS, is 'standard_io', this will set the tris register to make all pins into inputs. Personally, I'd suggest using either 'fast_io', or 'fixed_io' modes, if you intend to use wakeup, since you can then read the whole port without tris changing...
3) Now send the chip to sleep.
So a basic 'core' to this would look something like (lacking the chip initialisation etc.)
Code: |
#use standard_io(b)
#bit GPWUF=3.7
void main(void) {
int8 dummy;
if (GPWUF) {
//Here code to be called on the 'wakeup' event
}
else {
//Here code for the initialisation of the chip, and normal boot
//Set tris for port b to suit your use here
dummy=input_b();
//Read the port
sleep();
//Code will never get here
}
}
|
So the CCS example, won't work with this chip, but the chip can be made to wakeup, just with rather different behaviour...
Best Wishes |
|
|
phased
Joined: 03 Oct 2006 Posts: 17
|
YOU SIR ARE A LIFE SAVER!!!!! |
Posted: Wed Oct 18, 2006 11:00 am |
|
|
YOU SIR, ARE A LIFE SAVER!!!!!
I knew something was fishy with this *$*$&# chip!
I actually have NO PROBLEM with the whole process restarting.
This is a GREAT HELP.
I CANNOT thank you enough! |
|
|
phased
Joined: 03 Oct 2006 Posts: 17
|
So here's my code. But it doesn't work... |
Posted: Wed Oct 18, 2006 12:41 pm |
|
|
First off, Thanks again for the help Ttelmah.
Secondly, here's my code: It compiles but doesn't work.
I want the pic to run lights(), then go to sleep. When I press the switch (RB3), it should wake up, then I want it to run lights(), then go to sleep....
My fuses could be wrong...
Also the rest of my code could be wrong....
Code: |
#include <16F505.h>
#fuses INTRC,NOWDT,NOPROTECT
#use delay(clock=4000000)
#use standard_io(b)
#bit GPWUF=3.7
void lights() {
long counter;
counter=0;
while(counter<5){
output_high(PIN_C0);
delay_ms(100);
output_low(PIN_C0);
output_high(PIN_C1);
delay_ms(200);
output_low(PIN_C1);
counter=counter+1;
}
}
void main(void) {
int8 dummy;
if (GPWUF) {
lights(); //Here code to be called on the 'wakeup' event
}
else {
//Here code for the initialisation of the chip, and normal boot
SET_TRIS_B( 0b00001000 );//Set tris for port b to suit your use here
dummy=input_b(); //Read the port
sleep();
//Code will never get here
}
}
|
|
|
|
phased
Joined: 03 Oct 2006 Posts: 17
|
ALMOST! |
Posted: Wed Oct 18, 2006 12:53 pm |
|
|
Sadly it doesn't work completely... Lights1() never gets called, though Lights() does.
And how can I be certain that the pic is in sleep mode? Check the current being drawn?
Code: | #include <16F505.h>
#fuses INTRC,NOWDT,NOPROTECT
#use delay(clock=4000000)
#use standard_io(b)
#bit GPWUF=3.7
void lights() {
long counter;
counter=0;
while(counter<5){
output_high(PIN_C0);
delay_ms(100);
output_low(PIN_C0);
delay_ms(200);
counter=counter+1;
}
}
void lights1() {
long counter;
counter=0;
while(counter<5){
output_high(PIN_C1);
delay_ms(100);
output_low(PIN_C1);
delay_ms(200);
counter=counter+1;
}
}
void main(void) {
int8 dummy;
if (GPWUF) {
lights1(); //Here code to be called on the 'wakeup' event
}
else {
//Here code for the initialisation of the chip, and normal boot
lights();
SET_TRIS_B( 0b001000 ); //Set tris for port b to suit your use here
SET_TRIS_C( 0b001000 );
dummy=input_b(); //Read the port
sleep();
//Code will never get here
}
}
|
|
|
|
phased
Joined: 03 Oct 2006 Posts: 17
|
Status register access |
Posted: Wed Oct 18, 2006 1:28 pm |
|
|
I can't seem to read the status register. Or more specifically I'd like to read the GPWUF (7th bit) of the STATUS register.
Here's some code to explain:
Code: |
#include <16F505.h>
#fuses INTRC,NOWDT,NOPROTECT
#use delay(clock=4000000)
#use standard_io(b)
#bit GPWUF=03.7
void main()
if (GPWUF)
function1();
else
{
function2();
sleep();
}
}
|
I can't seem to ever call function1().
I just don't know why... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Oct 18, 2006 2:12 pm |
|
|
You don't need to start a new topic every time you have a new idea
on the same project. Right now you have two orphan topics that are
based on this current thread. Can you delete these two topics ?
http://www.ccsinfo.com/forum/viewtopic.php?t=28579
http://www.ccsinfo.com/forum/viewtopic.php?t=28565
To delete a topic, view it, and click on the little "X" in the upper right corner.
-------------
To answer your question, the information is in the data sheet.
In the pin description section, it says:
Quote: |
RB0:
Bidirectional I/O pin. Can be software programmed for internal
weak pull-up and wake-up from Sleep on pin change. |
The operative words are "Can be". This means that somewhere,
there is a register that enables or disables wake-up on change.
Do a search (in the Acrobat reader) for "wake". Then you find
the OPTION register. Find the page for the 16F505. Here's what
it says:
Quote: |
REGISTER 4-4: OPTION REGISTER (PIC16F505)
Bit 7:
RBWU: Enable Wake-up on Pin Change bit (RB0, RB1, RB3, RB4)
1 = Disabled
0 = Enabled
(The power-up default state is '1', which means its disabled).
|
So you want to set it to 0, to enable wake-up on change.
How to do this ? The data sheet says this:
Quote: |
By executing the OPTION instruction, the contents of
the W register will be transferred to the OPTION register.
|
CCS has a function, defined in the EX_MACRO.C file, which
can do this. Just copy the function into your own program,
and put it above main.
Code: | #define set_options(value) {#ASM \
MOVLW value \
OPTION \
#ENDASM} |
Call the set_options() function at the beginning of main().
Study the 16F505 data sheet, select the proper bit settings,
and give that value to the function as a parameter. |
|
|
phased
Joined: 03 Oct 2006 Posts: 17
|
|
Posted: Wed Oct 18, 2006 2:26 pm |
|
|
I apologize for my ignorance regarding forum behavior. I will delete the other two now. Thank you for your assistance.
Phased. |
|
|
phased
Joined: 03 Oct 2006 Posts: 17
|
more trouble. |
Posted: Wed Oct 18, 2006 2:42 pm |
|
|
Even before I set the option register using
set_options(0b01000000);
I WAS able to wake up from sleep by pushing a switch connected to pin RB3. However, I wanted to call func1() if the wakeup had occurred due to a pin change or call func2() otherwise (like the first startup).
This was not working. The 7th bit of the STATUS register was always zero EVEN THOUGH the data sheet says it will be set to 1 if the wake up was due to a pin change.
To complicate things further, when I tried the code as PCM suggested, and let the code run for a while, suddenly the chip would set the 7th bit of STATUS high... I don't have any idea what could cause that - excepte maybe the WDT??
Sorry to be so frantically posting today, but I am really in a crunch.
Many Thanks as always. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Oct 18, 2006 3:06 pm |
|
|
How is your switch connected ?
1. What pin does it go to on the PIC ?
2. Does one side of the push-button switch connect to the PIC pin,
and the other side to Ground ?
3. Do you have a pull-up resistor on the side of the switch that
goes to the PIC ? What value is the resistor ?
Can you post your current code ? (After the latest changes, including
adding the set_options() function call). |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Oct 18, 2006 5:25 pm |
|
|
I think I just realized your problem. I re-read your earlier post,
where you say this:
Quote: | When I press the switch (RB3), it should wake up. |
RB3 is the MCLR pin. But you have MCLR enabled, because you're
not using the NOMCLR fuse. So when you press your switch, you're
causing an MCLR reset, not a "wake-up-on-change" from sleep.
You need to add NOMCLR to your #fuses statement.
There's another problem.
When the line below is executed, it changes all pins on Port B to inputs.
Here's the .LST file for that line:
Code: |
0062: MOVLW FF // W register = 0xFF
0063: MOVWF 0D // Save it in TRISB shadow reg.
0064: TRIS 6 // Set Port B to all inputs
0065: MOVF 06,W // Read Port B
0066: MOVWF 0F // Put result in 'dummy'
|
So the other PortB pins that can do "Wake-up on change" are
inputs and if there's no pull-up resistor on them, they're floating.
A "change" could occur at random. This affects pins RB0, RB1,
and RB4. Those pins need to have external pull-ups on them,
or you could enable weak pull-ups by setting Bit 6 of the OPTION
register = 0.
Perhaps a better way would be to not use the input_b() function,
but instead read PortB directly. Use a #byte statement to declare
the address of PortB, and then put in a line of code to read it.
This will read it without affecting the TRIS. Example:
Code: |
#byte PortB = 6 // Put this line above main().
.................... dummy = PortB;
0067: MOVF 06,W
0068: MOVWF 0F |
|
|
|
Guest
|
|
Posted: Mon Sep 22, 2008 7:22 am |
|
|
What a nice explanation.
Thank you PCM. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|