CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Waking up a PIC16F505...

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
phased



Joined: 03 Oct 2006
Posts: 17

View user's profile Send private message

Waking up a PIC16F505...
PostPosted: Tue Oct 17, 2006 11:38 pm     Reply with quote

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







PostPosted: Wed Oct 18, 2006 4:19 am     Reply with quote

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

View user's profile Send private message

YOU SIR ARE A LIFE SAVER!!!!!
PostPosted: Wed Oct 18, 2006 11:00 am     Reply with quote

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

View user's profile Send private message

So here's my code. But it doesn't work...
PostPosted: Wed Oct 18, 2006 12:41 pm     Reply with quote

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.... Smile

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

View user's profile Send private message

ALMOST!
PostPosted: Wed Oct 18, 2006 12:53 pm     Reply with quote

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

View user's profile Send private message

Status register access
PostPosted: Wed Oct 18, 2006 1:28 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Oct 18, 2006 2:12 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Oct 18, 2006 2:26 pm     Reply with quote

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

View user's profile Send private message

more trouble.
PostPosted: Wed Oct 18, 2006 2:42 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Oct 18, 2006 3:06 pm     Reply with quote

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

View user's profile Send private message

PostPosted: Wed Oct 18, 2006 5:25 pm     Reply with quote

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.
Code:

dummy = input_b();

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








PostPosted: Mon Sep 22, 2008 7:22 am     Reply with quote

What a nice explanation.
Thank you PCM.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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