proteus仿真就動一下就沒反應了 求助啊
主要做熱電偶變送器
無標題.png (285.62 KB, 下載次數: 23)
下載附件
2019-5-15 16:30 上傳
程序還有一部分沒編完
/*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通信功能 顯示優化
|