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

stop timer 1

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



Joined: 25 Nov 2005
Posts: 56
Location: Porto - Portugal

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

stop timer 1
PostPosted: Wed Apr 12, 2006 7:57 am     Reply with quote

Hello

See this test program.

When receiving 'Q' turn on the relay and starts counting time with timer1. When reach 15 timer 1 must stop.
If i push the button and release (rb0) the program will turn relay on and start counting time and when reach 15 will stop timer. If i push and release the button (rb0) and relay is on then program put relay off and stops the timer1.

I put some printf instruction to see whats happen and i see that when i start the timer1 (enable_interrupts(int_timer1)) every time the timer blow it wents in the interrupt, but when i disable interrupts the program still went in the interrupt...

Can anyone explain to me??

And about fast_io: where to put
#use fast_io(a) and
set_tris_a(ob00000000) inside the main routine or after the #include???

Thanks

Code:

#include <16F628A.h>
#use delay (clock=20000000)
#use rs232(baud=19200, xmit=pin_b2, rcv=pin_b1, errors)
#use fast_io(a)
#use fast_io(b)
#fuses hs, nowdt, put, nobrownout, mclr, nolvp

#define sw pin_b0                            //botao
#define relay pin_b5                         // output relay
#define led_init pin_a0                      // led init
#define led_standby pin_a1

#bit ext_int_flag=0x0B.1
#bit tmr1_int_flag=0x0C.0

set_tris_a(0b00000000);
set_tris_b(0b00000011);

short int receive=0;
short int timer1_on=0;                       // flag timer1 in use
short int sw_pressed=0;                      // key pressed
short int someone_pressed_the_button=0;      //
int state=0;                                 // state machine
char temp=0;                                 // imput string
long time_count=0;                           // counts time in timer1

////////////////////////////////////////////////////////////////////////////////

#int_rda
void trata_rda()
{
temp=getc();
if(temp=='Q')
   receive=1;
printf("int rx\r");
//rc_int_flag=0;
}

////////////////////////////////////////////////////////////////////////////////

#int_ext
void_trata_ext()
{
delay_ms(100);                                  //debounce time
if(input(sw) && !sw_pressed)        //if sw pressed and flag=0
   {
   sw_pressed=1;                    //now the sw is pressed
   ext_int_edge(h_to_l);            //must detect when sw is released
   }
else if(!input(sw) && sw_pressed)   // if sw released and flag
   {
   sw_pressed=0;                    // sw is released
   ext_int_edge(l_to_h);            // must detect when is pressed
   someone_pressed_the_button=1;
   }

printf("int ext\r");

ext_int_flag=0;                     //keep external interrupt flag clean
}

////////////////////////////////////////////////////////////////////////////////

#int_timer1
void trata_timer_1()
{
set_timer1(3036+get_timer1());
time_count++;

printf("blow up %ld\r",time_count);

tmr1_int_flag=0;
}

////////////////////////////////////////////////////////////////////////////////

