STM8 I/O口模拟I2C

来源:互联网 发布:怎样金融网络投资 编辑:程序博客网 时间:2024/06/05 02:13
[cpp] view plain copy
 print?
  1. STM8I/O口模拟I2C所读数据不正确  
  2. STM8 I/O口模拟I2C  
  3.   
  4.   
  5. #define I2C_ERR   0  
  6.   
  7. #define I2C_CRR   1  
  8.   
  9. #define  I2CDataIn  1  
  10.   
  11. #define  I2CDataOut 0  
  12.   
  13. #define I2C_PORT  (GPIOC)  
  14.   
  15. #define I2CSCL   (GPIO_PIN_7)  
  16.   
  17. #define I2CSDA   (GPIO_PIN_6)  
  18.   
  19.   
  20. //***************************************************************  
  21.   
  22. // I2C Data input/output  
  23.   
  24. // 0-Output, 1-Input  
  25.   
  26. //***************************************************************  
  27.   
  28. void I2CDataInOut(bool InOut)  
  29.   
  30. {  
  31.   
  32. if(InOut)  
  33.   
  34.   {  
  35.   
  36.   GPIO_Init(I2C_PORT,I2CSDA,GPIO_MODE_IN_FL_NO_IT);  
  37.   
  38.   }  
  39.   
  40. else  
  41.   
  42.   {  
  43.   
  44.   GPIO_Init(I2C_PORT,I2CSDA,GPIO_MODE_OUT_OD_LOW_FAST);  
  45.   
  46.   }  
  47.   
  48. }  
  49.   
  50. //***************************************************************  
  51.   
  52. //  Send start condition  
  53.   
  54. //  ensure data is high then issue a start condition  
  55.   
  56. //  see also i2c_Start() macro  
  57.   
  58. //***************************************************************  
  59.   
  60. void I2C_Start (void)  
  61.   
  62. {  
  63.   
  64. GPIO_WriteHigh(I2C_PORT, I2CSDA);  
  65.   
  66. _delay_5us(5);  
  67.   
  68. GPIO_WriteHigh(I2C_PORT, I2CSCL);  
  69.   
  70. _delay_5us(5);  
  71.   
  72. GPIO_WriteLow(I2C_PORT, I2CSDA);  
  73.   
  74. _delay_5us(5);  
  75.   
  76. }  
  77.   
  78. //***************************************************************  
  79.   
  80. //   Send stop condition  
  81.   
  82. //   data low-high while clock high  
  83.   
  84. //***************************************************************  
  85.   
  86. void I2C_Stop (void)  
  87.   
  88. {  
  89.   
  90. GPIO_WriteLow(I2C_PORT, I2CSDA);  
  91.   
  92. _delay_5us(5);  
  93.   
  94. GPIO_WriteHigh(I2C_PORT, I2CSCL);  
  95.   
  96. _delay_5us(5);  
  97.   
  98. GPIO_WriteHigh(I2C_PORT, I2CSDA);  
  99.   
  100. }  
  101.   
  102. //***************************************************************  
  103.   
  104. //ROUTINE NAME : I2C_Ack  
  105.   
  106. //INPUT/OUTPUT : None.  
  107.   
  108. //DESCRIPTION  : Acknoledge generation from now.  
  109.   
  110. //COMMENTS     : Transfer sequence = DATA, ACK.  
  111.   
  112. //***************************************************************  
  113.   
  114. void I2C_Rack(void)  
  115.   
  116. {  
  117.   
  118. GPIO_WriteLow(I2C_PORT, I2CSDA);  
  119.   
  120. _delay_5us(5);  
  121.   
  122. GPIO_WriteHigh(I2C_PORT, I2CSCL);  
  123.   
  124. _delay_5us(5);  
  125.   
  126. GPIO_WriteLow(I2C_PORT, I2CSCL);  
  127.   
  128. _delay_5us(5);  
  129.   
  130. }  
  131.   
  132.   
  133. //***************************************************************  
  134.   
  135. //ROUTINE NAME : I2C_nAck  
  136.   
  137. //INPUT/OUTPUT : None.  
  138.   
  139. //DESCRIPTION  : Non acknoledge generation from now.  
  140.   
  141. //COMMENTS     : Transfer sequence = DATA, NACK.  
  142.   
  143. //***************************************************************  
  144.   
  145. void I2C_nAck (void)  
  146.   
  147. {  
  148.   
  149. GPIO_WriteHigh(I2C_PORT, I2CSDA);  
  150.   
  151. _delay_5us(5);  
  152.   
  153. GPIO_WriteHigh(I2C_PORT, I2CSCL);  
  154.   
  155. _delay_5us(5);  
  156.   
  157. GPIO_WriteLow(I2C_PORT, I2CSCL);  
  158.   
  159. _delay_5us(5);  
  160.   
  161. }  
  162.   
  163. //***************************************************************  
  164.   
  165. //  Send a byte to the slave 写一个数据没有应答  
  166.   
  167. //  return I2C_ERR OR I2C_CRR  
  168.   
  169. //***************************************************************  
  170.   
  171. bool SendByte(UCHAR I2cData)  
  172.   
  173. {  
  174.   
  175. UCHAR i;  
  176.   
  177. bool I2CStatus;  
  178.   
  179.   
  180. for(i=0; i<8; i++)  
  181.   
  182.   {  
  183.   
  184.   GPIO_WriteLow(I2C_PORT, I2CSCL);  
  185.   
  186.   _delay_5us(5);  
  187.   
  188.   if(I2cData & 0x80)  
  189.   
  190.    {GPIO_WriteHigh(I2C_PORT, I2CSDA);}  
  191.   
  192.   else  
  193.   
  194.    {GPIO_WriteLow(I2C_PORT, I2CSDA);}  
  195.   
  196.   GPIO_WriteHigh(I2C_PORT, I2CSCL);  
  197.   
  198.   _delay_5us(5);  
  199.   
  200.   I2cData <<= 1;  
  201.   
  202.   }  
  203.   
  204.   GPIO_WriteLow(I2C_PORT, I2CSCL);  
  205.   
  206.   GPIO_WriteHigh(I2C_PORT, I2CSDA);//发送完一字节,接收应答  
  207.   
  208.     
  209.   
  210.   I2CDataInOut(I2CDataIn);  
  211.   
  212.   
  213.   GPIO_WriteHigh(I2C_PORT, I2CSCL);  
  214.   
  215.   _delay_5us(5);  
  216.   
  217.   if(GPIO_ReadInputPin(I2C_PORT,I2CSDA) == 0)  
  218.   
  219.    {  
  220.   
  221.    I2CStatus = I2C_CRR;  
  222.   
  223.    }  
  224.   
  225.   else  
  226.   
  227.    {  
  228.   
  229.    I2CStatus = I2C_ERR;  
  230.   
  231.    }  
  232.   
  233.   I2CDataInOut(I2CDataOut);  
  234.   
  235.   return I2CStatus;  
  236.   
  237. }  
  238.   
  239.   
  240. //***************************************************************  
  241.   
  242. //ROUTINE NAME : I2Cm_RxData  
  243.   
  244. //INPUT/OUTPUT : Last byte to receive flag (active high)/Received data byte.  
  245.   
  246. //DESCRIPTION  : Receive a data byte.  
  247.   
  248. //COMMENTS     : Transfer sequence = DATA, ACK, EV7...  
  249.   
  250. //***************************************************************  
  251.   
  252. UCHAR RcvByte(void)  
  253.   
  254. {     
  255.   
  256.     UCHAR i;  
  257.   
  258.     UCHAR ReadByte=0;  
  259.   
  260.    GPIO_WriteHigh(I2C_PORT, I2CSDA);  
  261.   
  262.   
  263. I2CDataInOut(I2CDataIn);  
  264.   
  265. _delay_5us(10);  
  266.   
  267. for(i=0; i<8; i++)  
  268.   
  269.   {  
  270.   
  271.    ReadByte <<= 1;  
  272.   
  273.    GPIO_WriteLow(I2C_PORT, I2CSCL);  
  274.   
  275.    _delay_5us(5);  
  276.   
  277.    GPIO_WriteHigh(I2C_PORT, I2CSCL);  
  278.   
  279.    _delay_5us(5);  
  280.   
  281.   
  282.    if(GPIO_ReadInputPin(I2C_PORT,I2CSDA) == 1)  
  283.   
  284.     {ReadByte |= 0x01;}  
  285.   
  286.    _delay_5us(5);  
  287.   
  288.   }    
  289.   
  290. GPIO_WriteLow(I2C_PORT, I2CSCL);  
  291.   
  292. I2CDataInOut(I2CDataOut);  
  293.   
  294. _delay_5us(10);  
  295.   
  296.    return ReadByte;  
  297.   
  298. }  
  299.   
  300.   
  301. /*******************************************************  
  302.   
  303.   读N个数据,参数:?  
  304.   
  305.    wrDAdr: write device-address 写器件地址??  
  306.   
  307.    wordAdr: word address 读数据的寄存器地址??  
  308.   
  309.    rdDAdr: read device-address 读器件地址  
  310.   
  311.    *pRdDat: p->read data 读数据指针  
  312.   
  313.    num: number 需要读数据的个数  
  314.   
  315. *******************************************************/  
  316.   
  317. bool I2C_Read(UCHAR wrDAdr,UCHAR wordAdr,UCHAR *pRdDat,UCHAR num)  
  318.   
  319. {  
  320.   
  321. bool I2CAck;  
  322.   
  323. UCHAR i=0;  
  324.   
  325. UCHAR rdDAdr;  
  326.   
  327. rdDAdr = wrDAdr+1; //读器件地址为写地址加1  
  328.   
  329. I2C_Start();  /*启动I2C*/  
  330.   
  331. _delay_5us(5);  
  332.   
  333. I2CAck = SendByte(wrDAdr); /*发写器件地址*/  
  334.   
  335. if(!I2CAck)  
  336.   
  337.   {  
  338.   
  339.    return I2C_ERR;  
  340.   
  341.   }  
  342.   
  343. I2CAck = SendByte(wordAdr); /*发寄存器地址*/  
  344.   
  345. if(!I2CAck)  
  346.   
  347.   {  
  348.   
  349.    return I2C_ERR;  
  350.   
  351.   }  
  352.   
  353.   
  354. I2C_Start();   /*重启I2C*/  
  355.   
  356.   I2CAck = SendByte(rdDAdr); /*发读器件地址*/  
  357.   
  358. if(!I2CAck)  
  359.   
  360.   {  
  361.   
  362.    return I2C_ERR;  
  363.   
  364.   }  
  365.   
  366. _delay_5us(5);  
  367.   
  368. for(i=0;i<num-1;i++)  
  369.   
  370.   {  
  371.   
  372.   *(pRdDat+i) = RcvByte();  
  373.   
  374.   I2C_Rack();  
  375.   
  376.    }  
  377.   
  378. if(i==num-1)  
  379.   
  380.   {  
  381.   
  382.   *(pRdDat+i) = RcvByte();  
  383.   
  384.   I2C_nAck();  
  385.   
  386.   }  
  387.   
  388. I2C_Stop();  
  389.   
  390. return I2C_CRR;  
  391.   
  392. }  
  393.   
  394.   
  395. /******************************************************* 
  396.  
  397. 写N个数据,前N-1个要应答,最后一个不要应答 
  398.  
  399. wrDAdr: write device-address 写器件地址?? 
  400.  
  401.   wordAdr: word address 写数据的寄存器地址? 
  402.  
  403.   *pWrDat: p->write data 写数据指针 
  404.  
  405.   num: number  需要写入的数据个数 
  406.  
  407. *******************************************************/  
  408.   
  409. bool I2C_Write(UCHAR wrDAdr,UCHAR wordAdr,UCHAR *pWrDat,UCHAR num)  
  410.   
  411. {  
  412.   
  413. bool I2CAck;  
  414.   
  415. unsigned char i;  
  416.   
  417.   
  418. I2C_Start();      /*启动I2C*/  
  419.   
  420. _delay_5us(5);  
  421.   
  422. I2CAck = SendByte(wrDAdr); /*发写器件地址*/  
  423.   
  424. if(!I2CAck)  
  425.   
  426.   {  
  427.   
  428.    return I2C_ERR;  
  429.   
  430.   }  
  431.   
  432. I2CAck = SendByte(wordAdr);  /*发要写的寄存器地址*/  
  433.   
  434. if(!I2CAck)  
  435.   
  436.   {  
  437.   
  438.    return I2C_ERR;  
  439.   
  440.   }  
  441.   
  442. for(i=0;i<num-1;i++)  
  443.   
  444.   {  
  445.   
  446.   I2CAck = SendByte(*(pWrDat+i));  
  447.   
  448.   if(!I2CAck)  
  449.   
  450.    {return I2C_ERR;}  
  451.   
  452.   }  
  453.   
  454. if(i==num-1)  
  455.   
  456.   {  
  457.   
  458.   I2CAck = SendByte(*(pWrDat+num-1));  
  459.   
  460.   if(!I2CAck)  
  461.   
  462.    {return I2C_ERR;}  
  463.   
  464.   }  
  465.   
  466. I2C_Stop();  
  467.   
  468. return I2CAck;  
  469.   
  470. }   

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



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

原创粉丝点击