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();
}
/*版主注:因為你以前曾多次涉嫌以技術為名做廣告,因此不得不采取一些措施.否則是對其他網友的不公平,也是對版內原則的踐踏.希望您能理解并對單片機的技術發起和參與討論.*/