找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1332|回复: 0
打印 上一主题 下一主题
收起左侧

求大神帮找错误,谢谢,并祝新年快乐!

[复制链接]
跳转到指定楼层
楼主
ID:162963 发表于 2017-1-26 14:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
都40+的人了,还在学单片机,很多问题的理解能力都不比年轻人,自己设计了一个3路测温程序,用的STC12C5A60S2单片机,10位AD转换值,思路是先校准100℃和0℃的值求出K值,再来算对应的温度,问题是现在只显示0.0℃。传感器是PT100。请大神帮看一下程序的问题在哪里,尽量解释的清楚些,谢谢!
************************************************************************************
#include <STC12C5A60S2.H>
#define  uchar   unsigned  char
#define  uint    unsigned  int
sbit AB_164=P0^6;
sbit CLK_164=P0^7;
sbit I2C_SDA=P3^7;
sbit I2C_SCL=P3^6;
uchar call_lop;
uint xdata MAX_T;
float xdata TE_A;
float xdata TE_B;
float xdata TE_C;
uint xdata A_0;
uint xdata A_100;
float xdata A_k=0;
uint  xdata B_0;
uint xdata B_100;
float xdata B_k=0;
uint xdata C_0;
uint xdata C_100;
float xdata C_k=0;
sbit KEY=P4^5;



uchar  code LED_TAB[7]={0x1f,0x2f,0x37,0x3b,0x3d,0x3e,0x3f};//数码管7个位
uchar  code BCD_TAB[11]={0x03,0x9F,0x25,0x0D,0x99,0x49,0x41,0x1F,0x01,0x19,0xff};//0~9,0XFF是关闭
uchar  code CCBD_TAB[10]={0x31,0xFD,0x91,0x61,0xF5,0x11,0xC1,0x63,0xe3};
                   // P    -    H     E    R    A    B    C    L
uchar xdata DISP_SAVE[6]={0X03,0X03,0X03,0X03,0X03,0Xff};//要送显的数据寄存器

/*****************************************************************************************************
****************短暂延时****************************************************************/
void   delay1(uchar tt)
{
   while(tt>0)
   tt--;
}


/*********************************************************************************
**********74hc164操作************************************************************/
void  write_164(uchar lx)
{
    uchar  i;
        uchar  j=0;
        j=lx;
        for(i=0;i<8;i++)
        {
           CLK_164=0;
           if((j&0x01)==0x01)
           {
              AB_164=1;
           }
           else
           {
              AB_164=0;
           }
           delay1(10);
           CLK_164=1;
           j=j>>1;
           delay1(5);
        }
       
}

void   disp_all(void)
{
    uchar  i;
        uchar j;
        for(j=0;j<10;j++)
        {
          for(i=0;i<6;i++)
          {  
             P0=0X3F;
             write_164(DISP_SAVE[i]);//将要显示的数据写入164中
                 
             P0=LED_TAB[i];//选择要显示的位
                 delay1(300);
                 P0=0X3F;
          }
         }
        write_164(0xff);
}

/***************************************************************************
*******24C04***************************************************************/
void  MI2C_START(void)//I2C开始信号
{
  I2C_SDA=1;
  delay1(4);
  I2C_SCL=1;
  delay1(4);
  I2C_SDA=0;
  delay1(4);
  I2C_SCL=0;
}
void  MI2C_STOP(void)//I2C停止信号
{
  I2C_SDA=0;
  delay1(4);
  I2C_SCL=1;
  delay1(4);
  I2C_SDA=1;
  delay1(4);
  I2C_SCL=0;
}

void  MI2C_R_ACK(void)//应答
{
  uchar  i;
  I2C_SCL=1;
  delay1(4);
  while((I2C_SDA==1)&&(i<250))
  i++;
  I2C_SCL=0;
  delay1(4);
}

void   MI2C_UN_ACK(void)//主机不应答
{
  I2C_SDA=1;
  delay1(4);
  I2C_SCL=1;
  delay1(4);
  I2C_SCL=0;
}
void  MI2C_WRITE(uchar I2C_data)//写一个字节
{
    uchar i,j;
        j=I2C_data;//0xA0
        for(i=0;i<8;i++)
        {
          I2C_SCL=0;
          delay1(4);
          if((j&0X80)==0X80)//从最高位开始写
      {
      I2C_SDA=1;//如果欲写入数据为1,就将数据线置1
      }
      else
          {
          I2C_SDA=0;//如果欲写入数据为0,就将数据线写0
          }
          delay1(4);
          I2C_SCL=1;//时钟线做一个上升沿,将一位数据写入
          delay1(4);
          j=j<<1;  //数据左移一位,将下次要写入的位数据移到最高位
        }
        I2C_SCL=0; //将SCL=0,以准备通过上升沿将数据写入
}

uchar  MI2C_READ(void)
{
     uchar k;      //1个字节要分8次读出,需要定义一个寄存器用来计数
     uchar t=0;    //定义一个寄存器用保存读出数据
     for(k=0;k<8;k++)      //做一个8次的循环,每次读入1位,需要读8次
     {
         t=t<<1;           //数据左移一位,空出最低位以准备保存读入的一位数据
         I2C_SDA=1;        //将SDA写1准备读
         I2C_SCL=1;        //将SCL=1,做个上升沿准备读一位数据
          delay1(5);      //略做延时
         if(I2C_SDA==1)        //读一位数据,并判断
         {
             t=t|0x01;     //如果读入数据为1,就将接收缓冲区最低一位置1
         }
         else
         {
             t=t&0xfe;     //如果读入数据为0,就将接收缓冲区最低一位写0
         }
         I2C_SCL=0;            //SCL恢复为0,结束一位数据读操作
          delay1(5);       //略做延时
     }
     return t;             //将读入的一个字节返回
}

uchar   I2C_READ_ONE(uchar  slv_addr,uchar data_addr)//I2C读数据
{
   uchar  i=0;
   MI2C_START();//开始
   MI2C_WRITE(slv_addr);//写I2C地址
   delay1(20);
   MI2C_R_ACK();//应答
   MI2C_WRITE(data_addr);//写数据地址
   MI2C_R_ACK();//应答
   MI2C_START();//开始
   MI2C_WRITE(slv_addr|0x01);
   MI2C_R_ACK();//应答
   i=MI2C_READ();//读取的数据给i
   MI2C_UN_ACK();//主机不应答(结束读取)
   MI2C_STOP();//停止       
   return  i;
}
void  I2C_WRITE_ONE(uchar slv_addr,uchar data_addr,uchar A_data)//I2C写数据
{
    uchar i=0;
        i=A_data;
        MI2C_START();//开始
        MI2C_WRITE(slv_addr);//写I2C地址
        MI2C_R_ACK();//应答
        MI2C_WRITE(data_addr);//写数据地址
        MI2C_R_ACK();//应答
        MI2C_WRITE(i);//写数据
    MI2C_R_ACK();//应答
        MI2C_STOP();//停止
        delay1(200);
}
/**************************************************************************************
**********AD转换**********************************************************************/
void AD_init(void)
{
        P1ASF=0xe0;//将P1.5,P1.6,P1.7做AD口使用
        ADC_RES=0;
        ADC_RESL=0;
        ADC_CONTR=0x80;//将AD转换控制寄存器电源打开,360个时钟周期转换一次,准备转换

     delay1(50);//必须要延时
}
uint ADC_GET(unsigned char  channel)//channel是通道选择
{
   uint   temp=0;
   ADC_CONTR=0x88|channel;//打开选通通道准备转换
          delay1(50);
        while(!(ADC_CONTR&0x10));//判断ADC_FLAG是否为1,如果是1,转换结束
   ADC_CONTR&=0xe7;
        temp=(ADC_RES*4)+ADC_RESL;
   return  temp;
   
}
/*****************************************************************************
****************************************************************************/
float AD_work(unsigned char channel)
  {     

  uint AD_val;
  float tmp;

   AD_val=ADC_GET(channel);
       
   if(channel==0x07)//A相温度地址
        {
          if(AD_val>=A_0)//
          {
            tmp=(AD_val-A_0)*A_k;
           }
        }
        else if(channel==0x06)//B相温度
        {
          if(AD_val>=B_0)
          {
                tmp=(AD_val-B_0)*B_k;
          }
        else if(channel==0x05)//C相温度
        {
          if(AD_val>=C_0)
          {
            tmp=(AD_val-C_0)*C_k;
          }
        }
  }
          return  tmp;
}

  uchar   GET_KEY(void)//按键扫描函数
{
   uchar  i=0;
   uchar  j=0;
   uchar  k=10;
   for(i=0;i<6;i++)//循环6次,依次显示6个数码管位
   {
       P0=0X3F;//将P0口的164AB脚和CLK脚置0,数码管位全置1
           P0=LED_TAB[i];//顺序打开数码管位
       delay1(500);
           if(KEY==0)//有键按下
           {
              delay1(250);//稍做延时
                  if(KEY==0)//再次判断有按键按下
                  {
                           disp_all();
                           P0=0X3F;
                   P0=LED_TAB[i];
                           delay1(500);

                         }
                         while(KEY==0);
                         k=i;
                  }
           }
   
   return  k;
}

void   Tiaoshichengxu(void)
{
    uchar  i=0;
        uchar  tt=0;
        uchar  call_lop=0;
        uint   tmp1=0;
        uchar  tmp2=0;
    if(P20==0)
        {
            do
                {
                  tt=GET_KEY();
                  switch(tt)
                  {
                     case 0:if(call_lop<5)
                                {
                                          call_lop++;
                                        }
                                        else
                                        {
                                          call_lop=0;
                                        }break;
                         case 1:if(call_lop==0)
                                {
                                           tmp1=ADC_GET(0x07);//将A相0℃的温度赋值给tmp1
                                           delay1(20);
                                           tmp2=tmp1&0x00ff;//截取AD转换值低8位赋值给tmp2
                                           I2C_WRITE_ONE(0xa0,0x02,tmp2);//AD转换值低8位存入24c04的0x02地址中
                                           delay1(200);
                                           delay1(200);
                                           tmp2=(tmp1&0xff00)>>8;//取AD转换值高2位赋值给tmp2
                                           delay1(20);
                                           I2C_WRITE_ONE(0xa0,0x03,tmp2);//AD转换值高2位存入24c04的0x03地址中
                                           delay1(200);
                                           delay1(200);
                                          
                                        }
                                        else if(call_lop==1)
                                        {
                                           tmp1=ADC_GET(0x06);//将B相0℃的温度赋值给tmp1
                                           delay1(20);
                                           tmp2=tmp1&0x00ff;//取AD转换值低8位赋值给tmp2
                                           I2C_WRITE_ONE(0xa0,0x04,tmp2);//AD转换值低8位存入24c04的0x04地址中
                                           delay1(200);
                                           delay1(200);
                                           tmp2=(tmp1&0xff00)>>8;//取AD转换值高2位赋值给tmp2
                                           I2C_WRITE_ONE(0xa0,0x05,tmp2);//AD转换值高2位存入24c04的0x05地址中
                                           delay1(200);
                                           delay1(200);
                                          
                                        }
                                        else if(call_lop==2)
                                        {
                                          tmp1=ADC_GET(0x05);//将C相0℃的温度赋值给tmp1
                                           delay1(20);
                                           tmp2=tmp1&0x00ff;//取AD转换值低8位赋值给tmp2
                                           I2C_WRITE_ONE(0xa0,0x06,tmp2);//AD转换值低8位存入24c04的0x06地址中
                                           delay1(200);
                                           delay1(200);
                                           tmp2=(tmp1&0xff00)>>8;//取AD转换值高2位赋值给tmp2
                                           I2C_WRITE_ONE(0xa0,0x07,tmp2);//AD转换值高2位存入24c04的0x07地址中
                                           delay1(200);
                                           delay1(200);
                                        }
                                        else if(call_lop==3)
                                        {
                                           tmp1=ADC_GET(0x07);//将A相100℃的温度赋值给tmp1
                                           delay1(20);
                                           tmp2=tmp1&0x00ff;//取AD转换值低8位赋值给tmp2
                                           I2C_WRITE_ONE(0xa0,0x08,tmp2);//AD转换值低8位存入24c04的0x08地址中
                                           delay1(200);
                                           delay1(200);
                                           tmp2=(tmp1&0xff00)>>8;//取AD转换值高2位赋值给tmp2
                                           delay1(20);
                                           I2C_WRITE_ONE(0xa0,0x09,tmp2);//AD转换值高2位存入24c04的0x09地址中
                                           delay1(200);
                                           delay1(200);
                                        }
                                        else if(call_lop==4)
                                        {
                                           tmp1=ADC_GET(0x06);//将B相100℃的温度赋值给tmp1
                                           delay1(20);
                                           tmp2=tmp1&0x00ff;//取AD转换值低8位赋值给tmp2
                                           I2C_WRITE_ONE(0xa0,0x0a,tmp2);//AD转换值低8位存入24c04的0x0a地址中
                                           delay1(200);
                                           delay1(200);
                                           tmp2=(tmp1&0xff00)>>8;//取AD转换值高2位赋值给tmp2
                                           delay1(20);
                                           I2C_WRITE_ONE(0xa0,0x0b,tmp2);//AD转换值高2位存入24c04的0x0b地址中
                                           delay1(200);
                                                 delay1(200);
                                        }
                                        else if(call_lop==5)
                                        {
                                           tmp1=ADC_GET(0x05);//将C相100℃的温度赋值给tmp1
                                           delay1(20);
                                           tmp2=tmp1&0x00ff;//取AD转换值低8位赋值给tmp2
                                           I2C_WRITE_ONE(0xa0,0x0C,tmp2);//AD转换值低8位存入24c04的0x0c地址中
                                           delay1(200);
                                           delay1(200);
                                           tmp2=(tmp1&0xff00)>>8;//取AD转换值高2位赋值给tmp2
                                           delay1(20);
                                           I2C_WRITE_ONE(0xa0,0x0D,tmp2);//AD转换值高2位存入24c04的0x0d地址中
                                           delay1(200);
                                           delay1(200);
                                        }
                                        break;
                  }
                  if(call_lop==0)
                  {
                     DISP_SAVE[0]=CCBD_TAB[8];//相位显示L
                     DISP_SAVE[1]=CCBD_TAB[5];//百位显示A
                         DISP_SAVE[2]=BCD_TAB[0];//十位显示0
                 DISP_SAVE[3]=BCD_TAB[0];//个位显示0
                 DISP_SAVE[4]=BCD_TAB[0];//小数位显示0
                  }
                  else if(call_lop==1)
                  {
                     DISP_SAVE[0]=CCBD_TAB[8];//相位显示L
                     DISP_SAVE[1]=CCBD_TAB[6];//百位显示B
                         DISP_SAVE[2]=BCD_TAB[0];//十位显示0
                 DISP_SAVE[3]=BCD_TAB[0];//个位显示0
                 DISP_SAVE[4]=BCD_TAB[0];//小数位显示0
                  }
                  else if(call_lop==2)
                  {
                     DISP_SAVE[0]=CCBD_TAB[8];//相位显示L
                     DISP_SAVE[1]=CCBD_TAB[7];//百位显示C
                         DISP_SAVE[2]=BCD_TAB[0];//十位显示0
                 DISP_SAVE[3]=BCD_TAB[0];//个位显示0
                 DISP_SAVE[4]=BCD_TAB[0];//小数位显示0
                  }
                  else if(call_lop==3)
                  {
                     DISP_SAVE[0]=CCBD_TAB[2];//相位显示H
                     DISP_SAVE[1]=CCBD_TAB[5];//百位显示A
                         DISP_SAVE[2]=BCD_TAB[1];//十位显示0
                 DISP_SAVE[3]=BCD_TAB[0];//个位显示0
                 DISP_SAVE[4]=BCD_TAB[0];//小数位显示0
                  }
                  else if(call_lop==4)
                  {
                     DISP_SAVE[0]=CCBD_TAB[2];//相位显示H
                     DISP_SAVE[1]=CCBD_TAB[6];//百位显示B
                         DISP_SAVE[2]=BCD_TAB[1];//十位显示0
                 DISP_SAVE[3]=BCD_TAB[0];//个位显示0
                 DISP_SAVE[4]=BCD_TAB[0];//小数位显示0
                  }
                  else if(call_lop==5)
                  {
                     DISP_SAVE[0]=CCBD_TAB[2];//相位显示H
                     DISP_SAVE[1]=CCBD_TAB[7];//百位显示C
                         DISP_SAVE[2]=BCD_TAB[1];//十位显示0
                 DISP_SAVE[3]=BCD_TAB[0];//个位显示0
                 DISP_SAVE[4]=BCD_TAB[0];//小数位显示0
                  }
                  disp_all();
        }
        while(P20==0);
  }
}

void   READ_JIAOZHUN(void)
{
    uchar  temp1;
        uint   temp2;
        temp1=0;
        temp2=0;
        temp1=I2C_READ_ONE(0xa0,0x03);//读A相0℃转换值高2位给temp1
        temp2=temp1;//赋值给temp2
        temp1=I2C_READ_ONE(0xa0,0x02);//读A相0℃转换值低8位给temp1
        A_0=(temp2<<8)|temp1;//合并成10位数据给A_0
        temp1=I2C_READ_ONE(0xa0,0x09);//读A相100℃转换值高2位给temp1
        temp2=temp1;//赋值给temp2
        temp1=I2C_READ_ONE(0xa0,0x08);//读A相100℃转换值低8位给temp1
        A_100=(temp2<<8)|temp1;//合并成10位数据给A_100
        temp2=A_100-A_0;
        A_k=100.0/temp2;//求出K值
        temp1=0;//清零
        temp2=0;//清零
        temp1=I2C_READ_ONE(0xa0,0x05);//读B相0℃转换值高2位给temp1
        temp2=temp1;//赋值给temp2
        temp1=I2C_READ_ONE(0xa0,0x04);//读B相0℃转换值低8位给temp1                 
        B_0=(temp2<<8)|temp1;//合并成10位数据给B_0
        temp1=I2C_READ_ONE(0xa0,0x0b);//读B相100℃转换值高2位给temp1
        temp2=temp1;//赋值给temp2
        temp1=I2C_READ_ONE(0xa0,0x0a);//读B相100℃转换值低8位给temp1
        B_100=(temp2<<8)|temp1;//合并成10位数据给B_100
        temp2=B_100-B_0;
        B_k=100.0/temp2;
        temp1=0;//清零
        temp2=0;//清零
        temp1=I2C_READ_ONE(0xa0,0x07);//读C相0℃转换值高2位给temp1
        temp2=temp1;//赋值给temp2
        temp1=I2C_READ_ONE(0xa0,0x06);//读C相0℃转换值低8位给temp1
        C_0=(temp2<<8)|temp1;//合并成10位数据给C_0
        temp1=I2C_READ_ONE(0xa0,0x0D);//读C相100℃转换值高2位给temp1
        temp2=temp1;//赋值给temp2
        temp1=I2C_READ_ONE(0xa0,0x0C);//读C相100℃转换值低8位给temp1
        C_100=(temp2<<8)|temp1;//合并成10位数据给C_100
        temp2=C_100-C_0;
        C_k=100.0/temp2;
       
}

void   FDshu_disp(float  ut)
{
    uchar  temp1=0;
        uchar  temp2=0;
        uchar  temp3=0;
        uchar  temp4=0;
        uint  lt;
        lt=ut;
        temp1=lt/100;
        if(temp1==0)
        {
           temp1=10;
        }
        temp2=(lt%100)/10;
        if(temp1==10&&temp2==0)
        {
           temp2=10;
        }
        temp3=lt%10;
        lt=ut*10;
        temp4=lt%10;
        DISP_SAVE[1]=BCD_TAB[temp1];
        DISP_SAVE[2]=BCD_TAB[temp2];
        DISP_SAVE[3]=BCD_TAB[temp3]&0xFE;//0xfe显示小数点
        DISP_SAVE[4]=BCD_TAB[temp4];
        disp_all();
}


void timer0() interrupt 1
{
  MAX_T++;

  if(MAX_T>6000)
  {
     MAX_T=0;
  }
   TL0 = 0xF0;                //设置定时初值
        TH0 = 0xD8;                //设置定时初值
}

void  main(void)
{
        AUXR &= 0x7F;                //定时器时钟12T模式
        TMOD &= 0xF0;                //设置定时器模式
        TL0 = 0xF0;                //设置定时初值
        TH0 = 0xD8;                //设置定时初值
        TF0 = 0;                //清除TF0标志
        TR0 = 1;        //定时器0开始计时
        EA  =1;    //开总中断
        ET0 =1;    //开定时器0中断       
  AD_init();
  write_164(0XFF);//74hc164初始化

  while(1)
  {
             Tiaoshichengxu();
   READ_JIAOZHUN();
                   TE_A=AD_work(0x07);//A相温度

                   TE_B=AD_work(0x06);//B相温度

                   TE_C=AD_work(0x05);//C相温度

        if(MAX_T<2000)
                        {
                          
                             DISP_SAVE[0]=CCBD_TAB[5];//相位显示A
                             FDshu_disp(TE_A);
                                          disp_all();
                           }
               
                        else if((MAX_T>=2000)&&(MAX_T<4000))
                        {
       
                              DISP_SAVE[0]=CCBD_TAB[6];
                              FDshu_disp(TE_B);
                                                 disp_all();
                           }
       
                        else if(MAX_T>=4000)
                        {
                              DISP_SAVE[0]=CCBD_TAB[7];
                              FDshu_disp(TE_C);
                                                disp_all();
                           }

                    
     }
}
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表