标题:
stc60s2单片机运行一段时间就死机了,复位后用能运行
[打印本页]
作者:
han333
时间:
2018-6-12 09:52
标题:
stc60s2单片机运行一段时间就死机了,复位后用能运行
程序是循环使用超声波传感器测距 刚开始时正常工作,工作一两分钟后就死机了这是程序
//本程序为单机测试程序,大板可用
//本程序采用中断形式接收指令,同时在进入中断程序之后对所有控制指令进行停止
#include<reg52.h>
#include<math.h>
#include<intrins.h>
#define DIZHI 'C'
sfr CMOD=0XD9;//工作模式寄存器
sfr CCON=0XD8;//控制寄存器
sfr CCAPM0=0XDA;//模块0比较、捕获寄存器
sfr CCAPM1=0XDB;//模块1比较、捕获寄存器
sfr CH=0XF9;//可编程计数器高8位
sfr CL=0Xe9;//可编程计数器低8位
sfr CCAP0H=0XFA;//捕获、比较寄存器0高8位
sfr CCAP0L=0XEA;//捕获、比较寄存器0低8位
sfr CCAP1H=0XFB;//捕获、比较寄存器1高8位
sfr CCAP1L=0XEB;//捕获、比较寄存器1低8位
sfr PCAPWM0=0XF2;//模块0的PWM寄存器
sfr PCAPWM1=0XF3;//模块1的PWM寄存器
sfr AUXR=0X8E;//多路开关寄存器
sfr BRT=0X9C;//独立波特率发生器
sfr P1ASF=0X9D;//P1口模拟通道选择寄存器
sfr ADC_CONTR=0XBC;//ADC控制寄存器
sfr ADC_RES=0XBD;//ADC结果寄存器高8位
sfr ADC_RESL=0XBE;//ADC结果寄存器低2位
sfr P4SW=0XBB;//设置P4.4/5/6引脚为IO口
sfr P4=0XC0;
sfr IAP_CONTR=0XC7; //与复位相关寄存器
sfr AUXR1=0XA2;//可以将P1口迁移到P4口
sbit EADC=IE^5;//ADC中断允许位
sbit CR=CCON^6;//PWM时钟输入位
sbit b1=P2^3;//继电器——左——上前12V
sbit b2=P2^2;//继电器——左——下后12V
sbit b3=P2^0;//继电器——左——角度
sbit b4=P2^1;//继电器——左——距离
sbit b11=P2^6;//继电器——右——上前12V
sbit b21=P2^7;//继电器——右——下后12V
sbit b31=P2^4;//继电器——右——角度
sbit b41=P2^5;//继电器——右——距离
sbit trig1=P1^5;// j9 6
sbit echo1=P1^4;// 5
sbit trig2=P1^7;// 8
sbit echo2=P1^6;// 7
sbit trig3=P0^3;// 10
sbit echo3=P0^2;// 9
sbit trig4=P0^5;// 12
sbit echo4=P0^4;// 11
sbit d=P0^6;//灯——手动和自动选择指示灯
sbit d1=P0^7;//灯——亮表示左腿调平机构到位
sbit d2=P4^6;//灯——亮表示右腿调平机构到位
sbit w11=P0^0;//左电机方向
sbit w21=P0^1;//右电机方向
sbit Q3=P4^4;//左电机开关
sbit Q4=P4^5;//上升
sbit Q5=P3^6;//下降
sbit Q6=P3^4;//右电机开关
sbit pxx=P4^0;//多机通信判断是否有人占用T总线
int c1,m1,m2,m3;//m1上位机发送的角度值,m2上位机发送的前后距离值,m3上位机发送的上升距离值,
float a0,a1,a2,a3,b,b01;
bit dbzh,c5,c51,tzb=0;
unsigned char kzh;//kzh点动控制数据
float ceju(int b) //测距离
{ int k=0;float a;
// ES=0;
loop0:
TH0=0X00;
TL0=0X00;
if(b==1)//左腿——前后距离测量
{
trig1=1;
k++;k++;k++;k++;k++;k++;k++;k++;k++;k++;
trig1=0;
while(!echo1);
TR0=1;
while(echo1);
a=TH0*256+TL0;
a=a*12*17;
TR0=0;
}
if(b==2)//右腿——前后距离测量
{
trig2=1;
k++;k++;k++;k++;k++;k++;k++;k++;k++;
trig2=0;
while(!echo2);
TR0=1;
while(echo2);
a=TH0*256+TL0;
a=a*12*17;
TR0=0;
}
if(b==3)//左腿上升下降距离
{
trig3=1;
k++;k++;k++;k++;k++;k++;k++;k++;k++;
trig3=0;
while(!echo3);
TR0=1;
while(echo3);
a=TH0*256+TL0;
a=a*12*17;
TR0=0;
}
if(b==4)//右腿上升下降距离
{
trig4=1;
k++;k++;k++;k++;k++;k++;k++;k++;k++;
trig4=0;
while(!echo4);
TR0=1;
while(echo4);
a=TH0*256+TL0;
a=a*12*17;
TR0=0;
}
a=(a/11059.2)+0.7; //修正误差
if(a<2) goto loop0;
return a;
//ES=1;
}
float jiaodu(int b) // 角度测量
{ char i;float a1;
if(b==1) ADC_CONTR=0XEA;
else ADC_CONTR=0XEB;
i++;i++;//可以没有,有是为了读取ADC_CONTR时更加可靠;
while(!(ADC_CONTR&0X10));
ADC_CONTR=0XE0;
a1=(ADC_RES*4+ADC_RESL)*3.26/1024;
if(b==1) a1=-38.141*a1*a1*a1*a1+101.23*a1*a1*a1-25.47*a1*a1-201.9*a1+274.58;//zuo角度传感器
else a1=-31.349*a1*a1*a1*a1+91.498*a1*a1*a1+7.381*a1*a1-306.34*a1+383.6;//右角度传感器
return a1;
}
void songxian(float a) // 串口送显
{ float b1,c1;int b,c;char data x[8],i;
c1=modf(a,&b1);
b=(int)(b1);
c=(int)(1000*c1);
x[0]=0x30+b/100;
x[1]=0x30+b/10-10*(b/100);
x[2]=0x30+b-10*(b/10);
x[3]=0x2e;
x[4]=0x30+c/100;
x[5]=0x30+c/10-10*(c/100);
x[6]=0x20;;
x[7]='\0';
// ES=0; //关闭中断,采用查询发送,数据传输更快
for(i=0;i<8;i++)
{ if((x[i]==0x30)&&(i<2))
{ if(!(x[0]==0x30))
{ SBUF=x[i];
while(!TI);
TI=0;
}
else
{ SBUF=0x20;
while(!TI);
TI=0;
}
}
else { SBUF=x[i];
while(!TI);
TI=0;
}
}
// ES=1;
}
void delay(int a)
{
int i,j;
for(i=1;i<a;i++)
for(j=1;j<=500;j++);
}
void anjiankongzhi(char i) //手动控制模块
{
int k,j;
d=0;
while(1)
{
for(k=1;i<200;k++)
for(j=1;j<=500;j++);
a0=ceju(1);
a1=ceju(2);
a2=ceju(3);
a3=ceju(4);
b=jiaodu(1);
b01=jiaodu(2);
if(i==1) // 手动控制--左右腿同步上下移
{
/* a=ceju(3);// 左腿距离
songxian(a);
a=ceju(4);// 右腿距离
songxian(a);*/
if(Q3==0) CCAPM0=0X42;
else CCAPM0=0X40;
if(Q6==0) CCAPM1=0X42;
else CCAPM1=0X40;
if(Q4==0) {w11=1;w21=1;while(!Q4);}
if(Q5==0) {w11=0;w21=0;while(!Q5);}
}
if(i==2)//左腿下模块控制
{
/* a=ceju(1);// 左距离
songxian(a);
a=jiaodu(1); //左角度
songxian(a); */
if(Q6==0) { b1=1;b2=0;b3=0; }//角度向上走
if(Q5==0) { b1=0;b2=1;b3=0; }//角度向下走
if(Q3==0) { b1=1;b2=0;b4=0; }//距离向前走
if(Q4==0) { b1=0;b2=1;b4=0; }//距离向后走
if((Q6==1)&&(Q5==1)&&(Q3==1)&&(Q4==1)) {b1=1;b2=1;b3=1;b4=1;}
}
if(i==3)//右腿下模块控制
{
/* a=ceju(2);// 右距离
songxian(a);
a=jiaodu(2); //右角度
songxian(a); */
if(Q6==0) { b11=1;b21=0;b31=0; }//角度向上走
if(Q5==0) { b11=0;b21=1;b31=0; }//角度向下走
if(Q3==0) { b11=1;b21=0;b41=0; }//距离向前走
if(Q4==0) { b11=0;b21=1;b41=0; }//距离向后走
if((Q6==1)&&(Q5==1)&&(Q3==1)&&(Q4==1)) {b11=1;b21=1;b31=1;b41=1;}
}
}
}
void s1() interrupt 4 //中断接收数据,能提高实时性,发送采用查询更快
{
int zh,i,j;
bit pb;
ES=0;
if(d==0){pb=1;}
else pb=0;
if(RI==1)
{
RI=0;
SM2=0;
zh=SBUF;
if(DIZHI==zh)
{
CCAPM0=0x40; // 左腿停止工作 防止在接收数据期间发生碰撞
CCAPM1=0x40; // 右腿停止工作 防止在接收数据期间发生碰撞
b1=1;b2=1;b3=1;b4=1; b11=1;b21=1;b31=1;b41=1;//让所有继电器停止工作,防止位姿机构卡死
while(!RI);
RI=0;
zh=SBUF;// 接收数据包标志位
if(dbzh!=1)
{
switch(zh)//自动控制接收数据模块
{
case 0x31: while(RI==0);
RI=0;
m3=SBUF-0x30;//接收抬高控制数据
while(RI==0);
RI=0;
m2=SBUF-0x30;//接收位姿伸缩控制数据
while(RI==0);
RI=0;
m1=SBUF-0x30;//接收位姿角度控制数据
while(pxx==0);
pxx=0;
TB8=1;SBUF=DIZHI;
while(!TI);TI=0;
TB8=0;SBUF=0x31;
while(!TI);TI=0;
songxian(a2);songxian(a3);
songxian(a0);songxian(b);
songxian(a1);songxian(b01);
songxian(0);songxian(0);
TB8=0;SBUF='S' ;while(!TI);TI=0;
pxx=1;
case 0x32:if((c5!=0)||(c51!=0)||(pb==1))//c5=0;c51=0; 表示所有控制指令已经完成
{
while(pxx==0);
pxx=0;
TB8=1;SBUF=DIZHI;
while(!TI);TI=0;
TB8=0;SBUF=0x32;
while(!TI);TI=0;
songxian(a2);
songxian(a3);
songxian(a0);
songxian(b);
songxian(a1);
songxian(b01);
songxian(0);
songxian(0);
TB8=0;SBUF='S' ;while(!TI);TI=0;
pxx=1;
break;
}
else
{
while(pxx==0);
pxx=0;
TB8=1;SBUF=DIZHI;
while(!TI);TI=0;
TB8=0;SBUF=0x33;
while(!TI);TI=0;
songxian(a2);songxian(a3);
songxian(a0);songxian(b);
songxian(a1);songxian(b01);
songxian(0);songxian(0);
TB8=0;SBUF='S' ;while(!TI);TI=0;
pxx=1;
break;
}
case 0x35: d=0; //在多机情况下,表示烧写程序使用
for(i=0;i<5000;i++)
for(j=0;j<500;j++);
d=1;
IAP_CONTR=0x60; // 与复位相关的操作
break;
}
}
}
TI=0;SM2=1;
}
ES=1;
}
void main()
{
float d11,d12,d13;
int i,j,k,m,bzh=0;
bit e3,e4;
//初始化
BRT=0XFD;
AUXR=0X11;
TMOD=0X01;
SCON=0Xf8;
P1ASF=0X0C; //记住一定要把当ADC通道的引脚一定要值1;
ADC_CONTR=0XE0;
EADC=0;
EA=1;
ES=1;
trig1=0;
echo1=1;
trig2=0;
echo2=1;
trig3=0;
echo3=1;
trig4=0;
echo4=1;
CMOD=0X00; //控制输出速度
CL=0;
CH=0;
CCAP1H=CCAP1L=0X80;
CCAP0H=CCAP0L=0X80;
PCAPWM0=0;
PCAPWM1=0;
CCAPM0=0X40;
CCAPM1=0X40;
AUXR1=0X40;//将PWM口搬迁到P4口
CR=1;
P4SW=0X70;
pxx=1;
IAP_CONTR=0x40; //与复位相关的操作
b1=1;b2=1;b3=1;b4=1;d=1;d1=1;d2=1;b11=1;b21=1;b31=1;b41=1;
dbzh=0;
for(k=0;k<6;k++)//手动和自动选择部分
{ m++;d=m%2;
for(i=0;i<600;i++)
for(j=0;j<1000;j++);
if(Q3==0) { while(!Q3); anjiankongzhi(1); }//抬高机构按键
if(Q6==0) { while(!Q6); anjiankongzhi(2); }//左位姿调节机构按键
if(Q5==0) { while(!Q5); anjiankongzhi(3); }//右位姿调节机构按键
if(Q4==0) { while(!Q4); dbzh=1;break; }//上位机点动
}
d=1;
i=0;
while(1)//空循环
{; }
}
}
复制代码
作者:
chaoxin
时间:
2018-6-12 11:46
有可能是内存泄漏导致
欢迎光临 (http://www.51hei.com/bbs/)
Powered by Discuz! X3.1