51单片机 *** 作24c08,IIC应答时,以下程序怎样反应出来是为0和为1呢????

51单片机 *** 作24c08,IIC应答时,以下程序怎样反应出来是为0和为1呢????,第1张

这帆坦是程序设计者偷懒的结果,因为大多数正常情况下不会出现应答为1的情况。程序没有写出错处理,出错处理也就是把结果向上一级函数返回,IIC_single_byte_write定义为 bit型,返回IIC_Tack的值。

正常情况下 程序设计合理,电路器件正常,基本不会出错。程序设雀备计不合理调试不会通过,电路器件不正常,程序也没办法,只是知道错了而已。态岁桐解决不了问题,所以很多时候程序员都会舍去这部分出错处理程序。

用串口显示的

#include <REG52.H>

#include <math.h> //Keil library

#include <stdio.h> //Keil library

#include <INTRINS.H>

typedef unsigned char uchar

typedef unsigned short ushort

typedef unsigned int uint

//****************************************

// 定义51单片机端口

//****************************************

#define DataPort P0 //LCD1602数据端口

sbitSCL=P1^0 //IIC时钟引脚定义

sbitSDA=P1^1 //IIC数据引脚定义

sbitLCM_RS=P2^0 //LCD1602命令端口

sbitLCM_RW=P2^1 //LCD1602命令端口

sbitLCM_EN=P2^2 //LCD1602命令端口

