哈罗CQ火腿社区  

返回   哈罗CQ火腿社区 > 火腿技术区 > 单片机与自动控制
用户名
密码
注册 常见问题 会员列表 日历 标记论坛为已读

回复
 
主题工具 搜索本主题 显示模式
旧 2006-11-07, 09:39   #1
warason
菜鸟(*)
 
加入日期: 2006-10-29
帖子: 9
warason is on a distinguished road
Red face GPS OEM板+单片机+液晶显示

我所做的是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(); //显示程序
}
}
warason离线中   回复时引用此帖
旧 2006-11-07, 12:29   #2
loverslcn
怪兽级火腿(******)
 
加入日期: 2002-09-19
帖子: 576
loverslcn is off the scale
您这个串口中断处理函数的风格实在不敢恭维。
__________________
姓名:杨瑞兴
会员证编号:36952(05年1月入会)
操作证编号:63-36952
呼号:申请中
设备:c150,c450,IC-28C
爱好:无线电、编程(gcc,vc++)
现住北京
loverslcn离线中   回复时引用此帖
旧 2006-11-07, 15:23   #3
BD4VNF
情深不怨级
 
BD4VNF的头像
 
加入日期: 2002-10-28
帖子: 1,253
BD4VNF is off the scale
good good study,day day up.
__________________
淮安无线电运动协会 -- BD4VNF
www.haham.org
中继频率:
2.0 M 上行: 144.870 下行: 145.470
400M: 上行: 430.525 下行: 439.525


知识改变命运,财富创造人生
静静的做事,淡淡的伤感
13912088528
BD4VNF离线中   回复时引用此帖
旧 2006-11-07, 19:02   #4
warason
菜鸟(*)
 
加入日期: 2006-10-29
帖子: 9
warason is on a distinguished road
引用:
作者loverslcn
您这个串口中断处理函数的风格实在不敢恭维。


那你觉得做成什么样子?
warason离线中   回复时引用此帖
旧 2006-11-07, 19:19   #5
warason
菜鸟(*)
 
加入日期: 2006-10-29
帖子: 9
warason is on a distinguished road
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; //置此次数据接收有效,重开串行中断等待接收
}
warason离线中   回复时引用此帖
旧 2006-11-08, 20:13   #6
8200
B G 7 I H D
 
8200的头像
 
