51单片机 YF-S201水流量检测传感器的使用

第一章 YF-S201水流量检测传感器介绍

点击查看 —YF-S201水流量检测传感器接线介绍
点击查看 —YF-S201水流量检测传感器使用

每升水脉冲数:420

51单片机程序,测量结果通过LCD1602显示

第二章 主程序

主程序

#include<reg51.h>
#include<intrins.h>	
#include"lcd.h"

unsigned long PluNum=0;	//检测速度转化来的脉冲量

int i = 0 ;  //记录水量

sbit KEY3=P3^2;
//定义独立按键K3控制脚

sbit KEY4=P3^0;


//定义LED1管脚
sbit LED1=P2^0;

/*************定时器0初始化程序***************/
void exti0_init(void)
{
	IT0=1;//跳变沿触发方式(下降沿)
	EX0=1;//打开INT0的中断允许
	EA=1;//打开总中断
}

//蜂鸣器相关

sbit BEEP=P2^5;	//将P2.5管脚定义为BEEP

typedef unsigned int u16;	//对系统默认数据类型进行重定义
typedef unsigned char u8;
/*******************************************************************************
* 函 数 名       : delay_10us
* 函数功能		 : 延时函数,ten_us=1时,大约延时10us
* 输    入       : ten_us
* 输    出    	 : 无
*******************************************************************************/
void delay_10us(u16 ten_us)
{
	while(ten_us--);	
}


//unsigned char PuZh[]=" Pechin Science ";
unsigned char code ASCII[15] =    {'0','1','2','3','4','5','6','7','8','9','.','-','M'};

static unsigned char DisNum = 0; //显示用指针				  
       unsigned int  time=0;

	   unsigned char disbuff[4]	   ={ 0,0,0,0,};

		 //流量动态显示函数
void Conut(void)
	{
	  disbuff[0]=i%1000/100;
	  disbuff[1]=i%1000%100/10;
	  disbuff[2]=i%1000%10 %10;
//	  DisplayOneChar(0, 1, ASCII[disbuff[0]]);
//	  DisplayOneChar(1, 1, ASCII[10]);	//显示点
	  DisplayOneChar(2, 1, ASCII[disbuff[1]]);
	  DisplayOneChar(3, 1, ASCII[disbuff[2]]);
//	  DisplayOneChar(4, 1, ASCII[12]);	//显示M
		
		KEY4 = 1 ;
		delay_10us(100);
		KEY4 = 0 ;
	}


void delayms(unsigned int ms)
{
	unsigned char i=100,j;
	for(;ms;ms--)
	{
		while(--i)
		{
			j=10;
			while(--j);
		}
	}
}

void main(void)
{
	
	exti0_init();//外部中断0配置
	
	LcdInit();
  LcdShowStr(0,0,"Water Flow :0.1L");//第一行显示
	while(1)
	{
		Conut();
	}
			
}


void exti0() interrupt 0 //外部中断0中断函数
{
			PluNum++;	
	
	if(PluNum==42)
	{
	   i++;
		PluNum=0;
	}
			
}

第三章 LCD1602驱动程序

LCD1602驱动程序

驱动头文件 .h文件

lcd.h 头文件

#ifndef __LCD_H_
#define __LCD_H_
/**********************************
当使用的是4位数据传输的时候定义,
使用8位取消这个定义
**********************************/
//#define LCD1602_4PINS

/**********************************
包含头文件
**********************************/
#include<reg51.h>

//---重定义关键词---//
#ifndef uchar
#define uchar unsigned char
#endif

#ifndef uint 
#define uint unsigned int
#endif

/**********************************
PIN口定义
**********************************/
#define LCD1602_DATAPINS P0
sbit LCD1602_E=P2^7;
sbit LCD1602_RW=P2^5;
sbit LCD1602_RS=P2^6;

/**********************************
函数声明
**********************************/
/*在51单片机12MHZ时钟下的延时函数*/
void Lcd1602_Delay1ms(uint c);   //误差 0us
/*LCD1602写入8位命令子函数*/
void LcdWriteCom(uchar com);
/*LCD1602写入8位数据子函数*/	
void LcdWriteData(uchar dat)	;
/*LCD1602初始化子程序*/		
void LcdInit();	
void LcdSetCursor(unsigned char x,unsigned char y);  //坐标显示
void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str);     //显示字符串
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
					  

#endif

驱动文件lcd.c

驱动主程序 .c文件

#include"lcd.h"

/*******************************************************************************
* 函 数 名         : Lcd1602_Delay1ms
* 函数功能		   : 延时函数,延时1ms
* 输    入         : c
* 输    出         : 无
* 说    名         : 该函数是在12MHZ晶振下,12分频单片机的延时。
*******************************************************************************/

void Lcd1602_Delay1ms(uint c)   //误差 0us
{
    uchar a,b;
	for (; c>0; c--)
	{
		 for (b=199;b>0;b--)
		 {
		  	for(a=1;a>0;a--);
		 }      
	}
    	
}

/*******************************************************************************
* 函 数 名         : LcdWriteCom
* 函数功能		   : 向LCD写入一个字节的命令
* 输    入         : com
* 输    出         : 无
*******************************************************************************/
#ifndef 	LCD1602_4PINS	 //当没有定义这个LCD1602_4PINS时
void LcdWriteCom(uchar com)	  //写入命令
{
	LCD1602_E = 0;     //使能
	LCD1602_RS = 0;	   //选择发送命令
	LCD1602_RW = 0;	   //选择写入
	
	LCD1602_DATAPINS = com;     //放入命令
	Lcd1602_Delay1ms(1);		//等待数据稳定

	LCD1602_E = 1;	          //写入时序
	Lcd1602_Delay1ms(5);	  //保持时间
	LCD1602_E = 0;
}
#else 
void LcdWriteCom(uchar com)	  //写入命令
{
	LCD1602_E = 0;	 //使能清零
	LCD1602_RS = 0;	 //选择写入命令
	LCD1602_RW = 0;	 //选择写入

	LCD1602_DATAPINS = com;	//由于4位的接线是接到P0口的高四位,所以传送高四位不用改
	Lcd1602_Delay1ms(1);

	LCD1602_E = 1;	 //写入时序
	Lcd1602_Delay1ms(5);
	LCD1602_E = 0;

//	Lcd1602_Delay1ms(1);
	LCD1602_DATAPINS = com << 4; //发送低四位
	Lcd1602_Delay1ms(1);

	LCD1602_E = 1;	 //写入时序
	Lcd1602_Delay1ms(5);
	LCD1602_E = 0;
}
#endif
/*******************************************************************************
* 函 数 名         : LcdWriteData
* 函数功能		   : 向LCD写入一个字节的数据
* 输    入         : dat
* 输    出         : 无
*******************************************************************************/		   
#ifndef 	LCD1602_4PINS		   
void LcdWriteData(uchar dat)			//写入数据
{
	LCD1602_E = 0;	//使能清零
	LCD1602_RS = 1;	//选择输入数据
	LCD1602_RW = 0;	//选择写入

	LCD1602_DATAPINS = dat; //写入数据
	Lcd1602_Delay1ms(1);

	LCD1602_E = 1;   //写入时序
	Lcd1602_Delay1ms(5);   //保持时间
	LCD1602_E = 0;
}
#else
void LcdWriteData(uchar dat)			//写入数据
{
	LCD1602_E = 0;	  //使能清零
	LCD1602_RS = 1;	  //选择写入数据
	LCD1602_RW = 0;	  //选择写入

	LCD1602_DATAPINS = dat;	//由于4位的接线是接到P0口的高四位,所以传送高四位不用改
	Lcd1602_Delay1ms(1);

	LCD1602_E = 1;	  //写入时序
	Lcd1602_Delay1ms(5);
	LCD1602_E = 0;

	LCD1602_DATAPINS = dat << 4; //写入低四位
	Lcd1602_Delay1ms(1);

	LCD1602_E = 1;	  //写入时序
	Lcd1602_Delay1ms(5);
	LCD1602_E = 0;
}
#endif
/*******************************************************************************
* 函 数 名       : LcdInit()
* 函数功能		 : 初始化LCD屏
* 输    入       : 无
* 输    出       : 无
*******************************************************************************/		   
#ifndef		LCD1602_4PINS
void LcdInit()						  //LCD初始化子程序
{
 	LcdWriteCom(0x38);  //开显示
	LcdWriteCom(0x0c);  //开显示不显示光标
	LcdWriteCom(0x06);  //写一个指针加1
	LcdWriteCom(0x01);  //清屏
	LcdWriteCom(0x80);  //设置数据指针起点
}
#else
void LcdInit()						  //LCD初始化子程序
{
	LcdWriteCom(0x32);	 //将8位总线转为4位总线
	LcdWriteCom(0x28);	 //在四位线下的初始化
	LcdWriteCom(0x0c);  //开显示不显示光标
	LcdWriteCom(0x06);  //写一个指针加1
	LcdWriteCom(0x01);  //清屏
	LcdWriteCom(0x80);  //设置数据指针起点
}
#endif




void LcdSetCursor(unsigned char x,unsigned char y)  //坐标显示
{
    unsigned char addr;
    if(y == 0)
        addr = 0x00 + x;
    else
        addr = 0x40 + x;
    
    LcdWriteCom(addr|0x80);
}

//按指定位置显示一个字符
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
	Y &= 0x1;
	X &= 0xF; //限制X不能大于15,Y不能大于1
	if (Y) X |= 0x40; //当要显示第二行时地址码+0x40;
	X |= 0x80; //算出指令码
	LcdWriteCom(X); //发命令字
	LcdWriteData(DData); //发数据
}


void LcdShowStr(unsigned char x,unsigned char y,unsigned char *str)     //显示字符串
{
    LcdSetCursor(x,y);      //当前字符的坐标
    while(*str != '\0')
    {
        LcdWriteData(*str++);
    }
}

第四章 其他参考程序

#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#define uchar unsigned char  //无符号字符型 宏定义	变量范围0~255
#define uint  unsigned int	 //无符号整型 宏定义	变量范围0~65535
 
sbit rs=P1^0;	 //寄存器选择信号 H:数据寄存器  	L:指令寄存器
sbit rw=P1^1;	 //寄存器选择信号 H:数据寄存器  	L:指令寄存器
sbit e =P1^2;	 //片选信号   下降沿触发

unsigned long PluNum=0;	//检测速度转化来的脉冲量

sbit beep = P1^6;   //蜂鸣器IO口定义

uchar flag_1s=1 ;   //1秒的变量

float shudu=0;	 //速度
float LJ=0;	 //累计流量 

uint set_LJ=50;  //设置累计流量 

sbit KEY2 = P1^5;//按键1
sbit KEY1 = P1^4;//按键2
 	

/***********************1ms延时函数*****************************/
void delay_1ms(uint q)
{
	uint i,j;
	for(i=0;i<q;i++)
		for(j=0;j<120;j++);
}


/********************************************************************
* 名称 : delay_uint()
* 功能 : 小延时。
* 输入 : 无
* 输出 : 无
***********************************************************************/
void delay_uint(uint q)
{
	while(q--);
}


/********************************************************************
* 名称 : write_com(uchar com)
* 功能 : 1602指令函数
* 输入 : 输入的指令值
* 输出 : 无
***********************************************************************/
void write_com(uchar com)
{
 	rs=0;	     //写指令
	rw=0;	     //对1602写操作
	P0=com;	     //P0口对1602写指令数据 
	delay_uint(25);
	e=1;		 //e=1使能信号 
	delay_uint(100);   //延时一下等1602完成操作
	e=0;
}

/********************************************************************
* 名称 : write_data(uchar dat)
* 功能 : 1602写数据函数
* 输入 : 需要写入1602的数据
* 输出 : 无
***********************************************************************/
void write_data(uchar dat)
{
 	rs=1;	     //写数据
	rw=0;	     //对1602写操作
	P0=dat;	 	 //P0口对1602写数据 
	delay_uint(25);
	e=1;		 //e=1使能信号 
	delay_uint(100);   //延时一下等1602完成操作
	e=0;	
}

/********************************************************************
* 名称 : write_string(uchar hang,uchar add,uchar *p)
* 功能 : 改变液晶中某位的值,如果要让第一行,第五个字符开始显示"ab cd ef" ,调用该函数如下
	 	 write_string(1,5,"ab cd ef;")
* 输入 : 行,列,需要输入1602的数据
* 输出 : 无
***********************************************************************/
void write_string(uchar hang,uchar add,uchar *p)
{
	if(hang==1)   
		write_com(0x80+add);	   //1602写第一行的地址 
	else
		write_com(0x80+0x40+add);   //1602写第二行的地址 
	while(1)														 
	{
		if(*p == '\0')  break;	//\0字符串的结尾标志  break结束while循环 结束写字符
		write_data(*p);	    //写数据 
		p++;	            //指针地址加1  
	}	
}

