打印

pic16f877单片机,菜鸟一个,跪求帮助啊

[复制链接]
1766|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
qijiantao|  楼主 | 2013-1-9 16:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
pic16f877单片机,想实现一个过程的循环控制,可是循环几次就不能正常循环了,复位后又可以正常循环,不过也不能循环很多次。循环运行进程的条件有采集进来的温度和压力控制
沙发
qijiantao|  楼主 | 2013-1-9 16:57 | 只看该作者
#include<pic.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>//标准库头文件
//**************定义变量及函数******
#define P0      101.325         //标况压力Kpa
#define T0      293.15       //标况温度标准摄氏度
unsigned int cirdirect=5,closflag1=0,closflag2=0,closflag3=0,closflag4=0,closflag5=0,closflag6=0,loopflag=0,timeflag,i;
double Pf_num[3],Th_num[3],Ps_num[3],Pa_num[3];
double temp4=0.0,temp3=0.0,temp5=0.0,w=0.0,tem3=0.0,h=0.0,tem4=0.0,tem5=0.0;
double Th=0.0,Pw=0.0,Pf=0.0,Pa=0.0,Ps=0.0,a=0.0,b=0.0,e=0.0,f=0.0;
union adres2      //采用共同体存AD结果
{     unsigned int y2;
        unsigned char adre2[2];  
}adresult2;

void delay(unsigned int x)//约x ms延时,两个延时程序定时时间相同,有时中断和主程序中用同一个延迟的话可能编译不成功,所以用两个
{   
     unsigned int m;
     for(m=x*12;m>0;m--);
}

void yc(unsigned int y)//约x ms延时
{
    unsigned int l,n;
        for(l=y;l>0;l--)
        for(n=50;n>0;n--);
}
void sysinit()
{
        TRISA=0x2F;//0010 1111,1输入,0输出
        TRISB=0xF7;//1111 0111
        TRISC=0x00;       
    TRISD=0x00;
    TRISE=0x07;//0000 0111
        PORTA=0x00;
        PORTC=0x00;
    PORTD=0x00;
    RB3=0;
    RE0=0;
}

void interinit()//中断初始化
{
    INTEDG=0; //INT上升沿触发
    INTCON=0x50;//01010000
    PIE1=0x01;//00000001使能TMR1中断,
    PIR1=0X00;
    PIE2=0X00;
    PIR2=0X00;
    T1CON=0X20;        //4分频,内部时钟FOSC/4
    TMR1IF=0;
    TMR1H=0X00;
    TMR1L=0X00;//定时2s
}

void stateacq()//上电状态采集
{
    if(RB1==1)
     {
      cirdirect=0;//反循环,阀门已经闭合
      closflag6=1;
     }
    else
     cirdirect=1;//正循环
    if((RB4==1)&&(RB5==1)&&(RB6==1)&&(RB7==1))
      {
       closflag1=1;
       closflag2=1;
      }
    else
      closflag1=0;  
}
void keyscan()
{
  /* if(RB0==1)
   {
     stateacq();
     TMR1ON=1;
     GIE=1;
     loopflag=1;
   }*/
  if(RB0==0)
   {
     stateacq();
     //TMR1ON=1;
     // GIE=1;
     //loopflag=1;
   }
  else
   {
    TMR1ON=0;
    GIE=0;
    loopflag=0;
    RB3=0;
    RD4=0;
    RD5=0;
    RD6=0;
    RD7=0;
   }
}

void Th1_AD()   //冷凝器温度AD转换
{
   ADCON0=0B00000001; //RA0通道  
   ADCON1=0B10001001;//A/D结果右对齐,参考电压为VDD/VSS,RE0,RA0,RA1,RA2,RA3,RA5
   delay(10);
   for(i=0;i<3;i++)
  {
   GO_DONE=1;
   while(GO_DONE) continue;
   adresult2.adre2[0]=ADRESL;
   adresult2.adre2[1]=ADRESH;
   Th_num[i]=adresult2.y2;
   delay(10);
   }
   h=(Th_num[0]+Th_num[1]+Th_num[2])/3.0;
   Th=150.0*(5*h/1023.0-1.25)/3.75;

    if(Th<25.0)
     {
       RB3=1; //打开尾气加热
       RD6=0;//关水泵
       RD7=1;//开风扇
       loopflag=0;
     }
    else
     {  
      if(Th<40.0&&Th>=25.0)
        {
         RB3=1;//开尾气
        }
      else
        {
         RB3=0;//关尾气
        }
       PORTD|=0XC0;//开水泵 //开风扇
       loopflag=1;
       TMR1ON=1;
       GIE=1;
     }
}

