
//******************启动IIC总线**************************
void IICStart(void)
{
SCL=0
SDA=1
SCL=1
SDA=0
SCL=0
SDA=1
}
//*************************停止IIC总线********************
void IICStop(void)
{
SCL=0
SDA=0
SCL=1
SDA=1
SCL=0
}
//************************检查应答位**********************
bit IICRecAck(void)
{
SCL=0
SDA=1
SCL=1
CY=SDA //返回值放在CY中
SCL=0
return(CY)
}
//***************************对IIC总线产生应答兆芹**********
void IICACK(void)
{
SDA=0
SCL=1
SCL=0
SDA=1
}
//****************************不对IIC总线产生应答************
void IICNoAck(void)
{
SDA=1
SCL=0
SCL=0
}
//*************************向IIC总线写数***********
void IICSendByte(uchar sendbyte)
{
uchar data j=8
for(j>0j--)
{
SCL=0
sendbyte<<=1 //会使CY=sendbyte^7
SDA=CY
SCL=1
}
SCL=0
}
//***********************从IIC总线读数据族让毕****************
uchar IICReceiveByte(void)
{
register receivebyte,i=8
SCL=0
while(i--)
{
SCL=1
receivebyte=(receivebyte<<1)|SDA
SCL=0
}
return(receivebyte)
}
你说的是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
}
什么是单个数据?IIC总线就是把所需的数据经sda数据线串行传入芯片中,需敬陪手要多少传多少就是 了,我这有个以前写的IIC控制WM8731的乱雀例程,你可亮嫌以参考下//`timescale 1ns / 1ps
module i2c_control(
clk,
i2c_sclk,
i2c_sdat,
i2c_data,
start,
tr_end,
ack,
rst,
counter,
sdo)
input clk
input [23:0]i2c_data
input start
input rst
// input w_r
inout i2c_sdat
output i2c_sclk
output tr_end
output ack
output [5:0]counter
output sdo
reg sdo
reg sclk
reg tr_end
reg [23:0]sd
reg [5:0]counter
assign i2c_sclk=sclk |(((counter>=4)&(counter<=30))?~clk:0)
assign i2c_sdat=sdo?1'bz:0
reg ack1,ack2,ack3
wire ack=ack1 |ack2 |ack3
always@(negedge rst or posedge clk)begin
if(!rst)counter<=6'b111111
else begin
if(start==0)
counter<=0
else
if(counter<6'b111111)counter<=counter+1
end
end
always@(negedge rst or posedge clk)begin
if(!rst)begin sclk<=1sdo<=1ack1<=0ack2<=0ack3<=0tr_end<=0end
else
case(counter)
6'd0 :begin ack1<=0ack2<=0ack3<=0tr_end<=0sdo<=1sclk<=1end
6'd1 :begin sd<=i2c_datasdo<=0end
6'd2 :sclk=0
6'd3 :sdo<=sd[23]
6'd4 :sdo<=sd[22]
6'd5 :sdo<=sd[21]
6'd6 :sdo<=sd[20]
6'd7 :sdo<=sd[19]
6'd8 :sdo<=sd[18]
6'd9 :sdo<=sd[17]
6'd10 :sdo<=sd[16]
6'd11 :sdo<=1'b1
6'd12 :begin sdo<=sd[15]ack1<=i2c_sdatend
6'd13 :sdo<=sd[14]
6'd14 :sdo<=sd[13]
6'd15 :sdo<=sd[12]
6'd16 :sdo<=sd[11]
6'd17 :sdo<=sd[10]
6'd18 :sdo<=sd[9]
6'd19 :sdo<=sd[8]
6'd20 :sdo<=1'b1
6'd21 :begin sdo<=sd[7]ack2<=i2c_sdatend
6'd22 :sdo<=sd[6]
6'd23 :sdo<=sd[5]
6'd24 :sdo<=sd[4]
6'd25 :sdo<=sd[3]
6'd26 :sdo<=sd[2]
6'd27 :sdo<=sd[1]
6'd28 :sdo<=sd[0]
6'd29 :sdo<=1'b1
6'd30 :begin sdo<=1'b0sclk<=1'b0ack3<=i2c_sdatend
6'd31 :sclk<=1'b1
6'd32 :begin sdo<=1'b1tr_end<=1end
endcase
end
endmodule
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)