proteus仿真就动一下就没反应了 求助啊
主要做热电偶变送器
程序还有一部分没编完
/*2019年5月13日*/
- #include<reg52.h>
- #include<intrins.h>
- /*宏定义*/
- #define uchar unsigned char
- #define uint unsigned int
- /*串口、变量定义,位声明*/
- sbit ds18b20_io=P1^1;//18b20输入端口
- sbit tlc_clk=P1^2; //2543CLK端口
- sbit tlc_din=P1^3; //2543DIN端口
- sbit tlc_dout=P1^4; //2543DOUT端口
- sbit tlc_cs=P1^5; //2543片选端口
- sbit max485_1=P3^0 ; //485??端口
- sbit max485_2=P3^1 ; //485??端口
- sbit max485_src=P3^4 ; //485使能端口
- sbit E=P2^0 ; //1602EN端口
- sbit RW=P2^1 ; //1602RW端口
- sbit RS=P2^2 ; //1602RS端口
- /*键盘口定义*/
- /*键盘口定义*/
- /*键盘口定义*/
- /*键盘口定义*/
- /*各函数声明*/
- void delay(uchar i); //延时函数
- void ds_init(); //18b20初始化函数
- bit bitRead(); //18b20位读取
- uchar byteRead(); //18b20字节读取
- void writeByte(uchar dat);//向18B20写入一字节数据
- void sendChangeCmd(); //向18b20发送温度转换命令
- void sendReadCmd(); //向18b2发送温度读取命令
- uint getTmpValue(); //向18b2读取温度
- void AD2543_ini(); //2543初始化程序
- uint Read2543(unsigned char port); //2543读取程序
- void WaitNus(uint x); //延时x微秒
- void BUSYFLAG(void); //忙标志查询,忙时一直查询
- void writeCommand(uchar command); //写命令字(地址)
- void writeData(uchar DATA); //写控制字
- void LCDINT(void); //LCD初始化函数
- uint filtration(uint a,uint b,uint c); //滤波函数
-
- /*各数组定义*/
- code uint TP_DATA[61][2]={{0,0},{100,397},{200,789},{300,1203},{400,1612},{500,2023},{600,2436},
- {700,2851},{800,3267},{900,3682},{1000,4055},{1100,4468},{1200,4879},
- {1300,5288},{1400,5694},{1500,6138},{1600,6540},{1700,6941},{1800,7340},
- {1900,7739},{2000,8138},{2100,8539},{2200,8940},{2300,9343},{2400,9747},
- {2500,10153},{2600,10562},{2700,10971},{2800,11382},{2900,11795},{3000,12209},
- {3100,12624},{3200,13040},{3300,13457},{3400,13874},{3500,14293},{3600,14713},
- {3700,15133},{3800,15554},{3900,15975},{4000,16397},{4100,16820},{4200,17243},
- {4300,17667},{4400,18091},{4500,18516},{4600,18941},{4700,19366},{4800,19792},
- {4900,20218},{5000,20644},{5100,21071},{5200,21497},{5300,21924},{5400,22350},
- {5500,22776},{5600,23203},{5700,23269},{5800,24055},{5900,24480},{6000,24905}};
- /*函数部分*/
- void main() //主函数
- {
- LCDINT(); /*各芯片初始化*/
- ds_init();
- AD2543_ini();
- TMOD=0x01; //设置定时器0为工作方式1
- TH0=(65536-50000)/256;
- TL0=(65536-50000)%256;
- EA=1; //开总中断
- ET0=1; //开定时器0中断
- TR0=1; //启动定时器0
- while(1)
- {;}
-
- }
- /*延时函数,延时i毫秒 */
- void delay(uchar i)
- {
- uchar j,k;
- for(j=i;j>0;j--)
- {
- for(k=125;k>0;k--);
- }
- }
- /*18b20初始化函数*/
- void ds_init()
- {
- uint i;
- ds18b20_io=0;
- i=103;
- while(i>0);i--;
- ds18b20_io=1;
- i=4;
- while(i>0);i--;
- }
- /*18b20位读取*/
- bit bitRead()
- {
- uint i;
- bit b;
- ds18b20_io=0;
- i++;
- ds18b20_io = 1;
- i++; i++;
- b = ds18b20_io;
- i = 8;
- while(i>0) i--;
- return b;
- }
- /*字节读取*/
- unsigned char readByte()
- {
- uint i;
- uchar j, dat;
- dat = 0;
- for(i=0; i<8; i++)
- {
- j = bitRead();
- dat = (j << 7) | (dat >> 1);
- }
- return dat;
- }
- /*向DS18B20写入一字节数据*/
- void writeByte(uchar dat)
- {
- uint i;
- uchar j;
- bit b;
- for(j = 0; j < 8; j++)
- {
- b = dat & 0x01; //取最后一位
- dat >>= 1;
- if(b) //写"1", 让低电平持续2个小延时, 高电平持续8个小延时
- {
- ds18b20_io = 0;
- i++; i++;
- ds18b20_io = 1;
- i = 8;
- while(i>0) i--;
- }
- else //写"0", 让低电平持续8个小延时, 高电平持续2个小延时
- {
- ds18b20_io = 0;
- i = 8; while(i>0) i--;
- ds18b20_io = 1;
- i++; i++;
- }
- }
- }
- /*向18b20发送温度转换命令*/
- void sendChangeCmd()
- {
- ds_init(); //初始化DS18B20, 无论什么命令, 首先都要发起初始化
- delay(1); //延时1ms, 因为DS18B20会拉低DQ 60~240us作为应答信号
- writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
- writeByte(0x44); //写入温度转换命令字 Convert T
- }
- /*向18b2发送温度读取命令*/
- void sendReadCmd()
- {
- ds_init();
- delay(1);
- writeByte(0xcc); //写入跳过序列号命令字 Skip Rom
- writeByte(0xbe); //写入读取数据令字 Read Scratchpad
- }
- /*获取当前温度值*/
- uint getTmpValue()
- {
- uint ds18b20_value;
- float t;
- uchar low, high;
- sendReadCmd();
- low = readByte(); //连续读取两个字节数据
- high = readByte();
- ds18b20_value = high;
- ds18b20_value <<= 8;
- ds18b20_value |= low;
- t=ds18b20_value*0.0625;
- ds18b20_value=t*10+0.5;
- return ds18b20_value;
- }
- /*2543初始化函数*/
- void AD2543_ini()
- {
- tlc_cs=1;
- tlc_cs=0;
- }
- /*2543读取函数*/
- unsigned int Read2543(unsigned char port) //port为准备读取的端口
- {
- uint ad=0,n;//变量ad为返回值,n为临时变量(用于端口操作)
- uchar i;
-
- tlc_clk=0; //clk先给0,避免出错
- tlc_cs=0; //片选,0有效
- n=port; //用n来操作端口port,目的是写2次端口地址,这样回来的才是真正的端口ad值
- n<<=4; //先偏移4,让地址到高位
- for(i=0;i<12;i++) //输入12位端口地址(其实前4位是地址,后8位都是0)
- {
- tlc_din=(bit)(n&0x80); //高位(第8位)输出。(串口模式)
- tlc_clk=1;
- tlc_clk=0;
- n<<=1; //左移1位。利用循环逐位输出
- }
- tlc_cs=1; //关闭片选
- {_nop_();_nop_();_nop_();_nop_();} //缓冲一下
- {_nop_();_nop_();_nop_();_nop_();} //缓冲
-
- tlc_cs=0; //再次片选
- n=port; //再次写端口地址
- n<<=4;
- for(i=0;i<12;i++)
- {
- tlc_din=(bit)(n&0x80);
- tlc_clk=1;
- tlc_clk=0;
- n<<=1;
- }
- tlc_cs=1; //停止
- {_nop_();_nop_();_nop_();_nop_();}
- {_nop_();_nop_();_nop_();_nop_();}
-
- tlc_cs=0; //片选。开始读取数据
- for(i=0;i<12;i++) //12位循环
- {
- ad<<=1; //先左移1位
- if(tlc_dout) ad|=0x01; //判断:如AD_OUT为1,则ad低位赋值1
- tlc_clk=1;
- tlc_clk=0;
- }
- tlc_cs=1; //结束读数据
-
- return(ad); //返回值ad
- }
- /*LCD1602程序*/
- void WaitNus(uint x)//延时 x us
- {
-
- unsigned char j;
-
- while(x--)
-
- {
- for(j=0;j<12;j++)
-
- {;}
-
- }
-
- }
- /*忙标志判断*/
- void BUSYFLAG(void)
-
- {
-
- uchar temp;
-
- P0=0xff;
-
- RS=1;
-
- RW=1;
-
- while(1)
-
- {
-
- E=1;
-
- temp=P0; //读状态字
-
- E=0;
-
- if ((temp&0x80)==0)
-
- break; //判断忙标志是否为0
-
- }
-
- }
- /*写命令字 地址*/
- void writeCommand(uchar command)
- {
-
- BUSYFLAG();
-
- RS=0;
-
- RW=0;
-
- E=1;
-
- P0=command;
-
- E=0;
-
- }
- /*写控制字*/
- void writeData(uchar DATA)
- {
-
- BUSYFLAG();
- RS=1;
-
- RW=0;
-
- E=1;
-
- P0=DATA;
-
- E=0;
-
- }
- /*lcd初始化*/
- void LCDINT(void)
- {
-
- delay(15);////延时 x ms
-
- writeCommand(0x30);//8位
-
- delay(4);////延时 x ms
-
- writeCommand(0x30);
-
- WaitNus(100);////延时 x us
-
- writeCommand(0x30);
-
- writeCommand(0x38);//两行显示模式
-
- writeCommand(0x01);//清屏
-
- writeCommand(0x06);//画面不动
-
- writeCommand(0x0c);//光标设置
-
- writeCommand(0x80);//显示首址
-
- }
- /*终值滤波函数*/
- uint filtration (uint a,uint b,uint c)
- {
- uint mid;
- if((a<b&&a>c)||(a<c&&a>b))
- {mid=a;}
- else if((b<a&&b>c)||(b<c&&b>a))
- {mid=b;}
- else
- {mid=c;}
- return mid;
- }
-
- /*中断函数*/
- void RUN(void) interrupt 0
- {
-
-
- uint a,b,c; //临时变量
- uint Tmp,V, Vchg;
- uint i=0;
- a=getTmpValue(); // 采集18b20的温度数据
- b=getTmpValue();
- c=getTmpValue();
- Tmp=filtration (a,b,c); // 调用中值滤波函数
-
- a=Read2543(0); // 采集2543电势数据
- b=Read2543(0);
- c=Read2543(0);
-
- V=filtration (a,b,c)+0.5; // 调用中值滤波函数
- while(Tmp>TP_DATA[i][0])
- {i++;}
-
- 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];
-
- V=V/200.7*1000+Vchg;
- i=0;
- while(Tmp>TP_DATA[i][1])
- {i++;}
-
- 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]); //温度的十倍
-
-
- writeCommand(0);
- writeData(Tmp%100);
- writeCommand(0);
- writeData(Tmp%10);
- writeCommand(0);
- writeData(Tmp%100); // 送显(待优化)
-
- }
-
复制代码
//按键功能 485通信功能 显示优化
|