Sei sulla pagina 1di 5

#include <xc.

h>
#include <string.h>
// FICD
#pragma config ICS = PGD3
// ICD Communication Channel Select bits (Communicate on PGEC1 and PGED1)
#pragma config JTAGEN = OFF
// JTAG Enable bit (JTAG is disabled)
// FPOR
#pragma config ALTI2C1 = OFF
// Alternate I2C1 pins (I2C1 mapped to SDA1/SCL1 pins)
#pragma config ALTI2C2 = OFF
// Alternate I2C2 pins (I2C2 mapped to SDA2/SCL2 pins)
#pragma config WDTWIN = WIN25
// Watchdog Window Select bits (WDT Window is 25% of WDT period)
// FWDT
#pragma config WDTPOST = PS32768
// Watchdog Timer Postscaler bits (1:32,768)
#pragma config WDTPRE = PR128
// Watchdog Timer Prescaler bit (1:128)
#pragma config PLLKEN = ON
// PLL Lock Enable bit (Clock switch to PLL source will wait until the PLL lock
signal is valid.)
#pragma config WINDIS = OFF
// Watchdog Timer Window Enable bit (Watchdog Timer in Non-Window mode)
#pragma config FWDTEN = OFF
// Watchdog Timer Enable bit (Watchdog timer enabled/disabled by user software)
// FOSC
#pragma config POSCMD = HS
// Primary Oscillator Mode Select bits (HS Crystal Oscillator Mode)
#pragma config OSCIOFNC = OFF
// OSC2 Pin Function bit (OSC2 is clock output)
#pragma config IOL1WAY = OFF
// Peripheral pin select configuration (Allow multiple reconfigurations)
#pragma config FCKSM = CSECME
// Clock Switching Mode bits (Both Clock switching and Fail-safe Clock Monitor a
re enabled)
// FOSCSEL
#pragma config FNOSC = PRIPLL
// Oscillator Source Selection (Primary Oscillator with PLL module (XT + PLL, HS
+ PLL, EC + PLL))
#pragma config PWMLOCK = ON
// PWM Lock Enable bit (Certain PWM registers may only be written after key sequ
ence)
#pragma config IESO = ON
// Two-speed Oscillator Start-up Enable bit (Start up device with FRC, then swit
ch to user-selected oscillator source)
// FGS
#pragma config GWRP = OFF
// General Segment Write-Protect bit (General Segment may be written)
#pragma config GCP = OFF
// General Segment Code-Protect bit (General Segment Code protect is Disabled)
/**** TMR1 Variables ****/
volatile unsigned long int cnt = 0;

/**** PLL Variables *****/


unsigned int clk = 0;
/**** Status Variables **/
volatile int led1 = 0;
volatile char led_overrun = 0;
/**** UART1 Variables ***/
volatile char gpspos = 0;
volatile char gpssection = 0;
volatile char newgps = 0;
volatile char gpsdata[80];
char gps_str_request[3] = "RMC";
// GPRMC, GPGGA, GPGSV, GPGSA are the options
/************************/
int initPLL(int pllpre, int pllpost, int plldiv, int Fin) {
// function sets PLL to desired frequency, returns freq in MHz out
CLKDIVbits.PLLPRE = pllpre;
CLKDIVbits.PLLPOST = pllpost;
PLLFBDbits.PLLDIV = plldiv;
while(OSCCONbits.LOCK != 1);
// wait for PLL lock
return Fin * ((plldiv + 2) / ((pllpre + 2) * 2 * (pllpost + 1)));
}
void initTMR1(int tckps, int pr1) {
T1CONbits.TGATE = 0;
T1CONbits.TCS = 0;
TMR1 = 0x0000;
T1CONbits.TCKPS = tckps;
PR1 = pr1;
T1CONbits.TGATE = 0;
T1CONbits.TON = 1;
IPC0bits.T1IP = 0x02;
IFS0bits.T1IF = 0;
IEC0bits.T1IE = 1;
}
void initUART1() {
U1MODEbits.UARTEN = 0; // Bit15 TX, RX DISABLED, ENABLE at end of func
//U1MODEbits.notimplemented;// Bit14
U1MODEbits.USIDL = 0; // Bit13 Continue in Idle
U1MODEbits.IREN = 0;
// Bit12 No IR translation
U1MODEbits.RTSMD = 0; // Bit11 Simplex Mode
//U1MODEbits.notimplemented;// Bit10
U1MODEbits.UEN = 0;
// Bits8,9 TX,RX enabled, CTS,RTS not
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.BRGH = 0;
// Bit3 16 clocks per bit period
U1MODEbits.PDSEL = 0; // Bits1,2 8bit, No Parity
U1MODEbits.STSEL = 0; // Bit0 One Stop Bit
// Load a value into Baud Rate Generator. Example is for 9600.
// See section 19.3.1 of datasheet.
// U1BRG = (Fcy/(16*BaudRate))-1
// U1BRG = (140M/(16*9600))-1
// U1BRG = 910/2
U1BRG = 910;
// 100Mhz osc, 4800 Baud = 651

// Load all values


U1STAbits.UTXISEL1
U1STAbits.UTXINV =
U1STAbits.UTXISEL0

in for U1STA
= 0; //Bit15
0; //Bit14
= 0; //Bit13

SFR
Int when Char is transferred (1/2 config!)
N/A, IRDA config
Other half of Bit15

//U1STAbits.notimplemented = 0;//Bit12
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.URXISEL = 0; //Bits6,7 Int. on character recieved
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*
IPC7 = 0x4400;
// Mid Range Interrupt Priority level, no urgent rea
son
//IFS0bits.U1TXIF
//IEC0bits.U1TXIE
IFS0bits.U1RXIF =
IEC0bits.U1RXIE =
//IPC3bits.U1TXIP
IPC2bits.U1RXIP =
RPOR1bits.RP37R =
RPINR18bits.U1RXR
U1MODEbits.UARTEN
U1STAbits.UTXEN =

= 0;
// Clear the Transmit Interrupt Flag
= 1;
// Enable Transmit Interrupts
0;
// Clear the Recieve Interrupt Flag
1;
// Enable Recieve Interrupts
= 0x03;
0x01;
1;
//RP37/RB5 as U1TX
= 38; //RP38/RB6 as U1RX
= 1; // And turn the peripheral on
1;

}
void printUART1(char *data) {
while(*data) {
U1TXREG = *data++;
while(U1STAbits.UTXBF); // wait for TX buffer to clear
}
}
void __attribute__((interrupt, auto_psv)) _T1Interrupt(void) {
cnt++;
if(led1++ >= 10000) {
LATAbits.LATA1 ^= 1;
led1 = 0;
}
if(led_overrun) {
LATBbits.LATB0 ^= 1;
led_overrun = 0;
}
IFS0bits.T1IF = 0;
}
// #2 priority
void __attribute__((interrupt, no_auto_psv)) _U1RXInterrupt(void) {
// do something here when UART1 receives (the GPS)
if(newgps == 0) {
gpsdata[gpspos] = U1RXREG;
if(gpspos == 5 && (gpsdata[3] != gps_str_request[0] ||
gpsdata[4] != gps_str_request[1] ||
gpsdata[5] != gps_str_request[2])) {
// We don't have a GPRMC string, discard!
gpsdata[0] = 0;
gpspos = 0;
newgps = 0;

}
if(gpspos == 0 && gpsdata[gpspos] != '$') {
//We haven't received the start
//character, so ignore the data.
gpsdata[0] = 0;
gpspos = 0;
newgps = 0;
}
else if(gpspos >= 79) {
for(gpspos = 0; gpspos < 80; gpspos++) gpsdata[gpspos] = 0;
gpspos = 0;
newgps = 0;
}
else if(gpspos != 0 && (gpsdata[gpspos] == '\n' || gpsdata[gpspos] == '$
')) {
//We've reached the end of a
//new string, so stop receiving
//or else the new string will
//overwrite the old one.
int tmp;
if(gpsdata[gpspos] == '\n') for(tmp = gpspos + 1; tmp < 80; tmp++) g
psdata[tmp] = 0;
else for(tmp = gpspos; tmp < 80; tmp++) gpsdata[tmp] = 0;
gpspos = 0;
newgps = 1;
}
else {
gpspos++;
newgps = 0;
}
}
IFS0bits.U1RXIF = 0;
}
// #1 priority
//
//
//
//
//

two insependent sections, newgps and gpssection


newgps is the flag, gpssection is the section to write data into
newgps and gpssection are user set, not by the interrupt, just
incase there's something to read on the gpsdata, we don't want to
overwrite it. The overruns will handle all the extra data.

int main(void) {
ANSELA = 0x0000;
ANSELB = 0x0000;
// configure all pins as digital
TRISAbits.TRISA1 = 0;
TRISBbits.TRISB0 = 0;
clk = initPLL(0, 0, 68, 8);
// so the chip knows how fast the PLL is actually running at
initTMR1(0b01, clk / 2);
// cycling at 17.5 MHz / 70 = 250000 Hz
initUART1();
// initialize UART1
printUART1("Start of Program!\n");
strcpy(gps_str_request, "GGA");
while(1) {
if(U1STAbits.OERR) {
// if there's an overrun error
led_overrun = 1;
U1STAbits.OERR = 0;
while(1) LATBbits.LATB0 = 1;

}
if(newgps == 1) {
newgps = 0;
printUART1(gpsdata); // it's a GPRMC string
}
}
}

Potrebbero piacerti anche