找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2081|回复: 0
收起左侧

单片机热电偶变送器proteus仿真就动一下就没反应了?

[复制链接]
ID:528308 发表于 2019-5-15 16:30 | 显示全部楼层 |阅读模式
proteus仿真就动一下就没反应了 求助啊
主要做热电偶变送器
无标题.png
程序还有一部分没编完
/*2019年5月13日*/
  1. #include<reg52.h>
  2. #include<intrins.h>
  3. /*宏定义*/
  4. #define uchar unsigned char
  5. #define uint unsigned int

  6. /*串口、变量定义,位声明*/
  7. sbit ds18b20_io=P1^1;//18b20输入端口
  8. sbit tlc_clk=P1^2; //2543CLK端口
  9. sbit tlc_din=P1^3; //2543DIN端口
  10. sbit tlc_dout=P1^4; //2543DOUT端口
  11. sbit tlc_cs=P1^5; //2543片选端口
  12. sbit max485_1=P3^0 ; //485??端口
  13. sbit max485_2=P3^1 ; //485??端口
  14. sbit max485_src=P3^4 ; //485使能端口

  15. sbit E=P2^0 ;  //1602EN端口
  16. sbit RW=P2^1 ;  //1602RW端口
  17. sbit RS=P2^2 ;  //1602RS端口
  18. /*键盘口定义*/
  19. /*键盘口定义*/
  20. /*键盘口定义*/
  21. /*键盘口定义*/
  22. /*各函数声明*/
  23.    void delay(uchar i);   //延时函数
  24.    void ds_init();       //18b20初始化函数
  25.    bit bitRead();     //18b20位读取
  26.    uchar byteRead();   //18b20字节读取
  27.    void writeByte(uchar dat);//向18B20写入一字节数据
  28.    void sendChangeCmd();  //向18b20发送温度转换命令
  29.    void sendReadCmd();   //向18b2发送温度读取命令
  30.    uint getTmpValue();   //向18b2读取温度
  31.    void AD2543_ini();        //2543初始化程序
  32.    uint Read2543(unsigned char port); //2543读取程序
  33.    void WaitNus(uint x);            //延时x微秒
  34.    void BUSYFLAG(void);        //忙标志查询,忙时一直查询
  35.    void writeCommand(uchar command);   //写命令字(地址)
  36.    void writeData(uchar DATA);     //写控制字
  37.    void LCDINT(void);        //LCD初始化函数
  38.    uint filtration(uint a,uint b,uint c);  //滤波函数

  39. /*各数组定义*/
  40.     code uint TP_DATA[61][2]={{0,0},{100,397},{200,789},{300,1203},{400,1612},{500,2023},{600,2436},
  41.             {700,2851},{800,3267},{900,3682},{1000,4055},{1100,4468},{1200,4879},
  42.          {1300,5288},{1400,5694},{1500,6138},{1600,6540},{1700,6941},{1800,7340},
  43.          {1900,7739},{2000,8138},{2100,8539},{2200,8940},{2300,9343},{2400,9747},
  44.          {2500,10153},{2600,10562},{2700,10971},{2800,11382},{2900,11795},{3000,12209},
  45.          {3100,12624},{3200,13040},{3300,13457},{3400,13874},{3500,14293},{3600,14713},
  46.          {3700,15133},{3800,15554},{3900,15975},{4000,16397},{4100,16820},{4200,17243},
  47.          {4300,17667},{4400,18091},{4500,18516},{4600,18941},{4700,19366},{4800,19792},
  48.          {4900,20218},{5000,20644},{5100,21071},{5200,21497},{5300,21924},{5400,22350},
  49.          {5500,22776},{5600,23203},{5700,23269},{5800,24055},{5900,24480},{6000,24905}};



  50.     /*函数部分*/   
  51.    void main()     //主函数
  52.    {
  53.   LCDINT();      /*各芯片初始化*/
  54.   ds_init();
  55.   AD2543_ini();

  56.   TMOD=0x01;    //设置定时器0为工作方式1
  57.   TH0=(65536-50000)/256;
  58.   TL0=(65536-50000)%256;
  59.   EA=1;     //开总中断
  60.   ET0=1;     //开定时器0中断
  61.   TR0=1;     //启动定时器0
  62.   while(1)
  63.    {;}
  64.   
  65.    }

  66. /*延时函数,延时i毫秒 */
  67. void delay(uchar i)
  68. {
  69.   uchar j,k;
  70.   for(j=i;j>0;j--)
  71.   {
  72.    for(k=125;k>0;k--);
  73.   }
  74. }

  75. /*18b20初始化函数*/
  76. void ds_init()
  77. {
  78.   uint i;
  79.   ds18b20_io=0;
  80.   i=103;
  81.   while(i>0);i--;
  82.   ds18b20_io=1;
  83.   i=4;
  84.   while(i>0);i--;
  85. }
  86. /*18b20位读取*/
  87. bit bitRead()
  88. {
  89.    uint i;
  90.      bit b;
  91.   ds18b20_io=0;
  92.      i++;
  93.      ds18b20_io = 1;
  94.      i++; i++;
  95.         b = ds18b20_io;
  96.         i = 8;
  97.         while(i>0) i--;
  98.         return b;
  99. }
  100. /*字节读取*/
  101. unsigned char readByte()
  102.     {
  103.         uint i;
  104.         uchar j, dat;
  105.         dat = 0;
  106.         for(i=0; i<8; i++)
  107.          {
  108.             j = bitRead();
  109.             dat = (j << 7) | (dat >> 1);
  110.         }
  111.         return dat;
  112.     }

  113. /*向DS18B20写入一字节数据*/
  114. void writeByte(uchar dat)
  115.   {
  116.      uint i;
  117.      uchar j;
  118.      bit b;
  119.      for(j = 0; j < 8; j++)
  120.       {
  121.          b = dat & 0x01;  //取最后一位
  122.          dat >>= 1;         
  123.          if(b)      //写"1", 让低电平持续2个小延时, 高电平持续8个小延时
  124.           {
  125.              ds18b20_io = 0;
  126.              i++; i++;
  127.              ds18b20_io = 1;
  128.              i = 8;
  129.     while(i>0) i--;
  130.          }
  131.          else     //写"0", 让低电平持续8个小延时, 高电平持续2个小延时
  132.           {
  133.              ds18b20_io = 0;
  134.              i = 8; while(i>0) i--;
  135.              ds18b20_io = 1;
  136.              i++; i++;
  137.          }
  138.      }
  139. }
  140. /*向18b20发送温度转换命令*/
  141. void sendChangeCmd()
  142. {
  143.   ds_init();    //初始化DS18B20, 无论什么命令, 首先都要发起初始化
  144.   delay(1);    //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号
  145.   writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
  146.   writeByte(0x44); //写入温度转换命令字 Convert T
  147. }
  148. /*向18b2发送温度读取命令*/
  149. void sendReadCmd()
  150.   {
  151.      ds_init();
  152.      delay(1);
  153.      writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
  154.      writeByte(0xbe); //写入读取数据令字 Read Scratchpad
  155. }
  156.   /*获取当前温度值*/
  157. uint getTmpValue()
  158.   {
  159.      uint ds18b20_value;
  160.   float t;
  161.   uchar low, high;
  162.   sendReadCmd();
  163.    low = readByte();      //连续读取两个字节数据
  164.   high = readByte();
  165.    ds18b20_value = high;
  166.   ds18b20_value <<= 8;
  167.    ds18b20_value |= low;
  168.   t=ds18b20_value*0.0625;
  169.   ds18b20_value=t*10+0.5;
  170.   return ds18b20_value;
  171.    }
  172.    /*2543初始化函数*/
  173.    void AD2543_ini()         
  174. {
  175.   tlc_cs=1;
  176.      tlc_cs=0;
  177. }
  178.    /*2543读取函数*/
  179.    unsigned int Read2543(unsigned char port)        //port为准备读取的端口
  180. {
  181. uint ad=0,n;//变量ad为返回值,n为临时变量(用于端口操作)
  182. uchar i;

  183. tlc_clk=0;      //clk先给0,避免出错
  184. tlc_cs=0;       //片选,0有效
  185. n=port;           //用n来操作端口port,目的是写2次端口地址,这样回来的才是真正的端口ad值
  186. n<<=4;          //先偏移4,让地址到高位
  187. for(i=0;i<12;i++)   //输入12位端口地址(其实前4位是地址,后8位都是0)
  188.          {
  189.            tlc_din=(bit)(n&0x80);  //高位(第8位)输出。(串口模式)
  190.            tlc_clk=1;  
  191.            tlc_clk=0;
  192.            n<<=1;       //左移1位。利用循环逐位输出
  193.          }
  194. tlc_cs=1;        //关闭片选
  195.            {_nop_();_nop_();_nop_();_nop_();}         //缓冲一下
  196.          {_nop_();_nop_();_nop_();_nop_();} //缓冲
  197.                  
  198. tlc_cs=0;  //再次片选
  199. n=port;     //再次写端口地址
  200. n<<=4;
  201. for(i=0;i<12;i++)
  202.          {
  203.            tlc_din=(bit)(n&0x80);
  204.            tlc_clk=1;
  205.            tlc_clk=0;
  206.            n<<=1;
  207.          }
  208. tlc_cs=1;   //停止
  209.            {_nop_();_nop_();_nop_();_nop_();}
  210.          {_nop_();_nop_();_nop_();_nop_();}

  211. tlc_cs=0;                 //片选。开始读取数据
  212. for(i=0;i<12;i++)     //12位循环
  213.          {
  214.          ad<<=1;         //先左移1位
  215.            if(tlc_dout) ad|=0x01;  //判断:如AD_OUT为1,则ad低位赋值1
  216.            tlc_clk=1;
  217.            tlc_clk=0;
  218.          }
  219. tlc_cs=1;             //结束读数据
  220.          
  221. return(ad);           //返回值ad
  222. }

  223. /*LCD1602程序*/
  224. void WaitNus(uint x)//延时 x us
  225. {

  226.   unsigned char j;
  227.   
  228.   while(x--)
  229.   
  230.    {
  231.     for(j=0;j<12;j++)
  232.   
  233.      {;}
  234.   
  235.    }

  236. }
  237. /*忙标志判断*/
  238. void BUSYFLAG(void)

  239. {

  240.   uchar temp;
  241.   
  242.   P0=0xff;
  243.   
  244.   RS=1;
  245.   
  246.   RW=1;
  247.   
  248.   while(1)

  249.   {
  250.   
  251.    E=1;
  252.    
  253.    temp=P0; //读状态字
  254.    
  255.    E=0;
  256.    
  257.    if ((temp&0x80)==0)
  258.    
  259.    break; //判断忙标志是否为0
  260.   
  261.   }

  262. }
  263. /*写命令字 地址*/
  264. void writeCommand(uchar command)
  265. {

  266.   BUSYFLAG();
  267.   
  268.   RS=0;
  269.   
  270.   RW=0;
  271.   
  272.   E=1;
  273.   
  274.   P0=command;
  275.   
  276.   E=0;

  277. }
  278. /*写控制字*/
  279. void writeData(uchar DATA)
  280. {

  281.   BUSYFLAG();
  282.   RS=1;
  283.   
  284.   RW=0;
  285.   
  286.   E=1;
  287.   
  288.   P0=DATA;
  289.   
  290.   E=0;

  291. }
  292. /*lcd初始化*/
  293. void LCDINT(void)
  294. {

  295.   delay(15);////延时 x ms
  296.   
  297.   writeCommand(0x30);//8位
  298.   
  299.   delay(4);////延时 x ms
  300.   
  301.   writeCommand(0x30);
  302.   
  303.   WaitNus(100);////延时 x us
  304.   
  305.   writeCommand(0x30);
  306.   
  307.   writeCommand(0x38);//两行显示模式
  308.   
  309.   writeCommand(0x01);//清屏
  310.   
  311.   writeCommand(0x06);//画面不动
  312.   
  313.   writeCommand(0x0c);//光标设置
  314.   
  315.   writeCommand(0x80);//显示首址

  316. }

  317. /*终值滤波函数*/
  318. uint filtration (uint a,uint b,uint c)
  319. {
  320.   uint mid;
  321.   if((a<b&&a>c)||(a<c&&a>b))
  322.    {mid=a;}
  323.   else if((b<a&&b>c)||(b<c&&b>a))
  324.    {mid=b;}
  325.   else
  326.    {mid=c;}
  327.   return mid;
  328. }  

  329. /*中断函数*/
  330. void RUN(void) interrupt 0
  331. {
  332.   

  333.   uint a,b,c;   //临时变量
  334.   uint Tmp,V, Vchg;
  335.   uint i=0;     
  336.   a=getTmpValue();     // 采集18b20的温度数据
  337.   b=getTmpValue();   
  338.   c=getTmpValue();
  339.   Tmp=filtration (a,b,c);    // 调用中值滤波函数
  340.       
  341.   a=Read2543(0); // 采集2543电势数据        
  342.   b=Read2543(0);        
  343.   c=Read2543(0);
  344.   
  345.   V=filtration (a,b,c)+0.5;    // 调用中值滤波函数
  346.   while(Tmp>TP_DATA[i][0])
  347.    {i++;}
  348.       
  349.   Vchg=Tmp*(float)(TP_DATA[i][1]-TP_DATA[i-1][1])/(TP_DATA[i][0]-TP_DATA[i-1][0])+TP_DATA[i-1][0];
  350.   
  351.   V=V/200.7*1000+Vchg;
  352.   i=0;
  353.   while(Tmp>TP_DATA[i][1])
  354.    {i++;}
  355.       
  356.   Tmp=TP_DATA[i][0]-(float)(TP_DATA[i][1]-V)*(TP_DATA[i][0]-TP_DATA[i-1][0])/(TP_DATA[i][1]-TP_DATA[i-1][1]); //温度的十倍
  357.          
  358.          
  359.   writeCommand(0);        
  360.   writeData(Tmp%100);        
  361.   writeCommand(0);        
  362.   writeData(Tmp%10);
  363.   writeCommand(0);        
  364.   writeData(Tmp%100); // 送显(待优化)   
  365.      
  366. }
复制代码

  //按键功能 485通信功能 显示优化


回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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