51单片机模拟IIC总线问题

2023-12-26 17:26:01
推荐回答(4个)
回答1:

IIC的地址你可以自己定义的
在硬件上提供过IIC地址的你可以直接选择他的地址进行发送
像你这种情况的话可以自己定义地址:
假设你有两台或者以上的S3C2410,单片机作为主机,然后单片机发送数据,所有S3C接收(接收的前提是他的接收端口上获得IIC的开始信号,你可以选择利用中断进行检测),然后你在软件里可以预先设置好每台S3C的地址,即接收单片机的前8BIT,然后对照地址,一样的话就开始接收接下来的信息,没有就放弃这个通信,这样的话8BIT就可以控制256台S3C了

其实IIC也只是一种通信方式,你可以选择自己的协议,以IIC为基础,比如地址位选择16BIT甚至更多,如果从机是S3C这种32位的RAM9的话,数据位的传输可以32位的传。所谓的开始信号跟终止信号也只是双方默认的方式而已,就像是“点头YES,摇头NO”,你也可以选择相反的方式,只要两台通信的机子能懂就好。
不过最好是采用大家一起的,这样在软件移植的时候会有帮助,也方便别人看懂。当大家在某一领域都用一种方式的时候也就形成所谓的协议,比如TCP/IP,UART,IIC等等。

回答2:

1.当然是51是主机了。
2.建议你仔细看下IIC的结构和通信协议,其实挺简单的,这里面牵扯到开始信号、应答信号等等,看完就明白了。
3.没时间回答了,不过这里面还有重机怎样定义怎样传送数据等等,不过我也不是很明白。呵呵

回答3:

1.51单片机既可作丛机也可作主机,你可以扫描主机传来的地址码,若与自定的单片机地址吻合则被选中,否则被屏蔽。
2.51单片机作为主机那么先在总线上发送2410地址选中2410并注明是读操作(起始跳变后的第一个字节最低位写1)再发送2410数据寄存器地址,2410响应并返回对应的数据。
3.应该是:从机地址、数据目的地址(数据端口)、数据,也就是先找到位置再填数据,读和写都是这样的。

回答4:

1: 51做不了从机。
2: 51通过控制时钟信号来 控制2410的时序, 在SCK为高时,读取一位数据,sck 一个周期读一个bit数据。
3: 每种器件采用的具体IIC协议内容不是很相同,要仔细看PDF DataSheet上的时序图。
附上C源程序 (AT24C1024)

IIC.h
#define I2C_Sda P1_0
#define I2C_Sck P1_1

void I2C_WriteStr(unsigned char *cp_Src0); //c_Src = {Num, AddU, AddH AddL, Char0, Char1 .... Char n}
void I2C_ReadStr (unsigned char* cp_Src0); //c_Src = {Num, AddU, AddH AddL, Char0, Char1 .... Char n}

void I2C_Write(unsigned char c_Data){
unsigned char c_i;
for (c_i=0; c_i<8; c_i++)
{
I2C_Sda = c_Data&0x80;
c_Data = c_Data<<1;
I2C_Sck = 1;
I2C_Sck = 0;
}
}

unsigned char I2C_Read(){
unsigned char c_i, c_k;
for (c_i=0; c_i<8; c_i++)
{
I2C_Sck = 0;
I2C_Sda = 1;
I2C_Sck = 0;
I2C_Sck = 1;
c_k = c_k<<1;
c_k = c_k|I2C_Sda;
}
return c_k;
}

void I2C_WriteStr(unsigned char *cp_Src0){//c_Src = {Num, AddU, AddH AddL, Char0, Char1 .... Char n}
/*
Addu = 1010 0APW
7~3 = 10100
2(A1):Device Address
1(A17):Address 17 of the EEPROM
0(W/-R):
1: Write
0: Read
*/

unsigned char c_i, c_k, *cp_Src;
I2C_WriteStr_0:
c_k = *cp_Src0+3;
cp_Src = cp_Src0;
cp_Src++;
I2C_Sda = 1;
I2C_Sck = 1;
I2C_Sda = 0;
I2C_Sck = 0;

for (c_i=0; c_i {
I2C_Write(*cp_Src);
cp_Src++;
I2C_Sda = 1;
I2C_Sck = 1;
if (I2C_Sda==1) goto I2C_WriteStr_0;
I2C_Sck = 0;
}
I2C_Sda = 0;
I2C_Sck = 1;
I2C_Sda = 1;
}

void I2C_ReadStr (unsigned char* cp_Src0){//c_Src = {Num, AddU, AddH AddL, Char0, Char1 .... Char n}
/* c_Src0 = {Num, AddU, AddH AddL, Char0, Char1 .... Char n}
Addu = 1010 0APW
7~3 = 10100
2(A1):Device Address
1(A17):Address 17 of the EEPROM
0(W/-R):
1: Write
0: Read
*/
unsigned char* cp_k, c_i, *cp_Src;
I2C_ReadStr_0:
cp_Src = cp_Src0;
cp_k = cp_Src0+4;
cp_Src++;
I2C_Sda = 1;
I2C_Sck = 1;
I2C_Sda = 0;
I2C_Sck = 0;

for (c_i=0; c_i<3; c_i++)
{
I2C_Write(*cp_Src);
cp_Src++;
I2C_Sda = 1;
I2C_Sck = 1;
if (I2C_Sda) goto I2C_ReadStr_0;
I2C_Sck = 0;
}
// I2C_Sda = 0;
// I2C_Sck = 1;
// I2C_Sda = 1;

I2C_Sda = 1;
I2C_Sck = 1;
I2C_Sda = 0;
I2C_Sck = 0;

I2C_Write(*(cp_Src0+1)+1);

I2C_Sda = 1;
I2C_Sck = 1;
if (I2C_Sda==1) goto I2C_ReadStr_0;
I2C_Sck = 0;

for (c_i=0; c_i<*cp_Src0; c_i++)
{
*cp_k = I2C_Read();
cp_k++;
I2C_Sck = 0;
I2C_Sda = 0;
I2C_Sck = 1;
}
I2C_Sda = 1;
}

#include
#include "i2c.h"

main()
{
unsigned char c_Data[] = {8, 0xa0, 0, 0, 3, 4, 4, 3, 5, 6, 7, 8};

unsigned char c_i;

I2C_WriteStr (c_Data);
I2C_ReadStr(c_Data);
I2C_WriteStr (c_Data);

while(1);
}

分!分!分! 赶快拿来!