单片机IIC主从机通讯和理解【STC为例】

在最近的项目中需要用到一主多从多个单片机进行数据传输(非强时序),最开始打算使用USART串口来实现,但是串口在连接的时候多个单片机相连会导致数据无法收发的问题,综合考虑SPI和IIC后选择I2C

常见的I2C器件有AT24C02/MPU6050等等,这些都是默认从机,单片机部分从来都是作为主机去实现数据的读写,第一次把单片机做从机来使用就特别迷糊

我个人的理解是,IIC从机可以简单的理解为一个存储器,不能主动读写,受到从机控制,在一段存储范围内,可通过主机的读写函数来实现数据的更替

下面列一下STC的程序吧,其它单片机也是想通的,逻辑一样

sbit    SDA         =   P3^3;
sbit    SCL         =   P3^2;
void Wait()
{
 while(!(I2CMSST & 0x40));
 I2CMSST &= ~0x40;
}

void Start()
{
 I2CMSCR = 0x01; //发送 START 命令
 Wait();
}

void SendData(char dat)
{
 I2CTXD = dat; //写数据到数据缓冲区
 I2CMSCR = 0x02; //发送 SEND 命令
 Wait();
}

void RecvACK()
{
 I2CMSCR = 0x03; //发送读 ACK 命令
 Wait();
}

char RecvData()
{
 I2CMSCR = 0x04; //发送 RECV 命令
 Wait();
 return(I2CRXD);
}

void SendACK()
{
 I2CMSST = 0x00; //设置 ACK 信号
 I2CMSCR = 0x05; //发送 ACK 命令
 Wait();
}

void SendNAK()
{
 I2CMSST = 0x01; //设置 NAK 信号
 I2CMSCR = 0x05; //发送 ACK 命令
 Wait();
}

void Stop()
{
 I2CMSCR = 0x06; //发送 STOP 命令
 Wait();
}

void Delay()
{
 int i;
 for(i = 0; i < 3000; i++)
 {
  _nop_();
  _nop_();
  _nop_();
  _nop_();
 }
}


uchar REC_data(uchar device,char addr)
{
uchar buf1,buf2;
 Start(); //发送起始命令
 SendData(device); //发送设备地址 + 写命令
 RecvACK();
 SendData(addr-1); //发送存储地址高字节
 RecvACK();
 Start(); //发送起始命令
 SendData(device+1); //发送设备地址 + 读命令
 RecvACK();
 buf1 = RecvData(); //读取数据 1
 SendACK();
 buf2 = RecvData(); //读取数据 2
 SendNAK();
 Stop(); //发送停止命令
	return buf2;
	
	
	
	/*
				  SendByte((char)(buf2/1000 + '0'));
					SendByte((char)(buf2/100%10 + '0'));
					SendByte((char)(buf2/10%10 + '0'));
					SendByte((char)(buf2%10 + '0'));
					SendByte('\r');
					SendByte('\n');
	*/
}
void main()  
{
	 P_SW2 |= 0x30; //SCL_4/P3.2, SDA_4/P3.3
	 EA = 1;	
	 P_SW2 |= 0x80;
     I2CCFG = 0xe0; //使能 I2C 主机模式
     I2CMSST = 0x00;
while(1);
}

 

你可能感兴趣的:(单片机,IIC从机,单片机)