|
|
View previous topic :: View next topic |
Author |
Message |
vafonkin
Joined: 20 Mar 2012 Posts: 16
|
After upgrading to 5.019 RDA Interrupt no longer works |
Posted: Tue Dec 16, 2014 1:05 pm |
|
|
I recently upgraded to 5.019 and I am experiencing weird issue - with no code changes made and everything working and compiles with 4.x ccs-c compiler, RDA interrupt no longer works at all.
Any ideas why it works with old but not with 5.019??? Are there any changes to use rs232, it looks like all data over UART is garbled...
here is my fuses:
Code: |
#fuses INTRC_IO,NOWDT,NOPROTECT,PUT,NOCPD,NOLVP,NOMCLR,BROWNOUT
|
here is code:
Code: |
#use rs232(baud=19200, parity=N, bits=8, UART1)
|
In addition all characters sent out to UART are garbled now.
NO changes to the code - just updated to 5.019 |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Tue Dec 16, 2014 2:30 pm |
|
|
I'll bet your clock isn't getting set correctly and that's the reason why you're receiving garbled characters from the PIC and that the PIC's RDA interrupt seems to have stopped working.
What is the processor? |
|
|
vafonkin
Joined: 20 Mar 2012 Posts: 16
|
|
Posted: Tue Dec 16, 2014 2:45 pm |
|
|
newguy wrote: | I'll bet your clock isn't getting set correctly and that's the reason why you're receiving garbled characters from the PIC and that the PIC's RDA interrupt seems to have stopped working.
What is the processor? |
It was working fine and stopped after upgrade. I use PIC18F26k20
UPDATE:
while checking baud rate with oscilloscope, I see it sends out data with 9600, not with the baud rate I set in my settings:
Code: |
#use rs232(DISABLE_INTS, BAUD=19200, parity=N, bits=8, UART1)
|
So now I have to change my question ... it looks like interrupt is working however baud rate is not getting set to what I need. Why? |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Tue Dec 16, 2014 4:27 pm |
|
|
Your processor clock is getting set to half of what you want it to be.
As to why, there are two possibilities.
1. Your old version of the compiler correctly set your PIC's processor clock but now v5 is doing it wrong.
2. Your old version actually set it wrong and v5 now does it correctly but this exposed another compiler issue with v4 that masked the problem by screwing up the UART clock speed.
Either way, just give us a very short program that demonstrates the problem. Include all #use lines, etc. |
|
|
vafonkin
Joined: 20 Mar 2012 Posts: 16
|
|
Posted: Tue Dec 16, 2014 5:54 pm |
|
|
Thank you for response,
main.h :
Code: |
#define DEV_PIC18F26K20
#include <18F26K20.h>
#device adc=8
#fuses INTRC_IO,NOWDT,NOPROTECT,PUT,NOCPD,NOLVP,NOMCLR,BROWNOUT
#use delay(clock=7995392)
|
main.c :
Code: |
// *********************************************************************************************************//
// This is RX80M Project by Vadim Afonkin KB1RLI - contact me vadim.afonkin [ at ] gmail.com //
// Use Timer0 to clock 1sec - will drift 1-2 sec in 2-3 hours or Timer1 with external 32.768 oscillator //
// for precise RTC. Call do_1sec_event() from Timer0 OR Timer1. Set clock to #use delay(clock=7995392) //
// Requires 10k pullup resistor, since port A does not have internal pullups. //
// *********************************************************************************************************//
#include <main.h>
#include <stdlib.h>
#include <math.h>
#use rs232(BAUD=19200, parity=N, bits=8, UART1) //used for GPS
// Needed for Timer0
#define HIGH_START_SLOW 123 // to correcr 1 sec error
#define HIGH_START_FAST 122 // to correcr 1 sec error
// GPS DEFINES
#define GPS_HEADER 0
#define GPS_TIME 1
#define GPS_VALID 2
#define GPS_LAT 3
#define GPS_LAT_N_S 4
#define GPS_LON 5
#define GPS_LON_E_W 6
#define GPS_SPEED 7
#define GPS_TRUE_HEADING 8
#define GPS_DATE_OF_FIX 9
#define GPS_MAG_VAR 10
#define GPS_MAG_VAR_E_W 11
#define GPS_CHECKSUM 12
#define R 6371
#define TO_RAD (3.1415926 / 180)
#define TO_DEG (180 / 3.1415926)
byte high_i, HIGH_START_BYTE=0;
#Byte TMR1H = 0xFCF // TIMER1 HIGH BYTE LOOK DATASHEET
#Byte T1CON = 0xFCD // TIMER1 CONFIG REGISTER LOOK DATASHEET
#Byte RCREG = 0xFAE // UART RECEIVE REGISTER LOOK DATASHEET
static int8 tick=0; // TIMER COUNTER FOR SECONDS
static int gps_state,gps_have_packet;
static int16 gps_index;
static char gps_string[82],gps_string_copy[82];
static char GPGGA[7]="$GPGGA";
static char GPGSA[7]="$GPGSA";
static char GPGSV[7]="$GPGSV";
static char GPRMC[7]="$GPRMC";
static char GPVTG[7]="$GPVTG";
static char GPS_ARRAY[17];
static char *token=0;
static char delimeter[2] = ",";
static char S[2] = "S";
static char W[2] = "W";
static char ValidFix[2] = "A";
static char LatDegTmp[3];
static char LatMinTmp[9];
static float32 Lat,Lon;
static char LonDegTmp[4];
static char LonMinTmp[10];
static char sLat[];
static char sLon[];
static float MagVar=0;
float dist;
void do_1sec_event(void);
void parse_gps(void);
void get_lat_lon(void);
void distance(void);
#int_rtcc
void Timer0Interrupt(void){
if(--high_i==0){
if(HIGH_START_BYTE==0){
high_i=HIGH_START_FAST;
HIGH_START_BYTE=1;
}else{
high_i=HIGH_START_SLOW;
HIGH_START_BYTE=0;
}
do_1sec_event(); // update clock, etc
}
}
#int_TIMER1
void TIMER1_isr() // 2^16= 65536/2 = 32768 * 1/32.768Hz <--- (1sec)
{
bit_clear(T1CON,7); //Enable access to the individual bytes of the timer register
Bit_Set(TMR1H,7); //Add 32768 to timer1 by setting high bit or timer register
Bit_Set(T1CON,7); //Disable access to the individual bytes of the timer register
}
void do_1sec_event(void){
if(tick<=59){
tick++;
}
}
#INT_RDA
void isr_gps(void){
unsigned char c;
c = RCREG;
switch (gps_state){
case 0: if(gps_have_packet==0){
if(c == 0x24){
gps_index = 0;
gps_string[gps_index] = c;
gps_index = 1;
gps_state = 1;;
}
}
break;
case 1: gps_string[gps_index] = c;
if((c == 0x0A)||(c == 0x0D)){
gps_have_packet = 1;
gps_string[gps_index + 1] = 0;
gps_state = 0;
}
if(gps_index >= sizeof(gps_string)-1){
gps_string[gps_index + 1] = 0;
gps_have_packet = 1;
gps_state = 0;
}else{
gps_index++;
}
break;
default: gps_state = 0;
break;
}
}
void main() {
float32 testdeg;
gps_have_packet=0; // initialize uart
high_i=HIGH_START_SLOW;
setup_timer_0(RTCC_8_BIT|RTCC_DIV_128);
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1|T1_CLK_OUT); // external TIMER1 with 32.768Khz ,clock out for oscillator,asynchronus mode
enable_interrupts(INT_TIMER1); // enable Timer 1 interrupt
enable_interrupts(INT_RTCC); // enable Timer0 interrupt
enable_interrupts(INT_RDA); // enable INT_RDA to read GPS data
enable_interrupts(GLOBAL); // enable all interrupts
delay_ms(2500); // 2.5 sec needed to initialize LCD
putc(12); // clear screen
printf("Ready\n");
while(1){
// test our calculation saacuracy
//testdeg = TO_DEG*asin(acos(atan(tan(cos(sin(9*TO_RAD))))));
//printf("%f9.7\r\n", testdeg);
//delay_ms(2000);
if(gps_have_packet==1){
parse_gps();
if(strstr(gps_string_copy, GPRMC)){
distance();
printf("DIST: %f\r\n",dist);
}
}
}
}
void parse_gps(void){
int i=0;
//test
/*
for(i=0;i<sizeof(gps_string);i++){
printf("%s\r\n",gps_string[i]);
}
*/
strncpy(gps_string_copy,gps_string,82); //strcpy gone in v5.019????
gps_have_packet = 0; // release interrupt to get new data
if(strstr(gps_string_copy, GPRMC)){
i=0;
token = strtok(gps_string_copy, delimeter);
while(token!=NULL){
GPS_ARRAY[i]=token;
token = strtok(NULL, delimeter);
i++;
}
if(strstr(GPS_ARRAY[GPS_VALID],ValidFix)){
get_lat_lon();
if(MagVar==0){
MagVar = atof(GPS_ARRAY[GPS_MAG_VAR]);
if(strstr(GPS_ARRAY[GPS_MAG_VAR_E_W], W)){
MagVar=MagVar * -1;
}
}
printf("MAG VAR: %f\r\n",MagVar);
}else{
printf("NO VALID FIX\r\n");
}
}
}
void get_lat_lon(void){
int i=0;
// GET LATITUDE
sLat=GPS_ARRAY[GPS_LAT];
for (i=0;i<2;i++){
LatDegTmp[i]=sLat[i];
}
for (i=0;i<8;i++){
LatMinTmp[i]=sLat[2+i];
}
Lat=atof(LatDegTmp)+(atof(LatMinTmp)/60);
if(strstr(GPS_ARRAY[GPS_LAT_N_S], S)){
Lat=Lat * -1;
}
// GET LONGITUDE
sLon=GPS_ARRAY[GPS_LON];
for (i=0;i<3;i++){
LonDegTmp[i]=sLon[i];
}
for (i=0;i<9;i++){
LonMinTmp[i]=sLon[3+i];
}
Lon=atof(LonDegTmp)+(atof(LonMinTmp)/60);
if(strstr(GPS_ARRAY[GPS_LON_E_W], W)){
Lon=Lon * -1;
}
printf("LAT: %9.7f\r\n",Lat);
printf("LON: %9.7f\r\n",Lon);
}
void distance(void){
float32 mLat1,mLat2,mLon1,mLon2,dLat,dLon,a,c;
char cLat1[8] = "42.3079";
char cLon1[9] = "-71.2010";
char cLat2[8] = "42.3065";
char cLon2[9] = "-71.2020";
// FOR TEST ONLY
mLat1 = atof(cLat1);
mLat2 = atof(cLat2);
mLon1 = atof(cLon1);
mLon2 = atof(cLon2);
mLat1 = mLat1*TO_RAD;
mLat2 = mLat2*TO_RAD;
mLon1 = mLon1*TO_RAD;
mLon2 = mLon2*TO_RAD;
dLat = mLat2-mLat1;
dLon = mLon2-mLon1;
a = sin(dLat/2) * sin(dLat/2) + cos(mLat1) * cos(mLat2) * sin(dLon/2) * sin(dLon/2);
c = 2 * atan2(sqrt(a),sqrt(1-a));
dist = R * c;
}
|
As a side note - I noticed strcpy gone in v5.xxx ? |
|
|
Mike Walne
Joined: 19 Feb 2004 Posts: 1785 Location: Boston Spa UK
|
|
Posted: Tue Dec 16, 2014 6:29 pm |
|
|
newguy wrote: | Either way, just give us a very short program that demonstrates the problem. Include all #use lines, etc. |
What did he say?
Mike |
|
|
vafonkin
Joined: 20 Mar 2012 Posts: 16
|
|
Posted: Tue Dec 16, 2014 6:52 pm |
|
|
Big pardon.... here it is "stripped":
Code: |
// *********************************************************************************************************//
// This is RX80M Project by Vadim Afonkin KB1RLI - contact me vadim.afonkin [ at ] gmail.com //
// Use Timer0 to clock 1sec - will drift 1-2 sec in 2-3 hours or Timer1 with external 32.768 oscillator //
// for precise RTC. Call do_1sec_event() from Timer0 OR Timer1. Set clock to #use delay(clock=7995392) //
// Requires 10k pullup resistor, since port A does not have internal pullups. //
// *********************************************************************************************************//
#include <main.h>
#include <stdlib.h>
#include <math.h>
#use rs232(BAUD=19200, parity=N, bits=8, UART1) //used for GPS
// Needed for Timer0
#define HIGH_START_SLOW 123 // to correcr 1 sec error
#define HIGH_START_FAST 122 // to correcr 1 sec error
#define TO_RAD (3.1415926 / 180)
#define TO_DEG (180 / 3.1415926)
byte high_i, HIGH_START_BYTE=0;
#Byte TMR1H = 0xFCF // TIMER1 HIGH BYTE LOOK DATASHEET
#Byte T1CON = 0xFCD // TIMER1 CONFIG REGISTER LOOK DATASHEET
#Byte RCREG = 0xFAE // UART RECEIVE REGISTER LOOK DATASHEET
static int8 tick=0; // TIMER COUNTER FOR SECONDS
#int_rtcc
void Timer0Interrupt(void){
if(--high_i==0){
if(HIGH_START_BYTE==0){
high_i=HIGH_START_FAST;
HIGH_START_BYTE=1;
}else{
high_i=HIGH_START_SLOW;
HIGH_START_BYTE=0;
}
do_1sec_event(); // update clock, etc
}
}
#int_TIMER1
void TIMER1_isr() // 2^16= 65536/2 = 32768 * 1/32.768Hz <--- (1sec)
{
bit_clear(T1CON,7); //Enable access to the individual bytes of the timer register
Bit_Set(TMR1H,7); //Add 32768 to timer1 by setting high bit or timer register
Bit_Set(T1CON,7); //Disable access to the individual bytes of the timer register
}
void do_1sec_event(void){
if(tick<=59){
tick++;
}
}
#INT_RDA
void isr_gps(void){
unsigned char c;
c = RCREG;
switch (gps_state){
case 0: if(gps_have_packet==0){
if(c == 0x24){
gps_index = 0;
gps_string[gps_index] = c;
gps_index = 1;
gps_state = 1;;
}
}
break;
case 1: gps_string[gps_index] = c;
if((c == 0x0A)||(c == 0x0D)){
gps_have_packet = 1;
gps_string[gps_index + 1] = 0;
gps_state = 0;
}
if(gps_index >= sizeof(gps_string)-1){
gps_string[gps_index + 1] = 0;
gps_have_packet = 1;
gps_state = 0;
}else{
gps_index++;
}
break;
default: gps_state = 0;
break;
}
}
void main() {
float32 testdeg;
gps_have_packet=0; // initialize uart
high_i=HIGH_START_SLOW;
setup_timer_0(RTCC_8_BIT|RTCC_DIV_128);
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1|T1_CLK_OUT); // external TIMER1 with 32.768Khz ,clock out for oscillator,asynchronus mode
enable_interrupts(INT_TIMER1); // enable Timer 1 interrupt
enable_interrupts(INT_RTCC); // enable Timer0 interrupt
enable_interrupts(INT_RDA); // enable INT_RDA to read GPS data
enable_interrupts(GLOBAL); // enable all interrupts
setup_uart(UART_AUTODETECT);
while(1){
testdeg = TO_DEG*asin(acos(atan(tan(cos(sin(9*TO_RAD))))));
printf("%f9.7\r\n", testdeg);
delay_ms(2000);
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Dec 16, 2014 10:21 pm |
|
|
Quote: | setup_uart(UART_AUTODETECT); |
Why does your 2nd program have this line, but your first program doesn't ? |
|
|
vafonkin
Joined: 20 Mar 2012 Posts: 16
|
|
Posted: Tue Dec 16, 2014 10:44 pm |
|
|
Just to clarify, I understand RX is rate coming from other device, but I am setting baud on PIC to 19200 and I do not see it happening. Same code works compiled with 4.057 but not with 5.xxx Something messed up on uart
I spent all day digging problem and can't figure it out. Usually I am good with debugging, but not today
Auto detect does not help. I tried both - with and without auto detect.
I can't roll back to v 4.x because what was not working there compiles and works now with 5.xxx , except UART |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Dec 16, 2014 10:56 pm |
|
|
Quote: | static char GPS_ARRAY[17]; |
Based on the way you use GPS_ARRAY, I reckon it's supposed to be
an array of pointers. But pointers in 18F PICs take 2 bytes.
If you want an array of pointers to strings, you should declare it like this:
Code: | static char *GPS_ARRAY[17]; |
Then the compiler will allocate 2 bytes per pointer.
Here it seems that you're trying to make two uninitialized pointers:
Quote: |
static char sLat[];
static char sLon[];
|
But the compiler only allocates one byte of ram to each one.
From the .SYM file:
Whereas, if I declare a pointer to a char in the standard way,
Quote: | static char *my_ptr; |
the .SYM file shows 2 bytes are allocated to the pointer, as required:
|
|
|
vafonkin
Joined: 20 Mar 2012 Posts: 16
|
|
Posted: Tue Dec 16, 2014 11:14 pm |
|
|
You have a valid point but it does not explain why UART is not getting set properly. This was working with 4.057 .....
BTW what happened with strcpy in between 4.057 and 5.xxx ? I dont see it anymore and it will not compile. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Dec 17, 2014 12:21 am |
|
|
Quote: | what happened with strcpy in between 4.057 and 5.xxx ?
|
It works for me in vs. 5.019. I got this in the output window when I ran it
in MPLAB v8.92 simulator:
Quote: |
Hello 2
Hello Hello
|
Test program:
Code: | #include <18F26K20.h>
#fuses INTRC_IO, NOWDT
#use delay(clock=8M)
#use rs232(baud=9600, UART1, ERRORS)
//==================================
void main()
{
char s1[10] = "1";
char s2[10] = "2";
// Copy Hello into the first string.
strcpy(s1, "Hello");
printf("%s %s \r", s1, s2);
// Copy the 1st string into the 2nd string.
strcpy(s2, s1);
printf("%s %s \r", s1, s2);
while(TRUE);
} |
Last edited by PCM programmer on Wed Dec 17, 2014 12:56 am; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Dec 17, 2014 12:55 am |
|
|
Quote: | while checking baud rate with oscilloscope, I see it sends out data with 9600
|
I think you are interpreting your scope readings incorrectly. If I look
at pin C6 (Tx) on my scope while running the test program shown below,
I see a continuous squarewave and the scope's built-in frequency counter
says 9.64 KHz. But that's the frequency of a full cycle. It takes two bit
cells to make a full cycle. So the actual baud rate is 2x that, or 19.2
Kbaud. So it's working OK.
I submit that the reason you're seeing garbage with vs. 5.019 is probably
because of your incorrect pointers, which are missing the MSB byte.
I then theorize that the earlier compiler version may have allocated
variables in low ram (0 to FF), which masked the problem of the missing
MSB. Then in 5.019, the compiler allocates ram beyond the 0xFF
boundary and the missing MSB of the address causes incorrect data to
be read from ram (the addresses are wrong), which appears as garbage
on the screen.
Test program:
Code: |
#include <18F46K20.h>
#device adc=8
#fuses INTRC_IO,NOWDT,NOPROTECT,PUT,NOCPD,NOLVP,NOMCLR,BROWNOUT
#use delay(clock=8M)
#use rs232(BAUD=19200, parity=N, bits=8, UART1) //used for GPS
//==================================
void main()
{
while(TRUE)
{
putc(0x55);
}
} |
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Wed Dec 17, 2014 1:35 am |
|
|
There is one point that hasn't already been made, of the strange clock rate.
The internal oscillator can't generate 7995392Hz, so why try to set it to this?.
You will note PCM_programmer set the clock to 8Mhz, which is a legal setting for the internal oscillator.....
It may be as simple as a difference in the way the two compilers handle an impossible setting.
If you are using this clock setting to simplify the divisions done by the UART settings etc., then tell the compiler this is what you want:
Code: |
#use delay(clock=7995392,internal=8MHz)
|
Which says 'set the internal oscillator to 8MHz, but treat it as if it is running at 7995392Hz. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Wed Dec 17, 2014 7:00 am |
|
|
re: 'odd' clock setting..... from the comments in the program, it appears you want a 1 Hz interrupt.
One suggestion is to look at the SW RTC program in the code library here. It works fine and may be better than your current code.
While using the internal RC OSC saves a few pennies, it's not accurate for timers that need precision.Depending on the purpose of the project, you may want to upgrade to a real crystal and 2 caps,though you lose 2 I/O pins. Compromise, it's always a compromise...
Another option might be to add an external HW RTC like the DS1307. Gives you a 1Hz interrupt, battery backed,accurate...
something you might consider....
Jay |
|
|
|
|
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
|