/含扰档/****************************************

// 定义MPU6050内部地址

//****************************************

#define SMPLRT_DIV 0x19 //陀螺仪采样率,典型值:0x07(125Hz)

#define CONFIG 0x1A //低通滤波频率,典型值:0x06(5Hz)

#define GYRO_CONFIG 0x1B //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/谈乱s)

#define ACCEL_CONFIG 0x1C //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)

#define ACCEL_XOUT_H 0x3B

#define ACCEL_XOUT_L 0x3C

#define ACCEL_YOUT_H 0x3D

#define ACCEL_YOUT_L 0x3E

#define ACCEL_ZOUT_H 0x3F

#define ACCEL_ZOUT_L 0x40

#define TEMP_OUT_H 0x41

#define TEMP_OUT_L 0x42

#define GYRO_XOUT_H 0x43

#define GYRO_XOUT_L 0x44

#define GYRO_YOUT_H 0x45

#define GYRO_YOUT_L 0x46

#define GYRO_ZOUT_H 0x47

#define GYRO_ZOUT_L 0x48

#define PWR_MGMT_1 0x6B //电源管理,典型值:0x00(正常启用)

#define WHO_AM_I 0x75 //IIC地址寄存器(默认数值0x68,只读李隐)

#define SlaveAddress 0xD0 //IIC写入时的地址字节数据,+1为读取

//****************************************

//定义类型及变量

//****************************************

uchar dis[6] //显示数字(-511至512)的字符数组

int dis_data //变量

//int Temperature,Temp_h,Temp_l //温度及高低位数据

//****************************************

//函数声明

//****************************************

void delay(unsigned int k) //延时

void lcd_printf(uchar *s,int temp_data)

//MPU6050 *** 作函数

void InitMPU6050() //初始化MPU6050

void Delay5us()

void I2C_Start()

void I2C_Stop()

void I2C_SendACK(bit ack)

bit I2C_RecvACK()

void I2C_SendByte(uchar dat)

uchar I2C_RecvByte()

void I2C_ReadPage()

void I2C_WritePage()

void display_ACCEL_x()

void display_ACCEL_y()

void display_ACCEL_z()

uchar Single_ReadI2C(uchar REG_Address) //读取I2C数据

void Single_WriteI2C(uchar REG_Address,uchar REG_data) //向I2C写入数据

//****************************************

//整数转字符串

//****************************************

void lcd_printf(uchar *s,int temp_data)

{

if(temp_data<0)

{

temp_data=-temp_data

*s='-'

}

else *s=' '

*++s =temp_data/10000+0x30

temp_data=temp_data%10000//取余运算

*++s =temp_data/1000+0x30

temp_data=temp_data%1000//取余运算

*++s =temp_data/100+0x30

temp_data=temp_data%100//取余运算

*++s =temp_data/10+0x30

temp_data=temp_data%10 //取余运算

*++s =temp_data+0x30

}

//****************************************

void SeriPushSend(uchar send_data)

{

SBUF=send_data

while(!TI)TI=0

}

//****************************************

//延时

//****************************************

void delay(unsigned int k)

{

unsigned int i,j

for(i=0i<ki++)

{

for(j=0j<121j++)

}

}

//**************************************

//延时5微秒(STC90C52RC@12M)

//不同的工作环境,需要调整此函数

//当改用1T的MCU时,请调整此延时函数

//**************************************

void Delay5us()

{

_nop_()_nop_()_nop_()_nop_()

_nop_()_nop_()_nop_()_nop_()

_nop_()_nop_()_nop_()_nop_()

_nop_()_nop_()_nop_()_nop_()

_nop_()_nop_()_nop_()_nop_()

_nop_()_nop_()_nop_()_nop_()

}

//**************************************

//I2C起始信号

//**************************************

void I2C_Start()

{

SDA = 1 //拉高数据线

SCL = 1 //拉高时钟线

Delay5us()//延时

SDA = 0 //产生下降沿

Delay5us()//延时

SCL = 0 //拉低时钟线

}

//**************************************

//I2C停止信号

//**************************************

void I2C_Stop()

{

SDA = 0 //拉低数据线

SCL = 1 //拉高时钟线

Delay5us()//延时

SDA = 1 //产生上升沿

Delay5us()//延时

}

//**************************************

//I2C发送应答信号

//入口参数:ack (0:ACK 1:NAK)

//**************************************

void I2C_SendACK(bit ack)

{

SDA = ack //写应答信号

SCL = 1 //拉高时钟线

Delay5us()//延时

SCL = 0 //拉低时钟线

Delay5us()//延时

}

//**************************************

//I2C接收应答信号

//**************************************

bit I2C_RecvACK()

{

SCL = 1 //拉高时钟线

Delay5us()//延时

CY = SDA //读应答信号

SCL = 0 //拉低时钟线

Delay5us()//延时

return CY

}

//**************************************

//向I2C总线发送一个字节数据

//**************************************

void I2C_SendByte(uchar dat)

{

uchar i

for (i=0i<8i++) //8位计数器

{

dat <<= 1 //移出数据的最高位

SDA = CY //送数据口

SCL = 1 //拉高时钟线

Delay5us()//延时

SCL = 0 //拉低时钟线

Delay5us()//延时

}

I2C_RecvACK()

}

//**************************************

//从I2C总线接收一个字节数据

//**************************************

uchar I2C_RecvByte()

{

uchar i

uchar dat = 0

SDA = 1 //使能内部上拉,准备读取数据,

for (i=0i<8i++) //8位计数器

{

dat <<= 1

SCL = 1 //拉高时钟线

Delay5us()//延时

dat |= SDA//读数据

SCL = 0 //拉低时钟线

Delay5us()//延时

}

return dat

}

//**************************************

//向I2C设备写入一个字节数据

//**************************************

void Single_WriteI2C(uchar REG_Address,uchar REG_data)

{

I2C_Start() //起始信号

I2C_SendByte(SlaveAddress) //发送设备地址+写信号

I2C_SendByte(REG_Address) //内部寄存器地址,

I2C_SendByte(REG_data) //内部寄存器数据,

I2C_Stop() //发送停止信号

}

//**************************************

//从I2C设备读取一个字节数据

//**************************************

uchar Single_ReadI2C(uchar REG_Address)

{

uchar REG_data

I2C_Start() //起始信号

I2C_SendByte(SlaveAddress) //发送设备地址+写信号

I2C_SendByte(REG_Address)//发送存储单元地址,从0开始

I2C_Start() //起始信号

I2C_SendByte(SlaveAddress+1) //发送设备地址+读信号

REG_data=I2C_RecvByte() //读出寄存器数据

I2C_SendACK(1) //接收应答信号

I2C_Stop() //停止信号

return REG_data

}

//**************************************

//初始化MPU6050

//**************************************

void InitMPU6050()

{

Single_WriteI2C(PWR_MGMT_1, 0x00) //解除休眠状态

Single_WriteI2C(SMPLRT_DIV, 0x07)

Single_WriteI2C(CONFIG, 0x06)

Single_WriteI2C(GYRO_CONFIG, 0x18)

Single_WriteI2C(ACCEL_CONFIG, 0x01)

}

//**************************************

//合成数据

//**************************************

int GetData(uchar REG_Address)

{

uchar H,L

H=Single_ReadI2C(REG_Address)

L=Single_ReadI2C(REG_Address+1)

return (H<<8)+L //合成数据

}

//**************************************

//在1602上显示10位数据

//**************************************

void Display10BitData(int value,uchar x,uchar y)

{ uchar i

// value/=64 //转换为10位数据

lcd_printf(dis, value) //转换数据显示

for(i=0i<6i++)

{

SeriPushSend(dis[i])

}

// DisplayListChar(x,y,dis,4) //启始列,行,显示数组,显示长度

}

//**************************************

//显示温度

//**************************************

//void display_temp()

//{

// Temp_h=Single_ReadI2C(TEMP_OUT_H)//读取温度

// Temp_l=Single_ReadI2C(TEMP_OUT_L)//读取温度

// Temperature=Temp_h<<8|Temp_l//合成温度

// Temperature = 35+ ((double) (Temperature + 13200)) / 280// 计算出温度

// lcd_printf(dis,Temperature)//转换数据显示

// DisplayListChar(11,1,dis,4)//启始列,行,显示数组,显示位数

//}

void init_uart()

{

TMOD=0x21

TH1=0xfd

TL1=0xfd

SCON=0x50

PS=1 //串口中断设为高优先级别

TR0=1 //启动定时器

TR1=1

ET0=1//打开定时器0中断

ES=1

EA=1

}

//*********************************************************

//主程序

//*********************************************************

void main()

{

delay(500) //上电延时

// InitLcd() //液晶初始化

init_uart()

InitMPU6050() //初始化MPU6050

delay(150)

while(1)

{

Display10BitData(GetData(ACCEL_XOUT_H),2,0) //显示X轴加速度

Display10BitData(GetData(ACCEL_YOUT_H),7,0) //显示Y轴加速度

Display10BitData(GetData(ACCEL_ZOUT_H),12,0) //显示Z轴加速度

Display10BitData(GetData(GYRO_XOUT_H),2,1) //显示X轴角速度

Display10BitData(GetData(GYRO_YOUT_H),7,1) //显示Y轴角速度

Display10BitData(GetData(GYRO_ZOUT_H),12,1) //显示Z轴角速度

SeriPushSend(0x0d)

SeriPushSend(0x0a)//换行,回车

delay(100)

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12474859.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存