&(I2Cx)是取该结构体指针的地址,相当于二级指针
而i2cxbase是uint32_t类型的,非指针,C语言中,由于类型限制,要进行强制类型转换,下面所作的操作都是因为这个原因,最终达到了 利用uint32_t类型的i2cxbase存储I2Cx结构体指针的地址的目的,简单分析一下:
(uint32_t *) &(I2Cx),将&(I2Cx)类型强制转换为(uint32_t *)类型指针,
最外层的* 取该指针的地址的值,其实取的就是 结构体指针的地址,相当于
&(I2Cx),只不过用 uint32_t类型保存的,用的时候进行强制类型转换即可。
看下面的例子 *(__IO uint32_t *)i2cxbase ,首先将i2cxbase强制类型转换为一个指针,然后取指针的值,其实相当于取了传入的I2Cx指针的值。
有不清楚的或者个人理解有误,欢迎进一步交流、指正...
这是我写的模拟程序,只有一个发送函数和一个接收函数,EP为接收标志位,发送没有标志位,通过外部中断来发送起始信号,无应答与非应答,无结束信号,实测可以正常收发数据#ifndef _IOPORTSEND_H__
#define _IOPORTSEND_H__
#include<reg52.h>
unsigned char DAT,EP=0//可以把DAT当作串口中的SBUF,主机发送完后接收机从DAT提取数据
sbit flag = P3^3//外部中断口
sbit ok = P2^7//起始信号发送口
sbit PCL = P2^6//时钟线
sbit PDA = P2^5//数据线
void delay() //延时函数控制波特率
{
unsigned char a,b
for(b=3b>0b--)
for(a=13a>0a--)
}
void PortInit()//中断配置
{
EA=1
EX1=1
IT1=1
}
void SendPort(unsigned char dat)//发送函数
{
unsigned char i
PCL=0
ok=1//通过ok来启动接收机的中断
ok=0
for(i=0i<8i++)//开始发送数据
{
PCL=0
delay()
if(dat&0x80)
PDA=1
else
PDA=0
PCL=1
delay()
dat<<=1
}
PCL=0
delay()
ok=1//ok置1以便下次发送时启动中断
PCL=1//发送完毕释放时钟线与数据线
PDA=1
}
void ReadPort()interrupt 2//接收函数,在中断函数中接收数据
{
unsigned char i
static unsigned int b
PCL=1
PDA=1//防止接收机的PCL口和PDA口影响数据的接收
for(i=0i<8i++)//开始接收数据
{
DAT<<=1
while(PCL==0)
b=0
while(PCL==1)
{
b++
if(b==1)
if(PDA)
DAT|=0x01
}
}
EP=1//接收完毕后置EP为1,需要在其他函数中清零
}
#endif
#include<at89x51.h>#define uchar unsigned char
#define uint unsigned int
sbit SCL=P3^1
sbit SDA=P3^2
void delay(uint i)
{
uchar j
while(i--)
for(j=0j<100j++)
}
void write_add(uchar r)//r=1 读否则写
{
uchar i
uchar add_rw
if(r)
add_rw=0x91 //读
else
add_rw=0x90 //写
SCL=1 //START
SDA=1
SDA=0
SCL=0
for(i=0i<8i++) //ADDRESS
{
if(add_rw&0x80)
SDA=1
else SDA=0
SCL=1
SCL=0
add_rw=add_rw<<1
}
SDA=1
SCL=1
while(SDA) //等待应答
SCL=0
}
void write_data(uchar d)
{
uchar i
SCL=0
for(i=0i<8i++) //DATA
{
if(d&0x80)
SDA=1
else SDA=0
SCL=1
SCL=0
d=d<<1
}
SDA=1
SCL=1
while(SDA) //等待应答
SCL=0
}
void stop(void)
{
SCL=1
SDA=1
}
uchar read_data(uchar over)
{
uchar i,d
SCL=0
for(i=0i<8i++) //DATA
{
d=d<<1
SCL=1
if(SDA)
d=d|0x01
SCL=0
}
if(over) SDA=1
else SDA=0
SCL=1 //应答
SCL=0
SDA=0
return d
}
void write_cmd(uchar d)
{
uchar i,w_add=0x90
SCL=1 //START
SDA=1
SDA=0
SCL=0
for(i=0i<8i++) //ADDRESS
{
if(w_add&0x80)
SDA=1
else SDA=0
SCL=1
SCL=0
w_add=w_add<<1
}
SDA=1
SCL=1
while(SDA) //等待应答
SCL=0
SDA=0
for(i=0i<8i++) //DATA
{
if(d&0x80)
SDA=1
else SDA=0
SCL=1
SCL=0
d=d<<1
}
SDA=1
SCL=1
while(SDA) //等待应答
SCL=0
SDA=0
SCL=1
SDA=1
}
uchar read_tmp(void)
{
uchar h,l
write_add(0)
write_data(0xee)//转换
stop()
delay(1000)
write_add(0)
write_data(0xaa)//读温度
stop()
write_add(1)
h=read_data(0)
l=read_data(1)
stop()
return(h)
}
void main(void)
{
while(1)
P0=read_tmp()
}
显示部分我用的串口,你改改就可以了