📄 complete.c
字号:
}
if(m_meteraddrc==2) //判断地址表中的2个字节是否结束
{
m_meteraddrc=0x00;
rs485_status=0x01; //更新RS485接收中断程序的状态
}
}
else if(rs485_status==0x01) //如果接收中断程序状态处于1,则接收发送方的地址
{
m_sendaddrcode=rs485_data; //保存发送方的地址
rs485_status=0x02; //更新RS485接收中断程序的状态
}
else if(rs485_status==0x02) //如果接收中断程序状态处于2,则接收接收方的地址.
{
m_receiveaddrcode=rs485_data;//保存接收方的地址.
m_meterdatac=0x00; //复位数据段计数器.
rs485_status=0x03; //更新RS485接收中断程序的状态
}
else if(rs485_status==0x03) //如果接收中断程序处于3,则接收数据信息.
{
m_meterdatbuf[m_meterdatac]=rs485_data; //保存接收的数据信息
m_meterdatac++; //更新数据计数器
if(m_meterdatac==8) //判断数据段是否接收完?
{
m_metersyscheck= 0xac+0xca+m_sendaddrcode+m_receiveaddrcode; //初始化和校验变量
rs485_status=0x04; //更新RS485接收中断程序的状态
}
}
else if(rs485_status==0x04) //如果接收中断程序处于4,则接收累加和校验信息
{
m_metercheck=rs485_data; //保存接收到的累加和校验信息.
for(m_meterdatac=0;m_meterdatac<8;m_meterdatac++)//累加数据段.
{
m_metersyscheck+=m_meterdatbuf[m_meterdatac];
}
rs485_status=0x05; //更新RS485接收中断程序的状态
}
else if(rs485_status==0x05) //如果RS485接收中断程序处于状态5,则接收结束符.
{
re_de1=0; //设置RS485进入发送状态.设置MAX485(3)接收
re_de2=0; //设置MAX485(2)接收
re_de3=1; //设置MAX485(1)发送.
m_meteraddrc=0x00; //重新接收数据帧中的地址信息
rs485_status=0x00; //复位RS485接收中断程序状态标志.
if(m_metersyscheck==m_metercheck ) //如果正确接收到数据,发出dd.
{
switch(m_meterdatbuf[0])
{
case 0x30:send_ultrasonic();break; //如果是30H,发送超声信息。
case 0x40:send_mapan(); break; //如果是50H,发送码盘信息。
case 0x50:send_compass(); break; //如果是60H,发送罗盘信息。
default : send_frameagain(); //请求重发。
}
}
else
{
send_frameagain();
}
m_metersyscheck=0x00;
m_metercheck=0x00;
}
}
}
/*主程序*/
void main(void)
{
TMOD=0x11; //16位定时器T0,16位定时器T1工作方式皆方式1.
TCON=0x01; //设置TCON,INT1为低电平有效,INT0为下降沿有效.IT0=1
d=0;
EA=1;
PX0=1; //设置INT0中断优先级高
PT0=1; //定时器中1的中断优先级高
PS=0; //串口的优先级低,
P0_7=1; //CD4520先清零
P0_7=0; //让CD4520工作.
tmp1=0; //赋初值.
tmp2=0; //赋初值.
count1=0; //左车轮计数是否溢出先清零。
count2=0; //右车轮计数是否溢出先清零。
T2CON=0x30;
RCAP2H=0xff; //用T2做波特率发生器.9600 置初值.
RCAP2L=0xdc;
PCON&=0x0f; //波特率不加倍.
SCON=0x70; //设置串行口工作方式为方式1
ES=1; //串行中断允许
TR2=1; //定时器T1启动
re_de1=1; //设置MAX485进入接收状态,设置MAX485(3)发送.
re_de2=0;
re_de3=0; //设置MAX485(1)接收.
while(1)
{
int i;
for(i=0;i<8;i++) //清超声波组
{
array1[i]=0;
}
for(i=0;i<5;i++) //清红外线组
{
z[i]=0;
}
for(i=0;i<2;i++) //清码盘组
{
array3[i]=0;
}
for(i=0;i<=7;i++)
{
select=i;
IE = 0x82;
P0_0=flag0;P0_1=flag1;P0_2=flag2;P0_3=1; //选中第i路.分别为0.1.2.3.4.5.6.7路.
TH0=0xca;
TL0=0x00;
TH1=0xFe;TL1=0x33; //发送20个脉冲=0.5ms,用T1计时0.5ms.
TF1=0; //打开定时器T0,15ms
TF0=0;
TR1=1;TR0=1; //同时启动T0,T1
do{}while(TF1==0); //等0.5ms时间结束.
P0_3=0; //关闭555
TR1=0;TH1=0xfc;TL1=0x66; //延时1ms,盲区26cm
TF1=0;
TR1=1;
do{}while(TF1==0); //等待结束.
a=0;
IE0=0; //开中断前,清中断
EX0=1; //允许外部中断int0
do{}while(a==0);
array1[i]=count;
}
e1=1; //对P1口的高三位置位
e2=1;
e3=1;
IE1=0; //开中断前先清外部中断1,
EX1=1; //设置外部中断1允许.
delayms(1);
array2[0]=z0; //把第0路红外线信号赋入array2[0].
array2[1]=z1; //把第1路红外线信号赋入array2[1]
array2[2]=z2; //把第2路红外线信号赋入array2[2]
array2[3]=z3; //把第3路红外线信号赋入array2[3]
array2[4]=z4; //把第4路红外线信号赋入array2[4]
for(i=0;i<8;i++) //对超声波和红外线进行综合处理.
{
if(i<3)
{
if(z[i]==1)
{
array1[i]=-1; //说明在盲区内有障碍物的存在.
}
}
else if(i==3)
{
if(z[2]==1) //说明在盲区内有障碍物的存在.
{
array1[3]=-1;
}
}
else if(3<i<=5) //说明在盲区内有障碍物的存在.
{
if(z[3]==1)
{
array1[i]=-1;
}
}
else if(5<i<=7) //说明在盲区内有障碍物的存在.
{
if(z[4]==1)
{
array1[6]==-1;
array1[7]=-1;
}
}
}
dis1=tmp1; //记录tmp1的上一次的值.
dis2=tmp2; //记录tmp2的上一次的值.
tmp1=P2;
tmp1=tmp1&0x0f; //左车轮取P2低4位,
tmp2=P2;
tmp2>>=4; //取得的P2口数据右移4位,以便下一步取值。
tmp2=tmp2&0x0f; //右车轮取P2高4位。
if(tmp1<dis1)
{
++count3;
}
if(tmp2<dis2)
{
++count4;
}
array3[0]=road(count3,tmp1);
array3[1]=road(count4,tmp2);
/* for(i=0;i<8;i++) //以下程序用于输出测的值,经过实验,在KEIL中用PRINTF不能输出,可能由于本身PRINTF的原因.
{
printf("%dm ",array1[i]);
}
printf("\n");
for(i=0;i<5;i++)
{
printf("%d ",z[i]);
}
printf("\n");
for(i=0;i<2;i++)
{
printf("%dm ",array3[i]);
}
printf("\n");*/
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -