⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 软件模拟i2c从机.txt

📁 软件模拟I2C从机.rar
💻 TXT
字号:
模拟I2C主机的比较多,但是从机相对主机而言要难很多,这个供大家借鉴。 
这个从机程序支持主机对它的随机写和随机读,连续读和连续写没做,有兴趣的可以完善下。

Microcontrol CODE 

#include <msp430x22x4.h> 
#define SDA BIT1 
#define SCL BIT2 

#define SEG_A 0xA0 //0x0200---0x027F 
#define SEG_B 0xB0 //0x0280---0x02FF 
#define SEG_C 0xC0 //0x0300---0x037F 

//0x0380---0x0400 
__no_init char wokao@0x243; 
//============================= 
char *send_ptr; 
char DEVICE_ADR=0; 
char WORD_ADR=0; 
char REC_DATA=0; 
char START_flag = 0; 
char STOP_flag = 0; 
char PreState = 0; 
char NowState = 0; 
//*********************函数声明************************************* 
void ACK(void); 

//**************************************************************** 
void main( void ) 
{ 
// Stop watchdog timer to prevent time out reset 
WDTCTL = WDTPW + WDTHOLD; 

//======================MCLK=16MHz===================================== 
DCOCTL = CALDCO_16MHZ; 
BCSCTL1 = CALBC1_16MHZ; //MCLK=DCO=16MHz 
P3DIR &= ~(SDA+SCL); 
while(1) 
{ 
NN=10; 
PreState = READ_SDA; 
while(READ_SCL && NN--) 
{ 
NowState = READ_SDA; 
if(PreState && !NowState) 
{ 
START_flag = 1; 
_DINT(); 
} 
if(!PreState && NowState) 
{ 
STOP_flag = 1; 
_EINT(); 
} 
PreState = NowState; 
if(START_flag) 
{ 
START_flag=0; 
while(READ_SCL); //START时的SCL高电平状态就等待 
for(gg=8;gg>0;gg--) //接收器件地址 
{ 
while(!READ_SCL); //SCL低电平状态就等待 

DEVICE_ADR<<=1; 
if(READ_SDA) //数据的第一个CLK高电平来临 
DEVICE_ADR |= 0x01; 

while(READ_SCL); //SCL高电平状态就等待 
} 
ACK(); //对设备地址ACK应答信 
//-----------以上收到了设备地址,并知晓主机要对从机进行读还是写操作--- 

for(gg=8;gg>0;gg--) //接收内存单元地址 
{ 
while(!READ_SCL); 

WORD_ADR<<=1; 
if(READ_SDA) 
WORD_ADR |= 0x01; 

while(READ_SCL); 
} 
//-----------以上就已经接收到内存单元地址------------ 
ACK(); //对内存单元ACK应答信号 


if(DEVICE_ADR & 0x01) //从机发数据给主机 R/W=1 
{ 
if(DEVICE_ADR==SEG_A+0x01) 
{ 
send_ptr =(char*)(0x0200 + WORD_ADR); 
} 
else if(DEVICE_ADR==SEG_B+0x01) 
{ 
send_ptr =(char*)(0x0280 + WORD_ADR); 
} 
else if(DEVICE_ADR==SEG_C+0x01) 
{ 
send_ptr =(char*)(0x0300 + WORD_ADR); 
} 

//--------以上是判断出为主机读从机,要把要读的地址单元赋给指针--- 

for(gg=8;gg>0;gg--) 
{ 
while(!READ_SCL); 
if( *send_ptr & 0x80) 
_NOP(); 
else 
{ 
P3DIR |= SDA; //输出0 
} 
while(READ_SCL); //SCL为1,就保持SDA输出不变 
P3DIR &= ~SDA; //SCL为0,就把SDA从新切换到接收状态 
*send_ptr <<=1; 
} 
ACK(); //从机数据发送完毕,应答信号 
_NOP(); 
//------------------以上是从机发数据给主机----------------- 
} 
else //主机写从机 R/W=0 
{ 
for(gg=8;gg>0;gg--) //接收主机要写到该器件内存单元的数据 
{ 
while(!READ_SCL); 

REC_DATA <<=1; 
if(READ_SDA) 
REC_DATA |= 0x01; 

while(READ_SCL); 
} 
if(DEVICE_ADR==SEG_A) 
{ 
send_ptr =(char*)(0x0200 + WORD_ADR); 
*send_ptr = REC_DATA; 
} 
else if(DEVICE_ADR==SEG_B) 
{ 
send_ptr =(char*)(0x0280 + WORD_ADR); 
*send_ptr = REC_DATA; 
} 
else if(DEVICE_ADR==SEG_C) 
{ 
send_ptr =(char*)(0x0300 + WORD_ADR); 
*send_ptr = REC_DATA; 
} 
ACK(); 
_NOP(); 
while(!READ_SCL); 
} 
}// if(START_flag) 

}//while(NN--) 
_EINT(); 
_NOP(); 
}//while(1) 
} 
//**************************************************** 
void ACK(void) 
{ 
// while(READ_SCL); 
while(!READ_SCL); 
P3DIR |= SDA; //第9个CLK变高的情况下,SDA输出0 
while(READ_SCL); 
P3DIR &= ~SDA; //第9个CLK变低的情况下,SDA输出1 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -