|
|
View previous topic :: View next topic |
Author |
Message |
mohsin_hashmi
Joined: 07 Oct 2012 Posts: 12
|
Entering ISR when Power Up !!!! Plz Help |
Posted: Wed Oct 17, 2012 12:24 am |
|
|
I am making an interrupt based keypad. When I run the simulation it enters ISR even before I pressed any key. I have posted the keypad detecting code and the code for "#include <kbd_m.c> ".
I am monitoring the key presses on Serial Port
Please help !!! :(
Uploaded with ImageShack.us
Code: |
#include <18F452.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOOSCSEN //Oscillator switching is disabled, main oscillator is source
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES NOPUT //No Power Up Timer
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES LVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOCPD //No EE protection
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#include <string.h>
#include <kbd_m.c>
//#use standard_io(d)
#use fast_io(d)
#INT_EXT
//#use fast_io(d)
void ext_isr(void)
{
unsigned char temp=0;
unsigned char temp2=0;
unsigned char temp3=0;
unsigned char temp4=0;
unsigned char col=0;
unsigned char row=4;
int1 a=0;
int d=0;
printf("In ISR\n\r");
set_tris_d(0x0e);
temp=input_d();
//set_tris_d(0x0e);
temp=temp^(0x0e);
temp2=swap(temp);
while(temp2<<=1)
col++;
printf("Col : %d\n\r",col);
//finding row starts here
//set_tris_d(0x0e);
output_d(0xef);
if (input_d()!=0xef)
row=0;
//////////////////////////////// end of row
}
void main()
{
char k;
char name[10];
char temp[10];
int8 new;
putc('\f');
puts("**********************************");
puts(" Console Test ");
puts("**********************************");
putc('\n');
putc('\r');
kbd_init();
delay_ms(5);
enable_interrupts(global);
enable_interrupts(INT_EXT);
ext_int_edge(0,H_TO_L);
while(1)
{
printf("Inside the Loop");
putc('\n');
putc('\r');
delay_ms(1000);
}
}
|
Code: | char const KEYS[4][3] = {{'1','2','3'},
{'4','5','6'},
{'7','8','9'},
{'*','0','#'}};
void kbd_init(void)
{
set_tris_d(0x0e);
output_d(0x0e);
}
|
|
|
|
mohsin_hashmi
Joined: 07 Oct 2012 Posts: 12
|
|
Posted: Wed Oct 17, 2012 12:42 am |
|
|
I search the forum for this problem and found that I should clear interrupt flag so I did that now I cant enter the ISR
Code: | #include <18F452.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOOSCSEN //Oscillator switching is disabled, main oscillator is source
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES NOPUT //No Power Up Timer
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES LVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOCPD //No EE protection
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#include <string.h>
#include <kbd_m.c>
//#use standard_io(d)
//#use fast_io(d)
#INT_EXT
//#use fast_io(d)
void ext_isr(void)
{
unsigned char temp=0;
unsigned char temp2=0;
unsigned char temp3=0;
unsigned char temp4=0;
unsigned char col=0;
unsigned char row=4;
int1 a=0;
int d=0;
printf("In ISR\n\r");
set_tris_d(0x0e);
temp=input_d();
set_tris_d(0x0e);
temp=temp^(0x0e);
temp2=swap(temp);
while(temp2<<=1)
col++;
printf("Col : %d\n\r",col);
//finding row starts here
//set_tris_d(0x0e);
//////////////////////////////// end of row
}
void main()
{
char k;
char name[10];
char temp[10];
int8 new;
putc('\f');
puts("**********************************");
puts(" Console Test ");
puts("**********************************");
putc('\n');
putc('\r');
kbd_init();
delay_ms(5);
EXT_INT_EDGE(0,H_TO_L); // 1
CLEAR_INTERRUPT(INT_EXT); // 2
ENABLE_INTERRUPTS(INT_EXT); // 3
ENABLE_INTERRUPTS(GLOBAL); // 4
while(1)
{
printf("Inside the Loop");
putc('\n');
putc('\r');
delay_ms(1000);
}
} |
|
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Wed Oct 17, 2012 1:40 am |
|
|
Quote: | I search the forum for this problem and found that I should clear interrupt flag so I did that now I cant enter the ISR | So, does it now work OK?
OR
Do you still have a problem?
Mike |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Wed Oct 17, 2012 1:58 am |
|
|
It won't work, since the version he has posted, with the ISR cleared, has the fast_io directives all remmed out.
As such, port D, will be reprogrammed as 'output', as soon as he sends '0xE' to it, and so the interrupt won't work. Also whenever a key is pressed it'll be shorting a pin set as output and driven high, to one set as output and driven low. Nice overload.
The following lines need to be present:
Code: |
#use fast_io(D) //near the top of the code
//in the init
set_tris_D(0x70); //remember a '1' implies input a '0' output
output_D(0xF);
|
Get rid of all other TRIS lines.
Remember you need to ensure you leave the interrupt with the lines left driving high. The scanner in the interrupt needs to set just the bottom drive line high, then the second, then the third, and finally the fourth, reading the top three bits at each point to find which key is pressed. Then set the lines all high again before exiting.
Problems:
1) No diodes, so press two keys, and you may see a third made.
2) De-bounce needs to be handled. The interrupt solution, is _not_ a good way to do this.
Best Wishes |
|
|
Geps
Joined: 05 Jul 2010 Posts: 129
|
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Wed Oct 17, 2012 2:11 am |
|
|
Quote: | I didn't think Proteus questions were allowed?... |
I was getting round to that. The guy's in a big hole and asks for more shovels.
Mike
Last edited by Mike Walne on Wed Oct 17, 2012 2:18 am; edited 2 times in total |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Wed Oct 17, 2012 2:15 am |
|
|
Yes, though here if he had done it on a real chip, he might well have just blown it up...
Best Wishes |
|
|
mohsin_hashmi
Joined: 07 Oct 2012 Posts: 12
|
|
Posted: Wed Oct 17, 2012 6:23 am |
|
|
Yes ! I have gotten around the problem Thanks alot :D
But my code has lots of "set_tris_d()" if i get rid of those my ports wont be written properly.
I am posting the latest code but there is just one big problem with that, I just cant get around.
Problem is and occurs when:
When i press any key on row 2 or 3 or 4. the program gets the column and row but after that the column pin corresponding to that row pressed goes low forever.
But this does not happen when i press any column key on row 1
Code: | #include <18F452.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOOSCSEN //Oscillator switching is disabled, main oscillator is source
#FUSES BROWNOUT //Reset when brownout detected
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES NOPUT //No Power Up Timer
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES NODEBUG //No Debug mode for ICD
#FUSES LVP //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOCPD //No EE protection
#FUSES NOCPB //No Boot Block code protection
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#include <string.h>
#include <kbd_m.c>
//#use standard_io(d)
//#use fast_io(d)
//#byte portd=0xf83
#INT_EXT
//#use fast_io(d)
void ext_isr(void)
{
unsigned char temp=0;
unsigned char temp2=0;
unsigned char temp3=0;
unsigned char temp4=0;
unsigned char col=0;
unsigned char row=4;
printf("In ISR\n\r");
//set_tris_d(0x0e);
temp=input_d();
set_tris_d(0x0e);
temp=temp^(0x0e);
temp2=swap(temp);
while(temp2<<=1)
col++;
printf("Col : %d\n\r",col);
//finding rowwwww starts hereeeeeeee
set_tris_d(0x0e);
output_d(0xef);
set_tris_d(0x0e);
temp3=input_d();
temp4=temp3&(0x0f);
if(temp4!=0x0e)
{
printf("%x\n\r",temp3);
printf("%x\n\r",temp4);
set_tris_d(0x0e);
output_d(0x0e);
set_tris_d(0x0e);
printf("Row:1\n\r");
}
else
{
set_tris_d(0x0e);
output_d(0xdf);
set_tris_d(0x0e);
temp3=input_d();
temp4=temp3&(0x0f);
if(temp4!=0x0e)
{
printf("%x\n\r",temp3);
printf("%x\n\r",temp4);
set_tris_d(0x0e);
output_d(0x0e);
set_tris_d(0x0e);
printf("Row:2\n\r");
output_d(0x0e);
set_tris_d(0x0e);
}
else
{
set_tris_d(0x0e);
output_d(0xbf);
set_tris_d(0x0e);
temp3=input_d();
temp4=temp3&(0x0f);
if(temp4!=0x0e)
{
printf("%x\n\r",temp3);
printf("%x\n\r",temp4);
set_tris_d(0x0e);
output_d(0x0e);
set_tris_d(0x0e);
printf("Row:3\n\r");
}
else
{
set_tris_d(0x0e);
output_d(0x7f);
set_tris_d(0x0e);
temp3=input_d();
temp4=temp3&(0x0f);
if(temp4!=0x0e)
{
printf("%x\n\r",temp3);
printf("%x\n\r",temp4);
set_tris_d(0x0e);
output_d(0x0e);
set_tris_d(0x0e);
printf("Row:4\n\r");
}
}
}
}
}
void main()
{
char k;
char name[10];
char temp[10];
int8 new;
putc('\f');
puts("**********************************");
puts(" Console Test ");
puts("**********************************");
putc('\n');
putc('\r');
kbd_init();
EXT_INT_EDGE(H_TO_L); // 1
CLEAR_INTERRUPT(INT_EXT); // 2
ENABLE_INTERRUPTS(INT_EXT); // 3
ENABLE_INTERRUPTS(GLOBAL); // 4
while(1)
{
printf("Inside the Loop");
putc('\n');
putc('\r');
delay_ms(1000);
}
} |
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Wed Oct 17, 2012 6:51 am |
|
|
problem #1 ...ISIS aka Proteus simulation...
problem #2 ... no RS232 level converters in schematic
comments...
1) why not look at the keyboard programs that CCS kindly supplys for free when you buy the compiler ?It works and there are now several versions on the forum that work as well...
2) read the PIC101 sticky/message at the top of the forum...
3) GET RID OF PROTEUS ! You can't possibly expect to debug your code while you're running faulty,buggy PROTEUS.There are at least 10 errors in your schematic that if real hardware was built exactly as shown would never,ever work. |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Wed Oct 17, 2012 6:54 am |
|
|
Are you still working in ISIS, or with real hardware?
Mike
EDIT If you make your code readable by using proper indentation you will be more likely to get assistance. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19496
|
|
Posted: Wed Oct 17, 2012 7:06 am |
|
|
No, your code does _not_ need all the set_tris lines.
It only needs to set TRIS _once_. You are programming four bits as outputs and three as inputs (with one unused that really should be set as an output). Once this is done, they stay that way, and never need to change. Set the TRIS in the init, and you never need to touch it again.
Thing is though that your TRIS settings are still completely the wrong way round.
You have the three pins with pull down resistors, _which must be the ones you use as inputs, for the keyboard to work_, on D4,D5, & D6. These are the pins that need to be inputs. Then they will pull 'down' when a key is not made (because of the resistors), and be pulled 'up', if the key is made at an intersection to a 'row' wire that is driven high.
So the sequence is:
1) Set tris to 0x70
2) output 0x0F on the port
3) Now wait for any of the input lines to go low. - interrupt
4) In the interrupt. Set 'mask' = 1.
5) Output mask to port D
6) is any input bit high?. If so, key is at the intersection of 'mask', and the bit that is high. store and exit.
7) If not, multiply mask by 2. Is it 16?. If so exit. Otherwise loop back to 5
In each case, when you exit, you need to output 0x0F to the port before leaving the routine.
You need never change the TRIS.
But key thing is that you _must_ be reading the bits on the keyboard that are connected to the resistors. This is the 'output' side of the keypad.
Best Wishes |
|
|
mohsin_hashmi
Joined: 07 Oct 2012 Posts: 12
|
|
Posted: Wed Oct 17, 2012 7:24 am |
|
|
Because the keypad driver that comes with CCS C is a polling based. |
|
|
mohsin_hashmi
Joined: 07 Oct 2012 Posts: 12
|
|
Posted: Wed Oct 17, 2012 7:35 am |
|
|
Ok Ttelmah
I will change the code ! will post soon ! |
|
|
mohsin_hashmi
Joined: 07 Oct 2012 Posts: 12
|
|
Posted: Wed Oct 17, 2012 8:03 am |
|
|
the three column pins with pull ups are connected to d4->col0 ,d5->col1, d6->col2 (inputs)
row wires are connected to d0->row0, d1->row1, d2->row2, d3>row3
port d is : d7 d6 d5 d4 d3 d2 d1 d0 = 00001111
when key is pressed the and gate doesn't go low !!!
the code is as :
Code: | #include "C:\Users\Mohsin\Desktop\pro\kpd_2.h"
void main()
{
putc('\f');
puts("**********************************");
puts(" Console Test ");
puts("**********************************");
putc('\n');
putc('\r');
set_tris_d(0x70);
output_d(0x0f);
ext_int_edge(0,H_TO_L);
clear_interrupt(int_ext);
enable_interrupts(int_ext);
enable_interrupts(global);
while(1)
{
printf("Inside the Loop\n\r");
delay_ms(1000);
}
} |
|
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Wed Oct 17, 2012 8:07 am |
|
|
You have not answered the question:-
Are you working with ISIS or real hardware?
I'm not going any further 'til you do.
Mike |
|
|
|
|
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
|