|
|
View previous topic :: View next topic |
Author |
Message |
binu.kr
Joined: 22 Jun 2008 Posts: 20 Location: trivandrum
|
how to write interrupt service routine in 0004h address |
Posted: Wed Jul 16, 2008 12:19 am |
|
|
I am making a scrolling msg display, usart communication is used to give data directly to display from keyboard and i am shorting rb4 pin with rx pin of usart. If any interrupt comes i want to go to 0x0004 (interrupt vector address) and write a program for usart reception. Please help me to write program in #org 0x0004h location. I am working in pic16f877a and mplab v8.0, pcw compiler ide version 3.36. Can u please help me. _________________ nn |
|
|
Ttelmah Guest
|
|
Posted: Wed Jul 16, 2008 2:45 am |
|
|
The interrupt handler, has to do quite a bit of 'housekeeping'.
When the interrupt occurs, the processor calls the code at address '4', and the code here, _must_ save any 'in use' registers, _before_it starts to do it's own work. Then after finishing, these registers need to be restored, before returning to the main code. Also, if there is more than one interrupt, the code needs to work out which one has occurred, and call the correct routine.
Hence the code at address '04', needs to be more than just your routine. The way interrupts are handled in CCS, depends on how you want to deal with the needs for this housekeeping.
The simplest approach, will normally work fine:
Code: |
int8 chr;
int1 have_data=FALSE;
#INT_RDA
void serial_receive(void) {
chr=getc();
have_data=TRUE;
}
|
This tells CCS, to treat the routine 'serial_receive', as the handler for the RDA interrupt. In this example, it simply reads the waiting character (since the interrupt says there _is_ a character, stores it in a global variable, so the 'main' code can get at it, and sets the flag to say 'I have data'.
Done like this, the compiler will automatically generate all the housekeeping code needed at 04, and then call this routine. It'll also clear the interrupt flag automatically on the return, and restore all the registers.
You can do this for each interrupt you want to use, and the compiler automatically adds the extra tests needed to the 'housekeeper'.
Now, the 'housekeeping' routine, is called the 'global interrupt handler', and you can write your own.
If you generate a routine, just as shown, but use the keyword #INT_GLOBAL, then this replaces the system housekeeper, and will be put directly at address 4. Look in the examples at 'EX_GLINT'. However big caveat. The saving done in this example, is the _minimum_ needed. If you start to do anything more complex in the core of the routine, a _lot_ more registers need to be saved. If (for instance), you access an array, the table pointer registers need to be saved and restored. etc. etc..
So, while this is the way to go for the ultimate in speed, it should only be done, if you need that speed, and understand exactly what is needed.
Best Wishes |
|
|
binu.kr
Joined: 22 Jun 2008 Posts: 20 Location: trivandrum
|
problem in using interrupt vector 0004h |
Posted: Wed Jul 16, 2008 10:54 pm |
|
|
thank u for ur reply
But i am still in problem while i am using interrupt service routine the
program doesn't go to the main function. It only go to the
void serial_receive (void )
When i press a key in the keyboard, I want to go main function and
execute the main program. If usart interrupt comes it must go to the
service routine and after completing the service routine it must return
to main function. Pls help me to solve this problem.
this is my testing code
Code: |
#include<p16f87x.h>
#include<string.h>
char chr;
int k;
#INT_RDA
void serial_receive(void)
{
chr=getc();
write_eeprom(0,chr);
delay_ms(5);
output_b(0xFF);
#asm
RETFIE
#ENDASM
}
void main()
{
int k;
TXIE=1;
RCIE=1;
PEIE=1;
GIE =1;
output_a(0xff);
output_b(0x00);
k=read_eeprom(0);
output_d(k);
delay_ms(1000);
} |
This program didn't go to main function, and there is no output in port d,
so please help me. thank u _________________ nn |
|
|
Ttelmah Guest
|
|
Posted: Thu Jul 17, 2008 2:31 am |
|
|
First, get rid of the RETFIE....
By adding this, you have bypassed the housekeeping on the return, and everything will go wrong.
Then, get rid of the delay, and the EEPROM write....
The problem is that an EEPROM write takes about 4mSec, and the delay, another 5. Put together, the routine now takes about 9mSec. Serial characters at (say) 9600bps (you don't show your serial setup, so we can't tell what rate you are using), can arrive about every mSec. Hence, after one character, you are still inside the routine, and things _will_ go wrong. You need to get out of the interrupt handler ASAP.
Look at EX_SISR, which shows how to write received characters into a circular buffer. Then in your 'main', check if a character is in the buffer, and if so, write it to the EEPROM.
However, then another caveat. The EEPROM, has a relatively short 'write' life (in the case of the chip you are using, a minimum of 100K cycles). If you wrote a character every 4mSec (the typical write time), you could destroy the EEPROM in under 7 minutes. The EEPROM, is _not_ designed for continuous updates like this.
Best Wishes |
|
|
binu.kr
Joined: 22 Jun 2008 Posts: 20 Location: trivandrum
|
Re: thank u |
Posted: Tue Jul 22, 2008 11:23 pm |
|
|
thanks for your reply.....your reply helped me to solve most of the problem in my program... _________________ nn |
|
|
binu.kr
Joined: 22 Jun 2008 Posts: 20 Location: trivandrum
|
HOW TO REMOVE GLARE |
Posted: Sat Aug 02, 2008 3:47 am |
|
|
how to avoid glare in scrolling message display
PostPosted: Sat Aug 02, 2008 3:30 am Reply with quote Edit/Delete this post Delete this post
iam making a 10 character 5*7 scrolling led display using pic 16f877a....but in night it glows with glare ,can u please give me a solution to overcome this problem,glare is in next line onlymeans coming line, iam using shift register to give positive voltage to led,......pls help me to solve this problem
my display loop is
for(p1=0;p1<50;p1++)
{
V2=temp5[P1];
#ASM
BCF PORTC,3...clk to shift register
NOP
NOP
CALL DELAY1
BSF PORTC,3
MOVF V2,0
MOVWF PORTD
CALL DELAY1
#ENDASM
}
OUTPUT_BIT(PIN_C0,0);
#ASM
CALL DELAY1
#ENDASM
iam using asm inside because while iam using c code for display loop more glare is coming
my c loop,spi ptrotocol used to write value 0x01 to shiftregister
for(p1=0;p1<50;p1++)
{
OUTPUT_BIT( PIN_C3,0); shift register clock
DELAY();
OUTPUT_BIT( PIN_C3,1);
output_d(temp5[p1]);
DELAY();
}
OUTPUT_BIT(PIN_C0,0);
DELAY();
thank u ...... _________________ nn |
|
|
|
|
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
|