找回密码
 注册会员
img_loading
智能检测中
更新自动建库工具PCB Footprint Expert 2024.04 Pro / Library Expert 破解版

真的要跪求各位了,这个问题困扰了一个月了,真心求帮助

[复制链接]
admin 发表于 2012-8-24 10:52:20 | 显示全部楼层 |阅读模式

本文包含原理图、PCB、源代码、封装库、中英文PDF等资源

您需要 登录 才可以下载或查看,没有账号?注册会员

×
我的单片机是STC89C52RC,液晶是ASC2码的12864,GPS模块使用串口工具能接收到完整的定位数据,但单片机总是接收不到GPS的数据,我调试了快一个月了都未能成功,实在很沮丧,因为一定要在开学前搞定这个,不然我就惨了!求各路大神慷慨帮助我啊,我是初学者,真心不会啊!
下面是我的代码:
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
#define clear 0x01
#define firstrow 0x80
#define secondrow 0x90
#define thirdrow 0x88
#define fourthrow 0x98

static int begin=0;
sbit duan=P2^6;
sbit wei=P2^7;
sbit lcd_en=P1^6;
sbit lcd_rs=P2^1;
sbit lcd_rw=P1^5;
sbit lcd_psb=P2^0;
sbit lcd_res=P1^7;
uchar a,b,c,i,j;
uint flag=0;
//uchar d=0;
uchar table0[62];
uint temp0,temp1,temp2;
uchar shi_1,shi_2;
uchar code sj[]="0123456789";
uchar GD[8];
void delay(uint z);
void write_com(uchar com);
void write_date(uchar date);
void init();
void Char_Transform(uchar temp);
void Hour_Transform(uchar temp);
void Minute_Transform(uchar temp);
void Time_Transform(uchar temp1,uchar temp2);
void Height_Transform(void);
void main()
{
init();
ES=1;
/*
for(i=0;i<62;i++)
{ //uchar ch;
//ch = SBUF
table0[i] ='A';
}
*/
write_com(secondrow); //指定第二行显示
for(a=0;a<17;a++) //局部定义数组并写入液晶
{
uchar table[]="HELLO! ";
write_date(table[a]);
}
delay(10000);
write_com(clear); //清屏,
write_com(secondrow); //局部定义数组并写入液晶
for(a=0;a<16;a++)
{
uchar table1[]="GPS 信号接收中";
write_date(table1[a]);
}
write_com(thirdrow+3);
for(a=0;a<10;a++)
{
uchar table2[]={"请稍后...."};
write_date(table2[a]);
}
delay(20000);


//flag=1;
//P1=0x71;
while(1)
{

if(flag==1)
{
// if(table0[4]=='G')//确定是否收到GPGGA这一帧数据
// {


uchar table3[]="维度:";
uchar table4[]="经度:";
uchar table5[]="时间:";
uchar table6[]="高度:";

write_com(clear);//显示之前清屏
write_com(firstrow);//在第一行显示维度汉字
for(a=0;a<7;a++)
write_date(table3[a]);
write_com(thirdrow);//在第三行显示经度汉字
for(a=0;a<7;a++)
write_date(table4[a]);
write_com(secondrow+2);//在第二行空两格后再显示维度数字
for(a=0;a<11;a++)
{
Char_Transform(table0[a+18]);
write_date(temp0);
}
write_com(fourthrow+2);//在第四行空两格后再显示经度数字
for(a=0;a<12;a++)
{
Char_Transform(table0[a+30]);
write_date(temp0);
}
//ES=1;//开串口中断
//flag=0;
// }
delay(20000);

Height_Transform();
write_com(clear);//显示之前清屏,给液晶写高度内容
write_com(firstrow);
for(a=0;a<6;a++)
write_date(table5[a]);
write_com(thirdrow);
for(a=0;a<6;a++)
write_date(table6[a]);
write_com(fourthrow+2);
for(a=0;a<9;a++)
{
if(GD[a]==',')
{
a=9;
write_date('M');//无数据提前退出写入,同时结尾补写单位M
}
else
write_date(GD[a]);
}
Hour_Transform(table0[7]);
Minute_Transform(table0[8]);
Time_Transform(temp1,temp2);
write_com(secondrow);
write_date(sj[shi_1]);
write_com(secondrow+1);
write_date(sj[shi_2]);
write_com(secondrow+2);
write_date(':');
write_com(secondrow+3);
write_date(table0[9]);
write_com(secondrow+4);
write_date(table0[10]);
write_com(secondrow+5);
write_date(':');
write_com(secondrow+6);
write_date(table0[11]);
write_com(secondrow+7);
write_date(table0[12]);
delay(20000);
//ES=1;//开串口中断
//flag=0;
// }
// else
// {
ES=1;//开串口中断
flag=0;
// }
}
//}
}
}
void write_com(uchar com) //写命令函数
{
lcd_rs=0;
lcd_rw=0;
lcd_en=0;
P0=com;
delay(5);
lcd_en=1;
delay(5);
lcd_en=0;
}
void write_date(uchar date) //写数据函数
{
lcd_rs=1;
lcd_rw=0;
lcd_en=0;
P0=date;
delay(5);
lcd_en=1;
delay(5);
lcd_en=0;
}
void init()
{
lcd_psb=1;//并口方式
duan=0; //锁存器使能
wei=0;
lcd_res=0; //液晶复位
delay(1);
lcd_res=1; //禁止复位
i=0;
write_com(0x30);//八位数据接口
delay(5);
write_com(0x0c);//开显示
delay(5);
write_com(clear);//显示清零
delay(5);

//定时器设置
TMOD |=0x20;//定时器1,方式2,八位自动填装方式
TH1=0xFD;
//TL1=0XFD;
TR1=1;//定时器1 开始工作
//SCON=0x50;//串口设置,工作方式一,八位UART?
SM0=0;
SM1=1;
REN=1;//允许串口接收,为零时禁止接收
//RI=0;
EA=1;//开总中断
//ES= 1; //打开串口中断


//delay(2000);
}
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);//约九的负六次方秒,9uS延时
}
void UART_Receive(void) interrupt 4 //4表示串口中断方式
{
uchar ch;
if(RI)
{
RI=0;
ch=SBUF;
P1=ch;
begin=1;
if((ch==68)||(begin==1))
{
begin=1;
table0[i++]=ch;
//count++;
if(i==62)
{
flag=1;
begin=0;
i=0;
}
}
}
}
void Hour_Transform(uchar temp)
{
switch(temp)//分离字符串
{ //时的转换
case '0': temp1=0;break;
case '1': temp1=1;break;
case '2': temp1=2;break;
}
}
void Minute_Transform(uchar temp)
{
switch(temp)
{ //分秒的转换
case '0': temp2=0;break;
case '1': temp2=1;break;
case '2': temp2=2;break;
case '3': temp2=3;break;
case '4': temp2=4;break;
case '5': temp2=5;break;
case '6': temp2=6;break;
case '7': temp2=7;break;
case '8': temp2=8;break;
case '9': temp2=9;break;
}
}
void Time_Transform(uchar temp1,uchar temp2)
{
c=temp1*10+temp2;//合成时间
if(c>=16,c<=23)//时差转换成北京时间
{
shi_1=0;
shi_2=c-16;
}
if(c>=2,c<=15)
{
c+=8;
shi_1=c/10;
shi_2=c%10;
}
if(c>=0,c<=1)
{
shi_1=0;
shi_2=c+8;
}
}
void Height_Transform(void)
{
a=0;
for(b=0;b<62;b++)//这里完成高度数据分离
{
if(table0[b]==',')
{
a++;
if(a==9)
{
for(c=0;c<8;c++)
{
GD[c]=table0[b+c+1];//将分离的高度数据写入高度数组
}
}
}
}
}
void Char_Transform(uchar temp)
{
switch(temp)
{
case '0': temp0=48;break;
case '1': temp0=49;break;
case '2': temp0=50;break;
case '3': temp0=51;break;
case '4': temp0=52;break;
case '5': temp0=53;break;
case '6': temp0=54;break;
case '7': temp0=55;break;
case '8': temp0=56;break;
case '9': temp0=57;break;
case 'A': temp0=65;break;
case 'B': temp0=66;break;
case 'C': temp0=67;break;
case 'D': temp0=68;break;
case 'E': temp0=69;break;
case 'F': temp0=70;break;
case 'G': temp0=71;break;
case 'H': temp0=72;break;
case 'I': temp0=73;break;
case 'J': temp0=74;break;
case 'K': temp0=75;break;
case 'L': temp0=76;break;
case 'M': temp0=77;break;
case 'N': temp0=78;break;
case 'O': temp0=79;break;
case 'P': temp0=80;break;
case 'Q': temp0=81;break;
case 'R': temp0=82;break;
case 'S': temp0=83;break;
case 'T': temp0=84;break;
case 'U': temp0=85;break;
case 'V': temp0=86;break;
case 'W': temp0=87;break;
case 'X': temp0=88;break;
case 'Y': temp0=89;break;
case 'Z': temp0=90;break;
case ',': temp0=44;break;
case '$': temp0=36;break;
default : temp0=63;break;
}
}


串口中断出问题,SBUF总是空的,不能进入主程序的循环。若大侠能帮助我,我感激得不知所措!谢谢了!
№.々/约 发表于 2012-8-24 16:00:37 | 显示全部楼层
用KEIL写吗?如果用KEIL模拟的话,读SBUF是不会有数的~因为SBUF读跟写是两个物理地址一样但不同的寄存器,还有刚刚把你的程序作了写测试,发现串口中断中的ch变量可能与某些堆栈地址重复了~所以不能做传递使用。
    题外话:1、写程序的时候一定要注意格式;2、在KEIL中尽量不要用a,b,c作变量;3、51内核的单片机在调用串口中断时先把中断关掉再打开才能保证中断程序运行的可靠性。
您需要登录后才可以回帖 登录 | 注册会员

*滑块验证:
img_loading
智能检测中
本版积分规则

QQ|手机版|MCU资讯论坛 ( 京ICP备18035221号-2 )|网站地图

GMT+8, 2025-7-5 22:11 , Processed in 0.070397 second(s), 12 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表