void Th2_AD()   //冷凝器温度AD转换
{
   ADCON0=0B00000001; //RA0通道  
   ADCON1=0B10001001;//A/D结果右对齐,参考电压为VDD/VSS,RE0,RA0,RA1,RA2,RA3,RA5
   delay(10);
   for(i=0;i<3;i++)
  {
   GO_DONE=1;
   while(GO_DONE) continue;
   adresult2.adre2[0]=ADRESL;
   adresult2.adre2[1]=ADRESH;
   Th_num[i]=adresult2.y2;
   delay(10);
   }
   h=(Th_num[0]+Th_num[1]+Th_num[2])/3.0;
   Th=150.0*(5*h/1023.0-1.25)/3.75;

    if(Th<15.0)
     {
       RB3=1; //打开尾气加热
       RD6=0;//关水泵
       RD7=1;//开风扇
     }
    else
     {
      if(Th<30.0&&Th>=15.0)
        {
         RB3=1;//开尾气
        }
      else
        {
         RB3=0;//关尾气
        }
       PORTD|=0XC0;//开水泵 //开风扇
     }
}
void Pw_AD()
{
     ADCON0=0B00100001; //RA5通道  
     ADCON1=0B10001001;//A/D结果右对齐,参考电压为VDD/VSS,RE0,RA0,RA1,RA2,RA3,RA5
     delay(10);//26ms
     GO_DONE=1;
         while( GO_DONE) continue;
         adresult2.adre2[0]=ADRESL;
     adresult2.adre2[1]=ADRESH;
     w=(adresult2.y2/1023.0)*5.0;
     Pw=700.0/3.85*(w-0.65);
}
void Pf_AD()//发生器AD转换
{
     ADCON0=0B00010001; //RA2通道  
     ADCON1=0B10001001;//A/D结果右对齐,参考电压为VDD/VSS,RE0,RA0,RA1,RA2,RA3,RA5
     delay(10);//26ms
     for(i=0;i<3;i++)
    {
     GO_DONE=1;
         while( GO_DONE) continue;
         adresult2.adre2[0]=ADRESL;
         adresult2.adre2[1]=ADRESH;
     Pf_num[i]=adresult2.y2;
     delay(10);
    }
    tem3=(Pf_num[0]+Pf_num[1]+Pf_num[2])/3.0;
     temp3=(tem3/1023.0)*5.0;
     Pf=1600.0/3.85*(temp3-0.65);
}

void Ps_AD()//发生器AD转换
{
    ADCON0=0B00101001; //RE0通道  
    ADCON1=0B10001001;//A/D结果右对齐,参考电压为VDD/VSS,RE0,RA0,RA1,RA2,RA3,RA5
    delay(10);//26ms
    for(i=0;i<3;i++)
    {
    GO_DONE=1;
    while( GO_DONE) continue;
        adresult2.adre2[0]=ADRESL;
        adresult2.adre2[1]=ADRESH;
    Ps_num[i]=adresult2.y2;
    delay(10);
    }
    tem4=(Ps_num[0]+Ps_num[1]+Ps_num[2])/3.0;
    temp4=(tem4/1023.0)*5.0;
    Ps=1600.0/3.85*(temp4-0.65);
}

void Pa_AD()//吸收发生器AD转换
   {
    ADCON0=0B00011001; //RA3通道  
    ADCON1=0B10001001;//A/D结果右对齐,参考电压为VDD/VSS,RE0,RA0,RA1,RA2,RA3,RA5
    delay(10);//26ms
    for(i=0;i<3;i++)
   {
    GO_DONE=1;
    while( GO_DONE) continue;
    adresult2.adre2[0]=ADRESL;
    adresult2.adre2[1]=ADRESH;
    Pa_num[i]=adresult2.y2;
    delay(10);
   }
   tem5=(Pa_num[0]+Pa_num[1]+Pa_num[2])/3.0;
   temp5=(tem5/1023.0)*5.0;
   Pa=1600.0/3.85*(temp5-0.65);
}
void LLD()
{
   if(RB2==0)
   RD5=1;
   else
   RD5=0;
}

