您的位置:首页 > 其它

Atmega的TWI通信,包含模拟IIC,硬件查询方式,以及硬件方式收发程序

2015-11-08 22:20 471 查看
/*

* TWI.h

*

* Created: 2015/10/30 14:48:59

* Author: Administrator

*/

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

********************************************************************

**注意事项:在使用硬件查询方式和软件模拟方式进行IIC通信,每次读写数据之间***

**必须延时5ms,否者数据读操作会失败;硬件中断方式读写之间不需要延时时间;*****

********************************************************************

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

#ifndef TWI_H_

#define TWI_H_

#include "config.h"

////硬件中断模式;

//#define TWI_IIC_MODE 0

////硬件查询模式;

//#define TWI_IIC_MODE 1

//软件模拟方式;

#define TWI_IIC_MODE 2

#define TWI_START 0x08

#define TWI_REP_START 0x10

#define TWI_ARB_LOST 0x38

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

****************主机发送***************************************

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

#define TWI_MT_SLA_W_ACK 0x18

#define TWI_MT_SLA_W_NACK 0x20

#define TWI_MT_DATA_ACK 0x28

#define TWI_MT_DATA_NACK 0x30

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

****************主机接收***************************************

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

#define TWI_MR_SLA_R_ACK 0x40

#define TWI_MR_SLA_R_NACK 0x48

#define TWI_MR_DATA_ACK 0x50

#define TWI_MR_DATA_NACK 0x58

#define TWI_NO_INFO 0xF8

#define TWI_BUS_ERROR 0x00

#define TWI_TWCR_STATE (TWCR&0x0F)

#define TWI_NO_STATUS
0xF8

//数据缓存空间的大小;

#define TWI_BUFFER_SIZE 64

//数据返回;

#define TWI_OK 0x00

#define TWI_ERROR_NODEV 0x01

//使能TWI中断;

#define Enable_Interrupt_TWI() TWCR|=(1<<TWIE)

//不使能TWI中断;

#define Disable_Interrupt_TWI() TWCR&=~(1<<TWIE)

//清零TWINT、清零start状态、使能TWI.发出START 信号;

#define TWI_Start() (TWCR=TWI_TWCR_STATE|(1<<TWINT)|(1<<TWSTA)|(1<<TWEN))

//发送停止条件;

#define TWI_Stop() (TWCR=TWI_TWCR_STATE|(1<<TWINT)|(1<<TWEA)|(1<<TWSTO))

//等待TWI 总线操作完成;

#define TWI_Wait() {while (!(TWCR & (1<<TWINT)));}

//启动发送;

#define TWI_Enable_Send() TWCR=(TWI_TWCR_STATE|(1<<TWINT))

#define TWI_Enable_Rev() TWSR=(1<<TWINT)|(TWEA)

//接受应答回复;

#define TWI_ReceACK() TWCR=(TWI_TWCR_STATE|(1<<TWINT)|(1<<TWEA)|(1<<TWEN))

#define TWI_ReceNACK() TWCR=(TWI_TWCR_STATE|(1<<TWINT)|(1<<TWEN))

//总线状态;

#define TWI_STATUS (TWSR&TWI_NO_STATUS)

void TWI_Init(void);

U8 TWI_BitRate(U16 BitRateKHZ);

U8 TWI_GetReceByte(void);

void TWI_SendByte(U8 SendByte);

void TWI_RecByteAck(U8 AckFlag);

void TWI_WriteToDevice(U8 DeviceAddr,U8 length,U8 *pData);

void Fill_Data(U8 length,U8 *pData);

void TWI_StartTransmition(void);

void TWI_ReadFromDevice(U8 DeviceAddr,U8 length);

/******************************中断方式***********************/

/*******************************查询方式

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

U8 TWI_IIC_WriteToDevice(U8 DeviceAddr,U8 *pData,U8 DataLength);

U8 TWI_IIC_WriteToDeviceByAddr(U8 DeviceAddr,U8 DataAddr ,U8 *pData,U8 DataLength);

U8 TWI_IIC_ReadFromDevice(U8 DeviceAddr,U8 *pData,U8 DataLength);

U8 TWI_IIC_ReadFromDeviceByAddr(U8 DeviceAddr,U8 DataAddr,U8 *pData,U8 DataLength);

U8 TWI_ReciveDATA_NACK(U8 *pdata);

U8 TWI_ReciveDATA_ACK(U8 *pdata);

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

*************通过I/O口模拟IIC时序************************************************

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

//SDA--PC4 SCL--PC5

//IIC管脚定义;

#define SDA_Pin PC4

#define SCL_Pin PC5

#define SDA_OUT DDRC|=(1<<SDA_Pin)

#define SDA_IN DDRC&=~(1<<SDA_Pin)

#define SDA_LOW PORTC&=~(1<<SDA_Pin);_delay_us(IIC_DELAY_TIME)

#define SDA_HIGH PORTC|=(1<<SDA_Pin);_delay_us(IIC_DELAY_TIME)

#define SDA_Read PINC&=(1<<SDA_Pin)

#define SCL_OUT DDRC|=(1<<SCL_Pin)

#define SCL_IN DDRC&=~(1<<SCL_Pin)

#define SCL_LOW PORTC&=~(1<<SCL_Pin);_delay_us(IIC_DELAY_TIME)

#define SCL_HIGH PORTC|=(1<<SCL_Pin);_delay_us(IIC_DELAY_TIME)

#define SCL_Read PINC&=(1<<SCL_Pin)

#define IIC_CLOCK_FREQUENT 100

#if ((IIC_CLOCK_FREQUENT>400)||(IIC_CLOCK_FREQUENT==0))

#error "IIC_CLOCK_FREQUENT overflow!!!"

#elif (IIC_CLOCK_FREQUENT>250)

#define IIC_DELAY_TIME
2

#else

#define IIC_DELAY_TIME
(500/IIC_CLOCK_FREQUENT)

#endif

void IIC_Init(void);

void IIC_Start(void);

void IIC_Stop(void);

void IIC_SendByte(U8 Wdata);

U8 IIC_ReadAck(void);

void IIC_Send_ACK_Or_NACK(U8 ACK_Or_NACK);

U8 IIC_WriteToDevice(U8 DeviceAddr,U8 *pData,U8 DataLength);

U8 IIC_WriteToDeviceByAddr(U8 DeviceAddr,U8 DataAddr,U8 *pData,U8 DataLength);

U8 IIC_ReceiveByte(void);

U8 IIC_ReadFromDevice(U8 DeviceAddr,U8 *pData,U8 DataLength);

U8 IIC_ReadFromDeviceByAddr(U8 DeviceAddr,U8 DataAddr, U8 *pData,U8 DataLength);

/******************************模拟方式***********************/

void IIC_TWI_Init(void);

void IIC_TWI_WriteToDevice(U8 DeviceAddr,U8 *pData,U8 DataLength);

void IIC_TWI_WriteToDeviceByAddr(U8 DeviceAddr,U8 DataAddr ,U8 *pData,U8 DataLength);

void IIC_TWI_ReadFromDevice(U8 DeviceAddr,U8 *pData,U8 DataLength);

void IIC_TWI_ReadFromDeviceByAddr(U8 DeviceAddr,U8 DataAddr ,U8 *pData,U8 DataLength);

#endif /* TWI_H_ */

/*

* TWI.c

*

* Created: 2015/10/30 14:48:50

* Author: Administrator

*/

#include "TWI.h"

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

**********发送缓存区*******************

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

U8 TWI_SendData[TWI_BUFFER_SIZE];

//发送完成标志位;

U8 TWI_Write_Finish=0;

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

**********发送缓存区*******************

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

U8 TWI_ReceData[TWI_BUFFER_SIZE];

//读取完成标志位;

U8 TWI_Read_Finish=0;

//定义传输数据长度;

U8 TWI_DataLength=0;

U8 TWI_Index=0;

//定义IIC设备的地址;

U8 IIC_DeviceAddr=0;

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

**********功 能: TWI初始化***********

**********输入参数: 无
***********

**********返回 值:
无 ***********

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

void TWI_Init(void)

{

//设置设备的IIC接口的上拉使能;

PORTC=0xff;

//设备IIC的时钟频率;

TWBR=TWI_BitRate(100);

//释放SDA总线;

TWDR=0xff;

}

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

**********功 能: TWI时钟设置 ********

**********输入参数: 设置速率
********

**********返回 值:
TWBR的值 ********

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

U8 TWI_BitRate(U16 BitRateKHZ)

{

if ((F_CPU/1000)<(BitRateKHZ*36))

{

return 10;

}

else

{

return (U8)((((F_CPU/1000)/BitRateKHZ)-16)/2);

}

}

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

**********功 能: 接受的数据
******

**********输入参数: 无
******

**********返回 值:
TWDR中的数据 ******

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

U8 TWI_GetReceByte(void)

{

return (TWDR);

}

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

**********功 能: 单字节发送数据 ******

**********输入参数: 发送的数据
******

**********返回 值:
无 ******

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

void TWI_SendByte(U8 SendByte)

{

TWDR=SendByte;

TWI_Enable_Send();

}

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

**********功 能: 接收后是否应答 ******

**********输入参数: 1 应答;0 不应答 ****

**********返回 值:
无 ******

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

void TWI_RecByteAck(U8 AckFlag)

{

if (AckFlag)

{

//Ack=true,接受数据完成应答回复;

TWI_ReceACK();

}

else

{

//接收完成后不应答;

TWI_ReceNACK();

}

}

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

**********功 能: 主机中断模式发送数据 **************************************

**********输入参数: DeviceAddr 器件地址;length 数据长度 ;*pData 发送数据 ****

**********返回 值:
无 **************************************

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

void TWI_WriteToDevice(U8 DeviceAddr,U8 length,U8 *pData)

{

//关闭中断;

Disable_Interrupt_TWI();

TWI_DataLength=length;

//数据填充缓存空间;

Fill_Data(length,pData);

//设备写地址;

IIC_DeviceAddr=(DeviceAddr&0xFE);

//启动传输;

TWI_StartTransmition();

//等待写操作完成;

while(!TWI_Write_Finish)

wdt_reset();

//清楚写操作标志;

TWI_Write_Finish=0;

//发送停止条件;

TWI_Stop();

//关闭中断;

Disable_Interrupt_TWI();

}

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

**********功 能: 将发送的数据填充缓存空间 *********

**********输入参数: length 数据长度;*pData 数据 ****

**********返回 值:
无 ******************

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

void Fill_Data(U8 length,U8 *pData)

{

for (U8 i=0;i<length;i++)

{

TWI_SendData[i]=*(pData+i);

}

}

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

**********功 能: 启动数据传输 ******************

**********输入参数: 无
******************

**********返回 值:
无 ******************

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

void TWI_StartTransmition(void)

{

//启动数据传输;

TWI_Start();

//使能TWI中断;

Enable_Interrupt_TWI();

}

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

**********功 能: 主机中断模式读取数据 **************************************

**********输入参数: DeviceAddr 器件地址;length 数据长度 *********************

**********返回 值:
无 **************************************

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

void TWI_ReadFromDevice(U8 DeviceAddr,U8 length)

{

Disable_Interrupt_TWI();

//要读取的数据的长度;

TWI_DataLength=length;

//读数据地址;

IIC_DeviceAddr=(DeviceAddr|0x01);

//启动传输;

TWI_StartTransmition();

//等待读取完成;

while(!TWI_Read_Finish);

//清除IIC读标志位;

TWI_Read_Finish=0;

//发送停止条件;

TWI_Stop();

//关闭TWI中断;

Disable_Interrupt_TWI();

}

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

**************中断函数**************************************************

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

#ifdef __GNUC__

SIGNAL(TWI_vect)

#else

#pragma vector=TWI_vect

__interrupt void TWI_ISR(void)

#endif

{

switch (TWI_STATUS)

{

// 主机START信号传输完成;

case TWI_START:

// 主机重新开始信号传输完成;

case TWI_REP_START:

//发送IIC器件地址;

TWI_SendByte(IIC_DeviceAddr);

break;

// 使能TWI总线,
使能TWI中断, 发送RESTART信号;

case TWI_ARB_LOST:

//启动TWI;

TWI_Start();

break;

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

*****主机发送模式,发送数据*************************

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

// 主机发送-->从机地址及读写标志传输完成并收到ACK信号;

case TWI_MT_SLA_W_ACK:

// 主机发送-->数据传输完成并收到ACK信号;

case TWI_MT_DATA_ACK:

if (TWI_Index<TWI_DataLength)

{

//发送数据;

TWI_SendByte(TWI_SendData[TWI_Index]);

//加载下一个数据;

TWI_Index++;

}

else

{

//清楚数组指向,为接受准备;

TWI_Index=0;

TWI_Write_Finish=1;

}

break;

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

*****主机接收模式,接收数据*************************

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

// 主机接收模式下-->发送完成SLA+R 并收到ACK信号;

case TWI_MR_SLA_R_ACK:

if (TWI_Index<(TWI_DataLength-1))

{

//接收到数据后应答;

TWI_RecByteAck(1);

}

else

{

//接收到数据后不应答;

TWI_RecByteAck(0);

}

break;

// 主机接收模式下-->收到一个字节数据并发送完ACK信号;

case TWI_MR_DATA_ACK:

TWI_ReceData[TWI_Index]=TWI_GetReceByte();

TWI_Index++;

break;

// 主机接收模式下收到数据,发送了NACK信号;

case TWI_MR_DATA_NACK:

//存储最后一组数据;

TWI_ReceData[TWI_Index]=TWI_GetReceByte();

//清楚数组指向,为下一组数据准备;

TWI_Index=0;

//接收完成标志;

TWI_Read_Finish=1;

//停止通信;

TWI_Stop();

break;

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

*****主机接收和发送模式,其他错误状态*************************

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

// 主机发送模式发送从机地址后无应答;

case TWI_MR_SLA_R_NACK:

// 主机发送模式下数据传输完成无应答;

case TWI_MT_DATA_NACK:

// 主机接收模式发送从机地址后无应答;

case TWI_MT_SLA_W_NACK:

//释放总线;

TWI_Stop();

break;

// 总线错误;

case TWI_BUS_ERROR:

TWI_Stop();

break;

default:

TWCR = (1<<TWEN)| // 使能TWI总线,释放TWI端口;

(0<<TWIE)|(0<<TWINT)| // 禁止中断;

(0<<TWEA)|(0<<TWSTA)|(0<<TWSTO)| //

(0<<TWWC);
//



}

}

/******************************中断方式***********************/

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

***********************查询方式*************************************************

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

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

**********功 能: 向设备写入数据
****************************************

**********输入参数: DeviceAddr 设备地址,pdata 数据,DataLength 数据长度 ******

**********返回 值:
0 写入失败,1 写入成功 **********************************

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

U8 TWI_IIC_WriteToDevice(U8 DeviceAddr,U8 *pData,U8 DataLength)

{

U8 i=0;

TWI_Start();

TWI_Wait();

if (TWI_STATUS!=TWI_START)

{

TWI_Stop();

return 0;

}

//发送器件地址;

TWI_SendByte(DeviceAddr&0xFE);

TWI_Wait();

if (TWI_STATUS!=TWI_MT_SLA_W_ACK)

{

//没有应答结束通信;

TWI_Stop();

return 0;

}

//发送数据;

for (i=0;i<DataLength;i++)

{

TWI_SendByte(*pData);

TWI_Wait();

if (TWI_STATUS!=TWI_MT_DATA_ACK)

{

//没有应答结束通信;

TWI_Stop();

return 0;

}

pData++;

}

TWI_Stop();

return 1;

}

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

**********功 能: 向设备写入数据
****************************************

**********输入参数: DeviceAddr 设备地址,DataAddr 数据存储的地址 **************

****************** pdata 数据,DataLength 数据长度 *************************

**********返回 值:
0 写入失败,1 写入成功 **********************************

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

U8 TWI_IIC_WriteToDeviceByAddr(U8 DeviceAddr,U8 DataAddr ,U8 *pData,U8 DataLength)

{

U8 i=0;

TWI_Start();

TWI_Wait();

if (TWI_STATUS!=TWI_START)

{

TWI_Stop();

return 0;

}

//发送器件地址;

TWI_SendByte(DeviceAddr&0xFE);

TWI_Wait();

if (TWI_STATUS!=TWI_MT_SLA_W_ACK)

{

TWI_Stop();

return 0;

}

//发送数据地址;

TWI_SendByte(DataAddr);

TWI_Wait();

if (TWI_STATUS!=TWI_MT_DATA_ACK)

{

TWI_Stop();

return 0;

}

//发送数据;

for (i=0;i<DataLength;i++)

{

TWI_SendByte(*pData);

TWI_Wait();

if (TWI_STATUS!=TWI_MT_DATA_ACK)

{

TWI_Stop();

return 0;

}

pData++;

}

TWI_Stop();

return 1;

}

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

**********功 能: 从设备读出数据
****************************************

**********输入参数: DeviceAddr 设备地址,pdata 数据,DataLength 数据长度 ******

**********返回 值:
0 读出失败,1 读出成功 **********************************

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

U8 TWI_IIC_ReadFromDevice(U8 DeviceAddr,U8 *pData,U8 DataLength)

{

U8 i=0;

//U8 ACK_NACK=0;

TWI_Start();

TWI_Wait();

if (TWI_STATUS!=TWI_START)

{

TWI_Stop();

return 0;

}

//发送器件地址;

TWI_SendByte(DeviceAddr|0x01);

TWI_Wait();

if (TWI_STATUS!=TWI_MR_SLA_R_ACK)

{

//没有应答结束通信;

TWI_Stop();

return 0;

}

for (i=0;i<DataLength-1;i++)

{

if (TWI_ReciveDATA_ACK(pData+i)==0)

{

return 0;

}

}

//读取数据时,最后1字节的数据读取完成以后发送NAK而不是ACK

if(TWI_ReciveDATA_NACK(pData+i)==0)

{

return 0;

}

TWI_Stop();

return 1;

}

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

**********功 能: 从设备读出数据
****************************************

**********输入参数: DeviceAddr 设备地址,DataAddr 数据读出的地址 **************

****************** pdata 数据,DataLength 数据长度 *************************

**********返回 值:
0 读出失败,1 读出成功 **********************************

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

U8 TWI_IIC_ReadFromDeviceByAddr(U8 DeviceAddr,U8 DataAddr,U8 *pData,U8 DataLength)

{

U8 i=0;

//U8 ACK_NACK=0;

TWI_Start();

TWI_Wait();

if (TWI_STATUS!=TWI_START)

{

TWI_Stop();

return 0;

}

//发送器件地址;

TWI_SendByte(DeviceAddr&0xFE);

TWI_Wait();

if (TWI_STATUS!=TWI_MT_SLA_W_ACK)

{

//没有应答结束通信;

TWI_Stop();

return 0;

}

//发送数据地址;

TWI_SendByte(DataAddr);

TWI_Wait();

if (TWI_STATUS!=TWI_MT_DATA_ACK)

{

//没有应答结束通信;

TWI_Stop();

return 0;

}

TWI_Start();

TWI_Wait();

if ((TWI_STATUS!=TWI_START)&&(TWI_STATUS!=TWI_REP_START))

{

TWI_Stop();

return 0;

}

TWI_SendByte(DeviceAddr|0x01);

TWI_Wait();

if (TWI_STATUS!=TWI_MR_SLA_R_ACK)

{

//没有应答结束通信;

TWI_Stop();

return 0;

}

for (i=0;i<DataLength-1;i++)

{

if (TWI_ReciveDATA_ACK(pData+i)==0)

{

return 0;

}

}

//读取数据时,最后1字节的数据读取完成以后发送NAK而不是ACK

if(TWI_ReciveDATA_NACK(pData+i)==0)

{

return 0;

}

TWI_Stop();

return 1;

}

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

*****功能:接收数据,不发应答信号***************************************************

*****输入参数:存储接收到的数据buffer***********************************************

****输出参数:0:接收失败;1接收成功************************************************

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

U8 TWI_ReciveDATA_NACK(U8 *pdata)

{

TWI_ReceNACK();

TWI_Wait();

if (TWI_STATUS!=TWI_MR_DATA_NACK)

{

return 0;

}

*pdata=TWI_GetReceByte();

return 1;

}

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

*****功能:接收数据,发应答信号***************************************************

*****输入参数:存储接收到的数据buffer*********************************************

****输出参数:0:接收失败;1接收成功***********************************************

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

U8 TWI_ReciveDATA_ACK(U8 *pdata)

{

TWI_ReceACK();

TWI_Wait();

if (TWI_STATUS!=TWI_MR_DATA_ACK)

{

return 0;

}

*pdata=TWI_GetReceByte();

return 1;

}

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

***********************模拟IIC SDA--PC4 SCL--PC5********************************

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

/************注意:模拟IIC读和写数据之间必须有5ms的延时时****************************/

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

**********功 能: 模拟IIC初始化 ********************************************

**********输入参数: 无 ********************************************

**********返回 值:
无 ********************************************

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

void IIC_Init(void)

{

//设置为输出模式;

SDA_OUT;

SCL_OUT;

//设置输出为高;

SDA_HIGH;

SCL_HIGH;

}

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

**********功 能: 模拟IIC启动 ********************************************

**********输入参数: 无 ********************************************

**********返回 值:
无 ********************************************

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

void IIC_Start(void)

{

//设置为输出模式;

SDA_OUT;

SCL_OUT;

//钳住I2C总线,避免Start和Stop信号;

SCL_LOW;

//发送起始条件的数据信号;

SDA_HIGH;

SCL_HIGH;

//发送起始信号;

SDA_LOW;

//钳住I2C总线,准备发送或接收数据

SCL_LOW;

}

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

**********功 能: 模拟IIC停止 ********************************************

**********输入参数: 无 ********************************************

**********返回 值:
无 ********************************************

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

void IIC_Stop(void)

{

//设置为输出模式;

SDA_OUT;

SCL_OUT;

//钳住I2C总线,避免Start和Stop信号;

SCL_LOW;

//发送结束条件的数据信号;

SDA_LOW;

SCL_HIGH;

SDA_HIGH;

}

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

**********功 能: 读取应答信号 ********************************************

**********输入参数: 无 ****************************************

**********返回 值:
SDA_Read 1不应答,SDA_Read 0应答 **********************************

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

U8 IIC_ReadAck(void)

{

U8 ACK_NACK = 0;

U8 i=0;

SCL_OUT;

SCL_LOW;

//设置SDA为输入;

SDA_IN;

SCL_HIGH;

for (i=255;i>0;i--)

{

if (SDA_Read)

{

ACK_NACK=1;

SCL_LOW;

return ACK_NACK;

}

}

SCL_LOW;

return ACK_NACK=0;

}

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

**********功 能: 发送数据
********************************************

**********输入参数: 要发送的数据 ****************************************

**********返回 值:
无 **********************************

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

void IIC_SendByte(U8 Wdata)

{

U8 Bitcnt=0;

SDA_OUT;

SCL_OUT;

for (Bitcnt=0;Bitcnt<8;Bitcnt++)

{

SCL_LOW;

if (Wdata&0x80)

{

SDA_HIGH;

}

else

{

SDA_LOW;

}

Wdata<<=1;

SCL_HIGH;

}

}

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

**********功 能: 发送应答
*******************************************

**********输入参数: 1不应答,0应答 ********************************************

**********返回 值:
无 ******************************************

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

void IIC_Send_ACK_Or_NACK(U8 ACK_Or_NACK)

{

SDA_OUT;

SCL_OUT;

SCL_LOW;

if (ACK_Or_NACK)

{

//无应答信号;

SDA_HIGH;

}

else

{

//应答信号;

SDA_LOW;

}

SCL_HIGH;

SCL_LOW;

}

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

**********功 能: 向设备写入数据
****************************************

**********输入参数: DeviceAddr 设备地址,pdata 数据,DataLength 数据长度 ******


**********返回 值:
0 写入失败,1 写入成功 **********************************

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

U8 IIC_WriteToDevice(U8 DeviceAddr,U8 *pData,U8 DataLength)

{

U8 i=0;

IIC_Start();

IIC_SendByte(DeviceAddr&0xFE);

if (IIC_ReadAck())

{

//没有应答,结束通信;

IIC_Stop();

return 0;

}

for (i=0;i<DataLength;i++)

{

//发送数据;

IIC_SendByte(*pData);

if (IIC_ReadAck())

{

//没有应答,结束通信;

IIC_Stop();

return 0;

}

pData++;

}

IIC_Stop();

return 1;

}

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

**********功 能: 向设备写入数据
****************************************

**********输入参数: DeviceAddr 设备地址,DataAddr 数据存储的地址 **************

****************** pdata 数据,DataLength 数据长度 *************************

**********返回 值:
0 写入失败,1 写入成功 **********************************

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

U8 IIC_WriteToDeviceByAddr(U8 DeviceAddr,U8 DataAddr,U8 *pData,U8 DataLength)

{

U8 i=0;

//启动总线;

IIC_Start();

//发送器件地址;

IIC_SendByte(DeviceAddr);

if (IIC_ReadAck())

{

//没有应答,结束通信;

IIC_Stop();

return 0;

}

//发送数据地址;

IIC_SendByte(DataAddr);

if (IIC_ReadAck())

{

//没有应答,结束通信;

IIC_Stop();

return 0;

}

for (i=0;i<DataLength;i++)

{

//发送数据;

IIC_SendByte(*pData);

if (IIC_ReadAck())

{

//没有应答,结束通信;

IIC_Stop();

return 0;

}

pData++;

}

IIC_Stop();

return 1;

}

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

**********功 能: 接收数据函数
******************************************

**********输入参数: 无 ******************************************

**********返回 值:
接收到的数据 ******************************************

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

U8 IIC_ReceiveByte(void)

{

U8 Bitcnt=0;

U8 RevData=0;

SCL_OUT;

//将SDA设置为输入;

SDA_IN;

//SDA_LOW;

for (Bitcnt=0;Bitcnt<8;Bitcnt++)

{

//置时钟线为低,准备接收数据位;

SCL_LOW;

//上拉使;

SDA_HIGH;

//置时钟线为高使数据线上数据有效;

SCL_HIGH;

RevData=RevData<<1;

if (SDA_Read)

{

RevData+=1;

}

else

{

RevData+=0;

}

}

return RevData;

}

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

**********功 能: 从设备读出数据
****************************************

**********输入参数: DeviceAddr 设备地址,pdata 数据,DataLength 数据长度 ******

**********返回 值:
0 读出失败,1 读出成功 **********************************

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

U8 IIC_ReadFromDevice(U8 DeviceAddr,U8 *pData,U8 DataLength)

{

U8 i=0;

U8 ACK_NACK=1;

IIC_Start();

IIC_SendByte(DeviceAddr|0x01);

if (IIC_ReadAck())

{

//没有应答,结束通信;

IIC_Stop();

return 0;

}

for (i=0;i<DataLength;i++)

{

//接收的数据;

*pData=IIC_ReceiveByte();

if (i==(DataLength-1))

{

ACK_NACK=1;

}

else

{

pData++;

ACK_NACK=0;

}

//发送应答或不应答信号;

IIC_Send_ACK_Or_NACK(ACK_NACK);

}

IIC_Stop();

return 1;

}

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

**********功 能: 从设备读出数据
****************************************

**********输入参数: DeviceAddr 设备地址,DataAddr 数据读出的地址 **************

****************** pdata 数据,DataLength 数据长度 *************************

**********返回 值:
0 读出失败,1 读出成功 **********************************

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

U8 IIC_ReadFromDeviceByAddr(U8 DeviceAddr,U8 DataAddr, U8 *pData,U8 DataLength)

{

U8 i=0;

U8 ACK_NACK=1;

IIC_Start();

IIC_SendByte(DeviceAddr&0xFE);

if (IIC_ReadAck())

{

//没有应答,结束通信;

IIC_Stop();

return 0;

}

IIC_SendByte(DataAddr);

if (IIC_ReadAck())

{

//没有应答,结束通信;

IIC_Stop();

return 0;

}

IIC_Start();

IIC_SendByte(DeviceAddr|0x01);

if (IIC_ReadAck())

{

//没有应答,结束通信;

IIC_Stop();

return 0;

}

for (i=0;i<DataLength;i++)

{

//接收的数据;

*pData=IIC_ReceiveByte();

if (i==(DataLength-1))

{

ACK_NACK=1;

}

else

{

pData++;

ACK_NACK=0;

}

//发送应答h或不应答信号;

IIC_Send_ACK_Or_NACK(ACK_NACK);

}

IIC_Stop();

return 1;

}

/******************************模拟方式***********************/

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

**********功 能: 硬件还是软件模拟的IIC通信的初始化 ***************************

**********输入参数: 无 ********************************************

**********返回 值:
无 ********************************************

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

void IIC_TWI_Init(void)

{

if (TWI_IIC_MODE==0)

{

Enable_interrupt();

TWI_Init();

}

else if (TWI_IIC_MODE==1)

{

TWI_Init();

}

else

{

IIC_Init();

}

}

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

**********功 能: 向设备写入数据
****************************************

**********输入参数: DeviceAddr 设备地址,pdata 数据,DataLength 数据长度 ******

**********返回 值:
无 **********************************

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

void IIC_TWI_WriteToDevice(U8 DeviceAddr,U8 *pData,U8 DataLength)

{

if (TWI_IIC_MODE==0)

{

TWI_WriteToDevice(DeviceAddr,DataLength,pData);

}

else if (TWI_IIC_MODE==1)

{

TWI_IIC_WriteToDevice(DeviceAddr,pData,DataLength);

}

else

{

IIC_WriteToDevice(DeviceAddr,pData,DataLength);

}

}

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

**********功 能: 向设备写入数据
****************************************

**********输入参数: DeviceAddr 设备地址,DataAddr 数据存储的地址 **************

****************** pdata 数据,DataLength 数据长度 *************************

**********返回 值:
无 **********************************

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

void IIC_TWI_WriteToDeviceByAddr(U8 DeviceAddr,U8 DataAddr ,U8 *pData,U8 DataLength)

{

if (TWI_IIC_MODE==0)

{

//TWI_WriteToDevice(DeviceAddr,DataLength,*pData);

}

else if (TWI_IIC_MODE==1)

{

TWI_IIC_ReadFromDeviceByAddr(DeviceAddr,DataAddr,pData,DataLength);

}

else

{

IIC_WriteToDeviceByAddr(DeviceAddr,DataAddr,pData,DataLength);

}

}

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

**********功 能: 从设备读出数据
****************************************

**********输入参数: DeviceAddr 设备地址,pdata 数据,DataLength 数据长度 ******

**********返回 值:
无 **********************************

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

void IIC_TWI_ReadFromDevice(U8 DeviceAddr,U8 *pData,U8 DataLength)

{

if (TWI_IIC_MODE==0)

{

TWI_ReadFromDevice(DeviceAddr,DataLength);

}

else if (TWI_IIC_MODE==1)

{

TWI_IIC_ReadFromDevice(DeviceAddr,pData,DataLength);

}

else

{

IIC_ReadFromDevice(DeviceAddr,pData,DataLength);

}

}

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

**********功 能: 从设备读出数据
****************************************

**********输入参数: DeviceAddr 设备地址,DataAddr 数据读出的地址 **************

****************** pdata 数据,DataLength 数据长度 *************************

**********返回 值:
无 **********************************

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

void IIC_TWI_ReadFromDeviceByAddr(U8 DeviceAddr,U8 DataAddr ,U8 *pData,U8 DataLength)

{

if (TWI_IIC_MODE==0)

{

//TWI_ReadFromDevice(DeviceAddr,DataLength);

}

else if (TWI_IIC_MODE==1)

{

TWI_IIC_ReadFromDeviceByAddr(DeviceAddr,DataAddr,pData,DataLength);

}

else

{

IIC_ReadFromDeviceByAddr(DeviceAddr,DataAddr,pData,DataLength);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: