论坛风格切换切换到宽版
  • 63481阅读
  • 338回复

GPS OEM板+单片机+液晶显示 [复制链接]

上一主题 下一主题
离线warason
 
只看楼主 倒序阅读 0楼 发表于: 2006-11-07
我所做的是gps+单片机+液晶显示,板上晶振是11.5902mhz,硬件连接是用garmin25的nema端口经rs232转为ttl电平给89c51的10脚(rxd)


我有个问题,就是现在执行程序后不能进入串行口中断,

附程序如下:

/*************************************中断程序*****************************/
//定时器0中断函数,用于控制背光灯延时10s熄灭

void int_t0() interrupt 1 using 1
{
th0 = 0x4c;
tl0 = 0x00;               //重装定时器0,定时50ms
time_counter ++;         // 软件计数器+1
  }
}


//串行口中断函数,用于语句“$ gpgga”的判断和此语句的接收

void serial() interrupt 4 using 2
{
uchar pp;

  ri=0;
  pp=sbuf;

  if(pp==0x24)       //判断第1个是不是$
  {
    sflag=1;           //第一个是$,判断下一个是不是g
serial_counter=0;     //串行计数器清0
  }
else
  serial_byte=0;       //不是$,清标志位

if(sflag==1)       //第一个是$,判断第2个是不是g
  {
  if(pp==71)           //第2个是g,判断下一个是不是p
  g1flag=1;
else
  serial_byte=0;     //不是g,清标志位
  }
if(g1flag==1)       //第2个为g,判断第3个是不是p
  {
  if(pp==80)
  pflag=1;         //第3个是p,判断下一个是不是g
else
  serial_byte=0;     //不是p,清标志位
  }
if(pflag==1)       //第3个为p,判断第4个是不是g
  {
  if(pp==71)
  g2flag=1;         //第4个是g,判断下一个是不是g
else
  serial_byte=0;     //不是g,清标志位
  }
if(g2flag==1)       //第4个是g,判断第5个是不是g
  {
  if(pp==71)
  g3flag=1;         //第5个是g,判断下一个是不是a
else
  serial_byte=0;     //不是g,清标志位
  }
if(g3flag==1)       //第5个为g,判断第6个是不是a
  {
  if(pp==65)
  aflag=1;         //第6个是a判断下一个是不是“,”
else
  serial_byte=0;     //不是a,清标志位
  }
if(aflag==1)       //第6个为a,判断第7个是不是“,”
  {
  if(pp==44)
  dfflag=1;         //第7个是“,”开始接收“$ gpgga,”语句的数据
else
  serial_byte=0;     //不是“,”,清标志位
  }
if(dfflag==1)       //“$ gpgga”头判断完毕,开始接收“$ gpgga,”语句的数据
  {
  if(pp==42)
  enflag=1;         //等待收到*结束接收
else
{
  serial_buff[serial_counter]=pp; //没收到*,继续接收数据放入串口缓冲
    serial_counter++;
}
if(enflag==1)         //串口接收完毕,可以用来显示,清标志位重新开始
  {
  disp_flag=1;
serial_byte=0;
  }

}
}

下面的是我的主函数:

