|
|
View previous topic :: View next topic |
Author |
Message |
Sebastian
Joined: 01 Dec 2003 Posts: 21 Location: Milan Italy
|
Interrupt and two different output |
Posted: Tue Sep 30, 2014 10:53 am |
|
|
Hi all
I have written this little program to manage two outputs alternately at the touch of a button. Needless to say, so the interrupt routine is not functional.
Do you have any tips to handle this little problem?
Code: |
#if defined(__PCH__)
#include <18F458.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#endif
#include <input.c>
#define GPI1 PIN_D1
#define GPI2 PIN_D2
#define BUTTON PIN_B0
#define GPI1ON 1
#define GPI2ON 2
int GPI_CTRL;
#INT_EXT
void ext_isr()
{
while(!input(BUTTON));
delay_ms(100);
GPI_CTRL++;
if (GPI_CTRL==1) {
output_high(GPI1);
delay_ms(50);
output_low(GPI1);
}
else if (GPI_CTRL==2)
{
output_high(GPI2);
delay_ms(50);
output_low(GPI2);
GPI_CTRL=0;
}
}
void main() {
GPI_CTRL=0;
port_b_pullups(TRUE);
set_tris_D(0x00);
ext_int_edge(H_TO_L);
enable_interrupts(INT_EXT);
enable_interrupts(GLOBAL);
}
|
thanks in advance |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19552
|
|
Posted: Tue Sep 30, 2014 2:33 pm |
|
|
and, as a general comment on the program, what happens to a CCS program, when it drops 'off the end'?. |
|
|
Sebastian
Joined: 01 Dec 2003 Posts: 21 Location: Milan Italy
|
|
Posted: Mon Oct 06, 2014 9:58 am |
|
|
Thank you Ttelmath , PCM programmer for the encouragement !!!
I do not have the experience to tell you if this goes in the right direction !
This code is a collage of your examples and only for test !
Suggestions
Code: |
#if defined(__PCH__)
#include <18F458.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,BROWNOUT,PUT
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#endif
#define GPI1 PIN_D1
#define GPI2 PIN_D2
#define BUTTON PIN_B0
#define TICK_MS ((5000 * 256 * 256 ) / (20000000/4)) //13,1072Msec
#define TASK1_TIMER_VALUE (1/TICK_MS)
#define TASK2_TIMER_VALUE (2/TICK_MS)
#define GPI1ON 1
#define GPI2ON 2
char gc_old_button_status = input_b();
int GPI_CTRL=0;
int16 task1_timer;
int16 task2_timer;
//-----------------------
void timer_tick(void);
void task1(void);
void task2(void);
void main()
{
// Setup Timer0 so it rolls over at a 76,29 Hz rate.
// This gives a timer tick of approximately 13,1072Msec.
// All tasks (together) must execute in less than 13,1072Msec.
setup_timer_0(RTCC_DIV_256);
task1_timer = TASK1_TIMER_VALUE;
//task2_timer = TASK2_TIMER_VALUE;
while(1)
{
task1();
// task2();
timer_tick();
}
}
void task1(void)
{
char new_status;
if(task1_timer)
return;
else
task1_timer = TASK2_TIMER_VALUE;
GPI_CTRL++;
new_status = input_b(); // Read the buttons
if(new_status != gc_old_button_status)
{
switch (GPI_CTRL) {
case GPI1ON :
output_high(GPI1);
delay_ms(2);
output_low(GPI1);
break;
case GPI2ON :
output_high(GPI2);
delay_ms(2);
output_low(GPI2);
GPI_CTRL=0;
break;
}
gc_old_button_status = new_status;
}
}
//--------------------------
// This function waits for the hardware timer0
// to count up to 0xFF and roll over to 0x00.
void timer_tick(void)
{
// Wait until the Timer0 rolls over from 0xFF to 0x00.
while(!bit_test(get_timer0(), 7)); // Wait until MSB goes high
while(bit_test(get_timer0(), 7)); // Wait until Timer rolls over to 0
if(task1_timer)
task1_timer--;
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Oct 06, 2014 12:07 pm |
|
|
I would throw out your whole code and just start over again.
You must write code that you can understand. If you can't understand
what you're writing, then write something that's more simple. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Oct 06, 2014 9:41 pm |
|
|
I made a really simple program that you should be able to understand.
There are no interrupts involved. There is just a while() loop that runs
every 10 ms. Inside the loop we call a button() function to see if a
button has been pressed. There are two buttons that we check.
I used pins B0 and A4 for the buttons because that's how my board
is built. The reason I used the button() routine is so you don't have to
make the button code. It's already done. You just call the routine.
If a button is pressed, we set the "on" duration for the LED. This is in
10 ms increments. So an "on" duration value of 50 means the LED will
be on for 500 ms.
After checking the buttons, we look at the led duration timer variables.
If they are positive, we decrement them. After we have gone through
the while() loop the required number of times (50, for an LED "on"
duration of 500 ms), the led duration timer will have been decremented
down to 0, so then we turn off the LED.
This program was tested on a PicDem2-Plus (old non-rohs version)
with CCS compiler vs. 5.028.
The button() routine is in the link below. Save the button routine code
as button.c and put it in your project directory. Do not use the button
demo program. You only want the button.c code. It's the 2nd program
in this post:
http://www.ccsinfo.com/forum/viewtopic.php?t=23837
Code: |
#include <18F4520.h>
#fuses HS,NOWDT,PUT,BROWNOUT,PUT,NOLVP
#use delay(clock=20M)
// Your LEDs are on these two pins.
#define LED1_PIN PIN_B1
#define LED2_PIN PIN_B2
// Define Bvar variables for the buttons.
// The button() function requires this.
int8 button1 = 0; // For the button on pin B0
int8 button2 = 0; // For the button on pin A4
#include "button.c"
//===================================
void main()
{
int8 led1_timer; // 0 to 2550 ms led on time
int8 led2_timer; // 0 to 2550 ms led on time
while(TRUE)
{
if(button(PIN_B0, 0, 50, 10, button1, 1))
{
output_high(LED1_PIN);
led1_timer = 20; // Turn on LED1 for 200 ms
}
if(button(PIN_A4, 0, 50, 10, button2, 1))
{
output_high(LED2_PIN);
led2_timer = 75; // Turn on LED2 for 750 ms
}
if(led1_timer)
led1_timer--;
else
output_low(LED1_PIN);
if(led2_timer)
led2_timer--;
else
output_low(LED2_PIN);
delay_ms(10);
}
} |
Your buttons should be connected to the PIC with a circuit as shown below.
Each button should have its own separate circuit like this:
Code: |
+5v
|
<
> 4.7K
< ___ Push button switch
To | _|_|_
PIC -----------------o o------
pin |
--- GND
- |
|
|
|
Sebastian
Joined: 01 Dec 2003 Posts: 21 Location: Milan Italy
|
|
Posted: Tue Oct 07, 2014 12:53 am |
|
|
Thanks PCM programmer
You're really gentle, carefully read your advice.
I'm sorry but I'm not a programmer.
Thanks again for your time! |
|
|
Sebastian
Joined: 01 Dec 2003 Posts: 21 Location: Milan Italy
|
|
Posted: Tue Oct 07, 2014 7:36 am |
|
|
I tried to compile the project with the file button.c but returns
A #DEVICE REQUIRED BEFORE THIS LINE
Quote: |
#define read_bit_var(x) bit_test(*(int8 *)(x >> 3), x & 7)
|
What's the reason ?
I use MPLABX2.00 and CCS 5.027 |
|
|
stinky
Joined: 05 Mar 2012 Posts: 99 Location: Central Illinois
|
|
Posted: Tue Oct 07, 2014 9:24 am |
|
|
Most likely that the line that says Code: | #include "button.c" | is above your main headers. Move that line below the first lines: Code: | #include <18F4520.h>
#fuses HS,NOWDT,PUT,BROWNOUT,PUT,NOLVP
#use delay(clock=20M)
// Your LEDs are on these two pins.
#define LED1_PIN PIN_B1
#define LED2_PIN PIN_B2
// Define Bvar variables for the buttons.
// The button() function requires this.
int8 button1 = 0; // For the button on pin B0
int8 button2 = 0; // For the button on pin A4
#include "button.c" <---THIS LINE HERE! |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Oct 07, 2014 11:49 pm |
|
|
Quote: | I tried to compile the project with the file button.c but returns
A #DEVICE REQUIRED BEFORE THIS LINE |
There is another reason. In MPLAB X, click on the Project tab on the
far left side of MPLAB X. You should see the following lines in the Project
window as shown below. Click on "Source Files" to show the files:
Code: | Your Project name
+ Header Files
+ Important Files
+ Library Files
+ Linker Files
+ Object Files
- Source Files
Your Main Source Filename.c
Button.c <-- REMOVE THIS FILE FROM THE LIST.
+ Libraries
+ Loadables |
You will notice that Button.c is in the list. Select it with your mouse,
right-click on it, and select "Remove from Project". Do it. Only your
main source file (I don't know what you call it) should be in the list.
Now re-compile and it will probably build with no errors.
In the CCS command line compilers (which you have), only the main
source file for your project should be in the Source Files list. Other
#include files such as Button.c should not be in the list. If they are in
the list, MPLAB X will try to compile them as separate files, and you
will get the "A #device required before this line" error. So remove
button.c from the list and you will get a good build. |
|
|
Sebastian
Joined: 01 Dec 2003 Posts: 21 Location: Milan Italy
|
|
Posted: Wed Oct 08, 2014 1:04 am |
|
|
Thanks PCM now compile it's ok !!!
I have a clarification to submit ,
Code: |
+5v
|
<
> 4.7K
< ___ Push button switch
To | _|_|_
PIC -----------------o o------
pin |
--- GND
- |
You tell me to connect this abitual circuit i now
In this declaration Code: |
if(button(PIN_B0, 0, 50, 10, button1, 1)) |
all the instance must be true to complete if statement !
Downstate is 0!
Considering
Quote: |
// Downstate:
// This is the logic level of the button when it's pressed.
// For a circuit with a Normally-Open switch and a pull-up
// resistor, this parameter will be 0. |
This means that when i not press button the pin is in the high level +5v
because is pull-upped.
Downstate is to be considered 0 Quote: | For a circuit with a Normally-Open switch and a pull-up resistor, this parameter will be 0. |
here is tha question , why in the code i check in this way
Quote: |
// Check if the button is pressed. It's pressed if the
// pin value is the same as the "downstate". If it's not
// pressed, then zero the Bvar and return "Not pressed".
|
Code: |
if(pin_value != downstate)
{
Bvar = 0;
return(!action);
}
|
if statement it's true when pin_value is different from downstate and bit_test() function return 1 if pin is high.
I would expect exactly the opposite thing when button it's pressed !
How does it work downstate ?
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Oct 08, 2014 12:43 pm |
|
|
Code: | if(pin_value != downstate)
{
Bvar = 0;
return(!action);
}
|
The code shown above checks if the button is not pressed. If it's not
pressed, the code returns !action, which means it returns 0.
So "not pressed" returns 0. That's exactly what you want.
If the button is pressed, then we fall through to this code:
Code: |
if(Bvar == 0)
{
if(delay == 0)
Bvar = 255;
else
Bvar = delay;
return(action);
}
|
And we return "action", which is set to 1. A return value of 1 means
"True", or yes, we did get a keypress.
The code might seem a little hard to understand. That's because it's a
close translation of PicBasic Pro ASM code to CCS. |
|
|
|
|
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
|