?? iic.c
字號:
//描述:微控設計網 www.microcontrol.cn MSP430單片機模擬IIC(Inter IC)總線程序.
//編寫:微控設計網 DC版主,如有問題,歡迎到微控技術論壇來討論.
//使用方式:以涵數方式調用,使用時程序關閉總中斷,使用完后打開總中斷.
//占用資源為:使用兩個IO口,本程序CPU主時鐘MCLK=800K.
//本程序已在微控MC430F14實驗板上驗證通過,也可以應到其它設計中.
//以下程序如有不明之處歡迎討論
#include<msp430x14x.h>
//--------------------------------------
//SDA 數據線定義
#define error 0x01 //錯誤
#define right 0x00 //正確
#define AT24_ADD 0xA0 //24c02芯片地址
/*第1區(qū)256b,ds=0xa0;第2區(qū)256b,ds=0xa2
第3區(qū)256b,ds=0xa4;第4區(qū)256b,ds=0xa6
第5區(qū)256b,ds=0xa8;第6區(qū)256b,ds=0xaa
第7區(qū)256b,ds=0xac;第8區(qū)256b,ds=0xae
24c16分區(qū)
*/
#define write 0x00 //寫
#define read 0x01 //讀
#define SDAOUT P3DIR |= BIT6
#define SDAIN P3DIR &= ~BIT6
#define SDA1 P3OUT |= BIT6
#define SDA0 P3OUT &= ~BIT6
//SCL 時鐘線定義
#define SCLOUT P3DIR |= BIT5
#define SCL1 P3OUT |= BIT5
#define SCL0 P3OUT &= ~BIT5
#define SDA_STATE P3IN & BIT6 //讀入SDA狀態(tài)
//--------------------------------------
#define SDA_MOV_BIT 6 //SDA 數據調整移位
//從器件接收方的應答返回標志
#define OK 0x01 //表示從器件有應答
#define NO 0x00 //表示從器件無應答
//IIC總線操作成失標志
#define error 0x01 //錯誤
#define right 0x00 //正確
unsigned char iic_check; //檢查標志,可選的.
nop_()
{_NOP();_NOP();}
SomeNOP()
{nop_();nop_();nop_();nop_();}
//**************************************
//起始信號
void I2CStart(void)
{
_DINT(); //關總中斷;
SCLOUT; //SCL口設為輸出-------后加
SDAOUT; //SDA口設為輸出
SDA1;
//SCLOUT; //SCL口設為輸出
SCL1;
SomeNOP(); SomeNOP(); //INI
SDA0;
SomeNOP(); SomeNOP(); //START
SCL0;
}
//**************************************
//結束信號
void I2CStop(void)
{
SCL0;
SDA0;
SomeNOP(); //INI
SCL1;
SomeNOP();
SDA1; //STOP
_EINT(); //EA=1;
}
//**************************************
//等待從器件接收方的應答
unsigned char WaitAck(void)
{
unsigned char errtime=255; //因故障接收方無ACK,超時值為255。
SDA1;
SomeNOP();
SCL1;
SomeNOP();
SDAIN; //SDA口設為輸入
while(SDA_STATE) //SDA出現(xiàn)為0時,則為有應答
{ errtime--;
if (!errtime) //errtime是否為0
{I2CStop();
return NO;} //返回為0(失敗)
}
SDAOUT; //SDA口設為輸出
SCL0;
return OK; //返回為1(成功)
}
//**************************************
//主器件為接收方,從器件為發(fā)送方時,單片機發(fā)出應答信號
//MCU Send to IC
void SendAck(void)
{
SDA0;
SomeNOP();
SCL1;
SomeNOP();
SCL0;
}
//**************************************
//主器件為接收方,從器件為發(fā)送方時,非應答信號
void SendNotAck(void)
{
SDA1;
SomeNOP();
SCL1;
SomeNOP();
SCL0;
}
//**************************************
//發(fā)送字節(jié)
void I2CSendByte(unsigned char ch)
{
unsigned char i=8;
while (i--)
{
SCL0; //SCL=0;
nop_();
if(ch&0x80)
SDA1; //使SDA為1位
else
SDA0; //使SDA為0位
//---------------
ch<<=1;
SomeNOP();
SCL1;
SomeNOP();
}
SCL0;
}
//**************************************
//接收字節(jié)
unsigned char I2CReceiveByte(void)
{
unsigned char i=8; //接收8位
unsigned char ddata,timp;
ddata=0;
SDA1;
SDAIN; //SDA口設為輸入
while (i--)
{
ddata<<=1; //將ddata位向高位移,于讓位0
SCL0;
SomeNOP();
SCL1;
SomeNOP();
timp = SDA_STATE; //讀入SDA,后加
timp>>=SDA_MOV_BIT; //將timp的SDA位數據移到位0
ddata|=timp; //將timp的SDA位數據移到ddata位0
}
SCL0; //SCL=0;
SDAOUT; //(附加)SDA口設回為輸出
return ddata;
}
//**********************************************************************
//描述:微控設計網 www.microcontrol.cn MSP430單片機模擬IIC(Inter IC)總線程序
//編寫:微控設計網 DC 版主,如有問題,歡迎到微控技術論壇來討論
//正常操作時返回位值為0,有故障時返回位值為1.
//unsigned char *DataBuff數據緩沖區(qū)指針,char ByteQuantity字節(jié)數量,
//unsigned int Address IC片內地址,
//unsigned char ControlByte芯片控制字節(jié)-IC地址/讀寫位,
unsigned char IIC(unsigned char *DataBuff,char ByteQuantity,unsigned int Address,
unsigned char ControlByte)
{
unsigned char errorflag=error; //錯誤標志位,1為錯誤,0為正確
unsigned char i; //i為允許本次操作的最大次數
i=1;
SCLOUT; //時鐘口長設為輸出
while(i--)
{
I2CStart();
I2CSendByte(ControlByte&0xfe);//指定芯片,此次必定為寫
if(!WaitAck()) //涵數返回一個1為成功
continue; //結束寫操作,并i-1后,再來一次
I2CSendByte((unsigned char)Address); //發(fā)送片內地址
if(!WaitAck()) //數返回一個1為成功
continue; //結束寫操作,并i-1后,再來一次
//------------------------------已經選定好IC
if(!(ControlByte&0x01)) //本次操作是讀還是寫
{ //寫操作
errorflag=right; //清錯誤標志位為0
while(ByteQuantity--) //操作j個數字節(jié)
{
I2CSendByte(*DataBuff++);//發(fā)送
if(WaitAck()) //涵數返回一個1為成功,涵數返回一個0為失敗
continue; //成功,下一個數據循環(huán)(跳while)
errorflag=error; //不應答,失敗了. errorflag=1
break; //退出寫操作
}
if(errorflag==error) //經過寫完后,如果最后errorflag標志為1,則表示有錯誤
continue; //結束寫操作,并i-1后,再來一次
break; //寫操作完成
}
else //則為讀操作
{ I2CStart(); //開始
I2CSendByte(ControlByte);
if(!WaitAck()) //涵數返回一個1為成功
{continue;} //結束此操作,并i-1后,再來一次
while(--ByteQuantity) //讀入ByteQuantity個數字節(jié)
{*DataBuff++=I2CReceiveByte();//連續(xù)讀入ByteQuantity個數據
SendAck();} //主機向從機發(fā)出應答,表示主機已接收
*DataBuff=I2CReceiveByte(); //讀入最后個數據
SendNotAck(); //最后發(fā)出不應答信號(位),表示主機不再讀了.
errorflag=right; //向錯誤標志位寫0(right),表示讀數據正確.
break;} //讀操作完成*/
}
I2CStop(); //停止,結束IIC總線
return(errorflag); //返回操作成敗標志
}
//***********************************************************************
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -