cspiao 发表于 2012-7-26 13:35:14

【请教430普通IO口模拟I2C通信的方法。。】

所用的MCU是MSP430F5438。由于需要用到4组需要I2C的外围传感器,而该传感器不能串联使用,所以用了8个普通的IO口模拟I2C功能。

对于每个传感器模块,程序中需要一个IO口控制对方的DATA脚。该IO口需要输出高低电平以模拟通信时序(因此设成输出模式)。在读取数据前,需要给DATA输出高电平,然后通过判断此IO口外部的电平状态,对数据进行读取。

现在问题是,控制DATA的IO口一直是作为输出口进行应用控制,而读取数据时,又得查询该IO的状态(类似读PxIN。PxOUT只存储程序给出的输出状态,不能反映外部电平)。

请问高手们,该功能应该通过什么方式实现呢?

谢谢!!!

lcw_swust 发表于 2012-7-26 14:55:40

写DATA时,IO配置为输出
读DATA时,IO配置为输入

cspiao 发表于 2012-7-26 20:09:06

本帖最后由 cspiao 于 2012-7-26 20:11 编辑

lcw_swust 发表于 2012-7-26 14:55 static/image/common/back.gif
写DATA时,IO配置为输出
读DATA时,IO配置为输入
可以这样操作?
像下面这个51函数里的,操作那么频繁。

INT8 s_read_byte(UINT8 ack)
// reads a byte form the Sensibus and gives an acknowledge in case of "ack=1"
{
UINT8 i, val = 0;

DATA = 1;                              //release DATA-line
for(i = 0x80; i > 0; i /= 2)                //shift bit for masking
{
    SCK = 1;                              //clk for SENSI-BUS
    if(DATA)
    {
      val = (val | i);                        //read bit
    }
    _nop_();
    _nop_();
    _nop_();                              //pulswith approx. 3 us
    SCK = 0;
}
if(ack == 1)
{
    DATA = 0;                              //in case of "ack==1" pull down DATA-Line
}
else
{
    DATA = 1;                              //如果是校验(ack==0),读取完后结束通讯
}
_nop_();
_nop_();
_nop_();                              //pulswith approx. 3 us

SCK = 1;                              //clk #9 for ack
_nop_();
_nop_();
_nop_();                              //pulswith approx. 3 us

SCK = 0;
_nop_();
_nop_();
_nop_();                              //pulswith approx. 3 us

DATA = 1;                              //release DATA-line

return val;
}

lcw_swust 发表于 2012-7-26 20:45:10

cspiao 发表于 2012-7-26 20:09 static/image/common/back.gif
可以这样操作?
像下面这个51函数里的,操作那么频繁。



操作那么频繁,单片机也不会觉得累的

lin562794072 发表于 2012-7-26 23:48:47

{:handshake:}

cspiao 发表于 2012-7-27 13:36:20

lcw_swust 发表于 2012-7-26 14:55 static/image/common/back.gif
写DATA时,IO配置为输出
读DATA时,IO配置为输入

网上参考了一段程序,还真是这么回事。
#include <msp430x16x.h>
#define SDA_IN            P5DIR &=~BIT0    // P5.0 IN
#define SDA_OUT         P5DIR |=BIT0   // P5.0 OUT#define SDA_LOW         P5OUT &=~BIT0   // sda=0
#define SDA_HIGH          P5OUT |=BIT0   // sda=1#define SCL_IN            P5DIR &=~BIT1    // P5.1 IN
#define SCL_OUT         P5DIR |=BIT1    // P5.1 OUT#define SCL_LOW         P5OUT &=~BIT1
#define SCL_HIGH          P5OUT |=BIT1
unsigned char i2c_check_ACK(void)
{
unsigned char AckStatus;
SDA_IN;
SCL_HIGH;
i2c_delay(2);
if(P5IN & 0x01)
{
AckStatus = FALSE;
}
else
{
AckStatus = TURE;
}
SCL_LOW;
i2c_delay(2);
SDA_OUT;
return AckStatus;
}
页: [1]
查看完整版本: 【请教430普通IO口模拟I2C通信的方法。。】