📄 iic.c
字号:
#include "config.h"
#include <stdio.h>
union
{
float f;
uchar c;
uint i;
}IIC_union;
/******************************************************************************************/
//
/******************************************************************************************/
/*void delayXms(uint time) //延时xxms time<744
{
ulong i;
for(i=29*time;i>0;i--){}
} */
//=================================================================
// Provide some data setup time to allow
// SDA to stabilize in slave device
// Completely arbitrary delay (10 cycles)
//=================================================================
void I2CSetupDelay() { asm NOP; asm NOP; }
//=================================================================
// Bit delay to provide (approximately) the desired
// SCL frequency // Again, this is arbitrary (16 cycles)
//=================================================================
void I2CBitDelay() { asm NOP; asm NOP; asm NOP; asm NOP; asm NOP; }
/*****************************************************************************************
//
//IIC读写子程序
//
******************************************************************************************/
bit RW24XX(unsigned char *DataBuff,uchar ByteQuantity,uint Address,uchar ControlByte)
{
unsigned char i=ERRORCOUNT;
unsigned char errorflag=1;
IICStart();
IICSendByte(0xA0);
delayXms(10);
IICSendByte((unsigned char)(Address>>8));
delayXms(10);
IICSendByte((unsigned char)Address);
IICStart();
IICSendByte(0XA1);
delayXms(10);
while(--ByteQuantity) {
*DataBuff++=IICReceiveByte();
delayXms(10);
}
IICStop();
errorflag=0;
if(!(ControlByte&0x01))
{
delayXms(20);
}
return(errorflag);
}
//=================================================================
// A START condition is defined as a falling edge
// on SDA while SCL is high
//=================================================================
void I2CStartBit() {
I2CPORT |= SCL;
I2CPORT |= SDA;
SDA1=1;
SCL1=1;
SDA1=0;
//I2CDIR |= SDA;
//I2CDIR |= SCL;
//I2CPORT &= ~SDA;
I2CBitDelay();
//I2CPORT &= ~SCL;
SCL1=0;
}
//=================================================================
// A STOP condition is defined as a rising edge
// on SDA while SCL is high
//=================================================================
void I2CStopBit()
{
I2CPORT &= ~SDA;
I2CPORT |= SCL;
I2CPORT |= SDA;
I2CBitDelay();
}
//=================================================================
//
//=================================================================
void I2CTxByte(unsigned char ch)
{
unsigned char i;
for(i = 8;i >0;i--)
{
if((ch & 0x80)!=0) I2CPORT |= SDA; //Set the data bit value
else I2CPORT &= ~SDA;
I2CSetupDelay();
I2CPORT |= SCL;
I2CBitDelay();
I2CPORT &= ~SCL;
ch <<= 1;
}
I2CPORT |= SDA;
I2CDIR &= ~SDA; //Set SDA as input I2CSetupDelay();
I2CPORT |= SCL; //Clock the line to get ACK
I2CBitDelay();
//
if((I2CPORT & SDA)==0) {
//Look for ACK from slave device
I2CPORT &= ~SCL; //Restore clock line
I2CDIR |= SDA; //SDA back as output
}
else
{
//No acknowledgment received from slave device
//Some error action can be performed here
//For now, just restore the bus
I2CPORT &= ~SCL;
I2CDIR |= SDA;
}
}
//=================================================================
// I2CRxByte // Recieve the byte to Acc from the SDA pin
// (Acc will not be restored on return)
// Must be careful to change SDA values only while SCL is low,
// otherwise a STOP or START could be implied
//=================================================================
unsigned char I2CRxByte()
{
unsigned char i,ch=0;
I2CDIR &= ~SDA;
//Set the SDA as input
for(i = 8;i > 0;i--)
{ ch <<= 1;
// I2CSetupDelay();
//Wait a bit
I2CPORT |= SCL; //Clock it in
I2CSetupDelay(); //Wait a bit
if((I2CPORT & SDA)!=0) ch++;
I2CPORT &= ~SCL; //Restore clock to low state
I2CBitDelay();
}//
I2CPORT &= ~SDA;
//SDA set low
I2CDIR |= SDA;
//Set SDA as output
I2CSetupDelay();
I2CPORT |= SCL; //Clock the line to give ACK
I2CBitDelay();//
I2CPORT &= ~SCL;
return ch;
}
/*****************************************************************************************
//
//启动总线
//
******************************************************************************************/
void IICStart(void)
{
I2CPORT |= SCL;
I2CPORT |= SDA;
SDA1=1;
SCL1=1;
SDA1=0;
//I2CDIR |= SDA;
//I2CDIR |= SCL;
//I2CPORT &= ~SDA;
I2CBitDelay();
//I2CPORT &= ~SCL;
SCL1=0;
/*
I2CPORT |= SCL;
I2CPORT |= SDA;
I2CDIR |= SDA;
I2CDIR |= SCL;
I2CPORT &= ~SDA;
I2CBitDelay();
I2CPORT &= ~SCL;
*/
/*
SDA=1;
asm(nop);
asm(nop);
SCL=1;
PTCDD_PTCDD0=1;
PTCDD_PTCDD1=1;
asm(nop);
asm(nop);
SDA=0;
asm(nop);
asm(nop);
asm(nop);
asm(nop);
asm(nop);
SCL=0;
asm(nop);
asm(nop);
*/
}
/******************************************************************************************
//
// 停止总线
//
******************************************************************************************/
void IICStop(void)
{
SDA1=0;
SCL1=1;
SDA1=1;
I2CBitDelay();
/*
I2CPORT &= ~SDA;
I2CPORT |= SCL;
I2CPORT |= SDA;
I2CBitDelay();
*/
/*
SDA=0;
asm(nop);
asm(nop);
SCL=1;
asm(nop);
asm(nop);
SDA=1;
asm(nop);
asm(nop);
asm(nop);
asm(nop);
asm(nop);
*/
}
/******************************************************************************************
//
// 检查应答位
//
******************************************************************************************/
bit IICRecAck(void)
{
unsigned char CY=0;
/*
SDA=1;
PTCDD_PTCDD1=0;
asm(nop);
asm(nop);
SCL=1;
asm(nop);
asm(nop);
asm(nop);
asm(nop);
asm(nop);
CY=SDA;
asm(nop);
asm(nop);
PTCDD_PTCDD1=1;
*/
return(CY);
}
/******************************************************************************************
//
// 产生应答
//
*******************************************************************************************/
void abcIICAck(void)//
{
/*
PTCDD_PTCDD1=1;
SDA=0;
asm(nop);
asm(nop);
SCL=1;
asm(nop);
asm(nop);
SCL=0;
asm(nop);
asm(nop);
asm(nop);
asm(nop);
asm(nop);
SDA=1;
*/
}
/******************************************************************************************
//
// 不产生应答
//
******************************************************************************************/
void IICNoAck(void)
{
/*
PTCDD_PTCDD1=1;
SDA=1;
asm(nop);
asm(nop);
SCL=1;
asm(nop);
asm(nop);
asm(nop);
asm(nop);
asm(nop);
SCL=0;
*/
}
/******************************************************************************************
//
// 向总线写数据
//
******************************************************************************************/
void IICSendByte(unsigned char ch)
{
unsigned char i;
for(i = 8;i >0;i--)
{
if((ch&0x80)!=0)
I2CPORT |= SDA; //Set the data bit value
else
I2CPORT &= ~SDA;
I2CSetupDelay();
I2CPORT |= SCL;
I2CBitDelay();
I2CPORT &= ~SCL;
ch <<= 1;
}
I2CPORT |= SDA;
I2CDIR &= ~SDA; //Set SDA as input I2CSetupDelay();
I2CPORT |= SCL; //Clock the line to get ACK
I2CBitDelay();
//
if((I2CPORT & SDA)==0) {
//Look for ACK from slave device
I2CPORT &= ~SCL; //Restore clock line
I2CDIR |= SDA; //SDA back as output
}
else
{
//No acknowledgment received from slave device
//Some error action can be performed here
//For now, just restore the bus
I2CPORT &= ~SCL;
I2CDIR |= SDA;
}
}
/******************************************************************************************
//
// 总线上读数据
//
******************************************************************************************/
unsigned char IICReceiveByte(void)
{
unsigned char i,ch=0;
I2CDIR &= ~SDA;
//Set the SDA as input
for(i = 8;i > 0;i--)
{
ch <<= 1;
I2CSetupDelay();
//Wait a bit
I2CPORT |= SCL; //Clock it in
I2CSetupDelay(); //Wait a bit
if((I2CPORT & SDA)!=0) ch++;
I2CPORT &= ~SCL; //Restore clock to low state
I2CBitDelay();
}//
I2CPORT &= ~SDA;
//SDA set low
I2CDIR |= SDA;
//Set SDA as output
I2CSetupDelay();
I2CPORT |= SCL; //Clock the line to give ACK
I2CBitDelay();//
I2CPORT &= ~SCL;
return ch;
}
/******************************************************************************************
//
******************************************************************************************/
void WriteIicFunc(unsigned char *DataBuff,uchar ByteQuantity,uint Address) {
unsigned char j;
IICStart();
IICSendByte(0xA0);
delayXms(10);
IICSendByte((unsigned char)(Address>>8)); //0x03
delayXms(10);
IICSendByte((unsigned char)Address);
delayXms(10);
j=ByteQuantity;
while(j--)
{
IICSendByte(*DataBuff++);
}
IICStop();
delayXms(200);
}
/******************************************************************************************
//
******************************************************************************************/
void ReadIicFunc(unsigned char *DataBuff,uchar ByteQuantity,uint Address) {
IICStart();
IICSendByte(0xA0);
delayXms(10);
IICSendByte((unsigned char)(Address>>8)); //0x03
delayXms(10);
IICSendByte((unsigned char)Address);
IICStart();
IICSendByte(0XA1);
delayXms(10);
while(--ByteQuantity)
{
*DataBuff++=IICReceiveByte();
}
IICStop();
}
float read_IIC_float(uint adr)
{
ReadIicFunc((unsigned char *)&IIC_union.f,4,adr);
return IIC_union.f;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -