5531|6

76

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

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; //读器件地址为写地址加1
I2C_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,弄了一天没对相当郁闷,同志们指点下
此帖出自stm32/stm8论坛

最新回复

                                 你去看看GPIO_ReadInputPin这个程序你就知道为什么不能这样写了,想当然的想法 是的,不看、不调试,而想当然,这种做法不太好  详情 回复 发表于 2010-5-12 09:05
点赞 关注
 

回复
举报

76

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
                                 终于搞定了, 应该跟我的器件有关,另外if(GPIO_ReadInputPin(I2C_PORT,I2CSDA) == 1)这种不能写成==1,要直接写成if(GPIO_ReadInputPin(I2C_PORT,I2CSDA)),太郁闷了
此帖出自stm32/stm8论坛
 
 

回复

60

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
                                 呵呵
此帖出自stm32/stm8论坛
 
 

回复

76

帖子

0

TA的资源

一粒金砂(初级)

4
 
                                 还会有2楼所说的问题。两种写法应该是一样的呀
此帖出自stm32/stm8论坛
 
 
 

回复

67

帖子

0

TA的资源

一粒金砂(中级)

5
 
                                 有些编译器是这样的,奇怪的问题
此帖出自stm32/stm8论坛
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

6
 
终于搞定了, 应该跟我的器件有关,另外if(GPIO_ReadInputPin(I2C_PORT,I2CSDA) == 1)这种不能写成==1,要直接写成if(GPIO_ReadInputPin(I2C_PORT,I2CSDA)),太郁闷了
你去看看GPIO_ReadInputPin这个程序你就知道为什么不能这样写了,想当然的想法
此帖出自stm32/stm8论坛
 
 
 

回复

75

帖子

0

TA的资源

一粒金砂(初级)

7
 
你去看看GPIO_ReadInputPin这个程序你就知道为什么不能这样写了,想当然的想法
是的,不看、不调试,而想当然,这种做法不太好
此帖出自stm32/stm8论坛
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/7 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表