main()
{
output_a(0);
output_b(0);
set_tris_a(0b00000000);
set_tris_b(0b00000011);

while(1)
   {
   switch(state)
      {
      case 0:                       //initialization

      output_high(led_init);        //init led
      delay_ms (1000);              //pause

      setup_timer_1(t1_internal|t1_div_by_8);   //setup timer 1

      ext_int_edge(L_TO_H);         //setup external interrupt
      ext_int_flag=0;               //clean external interrupt flag
      enable_interrupts(int_ext);   //enable external interrupt

      enable_interrupts(int_rda);   //enable rda interrupt

      enable_interrupts(global);    //enable interrupts

      output_low(led_init);         //end of initialization

      state=1;                      //goto next state
      break;
/*----------------------------------------------------------------------------*/
      case 1:                       //stand by mode
      output_high(led_standby);

      if(receive)                   //uart rx
         {
         disable_interrupts(int_ext|int_timer1|int_rda);
         printf("receive\r");

         temp=0;
         receive=0;

         if(timer1_on)
            enable_interrupts(int_timer1);
         enable_interrupts(int_ext|int_rda);

         state=2;
         }

     else if(someone_pressed_the_button)     //sw pressed. If relay on -> turn off
         {                                   //if relay of -> turn on
         disable_interrupts(int_ext|int_timer1|int_rda);
         printf("key\r");

         someone_pressed_the_button=0;

         if(timer1_on)                       //see if timer is counting
            {
            output_low(relay);

            timer1_on=false;
            enable_interrupts(int_ext|int_rda);
            }
         else                                //active the output
            state=2;
         }

      else if(time_count>=15)                //when time over then turn off relay
         {
         disable_interrupts(int_ext|int_timer1|int_rda);

         printf("time over\r");

         timer1_on=false;
         time_count=0;
         
         output_low(relay);

         enable_interrupts(int_rda);
         enable_interrupts(int_ext);
         }


      break;
/*----------------------------------------------------------------------------*/
      case 2:                                // at this time i put the relay on and turn on the
      output_high(relay);                    //timer to count some time
      printf("output\r");
      timer1_on=true;                        //flag timer on
      set_timer1(3036);
      time_count=0;                          //counter
      enable_interrupts(int_timer1);         //enable timer

      enable_interrupts(int_ext|int_rda);    //enable others interrupts

      state=1;                                //return to state 1 - stand by
      break;

         }
      }
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Apr 12, 2006 12:58 pm     Reply with quote

Quote:
but when i disable interrupts the program still went in the interrupt...

disable_interrupts(int_ext|int_timer1|int_rda);
enable_interrupts(int_ext|int_rda);

It doesn't say anywhere in the manual or the 16F628A.H file
that you can OR the constants together. This is an invention,
and it's an error. You need to fix all the places where you
have done this. They must all go on separate lines.
tavioman



Joined: 22 Feb 2006
Posts: 65

View user's profile Send private message

Or Constants
PostPosted: Wed Apr 12, 2006 1:50 pm     Reply with quote

PCM i have some code in development that uses or'ed constants
Code:
#define MODE1  0b00011000
#define EXAMPL 0b01110110
.....
.....
spi_write(MODE1 | EXAMPL);


It will not work???
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Apr 12, 2006 1:55 pm     Reply with quote

For some CCS functions, it is correct to use OR'ed constants.
In other functions, it is not correct. The CCS manual and
the .H file for your PIC will tell you if you can OR constants
together for a specific function.

In the case of the enable_interrupts() and disable_interrupts()
functions, you can't do it. For setup_spi(), it's correct to do it.
tavioman



Joined: 22 Feb 2006
Posts: 65

View user's profile Send private message

PostPosted: Wed Apr 12, 2006 1:58 pm     Reply with quote

Thanks, my heart beats again. Very Happy
Ttelmah
Guest







PostPosted: Wed Apr 12, 2006 2:52 pm     Reply with quote

Interestingly (I was going to post about the or'ed constants), I went and tried it to see the effect. It appears that it generates part of the code 'rightish', _provided you select interrupts who's 'enable/disable bits are in the same memory register_. However where it gets completely 'screwed', is when the bits are in different registers.
So if (for instance), you or the constants for 'int_ad', and 'int_ext' (registers 0xF9D, and 0xFF2 on a 18F452), is creates a bit mask, but accesses address 0xFFF!. However if you or int_ext, and int_timer0 (both of which are in the 0xFF2 register, it actually works!.

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Apr 12, 2006 3:03 pm     Reply with quote

Right. I recognize that, but it's a very unsafe coding practice.
At some point, a newbie will come along and declare that they
"have always done this". If they have, it's sheer luck that it
hasn't failed them yet.
Ttelmah
Guest







PostPosted: Wed Apr 12, 2006 3:34 pm     Reply with quote

Totally agree.
As you say, the manual, and the .h file, do specifically say where the constants can be 'ored'.
A bit like the difference between 'fruit', and 'animals'. Generally perfectly safe to put multiple types of fruit into one basket, but try it with some animals, and you will discover that mixing may have problems... Very Happy

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