void gy()//过压保护
{
if(Pw>500.0||Pa>1400.0||Pf>1400.0||Ps>1400.0)
  PORTB=0;
}

void ZXH()
{  
   if(closflag1==0)
     {
      RD4=0;
      PORTC=0XA5; //红灯 //红灯
    // }
   //if((RB4==1)&&(RB5==1)&&(RB6==1)&&(RB7==1))
    //{
      closflag2=1;
      closflag1=1;
     }

    if(closflag2==1)
     {
       b=Pf-Pa;
       if(b>0.0)
       {
         RD0=1;
         RD1=0;
         RD2=0;
         RD3=1;//右斜左
         closflag2=0;
         closflag3=1;
       }
      }
    else NOP();
   if(closflag3==1)
    {   
        //RD5=1;
        f=Pf-Ps;
        if((Pa<=150.0)&&(f>=0.0))
        {
          RD4=1;
          closflag3=0;
          closflag4=1;
          //RD5=0;
        }
        else
        {
          delay(2);
        }   
    }
    else NOP();
    if(closflag4==1)
    {
      if(Pa>150.0)
       {
         RD4=0;
         PORTC=0X5A;//绿灯
         closflag5=1;
         closflag4=0;
       }
     }
    else NOP();
   if(closflag5==1)
   {
     a=Pa-Pf;
    if(a>0.0)
     {
      cirdirect=0;
      closflag5==0;
      closflag6=1;
     }
   }
   else NOP();
}

  
void FXH()
{  
   if(closflag6==1)
   {
     a=Pa-Pf;
     if(a>0.0)
     {
        RD0=0;
        RD1=1;
        RD2=1;
        RD3=0;
        closflag3=1;
        closflag6=0;
     }
   }
   else NOP();
   if(closflag3==1)
   {  
     e=Pa-Ps;
     if((Pf<=150.0)&&(e>=0.0))
     {
        RD4=1;
        closflag3=0;
        closflag4=1;
     }
     else
     {
       delay(2);
     }
   }
  else NOP();
  if(closflag4==1)
   {
     if(Pf>150.0)
     {
      RD4=0;
      PORTC=0XA5;//红灯
      closflag4=0;
      closflag5=1;
    }
  }
   else NOP();
  if(closflag5==1)
  {
    b=Pf-Pa;
    if(b>0.0)
    {
     cirdirect=1;
     closflag5=0;
     closflag2=1;
    }
  }
  else NOP();
}

void TMR1INT()
{
   TMR1IF=0;
   TMR1H=0x00;
   TMR1L=0x00;
   timeflag=1;
}
void RB0INT()
{
   
   GIE=0;
   TMR1ON=0;
   INTF=0;
   TMR1IF=0;
   loopflag=0;
   RB3=0;
   RD6=0;
   RD7=0;
   RD4=0;
   RD5=0;
}
void interrupt INTS(void)
{
   if(TMR1IF==1) TMR1INT();
   else if(INTF) RB0INT();
}
void main()
{
   sysinit();//端口设置,终端使能
   interinit();        
   while(1)
   {  
     keyscan();//然后先由中断判断是否进入循环
     if(RB0==0)
     {
      Th1_AD();
     }
     delay(2500);
     while(1)
     {
      if(timeflag==1)
      {
       timeflag=0;
       Th2_AD();
       Pw_AD();
       Pf_AD();
       Ps_AD();
       Pa_AD();
       LLD();
       gy();
       cirdirect=cirdirect;
      }  
     if(cirdirect==0)
       {
         FXH();     
       }
     if(cirdirect==1)
      {
        ZXH();
     }
   }
  }

使用特权

评论回复
板凳
Breming| | 2013-1-12 17:00 | 只看该作者
不要动不动就把整个程序COPY上来,设置断点看看为什么跳出回循环

使用特权

评论回复
评论
NE5532 2013-1-12 21:12 回复TA
严重同意 
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

2

帖子

0

粉丝