STM32:I2C接口讀寫EEPROM(AT24C02)試驗例程
硬件平臺:stm32f10xZET6
開發(fā)環(huán)境:keil MDK uVisionv4.10
開發(fā)語言:C、ST_lib_3.5固件庫
EEPROM:電可擦可編程只讀存儲器。
【stm32f10xZET6開發(fā)板的I2C外設(shè)物理層特點】
(1)兩條串行總線:一條雙向數(shù)據(jù)線(SDA),一條時鐘線(SCL);
(2)從設(shè)備地址唯一;
(3)支持總線仲裁;
(4)三種速率傳輸模式:
標(biāo)準(zhǔn)模式100kbit/s
快速模式400kbit/s
高速模式3.4Mbit/s (目前大多I2C設(shè)備尚不支持高速模式)
(5)片上的濾波器可以濾去總線數(shù)據(jù)線上的毛刺波保證數(shù)據(jù)完整;
(6)連接到相同總線的IC數(shù)量受到總線的最大電容400pF限制;
【I2C接口特性】
(1) STM32 中和大容量型號芯片均有多達 2 個I2C總線接口;
(2) 能夠工作于多主機或多從機模式,主從均可收發(fā);
(3) 支持標(biāo)準(zhǔn)模式 100Kbit/s 和快速模式 400Kbit/s,不支持高
速模式;
(4) 支持 7 位或 10 位從設(shè)備地址尋址;
(5) 內(nèi)置了硬件 CRC 發(fā)生器/ 校驗器;
(6) I2C 的接收和發(fā)送都可以使用 DMA 操作;
(7) 支持系統(tǒng)管理總線(SMBus)總線 2.0 版;
typedef struct
{
uint32_t I2C_ClockSpeed; /*!< 指定時鐘總線速率,100/400kHz */
uint16_t I2C_Mode; /*!< 指定為I2C通信模式 */
uint16_t I2C_DutyCycle; /*!< 指定I2C快速模式 */
uint16_t I2C_OwnAddress1; /*!< 指定從設(shè)備自身地址,7/10bit(地址0x0A對應(yīng)宏) */
uint16_t I2C_Ack; /*!< 使能或禁止ack */
uint16_t I2C_AcknowledgedAddress; /*!< 指定7/10bit從設(shè)備地址下的ack */
} I2C_InitTypeDef;
在 stm32 如何建立與 EEPROM 的通訊步驟:
(1) 配置 I/O 端口,確定并配置 I2C 的模式,使能 GPIO 和 I2C
時鐘。
(2) 寫:
1) 檢測 SDA 是否空閑;
2) 按 I2C 協(xié)議發(fā)出起始信號;
3) 發(fā)出 7 位器件地址和寫模式;
4) 要寫入的存儲區(qū)首地址;
5) 用頁寫入方式或字節(jié)寫入方式寫入數(shù)據(jù);
6) 發(fā)送 I2C 通訊結(jié)束訊信號
每個操作之后要檢測“事件”確定是否成功。寫完后檢測 EEPROM 是否進
入 standby 狀態(tài)。
(3) 讀:
1) 檢測 SDA 是否空閑;
2) 按 I2C 協(xié)議發(fā)出起始訊號;
3) 發(fā)出 7 位器件地址和寫模式(偽寫);
4) 發(fā)出要讀取的存儲區(qū)首地址;
5) 重發(fā)起始訊號;第 260 頁 共 729 頁
6) 發(fā)出 7 位器件地址和讀模式;
7) 接收數(shù)據(jù);
類似寫操作,每個操作之后要檢測“事件”確定是否成功。
I2C_GenerateSTART(); // 產(chǎn)生 I2C 的通訊起始信號 S
I2C_Send7bitAddress(); // 發(fā)送7位從設(shè)備地址
I2C_SendData(); // 發(fā)送一個數(shù)據(jù)字節(jié)(8bit)
I2C_GenerateSTOP(); // 產(chǎn)生 I2C 的通訊停止信號 P
I2C_CheckEvent (); // I2C 傳輸時的事件監(jiān)測
/*代碼演示-mian.c*/
/**
******************************************************************************
*@filemain.c
*@authorfire
*@versionV1.0
*@date2013-xx-xx
*@briefI2CEEPROM(AT24C02)測試,測試信息通過USART1打印在電腦的超級終端
******************************************************************************
*/
#include"stm32f10x.h"
#include"bsp_usart1.h"
#include"bsP_i2c_ee.h"
#include"bsP_led.h"
#include
#defineEEP_Firstpage0x00
u8I2c_Buf_Write[256];
u8I2c_Buf_Read[256];
voidI2C_Test(void);
/**
*@brief主函數(shù)
*@param無
*@retval無
*/
intmain(void)
{
/*串口1初始化*/
USART1_Config();
printf("rn這是一個I2C外設(shè)(AT24C02)讀寫測試例程rn");
//LED_GPIO_Config();
/*I2C外設(shè)初(AT24C02)始化*/
I2C_EE_Init();
printf("rn這是一個I2C外設(shè)(AT24C02)讀寫測試例程rn");
I2C_Test();
while(1)
{
}
}
/**
*@briefI2C(AT24C02)讀寫測試
*@param無
*@retval無
*/
voidI2C_Test(void)
{
u16i;
printf("寫入的數(shù)據(jù)nr");
for(i=0;i<=255;i++)//填充緩沖
{
I2c_Buf_Write[i]=i;
printf("0x%02X",I2c_Buf_Write[i]);
if(i%16==15)
printf("nr");
}
//將I2c_Buf_Write中順序遞增的數(shù)據(jù)寫入EERPOM中
//LED1(ON);
I2C_EE_BufferWrite(I2c_Buf_Write,EEP_Firstpage,256);
//LED1(OFF);
printf("nr寫成功nr");
printf("nr讀出的數(shù)據(jù)nr");
//將EEPROM讀出數(shù)據(jù)順序保持到I2c_Buf_Read中
//LED2(ON);
I2C_EE_BufferRead(I2c_Buf_Read,EEP_Firstpage,256);
//LED2(OFF);
//將I2c_Buf_Read中的數(shù)據(jù)通過串口打印
for(i=0;i<256;i++)
{
if(I2c_Buf_Read[i]!=I2c_Buf_Write[i])
{
printf("0x%02X",I2c_Buf_Read[i]);
printf("錯誤:I2CEEPROM寫入與讀出的數(shù)據(jù)不一致nr");
return;
}
printf("0x%02X",I2c_Buf_Read[i]);
if(i%16==15)
printf("nr");
}
printf("I2C(AT24C02)讀寫測試成功nr");
}
/*代碼演示-bsp_i2c_ee模塊*/
#ifndef__I2C_EE_H
#define__I2C_EE_H
#include"stm32f10x.h"
/*
*AT24C022kb=2048bit=2048/8B=256B
*32pagesof8byteseach
*
*DeviceAddress
*1010A2A1A0R/W
*10100000=0XA0
*10100001=0XA1
*/
/*EEPROMAddressesdefines*/
#defineEEPROM_Block0_ADDRESS0xA0/*E2=0*/
//#defineEEPROM_Block1_ADDRESS0xA2/*E2=0*/
//#defineEEPROM_Block2_ADDRESS0xA4/*E2=0*/
//#defineEEPROM_Block3_ADDRESS0xA6/*E2=0*/
void I2C_EE_Init