找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2340|回复: 4
打印 上一主题 下一主题
收起左侧

GP2Y0E02B测距模块89c52单片机串口程序

[复制链接]
跳转到指定楼层
楼主
ID:331263 发表于 2019-11-26 09:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 dingpeng1980 于 2019-12-11 01:28 编辑

iic接口,GPIO1需要3.3V转5v模块
程序已经调试可以用,串口输出晶振11.0592,波特率9600
SCL=P0^6;    iic接口需要3.3V转5v模块
SDA=P0^7;  iic接口需要3.3V转5v模块
GPIO1=P0^5;   //模块使能

#include<reg52.h>
#include<intrins.h>
#include<math.h>
#include "stdio.h"   //需要使用printf()函数故而包含该头文件

#define FOSC 11059200UL     //系统外部时钟频率(无符号长整型)
#define BAUD 9600           //欲配置的串口通信波特率值
#define DISTANCE_REG  0x5E
#define SHIFT         0x35
typedef unsigned int uint;
typedef unsigned char uchar ;
float distance = 0;                // 存储计算的距离
long high = 0, low = 0;              // 高字节和低字节的距离
int shift = 0;                   // 移位寄存器中的数值

uchar R_data;
bit R_flag=0;
sbit GPIO1=P0^5;   //模块使能
sbit SCL=P0^6;    //iic接口需要3.3V转5v模块
sbit SDA=P0^7;  //iic接口需要3.3V转5v模块

/*******************************************************************************
* 函数名         : Delay10us()
* 函数功能     : 延时10us
* 输入           : 无
* 输出           : 无
*******************************************************************************/
void Delay10us()
{
unsigned char a,b;
for(b=1;b>0;b--)
  for(a=2;a>0;a--);
}

/********************************************************************
* 名称 : Uart_Init()
* 功能 : 串口初始化,晶振11.0592,波特率9600,使能了串口中断
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Uart_Init(void)
{
SCON=0x50;       //10位数据异步通信模式,允许接收
TMOD=0x20;       //设定T1工作在8位自动重装载模式
TH1=-(FOSC/12/32/BAUD);    //赋值定时初值,为了设定波特率
TL1=TH1;       //赋值定时初值,为了设定波特率
TR1 = 1;       //启动T1运行控制位
ES = 1;        //使能UART中断开关ES
EA = 1;        //使能单片机总中断开关EA
}

/*******************************************************************************
* 函数名         : I2cStart()
* 函数功能   : 起始信号:在SCL时钟信号在高电平期间SDA信号产生一个下降沿
* 输入           : 无
* 输出           : 无
* 备注           : 起始之后SDA和SCL都为0
*******************************************************************************/
void I2cStart()
{
SDA=1;
Delay10us();
SCL=1;
Delay10us();//建立时间是SDA保持时间>4.7us
SDA=0;
Delay10us();//保持时间是>4us
SCL=0;   
Delay10us();  
}
/*******************************************************************************
* 函数名         : I2cStop()
* 函数功能   : 终止信号:在SCL时钟信号高电平期间SDA信号产生一个上升沿
* 输入           : 无
* 输出           : 无
* 备注           : 结束之后保持SDA和SCL都为1;表示总线空闲
*******************************************************************************/
void I2cStop()
{
SDA=0;
Delay10us();
SCL=1;
Delay10us();//建立时间大于4.7us
SDA=1;
Delay10us();  
}
/*******************************************************************************
* 函数名         : I2cSendByte(unsigned char dat)
* 函数功能   : 通过I2C发送一个字节。在SCL时钟信号高电平期间,保持发送信号SDA保持稳定
* 输入           : num
* 输出           : 0或1。发送成功返回1,发送失败返回0
* 备注           : 发送完一个字节SCL=0,SDA=1
*******************************************************************************/
unsigned char I2cSendByte(unsigned char dat)
{
unsigned char a=0,b=0;//最大255,一个机器周期为1us,最大延时255us。  
for(a=0;a<8;a++)//要发送8位,从最高位开始
{
  SDA=dat>>7;  //起始信号之后SCL=0,所以可以直接改变SDA信号
  dat=dat<<1;
  Delay10us();
  SCL=1;
  Delay10us();//建立时间>4.7us
  SCL=0;
  Delay10us();//时间大于4us  
}
SDA=1;
Delay10us();
SCL=1;
while(SDA)//等待应答,也就是等待从设备把SDA拉低
{
  b++;
  if(b>200)  //如果超过2000us没有应答发送失败,或者为非应答,表示接收结束
  {
   SCL=0;
   Delay10us();
   return 0;
  }
}
SCL=0;
Delay10us();
  return 1;  
}

