📄 main.c
字号:
/*
IO 口模拟232通讯程序
使用两种方式的C程序 占用定时器0
**********************************************/
#include <reg51.h>
#include <string.h>
#define byte unsigned char
#define GPGLL 0
#define GPGSA 1
#define GPRMC 2
#define GPZDA 3
#define GPVTG 4
#define GPGGA 5
pdata byte pData[200];
sbit BT_SND =P3^1;
sbit BT_REC =P3^0;
byte RxFlag=0;
byte RecTimeOut=0;
byte RecStatus=0;
byte RxCount=0;
//byte g_GPS; //GPS数据状态.
extern void putch(byte ch);
#define F_TM F0
#define TIMER0_ENABLE TL0=TH0; TR0=1;
#define TIMER0_DISABLE TR0=0;
sbit ACC0= ACC^0;
sbit ACC1= ACC^1;
sbit ACC2= ACC^2;
sbit ACC3= ACC^3;
sbit ACC4= ACC^4;
sbit ACC5= ACC^5;
sbit ACC6= ACC^6;
sbit ACC7= ACC^7;
//用IO模拟串口收,发数据占用定时器0
void IntTimer0() interrupt 1
{
F_TM=1;
}
//模拟串口,发送一个字符
void PSendChar(unsigned char inch)
{
ACC=inch;
F_TM=0;
BT_SND=0; //start bit
TIMER0_ENABLE; //启动
while(!F_TM);
BT_SND=ACC0; //先送出低位
F_TM=0;
while(!F_TM);
BT_SND=ACC1;
F_TM=0;
while(!F_TM);
BT_SND=ACC2;
F_TM=0;
while(!F_TM);
BT_SND=ACC3;
F_TM=0;
while(!F_TM);
BT_SND=ACC4;
F_TM=0;
while(!F_TM);
BT_SND=ACC5;
F_TM=0;
while(!F_TM);
BT_SND=ACC6;
F_TM=0;
while(!F_TM);
BT_SND=ACC7;
F_TM=0;
while(!F_TM);
BT_SND=1;
F_TM=0;
while(!F_TM);
TIMER0_DISABLE; //停止timer
}
//模拟串口,接收一个字符
unsigned char PGetChar()
{
TIMER0_ENABLE;
F_TM=0;
while(!F_TM); //等过起始位
ACC0=BT_REC;
TL0=TH0;
F_TM=0;
while(!F_TM);
ACC1=BT_REC;
F_TM=0;
while(!F_TM);
ACC2=BT_REC;
F_TM=0;
while(!F_TM);
ACC3=BT_REC;
F_TM=0;
while(!F_TM);
ACC4=BT_REC;
F_TM=0;
while(!F_TM);
ACC5=BT_REC;
F_TM=0;
while(!F_TM);
ACC6=BT_REC;
F_TM=0;
while(!F_TM);
ACC7=BT_REC;
F_TM=0;
while(!F_TM)
{
if(BT_REC)
{
break;
}
}
TIMER0_DISABLE; //停止timer
return ACC;
}
//发送字符串
unsigned char send_str(unsigned char *str)
{
unsigned char i;
i=0;
while( str[i] != 0 ){
PSendChar(str[i]);
i++;
}
return(0);
}
// 发送AT指令. (返回接收到的数据长度.)
unsigned char SendAT(unsigned char *command,unsigned char *ACK)
{
unsigned char i=0;
unsigned long m;
if(strlen(command) > 0){
if( strlen(command) < 2) return(0); // AT 命令格式错
while(command[i] != 0){
if( command[i] == '\n' )
{
command[i] = 0; // Remove the existing line terminating character (if any)
break;
}
if( command[i] == '\r' ) {
command[i] = 0; // Remove the existing line terminating character (if any)
break;
}
i++;
}
}
send_str(command);
send_str("\x0D"); //
/*
三秒钟内无回复,认为超时退出.
*/
m = 500000;
i = 0;
while(m--)
{
if(BT_REC==0)
{
ACK[i] =PGetChar();
i+=1;
if(i>2 && (ACK[i-1]==0X0A && ACK[i-2]==0X0D))
break;
}
}
return(i); //回复收到的数据长度.
}
unsigned long delay;
void main()
{
byte i,Len;
SCON= 0X50; //定议串口
TMOD=0x22; /*定时器1为工作模式2(8位自动重装),0为模式2(8位自动重装) */
PCON=0X80; //波特率加倍
TR0=0;
TF0=0;
TH0 =256-80; //用IO模拟的串口速率为 19200.
TL0=TH0;
ET0=1; //允许定时器0中断
/*
TH1 = 0XFB; //单片机的串口速度为19200,测试用
TL1 = 0XFB;
*/
TH1 = 0XF6; //单片机的串口速度为9600,用于接收GPS数据.
TL1 = 0XF6;
TR1 = 1; //启动定时器1
ES = 1; //允许串口中断
EA=1; //开总中断
delay = 0;
REN = 1;
// g_GPS =0;
while(1)
{
delay++;
if(delay>=600000L)
{
Len=0;
Len =SendAT("ATE0",pData);
for(i=0;i<Len;i++)
PSendChar(pData[i]);
memset(pData,0,200);
delay=0;
RxFlag=0;
}
if(RxFlag)
{
for(i=0;i<RxCount;i++)
putch(pData[i]);
// g_GPS +=1;
// if(g_GPS==6) g_GPS=0;
RxFlag=0;
}
}
}
void putch(byte ch)
{
ES = 0;
TI=0;
SBUF =ch;
while(!TI);
TI = 0;
ES = 1;
}
//接收GPS模块数据.
void Com_Int(void) interrupt 4 using 1 // com interrupt routin
{
RecTimeOut=120; // byte timeout==20ms
if(RI==1) // recieved interrupt
{
RI=0;
if(!RxFlag)
{
if(RecStatus==0)
{
if(SBUF=='$')
{
RxCount=1;
pData[0]='$';
RecStatus=1;
}
}
else
{
if(RxCount>=120){RxCount=0; RecStatus=0;return;}
RxCount++;
pData[RxCount-1]=SBUF;
if(pData[RxCount-1]==0X0A && pData[RxCount-2]==0X0D)
{
/*
switch(g_GPS)
{
case GPGLL:
if(pData[3]=='G' && pData[4]=='L')
RxFlag=1;
break;
case GPGSA:
if(pData[3]=='G' && pData[4]=='S')
RxFlag=1;
break;
case GPRMC:
if(pData[3]=='R' && pData[4]=='M')
RxFlag=1;
break;
case GPZDA:
if(pData[3]=='Z' && pData[4]=='D')
RxFlag=1;
break;
case GPVTG:
if(pData[3]=='V' && pData[4]=='T')
RxFlag=1;
break;
case GPGGA:
if(pData[3]=='G' && pData[4]=='G')
RxFlag=1;
break;
default:
break;
}
*/
//接收到GPS一个完整的数据包
if(pData[3]=='R' && pData[4]=='M') //徐工说只读这个数据就行了.
RxFlag=1;
RecStatus=0;
}
}
}
}
}
/*
//推荐最小明确数据: 纬度,经度,速度
$GPRMC,000000.000,V,0000.0000,S,00000.0000,W,0.00,0.00,220899,,,A*7E
UTC 时间
纬度,
经度
速度
高度
日,月,年
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -