c51单片机I2c总线的读写编程步骤

c51单片机I2c总线的读写编程步骤,第1张

你说的是IO模拟i2c吧,这个你参考下

#pragma ot(6,SIZE)

#define ERRORCOUNT 10

enum eepromtype {M2401,M2402,M2404,M2408,M2416,M2432,M2464,M24128,M24256}

enum eepromtype EepromType

/****************************** I2C总线 ******************************/

bit RW24XX(uchar *DataBuff,uchar ByteQuantity,uint Address,uchar ControlByte,enum eepromtype EepromType)

{

void Delay(uchar DelayCount)

void IICStart(void)

void IICStop(void)

bit IICRecAck(void)

void IICNoAck(void)

void IICAck(void)

uchar IICReceiveByte(void)

void IICSendByte(uchar sendbyte)

uchar data j,i = ERRORCOUNT

bit errorflag = 1

while (i--)

{

IICStart()

IICSendByte(ControlByte &0xfe)

if (IICRecAck())

continue

if (EepromType >M2416)

{

IICSendByte((uchar)(Address >>8))

if (IICRecAck())

continue

}

IICSendByte((uchar)Address)

if (IICRecAck())

continue

if (!(ControlByte &0x01))

{

j = ByteQuantity

errorflag = 0

while (j--)

{

IICSendByte(*DataBuff++)

if(!IICRecAck())

continue

errorflag = 1

break

}

if (errorflag==1)

continue

break

}

else

{

IICStart()

IICSendByte(ControlByte)

if (IICRecAck())

continue

while (--ByteQuantity)

{

*DataBuff++ = IICReceiveByte()

IICAck()

}

*DataBuff = IICReceiveByte() //read last byte data

IICNoAck()

errorflag = 0

break

}

}

IICStop()

if (!(ControlByte &0x01))

{

Delay(255)

Delay(255)

Delay(255)

Delay(255)

}

return(errorflag)

}

/***************** 启动总线 ********************/

void IICStart(void)

{

scl = 0

sda = 1

scl = 1

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

sda = 0

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

scl = 0

sda = 1

}

/***************** 停止IIC总线 ****************/

void IICStop(void)

{

scl = 0

sda = 0

scl = 1

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

sda = 1

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

scl = 0

}

/************** 检查应答位 *******************/

bit IICRecAck(void)

{

scl = 0

sda = 1

scl = 1

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

CY = sda//因为返回值总是放在CY中的

scl = 0

return(CY)

}

/*************** 对IIC总线产生应答 *******************/

void IICACK(void)

{

sda = 0

scl = 1

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

scl = 0

_nop_()

_nop_()

sda = 1

}

/***************** 不对IIC总线产生应答 ***************/

void IICNoAck(void)

{

sda = 1

scl = 1

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

scl = 0

}

/******************* 向IIC总线写数据 *********************/

void IICSendByte(uchar sendbyte)

{

uchar data j = 8

for (j >0j--)

{

scl = 0

sendbyte <<= 1 //无论C51怎样实现这个 *** 作,始终会使CY=sendbyte^7

sda = CY

scl = 1

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

_nop_()

}

scl = 0

}

/***************** 从IIC总线上读数据子程序 ******************/

uchar IICReceiveByte(void)

{

register receivebyte,i = 8

scl = 0

while (i--)

{

scl = 1

receivebyte = (receivebyte <<1) | sda

scl = 0

}

return(receivebyte)

}

/*************** 一个简单延时程序 ******************/

void Delay(uchar DelayCount)

{

while(DelayCount--)

}

void Delay_Msec(uchar t)

{

uchar i

while (t >0)

{

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

{

WDT = 1

_nop_()

_nop_()

_nop_()

_nop_()

}

t--

}

}

/*************** 24C256读一个字节 *****************/

uchar Rd_24c256(uint beginbyte)

{

uchar data result

uchar i

EA = 0

i = RW24XX(&result,1,beginbyte,rd_24c256,M24256)

EA = 1

return(result)

}

/*************** 24C256写一个字节 ***************/

void Wr_24c256(uint address,uchar datum)

{

uchar i

EA = 0

i = RW24XX(&datum,1,address,wr_24c256,M24256)

Delay_Msec(10)

EA = 1

}

网上down一个IIC模拟程序分析一下就是了,时序要求没那么精确的,大于多少ns就行了。稍作延时。上拉电阻一般就弄个10K。无论是对于哪种芯片IIC的时序是没多大差别的,弄个大概出来,在用示波器看,再比较手册,看哪不对再改。这样是调IIC最好方法。

还有,我不是记得STM32有硬IIC核吗,为何还需要用模拟IIC时序的方式去实现


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

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

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

发表评论

登录后才能评论

评论列表(0条)

保存