微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 大家来帮我看看这个温度控制系统的程序 有点不太懂

大家来帮我看看这个温度控制系统的程序 有点不太懂

时间:10-02 整理:3721RD 点击:

调试程序:(自定义头函数见附录Ⅰ)

#include  "C8051F020.h"

#include "absacc.h"

#include  "data_define.c"              

#include  "Init_Device.c"              

#include  "address.h"              //设备地址列表

#include  "keytable.h"                     //键盘的键值表

#include  "digtaltable.h"                  //数码管的编码表

static unsigned int DataT=0;               //16进制的A/D数据

static int DataTO=0;                       //10进制的温度数据

static unsigned int DataTI=0;              //10进制的目标温度(临时)

static unsigned int TargetT=0;             //10进制的目标温度

static char tp=0;                         //目标温度和当前温度的差值

static unsigned int sign=0;                //表示tp的正负号

static unsigned char Switch=0;             //开关键是否按下的标志

static unsigned int Input=0;               //输入

void delay(void);

void delay1(void);

void Display(const unsigned int,const unsigned int);

unsigned int Convert(const unsigned int);

unsigned int ReadT(void);

unsigned int ReadKey(void);

unsigned int ReadKeyS(void);

unsigned int Decode(unsigned int);

unsigned int ReadInput(void);

void Task(void);

void main(void)

{

       Init_Device();

       while(1)

       {

           ReadInput();                    //读取键盘

           Task();                         //对温度进行调整(主任务)

       }

}

unsigned int Convert(const unsigned int a)

{   

return (int) 95*a/0xff;               //返回值=输入数据*95/255 (取整数) 返回值范围(0~95)

   

}

unsigned int ReadT(void)

{

       C2=0;                               //向A/D转换器发出指令

       delay();                            //等待采样完成

       return C2;                          //返回采样数据数据

}

void Display(const unsigned int x,const unsigned int z)

{

           C13=DT3[z/10];                  //第三个数码管,显示第二个数字的个位

           C14=DT4[z%10];                  //第四个数码管,显示第二个数字的十位

           C11=DT1[x/10];                  //第一个数码管,显示第一个数字的个位

           C12=DT2[x%10];                  //第二个数码管,显示第一个数字的十位

}

void delay(void)                          //延时子程序

{

     long int i;

     for(i=0;i<0x1f0;++i) ;

}

void delay1(void)

{

     long int i;

     for(i=0;i<0x81f0;++i) ;

}

unsigned int ReadKeyS(void)

{

    unsigned char temp=0;

    unsigned char temp1=0;

    unsigned char i=0;

    temp=C43;                               //读取键盘第三行

    temp=0x1f&C43;                         //屏蔽高3位

    if(temp==0x1f)                         //如果没有按下,退出

    {

       return 0xff;

    }

    temp1=temp;                            //如有按下,则延时后再读一次,看看是不是抖动

    delay();

    temp=0x1f&C43;

    if(temp!=temp1)                        //两次读取值不同,说明是抖动,退出

    {

       return 0xff;

    }   

    if(temp==0x1e)                         //是第三行第一列的键,则返回K11(在keytable定义)

    {

       return K11;

    }

    if(temp==0x1d)                         //是第三行第二列的键,对Switch做求反操作,则返回K12(在keytable定义)

    {

       Switch=~Switch;

       return K12;

    }

}

unsigned int ReadKey(void)

{

    unsigned int temp=0;

    unsigned int i=0;

    while(1)

    {

       temp=0x1f&C41;                      //扫描第一行,看有无按下

       if(temp!=0x1f)                      //第一行如有有按下,则跳出while循环

       {

           i=0x0;

           break;

       }

       temp=0x1f&C42;                      //扫描第二行,看有无按下

       if(temp!=0x1f)                     //第二行如有有按下,则跳出while循环

       {   

           i=0x40;

           break;

       }

       temp=0x1f&C43;                     //扫描第三行,看有无按下

       if(temp!=0x1f)                     //第三行如有有按下,则跳出while循环

       {

           i=0x80;

           break;

       }

       temp=0x1f&C44;                     //扫描第四行,看有无按下

       if(temp!=0x1f)                     //第四行如有有按下,则跳出while循环

       {

           i=0xC0;

           break;

       }

       return 0xff;                        //都没有按下,返回0xff

    }

    return i|temp;                         //将高三位和低五位合并

}

unsigned int Decode(unsigned int a)        //对键值解码

{

    switch(a)

    {

       case K1:

       return 1;

       case K2:

       return 2;

       case K3:

       return 3;

       case K4:

       return 4;

       case K5:

       return 5;

       case K6:

       return 6;

       case K7:

       return 7;

       case K8:

       return 8;

       case K9:

       return 9;

       case K10:

       return 0;

       case K11:

       return 10;

       default:

       return 0xff;

      

    }

}

unsigned int ReadInput(void)

{

    unsigned int key=0;

    unsigned int i=0;

    unsigned int temp=0;

    key=ReadKeyS();                        //读取开关键是否按下

    i=Decode(ReadKeyS());                  //对读取的键值解码

    if(i!=10)                              //如果不等于开关键(10为开关键解码后的值),则不读数据,退出

    {

    return 0xff;

    }

    Display(0,DataTO);                     //数码管的输入区清零

    //delay1();

    while(1)

    {

       key=ReadKey();                     //读取第一个键值(十位)

       i=Decode(key);                     //解码

       if(i<10)                            //如果是前二行的键值,则更新DataTI(临时的输入数据)

       {

           DataTI=i;                       //更新DataTI

           Display(DataTI,DataTO);         //更新数码管,显示输入的数字

           break;

       }   

       Task();                            //和main()的那个Task()相同,目的是防止输入数据的时候单片机失去控温能力

    }

    while(1)

    {

       key=ReadKey();                     //读取键值

       if(key==0xff)                       //等键盘松开

       break;

       Task();

    }

    while(1)                    

    {

       key=ReadKey();                     //读取第二个键值(个位)

       i=Decode(key);                     //解码

       if(i<10)                            //如果是前二行的键值,则更新DataTI(临时的输入数据)

       {

           DataTI=DataTI*10+i;             //更新DateTI数据

           Display(DataTI,DataTO);         //更新数码管,显示输入的数字

           TargetT=DataTI;                 //更新目标温度(正式)

           break;

       }

       Task();

    }

    return DataTI;                         //返回输入的数据

   

}

void Task(void)

{

       DataT=ReadT();                     //读取A/D的数据

       DataTO=Convert(DataT);             //把A/D数据转化为10进制的温度数据

       if(DataTI>95)                       //如果温度大于95度,就修正为96度(95度时温度变送器为5V)

       {

           DataTI=95;

       }

       tp=TargetT-DataTO;                 //目标温度和目标温度的差值

       if(tp<0)                            //如果为负

       {

           tp=~tp+1;                       //求差值绝对值

           sign=1;                         //符号位标记为1(1为负数,0为正数)

       }

       else

       {

           sign=0;                         //符号位标记为0(1为负数,0为正数)

                  

       }

                                           //分三段控制,0~30度,31~70度,71~95度

       if(DataTO<31);                     //第一段

       {

           while(1)

           {

              if(tp<1)                     //如果差值为0,则令驱动器空载(0V)

              {

                  C3=0x80;

                  break;

              }

              if(tp<4&&sign==0)            //如果差值小于4且为正数,令驱动器加热(但不是满载)

              {

                  C3=170;

                  break;

              }

              if(tp<4&&sign==1)            //如果差值小于4且为负数,令驱动器冷却(但不是满载)

              {

                  C3=30;

                  break;

              }

              if(sign==1)                 //如果差值大于4且为负数,令驱动器冷却(满载)

              {

                  C3=0;

                  break;

              }

              if(sign==0)                 //如果差值大于4且为正数,令驱动器加热(满载)

              {

                  C3=255;

                  break;

              }

           

              break;

           }

       }

       if(DataTO<71&&DataTO>30);           //第二段

       {

           while(1)

           {

              if(tp<1)                    //如果差值为0,则令驱动器空载(0V)

              {

                  C3=0x80;

                  break;

              }

              if(tp<4&&sign==0)           //如果差值小于4且为正数,令驱动器加热(但不是满载)

              {

                  C3=220;

                  break;

              }

              if(tp<4&&sign==1)           //如果差值小于4且为负数,令驱动器冷却(但不是满载)

              {

                  C3=75;

                  break;

              }

              if(sign==1)                  //如果差值大于4且为负数,令驱动器冷却(满载)

              {

                  C3=0;

                  break;

              }

              if(sign==0)                  //如果差值大于4且为正数,令驱动器加热(满载)

              {

                  C3=255;

                  break;

              }

           

              break;

           }

       }

       if(DataTO<96&&DataTO>70);           //第三段

       {

           while(1)

           {

              if(tp<1)                     //如果差值为0,则令驱动器空载(0V)

              {

                  C3=0x80;

                  break;

              }

              if(tp<4&&sign==0)            //如果差值小于4且为正数,令驱动器加热(但不是满载)

              {

                  C3=255;

                  break;

              }

              if(tp<4&&sign==1)            //如果差值小于4且为负数,令驱动器冷却(但不是满载)

              {

                  C3=100;

                  break;

              }

               if(sign==1)                 //如果差值大于4且为负数,令驱动器冷却(满载)

              {

                  C3=0;

                  break;

              }

              if(sign==0)                 /如果差值大于4且为正数,令驱动器加热(满载)

              {

                  C3=255;

                  break;

              }

           

              break;

           }

       }

       Display(DataTI,DataTO);            //更新数码管显示

       return;

}

address.h:

#define   C11    XBYTE[0xE000]         //第一个数码管

#define    C12    XBYTE[0xE100]         //第二个数码管

#define    C13    XBYTE[0xE200]         //第三个数码管

#define    C14    XBYTE[0xE300]         //第四个数码管

#define    C3      XBYTE[0xBF00]        //D/A转换器

#define    C2      XBYTE[0xDF00]        //A/D转换器

#define    C40     XBYTE[0x7F00]        //键盘

#define    C41     XBYTE[0x7000]        //键盘第一行

#define    C42     XBYTE[0x7100]        //键盘第二行

#define    C43     XBYTE[0x7200]        //键盘第三行

#define   C44     XBYTE[0x7300]        //键盘第四行

keytable.h:

#define    K1         0x1E

#define    K2        0x1D

#define    K3         0x1B

#define    K4         0x17

#define    K5         0x0F

#define    K6         0x5E

#define    K7         0x5D

#define    K8         0x5B

#define    K9         0x57

#define    K10        0x4F

#define    K11        0x9E

#define    K12        0x9D

digtaltable.h:

#define    D10       0x50

#define    D11       0xF9

#define    D12       0x4A

#define    D13       0x49

#define    D14       0xE1

#define    D15       0x45

#define    D16       0x44

#define    D17       0xD9

#define    D18       0x40

#define    D19       0x41

#define    D20       0x0C

#define    D21       0xAF

#define    D22       0xC8

#define    D23       0x8A

#define    D24       0x2B

#define    D25       0x1A

#define    D26       0x18

#define    D27       0x8F

#define    D28       0x08

#define    D29       0x0A

#define    D30       0x44

#define    D31       0xF5

#define    D32       0x86

#define    D33       0x85

#define    D34       0x35

#define    D35       0x0D

#define    D36       0x0C

#define    D37       0xE5

#define    D38       0x04

#define    D39       0x05

#define    D40       0x0C

#define    D41       0xEE

#define    D42       0x58

#define    D43       0x4A

#define    D44       0xAA

#define    D45       0x0B

#define    D46       0x09

#define    D47       0x6E

#define    D48       0x08

#define    D49       0x0A

#define    DT1       digtaltable1

#define    DT2       digtaltable2

#define    DT3       digtaltable3

#define    DT4       digtaltable4

code const unsigned int digtaltable1[];      //存放第一个数码管编码的数组

code const unsigned int digtaltable2[];      //存放第二个数码管编码的数组

code const unsigned int digtaltable3[];      //存放第三个数码管编码的数组

code const unsigned int digtaltable4[];      //存放第四个数码管编码的数组


我想知道最后的键值表以及数码管编码表干什么用的 以及是怎么计算的  谢谢 各位了

附上图

键盘原理图


显示原理图


#define   C11    XBYTE[0xE000]         //第一个数码管

#define    C12    XBYTE[0xE100]         //第二个数码管

#define    C13    XBYTE[0xE200]         //第三个数码管

#define    C14    XBYTE[0xE300]         //第四个数码管

#define    C3      XBYTE[0xBF00]        //D/A转换器

#define    C2      XBYTE[0xDF00]        //A/D转换器

#define    C40     XBYTE[0x7F00]        //键盘

#define    C41     XBYTE[0x7000]        //键盘第一行

#define    C42     XBYTE[0x7100]        //键盘第二行

#define    C43     XBYTE[0x7200]        //键盘第三行

#define   C44     XBYTE[0x7300]        //键盘第四行
加红的地址是怎么来的 呢  小弟初学单片机 问的问题比较白痴望好心人耐心解答谢谢!

我现在用的键盘是这个方案 键值表用改吗


好像有点夸张了,只是简单的静态数码管显示而已,用51+ZLG7289+键盘搞定了

好像有点长

在学校的做的话是可以的。多学习一下芯片的操作是不错的。
工作中就算了吧。

研究一下

貌似注释快加满了,不如你哪句不明白还是单独问吧,这样不太好回答,嘻嘻

看不懂...帮顶好了

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top