Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

XC16 PIC24FJ64GA002 UART Received Wrong Value

Status
Not open for further replies.

maheshece28

Junior Member level 2
Joined
Jun 13, 2013
Messages
24
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Activity points
249
Hi guys,
Im working on PIC24FJ64GA002 microcontroller in proteus for simulation and compiling the code using MPLAB XC16 compiler. Im calculating a distance between two latitude and longitude value. I've checked with below code in eclipse. Its shows correct distance value.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <math.h>
    #define pi 3.14159265358979323846
    double deg2rad(double);
    double rad2deg(double);
    unsigned char gpsdata1[]="$GPGGA,091310.000,2255.1682,N,11356.3605,E,1,4,1.62,164";
    unsigned char gpsdata2[]="$GPGGA,101310.000,3355.1682,N,14356.3605,E,1,4,1.62,164";
    int i;
    int main(void){
            double deg2rad(double deg) {
              return (deg * pi / 180);
            }
     
            double rad2deg(double rad) {
                      return (rad * 180 / pi);
            }
     
    double distance(double lat1, double lon1, double lat2, double lon2) {
      double theta, dist;
      theta = lon1 - lon2;
      dist = sin(deg2rad(lat1)) * sin(deg2rad(lat2)) + cos(deg2rad(lat1)) * cos(deg2rad(lat2)) * cos(deg2rad(theta));
      dist = acos(dist);
      dist = rad2deg(dist);
      dist = dist * 60 * 1.1515;
      printf("%f",dist);
     
    }
     
    double dist;
    dist = distance(38.898556,-77.037852,38.897147,-77.043934);
    }



But it shows wrong value in the microcontroller. Im printing the value via uart terminal. According to the above code expecting value is 0.341 but im getting 1.366762. Below is the controller code.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
#include "p24FJ64GA002.h"
    #include "math.h"
    #include <stdio.h>
    #define pi 3.14159265358979323846
     
    #define DELAY 2000
     
    _CONFIG1(JTAGEN_OFF & GCP_OFF & GWRP_OFF & BKBUG_OFF & COE_OFF
      & ICS_PGx1 & FWDTEN_OFF & WINDIS_OFF & FWPSA_PR32 & WDTPS_PS1)
     
    _CONFIG2(IESO_OFF  & SOSCSEL_SOSC & WUTSEL_FST 
      & FNOSC_FRC & FCKSM_CSDCMD & OSCIOFNC_OFF & IOL1WAY_OFF
      & I2C1SEL_PRI  & POSCMOD_NONE )
     
      //Initialise UART
            void InitUART(void);
            void SendUART(char);
            void SendUARTStr(char *buffer1);
            void RecUART(char *);
            double deg2rad(double);
    double rad2deg(double);
    //unsigned char gpsdata1[]="$GPGGA,091310.000,2255.1682,N,11356.3605,E,1,4,1.62,164";
    //unsigned char gpsdata2[]="$GPGGA,101310.000,3355.1682,N,14356.3605,E,1,4,1.62,164";
    int i;
     
            int main(void)
                    {       
                   
                            T1CON = 0x8030;
                            TMR1 = 0;
                            TRISA=0000;
                            //  (3)Define PortB
                            TRISB = 0xFF00;
                            //  LATB  = 0x0000;
                            PORTB = 0x0000;
     
                            //  (4)Assign UART1 Pin (Rx:RP10,Tx:RP13)
                            //  Rx:RP10(Pin)
                            RPINR18bits.U1RXR = 10;
                            //  Tx:RP13(Pin)
                            RPOR6bits.RP13R   = 3;    //See Manual P.99
                           
                            InitUART();
                           
           
                            double deg2rad(double deg) {
              return (deg * pi / 180);
            }
     
            double rad2deg(double rad) {
                      return (rad * 180 / pi);
            }
     
    double distance(double lat1, double lon1, double lat2, double lon2) {
      double theta, dist;
      theta = lon1 - lon2;
      dist = sin(deg2rad(lat1)) * sin(deg2rad(lat2)) + cos(deg2rad(lat1)) * cos(deg2rad(lat2)) * cos(deg2rad(theta));
      dist = acos(dist);
      dist = rad2deg(dist);
      dist = dist * 60 * 1.1515;
     
     
      //SendUARTStr((char)dist);
      printf("%f",dist);
      printf("\n");
      //printf("hello world");
      while (TMR1 < DELAY)
                                    {
                                    }
     
      return 0;
     
    }
     
    double dist;
    dist = distance(38.898556,-77.037852,38.897147,-77.043934);
    //lat1=2255.1682; lat2=38.897147; lon1=11356.3605; lon2=77.043934;
                           
     
                            return 0;
                    }
                   
                    void InitUART(void)
    {
    // **************************
    // (1)Define U1MODE
    // **************************
        U1MODEbits.UARTEN = 0;        // Bit15 TX, RX DISABLED, ENABLE at end of func
        U1MODEbits.USIDL = 0;         // Bit13 Continue in Idle
        U1MODEbits.IREN = 0;          // Bit12 No IR translation
        U1MODEbits.RTSMD = 0;         // Bit11 Simplex Mode
        U1MODEbits.UEN0 = 0;          // Bits8,9 TX,RX enabled, CTS,RTS not
        U1MODEbits.UEN1 = 0;
        U1MODEbits.WAKE = 0;          // Bit7 No Wake up (since we don't sleep here)
        U1MODEbits.LPBACK = 0;        // Bit6 No Loop Back
        U1MODEbits.ABAUD = 0;         // Bit5 No Autobaud (would require sending '55')
        U1MODEbits.RXINV = 0;         // Bit4 IdleState = 1
        U1MODEbits.BRGH = 0;          // Bit3 16 clocks per bit period
        U1MODEbits.PDSEL1 = 0;        // Bits1,2 8bit, No Parity
        U1MODEbits.PDSEL0 = 0;
        U1MODEbits.STSEL = 0;         // Bit0 One Stop Bit
     
     
    // **************************
    // (2)Define U1BRG
    //     BAUDRATE(Register)=SYSCLK/32/BAUDRATE-1
    // **************************
        U1BRG = 25;         // BAUDRATE = 8MHz/32/9600-1 = 0d25 ¦9600BPS(8MHz)
     
    // **************************
    // (3)Define U1STA
    // **************************
        U1STAbits.UTXISEL1 = 0;       //Bit15 Int when Char is transferred (1/2 config!)
        U1STAbits.UTXINV = 0;         //Bit14 N/A, IRDA config
        U1STAbits.UTXISEL0 = 0;       //Bit13 Other half of Bit15
        U1STAbits.UTXBRK = 0;         //Bit11 Disabled
        U1STAbits.UTXEN = 0;          //Bit10 TX pins controlled by periph
        U1STAbits.UTXBF = 0;          //Bit9 *Read Only Bit*
        U1STAbits.TRMT = 0;           //Bit8 *Read Only bit*
        U1STAbits.URXISEL0 = 0;       //Bits6,7 Int. on character recieved
        U1STAbits.URXISEL1 = 0;
        U1STAbits.ADDEN = 0;          //Bit5 Address Detect Disabled
        U1STAbits.RIDLE = 0;          //Bit4 *Read Only Bit*
        U1STAbits.PERR = 0;           //Bit3 *Read Only Bit*
        U1STAbits.FERR = 0;           //Bit2 *Read Only Bit*
        U1STAbits.OERR = 0;           //Bit1 *Read Only Bit*
        U1STAbits.URXDA = 0;          //Bit0 *Read Only Bit*
     
        U1MODEbits.UARTEN = 1;        // And turn the peripheral on
     
        U1STAbits.UTXEN = 1;
     
    }
     
     
    //Receive GPS Data
     
     
           
    //Send Data     
    //void SendUARTStr(char in_s[])
    void SendUARTStr(char in_s[])
    {
        unsigned int lp = 0;
     
        while(in_s[lp] != 0){
            SendUART(in_s[lp]);
            lp++;
        }
    }
     
    //Send data1
     
    void SendUART(char in_c)
    {
        while(U1STAbits.UTXBF != 0);
        U1TXREG = in_c;
    }



