<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          STM32 的I2C 硬使用

          作者: 時間:2016-12-03 來源:網(wǎng)絡(luò) 收藏
          /*

          操作對象為一24C02
          */

          本文引用地址:http://www.ex-cimer.com/article/201612/325216.htm

          #include "STM32Lib\stm32f10x.h"
          #include "hal.h"

          //#define AT24C01A//24C01A,I2C時序和往后的24C02一樣
          #define AT24C01//24C01,I2C的時序和普通的有點不同

          #define EEPROM_ADDR0xA0
          #define I2C_PAGESIZE4//24C01/01A頁緩沖是4個


          void I2C_Configuration(void)
          {
          I2C_InitTypeDef I2C_InitStructure;
          GPIO_InitTypeDef GPIO_InitStructure;

          RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);

          /* PB6,7 SCL and SDA */
          GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
          GPIO_Init(GPIOB, &GPIO_InitStructure);

          I2C_DeInit(I2C1);
          I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
          I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
          I2C_InitStructure.I2C_OwnAddress1 = 0x30;
          I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
          I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
          I2C_InitStructure.I2C_ClockSpeed = 100000;//100K速度

          I2C_Cmd(I2C1, ENABLE);
          I2C_Init(I2C1, &I2C_InitStructure);
          /*允許1字節(jié)1應答模式*/
          I2C_AcknowledgeConfig(I2C1, ENABLE);

          }

          /***************************************************
          **函數(shù)名:I2C_ReadS
          **功能:讀取24C02多個字節(jié)
          **注意事項:24C02是256字節(jié),8位地址,A0-A2固定為0,從器件地址為EEPROM_ADDR
          ***************************************************/
          void I2C_ReadS_24C(u8 addr ,u8* pBuffer,u16 no)
          {
          if(no==0)
          return;

          while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));

          /*允許1字節(jié)1應答模式*/
          I2C_AcknowledgeConfig(I2C1, ENABLE);


          /* 發(fā)送起始位 */
          I2C_GenerateSTART(I2C1, ENABLE);
          while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));/*EV5,主模式*/

          #ifdef AT24C01A
          /*發(fā)送器件地址(寫)*/
          I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Transmitter);
          while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

          /*發(fā)送地址*/
          I2C_SendData(I2C1, addr);
          while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));/*數(shù)據(jù)已發(fā)送*/

          /*起始位*/
          I2C_GenerateSTART(I2C1, ENABLE);
          while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

          /*器件讀*/
          I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Receiver);
          while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));


          #else
          /*發(fā)送器件地址(讀)24C01*/
          I2C_Send7bitAddress(I2C1, addr<<1, I2C_Direction_Receiver);
          while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
          #endif

          while (no)
          {
          if(no==1)
          {
          I2C_AcknowledgeConfig(I2C1, DISABLE);//最后一位后要關(guān)閉應答的
          I2C_GenerateSTOP(I2C1, ENABLE);//發(fā)送停止位
          }

          while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); /* EV7 */
          *pBuffer = I2C_ReceiveData(I2C1);
          pBuffer++;
          /* Decrement the read bytes counter */
          no--;
          }
          //再次允許應答模式
          I2C_AcknowledgeConfig(I2C1, ENABLE);
          }

          /****************************************************
          **函數(shù)名:I2C_Standby_24C
          **功能:24C是否準備好再寫入的判斷
          **注意事項:本函數(shù)可以理解為:判忙
          就是不停發(fā)地址 直到器件有應答
          ****************************************************/
          void I2C_Standby_24C(void)
          {
          vu16 SR1_Tmp;
          do
          {
          /*起始位*/
          I2C_GenerateSTART(I2C1, ENABLE);
          /*讀SR1*/
          SR1_Tmp = I2C_ReadRegister(I2C1, I2C_Register_SR1);
          /*器件地址(寫)*/
          #ifdef AT24C01A
          I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Transmitter);
          #else
          I2C_Send7bitAddress(I2C1, 0, I2C_Direction_Transmitter);
          #endif
          }while(!(I2C_ReadRegister(I2C1, I2C_Register_SR1) & 0x0002));

          /*清除應答錯誤標志*/
          I2C_ClearFlag(I2C1, I2C_FLAG_AF);
          /*停止位*/
          I2C_GenerateSTOP(I2C1, ENABLE);
          }

          /*************************************************
          **函數(shù)名:I2C_ByteWrite_24C
          **功能:寫一個字節(jié)
          **注意事項:字寫入同樣需要調(diào)用忙判斷
          *************************************************/
          void I2C_ByteWrite_24C(u8 addr,u8 dat)
          {
          /* 起始位 */
          I2C_GenerateSTART(I2C1, ENABLE);
          while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

          #ifdef AT24C01A
          /* 發(fā)送器件地址(寫)*/
          I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Transmitter);
          while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

          /*發(fā)送地址*/
          I2C_SendData(I2C1, addr);
          while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

          #else
          I2C_Send7bitAddress(I2C1, addr<<1, I2C_Direction_Transmitter);
          while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
          #endif

          /* 寫一個字節(jié)*/
          I2C_SendData(I2C1, dat);
          while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

          /* 停止位*/
          I2C_GenerateSTOP(I2C1, ENABLE);

          I2C_Standby_24C();
          }

          /*************************************************
          **函數(shù)名:I2C_PageWrite_24C
          **功能:寫入一頁(以內(nèi))
          **注意事項:此函數(shù)供群寫入調(diào)用
          *************************************************/
          void I2C_PageWrite_24C(u8 addr,u8* pBuffer, u8 no)
          {
          while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));

          /*起始位*/
          I2C_GenerateSTART(I2C1, ENABLE);
          while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));

          #ifdef AT24C01A
          /*器件地址(寫)*/
          I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Transmitter);
          while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));

          /*寫地址值*/
          I2C_SendData(I2C1, addr);
          while(! I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));

          #else
          I2C_Send7bitAddress(I2C1, addr<<1, I2C_Direction_Transmitter);
          while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
          #endif
          while(no--)
          {
          I2C_SendData(I2C1, *pBuffer);
          pBuffer++;
          while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
          }

          /*停止位*/
          I2C_GenerateSTOP(I2C1, ENABLE);
          }

          /*************************************************
          **函數(shù)名:I2C_WriteS_24C
          **功能:頁寫入24C
          **注意事項:24C02最多允許一次寫入8個字節(jié)
          *************************************************/
          void I2C_WriteS_24C(u8 addr,u8* pBuffer, u16 no)
          {
          u8 temp;

          //1.先把頁不對齊的部分寫入
          temp=addr % I2C_PAGESIZE;
          if(temp)
          {
          temp=I2C_PAGESIZE-temp;
          I2C_PageWrite_24C(addr,pBuffer, temp);
          no-=temp;
          addr+=temp;
          pBuffer+=temp;
          I2C_Standby_24C();
          }
          //2.從頁對齊開始寫
          while(no)
          {
          if(no>=I2C_PAGESIZE)
          {
          I2C_PageWrite_24C(addr,pBuffer, I2C_PAGESIZE);
          no-=I2C_PAGESIZE;
          addr+=I2C_PAGESIZE;
          pBuffer+=I2C_PAGESIZE;
          I2C_Standby_24C();
          }
          else
          {
          I2C_PageWrite_24C(addr,pBuffer, no);
          no=0;
          I2C_Standby_24C();
          }
          }
          }


          //測試用
          void I2C_Test(void)
          {
          u8 i;
          u8 I2c_Buf[128];

          I2C_Standby_24C();

          //填充緩沖
          for(i=0;i<128;i++)
          I2c_Buf[i]=i;

          //寫
          I2C_WriteS_24C(1,I2c_Buf,120);

          //清緩沖
          for(i=0;i<128;i++)
          I2c_Buf[i]=0;

          //讀
          I2C_ReadS_24C(1,I2c_Buf,80);

          for(i=1;i<120;i++)
          {
          if(I2c_Buf[i]!=i)
          {
          while(1);
          }
          }

          }

          就看這里 確定是否正常~!

          其實 都是 while 這種 硬等待 導致屢次調(diào)不通 務必加入 超時判斷。

          簡單的像

          i=0;

          while((!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))&&i<12000);i++



          關(guān)鍵詞: STM32I2C硬使

          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();