View previous topic :: View next topic |
Author |
Message |
yamenn
Joined: 14 Jun 2014 Posts: 10
|
GPS DATA using RDA interrupt and Timer0 interrupt problem |
Posted: Sat Jun 14, 2014 8:37 am |
|
|
Hey Everyone
I am trying to get GPS DATA using RDA interrupt and using Timer0 interrupt for alarm
I can't use the both interrupts in the same time
Any ideas ? Wink
Code: |
#include <18f452.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code protected from reading
#FUSES NOBROWNOUT //No brownout reset
//#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#use delay(clock=20M)
#use rs232(baud=4800, xmit=PIN_C6,rcv=PIN_C7)
#include <lcd11.c>
#include <stdlib.h>
#int_RDA
void RDA_isr(void)
{
int i;
let=getch();
if (let=='$')
{
letter[0]=getch();
letter[1]=getch();
letter[2]=getch();
letter[3]=getch();
letter[4]=getch();
if (letter[0]=='G'&&letter[1]=='P'&&letter[2]=='V'&&letter[3]=='T'&&letter[4]=='G')
{
gets(speed);
}
if (letter[0]=='G'&&letter[1]=='P'&&letter[2]=='Z'&&letter[3]=='D'&&letter[4]=='A')
{
gets(time);
//for (i=1;i<=6;i++)
//ck [i-1]=time[i];
day [0]=time[12];
day [1]=time[13];
mun [0]=time[15];
mun [1]=time[16];
year[0]=time[18];
year[1]=time[19];
year[2]=time[20];
year[3]=time[21];
}
if (letter[0]=='G'&&letter[1]=='P'&&letter[2]=='G'&&letter[3]=='G'&&letter[4]=='A')
{
gets(letter1);
//for (i=0;i<=6;i++)
//ck[i]=letter1[i];
for (i=12;i<=22;i++)
L1[i-12]=letter1[i];
L3=letter1[24];
for (i=26;i<=37;i++)
L4[i-26]=letter1[i];
L5=letter1[39];
}
}
}
#int_timer0
timer0_isr()
{
set_timer0(255);
lcd_putc('\f');
lcd_putc("Hello");
delay_ms(2000);
}
void main()
{
int i;
enable_interrupts(GLOBAL);
enable_interrupts(int_rda);
enable_interrupts(INT_TIMER0);
setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_1);
lcd_init();
delay_ms(150);
set_timer0(255);
while(1)
{
for (i=0;i<=15;i++)
lcd_putc(L1[i]);
puts(L1);
delay_ms(1000);
lcd_putc('\f');
delay_ms(500);
}
}
|
this is my test code |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9221 Location: Greensville,Ontario
|
|
Posted: Sat Jun 14, 2014 8:54 am |
|
|
1) you need to add 'errors' to the use rs232(....options....)
2) your ISR for serial is a disaster
3) putting 2 SECOND delays in any ISR is WRONG |
|
|
yamenn
Joined: 14 Jun 2014 Posts: 10
|
|
Posted: Sat Jun 14, 2014 10:16 am |
|
|
when I cancel the timer0 interrupt the PIC take the GPS Data and write it on LCD
it is just a test and I wonder How to use Timer0 interrupt while RDA interrupt is working |
|
|
yamenn
Joined: 14 Jun 2014 Posts: 10
|
|
Posted: Sat Jun 14, 2014 10:24 am |
|
|
Thank you temtronic for your reply |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Sat Jun 14, 2014 11:02 am |
|
|
You need to understand that interrupts don't (by default) interrupt interrupts.
All the time your code is sitting in the 'timer' code, INT_RDA is blocked. Result lost data, and hung UART. (you need to add ERRORS to the #use rs232 declaration - this _must_ always be used with the hardware UART, unless _you_ handle UART errors yourself.
Reason is that the older chips didn't even have this ability.
Even on slightly later chips, there are restrictions on which interrupts can interrupt others.
In your case, INT_RDA, can be set to interrupt the timer, by adding:
#DEVICE HIGH_INTS=TRUE
near the head of the main file (just before fuses etc.).
and then adding the keyword 'HIGH' to the INT_RDA declaration,
It is this interrupt that needs to interrupt the timer, since your timer handling is so slow.
Generically it'd be better to not spend so long in the timer. The whole approach is rather flawed, since several things will also result in interrupts being disabled in large parts of the code. Have your main loop running quickly, rather than delaying, and then do the things you want in this. Have the things done to the LCD, ever x-hundred loops. Then set a flag in your timer, and in the main when this goes true, do the job associated with this.
Generally an interrupt should _only_ handle the hardware events. All other tasks should be out in the main code. |
|
|
yamenn
Joined: 14 Jun 2014 Posts: 10
|
|
Posted: Sat Jun 14, 2014 12:32 pm |
|
|
Thank you Ttelmah for your reply.
I need to ask you about "adding the keyword 'HIGH' to the INT_RDA declaration".
How to do that ?
Sorry for my poor language. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Sat Jun 14, 2014 1:06 pm |
|
|
Read the manual.... |
|
|
yamenn
Joined: 14 Jun 2014 Posts: 10
|
|
Posted: Sat Jun 14, 2014 1:16 pm |
|
|
i read it but show me examples for adding the keyword 'HIGH' to the INT_RDA declaration |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
yamenn
Joined: 14 Jun 2014 Posts: 10
|
|
Posted: Sat Jun 14, 2014 1:53 pm |
|
|
Thanks
I will try and reply soon. |
|
|
yamenn
Joined: 14 Jun 2014 Posts: 10
|
|
Posted: Sat Jun 14, 2014 7:21 pm |
|
|
NOW IT IS A STRANGE PROBLEM !!!
I try to cancel RDA interrupt like this code.
In 18f452 the code didn't work and it just show the data of GPS and no effect for Timer0 interrupt.
When I change the PIC to 16f877a the code is working as I want.
Anyone explain that ?
Code: |
#include <18f452.h>
// #include <16f877a.h>
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code protected from reading
#FUSES NOBROWNOUT //No brownout reset
//#FUSES NOMCLR //Master Clear pin used for I/O
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#use delay(clock=20M)
#use rs232(baud=4800, xmit=PIN_C6,rcv=PIN_C7,ERRORS)
#include <lcd11.c>
#include <stdlib.h>
#int_timer0
timer0_isr()
{
//disable_interrupts(int_rda);
set_timer0(255);
lcd_putc('\f');
lcd_putc("Hello");
delay_ms(2000);
}
char let,letter[5],letter1[70],L1[16],L4[16],day[2],mun[2],year[4],time[25],speed[40],km[7],L3,L5;
void GPS_Data(void)
{
int i;
mh:
while (let!='$')
{
let=getch();
}
if (let=='$')
{
letter[0]=getch();
letter[1]=getch();
letter[2]=getch();
letter[3]=getch();
letter[4]=getch();
/*
if (letter[0]=='G'&&letter[1]=='P'&&letter[2]=='V'&&letter[3]=='T'&&letter[4]=='G')
{
gets(speed);
}
if (letter[0]=='G'&&letter[1]=='P'&&letter[2]=='Z'&&letter[3]=='D'&&letter[4]=='A')
{
gets(time);
//for (i=1;i<=6;i++)
//ck [i-1]=time[i];
day [0]=time[12];
day [1]=time[13];
mun [0]=time[15];
mun [1]=time[16];
year[0]=time[18];
year[1]=time[19];
year[2]=time[20];
year[3]=time[21];
}
*/
if (letter[0]=='G'&&letter[1]=='P'&&letter[2]=='G'&&letter[3]=='G'&&letter[4]=='A')
{
gets(letter1);
//for (i=0;i<=6;i++)
//ck[i]=letter1[i];
for (i=12;i<=22;i++)
L1[i-12]=letter1[i];
L3=letter1[24];
for (i=26;i<=37;i++)
L4[i-26]=letter1[i];
L5=letter1[39];
}
else goto mh;
}
}
void main()
{
int i;
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER0);
setup_timer_0(RTCC_EXT_L_TO_H|RTCC_DIV_1);
lcd_init();
delay_ms(150);
set_timer0(255);
while(1)
{
GPS_Data();
for (i=0;i<=15;i++)
lcd_putc(L1[i]);
puts(L1);
delay_ms(1000);
lcd_putc('\f');
//delay_ms(500);
}
}
| |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Jun 14, 2014 9:39 pm |
|
|
Look at the Timer0 section in the 18F452 and 16F877 data sheets.
What is the main difference, in terms of features, between Timer0 in
the 18F PIC and the 16F PIC ?
How can you configure the 18F Timer0 to be similar to the 16F one ?
Look in the 18F452.h data sheet, in the section on Timer0, and find
a suitable parameter to use with the setup_timer_0() function, to
change the operation of the timer so it's similar to the 16F877. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19499
|
|
Posted: Sun Jun 15, 2014 12:29 am |
|
|
I wonder how old the compiler is that the poster is using?.
Reason is simply that the manual now clearly lists how to use HIGH. The posts that PCM_programmer is pointing to, date back a couple of years, when documentation hardly existed (it was in the read.me with the compiler, not in the manual). If you look at the #INT_xxxx manual section, and the #DEVICE manual section, both parts are explained.
I see PCM_programmer has answered the timer question. |
|
|
yamenn
Joined: 14 Jun 2014 Posts: 10
|
|
Posted: Sun Jun 15, 2014 7:42 am |
|
|
The compiler is C Compiler |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Sun Jun 15, 2014 7:54 am |
|
|
yamenn wrote: | The compiler is C Compiler |
We assume on this forum you are using CCS 'C' compiler.
You have been asked for your compiler version number.
Mike |
|
|
|