求高人详细解释C语言i2cxbase = (*(uint32_t*)&(I2Cx));

Python012

求高人详细解释C语言i2cxbase = (*(uint32_t*)&(I2Cx));,第1张

假设I2Cx本身就是结构体指针(即指向外设I2C寄存器首地址),

&(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()

}

显示部分我用的串口,你改改就可以了