標(biāo)題: stm32 iic,硬件iic主模式使用查詢模式,從模式使用中斷模式,已驗(yàn)證能正常收發(fā)數(shù)據(jù) [打印本頁]

作者: zxp123456    時(shí)間: 2019-7-26 10:27
標(biāo)題: stm32 iic,硬件iic主模式使用查詢模式,從模式使用中斷模式,已驗(yàn)證能正常收發(fā)數(shù)據(jù)
  1. int main(void)
  2. {
  3.         u8 i = 0;
  4.         u16 temp = 0;
  5.   RCC_Configuration();         //時(shí)鐘配置
  6.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);        //設(shè)置NVIC中斷分組2:2位搶占優(yōu)先級(jí),2位響應(yīng)優(yōu)先級(jí)
  7.         
  8.   IIC_Configuration1();
  9.         I2C_Configuration2();
  10.         
  11.         gpio_init();

  12. //        TIM2_Int_Init(719,999);  // 配置定時(shí)器TIM1每10ms產(chǎn)生中斷,定時(shí)器計(jì)數(shù)頻率為1kHz=72M/72000。
  13.         
  14.         //GPIO_SetBits(GPIOB,GPIO_Pin_0);
  15.          while(1)
  16.         {
  17.                 temp++;
  18.                 I2C_Master_BufferWrite(I2C1, I2C1_Buffer_Tx, 8, 0x20);
  19.    __nop();
  20.                 for(i=0;i<8;i++)
  21.                 {
  22.                         I2C1_Buffer_Tx[i] = 0;
  23.                         
  24.                 }
  25.     I2C_Master_BufferRead( I2C1, I2C1_Buffer_Tx,8, 0x20);
  26.                 for(i=0;i<8;i++)
  27.                 {
  28.                         I2C1_Buffer_Tx[i] = temp+i;
  29.                         
  30.                 }
  31.                
  32.         }
  33.         
  34. }

  35. #include  "i2c1.h"
  36. #include "delay.h"
  37. #include"stm32f10x.h"        

  38. u8 Tx_Idx1 = 0;
  39. u8 Rx_Idx1 = 0;
  40. u8 I2C1_Buffer_Tx[8] = {0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55};
  41. u8 I2C1_Buffer_Rx[8] = {0};

  42. u8 ReadingFlag = 0;
  43. /*IIC1從機(jī)模式*/
  44. void gpio_init()
  45. {
  46.          GPIO_InitTypeDef GPIO_InitStructure;
  47.          RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  48.          RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

  49.     //配置IO接口
  50.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9|GPIO_Pin_5;  //READY1/READY2
  51.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  52.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;        //
  53.     GPIO_Init(GPIOB, &GPIO_InitStructure);
  54.         
  55.                 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //Waring
  56.                 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;        
  57.                 GPIO_Init(GPIOB, &GPIO_InitStructure);
  58. }

  59. //void I2C_Configuration1(void)
  60. //{
  61. //    GPIO_InitTypeDef GPIO_InitStructure;
  62. //        I2C_InitTypeDef  I2C_InitStructure;
  63. //        NVIC_InitTypeDef NVIC_InitStructure;

  64. //    //使能時(shí)鐘
  65. //    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  66. //    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
  67. //        
  68. //    //配置IO接口
  69. //    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7; //PB6/PB7
  70. //    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  71. //    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;        //
  72. //    GPIO_Init(GPIOB, &GPIO_InitStructure);
  73. //         
  74. //                I2C_InitStructure.I2C_ClockSpeed=400000;        //I2C數(shù)據(jù)傳輸速度
  75. //                I2C_InitStructure.I2C_Mode=I2C_Mode_I2C;          //I2C模式設(shè)置         ,I2C模式,SMBus主模式,SMBus從模式
  76. //                I2C_InitStructure.I2C_DutyCycle=I2C_DutyCycle_2;
  77. //                I2C_InitStructure.I2C_OwnAddress1 =0x20;  //設(shè)備地址
  78. //                I2C_InitStructure.I2C_Ack =I2C_Ack_Enable;         
  79. //                I2C_InitStructure.I2C_AcknowledgedAddress=I2C_AcknowledgedAddress_7bit ;  //尋址模式,7bit或者10bit
  80. //                I2C_Init(I2C1,&I2C_InitStructure);        

  81. //                NVIC_InitStructure.NVIC_IRQChannel = I2C1_EV_IRQn;//事件中斷
  82. //    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
  83. //    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  84. //    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  85. //    NVIC_Init(&NVIC_InitStructure);

  86. //    NVIC_InitStructure.NVIC_IRQChannel = I2C1_ER_IRQn;//錯(cuò)誤中斷
  87. //    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
  88. //    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;                 
  89. //    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  90. //    NVIC_Init(&NVIC_InitStructure);

  91. //    I2C_ITConfig(I2C1, I2C_IT_BUF | I2C_IT_EVT |I2C_IT_ERR, ENABLE);   

  92. //                I2C_Cmd(I2C1, ENABLE);
  93. //                 
  94. //}

  95. //void I2C1_EV_IRQHandler(void)            //I2C1事件中斷響應(yīng)函數(shù) ,主要完成對(duì)上位機(jī)指令的響應(yīng)
  96. //{
  97. //        switch(I2C_GetLastEvent(I2C1))
  98. //        {
  99. //                case I2C_EVENT_SLAVE_RECEIVER_ADDRESS_MATCHED:
  100. //                        {
  101. ////                                 I2C_GenerateSTOP(I2C2, DISABLE);                                 
  102. //                                 I2C_ClearFlag(I2C1,I2C_FLAG_ADDR);
  103. //                                 I2C_ClearFlag(I2C1,I2C_FLAG_BTF);
  104. //                                 break;
  105. //                        }
  106. //                case I2C_EVENT_SLAVE_BYTE_TRANSMITTED:
  107. //                                I2C_SendData(I2C1, I2C1_Buffer_Tx[Tx_Idx1++]);        
  108. //                                break;               
  109. //                case I2C_EVENT_SLAVE_BYTE_TRANSMITTING:                                //EV3
  110. //                                I2C_SendData(I2C1, I2C1_Buffer_Tx[Tx_Idx1++]);
  111. //                                        break;
  112. //                case I2C_EVENT_SLAVE_BYTE_RECEIVED:        
  113. //                           I2C_ClearFlag(I2C1,I2C_FLAG_BTF);
  114. //                                 I2C1_Buffer_Rx[Rx_Idx1++] =  I2C_ReceiveData(I2C1);                                          
  115. //                                break;
  116. //                case I2C_EVENT_SLAVE_STOP_DETECTED:
  117. //                           I2C_ClearFlag(I2C1,I2C_FLAG_STOPF);
  118. //                     I2C_GenerateSTOP(I2C1, DISABLE);
  119. //                           Rx_Idx1=0;  
  120. //                                //i2c_event = EVENT_OPCOD_NOTYET_READ;
  121. //                                break;
  122. //                default:

  123. //                                break;   

  124. //        }        
  125. //}
  126. //        

  127. //void I2C1_ER_IRQHandler(void)            //I2C2錯(cuò)誤事件中斷響應(yīng)函數(shù)
  128. //{
  129. //   if (I2C_GetITStatus(I2C1, I2C_IT_AF))
  130. //         {
  131. //                         I2C_ClearITPendingBit(I2C1, I2C_IT_AF);
  132. //
  133. //                                Tx_Idx1 = 0;
  134. //                  //i2c_event = EVENT_OPCOD_NOTYET_READ;
  135. //                        
  136. //         }
  137. //         
  138. //         if (I2C_GetITStatus(I2C1, I2C_IT_BERR))
  139. //         {
  140. //                         I2C_ClearITPendingBit(I2C1, I2C_IT_BERR);
  141. //         }
  142. //}

  143. /*IIC1主機(jī)模式*/

  144. #define DEVICE_ADDRESS 0x20
  145. /*******************************************************************************
  146. * Function Name  : IIC_Configuration
  147. * Description    : 初始化IIC2外設(shè)
  148. * Input          : None
  149. * Output         : None
  150. * Return         : None
  151. *******************************************************************************/
  152. void IIC_Configuration1(void)
  153. {
  154.         //先定義結(jié)構(gòu)體
  155.         GPIO_InitTypeDef         GPIO_InitStructure;
  156.   I2C_InitTypeDef    I2C_InitStructure;
  157.         
  158.         //要開了對(duì)應(yīng)的gpio的時(shí)鐘還有其他的外設(shè)的時(shí)鐘,然后你配置寄存器才可以,軟件仿真里面開時(shí)鐘先后沒有影響,但是實(shí)物里面,要先開時(shí)鐘
  159.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);        //使能APB2外設(shè)的GPIOB的時(shí)鐘,I2C2是PB_10 SCL,PB_11 SDA上面的復(fù)用         
  160.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 ,ENABLE);  //開啟時(shí)鐘
  161.         
  162.         //要對(duì)上面定義的兩個(gè)結(jié)構(gòu)體進(jìn)行定義,首先PB要定義為復(fù)用的才行,而且是開漏復(fù)用
  163.         GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;         //選擇PB_6是SCL引腳
  164.         GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         //管腳頻率為50MHZ
  165.         GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;         //輸出模式為復(fù)用開漏輸出
  166.         GPIO_Init(GPIOB,&GPIO_InitStructure);                                 //初始化GPIOB寄存器
  167.         
  168.         //配置I2C
  169.         I2C_DeInit(I2C1);//I2C1寄存器復(fù)位
  170.         I2C_InitStructure.I2C_ClockSpeed = 400000;          /*I2C的時(shí)鐘頻率100kHz ,不是I2C輸入時(shí)鐘的頻率*/
  171.   I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;        
  172.   I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;  /*設(shè)置CCR寄存器的,占空比  快速模式下0:Tlow/Thigh = 2;1:Tlow/Thigh = 16/9 */
  173.   I2C_InitStructure.I2C_OwnAddress1 = 0x20 ;         /*這句話說的是stm32作為從機(jī)的時(shí)候它的地址,如果沒有做從機(jī)不用理會(huì)這個(gè)值*/
  174.   I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;        /*應(yīng)答使能 */
  175.   I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; /* */
  176.         I2C_Init(I2C1,&I2C_InitStructure);
  177.         
  178.         //使能I2C
  179.         I2C_Cmd(I2C1, ENABLE);
  180. }

  181. /*******************************************************************************
  182. 主機(jī)發(fā)送數(shù)據(jù)的流程:
  183. 1) 主機(jī)在檢測(cè)到總線為“空閑狀態(tài)”(即 SDA、SCL 線均為高電平)時(shí),發(fā)送一個(gè)啟動(dòng)信號(hào)“S”,開始一次通信的開始
  184.   2) 主機(jī)接著發(fā)送一個(gè)命令字節(jié)。該字節(jié)由 7 位的外圍器件地址和 1 位讀寫控制位 R/W組成(此時(shí) R/W=0)
  185.   3) 相對(duì)應(yīng)的從機(jī)收到命令字節(jié)后向主機(jī)回饋應(yīng)答信號(hào) ACK(ACK=0)
  186.   4) 主機(jī)收到從機(jī)的應(yīng)答信號(hào)后開始發(fā)送第一個(gè)字節(jié)的數(shù)據(jù)
  187.   5) 從機(jī)收到數(shù)據(jù)后返回一個(gè)應(yīng)答信號(hào) ACK
  188.   6) 主機(jī)收到應(yīng)答信號(hào)后再發(fā)送下一個(gè)數(shù)據(jù)字節(jié)
  189.   7) 當(dāng)主機(jī)發(fā)送最后一個(gè)數(shù)據(jù)字節(jié)并收到從機(jī)的 ACK 后,通過向從機(jī)發(fā)送一個(gè)停止信號(hào)P結(jié)束本次通信并釋放總線。從機(jī)收到P信號(hào)后也退出與主機(jī)之間的通信。
  190.   主機(jī)發(fā)送數(shù)據(jù)的程序
  191. *******************************************************************************//**/
  192. uint8_t I2C_Master_BufferWrite(I2C_TypeDef * I2Cx, uint8_t* pBuffer, uint32_t NumByteToWrite, uint8_t SlaveAddress)
  193. {
  194.     if(NumByteToWrite==0)
  195.         return 1;
  196.     /* 1.開始,發(fā)送一個(gè)s,也就是起始信號(hào)*/
  197.     I2C_GenerateSTART(I2Cx, ENABLE);
  198.                 ///判斷EV5,看下函數(shù)定義可以發(fā)現(xiàn),該事件是SB=1,MSL=1,BUSY=1 意思是起始條件已經(jīng)發(fā)送了,然后是主模式,總線在通訊
  199.     while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));

  200.     /* 2.設(shè)備地址·/寫 */
  201.     I2C_Send7bitAddress(I2Cx, SlaveAddress, I2C_Direction_Transmitter);
  202.     while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

  203.     /* 3.連續(xù)寫數(shù)據(jù) */
  204.     while(NumByteToWrite--)
  205.     {
  206.       I2C_SendData(I2Cx, *pBuffer);
  207.       while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
  208.       pBuffer++;
  209.     }

  210.     /* 4.停止 */
  211.     I2C_GenerateSTOP(I2Cx, ENABLE);//產(chǎn)生停止信號(hào)P,結(jié)束本次通訊釋放總線
  212.     while ((I2Cx->CR1&0x200) == 0x200);//完成當(dāng)前字節(jié)傳輸后釋放 SCL 和 SDA 線
  213.                
  214.     return 0;
  215. }
  216. /*******************************************************************************
  217. IIC主機(jī)讀取數(shù)據(jù)的具體流程:
  218.   1) 主機(jī)發(fā)送啟動(dòng)信號(hào)后,接著發(fā)送命令字節(jié)(其中 R/W=1)
  219.   2) 對(duì)應(yīng)的從機(jī)收到地址字節(jié)后,返回一個(gè)應(yīng)答信號(hào)并向主機(jī)發(fā)送數(shù)據(jù)
  220.   3) 主機(jī)收到數(shù)據(jù)后向從機(jī)反饋一個(gè)應(yīng)答信號(hào)
  221.   4) 從機(jī)收到應(yīng)答信號(hào)后再向主機(jī)發(fā)送下一個(gè)數(shù)據(jù)  
  222.   5) 當(dāng)主機(jī)完成接收數(shù)據(jù)后,向從機(jī)發(fā)送一個(gè)“非應(yīng)答信號(hào)(ACK=1)”,從機(jī)收到ACK=1 的非應(yīng)答信號(hào)后便停止發(fā)送
  223.   6) 主機(jī)發(fā)送非應(yīng)答信號(hào)后,再發(fā)送一個(gè)停止信號(hào),釋放總線結(jié)束通信.

  224. *******************************************************************************/
  225. uint8_t I2C_Master_BufferRead(I2C_TypeDef * I2Cx, uint8_t* pBuffer, uint32_t NumByteToRead, uint8_t SlaveAddress)
  226. {
  227.     if(NumByteToRead==0)
  228.         return 1;
  229.     ///等待總線空閑
  230.     while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY));
  231.                 ///在接受一個(gè)字節(jié)(匹配地址或數(shù)據(jù))之后返回應(yīng)答
  232.     I2C_AcknowledgeConfig(I2Cx, ENABLE);
  233.                
  234.     /* 1.開始 */
  235.     I2C_GenerateSTART(I2Cx, ENABLE);
  236.     while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
  237.                
  238.     /* 2.設(shè)備地址·/寫 */
  239.     I2C_Send7bitAddress(I2Cx, SlaveAddress, I2C_Direction_Transmitter);
  240.     while (!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

  241.     /* 3.開始*/
  242.     I2C_GenerateSTART(I2Cx, ENABLE);
  243.     while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));
  244.                
  245.     /* 4.設(shè)備地址·/讀 */
  246.     I2C_Send7bitAddress(I2Cx, SlaveAddress, I2C_Direction_Receiver);
  247.     while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));

  248.     /* 5.連續(xù)寫數(shù)據(jù) */
  249.     while (NumByteToRead)
  250.     {
  251.         if(NumByteToRead==1)
  252.         {
  253.             I2C_AcknowledgeConfig(I2Cx, DISABLE);
  254.             I2C_GenerateSTOP(I2Cx, ENABLE);//6.停止,非應(yīng)答
  255.         }

  256.         while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED));  /* EV7 */
  257.         *pBuffer++ = I2C_ReceiveData(I2Cx);
  258.         NumByteToRead--;
  259.     }

  260.     I2C_AcknowledgeConfig(I2Cx, ENABLE);
  261.     return 0;
  262. }
復(fù)制代碼

全部資料51hei下載地址:
stm32 IIC2.7z (190.48 KB, 下載次數(shù): 44)
作者: 月之光芒    時(shí)間: 2019-7-31 10:32
下下來用了下不太行啊兄弟
作者: jayzay008    時(shí)間: 2019-10-11 15:55
試一下行不行




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1