主题中讨论的其他器件:TCA9535
目标是读取 tca9535的端口0输入引脚。我的疑问是从器件地址 API、我应该提供0x42或0x21。
第二个是在 senddata API 中使用0x42来开始写入、还是仅为寄存器发送命令字节。
我的从地址为0x21、配置寄存器的命令字节为0x06、 输入端口寄存器的命令字节为0x00。
在 tca9535的数据表中、它显示 从目标读取与写入非常相似、但需要执行一些额外步骤。 要从目标中读取数据、控制器必须首先指示目标要读取哪个寄存器。 这是由控制器完成的
以与写入类似的方式启动传输、即发送 R/ W 位等于
0 (表示写入)、后跟要从中读取的寄存器地址。 当目标方确认这一点时
寄存器地址、控制器再次发送一个启动条件、然后是带有 R/ W 的目标地址
位设置为1 (表示读取)。 这一次、目标确认读取请求、控制器释放
SDA 总线、但会继续向目标器件提供时钟。 在事务的这一部分、控制器
成为控制器-接收器、而目标成为目标-发送器。
控制器继续发送时钟脉冲、但释放 SDA 线、以便目标器件可以发送
数据。 在每个数据字节结束时、控制器向目标器件发送一个 ACK、告知目标器件其
已准备好接收更多数据。 当控制器收到预期的字节数时、它会发送一个 NACK、
向目标器件发出信号、以停止通信并释放总线。 控制器随后会停止
中断。
重新启动后、命令字节定义的寄存器的值与在转换完成后
重新启动发生。 例如、如果命令字节在重新启动之前引用输入端口1、则重新启动
当读取输入端口0时、存储的命令字节更改为基准输入端口0。 原始
命令字节被忘记。 如果发生后续重新启动、则首先读取输入端口0。 将数据计时到
ACK 时钟脉冲的上升沿检测寄存器。 读取第一个字节后、可能会读取其他字节、但
数据现在反映该对中另一个寄存器中的信息。 例如、如果读取输入端口1、则下一个
读取的字节为输入端口0。
数据在 ACK 时钟脉冲的上升沿输入到寄存器中。 输出电压的数量和输出电压
一次读取传输中接收到的数据字节的数量、但当接收到最后一个字节时、总线控制器不得
确认数据。
uint8_t TX_TX_UCCle[3] Data_Master ={0x42、0x00、0x43};
uint8_t configData[2]={/*0x42、*/0x06、0xFF};//用于保存配置数据的阵列
/
int main (空)
{
/*用户代码开始(3)*/
INT I;
内部重复= 0;
INT 延迟= 0;
i2cInit();
sciInit();
I2C_io_exp_init ();
//主机接收功能//
/*配置要与之通信的从器件地址*/
i2cSetSlaveAdd (i2cREG2、0x42);
/*设置到接收器的方向*/
i2cSetDirection (i2cREG2、I2C_receiver);
for (REPEAT = 0;REPEAT < 2;REPEAT ++)
{
/*配置数据计数*/
/*注:可选-它在 Init 中完成,除非用户想要更改*/
i2cSetCount (i2cREG2、3);
/*将模式设置为主模式*/
i2cSetMode (i2cREG2、I2C_MASTER);
/*编程计数后设置停止*/
i2cSetStop (i2cREG2);
/*发送启动条件*/
i2cSetStart (i2cREG2);
/*轮询模式下发送 data_count 数据的数量*/
i2cReceive (i2cREG2、1、IO_RECEIVE_DATA);
/*等待清除总线忙状态*/
while (i2cIsBusy (i2cREG2)== true);
/*等待直到检测到停止*/
while (i2cIsStopDetected (i2cREG2)=0);
/*清除停止条件*/
i2cClearSCD (i2cREG2);
对于(I = 0;I < IO_DATA_SIZE;I++)
{
printBits (IO_RECEIVE_DATA[i]);
}
/*开始下一个块之前的简单 Dealya */
/*取决于从设备准备就绪的速度*/
for (delay=0;delay<1000000;delay++);
}
/功能将端口0上的引脚配置为输入
void configurePort0AsInputs(){
i2cSetSlaveAdd (i2cREG2、0x21);/*设置从器件地址*/
i2cSetDirection (i2cREG2、I2C_TRANSMIT);/*设置到发送器的方向*/
/*配置数据计数*/
i2cSetCount (i2cREG2、2);
i2cSetMode (i2cREG2、I2C_MASTER);/*将模式设置为主模式*/
i2cSetStop (i2cREG2);
i2cSetStart (i2cREG2);/*生成启动条件*/
/*轮询模式下发送 data_count 数据的数量*/
i2cSend (i2cREG2、2、configData);
/*等待清除总线忙状态*/
while (i2cIsBusy (i2cREG2)== true);
/*等待直到检测到停止*/
while (i2cIsStopDetected (i2cREG2)=0);
/*清除停止条件*/
i2cClearSCD (i2cREG2);
}
void i2c_io_exp_init()
{
configurePort0AsInputs();
i2cSetCount (i2cREG2、3);
/*编程计数后设置停止*/
i2cSetStop (i2cREG2);
i2cSetStart (i2cREG2);/*生成启动条件*/
/*传输数据字节*/
i2cSend (i2cREG2、3、Data_Master);
/*等待清除总线忙状态*/
while (i2cIsBusy (i2cREG2)== true);
/*等待直到检测到停止*/
while (i2cIsStopDetected (i2cREG2)=0);
/*清除停止条件*/
i2cClearSCD (i2cREG2);
}