最新传感器proteus虚拟实验.docx

上传人:b****5 文档编号:7502473 上传时间:2023-01-24 格式:DOCX 页数:26 大小:429.91KB
下载 相关 举报
最新传感器proteus虚拟实验.docx_第1页
第1页 / 共26页
最新传感器proteus虚拟实验.docx_第2页
第2页 / 共26页
最新传感器proteus虚拟实验.docx_第3页
第3页 / 共26页
最新传感器proteus虚拟实验.docx_第4页
第4页 / 共26页
最新传感器proteus虚拟实验.docx_第5页
第5页 / 共26页
点击查看更多>>
下载资源
资源描述

最新传感器proteus虚拟实验.docx

《最新传感器proteus虚拟实验.docx》由会员分享,可在线阅读,更多相关《最新传感器proteus虚拟实验.docx(26页珍藏版)》请在冰豆网上搜索。

最新传感器proteus虚拟实验.docx

最新传感器proteus虚拟实验

 

传感器proteus虚拟实验

 

《传感器原理与应用》实验指导书

 

Proteus-V1.0版本

实验1:

基于DS18B20传感器温度测量实验

步骤:

(1)在Proteus软件画出电路图

(2)用keilC软件写出C程序,并生成.hex文件,导入到单片机当中,进行仿真,观察结果。

包括:

2个头文件LCD1602.h和DS18B20.h;1个源文件LCD_18b20.c;代码如下

LCD1602.h:

#include//用AT89C51时就用这个头文件

//#include//用华邦W78E58B时必须用这个头文件

#include

//注意那个LCD_Wait()函数,它是判"忙"标志的,在实际硬件要把注掉的那种打开

//PortDefinitions**********************************************************

sbitLcdRs=P2^0;

sbitLcdRw=P2^1;

sbitLcdEn=P2^2;

sfrDBPort=0x80;//P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口

//内部等待函数**************************************************************************

unsignedcharLCD_Wait(void)

{

LcdRs=0;

LcdRw=1;_nop_();

LcdEn=1;_nop_();

//while(DBPort&0x80);//在用Proteus仿真时,注意用屏蔽此语句,在调用GotoXY()时,会进入死循环,

//可能在写该控制字时,该模块没有返回写入完备命令,即DBPort&0x80==0x80

//实际硬件时打开此语句

LcdEn=0;

returnDBPort;

}

//向LCD写入命令或数据************************************************************

#defineLCD_COMMAND0//Command

#defineLCD_DATA1//Data

#defineLCD_CLEAR_SCREEN0x01//清屏

#defineLCD_HOMING0x02//光标返回原点

voidLCD_Write(bitstyle,unsignedcharinput)

{

LcdEn=0;

LcdRs=style;

LcdRw=0;_nop_();

DBPort=input;_nop_();//注意顺序

LcdEn=1;_nop_();//注意顺序

LcdEn=0;_nop_();

LCD_Wait();

}

//设置显示模式************************************************************

#defineLCD_SHOW0x04//显示开

#defineLCD_HIDE0x00//显示关

#defineLCD_CURSOR0x02//显示光标

#defineLCD_NO_CURSOR0x00//无光标

#defineLCD_FLASH0x01//光标闪动

#defineLCD_NO_FLASH0x00//光标不闪动

voidLCD_SetDisplay(unsignedcharDisplayMode)

{

LCD_Write(LCD_COMMAND,0x08|DisplayMode);

}

//设置输入模式************************************************************

#defineLCD_AC_UP0x02

#defineLCD_AC_DOWN0x00//default

#defineLCD_MOVE0x01//画面可平移

#defineLCD_NO_MOVE0x00//default

voidLCD_SetInput(unsignedcharInputMode)

{

LCD_Write(LCD_COMMAND,0x04|InputMode);

}

//初始化LCD************************************************************

voidLCD_Initial()

{

LcdEn=0;

LCD_Write(LCD_COMMAND,0x38);//8位数据端口,2行显示,5*7点阵

LCD_Write(LCD_COMMAND,0x38);

LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR);//开启显示,无光标

LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);//清屏

LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE);//AC递增,画面不动

}

//************************************************************************

voidGotoXY(unsignedcharx,unsignedchary)

{

if(y==0)

LCD_Write(LCD_COMMAND,0x80|x);

if(y==1)

LCD_Write(LCD_COMMAND,0x80|(x-0x40));

}

voidPrint(unsignedchar*str)

{

while(*str!

='\0')

{

LCD_Write(LCD_DATA,*str);

str++;

}

}

voidLCD_Print(unsignedcharx,unsignedchary,unsignedchar*str)

{

GotoXY(x,y);

Print(str);

}

DS18b20.h

#include//用AT89C51时就用这个头文件

//#include//用华邦W78E58B时必须用这个头文件

sbitDQ=P3^4;//定义DQ引脚为P3.4

/***********ds18b20延迟子函数(晶振12MHz)*******/

/************DS18B20对时间要求很严,但只能长不能短

*************在11.0592M下也行,因为时间长些********/

voiddelay_18B20(unsignedinti)

{

while(i--);

}

/**********ds18b20初始化函数**********************/

voidInit_DS18B20(void)

{

unsignedcharx=0;

DQ=1;//DQ复位

delay_18B20(8);//稍做延时

DQ=0;//单片机将DQ拉低

delay_18B20(80);//精确延时大于480us

DQ=1;//拉高总线

delay_18B20(14);

x=DQ;//稍做延时后如果x=0则初始化成功x=1则初始化失败

delay_18B20(20);

}

/***********ds18b20读一个字节**************/

unsignedcharReadOneChar(void)

{

unsignedchari=0;

unsignedchardat=0;

for(i=8;i>0;i--)

{

DQ=0;//给脉冲信号

dat>>=1;

DQ=1;//给脉冲信号

if(DQ)

dat|=0x80;

delay_18B20(4);

}

return(dat);

}

/*************ds18b20写一个字节****************/

voidWriteOneChar(unsignedchardat)

{

unsignedchari=0;

for(i=8;i>0;i--)

{

DQ=0;

DQ=dat&0x01;

delay_18B20(5);

DQ=1;

dat>>=1;

}

}

/**************读取ds18b20当前温度************/

unsignedchar*ReadTemperature(charTH,charTL,unsignedcharRS)

{unsignedchartt[2];

Init_DS18B20();

WriteOneChar(0xCC);//跳过读序号列号的操作

WriteOneChar(0x4E);////写入"写暂存器"命令,修改TH和TL和分辩率配置寄存器

//先写TH,再写TL,最后写配置寄存器

WriteOneChar(TH);//写入想设定的温度报警上限

WriteOneChar(TL);//写入想设定的温度报警下限

WriteOneChar(RS);//写配置寄存器,格式为0R1R01,1111

//R1R0=00分辨率娄9位,R1R0=11分辨率为12位

delay_18B20(80);//thismessageisweryimportant

Init_DS18B20();

WriteOneChar(0xCC);//跳过读序号列号的操作

WriteOneChar(0x44);//启动温度转换

delay_18B20(80);//thismessageisweryimportant

Init_DS18B20();

WriteOneChar(0xCC);//跳过读序号列号的操作

WriteOneChar(0xBE);//读取温度寄存器等(共可读9个寄存器)前两个就是温度

delay_18B20(80);

tt[0]=ReadOneChar();//读取温度值低位

tt[1]=ReadOneChar();//读取温度值高位

return(tt);

}

LCD_18b20.c

#include//用AT89C51时就用这个头文件

//#include//用华邦W78E58B时必须用这个头文件

#include

#include

#include

#include

#include

#include

#include"LCD1602.h"////液晶显示头文件

//sbitDQ=P3^4;//定义DQ引脚为P3.4

unsignedchart[2],*pt;//用来存放温度值,测温程序就是通过这个数组与主函数通信的

unsignedcharTempBuffer1[9]={0x2b,0x31,0x32,0x32,0x2e,0x30,0x30,0x43,'\0'};

//显示实时温度,上电时显示+125.00C

unsignedcharTempBuffer0[17]={0x54,0x48,0x3a,0x2b,0x31,0x32,0x35,0x20,

0x54,0x4c,0x3a,0x2b,0x31,0x32,0x34,0x43,'\0'};

//显示温度上下限,上电时显示TH:

+125TL:

+124C

unsignedcharcodedotcode[4]={0,25,50,75};

/***因显示分辨率为0.25,但小数运算比较麻烦,故采用查表的方法*******

再将表值分离出十位和个位后送到十分位和百分位********************/

voidcovert0(unsignedcharTH,unsignedcharTL)//将温度上下限转换为LCD显示的数据

{

if(TH>0x7F)//判断正负,如果为负温,将其转化为其绝对值

{

TempBuffer0[3]=0x2d;//0x2d为"-"的ASCII码

TH=~TH;

TH++;

}

elseTempBuffer0[3]=0x2b;//0x2B为"+"的ASCII码

if(TL>0x7f)

{

TempBuffer0[11]=0x2d;//0x2d为"-"的ASCII码

TL=~TL+1;

}

elseTempBuffer0[11]=0x2b;//0x2B为"+"的ASCII码

TempBuffer0[4]=TH/100+0x30;//分离出TH的百十个位

if(TempBuffer0[4]==0x30)TempBuffer0[4]=0xfe;//百位数消隐

TempBuffer0[5]=(TH%100)/10+0x30;//分离出十位

TempBuffer0[6]=(TH%100)%10+0x30;//分离出个位

TempBuffer0[12]=TL/100+0x30;//分离出TL的百十个位

if(TempBuffer0[12]==0x30)TempBuffer0[12]=0xfe;//百位数消隐

TempBuffer0[13]=(TL%100)/10+0x30;//分离出十位

TempBuffer0[14]=(TL%100)%10+0x30;//分离出个位

}

voidcovert1(void)//将温度转换为LCD显示的数据

{

unsignedcharx=0x00,y=0x00;

t[0]=*pt;

pt++;

t[1]=*pt;

if(t[1]>0x07)//判断正负温度

{

TempBuffer1[0]=0x2d;//0x2d为"-"的ASCII码

t[1]=~t[1];/*下面几句把负数的补码*/

t[0]=~t[0];/*换算成绝对值*********/

x=t[0]+1;/***********************/

t[0]=x;/***********************/

if(x>255)/**********************/

t[1]++;/*********************/

}

elseTempBuffer1[0]=0x2b;//0xfe为变"+"的ASCII码

t[1]<<=4;//将高字节左移4位

t[1]=t[1]&0x70;//取出高字节的3个有效数字位

x=t[0];//将t[0]暂存到X,因为取小数部分还要用到它

x>>=4;//右移4位

x=x&0x0f;//和前面两句就是取出t[0]的高四位

t[1]=t[1]|x;//将高低字节的有效值的整数部分拼成一个字节

TempBuffer1[1]=t[1]/100+0x30;//+0x30为变0~9ASCII码

if(TempBuffer1[1]==0x30)TempBuffer1[1]=0xfe;//百位数消隐

TempBuffer1[2]=(t[1]%100)/10+0x30;//分离出十位

TempBuffer1[3]=(t[1]%100)%10+0x30;//分离出个位

t[0]=t[0]&0x0c;//取有效的两位小数

t[0]>>=2;//左移两位,以便查表

x=t[0];

y=dotcode[x];//查表换算成实际的小数

TempBuffer1[5]=y/10+0x30;//分离出十分位

TempBuffer1[6]=y%10+0x30;//分离出百分位

}

voiddelay(unsignedchari)

{

while(i--);

}

main()

{

unsignedcharTH=110,TL=-20;//下一步扩展时可能通过这两个变量,调节上下限

//测温函数返回这个数组的头地址

while

(1)

{

pt=ReadTemperature(TH,TL,0x3f);//上限温度-22,下限-24,分辨率10位,也就是0.25C

//读取温度,温度值存放在一个两个字节的数组中,

delay(100);

covert1();

covert0(TH,TL);

LCD_Initial();//第一个参数列号,第二个为行号,为0表示第一行

//为1表示第二行,第三个参数为显示数据的首地址

LCD_Print(0,0,TempBuffer0);

LCD_Print(0,1,TempBuffer1);

}

}

实验2:

基于MPX4115传感器温度测量实验

步骤:

(1)在Proteus软件画出电路图

(2)用keilC软件写出C程序,并生成.hex文件,导入到单片机当中,进行仿真,观察结果。

压力测试仪

系统描述;输入15--115kPA压力信号

输出00h--ffh数字信号(adc0832)

在LCD上显示实际的压力值,如果超限则报警

线性区间标度变换公式:

y=(115-15)/(243-13)*X+15kpa

作者:

单位:

日期:

2008.3.7

********************************************************/

#include

#include"intrins.h"

#defineuintunsignedint

#defineucharunsignedchar

//ADC0832的引脚

sbitADCS=P2^0;//ADC0832chipseclect

sbitADDI=P3^7;//ADC0832kin

sbitADDO=P3^7;//ADC0832kout

sbitADCLK=P3^6;//ADC0832clocksignal

unsignedchardispbitcode[8]={0xf7,0xfb,0xfd,0xfe,0xef,0xdf,0xbf,0x7f};//位扫描

unsignedchardispcode[11]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff};//共阳数码管字段码

unsignedchardispbuf[4];

uinttemp;

uchargetdata;//获取ADC转换回来的值

voiddelay_1ms(void)//12mhzdelay1.01ms

{

unsignedcharx,y;

x=3;

while(x--)

{

y=40;

while(y--);

}

}

voiddisplay(void)//数码管显示函数

{

chark;

for(k=0;k<4;k++)

{

P1=dispbitcode[k];

P0=dispcode[dispbuf[k]];

if(k==1)//加上数码管的dp小数点

P0&=0x7f;

delay_1ms();

}

}

/************

读ADC0832函数

************/

//采集并返回

unsignedintAdc0832(unsignedcharchannel)//AD转换,返回结果

{

uchari=0;

ucharj;

uintdat=0;

ucharndat=0;

if(channel==0)channel=2;

if(channel==1)channel=3;

ADDI=1;

_nop_();

_nop_();

ADCS=0;//拉低CS端

_nop_();

_nop_();

ADCLK=1;//拉高CLK端

_nop_();

_nop_();

ADCLK=0;//拉低CLK端,形成下降沿1

_nop_();

_nop_();

ADCLK=1;//拉高CLK端

ADDI=channel&0x1;

_nop_();

_nop_();

ADCLK=0;//拉低CLK端,形成下降沿2

_nop_();

_nop_();

ADCLK=1;//拉高CLK端

ADDI=(channel>>1)&0x1;

_nop_();

_nop_();

ADCLK=0;//拉低CLK端,形成下降沿3

ADDI=1;//控制命令结束

_nop_();

_nop_();

dat=0;

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

{

dat|=ADDO;//收数据

ADCLK=1;

_nop_();

_nop_();

ADCLK=0;//形成一次时钟脉冲

_nop_();

_nop_();

dat<<=1;

if(i==7)dat|=ADDO;

}

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

{

j=0;

j=j|ADDO;//收数据

ADCLK=1;

_nop_();

_nop_();

ADCLK=0;//形成一次时钟脉冲

_nop_();

_nop_();

j=j<<7;

ndat=ndat|j;

if(i<7)ndat>>=1;

}

ADCS=1;//拉低CS端

ADCLK=0;//拉低CLK端

ADDO=1;//拉高数据端,回到初始状态

dat<<=8;

dat|=ndat;

return(dat);//returnadk

}

voidmain(void)

{

while

(1)

{unsignedinttemp;

f

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 小升初

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1