main()
{
//ie=0;
p0=0xff;p1=0xff;p2=0xff;p3=0xff; //端口复位
delay(255);
lcd_init();
lcd_init();     //初始化液晶
lcd_cls();

//pcon:smod
//当pcon等于80h时,smod=1,
//pcon=0x80;

//tmod:gate|c/! t|m1|m0|gate|c/!t|m1|m0
//     0   0   1 0   0   0   0 1
tmod=0x21;         //t0 16位定时,t1 自动重装,方式3
th0=0x4c;
tl0=0x00;           //定时50ms
//tr0=1;

//scon:sm0|sm1|sm2|ren|tb8|rb8|ti|ri
//     0   1   0   0   0   0   0 0

scon=0x40;               //串行口8位utra
th1=0xfa;
tl1=0xfa;                 //波特率发生器,4800bps
et0=1;                 //开定时器0中断允许
es=1;                   //开串行口中断
ea=1;                   //开总中断
ren=1;                 //允许串行接收
tr1=1;                 //开串行口波特率发生器(t1)


while(1)                 //主程序
{
  up=1;                 //把键盘位置1,以便进行键盘输入
  down=1;
  keywork();               //键盘扫描
  if(disp_flag)             //判断是否可以更新显示
  {
  disp_flag=0;             //清显示更新标志
display();             //显示程序
  }
}
离线loverslcn
发帖
621
只看该作者 1楼 发表于: 2006-11-07
您这个串口中断处理函数的风格实在不敢恭维。
离线BD4VNF
发帖
1208
只看该作者 2楼 发表于: 2006-11-07
good good study,day day up.
离线warason
只看该作者 3楼 发表于: 2006-11-07
'
您这个串口中断处理函数的风格实在不敢恭维。
'

那你觉得做成什么样子?
离线warason
只看该作者 4楼 发表于: 2006-11-07
bit gps_ok;                 //如果gps_ok=1,表示接收成功、数据有效。
const char gga[]="$gpgga,";      
struct gps                 //存储gps接收并提取出来的有用数据
{
unsigned char m_latitude[11];     //纬度
unsigned char m_longitude[12];     //经度
unsigned char m_altitude[10];     //海拔
}gps;

unsigned char sbuf;
bit flag; //用于表征该字节数据接收有效与否:其值为1 时,此次字节接收正确有效;否则,为无效接收
void getch(void)
{ unsigned char i=0;
while(!ri)
{if(i++>100) //用于防止接收数据过程中可能出现的等
{         //待死锁
flag=0;
return;}
}
ri = 0;
flag=1;
sbuf=sbuf;
}
/**串行口通讯***/
void serial_int(void) interrupt 4
{
unsigned char ii=0;
ea=0;
es=0;
gps_ok=0;         //关串行中断
for(ii=0;ii<7;ii++) //接收并识别gga 数据帧的帧头
{
getch();
if(sbuf!=gga[ii] || flag==0) //若不是gga 数据帧的帧头,则开中断退出中断服务程序
{es=1;ea=1;return;}
};
do {                     //接收时钟“ hhmmss.dd,”字段
getch();
if(flag==0){es=1;ea=1;return;}   //接收无效,退出中断服务程序
}while(sbuf!=',');
ii=0;
do {                     //接收纬度“ xxmm.dddd,”字段
getch();
if(flag==0){es=1;ea=1;return;}   //接收无效,退出中断服务程序
gps.m_latitude[ii++]=sbuf;
}while(sbuf!=',');
do {                     //接收北半球或南半球“ <n|s>, ”字段
getch();
if(flag==0){es=1;ea=1;return;}   //接收无效,退出中断服务程序
gps.m_latitude[ii++]=sbuf;
}while(sbuf!=',');
gps.m_latitude[ii-1]='\0'       //转换成以‘\0’结尾的字符串
ii=0;
do {                     //接收经度“yyymm.dddd,”字段
getch();
if(flag==0){es=1;ea=1;return;}   //接收无效,退出中断服务程序
gps.m_longitude[ii++]=sbuf;
}while(sbuf!=',');
do {                     //接收东半球或西半球“ <e|w>,”字段
getch();
if(flag==0){es=1;ea=1;return;}   //接收无效,退出中断服务程序
gps.m_longitude[ii++]=sbuf;
}while(sbuf!=',');
gps.m_longitude[ii-1]='\0'     //转换成以‘\0’结尾的字符串
for(ii=0;ii<3;ii++)
do {                     //接收“ v,ss,d.d,”字段,但不保留存储
getch();
if(flag==0){es=1;ea=1;return;}   //接收无效,退出中断服务程序
}while(sbuf!=',');
ii=0;
do {                     // 接收海拔高度“ h.h,”字段
getch();
if(flag==0){es=1;ea=1;return;}   //接收无效,退出中断服务程序
gps.m_altitude[ii++]=sbuf;
}while(sbuf!=',');
gps.m_altitude[ii-1]='\0'       //转换成以‘\0’结尾的字符串
do {                     //接收所有剩下的字段直至数据帧的结尾标志换行号‘\n’
getch();
if(flag==0){es=1;ea=1;return;}   //接收无效,退出中断服务程序
}while(sbuf!='\n');
gps_ok=1;ti=0;es=1;ea=1;       //置此次数据接收有效,重开串行中断等待接收
}
离线8200
发帖
1974
只看该作者 5楼 发表于: 2006-11-08
顶 !
离线loverslcn
发帖
621
只看该作者 6楼 发表于: 2006-11-09
判断$gpgga,的那一串if else太不直观了,用个switch都比这个要好,您那么多的*flag也让人眼花缭乱,一个unsigned char 就可以搞定的。
我建议您用const char 的数组存贮你的那个$gpgga,
一个指针(unsigned char)指向字符串的下一个字符
一个bit判断$gpgga,是否接收完毕
离线warason
只看该作者 7楼 发表于: 2006-11-09
我也有想到过判断出帧头后,把后面的都存储到一个数组中,
然后以逗号作为分割点,
把时间,经纬度,高度提取出来,
但是具体怎么写就不会了,
能否赐教?用q么?
离线bd7rf
发帖
10148
只看该作者 8楼 发表于: 2006-11-12
我用汇编完成,没那么多语句啊。
离线8200
发帖
1974
只看该作者 9楼 发表于: 2006-11-12
'
我用汇编完成,没那么多语句啊。
'
能帖出来吗?包括线路图。
谢谢了!
离线bd7rf
发帖
10148
只看该作者 10楼 发表于: 2006-11-12
????????????、、
离线bd7rf
发帖
10148
只看该作者 11楼 发表于: 2006-11-12
没好好研究。
离线bd7rf
发帖
10148
只看该作者 12楼 发表于: 2006-11-12
'
能帖出来吗?包括线路图。
谢谢了!
'
哪部分的线路图?
离线8200
发帖
1974
只看该作者 13楼 发表于: 2006-11-12
谢谢了!!
线路图就是mcu那些脚接lcd,那些脚接gps。
晶振用22.1184mhz吗??
如果晶振改用11.5902mhz,程序需改动那些?
谢谢了。
离线dzyj
发帖
2275
只看该作者 14楼 发表于: 2006-11-12
'
谢谢了!!
线路图就是mcu那些脚接lcd,那些脚接gps。
晶振用22.1184mhz吗??
如果晶振改用11.5902mhz,程序需改动那些?
谢谢了。
'
俺也想知道呀.
离线bd7rf
发帖
10148
只看该作者 15楼 发表于: 2006-11-13
'
谢谢了!!
线路图就是mcu那些脚接lcd,那些脚接gps。
晶振用22.1184mhz吗??
如果晶振改用11.5902mhz,程序需改动那些?
谢谢了。
'
用11.0592的话,改f4为fd就行了
mov tmod,#20h
mov th1,#0f4h
mov tl1,#0f4h
mov pcon,#00h
离线bd7rf
发帖
10148
只看该作者 16楼 发表于: 2006-11-13
p3.0接gpsttl输出,不是ttl输出的要转换电平。
离线bd7rf
发帖
10148
只看该作者 17楼 发表于: 2006-11-13
我也是新手,请多指教。
离线8200
发帖
1974
只看该作者 18楼 发表于: 2006-11-13
太好了,谢谢bd7rf !
明天试试看。
离线dzyj
发帖
2275
只看该作者 19楼 发表于: 2006-11-14
'
我所做的是gps+单片机+液晶显示,板上晶振是11.5902mhz,硬件连接是用garmin25的nema端口经rs232转为ttl电平给89c51的10脚(rxd)
'

请教一下,我也想照着做一个,板上晶振是11.5902是哪个板上的晶振?是不是我把这个程序写到89c51里,照着图接好数据线就行了.