/*******************************************************************************
* 函数名         : I2cReadByte()
* 函数功能     : 使用I2c读取一个字节
* 输入           : 无
* 输出           : dat
* 备注           : 接收完一个字节SCL=0,SDA=1.
*******************************************************************************/
unsigned char I2cReadByte()
{
unsigned char a=0,dat=0;
SDA=1;   //起始和发送一个字节之后SCL都是0
Delay10us();
for(a=0;a<8;a++)//接收8个字节
{
  SCL=1;
  Delay10us();
  dat<<=1;
  dat|=SDA;
  Delay10us();
  SCL=0;
  Delay10us();
}
return dat;  
}
/********************************************************************
* 名称 : Main()
* 功能 : 主函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void main()
{
GPIO1 = 1;
Uart_Init();

I2cStart();
I2cSendByte(0x80);//发送写器件地址
I2cSendByte(SHIFT);//发送要写入内存地址
I2cStop();

I2cStart();
I2cSendByte(0x81); //发送读器件地址
shift = I2cReadByte(); //读取数据
I2cStop();
SBUF = 0x00;

while(1)
{

请求并从GP2Y0E02B读取2个地址字节
   I2cStart();
   I2cSendByte(0x80);//发送写器件地址
   I2cSendByte(DISTANCE_REG);//发送要写入内存地址
   I2cStop();
   
   I2cStart();
   I2cSendByte(0x81); //发送读器件地址
   high = I2cReadByte();
   I2cStop();

   I2cStart();
   I2cSendByte(0x80);//发送写器件地址
   I2cSendByte(DISTANCE_REG+1);//发送要写入内存地址
   I2cStop();
   
   I2cStart();
   I2cSendByte(0x81); //发送读器件地址
   low = I2cReadByte();
   I2cStop();
   
   SBUF = 0x00;
   distance = (high * 160 + low*10)/16/(float)pow(2,shift); // Calculate the range in mm
  
   printf("Distance = %f\n",distance);
}
/********************************************************************
* 名称 : Uart_Int()
* 功能 : 串口中断子函数
* 输入 : 无
* 输出 : 无
***********************************************************************/
void Uart_Int(void) interrupt 4
{
EA = 0;
if(RI)   //当硬件接收到一个数据时,RI会置位
{
  R_data= SBUF; //这里减去48是因为从电脑中发送过来的数据是ASCII码。
  RI = 0;  
  R_flag=1;
}
EA = 1;
}




评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:644037 发表于 2019-12-6 15:53 | 只看该作者
大佬,有这个传感器的I2C时序图吗?我搜索到的手册貌似都没有写到这个,感谢!
回复

使用道具 举报

板凳
ID:331263 发表于 2019-12-10 23:55 | 只看该作者
有啊,这程序你试了么?没发现问题么?
回复

使用道具 举报

地板
ID:331263 发表于 2019-12-10 23:58 | 只看该作者
有的,你直接去官网就有,这程序可以显示,但数值有点问题,做接近开关是可以的,我已经修改了
回复

使用道具 举报

5#
ID:826204 发表于 2020-11-3 21:45 | 只看该作者
dingpeng1980 发表于 2019-12-10 23:58
有的,你直接去官网就有,这程序可以显示,但数值有点问题,做接近开关是可以的,我已经修改了

楼主 你这个程序是不是只显示到255?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表