#include <msp430x22x4.h>
#define SDA BIT1
#define SCL BIT2
#define SEG_A 0xA0 //0x0200---0x027F
#define SEG_B 0xB0 //0x0280---0x02FF
#define SEG_C 0xC0 //0x0300---0x037F
//0x0380---0x0400
__no_init char wokao@0x243;
//=============================
char *send_ptr;
char DEVICE_ADR=0;
char WORD_ADR=0;
char REC_DATA=0;
char START_flag = 0;
char STOP_flag = 0;
char PreState = 0;
char NowState = 0;
//*********************函數聲明*************************************
void ACK(void);
//****************************************************************
void main( void )
{
// Stop watchdog timer to prevent time out reset
WDTCTL = WDTPW + WDTHOLD;
//======================MCLK=16MHz=====================================
DCOCTL = CALDCO_16MHZ;
BCSCTL1 = CALBC1_16MHZ; //MCLK=DCO=16MHz
P3DIR &= ~(SDA+SCL);
while(1)
{
NN=10;
PreState = READ_SDA;
while(READ_SCL && NN--)
{
NowState = READ_SDA;
if(PreState && !NowState)
{
START_flag = 1;
_DINT();
}
if(!PreState && NowState)
{
STOP_flag = 1;
_EINT();
}
PreState = NowState;
if(START_flag)
{
START_flag=0;
while(READ_SCL); //START時的SCL高電平狀態(tài)就等待
for(gg=8;gg>0;gg--) //接收器件地址
{
while(!READ_SCL); //SCL低電平狀態(tài)就等待
DEVICE_ADR<<=1;
if(READ_SDA) //數據的第一個CLK高電平來臨
DEVICE_ADR |= 0x01;
while(READ_SCL); //SCL高電平狀態(tài)就等待
}
ACK(); //對設備地址ACK應答信
//-----------以上收到了設備地址,并知曉主機要對從機進行讀還是寫操作---
for(gg=8;gg>0;gg--) //接收內存單元地址
{
while(!READ_SCL);
WORD_ADR<<=1;
if(READ_SDA)
WORD_ADR |= 0x01;
while(READ_SCL);
}
//-----------以上就已經接收到內存單元地址------------
ACK(); //對內存單元ACK應答信號
if(DEVICE_ADR & 0x01) //從機發(fā)數據給主機 R/W=1
{
if(DEVICE_ADR==SEG_A+0x01)
{
send_ptr =(char*)(0x0200 + WORD_ADR);
}
else if(DEVICE_ADR==SEG_B+0x01)
{
send_ptr =(char*)(0x0280 + WORD_ADR);
}
else if(DEVICE_ADR==SEG_C+0x01)
{
send_ptr =(char*)(0x0300 + WORD_ADR);
}
//--------以上是判斷出為主機讀從機,要把要讀的地址單元賦給指針---
for(gg=8;gg>0;gg--)
{
while(!READ_SCL);
if( *send_ptr & 0x80)
_NOP();
else
{
P3DIR |= SDA; //輸出0
}
while(READ_SCL); //SCL為1,就保持SDA輸出不變
P3DIR &= ~SDA; //SCL為0,就把SDA從新切換到接收狀態(tài)
*send_ptr <<=1;
}
ACK(); //從機數據發(fā)送完畢,應答信號
_NOP();
//------------------以上是從機發(fā)數據給主機-----------------
}
else //主機寫從機 R/W=0
{
for(gg=8;gg>0;gg--) //接收主機要寫到該器件內存單元的數據
{
while(!READ_SCL);
REC_DATA <<=1;
if(READ_SDA)
REC_DATA |= 0x01;
while(READ_SCL);
}
if(DEVICE_ADR==SEG_A)
{
send_ptr =(char*)(0x0200 + WORD_ADR);
*send_ptr = REC_DATA;
}
else if(DEVICE_ADR==SEG_B)
{
send_ptr =(char*)(0x0280 + WORD_ADR);
*send_ptr = REC_DATA;
}
else if(DEVICE_ADR==SEG_C)
{
send_ptr =(char*)(0x0300 + WORD_ADR);
*send_ptr = REC_DATA;
}
ACK();
_NOP();
while(!READ_SCL);
}
}// if(START_flag)
}//while(NN--)
_EINT();
_NOP();
}//while(1)
}
//****************************************************
void ACK(void)
{
// while(READ_SCL);
while(!READ_SCL);
P3DIR |= SDA; //第9個CLK變高的情況下,SDA輸出0
while(READ_SCL);
P3DIR &= ~SDA; //第9個CLK變低的情況下,SDA輸出1
}