大家好:
我最近在做亮片MSP430之间的I2C通讯,一个做主机从从机读取数据,使用MSP430自带的P1.6,P1.7口分别做SCL和SDA,使用MSP430自带的I2C接口功能,能够完成通讯,但是如果主机使用IO口模拟I2C通讯,发现作为从机的MSP430对地址没有应答,奇怪的是竟然连主机产生的最后一个SCL脉冲也消失了;但是如果主机向从机写数据,从机对地址就有相应,求高手解答,谢谢!
灰小子:
既然是用io模拟的I2C通讯,要从代码上找原因。
对照波形,查代码
hong wu:
回复 灰小子:
代码之前在ADS1100上使用过,没问题,但是到了MSP430做从机上就少了一个SCL脉冲,
程序如下:#include <msp430.h> #define SCL_H SCL_IN#define SCL_L SCLPullDown()#define SDA_H SDA_IN#define SDA_L SDAPullDown()#define SCL_OUT P1DIR |= BIT6#define SDA_OUT P1DIR |= BIT7#define SDA_IN P1DIR &= ~BIT7#define SCL_IN P1DIR &= ~BIT6#define SDA_VAL P1IN & BIT7#define SCL_VAL P1IN & BIT6#define ACK 0X00#define NACK 0X01#define ADSADDRESS 0X01void InitializeClock();void Start();void Stop();unsigned char WriteByte(unsigned char command);unsigned char ReadByte();unsigned char CheckACK();void MACK();void NMACK();void Write1();void Write0();void SDAPullDown();void SCLPullDown();void UartRegCfg();void UartGpioCfg();void UartInit();void UARTPutChar(unsigned char cTX);void UARTPutstring( char *str);void main(void) { volatile float voltage = 0; volatile unsigned char MSB, LSB, parameters; volatile unsigned int msb, lsb; volatile char VOL[4]; volatile unsigned int vol; UartInit(); WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer InitializeClock(); while(1) { Start(); if(WriteByte(0X91) == ACK) { MSB =ReadByte(); MACK(); LSB = ReadByte(); NMACK(); Stop(); } _delay_cycles(800000); }}void InitializeClock(){ BCSCTL1 = CALBC1_8MHZ; DCOCTL = CALDCO_8MHZ;}void Start() { SDA_H; _delay_cycles(100); SCL_H; _delay_cycles(100); SDA_L; _delay_cycles(100); SCL_L; _delay_cycles(100);}void Stop() { SDA_L; _delay_cycles(100); SCL_H; _delay_cycles(100); SDA_H; _delay_cycles(100); SCL_L; _delay_cycles(100);}unsigned char WriteByte(unsigned char command) { unsigned char temp, count, ACKFlag; for (count = 8; count > 0; count–) { temp = command & 0x80; if (temp) Write1(); else Write0(); command <<= 1; } ACKFlag = CheckACK(); return ACKFlag;}unsigned char CheckACK() { unsigned char flag; SDA_IN; SCL_L; _delay_cycles(100); SCL_H; _delay_cycles(100); flag = SDA_VAL; SCL_L; _delay_cycles(100); if(flag != 0) return NACK; else return ACK;}unsigned char ReadByte() { unsigned char count, flag; unsigned char data = 0; SDA_IN; SCL_L; for(count = 8; count > 0; count–) { _delay_cycles(100); SCL_H; _delay_cycles(100); flag = SDA_VAL; SCL_L; if(flag) { data |= 1; } if(count == 1) { SDA_OUT; break; } data <<= 1; } return data;}/*****************************************************************【函数名称】Mack【功 能】完成IIC的主机应答操作【参 数】无【返回值 】无*****************************************************************/void MACK(void){ SDA_L; __delay_cycles(100);//_NOP(); _NOP(); SCL_L; _delay_cycles(100); SCL_H; __delay_cycles(100);//Delay(); SCL_L; __delay_cycles(100);//_NOP(); _NOP();}/*****************************************************************【函数名称】MNack【功 能】完成IIC的主机无应答操作【参 数】无【返回值 】无*****************************************************************/void NMACK(void){ SDA_H; __delay_cycles(100);//_NOP(); _NOP(); SCL_H; __delay_cycles(100);//Delay(); SCL_L; __delay_cycles(100);//_NOP(); _NOP();}void Write1(){ SDA_H; _delay_cycles(100); SCL_H; _delay_cycles(100); SCL_L;}void Write0(){ SDA_L; _delay_cycles(100); SCL_H; _delay_cycles(100); SCL_L;}void SDAPullDown() { SDA_OUT; P1OUT &= ~BIT6;}void SCLPullDown() { SCL_OUT; P1OUT &= ~BIT7;}
jing zhang6:
回复 hong wu:
我也遇到相同的问题,用MSP430F149控制AT24C02,读不出数据。