[STM8] STM8S的I2C读写不了EEPROM

[复制链接]
 楼主| owenli520 发表于 2015-1-22 10:00 | 显示全部楼层 |阅读模式
本帖最后由 owenli520 于 2015-1-25 14:19 编辑

STM8S的I2C读写不了EEPROM,使用I2C功能一直处理忙状态,使用模拟方式也读写不了数据,模拟方式验证了可以读写时钟芯片,就是读写不了24C32,模拟方式的程序在其它单片机上一点问题都有,到STM8上就不行了,要崩溃了,求高人指点


实在是不想折腾了,结帖!有需要的请看我的另一帖子
http://bbs.21ic.com/icview-873551-1-1.html
 楼主| owenli520 发表于 2015-1-22 10:04 | 显示全部楼层
  1. //STM8 I/O口模拟I2C

  2. #define I2C_ERR   0
  3. #define I2C_CRR   1
  4. #define  I2CDataIn  1
  5. #define  I2CDataOut 0
  6. #define I2C_PORT  (GPIOB)
  7. #define I2CSCL   (GPIO_PIN_4)
  8. #define I2CSDA   (GPIO_PIN_5)

  9. //***************************************************************
  10. // I2C Data input/output
  11. // 0-Output, 1-Input
  12. //***************************************************************
  13. void I2CDataInOut(bool InOut)
  14. {
  15. if(InOut)
  16.   {
  17.   GPIO_Init(I2C_PORT,I2CSDA,GPIO_MODE_IN_FL_NO_IT);
  18.   }
  19. else
  20.   {
  21.   GPIO_Init(I2C_PORT,I2CSDA,GPIO_MODE_OUT_OD_LOW_FAST);
  22.   }
  23. }
  24. //***************************************************************
  25. //  Send start condition
  26. //  ensure data is high then issue a start condition
  27. //  see also i2c_Start() macro
  28. //***************************************************************
  29. void I2C_Start (void)
  30. {
  31. GPIO_WriteHigh(I2C_PORT, I2CSDA);
  32. _delay_5us(5);
  33. GPIO_WriteHigh(I2C_PORT, I2CSCL);
  34. _delay_5us(5);
  35. GPIO_WriteLow(I2C_PORT, I2CSDA);
  36. _delay_5us(5);
  37. }
  38. //***************************************************************
  39. //   Send stop condition
  40. //   data low-high while clock high
  41. //***************************************************************
  42. void I2C_Stop (void)
  43. {
  44. GPIO_WriteLow(I2C_PORT, I2CSDA);
  45. _delay_5us(5);
  46. GPIO_WriteHigh(I2C_PORT, I2CSCL);
  47. _delay_5us(5);
  48. GPIO_WriteHigh(I2C_PORT, I2CSDA);
  49. }
  50. //***************************************************************
  51. //ROUTINE NAME : I2C_Ack
  52. //INPUT/OUTPUT : None.
  53. //DESCRIPTION  : Acknoledge generation from now.
  54. //COMMENTS     : Transfer sequence = DATA, ACK.
  55. //***************************************************************
  56. void I2C_Rack(void)
  57. {
  58. GPIO_WriteLow(I2C_PORT, I2CSDA);
  59. _delay_5us(5);
  60. GPIO_WriteHigh(I2C_PORT, I2CSCL);
  61. _delay_5us(5);
  62. GPIO_WriteLow(I2C_PORT, I2CSCL);
  63. _delay_5us(5);
  64. }

  65. //***************************************************************
  66. //ROUTINE NAME : I2C_nAck
  67. //INPUT/OUTPUT : None.
  68. //DESCRIPTION  : Non acknoledge generation from now.
  69. //COMMENTS     : Transfer sequence = DATA, NACK.
  70. //***************************************************************
  71. void I2C_nAck (void)
  72. {
  73. GPIO_WriteHigh(I2C_PORT, I2CSDA);
  74. _delay_5us(5);
  75. GPIO_WriteHigh(I2C_PORT, I2CSCL);
  76. _delay_5us(5);
  77. GPIO_WriteLow(I2C_PORT, I2CSCL);
  78. _delay_5us(5);
  79. }
  80. //***************************************************************
  81. //  Send a byte to the slave 写一个数据没有应答
  82. //  return I2C_ERR OR I2C_CRR
  83. //***************************************************************
  84. bool SendByte(UCHAR I2cData)
  85. {
  86. UCHAR i;
  87. bool I2CStatus;

  88. for(i=0; i<8; i++)
  89.   {
  90.   GPIO_WriteLow(I2C_PORT, I2CSCL);
  91.   _delay_5us(5);
  92.   if(I2cData & 0x80)
  93.    {GPIO_WriteHigh(I2C_PORT, I2CSDA);}
  94.   else
  95.    {GPIO_WriteLow(I2C_PORT, I2CSDA);}
  96.   GPIO_WriteHigh(I2C_PORT, I2CSCL);
  97.   _delay_5us(5);
  98.   I2cData <<= 1;
  99.   }
  100.   GPIO_WriteLow(I2C_PORT, I2CSCL);
  101.   GPIO_WriteHigh(I2C_PORT, I2CSDA);//发送完一字节,接收应答
  102.   
  103.   I2CDataInOut(I2CDataIn);

  104.   GPIO_WriteHigh(I2C_PORT, I2CSCL);
  105.   _delay_5us(5);
  106.   if(GPIO_ReadInputPin(I2C_PORT,I2CSDA) == 0)
  107.    {
  108.    I2CStatus = I2C_CRR;
  109.    }
  110.   else
  111.    {
  112.    I2CStatus = I2C_ERR;
  113.    }
  114.   I2CDataInOut(I2CDataOut);
  115.   return I2CStatus;
  116. }

  117. //***************************************************************
  118. //ROUTINE NAME : I2Cm_RxData
  119. //INPUT/OUTPUT : Last byte to receive flag (active high)/Received data byte.
  120. //DESCRIPTION  : Receive a data byte.
  121. //COMMENTS     : Transfer sequence = DATA, ACK, EV7...
  122. //***************************************************************
  123. UCHAR RcvByte(void)
  124. {   
  125.     UCHAR i;
  126.     UCHAR ReadByte=0;
  127.    GPIO_WriteHigh(I2C_PORT, I2CSDA);

  128. I2CDataInOut(I2CDataIn);
  129. _delay_5us(10);
  130. for(i=0; i<8; i++)
  131.   {
  132.    ReadByte <<= 1;
  133.    GPIO_WriteLow(I2C_PORT, I2CSCL);
  134.    _delay_5us(5);
  135.    GPIO_WriteHigh(I2C_PORT, I2CSCL);
  136.    _delay_5us(5);

  137.    if(GPIO_ReadInputPin(I2C_PORT,I2CSDA) == 1)
  138.     {ReadByte |= 0x01;}
  139.    _delay_5us(5);
  140.   }  
  141. GPIO_WriteLow(I2C_PORT, I2CSCL);
  142. I2CDataInOut(I2CDataOut);
  143. _delay_5us(10);
  144.    return ReadByte;
  145. }

  146. /*******************************************************
  147.   读N个数据,参数:
  148.    wrDAdr: write device-address 写器件地址
  149.    wordAdr: word address 读数据的寄存器地址
  150.    rdDAdr: read device-address 读器件地址
  151.    *pRdDat: p->read data 读数据指针
  152.    num: number 需要读数据的个数
  153. *******************************************************/
  154. bool I2C_Read(UCHAR wrDAdr,UCHAR wordAdr,UCHAR *pRdDat,UCHAR num)
  155. {
  156. bool I2CAck;
  157. UCHAR i=0;
  158. UCHAR rdDAdr;
  159. rdDAdr = wrDAdr+1; //读器件地址为写地址加1
  160. I2C_Start();  /*启动I2C*/
  161. _delay_5us(5);
  162. I2CAck = SendByte(wrDAdr); /*发写器件地址*/
  163. if(!I2CAck)
  164.   {
  165.    return I2C_ERR;
  166.   }
  167. I2CAck = SendByte(wordAdr); /*发寄存器地址*/
  168. if(!I2CAck)
  169.   {
  170.    return I2C_ERR;
  171.   }

  172. I2C_Start();   /*重启I2C*/
  173.   I2CAck = SendByte(rdDAdr); /*发读器件地址*/
  174. if(!I2CAck)
  175.   {
  176.    return I2C_ERR;
  177.   }
  178. _delay_5us(5);
  179. for(i=0;i<num-1;i++)
  180.   {
  181.   *(pRdDat+i) = RcvByte();
  182.   I2C_Rack();
  183.    }
  184. if(i==num-1)
  185.   {
  186.   *(pRdDat+i) = RcvByte();
  187.   I2C_nAck();
  188.   }
  189. I2C_Stop();
  190. return I2C_CRR;
  191. }

  192. /*******************************************************
  193. 写N个数据,前N-1个要应答,最后一个不要应答
  194. wrDAdr: write device-address 写器件地址
  195.   wordAdr: word address 写数据的寄存器地址
  196.   *pWrDat: p->write data 写数据指针
  197.   num: number  需要写入的数据个数
  198. *******************************************************/
  199. bool I2C_Write(UCHAR wrDAdr,UCHAR wordAdr,UCHAR *pWrDat,UCHAR num)
  200. {
  201. bool I2CAck;
  202. unsigned char i;

  203. I2C_Start();      /*启动I2C*/
  204. _delay_5us(5);
  205. I2CAck = SendByte(wrDAdr); /*发写器件地址*/
  206. if(!I2CAck)
  207.   {
  208.    return I2C_ERR;
  209.   }
  210. I2CAck = SendByte(wordAdr);  /*发要写的寄存器地址*/
  211. if(!I2CAck)
  212.   {
  213.    return I2C_ERR;
  214.   }
  215. for(i=0;i<num-1;i++)
  216.   {
  217.   I2CAck = SendByte(*(pWrDat+i));
  218.   if(!I2CAck)
  219.    {return I2C_ERR;}
  220.   }
  221. if(i==num-1)
  222.   {
  223.   I2CAck = SendByte(*(pWrDat+num-1));
  224.   if(!I2CAck)
  225.    {return I2C_ERR;}
  226.   }
  227. I2C_Stop();
  228. return I2CAck;
  229. }

 楼主| owenli520 发表于 2015-1-22 11:15 | 显示全部楼层
有没有人知道啊?急啊
HorribleA 发表于 2015-1-22 12:55 | 显示全部楼层
系统时钟不一样 导致的软件延时问题?
 楼主| owenli520 发表于 2015-1-22 14:43 | 显示全部楼层
软件延时也调过了,不管用啊,不知道_delay_5us()是不是延时5秒,这段代码也是网上找的
 楼主| owenli520 发表于 2015-1-22 14:45 | 显示全部楼层
那位高手能帮忙解决一下啊?怎么没人呢?太安静了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

57

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部

7

主题

57

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部