【请教430普通IO口模拟I2C通信的方法。。】
所用的MCU是MSP430F5438。由于需要用到4组需要I2C的外围传感器,而该传感器不能串联使用,所以用了8个普通的IO口模拟I2C功能。对于每个传感器模块,程序中需要一个IO口控制对方的DATA脚。该IO口需要输出高低电平以模拟通信时序(因此设成输出模式)。在读取数据前,需要给DATA输出高电平,然后通过判断此IO口外部的电平状态,对数据进行读取。
现在问题是,控制DATA的IO口一直是作为输出口进行应用控制,而读取数据时,又得查询该IO的状态(类似读PxIN。PxOUT只存储程序给出的输出状态,不能反映外部电平)。
请问高手们,该功能应该通过什么方式实现呢?
谢谢!!! 写DATA时,IO配置为输出
读DATA时,IO配置为输入 本帖最后由 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;
}
cspiao 发表于 2012-7-26 20:09 static/image/common/back.gif
可以这样操作?
像下面这个51函数里的,操作那么频繁。
操作那么频繁,单片机也不会觉得累的 {:handshake:} 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]