|
这是我们的免试题目,有仿真原理图,源代码没希望能给大家提供帮助
仿真文件下载:
模拟粮仓温度检测报警系统-董晓臣.rar
(115.09 KB, 下载次数: 59)
源程序:
- #include <reg52.h>
- #include<intrins.h>
- #include <math.h>
- #define uchar unsigned char
- #define uint unsigned int
- sbit RW = P2^1; //定义LCD的读、写选择端
- sbit RS = P2^0; //定义LCD的数据、命令选择端
- sbit EN = P2^2; //定义LCD的使能信号端
- sbit DS = P3^5; //定义DS18B20的IO口
- sbit L=P1^3; //绿灯
- sbit H=P1^4; //红灯
- sbit LS=P3^4; //蜂鸣器
- sbit k1=P2^7; //显示64位的ROM
- sbit k2=P2^6; //显示当前温度
- sbit k3=P2^3; //显示温度上限及下线,并支持调节
- sbit k4=P2^4; // 上限加
- sbit k5=P2^5; // 下限减
- uchar k=2; //当前温度显示标志位
- uchar table0[] = " Current Temp : "; //当前温度
- uchar table1[] = " -- ROM CODE -- "; //显示DS18B20的ROM
- uchar table2[] = "ALARM TEMP Hi Lo"; //显示上下限温度
- uchar table3[] = "Hi: Lo: ";
- uchar table4[] = {0,0,0,0,0,0,0,0};
- uchar tempHL[] = { 40, 10}; //上下限温度的初始值
- void delayms(uint ms) //延时函数1
- {
- uint i;
- while(ms--)
- {
- for(i=0;i<120;i++);
- }
- }
- void writecom(uchar com) //写地址,也就是显示的数据的位置
- {
- RS = 0;
- P0 = com;
- EN = 1;
- delayms(1);
- EN = 0;
- }
- void writedata(uchar dat) //写数据,也就是显示的数据
- {
- RS = 1;
- P0 = dat;
- EN = 1;
- delayms(1);
- EN = 0;
- }
- void init() //LCD初始化
- {
- RW = 0;
- writecom(0x38); //16*2显示,5*7点阵
- writecom(0x0c);
- writecom(0x06);
- writecom(0x01); //清除LCD的显示内容
- }
- void writestring(uchar * str, uchar length) //写数据的过度函数。length:长度
- {
- uchar i;
- for(i = 0; i < length; i++)
- {
- writedata(str[i]);
- }
- }
- void delay(uint num) //延时函数
- {
- while( --num );
- }
- DSinit(void) //初始化ds1820
- {
- DS= 1; //DS复位
- delay(8); //稍做延时
- DS= 0; //将DS拉低
- delay(90); //精确延时 大于 480u
- DS= 1; //拉高总线
- delay(110);
- DS= 1;
- }
- uchar read_bit(void) //读一位(bit)
- {
- uchar i;
- DS= 0; //将DS拉低开始读时间隙
- DS= 1; // then return high
- for (i=0; i<3; i++); // 延时15μs
- return(DS); // 返回 DS线上的电平值
- }
- uchar readbyte() // 读一个字节
- {
- uchar i = 0;
- uchar dat = 0;
- for (i=0;i<8;i++)
- { // 读取字节,每次读取一个字节
- if(read_bit()) dat|=0x01<<i; // 然后将其左移
- delay(4);
- }
- return (dat);
- }
- void write_bit(char bitval) //写一位
- {
- DS= 0; // 将DS拉低开始写时间隙
- if(bitval==1) DS=1; // 如果写1,DS返回高电平
- delay(5); // 在时间隙内保持电平值,
- DS= 1; // delay函数每次循环延时16μs,因此delay(5) = 104μs
- }
- void writebyte(uchar dat) //写一个字节
- {
- uchar i = 0;
- uchar temp;
- for (i=0; i<8; i++) // 写入字节, 每次写入一位
- {
- temp = dat>>i;
- temp &= 0x01;
- write_bit(temp);
- }
- delay(5);
- }
- void sendchangecmd() //DS18B20?开始获取温度并转换
- {
- DSinit(); //DS18B20复位
- delayms(1);
- writebyte(0xcc); //写跳过读ROM指令
- writebyte(0x44); //写温度转换指令
- }
- void sendreadcmd() //读取寄存器中存储的温度数据
- {
- DSinit(); //DS18B20复位
- delayms(1);
- writebyte(0xcc); //写跳过读ROM指令
- writebyte(0xbe); //读取暂存器的内容
- }
- int gettmpvalue()
- {
- uint tmpvalue;
- float t;
- uchar low, high;
- sendreadcmd(); //读取寄存器中存储的温度数据
- low = readbyte(); //读取低八位
- high = readbyte(); //读取高八位
- tmpvalue = high;
- tmpvalue <<= 8; //高八位左移八位
- tmpvalue |= low; //两个字节组合为1个字
- t = tmpvalue * 0.0625 * 100; //分辨率为0.0625,在此将值扩大100倍
- return t;
- }
- void display(int v) //显示子函数
- {
- uchar i;
- uchar datas[] = {0, 0, 0, 0, 0, 0, 0, 0}; //定义缓存数组datas
- uint tmp = abs(v); //abs是求绝对值函数
- datas[0] = tmp % 10000 / 1000;
- datas[1] = tmp % 1000 / 100;
- datas[2] = tmp % 100 / 10;
- datas[3] = tmp % 10;
- datas[4] = 80; //空格的前30的ASCALL码
- datas[5] = 175; //温度符号的前30的ASCALL码
- datas[6] = 19; //C的前30的ASCALL码
- writecom(0xc0+3);
- if(v < 0) //当V小于0则输出负号
- {
- writestring("- ", 2);
- }
- else
- {
- writestring("+ ", 2); //当V大于0则输出正号
- }
- for(i = 0; i != 7; i++)
- {
- writedata('0'+datas[i]); //显示温度
- if(i == 1)
- {
- writedata('.'); //显示温度的小数点
- }
- }
- }
- void Read_RomCord() //读取64位序列码
- {
- unsigned char j;
- DSinit();
- writebyte(0x33); // 读序列码的操作
- for (j = 0; j < 8; j++)
- {
- table4[j] = readbyte();
- }
- }
- void Disp_RomCode() //数据转换与显示
- {
- uchar j,i;
- writecom(0xc0); //LCD第二行初始位置
- for(j=0;j<8;j++)
- {
- i=((table4[j]&0xf0)>>4);
- if(i>9)
- { i=i+0x37;}
- else{i=i+0x30;}
- writedata(i); //高位数显示
- i=(table4[j]&0x0f);
- if(i>9)
- {i=i+0x37;}
- else {i=i+0x30;}
- writedata(i); //低位数显示
- }
- }
- void lcd_display() //按键扫描
- {
- uchar i,m;
- uchar hl[]={0, 0, 0, 0, 0};
- if(k1 == 0) k = 1;
- if(k2 == 0) k = 2;
- if(k3 == 0) k = 3;
- if(tempHL[0]<=gettmpvalue()/100)
- delayms(100),LS=!LS,H=~H;
- else
- LS=1,H=1;
- if(m==1)
- {
- if(tempHL[1]>=gettmpvalue()/100)
- delayms(100),LS=!LS,L=~L;
- else
- LS=1,L=1;
- }
- switch(k)
- {
- case 1: //显示64位的ROM
- writecom(0x01);
- writecom(0x80);
- writestring(table1, 16);
- Read_RomCord(); //读取64位序列码
- Disp_RomCode(); //显示64位序列
- delayms(500); //温度转换时间需要750ms以上
- break;
- case 2: //显示当前温度
- delayms(750); //温度转换时间需要750ms以上
- sendchangecmd();
- writecom(0x01);
- writecom(0x80);
- writestring(table0, 16);
- display(gettmpvalue());
- break;
- case 3: //显示温度上限及下线,并支持调节
- writecom(0x80);
- writestring(table2, 16);
- writecom(0xC0);
- writestring(table3, 16);
- if(k4==0) {tempHL[0]++;if(m==1) tempHL[1]++;if(m==0){tempHL[1]--;if(tempHL[1]==0)m=1;}delayms(100);}
- if(k5==0) {tempHL[0]--;if(m==0) tempHL[1]++;if(m==1){tempHL[1]--;if(tempHL[1]==0)m=0;}delayms(100);}
- hl[0]=tempHL[0]/10;
- hl[1]=tempHL[0]%10;
- if(m==1) hl[2]=80;
- if(m==0) hl[2]=128;
- hl[3]=tempHL[1]/10;
- hl[4]=tempHL[1]%10;
- writecom(0xC0+4);
- for(i = 0; i != 2; i++)
- {
- writedata('0'+hl[i]); //显示上限温度
- }
- writecom(0xC0+11);
- for(i = 2; i != 5; i++)
- {
- writedata('0'+hl[i]); //显示下限温度
- }
- break;
- }
- }
- void main()
- {
- sendchangecmd(); //读取寄存器中存储的温度数据
- init(); //LCD初始化
- writecom(0x80); //选择LCD第一行
- writestring(table0, 16); //显示当前温度的英文字母
- while(1)
- {
- lcd_display(); //扫描按键
- }
- }
复制代码
|
评分
-
查看全部评分
|