View previous topic :: View next topic |
Author |
Message |
jaime
Joined: 25 Nov 2005 Posts: 56 Location: Porto - Portugal
|
stop timer 1 |
Posted: Wed Apr 12, 2006 7:57 am |
|
|
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
|
|
Posted: Wed Apr 12, 2006 12:58 pm |
|
|
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
|
Or Constants |
Posted: Wed Apr 12, 2006 1:50 pm |
|
|
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
|
|
Posted: Wed Apr 12, 2006 1:55 pm |
|
|
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
|
|
Posted: Wed Apr 12, 2006 1:58 pm |
|
|
Thanks, my heart beats again. |
|
|
Ttelmah Guest
|
|
Posted: Wed Apr 12, 2006 2:52 pm |
|
|
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
|
|
Posted: Wed Apr 12, 2006 3:03 pm |
|
|
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
|
|
Posted: Wed Apr 12, 2006 3:34 pm |
|
|
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...
Best Wishes |
|
|
|