📄 obdc.c
字号:
#include <io51.h>
#include "def.h"
/* #include "var.h" */
/* --VAR.H-- */
#define portmc ((char xdata *)0xef00) /* 8255 */
#define port80 ((char xdata *)0xf400) /* 8254 port.0 */
#define port81 ((char xdata *)0xf500) /* 8254 port.1 */
#define port82 ((char xdata *)0xf600) /* 8254 port.2 */
#define port83 ((char xdata *)0xf700) /* 8254 port.3 */
data unsigned int ms10count;
data bit setpwm; /* 0: VPW 1: PWM */
data bit starfrm;
data bit sfflg; /* 0: 接收 1: 发送 */
data bit recflg; /* 0: 不接收 1: 接收帧 */
data bit pwmsflg;
data bit pwmsfack; /* 1: 接收"发送帧"内响应 0: 不接收 */
data unsigned char cht2,recsj,rcount,timh0,timl0;
data unsigned char sendsj,scount,pwmd0;
data bit flag;
data bit rbflg;
data bit bflg;
data bit pwmsdf;
data bit pwmssf;
data char i;
data unsigned char ch1,ch2,ch3,ch4;
data unsigned char sett0h,sett0l,sett0md;
void time10ms(void);
void exint0(void);
void vpwc();
void pwmc();
void pwmsend();
void fout1();
void fout2();
void main() /* CPU: 24MHz */
{ ch4=0;
TMOD=1; IP=1; TCON=0X10; /* T0 定时方式1(16bit),INT0 级别高于 T0,INT0,
T0中断允许 INT0 电平方式*/
enable_ET0; /* T0 中断控制允许 */
EX0=0;EX1=0;ES=0;EA=1;T1=1;TXD=1;RXD=1;
P13=0; P12=0;P16=1;
P15=1; /* REC STA */
P17=1; /* SEND STA */
TH0=0XBE; TL0=0XE6;ms10count=0;
while(ms10count<10);
ch1= *portmc;
T1=0; while(ms10count<20); T1=1;
ch1=0;ch2=0;setpwm=0;pwmd0=0;
while(1)
{if(TXD==0)
{T1=0;
ch1=ch2;
ch2=*portmc;
T1=1;
while(RXD==1);
switch(ch2)
{case 0xa0: *portmc=0x10;break; /* OBD-II 调制硬件号 V1.0 */
case 0xa1: *portmc=0x20;break; /* OBD-II 调制软件号 V2.0 */
default: *portmc=~ch2;
}
if(ch2==0xf0) /* start */
{switch(ch1)
{case 0x10: /* VPW */
P14=0;setpwm=0;
ms10count=0;while(ms10count<3);vpwc();
break;
case 0x11: /* PWM */
case 0x12:
pwmsfack=1;
P14=1;setpwm=1;
ms10count=0;while(ms10count<3);pwmc();
break;
case 0x13: /* PWM */
pwmsfack=0;
P14=1;setpwm=1;
ms10count=0;while(ms10count<3);pwmc();
break;
case 0x20: /* 方波 */
while(TXD==1);
sett0md=*portmc;
while(TXD==1);
sett0h=*portmc;
while(TXD==1);
sett0l=*portmc;
ms10count=0;while(ms10count<2);
if(sett0md==0) fout1();
else fout2();
break;
}
}
}
}
}
void vpwc()
{
P13=0; P12=0;P16=1;P17=1;
TL0=0;TH0=0;TR0=1;
ET0=0;EX0=0;EA=1;
flag=1;INT0=1;
*port83=0x32; /* T0: 方式1; RD/WR 2Byte */
*port80=0; *port80=0;
*port83=0x72; /* T1: 方式1; RD/WR 2Byte */
*port81=0; *port81=0;
*port83=0xb0; /* T2: 方式0; RD/WR 2Byte */
*port82=0; *port82=0;
sfflg=0; /* 0: 接收 1: 发送 */
recflg=0; /* 0: 不接收 1: 接收帧 */
*port83=0x12; /* T0: 方式1; RD/WR 1Byte */
*port83=0x52; /* T1: 方式1; RD/WR 1Byte */
*port83=0x90; /* T2: 方式0; RD/WR 1Byte */
P10=0;P11=1; /* 初始化 D触发器 */
P12=1;
while(INT0==1);
*port82=0xff;
while(flag)
{if(sfflg) /* 发送 */
{if(P16==1)
{
if(scount==0) /* 转接收帧 */
{
while(P16==1);
sfflg=0;
P12=1; P10=0;P11=1;
*port82=0xff;
TL0=0;TH0=0;TR0=1;EX0=0;
}
else
{if((sendsj&scount)==0) /* 位为0 */
{*port83=0x72;*port81=32;*port81=0;}
else {*port83=0x72;*port81=64;*port81=0;}
scount=scount>>1;
}
while(P16==1);
}
else
{if((sendsj&scount)==0) /* 位为0 */
{*port83=0x32;*port80=64;*port80=0;}
else {*port83=0x32;*port80=32;*port80=0;}
scount=scount>>1;
if(scount==0)
{if(TXD==0) /* 发送下一字节 */
{sendsj=*portmc;
scount=0x80;
}
else P17=1; /* 置发送结束标记 */
}
while(P16==0);
}
}
else /* 接收 */
{if(INT0==1)
{EX0=1; /* 160 */
TR0=0;
timl0=TL0;
if((TH0==0)&&(timl0<205)) rcount=rcount>>1; /* 137 */
else
{if((TH0!=0)&&(timl0>86)) recflg=0;
else {recsj=recsj+rcount;rcount=rcount>>1;} /* 274 */
}
while(INT0==1);
}
else
{/* *port83=0x90; 方式0; RD/WR 1Byte */
*port82=0xff;
if(TH0>1)
{P15=1; /* 置接收结束标记 */
if(TXD==0) /* 转发送帧 */
{
sendsj=*portmc;
sfflg=1;
EX0=0;
while((TH0<3)||(INT0==1)) {if(INT0==1) TH0=0;} /* 检测空闲 */
P10=0;P11=1; /* 初始化 D触发器 */
*port83=0x32;*port80=96;*port80=0;
P10=1;P11=0;P11=0;P11=1;P12=1; /* 发送启动位 */
P17=0; /* 置发送开始标记 */
scount=0x80;
}
TH0=3;
}
}
}
}
}
void pwmc()
{rbflg=0;pwmssf=0;
P13=1; P12=0;P16=1;P17=1;
TMOD=0x19;
TL0=0;TH0=0;TR0=1; ET0=0;
TL1=0;TH1=0;TR1=0; ET1=0;
EX0=0;EA=0;
flag=1;INT0=1;
*port83=0x32; /* T0: 方式1; RD/WR 2Byte */
*port80=0; *port80=0;
*port83=0x72; /* T1: 方式1; RD/WR 2Byte */
*port81=0; *port81=0;
*port83=0xb0; /* T2: 方式0; RD/WR 2Byte */
*port82=0; *port82=0;
sfflg=0; /* 0: 接收 1: 发送 */
recflg=0; /* 0: 不接收 1: 接收帧 */
*port83=0x12; /* T0: 方式1; RD/WR 1Byte */
*port83=0x52; /* T1: 方式1; RD/WR 1Byte */
*port83=0x9a; /* T2: 方式5; RD/WR 1Byte */
P10=0;P11=1; /* 初始化 D触发器 */
P12=1;EX0=0;
while(INT0==1);
*port82=0xff;
TL0=0;TH0=0;TR0=1;
TL1=0;TH1=0;TR1=1;
/* 接收/空闲状态 */
pwmck_1:
if(INT0==1)
{ /* 160 */
TL1=0;TH1=0;
while(INT0==1);
cht2=TL0;TL0=0;
/* if((cht2<140)&&(cht2>90)&&(TH0==0)) 45: 帧开始 186+/-5 */
if((cht2<84)&&(cht2>50)&&(TH0==0)) /* 45: 帧开始 186+/-5 */
{
TL1=0;
recsj=0;rcount=0x80;
P15=0; goto pwmrec1; /* 接收帧开始 */
}
else TH0=0;
}
else /* INT0=0 */
{
TL0=0;TH0=0;
if(TH1>0) /* 28*6 */
{P15=1; /* 接收帧结束 */
if(TXD==0) /* 转发送帧 */
{
sendsj=*portmc;
/* sfflg=1;*/
TMOD=0x11;TR0=1;
EX0=0;
scount=0x80;pwmsflg=1;pwmsdf=1;
while((TH0<3)||(INT0==1)) {if(INT0==1) TH0=0;} /* 检测空闲 */
P10=0;P11=1; /* 初始化 D触发器 */
*port83=0x12;*port80=62; /* 60 */
P10=1;P11=0;P11=1; /* 发送启动位 */
*port83=0x52;*port81=34;/* 38 */
P17=0; /* 发送帧开始 */
pwmsend();
}
else TH1=4;
}
}
goto pwmck_1;
pwmrec1: /* 接收帧 */
if(INT0==1)
{ /* 160 */
pwmrec2:
TL1=0;
while(INT0==1);
pwmrec3:
if(TL0<22) recsj=recsj|rcount;
TL0=0;
rcount>>=1;
if(rcount==0)
{
*portmc=recsj;
recsj=0;rcount=0x80;
if(TL0!=0)
{TL1=0;
goto pwmrec2;
}
}
}
else /* INT0=0 */
{
if(TL1>48) /* 50: 15*3.5 */
{ P15=1; /* 接收帧结束 */
if(TXD==0) /* 转发送帧响应 */
{
sendsj=*portmc;
/* sfflg=1;*/
scount=0x40;
P10=0;P11=1; /* 初始化 D触发器 */
*port83=0x12;
while(TL1<65); /* 73--13, 77--14, */
if((sendsj&0x80)==0)
{*port80=32;
P10=1;P11=0;P11=1; /* 发送启动位 */
*port83=0x52;*port81=16;
P17=0; /* 发送帧开始 */
pwmsend();
}
else
{*port80=16;
P10=1;P11=0;P11=1; /* 发送启动位 */
*port83=0x52;*port81=32;
P17=0; /* 发送帧开始 */
pwmsend();
}
}
goto pwmck_1;
}
}
goto pwmrec1;
}
void pwmsend()
{
pwmsc1:
/* while(P16==1); */
if((sendsj&scount)==0) /* 位为0 */
{
while(P16==1);
*port80=32;
scount>>=1;
if(scount==0)
{
while(P16==0);
*port81=16;
if(TXD==0) /* 发送下一字节 */
{sendsj=*portmc;
scount=0x80;
goto pwmsc1;
}
else {P17=1;goto pwmsc2; } /* 发送帧结束 */
}
while(P16==0);
*port81=16;
goto pwmsc1;
}
else
{
while(P16==1);
*port80=16;
scount>>=1;
while(P16==0);
*port81=32;
if(scount==0)
{if(TXD==0) /* 发送下一字节 */
{sendsj=*portmc;
scount=0x80;
goto pwmsc1;
}
else {P17=1;goto pwmsc2; } /* 发送帧结束 */
}
goto pwmsc1;
}
pwmsc2: /* 发送帧结束处理 */
/* sfflg=0;*/
if(pwmsfack)
{
while(P16==1);
P12=1; P10=0;P11=1;
*port82=0xff;
TMOD=0x19;
TL0=0;TH0=0;TR0=1;
TL1=0;TH1=0;TR1=1;
recsj=0;rcount=0x80;
P15=0;
pwmsfrc1: /* 接收"发送帧"内响应 */
if(INT0==1)
{ /* 160 */
pwmsfrc2:
TL1=0;
while(INT0==1);
if(TL0<22) recsj=recsj|rcount;
TL0=0;
rcount>>=1;
if(rcount==0)
{
*portmc=recsj;
recsj=0;rcount=0x80;
if(TL0!=0)
{TL1=0;
goto pwmsfrc2;
}
}
}
else /* INT0=0 */
{TL0=0;
if(TL1>90) /* 50: 15*3.5 */
{ P15=1; /* 接收帧结束 */
goto pwmsc3;
}
}
goto pwmsfrc1;
}
else { while(P16==1); }
pwmsc3:
P12=1; P10=0;P11=1;
rbflg=0;
*port82=0xff;
TMOD=0x19;
TL0=0;TH0=0;TR0=1;
TL1=0;TH1=0;TR1=1;return;
}
void time10ms(void) interrupt 1
{TH0=0XBE; TL0=0XE6;
ms10count++;enable;
}
void EX0_int(void) interrupt 0
{
/* VPW */
TH0=0;TL0=0;TR0=1;EX0=0;
*port83=0x80; /* 锁存输出 */
cht2=*port82;
if(cht2<170) /* 102: 帧开始 */
{recflg=1;recsj=0;
rcount=0x80;
P15=0; /* 置接收开始标记 */
}
else
{if(recflg)
{if(cht2<204) rcount=rcount>>1; /* 68 */
else
{if(cht2<238) {recsj=recsj+rcount;rcount=rcount>>1;} /* 34 */
else recflg=0;
}
if(rcount==0)
{
*portmc=recsj;
recsj=0;rcount=0x80;
}
}
}
}
void fout1()
{ EA=0;
TMOD=1; TCON=0X10;
cf_start1:
T1=0;
TH0=sett0h;TL0=sett0l;
while(!TF0);
TF0=0;T1=1;
TH0=sett0h;TL0=sett0l;
if(!TXD)
{
if(*portmc==0x0f) {T1=1;EA=1;return;}
}
while(!TF0);
TF0=0;
goto cf_start1;
}
void fout2()
{data unsigned char count;
EA=0;
TMOD=1; TCON=0X10;
cf_start2:
T1=0;
count=sett0md;
while(count>0)
{TL0=0;TH0=0;TF0=0;
while(TF0==0);
count--;
}
TH0=sett0h;TL0=sett0l;
while(!TF0);
TF0=0;T1=1;
count=sett0md;
while(count>0)
{TL0=0;TH0=0;TF0=0;
while(TF0==0);
count--;
}
TH0=sett0h;TL0=sett0l;
if(!TXD)
{
if(*portmc==0x0f) {T1=1;EA=1;return;}
}
while(!TF0);
TF0=0;
goto cf_start2;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -