51单片机模拟IIC总线问题
我的单片机是STC12LE5412AD,CPU是三星公司的S3C2410,现在想用51单片机的P1.1和P1.2口来模拟IIC总线与S3C2410通信,有几个关于IIC的...
我的单片机是STC12LE5412AD,CPU是三星公司的S3C2410,现在想用51单片机的P1.1和P1.2口来模拟IIC总线与S3C2410通信,有几个关于IIC的问题不太明白:
1、到底是用51单片机作为主机还是用2410作为主机?如果2410作为主机地址,那么51单片机的从机地址是多少?
2、如果51单片机作为主机,那么如何接收从2410发过来的一个8位的数据?(用软件模拟IIC协议,没有相应的数据寄存器,怎么读对方传过来的数据?)
3、IIC协议的发送数据格式里面,跟在从机地址后面的数据地址是什么?按照我的理解,IIC发送格式里,起始条件后面跟着3个8bit的数据,分别是从机地址、数据地址、数据。最后一个才是我想要的数据,也才是真正需要传输的数据,前面两个都是寻址的东西吧?第一个8bit字节是从机地址还好理解,第二个8bit字节是什么地址?从机的IIC寄存器的地址?如果是IIC的寄存器的话那51单片机就应该不能作为从机了对吧?(因为它是软件模拟IIC的,硬件上并没有IIC的寄存器)
答的好的我加高分! 展开
1、到底是用51单片机作为主机还是用2410作为主机?如果2410作为主机地址,那么51单片机的从机地址是多少?
2、如果51单片机作为主机,那么如何接收从2410发过来的一个8位的数据?(用软件模拟IIC协议,没有相应的数据寄存器,怎么读对方传过来的数据?)
3、IIC协议的发送数据格式里面,跟在从机地址后面的数据地址是什么?按照我的理解,IIC发送格式里,起始条件后面跟着3个8bit的数据,分别是从机地址、数据地址、数据。最后一个才是我想要的数据,也才是真正需要传输的数据,前面两个都是寻址的东西吧?第一个8bit字节是从机地址还好理解,第二个8bit字节是什么地址?从机的IIC寄存器的地址?如果是IIC的寄存器的话那51单片机就应该不能作为从机了对吧?(因为它是软件模拟IIC的,硬件上并没有IIC的寄存器)
答的好的我加高分! 展开
4个回答
展开全部
IIC的地址你可以自己定义的
在硬件上提供过IIC地址的你可以直接选择他的地址进行发送
像你这种情况的话可以自己定义地址:
假设你有两台或者以上的S3C2410,单片机作为主机,然后单片机发送数据,所有S3C接收(接收的前提是他的接收端口上获得IIC的开始信号,你可以选择利用中断进行检测),然后你在软件里可以预先设置好每台S3C的地址,即接收单片机的前8BIT,然后对照地址,一样的话就开始接收接下来的信息,没有就放弃这个通信,这样的话8BIT就可以控制256台S3C了
其实IIC也只是一种通信方式,你可以选择自己的协议,以IIC为基础,比如地址位选择16BIT甚至更多,如果从机是S3C这种32位的RAM9的话,数据位的传输可以32位的传。所谓的开始信号跟终止信号也只是双方默认的方式而已,就像是“点头YES,摇头NO”,你也可以选择相反的方式,只要两台通信的机子能懂就好。
不过最好是采用大家一起的,这样在软件移植的时候会有帮助,也方便别人看懂。当大家在某一领域都用一种方式的时候也就形成所谓的协议,比如TCP/IP,UART,IIC等等。
在硬件上提供过IIC地址的你可以直接选择他的地址进行发送
像你这种情况的话可以自己定义地址:
假设你有两台或者以上的S3C2410,单片机作为主机,然后单片机发送数据,所有S3C接收(接收的前提是他的接收端口上获得IIC的开始信号,你可以选择利用中断进行检测),然后你在软件里可以预先设置好每台S3C的地址,即接收单片机的前8BIT,然后对照地址,一样的话就开始接收接下来的信息,没有就放弃这个通信,这样的话8BIT就可以控制256台S3C了
其实IIC也只是一种通信方式,你可以选择自己的协议,以IIC为基础,比如地址位选择16BIT甚至更多,如果从机是S3C这种32位的RAM9的话,数据位的传输可以32位的传。所谓的开始信号跟终止信号也只是双方默认的方式而已,就像是“点头YES,摇头NO”,你也可以选择相反的方式,只要两台通信的机子能懂就好。
不过最好是采用大家一起的,这样在软件移植的时候会有帮助,也方便别人看懂。当大家在某一领域都用一种方式的时候也就形成所谓的协议,比如TCP/IP,UART,IIC等等。
展开全部
1.当然是51是主机了。
2.建议你仔细看下IIC的结构和通信协议,其实挺简单的,这里面牵扯到开始信号、应答信号等等,看完就明白了。
3.没时间回答了,不过这里面还有重机怎样定义怎样传送数据等等,不过我也不是很明白。呵呵
2.建议你仔细看下IIC的结构和通信协议,其实挺简单的,这里面牵扯到开始信号、应答信号等等,看完就明白了。
3.没时间回答了,不过这里面还有重机怎样定义怎样传送数据等等,不过我也不是很明白。呵呵
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
1.51单片机既可作丛机也可作主机,你可以扫描主机传来的地址码,若与自定的单片机地址吻合则被选中,否则被屏蔽。
2.51单片机作为主机那么先在总线上发送2410地址选中2410并注明是读操作(起始跳变后的第一个字节最低位写1)再发送2410数据寄存器地址,2410响应并返回对应的数据。
3.应该是:从机地址、数据目的地址(数据端口)、数据,也就是先找到位置再填数据,读和写都是这样的。
2.51单片机作为主机那么先在总线上发送2410地址选中2410并注明是读操作(起始跳变后的第一个字节最低位写1)再发送2410数据寄存器地址,2410响应并返回对应的数据。
3.应该是:从机地址、数据目的地址(数据端口)、数据,也就是先找到位置再填数据,读和写都是这样的。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
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<c_k; 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 <at89x52.h>
#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);
}
分!分!分! 赶快拿来!
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<c_k; 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 <at89x52.h>
#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);
}
分!分!分! 赶快拿来!
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询