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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > STM32開發(fā)板- I2C--24Cxx

          STM32開發(fā)板- I2C--24Cxx

          作者: 時(shí)間:2016-11-27 來源:網(wǎng)絡(luò) 收藏
          我們所用來示范的24Cxx系列是最常用的EEPROM芯片。
          前面提到了一個(gè)地址碼,
          24Cxx的地址碼是固定的,
          8位如下:
          1010A2 A1 A00
          A2 A1 A0分別是它三個(gè)管腳的電平

          24Cxx 理解起來有一個(gè)特別之處。
          24Cxx 包括 01/02/04/08/16 四種,容量關(guān)系剛好和數(shù)字一樣。1K 2K 4K 8K 16K
          24C02 最為常見, 它的三個(gè)地址管腳A2 A1 A0都是可用的,
          A2 A1 A0 有8中電平組合,也就是說,可以有8個(gè) 24C02 掛載同一個(gè)I2C總線上。
          24C04呢, A0管腳就失效了,只有A2 和 A1 有用,四種組合,最多有4個(gè)24C04在總線上,
          以此類推。24C16只能有一個(gè)在總線上。
          這里就不好理解了,為什么要這樣呢。
          事實(shí)是一片 24C16 == 8片24C02 總線掛到一起。A2 A1 A0雖然起不到設(shè)置作用了,但你使用地址碼還是會(huì)訪問到特定的區(qū)域。
          明白了吧。所以其實(shí)24C系列的代碼是通用的。
          地址碼也是固定的。就是 0xA0 0xA2 0xA4 0xA6 0xA8 0xAA 0xAC 0xAE
          好,我們以24C16為范例吧。

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

          IO設(shè)置在I2C1上,無Remap,復(fù)用開漏輸出。I2C 總線是掛4.7k電阻上拉到高電平的。
          //-----------------------I2C--------------------------------------------

          GPIO_InitStruct.GPIO_Pin =GPIO_Pin_6 | GPIO_Pin_7;
          GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
          GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD;//復(fù)用開漏輸出
          GPIO_Init(GPIOB, &GPIO_InitStruct);

          I2C init函數(shù):

          void i2c_24c_init(I2C_TypeDef *I2Cx)
          {
          I2C_InitTypeDef I2C_InitStruct;

          I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;// I2C模式
          I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;// ACK 在通訊中常見,握手包,即發(fā)送到了一個(gè)數(shù)據(jù),接收方回一句,我收到鳥。
          I2C_InitStruct.I2C_ClockSpeed = I2C_Speed;// I2C 速度設(shè)置,一般是40KHZ,400KHZ是極限,一般到不了那么高
          I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2;//快速模式下的選項(xiàng),這里先不講,100KHZ以上才有用
          I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//應(yīng)答地址碼長度,7位或者10位,24C是7位

          // EEprom Block Select;
          I2C_InitStruct.I2C_OwnAddress1 = I2C_Slave_Adress7;//第一個(gè)設(shè)備自身地址

          I2C_Cmd(I2Cx,ENABLE);//開啟I2C

          I2C_Init(I2Cx,&I2C_InitStruct);//將剛剛的設(shè)置送進(jìn)去
          }

          注意:現(xiàn)在的片子一般都不止一個(gè)I2C。所以用了上述模式,請?jiān)敿?xì)看注釋。

          寫一個(gè)字節(jié)進(jìn)EEPROM:
          參數(shù)解釋:Byte待寫的字節(jié),WriteAddr預(yù)計(jì)寫入的地址,ByteToWrite寫多少給字節(jié),EE24cBlockSelect選擇EEPROM相應(yīng)的區(qū)域(I2C地址),*I2Cx,I2C設(shè)備指針
          void i2c_24c_byte_write(unsigned char Byte, unsigned char WriteAddr, unsigned int ByteToWrite, unsigned char EE24cBlockSelect,I2C_TypeDef *I2Cx)
          {
          // Start the I2C
          I2C_GenerateSTART(I2Cx,ENABLE); //打開I2C,開始發(fā)送過程

          //not recommanded, stupid way
          while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT));//設(shè)置主機(jī)模式

          I2C_Send7bitAddress(I2Cx,EE24cBlockSelect,I2C_Direction_Transmitter); //發(fā)送片選,選擇哪一片區(qū)域?qū)?。i2C地址區(qū)分

          // when get ACK, means Set Success
          while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); //等待這次選擇過程完成

          I2C_SendData(I2Cx, WriteAddr);//發(fā)送要寫入的地址碼

          while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //等待字節(jié)發(fā)送完成

          I2C_SendData(I2Cx, Byte); //發(fā)送要寫的字節(jié)

          while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); //等待直到字節(jié)發(fā)送完成

          I2C_GenerateSTOP(I2Cx, ENABLE); //發(fā)送過程結(jié)束。
          }

          讀EEPROM函數(shù)類似,卻稍微復(fù)雜。
          參數(shù)說明:pBuffer接收I2C數(shù)據(jù)的緩沖區(qū),Addr讀的地址,NumToRead讀多少個(gè)字節(jié),ee24cblockselect讀哪個(gè)區(qū)域,I2Cx i2c設(shè)備指針
          void i2c_24c_buffer_read(unsigned char *pBuffer, unsigned char Addr,unsigned char NumToRead,unsigned char EE24cBlockSelect, I2C_TypeDef *I2Cx)
          {
          //open I2C
          I2C_GenerateSTART(I2Cx, ENABLE);//開始發(fā)送

          while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT))); //設(shè)置自己為主機(jī)

          I2C_Send7bitAddress(I2Cx,EE24cBlockSelect,I2C_Direction_Transmitter);//設(shè)置自己為發(fā)送

          while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))); //等待主機(jī)發(fā)送模式設(shè)置成功

          I2C_Cmd(I2Cx,ENABLE);//使能I2C

          I2C_SendData(I2Cx, Addr); //發(fā)送地址碼,即要讀的地址

          while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)));//等待主機(jī)發(fā)送過程完成

          I2C_GenerateSTART(I2Cx, ENABLE); //I2C開始發(fā)送

          while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)));//設(shè)置主機(jī)模式

          I2C_Send7bitAddress(I2Cx,EE24cBlockSelect,I2C_Direction_Receiver);//設(shè)置從機(jī)地址,并設(shè)置主機(jī)為接收模式

          while(!(I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))); //確認(rèn)該過程完成

          while(NumToRead)
          {
          if(NumToRead==1)
          {
          I2C_AcknowledgeConfig(I2Cx, DISABLE);//關(guān)閉I2C的應(yīng)答功能

          I2C_GenerateSTOP(I2Cx, ENABLE); //發(fā)送結(jié)束信息
          }

          if((I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)))//如果接收到信息了
          {
          *pBuffer = I2C_ReceiveData(I2Cx);//把接收到的數(shù)據(jù) 填進(jìn)緩沖區(qū)當(dāng)中

          pBuffer++;

          NumToRead--;
          }
          }

          I2C_AcknowledgeConfig(I2Cx, ENABLE);//開啟主機(jī)I2C的應(yīng)答功能

          }

          在寫i2C和讀i2C之間要插入下面函數(shù)等待,否則會(huì)有問題

          I2C_EE_WaitEepromStandbyState();



          關(guān)鍵詞: STM32I2C24Cx

          評論


          技術(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); })();