加入日期: 2002-04-05
您的住址: 广东 潮州
帖子: 1,776
8200 is off the scale
顶 !
__________________
VY 73!de BG7IHD 汤伟东
☆ ☆ ☆ ☆ ☆
GSM : 零-壹叁柒-XXXX-壹零叁零(PAUSED
CDMA: 零-壹叁叁-叁贰柒捌-叁柒零零(24h On Air
Email: bg7ihd <at> 163.com(主题请标注:HAM
8200离线中   回复时引用此帖
旧 2006-11-09, 12:34   #7
loverslcn
怪兽级火腿(******)
 
加入日期: 2002-09-19
帖子: 576
loverslcn is off the scale
判断$GPGGA,的那一串if else太不直观了,用个switch都比这个要好,您那么多的*flag也让人眼花缭乱,一个unsigned char 就可以搞定的。
我建议您用const char 的数组存贮你的那个$GPGGA,
一个指针(unsigned char)指向字符串的下一个字符
一个bit判断$GPGGA,是否接收完毕
__________________
姓名:杨瑞兴
会员证编号:36952(05年1月入会)
操作证编号:63-36952
呼号:申请中
设备:c150,c450,IC-28C
爱好:无线电、编程(gcc,vc++)
现住北京
loverslcn离线中   回复时引用此帖
旧 2006-11-09, 12:50   #8
warason
菜鸟(*)
 
加入日期: 2006-10-29
帖子: 9
warason is on a distinguished road
我也有想到过判断出帧头后,把后面的都存储到一个数组中,
然后以逗号作为分割点,
把时间,经纬度,高度提取出来,
但是具体怎么写就不会了,
能否赐教?用Q么?
warason离线中   回复时引用此帖
旧 2006-11-12, 15:08   #9
bd7rf
到处流浪的火腿
 
bd7rf的头像
 
加入日期: 2001-10-05
您的住址: /ZL
帖子: 3,428
bd7rf is on a distinguished road
我用汇编完成,没那么多语句啊。
__________________
——————————————————————
================================
bd7rf现在在线   回复时引用此帖
旧 2006-11-12, 15:11   #10
8200
B G 7 I H D
 
8200的头像
 
加入日期: 2002-04-05
您的住址: 广东 潮州
帖子: 1,776
8200 is off the scale
引用:
作者bd7rf
我用汇编完成,没那么多语句啊。

能帖出来吗?包括线路图。
谢谢了!
__________________
VY 73!de BG7IHD 汤伟东
☆ ☆ ☆ ☆ ☆
GSM : 零-壹叁柒-XXXX-壹零叁零(PAUSED
CDMA: 零-壹叁叁-叁贰柒捌-叁柒零零(24h On Air
Email: bg7ihd <at> 163.com(主题请标注:HAM
8200离线中   回复时引用此帖
旧 2006-11-12, 15:38   #11
bd7rf
到处流浪的火腿
 
bd7rf的头像
 
加入日期: 2001-10-05
您的住址: /ZL
帖子: 3,428
bd7rf is on a distinguished road
????????????、、
__________________
——————————————————————
================================

此帖于 2007-04-29 18:18 被 bd7rf 编辑.
bd7rf现在在线   回复时引用此帖
旧 2006-11-12, 15:41   #12
bd7rf
到处流浪的火腿
 
bd7rf的头像
 
加入日期: 2001-10-05
您的住址: /ZL
帖子: 3,428
bd7rf is on a distinguished road
没好好研究。
__________________
——————————————————————
================================

此帖于 2007-04-29 18:26 被 bd7rf 编辑.
bd7rf现在在线   回复时引用此帖
旧 2006-11-12, 17:46   #13
bd7rf
到处流浪的火腿
 
bd7rf的头像
 
加入日期: 2001-10-05
您的住址: /ZL
帖子: 3,428
bd7rf is on a distinguished road
引用:
作者8200
能帖出来吗?包括线路图。
谢谢了!

哪部分的线路图?
__________________
——————————————————————
================================
bd7rf现在在线   回复时引用此帖
旧 2006-11-12, 20:50   #14
8200
B G 7 I H D
 
8200的头像
 
加入日期: 2002-04-05
您的住址: 广东 潮州
帖子: 1,776
8200 is off the scale
谢谢了!!
线路图就是MCU那些脚接LCD,那些脚接GPS。
晶振用22.1184MHz吗??
如果晶振改用11.5902MHz,程序需改动那些?
谢谢了。
__________________
VY 73!de BG7IHD 汤伟东
☆ ☆ ☆ ☆ ☆
GSM : 零-壹叁柒-XXXX-壹零叁零(PAUSED
CDMA: 零-壹叁叁-叁贰柒捌-叁柒零零(24h On Air
Email: bg7ihd <at> 163.com(主题请标注:HAM
8200离线中   回复时引用此帖
旧 2006-11-12, 22:01   #15
dzyj
火腿长老(*********)
 
dzyj的头像
 
加入日期: 2002-07-06
您的住址: 北京
帖子: 1,980
dzyj is off the scale
引用:
作者8200
谢谢了!!
线路图就是MCU那些脚接LCD,那些脚接GPS。
晶振用22.1184MHz吗??
如果晶振改用11.5902MHz,程序需改动那些?
谢谢了。

俺也想知道呀.
__________________
我就是我,请不要抄用我的图像,如必须抄用请注明出处

QQ:1*7*3*9*3*9*9*1
会员号:1141
呼号:B*G*1*E*U*I
电话:1叁柒零1叁捌24陆7

欢迎您来北京
dzyj离线中   回复时引用此帖
旧 2006-11-13, 11:51   #16
bd7rf
到处流浪的火腿
 
bd7rf的头像
 
加入日期: 2001-10-05
您的住址: /ZL
帖子: 3,428
bd7rf is on a distinguished road
引用:
作者8200
谢谢了!!
线路图就是MCU那些脚接LCD,那些脚接GPS。
晶振用22.1184MHz吗??
如果晶振改用11.5902MHz,程序需改动那些?
谢谢了。

用11.0592的话,改F4为FD就行了
mov TMOD,#20H
MOV TH1,#0F4H
MOV TL1,#0F4H
MOV PCON,#00H
上传的图像
 
__________________
——————————————————————
================================
bd7rf现在在线   回复时引用此帖
旧 2006-11-13, 11:56   #17
bd7rf
到处流浪的火腿
 
bd7rf的头像
 
加入日期: 2001-10-05
您的住址: /ZL
帖子: 3,428
bd7rf is on a distinguished road
P3.0接GPSTTL输出,不是TTL输出的要转换电平。
__________________
——————————————————————
================================
bd7rf现在在线   回复时引用此帖
旧 2006-11-13, 12:12   #18
bd7rf
到处流浪的火腿
 
bd7rf的头像
 
加入日期: 2001-10-05
您的住址: /ZL
帖子: 3,428
bd7rf is on a distinguished road
我也是新手,请多指教。
__________________
——————————————————————
================================
bd7rf现在在线   回复时引用此帖
旧 2006-11-13, 20:53   #19
8200
B G 7 I H D
 
8200的头像
 
加入日期: 2002-04-05
您的住址: 广东 潮州
帖子: 1,776
8200 is off the scale
太好了,谢谢BD7RF !
明天试试看。
__________________
VY 73!de BG7IHD 汤伟东
☆ ☆ ☆ ☆ ☆
GSM : 零-壹叁柒-XXXX-壹零叁零(PAUSED
CDMA: 零-壹叁叁-叁贰柒捌-叁柒零零(24h On Air
Email: bg7ihd <at> 163.com(主题请标注:HAM
8200离线中   回复时引用此帖
旧 2006-11-14, 14:43   #20
dzyj
火腿长老(*********)
 
dzyj的头像
 
加入日期: 2002-07-06
您的住址: 北京
帖子: 1,980
dzyj is off the scale
引用:
作者warason
我所做的是GPS+单片机+液晶显示,板上晶振是11.5902Mhz,硬件连接是用Garmin25的NEMA端口经RS232转为TTL电平给89C51的10脚(RXD)



请教一下,我也想照着做一个,板上晶振是11.5902是哪个板上的晶振?是不是我把这个程序写到89c51里,照着图接好数据线就行了.
__________________
我就是我,请不要抄用我的图像,如必须抄用请注明出处

QQ:1*7*3*9*3*9*9*1
会员号:1141
呼号:B*G*1*E*U*I
电话:1叁柒零1叁捌24陆7

欢迎您来北京
dzyj离线中   回复时引用此帖
旧 2006-11-14, 16:21   #21
bd7rf
到处流浪的火腿
 
bd7rf的头像
 
加入日期: 2001-10-05
您的住址: /ZL
帖子: 3,428
bd7rf is on a distinguished road
引用:
作者dzyj
请教一下,我也想照着做一个,板上晶振是11.5902是哪个板上的晶振?是不是我把这个程序写到89c51里,照着图接好数据线就行了.

晶振是11.0592,是单片机的板上的.上面那个图是简化,还有几个外围零件要加上的.
__________________
——————————————————————
================================
bd7rf现在在线   回复时引用此帖
旧 2006-11-14, 16:27   #22
dzyj
火腿长老(*********)
 
dzyj的头像
 
加入日期: 2002-07-06
您的住址: 北京
帖子: 1,980
dzyj is off the scale
引用:
作者bd7rf
晶振是11.0592,是单片机的板上的.上面那个图是简化,还有几个外围零件要加上的.

明白一点儿了,那你有单片机的板图吗?想了解一下,看看怎么弄,好弄的话,我自己也做一个.谢谢.
__________________
我就是我,请不要抄用我的图像,如必须抄用请注明出处

QQ:1*7*3*9*3*9*9*1
会员号:1141
呼号:B*G*1*E*U*I
电话:1叁柒零1叁捌24陆7

欢迎您来北京
dzyj离线中   回复时引用此帖
旧 2006-11-15, 14:25   #23
warason
菜鸟(*)
 
加入日期: 2006-10-29
帖子: 9
warason is on a distinguished road
有没有用keilC编写的中断程序和显示程序啊55555555555555

有没有用keilC编写的中断程序和显示程序啊55555555555555
warason离线中   回复时引用此帖
旧 2006-11-17, 15:19   #24
BG8WJ
蛤蟆级火腿(**)
 
加入日期: 2004-04-09
帖子: 135
BG8WJ is on a distinguished road
这个程序太复杂拉!这个非常简单啊。你是用中断方式接收信息,在构造个数组么完全可以啊!具体可以参考 求实科技的 单片机典型模块设计 一书!
BG8WJ离线中   回复时引用此帖
旧 2006-11-18, 18:05   #25
warason
菜鸟(*)
 
加入日期: 2006-10-29
帖子: 9
warason is on a distinguished road
楼上的有没有电子版本推荐?
warason离线中   回复时引用此帖
旧 2006-11-21, 15:23   #26
warason
菜鸟(*)
 
加入日期: 2006-10-29
帖子: 9
warason is on a distinguished road
中断程序还是进不去啊,
为什么?
warason离线中   回复时引用此帖
旧 2006-11-21, 15:58   #27
loverslcn
怪兽级火腿(******)
 
加入日期: 2002-09-19
帖子: 576
loverslcn is off the scale
呵呵,别着急,我给你写了一下,可能有部分错误,但是算法基本上就是这样的:
代码:
#define DATA_END '*' #define CMD_LEN 7 const char cmd = "$GPGGA,"; uchar pCmd = 0; sbit cmdReady = 0; sbit dataFull = 0; void serial() interrupt 4 { uchar tmp; RI = 0; tmp = SBUF; if( cmdReady && !dataFull ){ //命令正确,接收数据 if( tmp == DATA_END ){ cmdReady = 0; dataFull = 1; //缓冲中已有全部数据,主程序可判断dataFull,读出缓冲区数据,并清空缓冲区,置dataFull为0, } //接收数据放入缓冲, adding } else{ if( tmp == cmd[pCmd] ){ //接收到正确命令 pCmd++; if( pCmd >= CMD_LEN ){ pCmd = 0; cmdReady = 1; } } else{ pCmd = 0; } } }
__________________
姓名:杨瑞兴
会员证编号:36952(05年1月入会)
操作证编号:63-36952
呼号:申请中
设备:c150,c450,IC-28C
爱好:无线电、编程(gcc,vc++)
现住北京
loverslcn离线中   回复时引用此帖