|
|
View previous topic :: View next topic |
Author |
Message |
m1geo
Joined: 31 Dec 2008 Posts: 5 Location: London, England, UK
|
GPS 18F458 Hardware UART Problems |
Posted: Wed Dec 31, 2008 12:39 am |
|
|
Hello, and thank you for reading this post.
I have a problem with a project I'm starting out with. I am attempting to write a GPS logger to SD-card. I know its been done before many-a-time, but I am to improve on this at a later stage.
The PIC is running at 16MHz (no PLL), and displays the screen to the hitachi LCD no problem via (unmodified) LCD.C CCS driver. However, the PIC then locks/hangs/crashes in the delay following the splash screen.
By commenting out the "#use rs232(...)" statement, the program does not hang. This is only a very simple test program, and has no real use. I was intending for the code above to show how the RDA interrupt worked. I wasn't sure if it interrupted on a null character, line feed, carriage return, or for each character. This is what i aimed to find out. The other interrupt just gives approx 1s pulses. Both ISRs just increment a variable and the main routine updates the screen with the data.
As i touched on before, the program works fine without the "#use rs232(...)" statement, but dies with any mention of it.
I have never used the Hardware UART before, and so I may have completely gone around this the wrong way.
I also searched the CCS forums too, and found nothing detailing my problem (closest match; http://www.ccsinfo.com/forum/viewtopic.php?t=36875). I am really stumped by this. My initial thought was about the clock frequency. I am, as I say, unsure.
Any help would be greatly appreciated.
Kind Regards and Happy New Year to all!
George Smart, M1GEO
---
This is the header file, Att1.h:
Code: |
#include <18F458.h>
#device ICD=TRUE
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES WDT128 //Watch Dog Timer uses 1:128 Postscale
#FUSES HS //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOOSCSEN //Oscillator switching is disabled, main oscillator is source
#FUSES NOBROWNOUT //No brownout reset
#FUSES BORV20 //Brownout reset at 2.0V
#FUSES PUT //Power Up Timer
#FUSES NOCPD //No EE protection
#FUSES STVREN //Stack full/underflow will cause reset
#FUSES DEBUG //Debug mode for use with ICD
#FUSES NOLVP //No Low Voltage Programming
#FUSES NOWRT //Program memory not write protected
#FUSES NOWRTD //Data EEPROM not write protected
#FUSES NOWRTB //Boot block not write protected
#FUSES NOCPB //No Boot Block code protection
#FUSES NOWRTC //configuration not registers write protected
#FUSES NOEBTR //Memory not protected from table reads
#FUSES NOEBTRB //Boot block not protected from table reads
#use delay(clock=16000000)
#use rs232(baud=4800,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
|
This is the main program file, Att1.c
Code: |
#include "Z:\Electronics\GPS\Att1.h" // file/code posted above
#include <LCD.C>
#ZERO_RAM
int times;
int rda;
#int_RTCC // every 1 second
void RTCC_isr(void) {
times++;
}
#int_RDA // receive data available
void RDA_isr(void) {
rda++;
}
void main() {
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
lcd_init();
enable_interrupts(INT_RTCC);
enable_interrupts(INT_RDA);
enable_interrupts(INT_LOWVOLT);
enable_interrupts(GLOBAL);
output_high(PIN_D3); // turns on the LCD backlight
lcd_putc('\f'); // clear screen
delay_ms(5);
printf(lcd_putc, " GPS Logger \n Attempt 1.00 ");
delay_ms(2000);
while(true) {
printf(lcd_putc, "\fRDA: %u\nTIME: %u", rda, times);
delay_ms(250);
}
}
|
_________________ George Smart
Student in Electronic & Electrical Engineering
University College London |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Dec 31, 2008 1:04 am |
|
|
Quote: |
#int_RDA // receive data available
void RDA_isr(void) {
rda++;
}
By commenting out the "#use rs232(...)" statement, the program does not hang. |
You need to read the character from the UART to clear the interrupt
condition. Use getc() to do this, inside the isr. |
|
|
m1geo
Joined: 31 Dec 2008 Posts: 5 Location: London, England, UK
|
GPS/NMEA String Handling |
Posted: Wed Dec 31, 2008 10:20 am |
|
|
PCM programmer, thanks for your reply. Guess that kinda answers the other questions too
One other quick question, as i wish to read NMEA data, which is terminated by "<CR><LF>". Is it possible to get the data using the gets(), as opposed to your suggestion of getc().
For example
Code: |
struct {
char data[128]; // uart data dumped in here, to work on
int element; // position in the array
int1 new; // flag for new raw data
} gpsraw;
|
Then using this
Code: |
#int_RDA // receive data available
void RDA_isr(void) {
gets(gpsraw.data);
}
|
Will this handle the reading in of a string, rather than char-by-char?
Any help, greatly appreciated! _________________ George Smart
Student in Electronic & Electrical Engineering
University College London |
|
|
FvM
Joined: 27 Aug 2008 Posts: 2337 Location: Germany
|
|
Posted: Wed Dec 31, 2008 10:42 am |
|
|
gets() can't be used in a receiver interrupt in a meaningful way. You can use it e. g. with a user defined stream, that get it's receive buffer filled in an ISR. Simple CCS examples are using gets() with a polled UART, in applications, that have nothing to do but waiting for UART input. |
|
|
m1geo
Joined: 31 Dec 2008 Posts: 5 Location: London, England, UK
|
|
Posted: Wed Dec 31, 2008 11:59 am |
|
|
FvM, many thanks for your reply.
I kind of realized this by looking at the source code, but thanks for the confirmation. I have basically just implemented a char array where I read data into it whenever the RDA ISR is run. This then also checks for the CR/LF ending, and sets a new-data flag.
Code: |
#int_RDA // receive data available
void RDA_isr(void) {
char c;
c = getc();
if (c != 13) { // if the char is not a CR
if (c != 10) { // if the char is not a LF
gpsraw.data[gpsraw.element] = c; // put in the array
gpsraw.element++; // next element in the array
}
} else { // if the char is a CR
gpsraw.new = TRUE; // thats the end of what we expect, new data available
gpsraw.element=0; // get back to the beginning.
}
}
|
Here, the gpsraw structure is as before, in my previous posts.
Many thanks both for your help. It was greatly appreciated
Happy New Year. _________________ George Smart
Student in Electronic & Electrical Engineering
University College London |
|
|
|
|
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
|