The problem occur because of "math.h" header file?. Is eclipse's header file is same as xc16's header file? I've compared the both header files, code is looks different. Pls suggest some solutions. Sorry for the poor english.

Thanks.
 
Last edited by a moderator:

For the XC16 compiler, you typically do NOT have an include file that is specific to the processor, but rather you include the <xc.h> file which uses directives from the IDE to define the processor in a far more flexible manner.
RP13 is on a pin that has analog functionality. While you are using it for transmission, it is a good idea to make the pin 'digital' if you are using it that way.
I must admit I have never seen nested function declarations in XC16 (I didn't think it would compiler even - obviously it does!). However the XC16 User Guide also contains an 'diagnostic' message that states that "ISO C forbids nested functions". Even if you are not getting this error, I would suggest that you move the nested function out of the 'main' function.
Also, for embedded applications the 'main' function should not return. I know that is probably not an issue for this specific situation, but I assume that you are using a debugger as otherwise the XC16 runtime would be continuously resetting the processor and then calling your 'main' function again.
Similarly, I 'm not sure what the timer and the final "while" loop in your main code is for. This is not the normal way of using the timer and may indicate some rather 'unusual' coding practices that will cause you issues later on.
As for your specific problem, I can only suggest that you split up the initial calculation for 'dist' and check each part to make sure that it is returning what you expect.
Given the two longitude values you are using, the value of 'theta' will be quite small which means the 'cos' of the angle will effectively be 1. Given that the two latitude values are also almost the same, the first calculation for 'dist' is very close to 'sine squared + cosine squared' which will (by definition) generate a number very close to 1. Taking the acos of that might be leading to a number with a fairly large error.
Susan
 

Thanks for the reply. Actually the problem is in "acos()" function. When i statically pass the value "0.000086" instead pass the "dist" variable to the "acos()", im getting correct final value.

Code:
dist = acos(0.000086);

Is i've replace other function instead of using "acos"?

- - - Updated - - -

Sorry,
not acos(0.000086), its acos(1). The problem is acos(1) gives "0.000345" value, but im expecting "0.000086".
 

Check the compiler switches being used to select the library as there are several floating point maths libraries and they vary in their speed and accuracy. You might need something like the -fast-math option.
Susan
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top