I2C通讯的C语言程序
2015-06-16 09:38
555 查看
#include <INTRINS.H>
#include <stdio.h>
#include <reg51.h>
sbit SCK=0x91;//时钟线端口
sbit SDA=0x90;//数据线端口
#define I2C_Address 0xa0 //I2C芯片地址
#define nop _nop_()
#define NOP nop;nop;nop;nop;nop;nop//延时应大于4.7us
//开始信号
//在时钟线为高电平时,数据线由高向低跳变.
void StartI2C(void)
{ SCK=1;
SDA=1;
NOP;
SDA=0;
NOP;
SCK=0;
NOP;
}
//停止信号
//在时钟线为高电平时,数据线由低向高跳变.
void StopI2C(void)
{ SDA=0;
NOP;
SCK=1;
NOP;
SDA=1;
}
//发送一个字节.
bit SendChar(unsigned char SendData)
{ unsigned char i;
bit ACK;
for(i=0;i<8;i++)
{ if((SendData<<i)&0x80)SDA=1;
else SDA=0;
SCK=1;
NOP;
SCK=0;
NOP;
}
//发送一个字节后,读取来自I2C芯片的响应.
//即在发送完8个字节后,在第九个时钟内,SDA总线应为低电平,表示I2C芯片已经读取了数据.
//否则为高电平.即发送收败.
SDA=1;
SCK=1;
NOP;
ACK=SDA;
SCK=0;
NOP;
return ACK;
}
//在读取完来自I2C的8位数据后,发出读取正确位.
//即发送一个低电平,表示已经读取到来自I2C的数据,并允许I2芯片发送下一字节.
void ACK(void)
{ SDA=0;
NOP;
SCK=1;
NOP;
SCK=0;
}
//在读取完来自I2C的8位数据后,发送不响应位.
//即发送一个高电平,表示已经读取完来自I2C的数据,并且不允许I2C发送下一字节.
void NAK(void)
{
SDA=1;
NOP;
SCK=1;
NOP;
SCK=0;
}
//读入一个字节的数据.
unsigned char ReadChar(void)
{ unsigned char i,BackData;
BackData=0;
SDA=1;
for(i=0;i<8;i++)
{ SCK=1;
nop;nop;nop;
BackData=BackData<<1;
if(SDA)BackData++;
SCK=0;
}
return BackData;
}
//以下所有为测试使用...
//应注意,在读I2C芯片时,在发送完I2C片内地址后,
//一定要发送一个重开始信号,然后再发送读命令.
bit WriteI2C(unsigned char Address,unsigned char WriteData)
{ SENDSTART:
StartI2C();
if(SendChar(I2C_Address)) goto SENDSTART;
SENDADD:
if(SendChar(Address)){StartI2C;goto SENDADD;}
SENDDATA:
if(SendChar(WriteData)){StartI2C;goto SENDDATA;}
if(SendChar(WriteData)){StartI2C;goto SENDDATA;}
StopI2C();
return 0;
}
unsigned char ReadI2C(unsigned char Address)
{ unsigned char BackData;
ReadSTART:
StartI2C();
if(SendChar(I2C_Address)) goto ReadSTART;
ReadADD:
if(SendChar(Address)){StartI2C;goto ReadADD;}
ReadSTART2:
StartI2C();
if(SendChar(I2C_Address+1)) goto ReadSTART2;
BackData=ReadChar();
ACK();
BackData=ReadChar();
NAK();
StopI2C();
return BackData;
}
void Delay(unsigned int ms)
{ unsigned int i,j;
for(i=0;i<ms;i++)
for(j=0;j<240;j++);
}
void main(void)
{ bit j;
unsigned char i,BackData=0;
unsigned char Address=0x00,ReadData=0x00;
while(1)
{ ResetI2C;
ReadData=ReadI2C(Address);
ReadData++;
Delay(5);
WriteI2C(Address,ReadData);
Delay(5);
Address++;Address++;
}
}
I2C 程序(已经验证 )
#define _I2C_C_#include "include_all.h"
/**************************
AT24C02????
//Author: Yuki
//Last modified : 2008-6-8
**************************/
#define NOPS();{_nop_();_nop_();_nop_();_nop_();_nop_();}
sbit SCL = P3^4; //pin16
sbit SDA = P3^5; //pin17
sbit TLED = P3^6;
unsigned char SystemError;
void Delay(int TIME)
{
while(TIME--);
}
//---------------------------------
// Function: void I2C_Start(void)
// Discrption:
//----------------------------------
void I2C_Start(void)
{
SDA = 1;
SCL = 1;
NOPS(); //Initial
SDA = 0;
NOPS(); //START
SCL = 0;
}
//---------------------------------
// Function: void I2C_Stop(void)
// Discrption:
//----------------------------------
void I2C_Stop(void)
{
SCL = 0;
SDA = 0;
NOPS(); //Initial
SCL = 1;
NOPS(); //STOP
SDA = 1;
}
//---------------------------------
// Function: void I2C_Start(void)
// Discrption:
//----------------------------------
WaitAck(void)
{
unsigned char errtime = 255;
SDA = 1;
NOPS();
SCL = 1;
NOPS();
SystemError = 0x10;
while(SDA)
{
errtime--;
if(!errtime)
{
I2C_Stop();
SystemError = 0x11;
return;
}
}
SCL = 0;
}
//---------------------------------
// Function: void SendAck(void)
// Discrption:
//----------------------------------
void SendAck(void)
{
SDA =0 ;
NOPS();
SCL = 1;
NOPS();
SCL = 0;
}
//---------------------------------
// Function: void SendNotAck(void)
// Discrption:
//----------------------------------
void SendNotAck(void)
{
SDA =1 ;
NOPS();
SCL = 1;
NOPS();
SCL = 0;
}
//-----------------------------------------------------
// Function: void I2CSendByte(unsigned char send_data)
// Discrption:
//-----------------------------------------------------
void I2CSendByte(unsigned char send_data)
{
unsigned char count = 8;
for(count = 0;count<8;count++)
{
SCL = 0;
_nop_();
SDA = (bit)(send_data & 0x80);
send_data <<= 1;
NOPS();
SCL = 1;
NOPS();
}
SCL = 0;
}
//-----------------------------------------------------
// Function: unsigned char I2CReceiveByte(void)
// Discrption:
//-----------------------------------------------------
unsigned char I2CReceiveByte(void)
{
unsigned char count = 8;
unsigned char dat = 0;
SDA = 1;
for(count = 0;count<8;count++)
{
dat <<= 1;
SCL = 0;
NOPS();
SCL = 1;
NOPS();
dat |= SDA;
}
SCL = 0;
return(dat);
}
//--------------------------------------------------------------------------
// Function: void WriteCharToChip(unsigned int address,unsigned char dat)
// Discrption:
//--------------------------------------------------------------------------
void WriteCharToChip(unsigned int address,unsigned char dat)
{
I2C_Start();
I2CSendByte(0xA0);
WaitAck();
I2CSendByte((char)(address)>>8); //????AT24C02,AT24C64,AT24C128,AT24C256??,??????????
Delay(300);
WaitAck();
I2CSendByte((char)(address));
WaitAck();
I2CSendByte(dat);
Delay(300);
WaitAck();
I2C_Stop();
}
//--------------------------------------------------------------------------
// Function: unsigned char ReadCharFromChip(unsigned int Address)
// Discrption:
//--------------------------------------------------------------------------
unsigned char ReadCharFromChip(unsigned int Address)
{
unsigned char recv_data;
I2C_Start();
I2CSendByte(0xA0);
WaitAck();
I2CSendByte((char)(Address>>8));//????AT24C02,AT24C64,AT24C128,AT24C256??,??????????
WaitAck();
I2CSendByte((char)(Address));
WaitAck();
I2C_Start();
I2CSendByte(0xA1);
WaitAck();
recv_data = I2CReceiveByte();
SendNotAck();
I2C_Stop();
return(recv_data);
}
main()
{
unsigned char Read_data;
for(;;)
{
WriteCharToChip(0x10,0xA3);
Read_data = ReadCharFromChip(0x10);
}
}
相关文章推荐
- C++通过引用来传递和返回类对象
- C#调用C++DLL出现的堆被损坏,说明加载的任何DLL中有Bug
- C#调用C++DLL出现的堆被损坏,说明加载的任何DLL中有Bug
- NYOJ 79 拦截导弹(dp)
- C++栈和队列
- C++ 查找获取文件名相关函数和实现(_findfirst;_findnext;_findclose;_finddata_t)
- C++ 自定义事件机制2
- Effective C++ 条款50
- c++ new 的几个用法
- C++ Dog类
- 插入排序的C++实现
- 用C++进行函数式编程
- 开始学习C++心得实例(3)
- 【整理】--C++三种参数传递方式
- C++对象模型之默认构造函数的构造操作,拷贝构造函数同
- C++温习-标准库-vector
- 《C++语言基础》程序阅读——二进制文件及文件的随机读写(4)
- C++经典开源库
- C++ Tree类
- 15周《C++语言基础》程序阅读——二进制文件及文件的随机读写(2)(3)