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 CCS Technical Support

Need help with my bits

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



Joined: 10 Aug 2006
Posts: 5

View user's profile Send private message

Need help with my bits
PostPosted: Mon Aug 21, 2006 4:28 pm     Reply with quote

High Guys
Im not sure whats goin on.
In the code that follows Ive set the register 0x20 the name Phasereg.
I have an ISR for Timer 1. The ISR is meant to check the status of bits 1,2,3 in Phasereg.
I set the value of these bits to 1 in the main code and when I check, they are as i have set them, in the main code. However when the code throws the ISR, the value of the bits appears to have returned to Zero????

The idea behind the code is to tell the ISR which input C2,C3,C4 has lost its input, causing the ISR.


#include <16f877a.h>
#device ICD=TRUE
#fuses HS,NOLVP,NOWDT,PUT
#use delay(clock=20000000)
#use rs232 (DEBUGGER)
#define GREEN_LED PIN_A5
#define YELLOW_LED PIN_B4
#define RED_LED PIN_B5
#define PUSH_BUTTON PIN_A4
#define R_PHASE PIN_C2
#define S_PHASE PIN_C3
#define T_PHASE PIN_C4
#define OUT PIN_C5
#define Phasereg 0x20
#bit rphase=0x20.1
#bit sphase=0x20.2
#bit tphase=0x20.3
#int_timer1

timer1_isr()
{//char phase;
printf("int, Rphase=%u",rphase);
IF(rphase)
{output_LOW(RED_LED);
delay_ms(100);
output_high(RED_LED);
delay_ms(100);}
IF(sphase==1)
{output_LOW(GREEN_LED);
delay_ms(100);
output_high(GREEN_LED);
delay_ms(100);}
IF(tphase==1)
{output_LOW(YELLOW_LED);
delay_ms(100);
output_high(YELLOW_LED);
delay_ms(100);}
}

void main(){

WHILE(1){
output_high(GREEN_LED);
output_high(RED_LED);

setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
set_timer1(58661);
//rphase=1;
#asm
movlw 11111111
movwf 0x20
#endasm

//printf("int, Rphase=%u",rphase);

while(!input(R_PHASE));
set_timer1(58661);
sphase=1;
while(!input(S_PHASE));
set_timer1(58661);
tphase=1;
while(!input(T_PHASE));
disable_interrupts(GLOBAL);
(output_low(GREEN_LED));
//delay_ms(100);
}}


I would really appreciate help and/or advice
Shocked
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Aug 21, 2006 9:16 pm     Reply with quote

Quote:
#define Phasereg 0x20
#bit rphase=0x20.1
#bit sphase=0x20.2
#bit tphase=0x20.3

It's not done that way. You need to use the #locate statement.
Example:
Code:

#locate Phasereg = 0x20
#bit rphase=Phasereg.1
#bit sphase=Phasereg.2
#bit tphase=Phasereg.3


Quote:
#asm
movlw 11111111
movwf 0x20
#endasm

You don't need to use ASM code. Use C code instead:
Code:
Phasereg = 0xFF;


Also, did you know that in CCS, it's not required to assign the address
of a variable ? (unless you want to). In some compilers like Hi-Tech,
you have to assign everything. CCS is like normal C (on a PC).
It automatically assigns the variable to a suitable RAM location.
You don't even have to worry about it.
MikeW



Joined: 15 Sep 2003
Posts: 184
Location: Warrington UK

View user's profile Send private message

PostPosted: Tue Aug 22, 2006 2:42 am     Reply with quote

and of course, the last thing you want in an isr are delay_ms routines.

it is always best to just use the isr to set and clear semaphore flags, and let a routine in main turn leds on, and have delays.

Mike
sjbaxter



Joined: 26 Jan 2006
Posts: 141
Location: Cheshire, UK

View user's profile Send private message Visit poster's website

PostPosted: Tue Aug 22, 2006 3:57 am     Reply with quote

You also want to move the

Code:
WHILE(1){


statement down the Main function (passed the initialization code) other wise your program will effectively reset itself very quickly and many times !!!

I would start with a simple application before moving onto interrupts as you don't seem to have grasped the basics yet. Shocked

and as Mike says, DON'T use delays or printfs in interrupt handlers. The interrupt handler is there to 'capture an event' ... not process it. Code in an interrupt handler should consum as little time as possible. Otherwise you WILL miss other events.
_________________
Regards,
Simon.
shocks



Joined: 10 Aug 2006
Posts: 5

View user's profile Send private message

Need help with my bits
PostPosted: Tue Aug 22, 2006 5:47 pm     Reply with quote

Guys thanks much for the help.
PCM programmers reply is particularily helpful.

Your collective comments on the use of while loops and printf are quite correct. Rest assured Ionly use them for debugging. I find looped code is easier to debug when implemented with hardware.
The printf's give an indication of whats actually happening when used in conjunction with the monitor in debugger.

I dont have a big problem with time constraints in terms of signal input frequency (VLF), hence the ISR contains actual executable code with delays to flash LEDs.

In terms of your collective responses I would be grateful for any insightful code snippets, particularily from Simon.
Thanks once again
sjbaxter



Joined: 26 Jan 2006
Posts: 141
Location: Cheshire, UK

View user's profile Send private message Visit poster's website

PostPosted: Wed Aug 23, 2006 2:48 am     Reply with quote

First here is your code with a few corrections and improvements:

Note: there is nothing in you code that resets any of the *phase values to zero !!! so this is supposed to be a one-shot application ??

Code:
#include <16f877a.h>
#device ICD=TRUE
#fuses HS,NOLVP,NOWDT,PUT
#use delay(clock=20000000)
#use rs232 (DEBUGGER)

#define GREEN_LED PIN_A5
#define YELLOW_LED PIN_B4
#define RED_LED PIN_B5
#define PUSH_BUTTON PIN_A4
#define R_PHASE PIN_C2
#define S_PHASE PIN_C3
#define T_PHASE PIN_C4
#define OUT PIN_C5

int1 rphase;
int1 sphase;
int1 tphase;

#int_timer1
timer1_isr()
{
   //char phase;
   printf("int, Rphase=%u",rphase);

   if (rphase)
   {
      output_LOW(RED_LED);
      delay_ms(100);
      output_high(RED_LED);
      delay_ms(100);
   }

   if (sphase)
   {
      output_LOW(GREEN_LED);
      delay_ms(100);
      output_high(GREEN_LED);
      delay_ms(100);
   }

   if (tphase)
   {
      output_LOW(YELLOW_LED);
      delay_ms(100);
      output_high(YELLOW_LED);
      delay_ms(100);
   } 
}

void main()
{
   // initialise hardware
   output_high(GREEN_LED);
   output_high(RED_LED);
   
   // initialise globals
   rphase=1;
   sphase=1;
   tphase=1;

   // setup timers and interrupts
   setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
   enable_interrupts(INT_TIMER1);
   enable_interrupts(GLOBAL);
   set_timer1(58661);

   //printf("int, Rphase=%u",rphase);

   // main program loop
   while(1)
   {
      while(!input(R_PHASE));
      set_timer1(58661);
      sphase=1;

      while(!input(S_PHASE));
      set_timer1(58661);
      tphase=1;

      while(!input(T_PHASE));
      disable_interrupts(GLOBAL);
      (output_low(GREEN_LED));
      //delay_ms(100);
   }
}


.. however, going by your original post, I think you need to switch around the code between the main loop and the isr. I would use the isr to poll the status of the inputs (at an interval defined by Timer1) and set the relavent *phase flag. The main program loop would then test this flag and flash the corresponding LED.

To change anymore code, I would need to know some more information...

When you say 'checks to see if 'C2,C3,C4 has lost its input', are these simple steady state inputs or is there 'data' on these lines. By that I mean is the PIC checking for the pins being ON, OFF or a loss of a data stream ?

BTW: Doesn't code look far better and more readable if you format it, add comments and use the CODE button when submitting posts Confused HINT !!
_________________
Regards,
Simon.
shocks



Joined: 10 Aug 2006
Posts: 5

View user's profile Send private message

Need help with my bits
PostPosted: Thu Aug 24, 2006 4:09 pm     Reply with quote

Simon
You're quite correct. Commenting would be better, bad habit on my behalf.
Im new to the forum so I need a small bit of grace.

The project is composed of a number of features, hence the code is written to become part of a bigger code.

The code posted, looks at pins C2 C3 C4 and tests for loss of voltage( ie zero) on a pin by waiting for the pin to go high for 11ms.
The inputs are 3 square waves with a 120 degree phase displacement. The frequency is 50 HZ same as your AC supply in UK.
The 11ms delay which is the count to ISR on T1, is 1 ms longer than half the cycle time.
I start the timer, wait for a high on the pin , if it goes high TI resets and looks at the next pin.
If not, the ISR is called the missing input identified and the relevant LED energised.

Thats all, in theory at least.

I appreciate your help.

Paul
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Fri Aug 25, 2006 1:34 pm     Reply with quote

How about something simple

Code:
   while(1)
   {
     
      //some other code
     
      if(ms_Tick)                                           // SET IN AN INTERUPT
      {  if (++Phase_A_Time>15) Phase_A_Lost=1;             // Detect excessive phase time
         if (++Phase_B_Time>15) Phase_B_Lost=1;             // Detect excessive phase time
         if (++Phase_C_Time>15) Phase_C_Lost=1;             // Detect excessive phase time
         if (Phase_A_Old != Phase_A)
         {  Phase_A_Time=0;                                 // Clear Phase time
            Phase_A_Lost=0;                                 // Clear Phase lost flag
         }
         if (Phase_B_Old != Phase_B)
         {  Phase_b_Time=0;                                 // Clear Phase time
            Phase_b_Lost=0;                                 // Clear Phase lost flag
         }
         if (Phase_C_Old != Phase_C)
         {  Phase_c_Time=0;                                 // Clear Phase time
            Phase_c_Lost=0;                                 // Clear Phase lost flag
         }
         Phase_A_Old = Phase_A;
         Phase_B_Old = Phase_B;
         Phase_C_Old = Phase_C;
         
         if ((!Phase_A_Time) && (((!Phase_B_Time)||(!Phase_C_Time)) || (Phase_B_Time == Phase_C_Time)))
         Phase_A_Lost=1;                                    // Set Phase lost flag if phases are in time
     
         //some other code
     
         ms_Tick=0;
      }
     
      //some other code
     
   }
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