|
|
View previous topic :: View next topic |
Author |
Message |
ILLIAS28
Joined: 11 Jan 2011 Posts: 42
|
Problem with pic18f2550 |
Posted: Fri May 20, 2022 12:12 pm |
|
|
Hi everybody,
Could anyone help me please? I am trying to read data from a GPS module using UART. I have used the next C program with CCS 5, but it doesn't work either on simulation in ISIS nor in real on a breadboard using pic18f2550.
But when I change the pic18f2550 with pic18f252 it works good in simulation in ISIS. I use the same code i just change "#include <18F2550.h>" with "#include <18F252.h>
Code: | #include <18F2550.h>
#device PASS_STRINGS=IN_RAM
#fuses HS NOWDT PUT NOPROTECT BROWNOUT NOLVP NOCPD WRT NODEBUG
#use delay(clock=8000000)
#use rs232(baud=4800,UART1,BITS=8,XMIT=PIN_C6,RCV=PIN_C7,PARITY=N,STOP=1,ERRORS)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#define LCD_ENABLE_PIN PIN_B5
#define LCD_RS_PIN PIN_B4
#define LCD_RW_PIN PIN_B6
#define LCD_DATA4 PIN_B0
#define LCD_DATA5 PIN_B1
#define LCD_DATA6 PIN_B2
#define LCD_DATA7 PIN_B3
#include <lcd.c>
#byte UCFG = 0xF6F
#bit UTRDIS = UCFG.3
int16 ndxint, i;
char *reponse , txt[100],texto[45],latit[12],longit[13],string[10],c;
unsigned char ndxcar=0, rec_data=0 ,zz,xx,bb;
float lat;
#INT_RDA
void SerialInt()
{
txt[i]=getchar();
i++;
}
void effacer()
{
memset(txt,NULL,100);
memset(texto,NULL,45);
memset(latit,NULL,12);
memset(longit,NULL,13);
reponse=NULL;
i=0;
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
SET_TRIS_B(0x00);
SET_TRIS_C(0x80);
i=0;
effacer();
lcd_init();
DELAY_ms(1000);
ENABLE_INTERRUPTS(GLOBAL); // Enable Interrupts
ENABLE_INTERRUPTS(INT_RDA);
lcd_putc('\f');
printf(lcd_putc,"hallo");
DELAY_ms(3000);
lcd_putc('\f');
for(;;)
{
do{
reponse=strstr(txt,"GGA");
}while (reponse == NULL);
strncpy(texto,reponse,44);
texto[44]='\0';
printf(LCD_PUTC,"%s",texto);
delay_ms(3000);
lcd_putc('\f');
effacer();
delay_ms(1000);
}
}
|
_________________ i am newbe |
|
|
PrinceNai
Joined: 31 Oct 2016 Posts: 481 Location: Montenegro
|
|
Posted: Fri May 20, 2022 3:44 pm |
|
|
I'm in the middle of a busy Friday, so I haven't really go through the code. Be warned, you might get some interesting answers regarding ISIS (hint: see sticky) :-) |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19568
|
|
Posted: Sat May 21, 2022 5:08 am |
|
|
Your problem is the clock rate.
The 2550 has a much more complex clock that the 252. Your setup is not
setting the clock up correctly, so the code won't work.
By default the chip wakes with the CPUDIV4 fuse set.
Easiest way is to use the compiler to make the settings for you:
Code: |
#include <18F2550.h>
#device PASS_STRINGS=IN_RAM
#fuses HS NOWDT PUT NOPROTECT BROWNOUT NOLVP NOCPD WRT NODEBUG
#use delay(crystal=8000000)
|
Note the critical change in the last line. This tells the compiler that your
8MHz is coming from a crystal. With this extra information, the compiler
will automatically add the CPUDIV1 fuse setting (and in fact the PLL2
setting, which then feeds the USB clock correctly from 4MHz). |
|
|
ILLIAS28
Joined: 11 Jan 2011 Posts: 42
|
|
Posted: Sat May 21, 2022 1:24 pm |
|
|
thank you very much for your help Ttelmah.
i have changed "clock" with "crystal" and now it's working in simulation but not in real on the pic.i think it must be a problem with fuse configuration.i think it's a problem with the compiler of ccs or somthing else.because i have tried this program with MIKROC pro for pic and it's working good. _________________ i am newbe |
|
|
ILLIAS28
Joined: 11 Jan 2011 Posts: 42
|
|
Posted: Sun May 22, 2022 7:07 am |
|
|
can someone please help me with configuration of fuses pic18f2550 _________________ i am newbe |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19568
|
|
Posted: Sun May 22, 2022 7:15 am |
|
|
Seriously, I'd be more suspicious that something in the hardware is wrong.
The crystal itself, the capacitors used for the loading on this, the power
connections (all have to be made), etc. etc.. |
|
|
ILLIAS28
Joined: 11 Jan 2011 Posts: 42
|
|
Posted: Sun May 22, 2022 7:58 am |
|
|
How can i load an image here? _________________ i am newbe |
|
|
ILLIAS28
Joined: 11 Jan 2011 Posts: 42
|
|
Posted: Sun May 22, 2022 8:32 am |
|
|
I am using the same PIC, the same crystal, the same components on the same place on the same test board, but when i write and compile the program with MikroC it works fine, but when i use CCS pic it doesn't work.
Normally the screen should display "Hallo" for 3 seconds, the LCD should clear and wait for data from GPS and display something on the LCD. But "Hallo" stays displayed on the LCD and that's all. What's wrong in my code? Could you please help me? _________________ i am newbe |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19568
|
|
Posted: Sun May 22, 2022 9:43 am |
|
|
On posting an image, what you do is put the image onto a hosting site,
and post a link here.
Now if the chip is displaying your Hallo message, then it is running.
Prove first of all that it is running at the right speed. Instead of going to
the serial handling, have it just display the first message, wait 3 seconds,
then clear the LCD and display a second message. If this works and the
time between the messages is 3 seconds, then you know that the chip
is working correctly, and at the right speed.
Now, there are serious issues with all your serial handling.
First the INT_RDA needs to test the value of 'i' to ensure that it cannot
go past 99, Otherwise if lots of data arrives, this will overwite the values
in the following variables. Disaster.
If the GPS is sending a string every second, and this is 44 characters,
then in the 3 second delay, the input buffer will have overflowed, and
destroyed things after it.
Your effacer routine takes lot of time, and is uneccesarily complex.
You only need to set the counter back to zero, and put a single null
charcter at the start of each buffer.
Then you have the issue, that the response test can go 'TRUE', before
the entire sequence has been received. You could have just received
the first three characters and it'll return TRUE. You should set a flag
in he RDA interrupt when the line feed at the end of the packet is
seen, and only test when this is set. Clear it immediately after testing. |
|
|
ILLIAS28
Joined: 11 Jan 2011 Posts: 42
|
|
Posted: Sun May 22, 2022 10:23 am |
|
|
Thank you very much Ttelmah for your help. I am going to test all that and give feedback. _________________ i am newbe |
|
|
ILLIAS28
Joined: 11 Jan 2011 Posts: 42
|
|
Posted: Sun May 22, 2022 12:45 pm |
|
|
Hi,
I have tested a simple program as you told me: it displays once "Hi" for 3 seconds and then it toggles between 'Hallo" and "salut" every 3 seconds.
It's working fine. But when i add the code concerning the RDA interrupt (all what is commented) the program becomes crazy and displays strange characters on the lcd and the program doesn't work anymore.
Code: |
#include <18F2550.h>
#use delay(crystal=8000000)
#use rs232(baud=9600,UART1,BITS=8,XMIT=PIN_C6,RCV=PIN_C7,PARITY=N,STOP=1,ERRORS)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LCD_ENABLE_PIN PIN_B5
#define LCD_RS_PIN PIN_B4
#define LCD_RW_PIN PIN_B6
#define LCD_DATA4 PIN_B0
#define LCD_DATA5 PIN_B1
#define LCD_DATA6 PIN_B2
#define LCD_DATA7 PIN_B3
#include <lcd.c>
char txt[300];
int16 i;
//!#INT_RDA
//!void SerialInt()
//!{
//!do{
//! txt[i]=getchar();
//!
//! i++;
//!}while (i<=298);
//!}
void main()
{
SET_TRIS_B(0x40);
SET_TRIS_C(0x80);
i=0;
lcd_init();
DELAY_ms(1000);
lcd_putc('\f');
printf(lcd_putc,"hi");
DELAY_ms(3000);
lcd_putc('\f');
//!ENABLE_INTERRUPTS(INT_RDA);
//!ENABLE_INTERRUPTS(GLOBAL);
while(TRUE)
{
printf(lcd_putc,"hallo");
DELAY_ms(3000);
lcd_putc('\f');
DELAY_ms(1000);
printf(lcd_putc,"salut");
DELAY_ms(3000);
lcd_putc('\f');
}
} |
_________________ i am newbe |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19568
|
|
Posted: Sun May 22, 2022 11:09 pm |
|
|
OK. So that tells us the problem is with the serial handling code, not
fuses.
As I said there is a huge potential problem with your serial handling,
that if data arrives during the delays, the interrupt can/will start writing
over the variables after the end of the buffer.
Code: |
#INT_RDA
void SerialInt()
{
txt[i]=getchar();
i++;
if (i>99)
i=99;
}
|
The effect of this is dependant on the order the variables are stored in
RAM. Suspect your MicroC code just happens to lay the variables out
in an order that is not causing problems.... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9255 Location: Greensville,Ontario
|
|
Posted: Mon May 23, 2022 6:05 am |
|
|
hmm... maybe I'm reading this wrong...
//!#INT_RDA
//!void SerialInt()
//!{
//!do{
//! txt[i]=getchar();
//!
//! i++;
//!}while (i<=298);
//!}
I see this as
A single interrupt has fired, he then stays in the do-while loop until 298 characters have been read in and placed into the txt[buffer].
He only leaves the ISR after 298 reads ?? |
|
|
ILLIAS28
Joined: 11 Jan 2011 Posts: 42
|
|
Posted: Mon May 23, 2022 6:39 am |
|
|
Thank you Temtronic for your help,
I would like to load 298 characters coming from uart into my array txt, and then stop loading characters coming from uart, so i can parse the data in txt. Should i do that like this:
Code: | #INT_RDA
void SerialInt()
{
if(i!=298)
{
txt[i]=getchar();
i++;
}
} |
_________________ i am newbe |
|
|
ILLIAS28
Joined: 11 Jan 2011 Posts: 42
|
|
Posted: Mon May 23, 2022 8:35 am |
|
|
Hi Tetelmah
Quote: | You should set a flag
in he RDA interrupt when the line feed at the end of the packet is
seen, and only test when this is set. Clear it immediately after testing.
|
Do you mean a flag in registers of pic or a variable?[/quote] _________________ i am newbe |
|
|
|
|
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
|