|
|
View previous topic :: View next topic |
Author |
Message |
scottc
Joined: 16 Aug 2010 Posts: 95
|
Interrupt on change RB.3 Problems |
Posted: Sat Sep 04, 2010 8:43 pm |
|
|
Hi
I am using a pic16f886 running at 8MHZ internal clock.
I have not been able to get the interrupt on change function to work.
for pin RB3 detecting a high to low transition.
In my code I was expecting that when button2 gets pressed, The ISR
would invoke and update value1. Since my display routine is running in
main I was expecting it to show an increment to Value1, but alas it just
sits there doing nothing as the button gets pressed.
I verified the display works by removing the interrupt routines and
making a call to the button function from main. Without the ISR's I can press the button and the display does increment.
Would I be correct in my assumption, or way off base as to how the ISR
should work.
The code compiles Ok without errors.
Thanks Scott
Code: |
#include <main.h>
#use delay (INTERNAL = 8MHZ)
#include <lcd4bit.c>
#byte port_a = 0x05
#byte port_b = 0x06
#byte port_c = 0x07
#BIT BUTTON1 = port_b.2
#BIT BUTTON2 = port_b.3
#Define Backlight Pin_B1
int16 VALUE1;
int16 VALUE2;
void Display_Stuff()
{
Lcd_cmd( LCD_LINE1 );
printf(Write_LCD, " %lu.%02lu0 :) ", VALUE1,VALUE2);
}
//====== Button Press =========================
#int_RB
void ButtonPress(void)
{
if( BUTTON2 == 0 )
{
++VALUE1;
if (VALUE1 > 1000)
VALUE1 = 1000;
}
Else
{
--VALUE1;
if (VALUE1 < 2)
VALUE1 = 1;
}
}
void main()
{
setup_oscillator(OSC_8MHZ);
set_tris_b(0b00001101);
set_tris_c(0b10000000);
LCD_START();
Output_Low(Backlight);
VALUE1=1;
VALUE2=0;
enable_interrupts(INT_RB3);
EXT_INT_EDGE(H_TO_L);
clear_interrupt(INT_RB);
enable_interrupts(GLOBAL);
while (true)
{
Display_Stuff();
}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Sun Sep 05, 2010 2:35 am |
|
|
First thing, 'Interrupt on change', does what it says. It generates an interrupt _when the level on the pin changes_. It does not support setting the 'edge'. This later ability is reserved for the hardware interrupt pin(s). This is why the setting edge function, refers to int_ext. So your function would be called on both edges, and needs to be written to handle this, and the edge selection code does nothing...
Then, if you want to do direct I/O, and not change the tris, select 'fast_io'. There is a very significant risk, that if your LCD code, does a write anywhere to portB, the tris may be being overridden.
Finally, simple question. Compiler version?. The individual bit masking involved in the interrupt on change on some of the later chips, is faulty in some compiler versions.
Best Wishes |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Sun Sep 05, 2010 4:24 am |
|
|
The last comment about tris, is almost certainly your problem.
I'm assuming the LCD code, is the code you have posted in the other thread about LCD speed. If so, this performs a byte wide output to port B, which will set the tris to zero. Your interrupt will then never work. You _need_ to select #use fast_io(B)
Best Wishes |
|
|
scottc
Joined: 16 Aug 2010 Posts: 95
|
|
Posted: Sun Sep 05, 2010 4:44 pm |
|
|
I was using 4.108 ver.
I tried the LCD routine with the button test using both fast_io and the
standard io produced by the compiler.
In both cases the lcd and button function worked fine. The help file talks
about using Tris function and says that
These functions allow the I/O port direction (TRI-State) registers to be set. This must be used with FAST_IO and when I/O ports are accessed as memory such as when a # BYTE directive is used to access an I/O port. Using the default standard I/O the built in functions set the I/O direction automatically.
If I understand what your saying, then basically if using Tris to set the Pin
direction will work ok, but if you introduce a ISR into the code and I don't use Fast_IO then the default std/io of the compiler will go out to lunch and choke ?
Is that correct ?
Thanks Scott |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Mon Sep 06, 2010 1:54 am |
|
|
With 'standard_io', the port direction, is set whenever you read or write to a port or bit. So, in your LCD code, the tris gets set to '0' specifying 'all output', by the output_b instruction. If you then don't have an interrupt, but read the port bit in a loop, the act of reading the port bit, sets the required pin to 'input', and the read code works.
Problem with the interrupt, is that the 'read', doesn't occur, till _after_ the interrupt has fired. Since the port has been set as an 'output', the interrupt won't fire, so you are stuck.
Two routes round:
1) Use fast_io. This makes controlling the tris _your_ responsibility.
2) Tell the code to set the required pin as an input. You could (for instance), add a dummy 'read' of the input pin to the LCD code, which would then do this.
Best Wishes |
|
|
scottc
Joined: 16 Aug 2010 Posts: 95
|
|
Posted: Mon Sep 06, 2010 1:36 pm |
|
|
Ttelamh, ah ha I see, Excellent explaination.
I appreciate your insight. With respect to using the tris for the direction
register. I notice that, in the compiler under the device editor Tris is
disabled for the 16f886 part in the "Other features" section
I had read somewhere that using tris was not a good idea. I am curious
to know if you dont use tris to set the direction of a port pin is there a
more reliable method of doing so ?
Most of the code I will be writing in the short term will use byte wide I/0
so I guess I am trying to figure out the correct method to configure port
pins so the compiler will know never to change an actual pin setting.
Is there any potential issues to using Tris going forward with some of the newer parts, like the f18 series.
Thanks Scott. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19538
|
|
Posted: Mon Sep 06, 2010 1:43 pm |
|
|
OK.
Historically, on the older chips, there was no tris register, and instead a separate tris instruction. This is still available on the later PIC 16 chips, but is no longer recommended. Instead you should write directly to the tris register. Just use the compiler's tris instruction, it will use the older instruction on chips that support it, and access the registers on latter chips.
Best Wishes |
|
|
scottc
Joined: 16 Aug 2010 Posts: 95
|
|
Posted: Mon Sep 06, 2010 2:49 pm |
|
|
Ok, will do
Thanks for the help
Best regards Scott |
|
|
|
|
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
|