MSP430口線模擬I2C總線 /**********************************************************************************************功能: 實現MSP430口線模擬I2C總線協議與24C04通信. * * 描述: 主系統工作時鐘為12MHz,I2C工作時鐘頻率為1MHz.給某地址寫入一個數據 * * 再讀出來,如寫入前和讀出后的數據一致,則P1.0輸出高電平,否則輸出低電 * * 平. * * /|\ /|\ * * MSP430x22x4 10k 10k ATMEL 24c04 * * master | | slave * * --------------------------- | | ---------- * * -|XIN P3.1/UCB0SDA|<-|----+>|SDA | * * 32kHz | | | | | * * -|XOUT | | | | * * | P3.2/UCB0SCL|<-+-----> |SCL | * * | | | | * * -------------------------- ---------- * * * * 作者: Singel * * 時間: 2008年10月17日22時35分 * * 此例在 IAR Embedded Workbench IDE for MSP430 v3.42a 調試通過 . * ********************************************************************************************/ #include <MSP430x22x4.h> #define SlaveWriteAddress 0xa0 #define SlaveReadAddress 0xa1 #define OwnAddress 0xee #define I2CSDA BIT1 #define I2CSCL BIT2 #define I2CSDA_SET_1 P3OUT |= I2CSDA #define I2CSDA_SET_0 P3OUT &=~ I2CSDA #define I2CSCL_SET_1 P3OUT |= I2CSCL #define I2CSCL_SET_0 P3OUT &=~ I2CSCL #define I2CSDA_INPUT_IN P3IN&I2CSDA unsigned char READI2CBUF; void delay5us( void ) { unsigned char count=8; while(count--); } void Delay_MS( unsigned int m ) { unsigned int i,j; for(i=0;i<m;i++) for(j=0;j<125;j++); } void Setting_System_Clock_For_On_Chip_RC( char Frequency ) { switch (Frequency) { case 1 COCTL = BCSCTL1 = CALBC1_1MHZ;break; case 8 COCTL = BCSCTL1 = CALBC1_8MHZ;break; case 12COCTL = BCSCTL1 = CALBC1_12MHZ;break; case 16COCTL = BCSCTL1 = CALBC1_16MHZ;break; } } void I2C_Pins_DIR_Setting ( unsigned char SDADIR ) { P3DIR |= I2CSDA + I2CSCL; if(SDADIR==1) { P3DIR &=~ I2CSDA; P3OUT &=~ I2CSDA; } } void Engender_I2C_start_signal(void) { I2CSCL_SET_1; delay5us(); I2CSDA_SET_1; delay5us(); I2CSDA_SET_0; delay5us(); } void Engender_I2C_stop_signal(void) { I2CSDA_SET_0; delay5us(); I2CSCL_SET_1; delay5us(); I2CSDA_SET_1; delay5us(); } void Engender_I2C_ack_signal(void) { I2CSCL_SET_0; delay5us(); I2CSCL_SET_1; delay5us(); I2CSCL_SET_0; delay5us(); } void Engender_I2C_noack_signal(void) { I2CSDA_SET_1; delay5us(); I2CSCL_SET_0; delay5us(); I2CSCL_SET_1; delay5us(); I2CSCL_SET_0; delay5us(); } void WRITE_BYTE_TO_24C04( unsigned char BytEDAta ) { unsigned char count; for(count=0;count<8;count++) { I2CSCL_SET_0; delay5us(); if(BytEDAta&0x80)I2CSDA_SET_1; else I2CSDA_SET_0; delay5us(); I2CSCL_SET_1; delay5us(); BytEDAta<<=1; } } unsigned char READ_BYTE_TO_24C04( void ) { unsigned char count,readbyte=0; I2CSCL_SET_0; for(count=0;count<8;count++) { readbyte=readbyte<<1; I2CSCL_SET_1; delay5us(); if(I2CSDA_INPUT_IN)readbyte=readbyte|0x01; else readbyte=readbyte&0xfe; delay5us(); I2CSCL_SET_0; delay5us(); } I2CSCL_SET_0; return readbyte; } void WRITE_DATA_TO_24C04( unsigned char Address,unsigned char Date ) { Setting_System_Clock_For_On_Chip_RC(1); I2C_Pins_DIR_Setting(0); Engender_I2C_start_signal(); WRITE_BYTE_TO_24C04(SlaveWriteAddress); Engender_I2C_ack_signal(); WRITE_BYTE_TO_24C04(Address); Engender_I2C_ack_signal(); WRITE_BYTE_TO_24C04(Date); Engender_I2C_ack_signal(); Engender_I2C_stop_signal(); Delay_MS(15); I2CSCL_SET_0; I2CSDA_SET_0; Setting_System_Clock_For_On_Chip_RC(12); } unsigned char READ_DATA_FROM_24C04( unsigned char Address ) { unsigned char readdate; Setting_System_Clock_For_On_Chip_RC(1); I2C_Pins_DIR_Setting(0); Engender_I2C_start_signal(); WRITE_BYTE_TO_24C04(SlaveWriteAddress); Engender_I2C_ack_signal(); WRITE_BYTE_TO_24C04(Address); Engender_I2C_ack_signal(); Delay_MS(15); Engender_I2C_start_signal(); WRITE_BYTE_TO_24C04(SlaveReadAddress); I2C_Pins_DIR_Setting(1); Engender_I2C_ack_signal(); readdate=READ_BYTE_TO_24C04(); I2C_Pins_DIR_Setting(0); Engender_I2C_noack_signal(); Engender_I2C_stop_signal(); I2CSCL_SET_0; I2CSDA_SET_0; Setting_System_Clock_For_On_Chip_RC(12); return (readdate); } void main( void ) { unsigned char Data=0x59; WDTCTL = WDTPW+WDTHOLD; Setting_System_Clock_For_On_Chip_RC(12); P1DIR |= BIT0; while(1) { WRITE_DATA_TO_24C04(0X00,Data); READI2CBUF=READ_DATA_FROM_24C04(0x00); if(Data == READI2CBUF) { P1OUT |= BIT0; } else { P1OUT &=~ BIT0; } Delay_MS(15); } } |