📄 gps.c
字号:
/*----------------------------------------------------------------
GPS采集控制单元
1.GPS模块初始化采集, 串口1 19200,需要先进行唤醒操作,然后定期接收(中断)位置信息
------------------------------------------------------------------*/
#include<iom162v.h>
#include <macros.h>
//带有可选回车换行符输出的MEGA162的双UART程序
//发送采用查询方式,接收采用中断方式。晶振7.3728M,无分频。
unsigned char gpsbuf[100];
unsigned char uartrbuffer[100]; //uart接受缓存100字节
unsigned char uarttbuffer[50]; //uart发送缓存50字节
int stringlon=0;
unsigned char urflag;
unsigned char tmpchar;
//UART0 initialisation
// desired baud rate:1200
// actual baud rate:1200 (0.0%)
// char size: 8 bit
// parity: Disabled
void uart0_init(void)
{
UCSR0B = 0x00; //disable while setting baud rate
UCSR0A = 0x00; //disable while setting baud rate
UBRR0L =0x03; //set baud rate
UBRR0H=0x00;
UCSR0C =(1<<URSEL0)|0b00000110;
UCSR0B=0b10011000; //enable
}
#pragma interrupt_handler uart0_rx_isr:20
void uart0_rx_isr(void)
{
//uart has received a character in UDR
uartrbuffer[stringlon]=UDR0;
stringlon++;
urflag=1;
if(stringlon>=100)
stringlon=0;
}
unsigned char recgpsstate; //GPS 接收状态字,初始化为0
unsigned char recgpsP; //接收缓冲区指针
unsigned char recgpslen;
//UART1 initialisation
// desired baud rate: 19200
// actual: baud rate:19200 (0.0%)
// char size: 8 bit
// parity: NONE
void uart1_init(void)
{
UCSR1B = 0x00; //disable while setting baud rate
UCSR1A = 0x00; //disable while setting baud rate
UBRR1L =0x17; //set baud rate
UBRR1H = 0x00;
UCSR1C = (1<<URSEL1)|0b00000110;;
UCSR1A = 0x00; //enable
UCSR1B = 0x98; //enable
urflag = 0;
recgpsstate = 0;
recgpsP = 0;
recgpslen = 0;
}
#pragma interrupt_handler uart1_rx_isr:21
void uart1_rx_isr(void)
{
//uart has received a character in UDR
tmpchar=UDR1;
switch(recgpsstate)
{
case 0: //检查$字符,为一句开始
if(tmpchar=='$'){
recgpsstate=1;
recgpsP=0;
uartrbuffer[recgpsP++]=tmpchar;
}
else recgpsstate=0;
break;
case 1: //检查GPRMC
uartrbuffer[recgpsP++]=tmpchar;
if(recgpsP>6){
if((uartrbuffer[3]=='R')&&(uartrbuffer[4]=='M')&&(uartrbuffer[5]=='C'))
recgpsstate=2;
else recgpsstate=0;
}
break;
case 2:
uartrbuffer[recgpsP++]=tmpchar;
if((tmpchar==0x0a)&&(uartrbuffer[recgpsP-2]==0x0d)){
recgpslen=recgpsP;
for(recgpsP=0;recgpsP<recgpslen;recgpsP++)
gpsbuf[recgpsP]=uartrbuffer[recgpsP];
urflag=1;
recgpsstate=0;
}else{
if(recgpsP>120) recgpsstate=0;
}
break;
default:
recgpsstate=0;
break;
}
}
//*******************************************uart字符输出***************************
void putchar(int upart,unsigned char charx)
//upart表示UART标号,0表示UART0,其他表示UART1;char0表示要发出的数据;
{
int i=0;
if(upart==0)
{
while(!(UCSR0A & 0x20));
UDR0 = charx;
}
else
{
while(!(UCSR1A & 0x20));
UDR1 = charx;
}
}
//******************************************uart字符输出函数结束***************
//*******************************带可选回车换行的字符串输出函数******
//upart表示发出数据使用的端口号0表示使用UART0,其他表示使用UART1;
//*s表示要发出数据的指针
//senter0表示结尾是否使用0x0d,0表示使用,其他表示不使用
//senter1表示结尾是否使用0x0a,0表示使用,其他表示不使用
//stringl表示所要输出的字符串长度,0表示无限制
void puts(unsigned char *s,int upart,int senter0,int senter1,int stringl)
{
unsigned char outchar;
stringlon=0;
if(upart==0)
{
if(stringl==0)
{
while(*s)
{
outchar=*s;
putchar(0,outchar);
s++;
}
if(senter0==0)
putchar(0,0x0d);
if(senter1==0)
putchar(0,0x0a);
}
else
{
while(stringlon<=(stringl-1))
{
outchar=*(s+stringlon);
putchar(0,outchar);
stringlon++;
}
if(senter0==0)
putchar(0,0x0d);
if(senter1==0)
putchar(0,0x0a);
}
}
else
{
if(stringl==0)
{
while(*s)
{
outchar=*s;
putchar(1,outchar);
s++;
}
if(senter0==0)
putchar(1,0x0d);
if(senter1==0)
putchar(1,0x0a);
}
else
{
while(stringlon<=(stringl-1))
{
outchar=*(s+stringlon);
putchar(1,outchar);
stringlon++;
}
if(senter0==0)
putchar(1,0x0d);
if(senter1==0)
putchar(1,0x0a);
}
}
}
/******************************************************
SPI 双机通信
*******************************************************/
#define SIZE 100
unsigned char SPI_rx_buff[SIZE];
unsigned char SPI_tx_buff[SIZE];
unsigned char rx_wr_index,rx_rd_index,rx_counter,rx_buffer_overflow;
unsigned char tx_wr_index,tx_rd_index,tx_counter,SPI_ok;
#pragma interrupt_handler spi_stc_isr:19
void spi_stc_isr(void)
{
SPI_rx_buff[rx_wr_index] = SPDR; //从ISP口读出收到的字节
SPI_ok = 1; // SPI 空闲
if (++rx_wr_index == SIZE) rx_wr_index = 0; //放入接收缓冲区,并调整队列指针
if (++rx_counter == SIZE)
{
rx_counter = 0;
rx_buffer_overflow = 1;
}
if (tx_counter) //如果发送缓冲区中有待发的数据
{
--tx_counter;
SPDR = SPI_tx_buff[tx_rd_index]; //发送一个字节数据,并调整指针
if (++tx_rd_index == SIZE) tx_rd_index = 0;
SPI_ok = 0;
}
}
unsigned char getSPIchar(void)
{
unsigned char data;
while (rx_counter == 0); //无接收数据,等待
data = SPI_rx_buff[rx_rd_index]; //从接收缓冲区取出一个SPI收到的数据
if (++rx_rd_index == SIZE) rx_rd_index = 0; //调整指针
CLI();
--rx_counter;
SEI();
return data;
}
void putSPIchar(char c)
{
while (tx_counter == SIZE);//发送缓冲区满,等待
CLI();
if (tx_counter || SPI_ok==0 ) //发送缓冲区已中有待发数据
{ //或SPI正在发送数据时
SPI_tx_buff[tx_wr_index] = c; //将数据放入发送缓冲区排队
if (++tx_wr_index == SIZE) tx_wr_index = 0; //调整指针
++tx_counter;
}
else
{
SPDR = c; //发送缓冲区中空且SPI口空闲,直接放入SPDR由SIP口发送
SPI_ok = 0; //
}
SEI();
}
void spi_init(void)
{
unsigned char temp;
DDRB |= (1<<PB6); //MOSI 设置为输出,MISO and SCK,SS = input
SPCR = 0xC5; //1101 0101 SPI允许,从机模式,MSB,允许SPI中断,极性方式01,1/16系统时钟速率
/***************************************************
SPCR
0
SPIE SPE DORDER MSTR CPOL CPHAP SPR1 SPR0
中断允许 1LSB,0 MSB 时钟方式选择
允许SPI 主从
***************************************************/
SPSR = 0x00; //2x 0x01
temp = SPSR;
temp = SPDR; //清空SPI,和中断标志,使SPI空闲
SPI_ok = 1; // SPI 空闲
}
/**************************************************
SPI END
***************************************************/
void delayms(int nsec)
{
int i=0;
int k=0;
for(k=0;k<nsec;k++)
for(i=0;i<2000;i++) asm("nop");
}
const unsigned char InitGPSBUF1[8]={0x07,0x40,0x40,0x4f,0x69,0x26,0x0d,0x0a};
const unsigned char InitGPSBUF2[32]={0x1f,0x40,0x40,0x4f,0x46,0x00,0x00,0x02,0x00,0x00,0x00,
0x01,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0a,0x0d,0x0a};
const unsigned char InitGPSBUF3[31]={0x1e,0x40,0x40,0x4f,0x6a,0x00,0x00,0x0a,0x03,0x70,0x07,
0x3c,0xff,0x11,0x92,0x07,0x0a,0x8b,0x07,0x00,0x00,
0x1e,0x00,0x1e,0x00,0x12,0x00,0x12,0x9a,0x0d,0x0a};
const unsigned char InitGPSBUF4[19]={0x12,0x40,0x40,0x4f,0x61,0x04,0x00,0x05,0x00,0x05,0x14,
0x7f,0x00,0x01,0x01,0x01,0x40,0x0d,0x0a};
const unsigned char InitGPSBUF5[14]={0x0d,0x40,0x40,0x4f,0x74,0xff,0xff,0x10,0x01,0x00,0x00,
0x2a,0x0d,0x0a};
//const unsigned char InitGPSBUF5[14]={0x0d,0x40,0x40,0x4f,0x74,0x01,0x00,0x00,0x01,0x00,0x01,
// 0x3a,0x0d,0x0a};
const unsigned char InitGPSBUF6[31]={0x14,0x24,0x50,0x4d,0x4f,0x54,0x47,0x2c,0x47,0x47,0x41,
0x2c,0x30,0x30,0x30,0x31,0x2a,0x30,0x31,0x0d,0x0a};
const unsigned char InitGPSBUF7[31]={0x14,0x24,0x50,0x4d,0x4f,0x54,0x47,0x2c,0x52,0x4d,0x43,
0x2c,0x30,0x30,0x30,0x31,0x2a,0x31,0x43,0x0d,0x0a};
const unsigned char InitGPSBUF8[31]={0x14,0x24,0x50,0x4d,0x4f,0x54,0x47,0x2c,0x56,0x54,0x47,
0x2c,0x30,0x30,0x30,0x31,0x2a,0x30,0x35,0x0d,0x0a};
const unsigned char InitGPSBUF9[31]={0x14,0x24,0x50,0x4d,0x4f,0x54,0x47,0x2c,0x47,0x53,0x41,
0x2c,0x30,0x30,0x30,0x31,0x2a,0x31,0x35,0x0d,0x0a};
const unsigned char InitGPSBUF10[31]={0x14,0x24,0x50,0x4d,0x4f,0x54,0x47,0x2c,0x47,0x53,0x56,
0x2c,0x30,0x30,0x30,0x31,0x2a,0x30,0x32,0x0d,0x0a};
void init_FCOnOre(void)
{
unsigned char buflen=0;
unsigned char j=0;
buflen=InitGPSBUF1[0]; for(j=0;j<buflen;j++) putchar(1,InitGPSBUF1[j+1]);
delayms(1500);
buflen=InitGPSBUF2[0]; for(j=0;j<buflen;j++) putchar(1,InitGPSBUF2[j+1]);
delayms(100);
buflen=InitGPSBUF3[0]; for(j=0;j<buflen;j++) putchar(1,InitGPSBUF3[j+1]);
delayms(100);
buflen=InitGPSBUF4[0]; for(j=0;j<buflen;j++) putchar(1,InitGPSBUF4[j+1]);
delayms(100);
buflen=InitGPSBUF5[0]; for(j=0;j<buflen;j++) putchar(1,InitGPSBUF5[j+1]);
delayms(100);
buflen=InitGPSBUF6[0]; for(j=0;j<buflen;j++) putchar(1,InitGPSBUF6[j+1]);
delayms(100);
buflen=InitGPSBUF7[0]; for(j=0;j<buflen;j++) putchar(1,InitGPSBUF7[j+1]);
delayms(100);
buflen=InitGPSBUF8[0]; for(j=0;j<buflen;j++) putchar(1,InitGPSBUF8[j+1]);
delayms(100);
buflen=InitGPSBUF9[0]; for(j=0;j<buflen;j++) putchar(1,InitGPSBUF9[j+1]);
delayms(100);
buflen=InitGPSBUF10[0]; for(j=0;j<buflen;j++) putchar(1,InitGPSBUF10[j+1]);
delayms(100);
}
void main()
{
int i;
char recinfo[64];
char singlech;
char recch;
char reccounter=0;
//stop errant interrupts until set up
delayms(200);
CLI(); //disable all interrupts uart0_init();
uart1_init();
uart0_init();
spi_init();
SEI(); //re-enable interrupts
init_FCOnOre();
while(1)
{
if(urflag==1){
for(i=0;i<recgpslen;i++) putchar(0,gpsbuf[i]);
putSPIchar(0x7e);
putSPIchar(0x7e);
putSPIchar(0x7e);
putSPIchar(0x7f);
for(i=0;i<recgpslen;i++) putSPIchar(gpsbuf[i]);
putSPIchar(0x7f);
putSPIchar(0x7e);
putSPIchar(0x7e);
putSPIchar(0x7e);
urflag=0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -