硬件中断方式I2C(CVAVR)
时间:11-18
来源:互联网
点击:
//i2c.h
#defineTWPS00
#defineTWPS11
#defineTWEN2
#defineTWIE0
#defineTWEA6
#defineTWINT7
#defineTWSTA5
#defineTWSTO4
//TWSRvalues(notbits)
//Master
#defineTW_START0x08
#defineTW_REP_START0x10
//MasterTransmitter
#defineTW_MT_SLA_ACK0x18
#defineTW_MT_SLA_NACK0x20
#defineTW_MT_DATA_ACK0x28
#defineTW_MT_DATA_NACK0x30
#defineTW_MT_ARB_LOST0x38
//MasterReceiver
#defineTW_MR_ARB_LOST0x38
#defineTW_MR_SLA_ACK0x40
#defineTW_MR_SLA_NACK0x48
#defineTW_MR_DATA_ACK0x50
#defineTW_MR_DATA_NACK0x58
//SlaveTransmitter
#defineTW_ST_SLA_ACK0xA8
#defineTW_ST_ARB_LOST_SLA_ACK0xB0
#defineTW_ST_DATA_ACK0xB8
#defineTW_ST_DATA_NACK0xC0
#defineTW_ST_LAST_DATA0xC8
//SlaveReceiver
#defineTW_SR_SLA_ACK0x60
#defineTW_SR_ARB_LOST_SLA_ACK0x68
#defineTW_SR_GCALL_ACK0x70
#defineTW_SR_ARB_LOST_GCALL_ACK0x78
#defineTW_SR_DATA_ACK0x80
#defineTW_SR_DATA_NACK0x88
#defineTW_SR_GCALL_DATA_ACK0x90
#defineTW_SR_GCALL_DATA_NACK0x98
#defineTW_SR_STOP0xA0
//Misc
#defineTW_NO_INFO0xF8
#defineTW_BUS_ERROR0x00
//definesandconstants
#defineTWCR_CMD_MASK0x0F
#defineTWSR_STATUS_MASK0xF8
//returnvalues
#defineI2C_OK0x00
#defineI2C_ERROR_NODEV0x01
#defineI2C_SEND_DATA_BUFFER_SIZE0x20
#defineI2C_RECEIVE_DATA_BUFFER_SIZE0x20
#defineF_CPU8000000
#defineTRUE1
#defineFALSE0
//types
typedefenum
{
I2C_IDLE=0,I2C_BUSY=1,
I2C_MASTER_TX=2,I2C_MASTER_RX=3,
I2C_SLAVE_TX=4,I2C_SLAVE_RX=5
}eI2cStateType;
//i2c.c
#include
#include"i2c.h"
//I2C标准波特率:
//低速100KHz
//高速400KHz
//I2C状态和地址变量
staticvolatileeI2cStateTypeI2cState;
staticunsignedcharI2cDeviceAddrRW;
//发送缓冲区
staticunsignedcharI2cSendData[I2C_SEND_DATA_BUFFER_SIZE];
staticunsignedcharI2cSendDataIndex;
staticunsignedcharI2cSendDataLength;
//接收缓冲区
staticunsignedcharI2cReceiveData[I2C_RECEIVE_DATA_BUFFER_SIZE];
staticunsignedcharI2cReceiveDataIndex;
staticunsignedcharI2cReceiveDataLength;
unsignedcharlocalBuffer[]="!!";
unsignedcharlocalBufferLength=0x20;
//指向接收处理函数的指针,当本机被选中从接收时调用函数:I2cSlaveReceive
staticvoid(*i2cSlaveReceive)(unsignedcharreceiveDataLength,unsignedchar*recieveData);
//指向发送处理函数的指针,当本机被选中从发送时调用函数:II2cSlaveTransmit
staticunsignedchar(*i2cSlaveTransmit)(unsignedchartransmitDataLengthMax,unsignedchar*transmitData);
//设置总线速率
voidi2cSetBitrate(unsignedintbitrateKHz)
{
unsignedcharbitrate_div;
//SCLfreq=F_CPU/(16+2*TWBR))
#ifdefTWPS0
//对于用速率分频的AVR(mega128)
//SCLfreq=F_CPU/(16+2*TWBR*4^TWPS)
//setTWPStozero
TWSR&=~(1 TWSR&=~(1 #endif
//计算分频
bitrate_div=((F_CPU/1000l)/bitrateKHz);
if(bitrate_p>=16)
bitrate_div=(bitrate_div-16)/2;
TWBR=bitrate_div;
}
//总线初始化
voidi2cInit(void)
{
//设置总线上拉
#ifdef_MEGA128_INCLUDED_
//#ifdef_MEGA64_INCLUDED_
PORTD.0=1;//i2cSCLonATmega128,64
PORTD.1=1;//i2cSDAonATmega128,64
#else
PORTC.0=1;//i2cSCLonATmega163,323,16,32,等
PORTC.1=1;//i2cSDAonATmega163,323,16,32,等
#endif
//清空从发送和从接受
i2cSlaveReceive=0;
i2cSlaveTransmit=0;
//设置i2c波特率为100KHz
i2cSetBitrate(100);
//I2C总线使能
TWCR|=1 //状态设置
I2cState=I2C_IDLE;
//开I2C中断和回应
TWCR|=1 TWCR|=1
#asm("sei");
}
voidi2cSetLocalDeviceAddr(unsignedchardeviceAddr,unsignedchargenCallEn)
{
//设置本机从地址(从方式时)
TWAR=(deviceAddr&0xFE)|(genCallEn?1:0);
}
voidi2cSetSlaveReceiveHandler(void(*i2cSlaveRx_func)(unsignedcharreceiveDataLength,unsignedchar*recieveData))
{
i2cSlaveReceive=i2cSlaveRx_func;
}
voidi2cSetSlaveTransmitHandler(unsignedchar(*i2cSlaveTx_func)(unsignedchartransmitDataLengthMax,unsignedchar*transmitData))
{
i2cSlaveTransmit=i2cSlaveTx_func;
}
inlinevoidi2cSendStart(void)
{
TWCR=TWCR&TWCR_CMD_MASK|(1 }
inlinevoidi2cSendStop(void)
{
//发送停止条件,保持TWEA以便从接收
TWCR=TWCR&TWCR_CMD_MASK|(1 }
inlinevoidi2cWaitForComplete(void)
{
//等待i2c总线操作完成
while(!(TWCR&(1 }
inlinevoidi2cSendByte(unsignedchardata)
{
//装载数据到TWDR
TWDR=data;
//发送开始
TWCR=TWCR&TWCR_CMD_MASK|(1 }
inlinevoidi2cReceiveByte(unsignedcharackFlag)
{
//开始通过i2c接收
if(ackFlag)
{
//ackFlag=TRUE:数据接收后回应ACK
TWCR=TWCR&TWCR_CMD_MASK|(1 }
else
{
//ackFlag=FALSE:数据接收后无回应
TWCR=TWCR&TWCR_CMD_MASK|(1 }
}
inlineunsignedchari2cGetReceivedByte(void)
{
//返回接收到的数据
return(TWDR);
}
inlineunsignedchari2cGetStatus(void)
{
//返回总线状态
return(TWSR);
}
voidi2cMasterSend(unsignedchardeviceAddr,unsignedcharlength,unsignedchar*data)
{
unsignedchari;
//等待总线准备完成
while(I2cState);
//设置状态
I2cState=I2C_MASTER_TX;
//准备数据
I2cDeviceAddrRW=(deviceAddr&0xFE);//RW为0:写操作
for(i=0;i I2cSendData[i]=*data++;
I2cSendDataIndex=0;
I2cSendDataLength=length;
//发送开始条件
i2cSendStart();
}
voidi2cMasterReceive(unsignedchardeviceAddr,unsignedcharlength,unsignedchar*data)
{
unsignedchari;
//等待总线准备完成
while(I2cState);
//设置状态
I2cState=I2C_MASTER_RX;
//保存数据
I2cDeviceAddrRW=(deviceAddr|0x01);//RW为1:读操作
I2cReceiveDataIndex=0;
I2cReceiveDataLength=length;
//发送开始条件
i2cSendStart();
//等待数据准备好
while(I2cState);
//取数据
for(i=0;i *data++=I2cReceiveData[i];
}
unsignedchari2cMasterSendNI(unsignedchardeviceAddr,unsignedcharlength,unsignedchar*data)
{
unsignedcharretval=I2C_OK;
//关I2C中断
TWCR&=~(1
//发送开始条件
i2cSendStart();
i2cWaitForComplete();
//发送器件写地址
i2cSendByte(deviceAddr&0xFE);
i2cWaitForComplete();
//检查器件是否可用
if(TWSR==TW_MT_SLA_ACK)
{
//发送数据
while(length)
{
i2cSendByte(*data++);
i2cWaitForComplete();
length--;
}
}
else
{
//如未回应器件地址,停止发送,返回错误
retval=I2C_ERROR_NODEV;
}
//发送停止条件,保持TWEA以便从接收
i2cSendStop();
while(!(TWCR&(1
//开I2C中断
TWCR|=(1
returnretval;
}
unsignedchari2cMasterReceiveNI(unsignedchardeviceAddr,unsignedcharlength,unsignedchar*data)
{
unsignedcharretval=I2C_OK;
//关I2C中断
TWCR&=~(1
//发送开始条件
i2cSendStart();
i2cWaitForComplete();
//发送器件读地址
i2cSendByte(deviceAddr|0x01);
i2cWaitForComplete();
//检查器件是否可用
if(TWSR==TW_MR_SLA_ACK)
{
//接收数据并回应
while(length>1)
{
i2cReceiveByte(TRUE);
i2cWaitForComplete();
*data++=i2cGetReceivedByte();
length--;
}
//接收数据无回应(末位信号)
i2cReceiveByte(FALSE);
i2cWaitForComplete();
*data++=i2cGetReceivedByte();
}
else
{
//如未回应器件地址,停止发送,返回错误
retval=I2C_ERROR_NODEV;
}
//发送停止条件,保持TWEA以便从接收
i2cSendStop();
//开I2C中断
TWCR|=TWIE;
returnretval;
}
eI2cStateTypei2cGetState(void)
{
returnI2cState;
}
//I2C(TWI)中断服务程序
#defineTWPS00
#defineTWPS11
#defineTWEN2
#defineTWIE0
#defineTWEA6
#defineTWINT7
#defineTWSTA5
#defineTWSTO4
//TWSRvalues(notbits)
//Master
#defineTW_START0x08
#defineTW_REP_START0x10
//MasterTransmitter
#defineTW_MT_SLA_ACK0x18
#defineTW_MT_SLA_NACK0x20
#defineTW_MT_DATA_ACK0x28
#defineTW_MT_DATA_NACK0x30
#defineTW_MT_ARB_LOST0x38
//MasterReceiver
#defineTW_MR_ARB_LOST0x38
#defineTW_MR_SLA_ACK0x40
#defineTW_MR_SLA_NACK0x48
#defineTW_MR_DATA_ACK0x50
#defineTW_MR_DATA_NACK0x58
//SlaveTransmitter
#defineTW_ST_SLA_ACK0xA8
#defineTW_ST_ARB_LOST_SLA_ACK0xB0
#defineTW_ST_DATA_ACK0xB8
#defineTW_ST_DATA_NACK0xC0
#defineTW_ST_LAST_DATA0xC8
//SlaveReceiver
#defineTW_SR_SLA_ACK0x60
#defineTW_SR_ARB_LOST_SLA_ACK0x68
#defineTW_SR_GCALL_ACK0x70
#defineTW_SR_ARB_LOST_GCALL_ACK0x78
#defineTW_SR_DATA_ACK0x80
#defineTW_SR_DATA_NACK0x88
#defineTW_SR_GCALL_DATA_ACK0x90
#defineTW_SR_GCALL_DATA_NACK0x98
#defineTW_SR_STOP0xA0
//Misc
#defineTW_NO_INFO0xF8
#defineTW_BUS_ERROR0x00
//definesandconstants
#defineTWCR_CMD_MASK0x0F
#defineTWSR_STATUS_MASK0xF8
//returnvalues
#defineI2C_OK0x00
#defineI2C_ERROR_NODEV0x01
#defineI2C_SEND_DATA_BUFFER_SIZE0x20
#defineI2C_RECEIVE_DATA_BUFFER_SIZE0x20
#defineF_CPU8000000
#defineTRUE1
#defineFALSE0
//types
typedefenum
{
I2C_IDLE=0,I2C_BUSY=1,
I2C_MASTER_TX=2,I2C_MASTER_RX=3,
I2C_SLAVE_TX=4,I2C_SLAVE_RX=5
}eI2cStateType;
//i2c.c
#include
#include"i2c.h"
//I2C标准波特率:
//低速100KHz
//高速400KHz
//I2C状态和地址变量
staticvolatileeI2cStateTypeI2cState;
staticunsignedcharI2cDeviceAddrRW;
//发送缓冲区
staticunsignedcharI2cSendData[I2C_SEND_DATA_BUFFER_SIZE];
staticunsignedcharI2cSendDataIndex;
staticunsignedcharI2cSendDataLength;
//接收缓冲区
staticunsignedcharI2cReceiveData[I2C_RECEIVE_DATA_BUFFER_SIZE];
staticunsignedcharI2cReceiveDataIndex;
staticunsignedcharI2cReceiveDataLength;
unsignedcharlocalBuffer[]="!!";
unsignedcharlocalBufferLength=0x20;
//指向接收处理函数的指针,当本机被选中从接收时调用函数:I2cSlaveReceive
staticvoid(*i2cSlaveReceive)(unsignedcharreceiveDataLength,unsignedchar*recieveData);
//指向发送处理函数的指针,当本机被选中从发送时调用函数:II2cSlaveTransmit
staticunsignedchar(*i2cSlaveTransmit)(unsignedchartransmitDataLengthMax,unsignedchar*transmitData);
//设置总线速率
voidi2cSetBitrate(unsignedintbitrateKHz)
{
unsignedcharbitrate_div;
//SCLfreq=F_CPU/(16+2*TWBR))
#ifdefTWPS0
//对于用速率分频的AVR(mega128)
//SCLfreq=F_CPU/(16+2*TWBR*4^TWPS)
//setTWPStozero
TWSR&=~(1
//计算分频
bitrate_div=((F_CPU/1000l)/bitrateKHz);
if(bitrate_p>=16)
bitrate_div=(bitrate_div-16)/2;
TWBR=bitrate_div;
}
//总线初始化
voidi2cInit(void)
{
//设置总线上拉
#ifdef_MEGA128_INCLUDED_
//#ifdef_MEGA64_INCLUDED_
PORTD.0=1;//i2cSCLonATmega128,64
PORTD.1=1;//i2cSDAonATmega128,64
#else
PORTC.0=1;//i2cSCLonATmega163,323,16,32,等
PORTC.1=1;//i2cSDAonATmega163,323,16,32,等
#endif
//清空从发送和从接受
i2cSlaveReceive=0;
i2cSlaveTransmit=0;
//设置i2c波特率为100KHz
i2cSetBitrate(100);
//I2C总线使能
TWCR|=1
I2cState=I2C_IDLE;
//开I2C中断和回应
TWCR|=1
#asm("sei");
}
voidi2cSetLocalDeviceAddr(unsignedchardeviceAddr,unsignedchargenCallEn)
{
//设置本机从地址(从方式时)
TWAR=(deviceAddr&0xFE)|(genCallEn?1:0);
}
voidi2cSetSlaveReceiveHandler(void(*i2cSlaveRx_func)(unsignedcharreceiveDataLength,unsignedchar*recieveData))
{
i2cSlaveReceive=i2cSlaveRx_func;
}
voidi2cSetSlaveTransmitHandler(unsignedchar(*i2cSlaveTx_func)(unsignedchartransmitDataLengthMax,unsignedchar*transmitData))
{
i2cSlaveTransmit=i2cSlaveTx_func;
}
inlinevoidi2cSendStart(void)
{
TWCR=TWCR&TWCR_CMD_MASK|(1
inlinevoidi2cSendStop(void)
{
//发送停止条件,保持TWEA以便从接收
TWCR=TWCR&TWCR_CMD_MASK|(1
inlinevoidi2cWaitForComplete(void)
{
//等待i2c总线操作完成
while(!(TWCR&(1
inlinevoidi2cSendByte(unsignedchardata)
{
//装载数据到TWDR
TWDR=data;
//发送开始
TWCR=TWCR&TWCR_CMD_MASK|(1
inlinevoidi2cReceiveByte(unsignedcharackFlag)
{
//开始通过i2c接收
if(ackFlag)
{
//ackFlag=TRUE:数据接收后回应ACK
TWCR=TWCR&TWCR_CMD_MASK|(1
else
{
//ackFlag=FALSE:数据接收后无回应
TWCR=TWCR&TWCR_CMD_MASK|(1
}
inlineunsignedchari2cGetReceivedByte(void)
{
//返回接收到的数据
return(TWDR);
}
inlineunsignedchari2cGetStatus(void)
{
//返回总线状态
return(TWSR);
}
voidi2cMasterSend(unsignedchardeviceAddr,unsignedcharlength,unsignedchar*data)
{
unsignedchari;
//等待总线准备完成
while(I2cState);
//设置状态
I2cState=I2C_MASTER_TX;
//准备数据
I2cDeviceAddrRW=(deviceAddr&0xFE);//RW为0:写操作
for(i=0;i
I2cSendDataIndex=0;
I2cSendDataLength=length;
//发送开始条件
i2cSendStart();
}
voidi2cMasterReceive(unsignedchardeviceAddr,unsignedcharlength,unsignedchar*data)
{
unsignedchari;
//等待总线准备完成
while(I2cState);
//设置状态
I2cState=I2C_MASTER_RX;
//保存数据
I2cDeviceAddrRW=(deviceAddr|0x01);//RW为1:读操作
I2cReceiveDataIndex=0;
I2cReceiveDataLength=length;
//发送开始条件
i2cSendStart();
//等待数据准备好
while(I2cState);
//取数据
for(i=0;i
}
unsignedchari2cMasterSendNI(unsignedchardeviceAddr,unsignedcharlength,unsignedchar*data)
{
unsignedcharretval=I2C_OK;
//关I2C中断
TWCR&=~(1
//发送开始条件
i2cSendStart();
i2cWaitForComplete();
//发送器件写地址
i2cSendByte(deviceAddr&0xFE);
i2cWaitForComplete();
//检查器件是否可用
if(TWSR==TW_MT_SLA_ACK)
{
//发送数据
while(length)
{
i2cSendByte(*data++);
i2cWaitForComplete();
length--;
}
}
else
{
//如未回应器件地址,停止发送,返回错误
retval=I2C_ERROR_NODEV;
}
//发送停止条件,保持TWEA以便从接收
i2cSendStop();
while(!(TWCR&(1
//开I2C中断
TWCR|=(1
returnretval;
}
unsignedchari2cMasterReceiveNI(unsignedchardeviceAddr,unsignedcharlength,unsignedchar*data)
{
unsignedcharretval=I2C_OK;
//关I2C中断
TWCR&=~(1
//发送开始条件
i2cSendStart();
i2cWaitForComplete();
//发送器件读地址
i2cSendByte(deviceAddr|0x01);
i2cWaitForComplete();
//检查器件是否可用
if(TWSR==TW_MR_SLA_ACK)
{
//接收数据并回应
while(length>1)
{
i2cReceiveByte(TRUE);
i2cWaitForComplete();
*data++=i2cGetReceivedByte();
length--;
}
//接收数据无回应(末位信号)
i2cReceiveByte(FALSE);
i2cWaitForComplete();
*data++=i2cGetReceivedByte();
}
else
{
//如未回应器件地址,停止发送,返回错误
retval=I2C_ERROR_NODEV;
}
//发送停止条件,保持TWEA以便从接收
i2cSendStop();
//开I2C中断
TWCR|=TWIE;
returnretval;
}
eI2cStateTypei2cGetState(void)
{
returnI2cState;
}
//I2C(TWI)中断服务程序
硬件中断方式I2CCVAV 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)
