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

How to wake-up the PIC?

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



Joined: 25 Nov 2004
Posts: 30
Location: Germany

View user's profile Send private message

How to wake-up the PIC?
PostPosted: Thu Dec 23, 2004 4:44 am     Reply with quote

I cannot find the solution for the following problem:

A PIC shall measure voltages and send the values by can. It also shall receive a message and save the datas of this message to eeprom. By receiving another message, it shall read out the eeprom and send the datas by can.

This activities must not be done all the time. So the controller shall be put to sleep several times. It has to wake up by time (so that measuring voltage will always be done after a known time interval) or by an incoming can message.

My first try was to wake it up by the can message. Unfortunately I guess, I forgot some commands to tell the PIC it should wake up by can-interrupt. I didn't find them.

I just added the line "sleep()" and it falls to sleep. But I can send as many messages as I like to, I did not wake up.

This is my code:

Code:

#if defined(__PCH__)
#include <18F258.h>
#fuses HS,PUT,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT
#use delay(clock=20000000)
#use rs232(baud=57600, xmit=PIN_C6, rcv=PIN_C7)  // Jumpers: 8 to
                                                                               //11, 7 to 12

#endif

#include <bootloader.h>
#include <Messung0-2,5_b.c> //includes set_channel_adc,
                                            //make_setup_adc, print_voltage
#include "can_ewald_20MHz_0_1.c" //includes the can settings

int32 ms;


   int adc_value[3];
   int data[3];
   int channel = 0;           //Eingangskanal wählen
   int reference_up = 25; //Auswahl obere Referenzspannung
                                     //(Referenz * 10)
   int reference_down = 0;    //Auswahl untere Referenzspannung
                                          //(Referenz * 10)

   int32 tx_id;
   int1 tx_rtr=0;
   int1 tx_ext=0;
   int tx_len=3;
   int tx_pri=3;

   struct rx_stat rxstat;
   int32 rx_id;
   int rx_len;
   int n;


#int_timer2
void isr_timer2(void) {
   ms++; //keep a running timer that increments every milli-second
}


//Nachrichten-Buffer prüfen, entsprechend reagieren
#int_CANRX0
void can_empfangen(void){

   printf("Ich empfange etwas \r\n");

   if ( can_kbhit() )   //if data is waiting in buffer...
      {
         if(can_getd(rx_id, &data[0], rx_len, rxstat)) { //...then get data
                                                                           //from buffer
            switch (rx_id){
               case 1297:{ //Daten aus EEPROM auslesen und über den CAN
                                 //schicken
                  for(n=0;n<3;n++)
                     data[n]=read_eeprom(n);
                  tx_id = 1297;
                  can_putd(tx_id, data, tx_len,tx_pri,tx_ext,tx_rtr);
                  break;
               }
               case 1281:{ //angekommene Daten in den EEPROM
                  for(n=0;n<rx_len;n++)
                     write_eeprom(n, data[n]);
                     break;
               }
            }

         }
         else {
            printf("\r\nFAIL on GETD\r\n");
         }
      }

}



void main(void) {

   printf("\r\nApplication program version 1.01 \r\n");

//Einstellungen
   setup_timer_2(T2_DIV_BY_4,79,16);   //setup up timer2 to interrupt                     
                                                           //every 1ms if using 20Mhz clock

   can_init();

   enable_interrupts(INT_TIMER2);   //enable timer2 interrupt
   enable_interrupts(INT_CANRX0);
   enable_interrupts(GLOBAL);       //enable all interrupts (else timer2 wont     
                                                  //happen)



   make_setup_adc(reference_up,reference_down); //Einstellungen setzen
   set_channel_adc(channel);                    //Eingangskanal setzen

   while(true){


//AD-Eingänge auslesen und Ergebnisse in korrekter Form ablegen
   set_channel_adc(0);

   delay_us(10);

   adc_value[0] = read_adc();    //Wert auf gesetztem Kanal auslesen
   set_channel_adc(1);

   delay_us(10);

   adc_value[1] = read_adc();    //Wert auf gesetztem Kanal auslesen
   set_channel_adc(4);

   delay_us(10);

   adc_value[2] = read_adc();    //Wert auf gesetztem Kanal auslesen

   delay_us(10);

   print_voltage(adc_value[0]);  //Ergebnis ausgeben

   sleep();


//send
   if ( can_tbe() && (ms > 1000)){
      printf("Jetzt sende ich etwas \r\n");
      tx_id = 1280;
      can_putd(tx_id, adc_value, tx_len,tx_pri,tx_ext,tx_rtr);
   }

   delay_ms(1000);
   }
}


The code works correctly without putting the PIC to sleep. But inserting the sleep-command, it does not wake-up. Which command may I have forgotten? I don't find anything in the help, in the example EX_WAKUP.c or in the old posts of the forum, although it was spoken about such problems several time.

I would be very thankful for help. Have a nice christmas time, pom
Ttelmah
Guest







PostPosted: Thu Dec 23, 2004 5:09 am     Reply with quote

Look at the data sheet.
Which devices can 'wake' the chip?.
Both the CAM system, and the timer2 interrupt, are _dependant_ on the clock being running. This stops when you sleep, so neither can wake the chip.
You do not have to put the chip to sleep to do what you want. Just create a global 'bit' variable, called (say) 'has_happened', and sit in a loop with:
Code:

    while (! has_happened) ;
    has_happened=false;


Then in the two interrupt routines, set this bit.
The code will it waiting, and continue if either event occurs.
Seperatly, note also, that if you were using a peripheral that could wake the chip, you should add another 'dummy' instruction between the 'sleep', and the test. The reason is that the instruction after the sleep, has been 'pre-fetched', when you go to sleep, and you do not want this to happen.

Best Wishes
pom



Joined: 25 Nov 2004
Posts: 30
Location: Germany

View user's profile Send private message

PostPosted: Wed Dec 29, 2004 6:16 am     Reply with quote

Your easier solution cannot help me, because my intention is to save energy by sending the PIC to sleep. I don't think that this will the effect of the while-construction.

I looked up the devices for waking the PIC, but I didn't really understand it.

Devices for waking up the PIC:
-external reset
-watch-dog timer (what is this?)
-interrupt from INT-pin, port B port change or a peripheral interrupt

Peripheral interrupts:
-PSP read or write (don't know what it is, but I hink I don't need)
-Timer1 or Timer3 (ok, I am trying to use the wrong timer in my code)
-CCP capture mode interrupt (what is this, something with CAN?)
-something with MSSP
-USART RX and TX (I think, this are the pins, where the RS232 is
connected)
-A/D-Conversion
-EEPROM write operation complete
-LVD interrupt (what is LVD?)

This is, what is said in the datasheet. I think the problem of waking him up by the timer is clear. I am not allowed to use Timer2. But waking him up by CAN-message?

In PICC the CAN-message causes an interrupt. May it nevertheless not be able to wake up the PIC?
Such an Interrupt is not in the list before, unless it is the CCP capture mode interrupt. Is it?

The Can is connected the RB3(CANRX) and RB2(CANTX). Are these not represented by the port B change interrupt? In PICC there is a speciel interrupt-bit for RB4 to RB7, are only these the port b change interrupt pins?

There are so many questions to this theme because I am so low in experiences with microcontrollers. Please help me another time.

May be there is a book or a page in the internet, where I can learn more about these things. If you know some, please tell me.

I am looking forward to your answers. Have nice last days of the year 2004 and have a happy 2005.
pom



Joined: 25 Nov 2004
Posts: 30
Location: Germany

View user's profile Send private message

PostPosted: Wed Dec 29, 2004 6:56 am     Reply with quote

I tried to use the timer1 instead of the timer2. Besides this, I kept the code.

I inserted this line to configer timer1:

setup_timer_1(T1_EXTERNAL_SYNC | T1_DIV_BY_8);

I also tried with T1_INTERNAL and T1_EXTERNAL.

I changed
#int_timer2
and
enable_interrupts(INT_TIMER2);

to timer1, but it does not work. How do I choose to use the Timer1 as asynchronous timer? I neither found anything in the help of PICC nor did I find anything in the datasheet of the controller.
Ttelmah
Guest







PostPosted: Wed Dec 29, 2004 8:21 am     Reply with quote

pom wrote:
I tried to use the timer1 instead of the timer2. Besides this, I kept the code.

I inserted this line to configer timer1:

setup_timer_1(T1_EXTERNAL_SYNC | T1_DIV_BY_8);

I also tried with T1_INTERNAL and T1_EXTERNAL.

I changed
#int_timer2
and
enable_interrupts(INT_TIMER2);

to timer1, but it does not work. How do I choose to use the Timer1 as asynchronous timer? I neither found anything in the help of PICC nor did I find anything in the datasheet of the controller.

T1_external, would put you in asynch mode (key is that the word 'sync', is short for 'synchronous', which implies the clock will be internally synchronised to the oscillator - without this, the input runs in asynch mode).
You do realise for this to work, there has to be an external clock of the right frequency, fed in to the external clock input for T1?.
How much power do you think the processor itself uses?. Unless your clock rate is very high, the odds are that it is less than the other chips around. Reducing this, will be as much down to setting the logic levels and controls to the voltages needed to disable these parts, as to stopping the PIC. You can lower this to really low levels, by taking advantage of the secondary oscillator option, and 'slowing' the chip, rather than putting it to sleep. Yes, you could trigger a wake up on the 'can' signals, using the interrupt on change, _but_ the problem then is that when the chip wakes, it has already 'missed' the first clock on the can bus, and possibly more (it takes quite a lng time fr a chip to wake, especially if you are using it's own oscillator).
There is a lot of information about using 'sleep', extenal clocks etc., on the MicroChip site. Try looking at the 'application notes' rather than the data sheets. The latter give specific details of the hardware on the particular chip, while the former, give overall examples of how to use most of this hardware.

Best Wishes
pom



Joined: 25 Nov 2004
Posts: 30
Location: Germany

View user's profile Send private message

Timer1 external not possible
PostPosted: Thu Dec 30, 2004 4:00 am     Reply with quote

I have to solve this puzzle, but I have no idea, what to do.

Another question fpr timer1:

I am not the electrician who build the curcuit, so I am not sure, but I guess there is a big mistake with timer1.

I think to use Timer1 as an asynchronous, external timer, it needs its own crystal. Am I right so far?
I guess, this second crystal has to be connected to T1OSI and T1OSO. But in this curcuit I have, this to PINs are used as outputs. So there won't be a chance to use the Timer1 in the required way?

What about Timer3. Do I understand the datasheet correct, that it uses the same PINs for an external clock?

If I am correct, I have to give up and build a new curcuit. But maybe someone can help me to be successful with this curcuit. I am thankful for your help so far.
Ttelmah
Guest







Re: Timer1 external not possible
PostPosted: Thu Dec 30, 2004 9:20 am     Reply with quote

pom wrote:
I have to solve this puzzle, but I have no idea, what to do.

Another question fpr timer1:

I am not the electrician who build the curcuit, so I am not sure, but I guess there is a big mistake with timer1.

I think to use Timer1 as an asynchronous, external timer, it needs its own crystal. Am I right so far?
I guess, this second crystal has to be connected to T1OSI and T1OSO. But in this curcuit I have, this to PINs are used as outputs. So there won't be a chance to use the Timer1 in the required way?

What about Timer3. Do I understand the datasheet correct, that it uses the same PINs for an external clock?

If I am correct, I have to give up and build a new curcuit. But maybe someone can help me to be successful with this curcuit. I am thankful for your help so far.

You only technically 'need' the single input bit pin, if you use a complete external oscillator. This is the T1CKI pin. The output pin is used if you want to just add a crystal, rather than an oscillator. Yes, the source for T3, is the same clock.
I have to ask how low you need the power to go, what the consumption of the other parts is, and what clock rate you are running?. If you disable some of the internal peripherals, and are running at a rate like 4MHz, the chip itself, typically draws about 1.7mA. Unless the crcuit has been carefully designed to be 'low power', other parts will usually draw more (a normal 5v 'regulator', will typically have more quiescent consumption than this). If you can get access to the T1CKI pin, this is also the pin used for oscillator switching (which as I have mentioned before, may be a 'better' solution than sleep). Feeding this with a 32768Hz signal from a watch oscillator, the chip running at this rate, only draws about 60uA.

Best Wishes
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