/*********************************************
Atmega16 IIC底层程序,使用AVR内部硬件iic,引脚定义:PC0->SCL ; PC1->SDA
使用前请先到i2c.h中修改“设备地址”和“数据地址”,以及i2c.h中包含的Global.h文件
所在的位置,后直接调用函数即可
作者:天微凉
**********************************************/
#include "i2c.h"
/*********************************************
I2C总线采用“按字节写时序”写一个字节
输入:要写的数据
输出:返回值为0:写成功 ,返回值为1:写失败
**********************************************/
unsigned char I2C_Write(unsigned char Wdata)
{
Start(); //I2C启动
Wait();
if(TestAck()!=START)
return 1; //ACK
Write8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式
Wait();
if(TestAck()!=MT_SLA_ACK)
return 1; //ACK
Write8Bit(DATA_ADDR); //写I2C从器件的数据地址
Wait();
if(TestAck()!=MT_DATA_ACK)
return 1; //ACK
Write8Bit(Wdata); //写数据到器件相应寄存器
Wait();
if(TestAck()!=MT_DATA_ACK)
return 1; //ACK
Stop(); //I2C停止
return 0;
}
/*********************************************
I2C总线采用“当前地址读时序”读一个字节
返回:16位数值
**********************************************/
unsigned int I2C_Read_1(void)
{
unsigned int temp;
Start(); //I2C启动
Wait();
if(TestAck()!=START)
return 1; //ACK
Write8Bit(RD_DEVICE_ADDR); //写I2C从器件地址和读方式
Wait();
if(TestAck()!=MR_SLA_ACK)
return 1; //ACK
Twi(); //启动主I2C读方式,结果应答NACK
Wait();
temp=TWDR; //读取I2C接收数据
Stop();
return temp;
}
/*********************************************
I2C总线采用“按字节读时序”读一个字节
返回:16位数值
**********************************************/
unsigned int I2C_Read_2(void)
{
unsigned int temp;
Start(); //I2C启动
Wait();
if(TestAck()!=START)
return 1; //ACK
Write8Bit(WD_DEVICE_ADDR); //写I2C从器件地址和写方式
Wait();
if(TestAck()!=MT_SLA_ACK)
return 1; //ACK
Write8Bit(DATA_ADDR); //写I2C从器件数据地址
Wait();
if(TestAck()!=MT_DATA_ACK)
return 1; //ACK
Start(); //I2C再次启动
Wait();
if(TestAck()!=RE_START)
return 1; //ACK
Write8Bit(RD_DEVICE_ADDR); //写I2C从器件地址和读方式
Wait();
if(TestAck()!=MR_SLA_ACK)
return 1; //ACK
Twi(); //启动主I2C读方式,结果应答NACK
Wait();
temp=TWDR; //读取I2C接收数据
Stop();
return temp;
}