文章目錄
- 一.概要
- 二.IIC總線基本概念
- 1.總體特征
- 2.通訊流程
- 三.EEPROM介紹
- 1.M24C08基本介紹
- 2.向M24C08寫一個字節時序圖
- 3.從M24C08讀一個字節時序圖
- 四.GPIO模擬IIC驅動M24C08讀寫
- 五.CubeMX工程源代碼下載
- 六.講解視頻鏈接地址
- 七.小結
一.概要
IIC(Inter-Integrated Circuit)總線是一種由NXP(原PHILIPS)公司開發的兩線式串行總線,用于連接微控制器及其外圍設備。多用于主控制器和從器件間的主從通信,在小數據量場合使用,傳輸距離短,任意時刻只能有一個主機等特性。
二.IIC總線基本概念
I2C 總線,分別由SDA(串行數據線)和SCL(串行時鐘線)及上拉電阻組成。
1.總體特征
2.通訊流程
三.EEPROM介紹
EEPROM( Electrically Erasable Programmable Read Only Memory )全稱是電可擦除可編程只讀存儲器,是非易失存儲器,可以訪問到每個字節,容量比較小。目前的EEPROM一般是IIC接口或者SPI接口的。
1.M24C08基本介紹
M24C08是ST公司(意法半導體公司)的串行接口的EEPROM存儲芯片,它的容量是8K bit。
?
芯片功能描述:
M24C08系列支持I2C,總線數據傳送協議I2C,總線協議規定任何將數據傳送到總線的器件作為發送器。任何從總線接收數據的器件為接收器;數據傳送是由產生串行時鐘和所有起始停止信號的主器件控制的。主器件和從器件都可以作為發送器或接收器,但由主器件控制傳送數據(發送或接收)的模式。
芯片特性介紹:
1.兩線串行接口(SDA、SCL)
2.有用于硬件數據保護的寫保護引腳
3.自定時寫入周期(5毫秒),因為內部有頁緩沖區,向M24C08寫入數據之后,還需要等待M24C08將緩沖區數據寫入到內部EEPROM區域
4.數據保存可達100年
5.100萬次擦寫周期
6.高數據傳送速率為400KHz、低速100KHZ和IIC總線兼容
7.16字節頁寫緩沖區
這個緩沖區大小與芯片具體型號有關: 8字節頁(1K、2K)、16字節頁(4K、8K、16K)
M24C08的E2(3腳)一般接地,E1,E0是容量大點的EEPROM才有,這樣M24C08這個器件,寫操作時候的地址就是0xA0,讀操作時候的地址是0xA1。
2.向M24C08寫一個字節時序圖
寫操作過程中只有ACK是M24C08發出的,其他信號都是單片機發出的。
3.從M24C08讀一個字節時序圖
讀操作過程中ACK跟返回的數據是M24C08發出的,其他信號都是單片機發出的。
四.GPIO模擬IIC驅動M24C08讀寫
硬件準備:
STLINK接STM32F103C8T6小系統板,STLINK接電腦USB口,
STM32F103C8T6小系統板跟EEPROM模塊連接:
板子G----模塊GND
板子3.3–模塊VCC
板子PB10—模塊SCL
板子PB11—模塊SDA
打開STM32CubeMX軟件,新建工程
Part Number處輸入STM32F103C8,再雙擊就創建新的工程
配置下載口引腳
配置外部晶振引腳
配置系統主頻
配置工程文件名,保存路徑,KEIL5工程輸出方式
生成工程
用Keil5打開工程
添加代碼
主要代碼
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();//8M外部晶振,系統主頻72M/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();/* USER CODE BEGIN 2 */EE_IIC_Init();//管腳初始化EE_EE_IIC_SendByteToSlave(0xA0,0x00,0x55);//0地址寫入0x55HAL_Delay(10);//等待10msEE_IIC_ReadByteFromSlave(0xA0,0x00,&EEDATA);//從0地址讀取內容存儲到變量/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}#include "main.h"
#define EE_ADDR 0xa0
#define EE_SCL_PIN GPIO_PIN_10 //模擬IIC的SCL信號 1.修改引腳即可修改IIC接口
#define EE_SDA_PIN GPIO_PIN_11 //模擬IIC的SDA信號void EE_SDA_IN(void) //配置成輸入 { GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = GPIO_PIN_11;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
void EE_SDA_OUT(void)//配置成輸出
{GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = GPIO_PIN_11;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);}void EE_SCK_OUT(void) //配置成輸出
{GPIO_InitTypeDef GPIO_InitStruct = {0};GPIO_InitStruct.Pin = GPIO_PIN_10;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}#define EE_IIC_SCL(val) HAL_GPIO_WritePin(GPIOB, GPIO_PIN_10,val) //SCL 2.修改引腳即可修改IIC接口
#define EE_IIC_SDA(val) HAL_GPIO_WritePin(GPIOB, GPIO_PIN_11,val) //SDA unsigned char EE_READ_SDA(void)
{
return HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_11);
} /******************************************************************************
*函 數:void EE_IIC_Delay(void)
*功 能:IIC延時
*參 數:無
*返回值:無
*備 注: 移植時只需要將EE_IIC_Delay()換成自己的延時即可
*******************************************************************************/
void EE_IIC_Delay(uint8_t us)
{for(int i = 0; i < 20; i++) {__asm("NOP");//core bus 160M 情況下大概IIC速率 400K}}
/******************************************************************************
*函 數:void IIC_Init(void)
*功 能:IIC初始化
*參 數:無
*返回值:無
*備 注:無
*******************************************************************************/void EE_IIC_Init(void)
{ __HAL_RCC_GPIOB_CLK_ENABLE();EE_SCK_OUT();EE_SDA_OUT();EE_IIC_SCL(1);EE_IIC_SDA(1);}void EE_IIC_Start(void)
{EE_SDA_OUT(); //sda線輸出 EE_IIC_SDA(1); EE_IIC_SCL(1);EE_IIC_Delay(4);EE_IIC_SDA(0); //START:when CLK is high,DATA change form high to low EE_IIC_Delay(4);EE_IIC_SCL(0); //鉗住I2C總線,準備發送或接收數據
}void EE_IIC_Stop(void)
{EE_SDA_OUT(); //sda線輸出EE_IIC_SCL(0);EE_IIC_SDA(0); //STOP:when CLK is high DATA change form low to highEE_IIC_Delay(4);EE_IIC_SCL(1); EE_IIC_SDA(1); //發送I2C總線結束信號EE_IIC_Delay(4);
}uint8_t EE_IIC_WaitAck(void)
{uint8_t ucErrTime=0;EE_SDA_IN(); //SDA設置為輸入 (從機給一個低電平做為應答) EE_IIC_SDA(1);EE_IIC_Delay(1); EE_IIC_SCL(1);EE_IIC_Delay(1);; while(EE_READ_SDA()){ucErrTime++;if(ucErrTime>250){EE_IIC_Stop();return 1;}}EE_IIC_SCL(0); //時鐘輸出0 return 0;
} void EE_IIC_Ack(void)
{EE_IIC_SCL(0);EE_SDA_OUT();EE_IIC_SDA(0);EE_IIC_Delay(1);EE_IIC_SCL(1);EE_IIC_Delay(2);EE_IIC_SCL(0);
}void EE_IIC_NAck(void)
{EE_IIC_SCL(0);EE_SDA_OUT();EE_IIC_SDA(1);EE_IIC_Delay(1);EE_IIC_SCL(1);EE_IIC_Delay(1);EE_IIC_SCL(0);
} void EE_IIC_SendByte(uint8_t data)
{ uint8_t t; EE_SDA_OUT(); EE_IIC_SCL(0); //拉低時鐘開始數據傳輸for(t=0;t<8;t++){ EE_IIC_SDA((data&0x80)>>7);EE_IIC_Delay(1); EE_IIC_SCL(1);data<<=1;EE_IIC_Delay(1);EE_IIC_SCL(0); }EE_IIC_Delay(1);
} uint8_t EE_IIC_ReadByte(uint8_t ack)
{uint8_t i,receive=0;EE_SDA_IN(); //SDA設置為輸入模式 等待接收從機返回數據for(i=0;i<8;i++ ){EE_IIC_SCL(0); EE_IIC_Delay(1);EE_IIC_SCL(1);receive<<=1;if(EE_READ_SDA())receive++; //從機發送的電平EE_IIC_Delay(1); } if(ack)EE_IIC_Ack(); //發送ACK elseEE_IIC_NAck(); //發送nACK return receive;
}uint8_t EE_IIC_ReadByteFromSlave(uint8_t I2C_Addr,uint8_t reg,uint8_t *buf)
{EE_IIC_Start(); EE_IIC_SendByte(I2C_Addr); //發送從機地址if(EE_IIC_WaitAck()) //如果從機未應答則數據發送失敗{EE_IIC_Stop();return 1;}EE_IIC_SendByte(reg); //發送寄存器地址EE_IIC_WaitAck(); EE_IIC_Start();EE_IIC_SendByte(I2C_Addr+1); //進入接收模式 EE_IIC_WaitAck();*buf=EE_IIC_ReadByte(0); EE_IIC_Stop(); //產生一個停止條件return 0;
}uint8_t EE_EE_IIC_SendByteToSlave(uint8_t I2C_Addr,uint8_t reg,uint8_t data)
{EE_IIC_Start();EE_IIC_SendByte(I2C_Addr); //發送從機地址if(EE_IIC_WaitAck()){EE_IIC_Stop();return 1; //從機地址寫入失敗}EE_IIC_SendByte(reg); //發送寄存器地址EE_IIC_WaitAck(); EE_IIC_SendByte(data); if(EE_IIC_WaitAck()){EE_IIC_Stop(); return 1; //數據寫入失敗}EE_IIC_Stop(); //產生一個停止條件return 0;
}
五.CubeMX工程源代碼下載
鏈接:https://pan.baidu.com/s/1MMYww6IgUNa3wPaN-pWqdw
提取碼:d39f
如果鏈接失效,可以聯系博主給最新鏈接
程序下載下來之后解壓就行
六.講解視頻鏈接地址
IIC總線講解
七.小結
學會使用模擬IIC,能適應各種平臺,不管是STM32的單片機,還是其他牌子的單片機,都能很快實現對EEPROM等IIC總線的設備進行數據讀寫。