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

📄 新建 文本文档.txt

📁 C51单片机模拟I2C双机通信协议
💻 TXT
字号:


i2c总线程序
[日期:2005-3-13] 来源:Lierda论坛  作者:石建华 [字体:大 中 小]  

     本程序是i2c总线读写一个字节的程序。在写过程序中,不一定非要检测i2c的应答位,可以直接延时过去就行,但是在读过程中必须给应答信号,读完发停止位,一定确认所发的信号都发上了。否则在连续地址读的过程中可能不会出错,但是在随机度过程中就会出错,我的程序就是在给停止信号时没有给上,24cxx一直在输出数据,结果读出错。找着问题后我的程序只加入了一条命令便完全正常。顺便提醒大家在调试24cxx时最好不要读些连续的地址,这样容易造成巧合因素导致疏忽,我这次犯的就是这个错误,程序一调试就通了,结果不再管它,到后来标定程序后算不出结果才有回头调试,折腾我两周。唉!!!郁闷呀!!!! 

/* *********************** EEPROM 24C256******************************* */ 
// 调试环境:时钟为DCO的时钟;频率4.00MHz 
// 串行接口:P5.6 ------>SDA 
// P5.7 ------>SCL 
// 测试器件:MICROCHIP 24LC256 
// 测试时间:2004-10-15 
// 编写人员:石建华 
/* *********************************************************************** */ 
#include <msp430x14x.h> 
#define SDA_IN P5DIR &=~BIT6 // P5.6 IN 
#define SDA_OUT P5DIR |=BIT6 // P5.6 OUT 

#define SDA_LOW P5OUT &=~BIT6 // sda=0 
#define SDA_HIGH P5OUT |=BIT6 // sda=1 

#define SCL_IN P5DIR &=~BIT7 // P5.7 IN  
#define SCL_OUT P5DIR |=BIT7 // P5.7 OUT 

#define SCL_LOW P5OUT &=~BIT7 
#define SCL_HIGH P5OUT |=BIT7  

void delay (unsigned int TT) 
{ 
for (;TT!=0;TT--); 
}  
unsigned char DATAR01,DATAR11,DATAR21,DATAR31,DATAR41;  
void IIC_START (void) 
{ SDA_OUT; 
SDA_HIGH; 
SCL_HIGH; 
delay (50); 
SDA_LOW; 
delay (50); 
SCL_LOW; 
delay (50); 
} 
void IIC_STOP (void) 
{ SDA_OUT; 
SDA_LOW; 
delay (50); 
SCL_HIGH; 
delay (50); 
SDA_HIGH; 
delay (50); 
} 
void IIC_ACK (void) 
{ SDA_OUT; 
SDA_LOW; 
delay (50); 
SCL_HIGH; 
delay (50); 
SCL_LOW; 
delay (50); 
} 
void IIC_TX_DATA (unsigned char DATA) 
{unsigned char Rn=8,RR=0x80; 
SDA_OUT; 
delay (50); 
for (;Rn!=0;Rn--) 
{ 
if ((DATA&RR)!=0) 
SDA_HIGH; 
else 
SDA_LOW; 
delay (50); 
SCL_HIGH; 
delay (50); 
SCL_LOW; 
delay (50); 
RR>>=1; 
} 
SDA_HIGH; 
delay (50); 
SCL_HIGH; 
delay (50); 
SCL_LOW; 
delay (50); 
} 

unsigned char IIC_RX_DATA (void) 
{unsigned int Rn=8,DATA=0,RR=0x80; 
SDA_IN; // 端口为输入 
delay (50); 
for (;Rn!=0;Rn--) 
{ 
SCL_HIGH; 
delay (50); 

if ((P5IN&BIT6)!=0) 
DATA|=RR; 
else 
DATA&=~RR; 
RR>>=1; 
SCL_LOW; 
delay (50); 
} 

return DATA; 
} 
unsigned char READ_BYTE (unsigned int ADDR) 
{ unsigned char DATA_R,ADDR_L,ADDR_H; 
ADDR_L=ADDR%256; 
ADDR_H=ADDR/256; 
IIC_START (); 
IIC_TX_DATA (0xA0); 
delay(50); 
IIC_TX_DATA (ADDR_H); 
delay(50);  
IIC_TX_DATA (ADDR_L); 
delay(50); 
IIC_START (); 
IIC_TX_DATA (0xA1); 
delay(50); 
DATA_R=IIC_RX_DATA(); 
IIC_STOP (); 
return DATA_R; 
} 

void WRITE_BYTE (unsigned int ADDR,unsigned char DATA_W) 
{ unsigned char ADDR_H,ADDR_L; 
ADDR_L=ADDR%256; 
ADDR_H=ADDR/256; 

SDA_OUT; 
IIC_START (); 
IIC_TX_DATA (0xA0); // E2PROM 片选 

IIC_TX_DATA (ADDR_H); // 大于256BIT的EEPROM需加地址高位 
IIC_TX_DATA (ADDR_L); 
IIC_TX_DATA (DATA_W); 
IIC_STOP (); 
delay (0x3FFF); // 等待写时序 
} 

main() 
{ unsigned int ADDRESS; 
unsigned char DATAR0,DATAR1,DATAR2,DATAR3,DATAR4,DATAW;  

WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer 
DCOCTL = 0X73;  
BCSCTL1= 0X87; // 设置时钟频率4.00MHz 
P5DIR |=0XC0; 
P5OUT |=0XC0; 
DATAR01=0; 
DATAR11=0; 
DATAR21=0; 
DATAR31=0; 
DATAR41=0; 
/* **********WRITE********** */ 
ADDRESS=0X0000; 
DATAW=0X10; 
WRITE_BYTE(ADDRESS,DATAW); 
_NOP(); 
ADDRESS=0X0001; 
DATAW=0X11; 
WRITE_BYTE(ADDRESS,DATAW); 
_NOP(); 
ADDRESS=0X0002; 
DATAW=0X12; 
WRITE_BYTE(ADDRESS,DATAW); 
_NOP(); 
ADDRESS=0X0003; 
DATAW=0X13; 
WRITE_BYTE(ADDRESS,DATAW); 
_NOP(); 
ADDRESS=0X0004; 
DATAW=0X14; 
WRITE_BYTE(ADDRESS,DATAW); 
_NOP(); 
/* ***********READ************** */ 
ADDRESS=0X0005; 
DATAR0=READ_BYTE(ADDRESS); 
DATAR01 = DATAR0; 
_NOP(); 
ADDRESS=0X0001; 
DATAR1=READ_BYTE(ADDRESS); 
DATAR11 = DATAR1; 
_NOP(); 

ADDRESS=0X0002; 
DATAR2=READ_BYTE(ADDRESS); 
DATAR21 = DATAR2; 
_NOP(); 

ADDRESS=0X0004; 
DATAR3=READ_BYTE(ADDRESS); 
DATAR31 = DATAR3; 
_NOP(); 
ADDRESS=0X0000; 
DATAR4=READ_BYTE(ADDRESS); 
DATAR41 = DATAR4; 
_NOP(); 
_NOP(); 
} 



⌨️ 快捷键说明

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