⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ocm4x8c.c

📁 单片机应用系统(光盘内容)
💻 C
字号:
#include <reg51.h>
#include <intrins.h>
#define uint  unsigned int
#define uchar unsigned char
#define comm  0
#define dat   1
sbit RS=P2^6;								//高电平数据,低电平命令
sbit RW=P2^5;								//读写控制脚,高电平读,低电平写
sbit E=P2^7;								//输入使能
sbit busy=P0^7;								//忙信号检测
sbit SDA=P1^0;								//I2C数据线
sbit SCL=P1^1;								//I2C时钟线
sbit Buzz=P1^2;								//蜂鸣器控制脚
sbit LED_G=P1^3;							//绿色指示灯控制脚
sbit LED_R=P1^4;							//红色指示灯控制脚
uchar buf[6],dis_buf[6];					//数据缓冲区
uint buffer[3];								//测量距离存储区
uint dis;									//最小距离存储器
uchar code tab1[]={"距离障碍物:"};			//显示字符
uchar code tab2[]={"无障碍物"};
uchar code tab[]={"0123456789cm"};
/*****************函数声明*****************/
void start_bit(void);						//I2C起始函数
void stop_bit(void);						//I2C停止函数
void mast_ack(void);						//主答函数
bit write_8bit(uchar ch);					//I2C总线写8位数据函数
bit page_rd(uchar device,uint fir_ad,uint count,uchar *firw_ad);//I2C总线页面读函数
uint measure(uchar device);					//启动测距函数
uint get_distance(void);					//读测距值函数
void judge(void);							//判断距离函数
void init_lcd (void);						//LCD初始化函数
void wr_lcd(uchar dat_comm,uchar content);//LCD写数据函数
void chk_busy (void);						//忙信号检测
void chn_disp(uchar code *chn,uchar pos,uchar n);//显示提示汉字函数
uchar dat_adj(uint dat1);					//显示数据调整函数
void disp_dist(uchar dat1);					//显示距离函数
void disp(void);							//显示函数
void delay (uint us);						//延时函数
void delay1 (uint ms);						//延时函数
/*********************主程序***********************/
void main ()
{
    init_lcd ();							//初始化LCD
    while (1)
    {
		judge();							//判断障碍物距离
		disp();								//显示提示信息
	}
}
/********************I2C起始函数*******************/
void start_bit(void)
{
    SCL=1;_nop_();
    SDA=1;_nop_();
    SDA=0;_nop_();
    SCL=0;_nop_();
}
/*******************I2C停止函数********************/
void stop_bit(void)
{
    SDA=0;_nop_();
    SCL=1;_nop_();
    SDA=1;_nop_();
}
/****************I2C总线写8位数据函数**************/
bit write_8bit(uchar ch)
{
    uchar i=8;
    bit fan_w;
    SCL=0;_nop_();
    while (i--)
    {
        SDA=(bit)(ch&0x80);_nop_();				//获取发送位数据
        ch<<=1;
        SCL=1;_nop_();
        SCL=0;_nop_();
    }
    SDA=1;_nop_();
    SCL=1;_nop_();
    fan_w=SDA;									//应答位
    SCL=0;_nop_();
    return(fan_w);								//返回应答位
}
/*****************I2C总线页面读函数****************/
bit page_rd(uchar device,uint fir_ad,uint count,uchar *firw_ad)
{
	uchar j=8;
	uchar data *ufirstwr_ad;
	ufirstwr_ad=firw_ad;
	start_bit();
	if(write_8bit(device)!=0){stop_bit();return(0);}//送器件地址,写数据
	if(write_8bit(fir_ad)!=0){stop_bit();return(0);}//送读数据寄存器首地址
	start_bit();
	if(write_8bit(device|0x01)!=0){stop_bit();return(0);}//准备读数据
	while(count--)
	{
		uchar i=8;
		while(i--)								//读入数据
		{
			(*ufirstwr_ad)<<=1;
			SCL=1;_nop_();
			if(SDA) (*ufirstwr_ad)|=0x01;
			SCL=0; _nop_();
		}
		ufirstwr_ad++;
		mast_ack();								//主机产生应答位
	}
	while(j--)
	{
		(*ufirstwr_ad)<<=1;
		SCL=0;_nop_();_nop_();SCL=1;
		if(SDA) (*ufirstwr_ad)|=0x01;
	}
	stop_bit();									//停止I2C数据传送
	return(1);
}
/*********************主答函数*********************/
void mast_ack(void)
{
   SCL=0;_nop_();
   SDA=0;_nop_();
   SCL=1;_nop_();
   SCL=0;_nop_();
   SDA=1;_nop_();
}
/********************测距函数******************/
uint measure(uchar device)
{
	uint temp;
	start_bit();								//启动I2C
	while(!write_8bit(device));					//发器件地址
	while(!write_8bit(0x00));					//命令寄存器
	while(!write_8bit(0x51));					//以厘米为单位返回距离
	stop_bit();									//停止I2C
	delay1(100);
	while(!page_rd(device,0x02,2,buf));			//读距离值
	temp=(buf[0]<<8)|buf[1];
	return(buffer);								//返回距离值
}
/*******************求最小测距值函数*****************/
uint get_distance(void)
{
	uint mix;
	buffer[0]=measure(0xe0);					//读左侧测距值
	buffer[1]=measure(0xe2);					//读中间测距值
	buffer[2]=measure(0xe4);					//读右侧测距值
	if(buffer[0]<buffer[1])
		mix=buffer[0];
	else
		mix=buffer[1];
	if(mix>buffer[2])mix=buffer[2];				//合并为一个16位数据
	return(mix);
}
/*******************判断距离函数*******************/
void judge(void)
{
	dis=get_distance();							//读取测量距离最小值
	if(dis<5000)
	{
		LED_R=0;								//红色报警灯亮
		LED_G=1;								//绿色报警灯灭
	}	
	else
	{
		LED_R=1;								//红色报警灯灭
		LED_G=0;								//绿色报警灯亮
	}	
	if(dis<3000)
		Buzz=0;									//蜂鸣器报警
	else
		Buzz=1;									//蜂鸣器停止报警
}
/******************LCD初始化函数*******************/
void init_lcd (void)
{
	wr_lcd (comm,0x30);							//基本指令动作   
	wr_lcd (comm,0x01);							//清屏
	wr_lcd (comm,0x06);							//光标的移动方向
	wr_lcd (comm,0x0c);							//开显示,关游标
}
/*******************LCD写数据函数*****************/
void wr_lcd (uchar dat_comm,uchar content)
{
	chk_busy ();
	if(dat_comm)
	{
		RS=1;									//数据
		RW=0;									//写入
	}
	else 
	{
		RS=0;									//命令
		RW=0;									//写入
	}
	P0=content;									//输出数据或命令
	E=1;
	E=0;
}
/********************忙信号检测********************/
void chk_busy (void)
{
	P0=0xff;
	RS=0;
	RW=1;
	E=1;
	while(busy==1);								//检验LCD是否处于忙状态
	E=0;
}
/****************显示提示汉字函数******************/
void chn_disp(uchar code *chn,uchar pos,uchar n)
{
	uchar i;
	wr_lcd (comm,0x30);							//基本指令动作 
	wr_lcd (comm,pos);							//显示位置
	for (i=0;i<n;i++)
		wr_lcd (dat,chn[i]);
}
/****************显示数据调整函数******************/
uchar dat_adj(uint dat1)
{
    uchar i;
	dis_buf[0]=(uchar)(dat1/1000);				//高度千位
	dis_buf[1]=(uchar)((dat1%1000)/100);		//高度百位
	dis_buf[2]=(uchar)((dat1%100)/10);			//高度十位
	dis_buf[3]=(uchar)(dat1%10);				//高度个位
	dis_buf[4]=10;
	for(i=0;i<3;i++)
	{
		if(dis_buf[i]!=0)break;					//确定显示位数
	}
	return(i);
}
/******************显示距离函数********************/
void disp_dist(uchar dat1)
{
	uchar temp,i;
	if(dat1>5000)
	{
		chn_disp(tab2,0x92,4);					//无障碍显示
	}
	else
	{
		temp=dat_adj(dat1);
		wr_lcd(comm,0x30);						//基本指令
		wr_lcd(comm,temp+0x92);					//设置显示起始位置
		for (i=temp;i<6;i++)					//送显示数据
			wr_lcd(dat,tab[dis_buf[i]]);
	}
}
/********************显示函数**********************/
void disp(void)
{
	chn_disp(tab1,0x80,11);						//显示提示汉字
	disp_dist(dis);								//显示距离值
}
/********************延时函数**********************/
void delay (uint us)
{
	while(us--);
}
/********************延时函数**********************/
void delay1 (uint ms)
{
	uint i,j;
	for(i=0;i<ms;i++)
	for(j=0;j<15;j++)
	delay(1);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -