STM8 I/O口模拟I2C

来源:互联网 发布:熟丝桃子圈微博全数据 编辑:程序博客网 时间:2024/06/05 17:08
STM8I/O口模拟I2C所读数据不正确STM8 I/O口模拟I2C#define I2C_ERR   0#define I2C_CRR   1#define  I2CDataIn  1#define  I2CDataOut 0#define I2C_PORT  (GPIOC)#define I2CSCL   (GPIO_PIN_7)#define I2CSDA   (GPIO_PIN_6)//***************************************************************// I2C Data input/output// 0-Output, 1-Input//***************************************************************void I2CDataInOut(bool InOut){if(InOut)  {  GPIO_Init(I2C_PORT,I2CSDA,GPIO_MODE_IN_FL_NO_IT);  }else  {  GPIO_Init(I2C_PORT,I2CSDA,GPIO_MODE_OUT_OD_LOW_FAST);  }}//***************************************************************//  Send start condition//  ensure data is high then issue a start condition//  see also i2c_Start() macro//***************************************************************void I2C_Start (void){GPIO_WriteHigh(I2C_PORT, I2CSDA);_delay_5us(5);GPIO_WriteHigh(I2C_PORT, I2CSCL);_delay_5us(5);GPIO_WriteLow(I2C_PORT, I2CSDA);_delay_5us(5);}//***************************************************************//   Send stop condition//   data low-high while clock high//***************************************************************void I2C_Stop (void){GPIO_WriteLow(I2C_PORT, I2CSDA);_delay_5us(5);GPIO_WriteHigh(I2C_PORT, I2CSCL);_delay_5us(5);GPIO_WriteHigh(I2C_PORT, I2CSDA);}//***************************************************************//ROUTINE NAME : I2C_Ack//INPUT/OUTPUT : None.//DESCRIPTION  : Acknoledge generation from now.//COMMENTS     : Transfer sequence = DATA, ACK.//***************************************************************void I2C_Rack(void){GPIO_WriteLow(I2C_PORT, I2CSDA);_delay_5us(5);GPIO_WriteHigh(I2C_PORT, I2CSCL);_delay_5us(5);GPIO_WriteLow(I2C_PORT, I2CSCL);_delay_5us(5);}//***************************************************************//ROUTINE NAME : I2C_nAck//INPUT/OUTPUT : None.//DESCRIPTION  : Non acknoledge generation from now.//COMMENTS     : Transfer sequence = DATA, NACK.//***************************************************************void I2C_nAck (void){GPIO_WriteHigh(I2C_PORT, I2CSDA);_delay_5us(5);GPIO_WriteHigh(I2C_PORT, I2CSCL);_delay_5us(5);GPIO_WriteLow(I2C_PORT, I2CSCL);_delay_5us(5);}//***************************************************************//  Send a byte to the slave 写一个数据没有应答//  return I2C_ERR OR I2C_CRR//***************************************************************bool SendByte(UCHAR I2cData){UCHAR i;bool I2CStatus;for(i=0; i<8; i++)  {  GPIO_WriteLow(I2C_PORT, I2CSCL);  _delay_5us(5);  if(I2cData & 0x80)   {GPIO_WriteHigh(I2C_PORT, I2CSDA);}  else   {GPIO_WriteLow(I2C_PORT, I2CSDA);}  GPIO_WriteHigh(I2C_PORT, I2CSCL);  _delay_5us(5);  I2cData <<= 1;  }  GPIO_WriteLow(I2C_PORT, I2CSCL);  GPIO_WriteHigh(I2C_PORT, I2CSDA);//发送完一字节,接收应答    I2CDataInOut(I2CDataIn);  GPIO_WriteHigh(I2C_PORT, I2CSCL);  _delay_5us(5);  if(GPIO_ReadInputPin(I2C_PORT,I2CSDA) == 0)   {   I2CStatus = I2C_CRR;   }  else   {   I2CStatus = I2C_ERR;   }  I2CDataInOut(I2CDataOut);  return I2CStatus;}//***************************************************************//ROUTINE NAME : I2Cm_RxData//INPUT/OUTPUT : Last byte to receive flag (active high)/Received data byte.//DESCRIPTION  : Receive a data byte.//COMMENTS     : Transfer sequence = DATA, ACK, EV7...//***************************************************************UCHAR RcvByte(void){       UCHAR i;    UCHAR ReadByte=0;   GPIO_WriteHigh(I2C_PORT, I2CSDA);I2CDataInOut(I2CDataIn);_delay_5us(10);for(i=0; i<8; i++)  {   ReadByte <<= 1;   GPIO_WriteLow(I2C_PORT, I2CSCL);   _delay_5us(5);   GPIO_WriteHigh(I2C_PORT, I2CSCL);   _delay_5us(5);   if(GPIO_ReadInputPin(I2C_PORT,I2CSDA) == 1)    {ReadByte |= 0x01;}   _delay_5us(5);  }  GPIO_WriteLow(I2C_PORT, I2CSCL);I2CDataInOut(I2CDataOut);_delay_5us(10);   return ReadByte;}/*******************************************************  读N个数据,参数:?   wrDAdr: write device-address 写器件地址??   wordAdr: word address 读数据的寄存器地址??   rdDAdr: read device-address 读器件地址   *pRdDat: p->read data 读数据指针   num: number 需要读数据的个数*******************************************************/bool I2C_Read(UCHAR wrDAdr,UCHAR wordAdr,UCHAR *pRdDat,UCHAR num){bool I2CAck;UCHAR i=0;UCHAR rdDAdr;rdDAdr = wrDAdr+1; //读器件地址为写地址加1I2C_Start();  /*启动I2C*/_delay_5us(5);I2CAck = SendByte(wrDAdr); /*发写器件地址*/if(!I2CAck)  {   return I2C_ERR;  }I2CAck = SendByte(wordAdr); /*发寄存器地址*/if(!I2CAck)  {   return I2C_ERR;  }I2C_Start();   /*重启I2C*/  I2CAck = SendByte(rdDAdr); /*发读器件地址*/if(!I2CAck)  {   return I2C_ERR;  }_delay_5us(5);for(i=0;i<num-1;i++)  {  *(pRdDat+i) = RcvByte();  I2C_Rack();   }if(i==num-1)  {  *(pRdDat+i) = RcvByte();  I2C_nAck();  }I2C_Stop();return I2C_CRR;}/*******************************************************写N个数据,前N-1个要应答,最后一个不要应答wrDAdr: write device-address 写器件地址??  wordAdr: word address 写数据的寄存器地址?  *pWrDat: p->write data 写数据指针  num: number  需要写入的数据个数*******************************************************/bool I2C_Write(UCHAR wrDAdr,UCHAR wordAdr,UCHAR *pWrDat,UCHAR num){bool I2CAck;unsigned char i;I2C_Start();      /*启动I2C*/_delay_5us(5);I2CAck = SendByte(wrDAdr); /*发写器件地址*/if(!I2CAck)  {   return I2C_ERR;  }I2CAck = SendByte(wordAdr);  /*发要写的寄存器地址*/if(!I2CAck)  {   return I2C_ERR;  }for(i=0;i<num-1;i++)  {  I2CAck = SendByte(*(pWrDat+i));  if(!I2CAck)   {return I2C_ERR;}  }if(i==num-1)  {  I2CAck = SendByte(*(pWrDat+num-1));  if(!I2CAck)   {return I2C_ERR;}  }I2C_Stop();return I2CAck;} 

以上代码不知为何读出数据不正确,用示波器看我发送的器件地址,寄存器地址这些都对,器件输出的数据是0xFF,程序中读出返回的数据是0x00,弄了一天没对相当郁闷,同志们指点下



终于搞定了, 应该跟我的器件有关,另外if(GPIO_ReadInputPin(I2C_PORT,I2CSDA) == 1)这种不能写成==1,要直接写成if(GPIO_ReadInputPin(I2C_PORT,I2CSDA)),太郁闷了


原创粉丝点击