/***********************lcd1602上显示3位十进制数************************/
void write_kcd3_sd(uchar hang,uchar add,uint date)
{
	if(hang==1)   
		write_com(0x80+add);	   //1602写第一行的地址 
	else
		write_com(0x80+0x40+add);  //1602写第二行的地址 
 	write_data(0x30+date/100%10);  //显示百位数
	write_data('.');			   //显示小数点
	write_data(0x30+date/10%10);   //显示十位数
	write_data(0x30+date%10);	   //显示个位数
}

/***********************lcd1602上显示4位十进制数************************/
void write_kcd3_lj(uchar hang,uchar add,uint date)
{
 	if(hang==1)   
		write_com(0x80+add);	   //1602写第一行的地址 
	else
		write_com(0x80+0x40+add);  //1602写第二行的地址 
 	write_data(0x30+date/1000%10); //显示千位数
	write_data(0x30+date/100%10);  //显示百位数
	write_data(0x30+date/10%10);   //显示十位数
	write_data('.');			   //显示小数点
	write_data(0x30+date%10);	   //显示个位数
	write_data('L');
}


/***********************lcd1602初始化设置************************/
void init_1602()
{
	write_com(0x38);  //显示模式设置:16×2显示,5×7点阵,8位数据接口 不检测忙信号
	write_com(0x0c);  //开显示 不显示光标
	write_com(0x06);  //当写一个字符是,地址指针加 1
	write_string(1,0,"Sd:0.00L/S       ");	  //初始化1602显示 
	write_string(2,0,"LJ:000.0L H000.0L");	  //初始化1602显示 

}

/*************定时器0初始化程序***************/
void time_init()	  
{
	EA   = 1;	 	  //开总中断
	TMOD = 0X01;	  //定时器0工作方式1
	ET0  = 1;		  //开定时器0中断 
	TR0  = 1;		  //允许定时器0定时
	TH0 = 0x3c;
	TL0 = 0xb0;     // 50ms
}

/****************报警函数***************/
void clock_h_l()
{
	if(LJ > set_LJ)
	{
		beep = ~beep; 	  //蜂鸣器报警	
	}
	else 
	{
		beep = 1;		//取消报警
	}	
}

/*------------------------------------------------
                    主函数
------------------------------------------------*/
void main (void)
{     
    int value;	         
	beep = 0;		 //开机叫一声   
	delay_1ms(150);
	P0 = P1 = P2 = P3 = 0xff;	   //初始化单片机IO口为高电平
	EX0=1;         //外部中断0开
	IT0=1;         //边沿触发
    EA=1;          //全局中断开
	time_init();	 // 定时器0初始化程序
 	init_1602();                    //1602初始化
	while(1)         //主循环
	{
		
		if(flag_1s == 1)
		{
			flag_1s = 0;
			shudu=PluNum * (1/450);	//计算瞬时流量 一个脉冲代表1/450ml 
			LJ=LJ+PluNum * (1/450)  ;	 //累计计算累计流量
 			write_kcd3_sd(1,2,shudu);	    //显示速度 
			write_kcd3_lj(2,2,LJ);	    //显示累计流量  
			write_kcd3_lj(2,10,set_LJ);	    //显示设置累计流量  
		}
		if(KEY1==0)
		{
			delay_1ms(50);
			if(KEY1==0) 
			{
				set_LJ ++;	  //报警累计流量+1 
 				write_kcd3_lj(2,11,set_LJ);	    //显示设置累计流量  
 			}

		}
		if(KEY2==0)
		{
			delay_1ms(50);
			if(KEY2==0) 
			{
				if(set_LJ != 0)
					set_LJ--;	 //报警累计流量-1 
				write_kcd3_lj(2,11,set_LJ);	    //显示设置累计流量  
 			}
		}
		value ++;
		if(value >= 200)
		{
			value = 0;
			clock_h_l();   //报警
		}
		delay_1ms(1);
	}
}

/*************定时器0中断服务程序***************/
void time0_int() interrupt 1
{	
	uchar value;
	TH0 = 0x3c;
	TL0 = 0xb0;     // 50ms
	value ++;	 
	if(value >= 20)
	{
		flag_1s = 1;	   //1秒
		value = 0;
	}
}

/*------------------------------------------------
                 外部中断程序
------------------------------------------------*/
void ISR_Key(void) interrupt 0 using 1
{
	PluNum++;		
}

  • 5
    点赞
  • 88
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嵌入式路上的小菜鸟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值