• 回复
  • 收藏
  • 点赞
  • 分享
  • 发新帖

24C16规范的51读写C文件(公开开发板程序之一)

/*I2C总线是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据.在CPU与被控IC之间、IC与IC之间进行双向传送,最高传送速率400kbps.各种被控制电路均并联在这条总线上,但就像电话机一样只有拨通各自的号码才能工作,所以每个电路和模块都有唯一的地址,在信息的传输过程中,I2C总线上并接的每一模块电路既是主控器(或被控器),又是发送器(或接收器),这取决于它所要完成的功能.CPU发出的控制信号分为地址码和控制量两部分,地址码用来选址,即接通需要控制的电路,确定控制的种类;控制量决定该调整的类别(如对比度、亮度等)及需要调整的量.这样,各控制电路虽然挂在同一条总线上,却彼此独立,互不相关.
   I2C总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号、结束信号和应答信号.
   开始信号:SCL为高电平时,SDA由高电平向低电平跳变,开始传送数据.
   结束信号:SCL为低电平时,SDA由低电平向高电平跳变,结束传送数据.
   应答信号:接收数据的IC在接收到8bit数据后,向发送数据的IC发出特定的低电平脉冲,表示已收到数据.CPU向受控单元发出一个信号后,等待受控单元发出一个应答信号,CPU接收到应答信号后,根据实际情况作出是否继续传递信号的判断.若未收到应答信号,由判断为受控单元出现故障.
   目前有很多半导体集成电路上都集成了I2C接口.*/

/*
***************************************************************************
*
*     (C) Copyright 2007,单片机初学者园地
*                          All Rights reserved.
*
*项目名称:    51单片机学习开发系统
*                
*本文件名称:IIC.c        
* 完成作者 : 单片机初学者  
* 当前版本 : V1.0        
* 完成日期 :
* 描        述 :  本程序结构简单、合理,有帮助于初学者养成良好的编
*                         程风格.主要实现IIC总线的读写.
****************************************************************************
*/

#include    //调用头文件(单片机内部的寄存器定义)
#include <     .h>
#define uchar unsigned char
#define uint unsigned int
#define IIC_READ  0XA1   //定义读指令
#define IIC_WRITE 0XA0   //定义写指令
#define NOP _nop_(); _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_()

//==============================

sbit  SDA=P0^6;  
sbit  SCL=P0^7;  

