STM32CubeMx之硬體IIC驅動EEPROM
1.I2C簡介
I2C( Inter-Integrated Circuit)總線是由 PHILIPS 公司開發的兩線式串行總線,用于連接配接微控制器及其外圍裝置。是微電子通信控制領域廣泛采用的一種總線标準。具有接口線少,控制方式簡單,器件封裝形式小,通信速率較高等優點。
- I2C特性:
(1)隻要求兩條總線線路一條串行資料線SDA,一條串行時鐘線SCL;
(2)每個連接配接到總線的器件都可以通過唯一的位址和一直存在的簡單的主機/從機關系軟體設定位址,主機可以作為主機發送器或主機接收器;
(3)它是一個真正的多主機總線,如果兩個或更多主機同時初始化資料傳輸可以通過沖突檢測和仲裁防止資料被破壞;
(4)串行的 8 位雙向資料傳輸位速率在标準模式下可達100kbit/s,快速模式下可達400kbit/s,高速模式下可達 3.4Mbit/s
(5)片上的濾波器可以濾去總線資料線上的毛刺波保證資料完整;
(6)連接配接到相同總線的IC數量隻受到總線的最大電容400pF;
IIC是屬串行通訊總線,同步傳輸、半雙工。
2. I2C總線協定
IIC協定格式:起始信号、停止信号、應答信号、非應答信号、發送資料、接收資料。
空閑狀态:SCL和SDA均保持高電平;
2.1 起始信号
時鐘為高電平時,資料由高電平變為低電平。
SDA_OUT=1;
SCL=1;
delay_us(2);
SDA_OUT=0;
//友善下一次資料收發
delay_us(2);
SCL=0;
2.2 停止信号
時鐘線為高電平時,資料線由低變高。
SDA_OUT=0;
SCL=0;
Delay_us(2);
SCL=1;
Delay_us(2);
SDA_OUT=1;
資料傳輸時序:
2.3 擷取應答
時鐘線為高時讀取資料。應答信号本身就是一位資料。
u8 i=0;
SCL=0;//告訴從機,主機需要讀取資料
Delay_us(2);
SCL=1;//開始讀取資料
while(SDA_IN)
{
i++;
Delay_us(1);
if(i>=20)return 1;//非應答
}
Delay_us(2);
SCL=0;//友善下一次資料收發
return 0;//擷取應答信号
2.4 發送應答(非應答)信号
時鐘線為低電平時發送資料。應答信号本身就是一位資料。
SCL=0;
SDA_OUT=ack&0x01;//ack為應答參數,0為應答,1為非應答
Delay_us(2);
SCL=1;//資料發送完成
//友善下一次資料收發
Delay_us(2);
SCL=0;
2.5 發送一個位元組資料
for(i=0;i<8;i++)
{
SCL=0;
if(data&0x80)SDA_OUT=1;
else SDA_OUT=0;
Delay_us(2);
SCL=1;//資料發送完成
data<<=1;
Delay_us(2);
}
SCL=0;//友善下一次資料收發
2.6 接收一個位元組資料
u8 data=0;
for(i=0;i<8;i++)
{
SCL=0;//告訴從機,主機需要讀取資料
Delay_us(2);
SCL=1;//主機開始讀取資料
data<<=1;
if(SDA_IN)data|=0x01;
Delay_us(2);
}
SCL=0;//友善下一次資料收發
return data;
3.AT24CXX介紹
CAT24WC01/02/04/08/16是一個1K/2K/4K/8K/16K位串行CMOS E2PROM。内部含有12/256/512/1024/2048個8位位元組,CATALYST公司的先進CMOS技術實質上減少了器件的功耗,CAT24WC01有一個8位元組頁寫緩沖器,CAT24WC02/04/08/16有一個16位元組頁寫緩沖器,該器件通過I2C總線接口進行操作有一個專門的寫保護功能。
特性:
與400KHz I2C總線相容
1.8到6.0伏工作電壓範圍
低功耗CMOS 技術
寫保護功能當WP為高電平時進入寫保護狀态
頁寫緩沖器
自定時擦寫周期
1,000,000程式設計/擦除周期
可儲存資料100年
8 腳 DIP SOIC或TSSOP封裝
溫度範圍:商業級工業級和汽車級
3.1 引腳說明
3.2 總線時序
時鐘上升沿讀取資料,下降發送資料。
3.3 從器件位址
3.4 寫操作時序
位元組寫
在位元組寫模式下,主器件發送起始指令和從器件位址資訊(R/W位置零)給從器件在從器件産生應答信号後,主器件發送 CAT24WC01/02/04/08/16的位元組位址,主器件在收到從器件的另一個應答信号後,再發送資料到被尋址的存儲單元。AT24WC01/02/04/08/16再次應答,并在主器件産生停止信号後開始内部資料的擦寫,在内部擦寫過程中,CAT24WC01/02/04/08/16不再應答主器件的任何請求。
頁寫
用頁寫, CAT24WC01可一次寫入8個位元組資料,CAT24WC02/04/08/16可以一次寫入16個位元組的資料。頁寫操作的啟動和位元組寫一樣不同在于傳送了一位元組資料後并不産生停止信号。主器件被允許發送P(AT24WC01 P=7;AT24WC02/04/08/16 P=15)個額外的位元組,每發送一個位元組資料後,CAT24WC01/02/04/08/16産生一個應答位并将位元組位址低位加1,高位保持不變。
如果在發送停止信号之前,主器件發送超過P+1個位元組,位址計數器将自動翻轉,先前寫入的資料被覆寫。
接收到P+1位元組資料和主器件發送的停止信号後,CAT24CXXX啟動内部寫周期将資料寫到資料區。所有接收的資料在一個寫周期内寫入CAT24WC01/02/04/08/16。
3.5 讀操作時序
選擇性讀
選擇性讀操作允許主器件對寄存器的任意位元組進行讀操作,主器件首先通過發送起始信号、從器件位址和它想讀取的位元組資料的位址執行一個僞寫操作。在 CAT24WC01/02/04/08/16 應答之後,主器件重新發送起始信号和從器件位址,此時R/W 位置1,CAT24WC01/02/04/08/16響應并發送應答信号,然後輸出所要求的一個 8位位元組資料,主器件不發送應答信号但産生一個停止信号。
連續讀
連續讀操作可通過立即讀或選擇性讀操作啟動。在CAT24WC01/02/04/08/16發送完一個8位位元組資料後,主器件産生一個應答信号來響應,告知CAT24WC01/02/04/08/16 主器件要求更多的資料,對應每個主機産生的應答信号CAT24WC01/02/04/08/16将發送一個8位資料位元組。當主器件不發送應答信号而發送停止位時結束此操作。
從CAT24WC01/02/04/08/16 輸出的資料按順序由N到N+1輸出。讀操作時位址計數器在CAT24WC01/02/04/08/16整個位址内增加,這樣整個寄存器區域在可在一個讀操作内全部讀出。當讀取的位元組超過 E(對于 24WC01,E=127;對24WC02,E=255;對24WC04,E=511;對24WC08,E=1023;對24WC16 E=2047)計數器将翻轉到零并繼續輸出資料位元組。
4. EEPROM硬體接口
在本示例中采用的EEPROM晶片為AT24C08型号,該封裝類型和24C02完全相容;
AT24C08容量為8Kbit,即1KB,1024位元組;24C02量為2kbit,為256位元組。
引腳 | GPIO |
IIC_SCL | 時鐘線PB6 |
IIC_SDA | 雙向資料線PB7 |
5.軟體設定
6.代碼生成
6.1 IIC硬體配置
6.2 IIC硬體産生起始信号、停止信号
//産生起始信号
void IIC_Start(void)
{
hi2c1.Instance->CR1|=1<<8;
while(!(hi2c1.Instance->SR1&1<<0)){}//等待起始信号發送成功
hi2c1.Instance->CR1&=~(1<<8);
}
//停止信号
void IIC_Stop(void)
{
hi2c1.Instance->CR1|=1<<9;
}
6.3 IIC硬體資料收發
//發送資料
void IIC_WriteData(uint8_t data)
{
hi2c1.Instance->DR=data;
while(!(hi2c1.Instance->SR1&1<<7)){}//等待資料發送完成
}
/*發送位址*/
void IIC_WriteAddr(uint8_t adrr)
{
uint8_t stat;
hi2c1.Instance->DR=adrr;
while(!(hi2c1.Instance->SR1&1<<1)){}//等待資料發送完成
stat=hi2c1.Instance->SR2;//對SR2讀取清除标志位
}
uint8_t IIC_readData(void)
{
uint8_t data;
hi2c1.Instance->CR1|=1<<10;//産生應答
while(!(hi2c1.Instance->SR1&1<<6)){}//等待資料到來
data=hi2c1.Instance->DR;
hi2c1.Instance->CR1&=~(1<<10);//取消應答發送
return data;
}
6.4 AT24C08讀寫位元組
#define AT24C08_ADDR_W 0xA0 //器件位址+寫使能位
#define AT24C08_ADDR_R 0xA1 //器件位址+讀使能位
/*寫一個位元組函數*/
void AT24C08_WriteOneByte(uint8_t addr,uint8_t data)
{
IIC_Start();//發送起始信号
IIC_WriteAddr(AT24C08_ADDR_W);//發送位址
IIC_WriteData(addr);//發送寫入資料位址
IIC_WriteData(data);//寫入資料
IIC_Stop();//停止信号
HAL_Delay(10);//寫周期時間
}
/*讀一個位元組函數*/
uint8_t AT24C08_ReadOneByte(uint8_t addr)
{
uint8_t data;
IIC_Start();//發送起始信号
IIC_WriteAddr(AT24C08_ADDR_W);//器件位址+寫使能
IIC_WriteData(addr);//發送寫入資料位址
IIC_Start();//發送起始信号
IIC_WriteAddr(AT24C08_ADDR_R);//器件位址+讀使能
data=IIC_readData();//讀取一個位元組資料
IIC_Stop();//停止信号
return data;
}
6.5 主函數
MX_GPIO_Init();
MX_USART1_UART_Init();
//MX_FSMC_Init();
MX_SPI2_Init();
MX_I2C1_Init();
/* USER CODE BEGIN 2 */
printf("序列槽初始化完成\n");
uint8_t buff_tx[]="STM32CubeMX硬體IIC驅動AT24C08資料讀寫測試! --VER1.0";
uint8_t buff_rx[100];
uint8_t data;
//NT35310_Init();//LCD初始化
AT24C08_WriteData(100,buff_tx,sizeof(buff_tx));
AT24C08_ReadData(100,buff_rx,sizeof(buff_tx));
printf("buff_rx=%s\r\n",buff_rx);
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
注意:STM32F10x硬體IIC和FSMC不能同時使用;