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