//===============================
//define a bit_operation byte to use in shift operation
//use this mode can achieve high operation speed
uchar bdata bbyte;//定义位操作用数组,采用此方法可提高位操作速度
sbit a0=bbyte^0;
sbit a1=bbyte^1;
sbit a2=bbyte^2;
sbit a3=bbyte^3;
sbit a4=bbyte^4;
sbit a5=bbyte^5;
sbit a6=bbyte^6;
sbit a7=bbyte^7;
//=============定义位标志===========================
bit IFACK; //record the SDA state to confirn if ACK has happened
bit NO_ACK; //no ack flag
bit BUS_FAULT; //bus fault flag
//=============IIC开始时序==========================
//FUNCTION:ROUTES TO PROVIDE A START SIGNAL
void start(void)
{
SCL=0;SDA=1; NOP;SCL=1;SDA=0;NOP;SCL=0;
}
//==============IIC停止时序=========================
//FUNCTION:ROUTES TO PROVIDE A STOP SIGNAL
void stop(void)
{
SCL=0;SDA=0;NOP;SCL=1;SDA=1;NOP;SCL=0;
}
//=====================================
//FUNCTION:ROUTES TO PROVIDE ACK SINGAL
void ack(void)
{
SCL=0;SDA=0;NOP;SCL=1;NOP;SCL=0;
}
//=====================================
//FUNCTION:ROUTES TO RELEASE THE SDA TO RECEIVE A ACK SIGNAL
//              OR TO PROVIDE A NO_ACK SIGNAL
//type=1等待应答信号
//type=0 产生无应答信号
void nack(uchar type)
{
SCL=0;SDA=1;NOP;SCL=1;IFACK=SDA; NOP;SCL=0;
if(type)
{
  if(IFACK) //如果无应答信号,则置标志位NO_ACK,程序中止
  {
   NO_ACK=1; //用户可以加入自己的异常处理程序
   //while(1);
  }
  else NO_ACK=0;
}
}
//=======================================================
//FUNCTION:THE IIC DEVICE SHIFT OUT A BYTE  TO THE MASTER
uchar  inbyte(void)
{ //从IIC器件中读出数据
SDA=1;
SCL=1;a7=SDA;NOP;SCL=0;
SCL=1;a6=SDA;NOP;SCL=0;
SCL=1;a5=SDA;NOP;SCL=0;
SCL=1;a4=SDA;NOP;SCL=0;
SCL=1;a3=SDA;NOP;SCL=0;
SCL=1;a2=SDA;NOP;SCL=0;
SCL=1;a1=SDA;NOP;SCL=0;
SCL=1;a0=SDA;NOP;SCL=0;
return(bbyte);
}
//=======================================================
//FUNCTION:THE IIC DEVICE SHIFT IN A BYTE FROM THE MASTER
void outbyte(uchar outdata)
{ //将数据写放IIC器件
bbyte=outdata;
SDA=a7;SCL=1;NOP;SCL=0;
SDA=a6;SCL=1;NOP;SCL=0;
SDA=a5;SCL=1;NOP;SCL=0;
SDA=a4;SCL=1;NOP;SCL=0;
SDA=a3;SCL=1;NOP;SCL=0;
SDA=a2;SCL=1;NOP;SCL=0;
SDA=a1;SCL=1;NOP;SCL=0;
SDA=a0;SCL=1;NOP;SCL=0;
}

/**********************写函数****************************************
**   函数名称:  写数据
**   入口参数:add为读起始地址,ptr数据保存指针,writelen为写出数据长度
********************************************************************/
void writebyteseq(unsigned char page_addr, unsigned char byte_address,uchar *ptr,uchar writelen)
{
uchar temph;
uchar i;
unsigned char x;
  x = (page_addr<<1);                        
     temph = (x | IIC_WRITE);  
start();  
// outbyte(IIC_WRITE);  
// nack(1);  
outbyte(temph);
nack(1);
outbyte(byte_address);
nack(1);
for(i=0;i {
  outbyte(*(ptr+i));
  nack(1);
}
stop();
}
/**********************读函数***************************************
**   函数名称:  连续读数据
**   入口参数:add为读起始地址,ptr数据保存指针,readlen为读出数据长度
********************************************************************/
void readbyteseq(unsigned char page_addr, unsigned char byte_address,uchar *ptr,uchar readlen)
{
uchar temph;
uchar i;
unsigned char x;
  x = (page_addr<<1);                          // 2 address bytes.
     temph = (x | IIC_WRITE);  
start();
// outbyte(IIC_WRITE);
// nack(1);
outbyte(temph);
nack(1);
outbyte(byte_address);
nack(1);
start();
outbyte(IIC_READ);
nack(1);
for(i=0;i {
  *(ptr+i)=inbyte();
  ack();  
}
*(ptr+readlen-1)=inbyte();
nack(0);
stop();
}
/*版主注:因为你以前曾多次涉嫌以技术为名做广告,因此不得不采取一些措施.否则是对其他网友的不公平,也是对版内原则的践踏.希望您能理解并对单片机的技术发起和参与讨论.*/
全部回复(2)
正序查看
倒序查看
ahai0306
LV.4
2
2008-02-25 23:29
这么好的帖子,留个QQ都不行啊,斑竹有点过分
0
回复
hotpower
LV.5
3
2008-02-28 22:59
@ahai0306
这么好的帖子,留个QQ都不行啊,斑竹有点过分
不错~~~不过还是一般般~~~
0
回复