《传感器原理与应用》实验指导书
Proteus-V1.0 版本
1
实验 1:基于 DS18B20 传感器温度测量实验
步骤:(1)在 Proteus 软件画出电路图
(2)用 keil C 软件写出 C 程序,并生成.hex 文件,导入到单片机当中,进行仿真,
观察结果。
包括:2 个头文件 LCD1602.h 和 DS18B20.h; 1 个源文件 LCD_18b20.c;代码如下
LCD1602.h:
#include <at89x51.h>//用 AT89C51 时就用这个头文件
//#include <reg52.h>//用华邦 W78E58B 时必须用这个头文件
#include <intrins.h>
//注意那个 LCD_Wait()函数,它是判"忙"标志的,在实际硬件要把注掉的那种打开
//Port Definitions**********************************************************
sbit LcdRs = P2^0;
sbit LcdRw = P2^1;
sbit LcdEn = P2^2;
sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
//内部等待函数*****************************************************************
*********
2
unsigned char LCD_Wait(void)
{
LcdRs=0;
LcdRw=1; _nop_();
LcdEn=1; _nop_();
//while(DBPort&0x80);//在用 Proteus 仿真时,注意用屏蔽此语句,在调用 GotoXY()时,
会进入死循环,
//可能在写该控制字时,该模块没有返回写入完备命令,即
DBPort&0x80==0x80
//实际硬件时打开此语句
LcdEn=0;
return DBPort;
}
//向 LCD 写入命令或数据*********************************************************
***
#define LCD_COMMAND 0 // Command
#define LCD_DATA 1 // Data
#define LCD_CLEAR_SCREEN 0x01 // 清屏
#define LCD_HOMING 0x02 // 光标返回原点
void LCD_Write(bit style, unsigned char input)
{
LcdEn=0;
LcdRs=style;
LcdRw=0; _nop_();
DBPort=input;_nop_();//注意顺序
LcdEn=1; _nop_();//注意顺序
LcdEn=0; _nop_();
LCD_Wait();
}
//设置显示模式************************************************************
#define LCD_SHOW 0x04 //显示开
#define LCD_HIDE 0x00 //显示关
#define LCD_CURSOR 0x02 //显示光标
#define LCD_NO_CURSOR 0x00 //无光标
#define LCD_FLASH 0x01 //光标闪动
#define LCD_NO_FLASH 0x00 //光标不闪动
void LCD_SetDisplay(unsigned char DisplayMode)
{
LCD_Write(LCD_COMMAND, 0x08|DisplayMode);
}
3
//设置输入模式************************************************************
#define LCD_AC_UP 0x02
#define LCD_AC_DOWN 0x00 // default
#define LCD_MOVE 0x01 // 画面可平移
#define LCD_NO_MOVE 0x00 //default
void LCD_SetInput(unsigned char InputMode)
{
LCD_Write(LCD_COMMAND, 0x04|InputMode);
}
//初始化 LCD************************************************************
void LCD_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 递增, 画面不动
}
//************************************************************************
void GotoXY(unsigned char x, unsigned char y)
{
if(y==0)
LCD_Write(LCD_COMMAND,0x80|x);
if(y==1)
LCD_Write(LCD_COMMAND,0x80|(x-0x40));
}
void Print(unsigned char *str)
{
while(*str!='\0')
{
LCD_Write(LCD_DATA,*str);
str++;
}
}
void LCD_Print(unsigned char x, unsigned char y, unsigned char *str)
{
GotoXY(x,y);
Print(str);
4
}
DS18b20.h
#include <at89x51.h>//用 AT89C51 时就用这个头文件
//#include <reg52.h>//用华邦 W78E58B 时必须用这个头文件
sbit DQ = P3^4; //定义 DQ 引脚为 P3.4
/***********ds18b20 延迟子函数(晶振 12MHz )*******/
/************DS18B20 对时间要求很严,但只能长不能短
*************在 11.0592M 下也行,因为时间长些********/
void delay_18B20(unsigned int i)
{
while(i--);
}
/**********ds18b20 初始化函数**********************/
void Init_DS18B20(void)
{
unsigned char x=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 读一个字节**************/
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(4);
}
5
- 1
- 2
前往页