2020-08-15

超声波报警器
温湿度显示器
本章节介绍超声波测距报警器以及通过按键按下切换屏幕显示温湿度。

主函数

#include "csb12864.h"
#include "WD.H"

uchar code table1[]="距离为: ";       //定义需要显示的数组
uchar code table2[]="I am over you";
//uchar code table2[]="GOOD GOOD study"; 
uchar code table3[]="CM";
uchar code A[]="0123456789";
uchar code lcd[]={"当前的温湿度"};
uchar code lcd1[]={"温度;      ℃"};
uchar code lcd2[]={"湿度:    %RH"};

//uchar  str1[]={"   "};
//uchar  str2[]={"   "};
uint num,bai,shi,ge;

/*************延时函数****************/

void delay(uint t)//消抖
{
  int i;
  for(i = t;i >0;i--);
}


void Delay20us()		//@11.0592MHz
{
	unsigned char i;

	_nop_();
	_nop_();
	_nop_();
	i = 52;
	while (--i);
}

/**毫秒级延时函数**/
void delayms(uint xms)
{
	uint i,j;
	for(i=xms;i>0;i--)
		for(j=110;j>0;j--);
}

/***********中超声波测距函数************/
//unsigned int csbProcess_F()
uint csbProcess_F()
{
   uint i = 0;
	 float Distance_float = 0;	          //定义float类型变量Distance_float
	 uint Distance_int =0;	              //定义int类型变量Distance_int			       

   TMOD |= 0x01;				                //设定定时器0方式为1
   Trig =	1;					                  //控制端发射高电平
   Delay20us();					                //延时10us以上
   Trig = 0;					                  //延时10us以上后把控制端拉低
	
   while (!Echo && i<20000)	            //低电平等待,等待高电平出现,定义i变量,防止卡死
   {
    i++;  
   }
   i = 0;
   TR0 = 1;						                  //打开定时器0,开始计时

   while (Echo && i<20000)		          //高电平等待,等待低电平出现,定义i变量,防止卡死
   {
    i++;                                //等待变量自加
   }
   TR0 = 0; 					                   //关闭定时器0,终止计时
	 
   Distance_float = (TH0*256+TL0)*1.70/100;  //计算距离

   TH0 = 0;						                   //计数器清零
   TL0 = 0;						                   //计数器清零
	 
   Distance_int = (uint)Distance_float;  //float类型的数据转换成int类型的数据
   return Distance_int;                  //返回距离值
	 
}

/**写指令数据到LCD**/
void write_com(uchar com)
{
	RS = 0;                               //选择指令信号
	RW = 0;                               //写入信号
	P0 = com;                             //存放数据
	delayms(5);                           //短暂延时待存放完毕
	E = 1;                                //开始传输数据
	delayms(5);                           //短暂延时待传输数据完毕
	E = 0;                                //传输完成,使能端置0 
}

/**写显示数据到LCD**/
void write_data(uchar Data)
{
	RS = 1;                                //选择数据信号
	RW = 0;                                //写入信号
	P0 = Data;                             //存放数据
	delayms(5);                            //短暂延时待存放完毕
	E = 1;                                 //显示数据
	delayms(5);                            //短暂延时待显示完毕
	E = 0;                                 //显示完成,使能端置0 
}

/*初始化12864*/
void init_12864()
{
	PSB = 1;                               //选择并行接口
	E = 0;                                 //使能端置0 
	write_com(0x30);                       //功能设定为基本指令
	delayms(5);
	write_com(0x0c);                       //开启整体显示,关光标
	delayms(5);
	write_com(0x01);                       //清屏
	delayms(5);
}

void place(uchar x, uchar y)
{
	uchar sum;
	if(x == 1)
	{x = 0x80;}                            //字节地址
	if(x == 2)
	{x = 0x90;}
	if(x == 3)
	{x = 0x88;}
	if(x == 4)
	{x = 0x98;}
	sum = x + y;
	write_com(sum);                        //将行数和列数整合
}

/**显示字符串**/
void display(uchar x, uchar y, uchar *p)
{
	 place(x,y);                            //选择位置,x以字节为单位,y以位为单位
	 while(*p != '\0')                      //判断是否读到最后一个字符
	 {
		 write_data(*p);                      //显示数据
		 p++;                                 //指针指向下一个元素
	 }
}
/**显示字符**/
void display_z(uchar x, uchar y, uchar Data)
{
	  place(x,y);                            //选择位置,x以字节为单位,y以位为单位
  	write_data(Data);                      //显示数据
}

/**超声波距离显示函数**/
void display_CSB(uint bai,uchar shi,uchar ge)
{
		display(1,0, table1);	  
		display(2,5,table3);
		display_z(2,2,A[bai]);               //显示距离的百位,下面依次为十、个
		display_z(2,3,A[shi]);
		display_z(2,4,A[ge]);
		display(3, 0, table2);
}

void Delay10ms()		//@11.0592MHz
{
	unsigned char i, j;

	_nop_();
	_nop_();
	i = 108;
	j = 144;
	do
	{
		while (--j);
	} while (--i);
}


/*主函数*/
void main()
{
	init_12864();                          //首先初始化LCD12864
	while(1)
	{
		num=csbProcess_F();                  //获取距离值
		bai=num/100;      	                 //获取距离的百位,下面依次为十、个
	  shi=num%100/10; 
	  ge=num%10; 
		
		if(key==0)
		{
			delay(500);
			if(key==0)
			{
				delay(500);
				//init_12864();
				write_com(0x01); //清屏	
				 //delay(500);
				display(1,0,lcd);
				Rec_DHTI0();
				xianshi();
				delay(500);
				while(!key);//判断按键是否弹起
				write_com(0x01);
			}
		}
	 else if(num<10)
	 {
//					while(1)
//			{
				BELL = 0;
				Delay10ms();	   //延时10毫秒
				BELL = 1;
				Delay10ms();   //延时10毫秒
				display_CSB(bai,shi,ge);
//			}
			}	
			 else	
			 {		 
				display_CSB(bai,shi,ge);  	 //调用显示函数
			 }

		 }
		
}

```c
#ifndef _FMQ_H_
#define _FMQ_H_
#include<reg51.h>
//#include "csb12864.h"
//#define uchar unsigned char
//
//#define uint  unsigned int	  
//sbit BELL = P1^2;		  	//设置P1.2口,为控制蜂鸣器发声的引脚									  
//extern void Delay10ms();
#endif

温湿度函数

#include "WD.H"

uchar  str1[]={"   "};
uchar  str2[]={"   "};
uchar RL_data, RH_data, TH_data, TL_data, CK_data;
uchar undata;

void Rec_DHTI0()
{
	//主机信号
	DHTI0 = 1;        //拉高
	Delay1000ms();  	//延时1s以上 等待状态稳定
	DHTI0 = 0;        //拉低	
	Delay18ms();     //主机拉低25Ms
	DHTI0 = 1;        //拉高
	Delay40us();  //主机拉高40us
	//从机响应信号
	if(!DHTI0)
	{
		  while(!DHTI0);    //while(!0)==(1)判断从机是否发出80毫秒的低电平响应信号
			while(DHTI0);     //判断从机是否发出80毫秒的高电平 , 发出则开始采集数据
		  RH_data = Read_8bit();  //温度整数部分
		  RL_data = Read_8bit();  //温度小数部分
		  TH_data = Read_8bit();  //湿度整数部分
		  TL_data = Read_8bit();  //湿度小数部分
		  CK_data = Read_8bit();  //校验位
		
		  undata = RH_data + RL_data + TH_data + TL_data; //校验获取的数据
	}
	//湿度整数
	str1[0] = (char)(0x30 + RH_data/10);   //0x30将数字0-9转化为字符0-9
	str1[1] = (char)(0x30 + RH_data%10);
	//温度整数
	str2[0] = (char)(0x30 + TH_data/10);
	str2[1] = (char)(0x30 + TH_data%10);
}
void Delay1000ms()		//@11.0592MHz
{
	unsigned char i, j, k;
	_nop_();
	_nop_();
	i = 43;
	j = 6;
	k = 203;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}

void Delay18ms()		//@11.0592MHz
{
	unsigned char i, j, k;

	i = 1;
	j = 194;
	k = 160;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}
void Delay40us()		//@11.0592MHz
{
	unsigned char i;

	i = 108;
	while (--i);
}
void Delay30us()		//@11.0592MHz
{
	unsigned char i;

	i = 80;
	while (--i);
}


uchar Read_8bit()
{
	uint i;
	uchar temp = 0;
	uchar dat;
	for(i = 0;i < 8;i++)
	{
		//以下部分判断数据是0或是1
		while(!DHTI0);  //等待50毫秒的低电平结束
		Delay30us();
	  temp = 0;
		if(DHTI0 == 1)
		{
			temp = 1;
		}
		while(DHTI0);   //等待高电平结束
	  dat<<=1;
		dat = dat|temp;
	}
	return dat;
}
void xianshi()
{
	uchar k,j;
//  温度
	for(j = 0;j < 2;j++)
	{
		place(3,j+4);  //显示位置,第3行,j为0或1,j+4为第几位开始显示
		write_data(str2[j]);	
	}
//  湿度
	for(k = 0;k < 2;k++)
	{
		place(4,k+4);
		write_data(str1[k]);
	}	
}

函数的封装

#ifndef _WD_H_
#define _WD_H_
#include "csb12864.h"

extern  void Rec_DHTI0();
extern void Delay1000ms();
extern void Delay30us();
extern void Delay18ms()	;	//@11.0592MHz
extern void Delay40us();		//@11.0592MHz
extern uchar Read_8bit();
//extern void 	LCD_Display();
extern void xianshi();

#endif 

```c
#ifndef _CSB12864_H_
#define _CSB12864_H_



//#include <stc15f2k60s2.h> //头文件
#include <reg51.h>
#include <intrins.h>
#define uint unsigned int             //宏定义
#define uchar unsigned char
sbit RS = P2^2;                       // 指令/数据选择信号
sbit RW = P2^1;                       //读写选择信号
sbit E = P2^0;	                      //使能信号
sbit PSB = P2^3;                      //并/串行接口选择
sbit Trig = P3^6;	                    //控制端引脚声明
sbit BELL=P1^2;
sbit key=P3^5;
sbit DHTI0 = P3^0;
sbit led1=P2^4;  //定义LED灯
extern void place(uchar x, uchar y);
extern void delay(uint t);//消抖;
extern void Delay20us();		//@11.0592MHz;
extern void delayms(uint xms);
extern void Delay10ms();
extern uint csbProcess_F();
extern void write_com(uchar com);
extern void write_data(uchar Data);
extern void init_12864();
extern void place(uchar x, uchar y);
extern void display(uchar x, uchar y, uchar *p);
extern void display_z(uchar x, uchar y, uchar Data);
extern void display_CSB(uint bai,uchar shi,uchar ge);

#include "WD.H"
//uchar RL_data, RH_data, TH_data, TL_data, CK_data;
//uchar undata;

//uchar  str1[]={"   "};
//uchar  str2[]={"   "};
sbit Echo = P3^7;	//接收端引脚声明
//uint num,bai,shi,ge;

#endif

本章节基于C51的基础知识,运用到函数的封装,在封装的应注意函数定义的重复以及定义的变量是否重复,在函数的调用时应注意函数的名称,以及包含端口的头文件。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值