最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊

CW32單片機(jī)I2C接口讀寫EEPROM芯片介紹

2023-04-12 10:48 作者:武漢芯源半導(dǎo)體  | 我要投稿

一、概述

CW32L083 內(nèi)部集成 2 個(gè) I2C 控制器,能按照設(shè)定的傳輸速率(標(biāo)準(zhǔn),快速,高速)將需要發(fā)送的數(shù)據(jù)按照 I2C 規(guī)范串行發(fā)送到 I2C 總線上,或從總線上接收數(shù)據(jù),并對通信過程中的狀態(tài)進(jìn)行檢測,另外還支持多主機(jī)通信中的總線沖突和仲裁處理。


二、主要功能

? 支持主機(jī)發(fā)送 / 接收,從機(jī)發(fā)送 / 接收四種工作模式?

? 支持時(shí)鐘延展 ( 時(shí)鐘同步 ) 和多主機(jī)通信沖突仲裁

? 支持標(biāo)準(zhǔn) (100Kbps)/ 快速 (400Kbps)/ 高速 (1Mbps) 三種工作速率?

? 支持 7bit 尋址功能?

? 支持 3個(gè)從機(jī)地址?

? 支持廣播地址?

? 支持輸入信號噪聲過濾功能?

? 支持中斷狀態(tài)查詢功能


1.協(xié)議介紹

I2C 總線使用兩根信號線(數(shù)據(jù)線 SDA 和時(shí)鐘線 SCL)在設(shè)備間傳輸數(shù)據(jù)。SCL 為單向時(shí)鐘線,固定由主機(jī)驅(qū)動(dòng)。SDA 為雙向數(shù)據(jù)線,在數(shù)據(jù)傳輸過程中由收發(fā)兩端分時(shí)驅(qū)動(dòng)。I2C 總線上可以連接多個(gè)設(shè)備,所有設(shè)備在沒有進(jìn)行數(shù)據(jù)傳輸時(shí)都處于空閑狀態(tài)(未尋址從機(jī)接收模式),任一設(shè)備都可以作為主機(jī)發(fā)送 START 起始信號來開始數(shù)據(jù)傳輸,在 STOP 停止信號出現(xiàn)在總線上之前,總線一直處于 被占用狀態(tài)。I2C 通信采用主從結(jié)構(gòu),并由主機(jī)發(fā)起和結(jié)束通信。主機(jī)通過發(fā)送 START 起始信號來發(fā)起通信,之后發(fā)送 SLA+W/R 共 8bit 數(shù)據(jù)(其中,SLA 為 7bit 從機(jī)地址,W/R 為讀寫位),并在第 9個(gè)SCL 時(shí)鐘釋放 SDA 總線, 對應(yīng)的從機(jī)在第 9個(gè)SCL 時(shí)鐘占用 SDA 總線并輸出 ACK 應(yīng)答信號,完成從機(jī)尋址。此后根據(jù)主機(jī)發(fā)送的第 1 字 節(jié)的 W/R 位來決定數(shù)據(jù)通信的發(fā)端和收端,發(fā)端每發(fā)送 1個(gè)字節(jié)數(shù)據(jù),收端必須回應(yīng) 1個(gè)ACK 應(yīng)答信號。數(shù)據(jù)傳輸完成后,主機(jī)發(fā)送 STOP 信號結(jié)束本次通信。


2.功能框圖

I2C 模塊主要包括時(shí)鐘發(fā)生器、輸入濾波器、地址比較器、協(xié)議控制邏輯、仲裁和同步邏輯、以及相關(guān)寄存器等。

圖片

CW32L083 支持用戶靈活選擇 GPIO 作為 I2C 通信引腳,如下表所示:

圖片


3.I2C中斷

I2C 控制寄存器 I2Cx_CR 的 SI 位域?yàn)橹袛鄻?biāo)志位。當(dāng) I2C 狀態(tài)寄存器 I2Cx_STAT 的 STAT 位域值發(fā)生改變(變成 0xF8 除外)時(shí),I2Cx_CR.SI 標(biāo)志位就會(huì)被置位,同時(shí)產(chǎn)生中斷請求。在用戶 I2C 中斷服務(wù)程序中,應(yīng)查詢 I2C 狀態(tài)寄存器 I2Cx_STAT 的 STAT 位域值獲取 I2C 總線的狀態(tài),以確定中斷產(chǎn)生原因。設(shè)置 I2Cx_CR.SI 為 0 清除該標(biāo)志位。


4.工作模式

I2C 控制器支持 4 種工作模式:主機(jī)發(fā)送模式、主機(jī)接收模式、從機(jī)發(fā)送模式、從機(jī)接收模式。另外還支持廣播 接收模式,其工作方式和從機(jī)接收模式類似。


三、EEPROM(CW24C02AD)

1.功能簡介

CW24C02是一個(gè)2Kbit的串行EEPROM存儲(chǔ)芯片,可存儲(chǔ)256個(gè)字節(jié)數(shù)據(jù)。芯片內(nèi)部分為32頁,每頁8字節(jié)。工作電壓范圍為1.7V到5.5V,I2C接口時(shí)鐘頻率為 1MHz (5V,3V),400 KHz (1.7V)。器件地址為1010 A2 A1 A0,對于我們單板A2 A1 A0引腳全部接GND,故器件地址為1010000,即0x50。器件內(nèi)部存儲(chǔ)空間地址長度8 bit。


2.讀寫時(shí)序

字節(jié)寫操作時(shí)序:起始信號+器件地址(7bit)+讀寫指示(1bit)+存儲(chǔ)空間地址(8bit)+寫入數(shù)據(jù)(8bit)+停止信號,即可完成指定字節(jié)寫入操作。


頁寫操作時(shí)序:起始信號+器件地址(7bit)+讀寫指示(1bit)+存儲(chǔ)空間地址(8bit)+寫入數(shù)據(jù)(8bit*8)+停止信號,即可完成指定地址(必須是頁起始地址)的頁寫入操作。


隨機(jī)讀操作時(shí)序:起始信號+器件地址(7bit)+讀寫指示(1bit)+存儲(chǔ)空間地址(8bit)+重復(fù)起始信號+器件地址(7bit)+讀寫指示(1bit),之后器件會(huì)返回1字節(jié)數(shù)據(jù),主機(jī)收到后發(fā)送停止信號,即可完成指定字節(jié)讀取操作。



順序讀操作時(shí)序:和隨機(jī)讀時(shí)序類似,只是在主機(jī)接收到1字節(jié)數(shù)據(jù)后,不發(fā)送停止信號,而是繼續(xù)發(fā)送時(shí)鐘進(jìn)行下一個(gè)字節(jié)數(shù)據(jù)的接收,直到所有所需讀取的數(shù)據(jù)全部讀取,之后再發(fā)送停止信號。



四、硬件連接

如下圖所示,MCU和EEPROM通過I2C總線互連。



五、實(shí)例演示:MCU采用頁寫和順序讀操作時(shí)序完成EERPOM的訪問。

1.I2C讀寫EEPROM芯片中斷函數(shù)(I2C分為I2C1和I2C2)

void I2c1EepromReadWriteInterruptFunction(void)

{

? ? u8State = I2C_GetState(CW_I2C1);// I2C:獲取狀態(tài)寄存器函數(shù)

? ? switch(u8State)

? ? {

? ? ? ? case 0x08:? ? ?//發(fā)送完START信號

? ? ? ? ? ? I2C_GenerateSTART(CW_I2C1, DISABLE);// 發(fā)送START信號

? ? ? ? ? ? I2C_Send7bitAddress(CW_I2C1, I2C_SLAVEADDRESS,0X00);// 做主時(shí)發(fā)送從機(jī)地址字節(jié)

? ? ? ? ? ? break;

? ? ? ? case 0x10:? ? ?//發(fā)送完重復(fù)起始信號

? ? ? ? ? ? I2C_GenerateSTART(CW_I2C1, DISABLE);

? ? ? ? ? ? if(0 == SendFlg)

? ? ? ? ? ? {

? ? ? ? ?I2C_Send7bitAddress(CW_I2C1, I2C_SLAVEADDRESS,0X00);? ? //寫命令

? ? ? ? ? ? }

? ? ? ? ? ? else

? ? ? ? ? ? {

? ? ? ? ?I2C_Send7bitAddress(CW_I2C1, I2C_SLAVEADDRESS,0X01); //讀命令,eeprom 隨機(jī)讀

? ? ? ? ? ? }

? ? ? ? ? ? break;

? ? ? ? case 0x18:? ? //發(fā)送完SLA+W/R字節(jié)

? ? ? ? ? ? I2C_GenerateSTART(CW_I2C1, DISABLE);

? ? ? ? ? ? I2C_SendData(CW_I2C1, u8Addr);? ?//發(fā)送訪問EEPROM的目標(biāo)地址字節(jié)

? ? ? ? ? ? break;

? ? ? ? case 0x20:? ? //發(fā)送完SLA+W后從機(jī)返回NACK

? ? ? ? case 0x38:? ? //主機(jī)在發(fā)送 SLA+W 階段或者發(fā)送數(shù)據(jù)階段丟失仲裁? 或者? 主機(jī)在發(fā)送 SLA+R 階段或者回應(yīng) NACK 階段丟失仲裁

? ? ? ? case 0x30:? ? //發(fā)送完一個(gè)數(shù)據(jù)字節(jié)后從機(jī)返回NACK

? ? ? ? case 0x48:? ? //發(fā)送完SLA+R后從機(jī)返回NACK

? ? ? ? ? ? I2C_GenerateSTOP(CW_I2C1, ENABLE);

? ? ? ? ? ? I2C_GenerateSTART(CW_I2C1, ENABLE);

? ? ? ? ? ? break;

? ? ? ? case 0x58:? ? //接收到一個(gè)數(shù)據(jù)字節(jié),且NACK已回復(fù)

? ? ? ? ? ? u8Recdata[u8RecvLen++] = I2C_ReceiveData(CW_I2C1);//所有數(shù)據(jù)讀取完成,NACK已發(fā)送

? ? ? ? ? ? receivedflag =1;

? ? ? ? ? ? I2C_GenerateSTOP(CW_I2C1, ENABLE);//發(fā)送停止條件

? ? ? ? ? ? break;

? ? ? ? case 0x28:? ? ?//發(fā)送完1字節(jié)數(shù)據(jù):發(fā)送EEPROM中memory地址也會(huì)產(chǎn)生,發(fā)送后面的數(shù)據(jù)也會(huì)產(chǎn)生

? ? ? ? ? ? if(0 == SendFlg)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? if(u8SendLen <WRITELEN)

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? I2C_SendData(CW_I2C1,u8Senddata[u8SendLen++]);

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? else

? ? ? ? ? ? ? ? {

? ? ? ? ? ? ? ? ? ? u8SendLen = 0;

? ? ? ? ? ? ? ? ? ? Comm_flg = 1;

? ? ? ? ? ? ? ? ? ? SendFlg = 1;

? ? ? ? ? ? ? ? ? ? I2C_GenerateSTOP(CW_I2C1, ENABLE);//發(fā)送完數(shù)據(jù),發(fā)送停止信號

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? ?else//SendFlg=1為讀,SendFlg=0為寫。讀數(shù)據(jù)發(fā)送完地址字節(jié)后,重復(fù)起始條件

? ? ? ? ? ? {

? ? ? ? ? ? ? ? CW_I2C1->CR_f.STA = 1;? //set start? ? ? ?//發(fā)送重復(fù)START信號,START生成函數(shù)改寫后,會(huì)導(dǎo)致0X10狀態(tài)被略過,故此處不調(diào)用函數(shù)

? ? ? ? ? ? ? ? I2C_GenerateSTOP(CW_I2C1, DISABLE);

? ? ? ? ? ? }

? ? ? ? ? ? break;


? ? ? ? case 0x40:? ? ?//發(fā)送完SLA+R信號,開始接收數(shù)據(jù)

? ? ? ? ? ? u8RecvLen = 0;

? ? ? ? ? ? if(READLEN>1)

? ? ? ? ? ? {

? ? ? ? ? ? I2C_AcknowledgeConfig(CW_I2C1,ENABLE);//讀取數(shù)據(jù)超過1個(gè)字節(jié)才發(fā)送ACK

? ? ? ? ? ? }

? ? ? ? ? ? break;

? ? ? ? case 0x50:? ? ?//接收完一字節(jié)數(shù)據(jù),在接收最后1字節(jié)數(shù)據(jù)之前設(shè)置AA=0;

? ? ? ? ? ? u8Recdata[u8RecvLen++] = I2C_ReceiveData(CW_I2C1);

? ? ? ? ? ? if(u8RecvLen==READLEN-1)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? I2C_AcknowledgeConfig(CW_I2C1,DISABLE);;

? ? ? ? ? ? }

? ? ? ? ? ? break;

? ? }

? ? I2C_ClearIrq(CW_I2C1);

}


2.設(shè)置系統(tǒng)時(shí)鐘

void RCC_Configuration(void)

{

? ? CW_SYSCTRL->APBEN1_f.I2C1 = 1U;? ?

}


3.設(shè)置GPIO口

void GPIO_Configuration(void)

{

? ? GPIO_InitTypeDef GPIO_InitStructure = {0};

? ? CW_SYSCTRL->AHBEN_f.GPIOA? = 1;

? ? CW_SYSCTRL->AHBEN_f.GPIOB? = 1;

? ? CW_SYSCTRL->AHBEN_f.GPIOC? = 1;

? ? CW_SYSCTRL->AHBEN_f.GPIOD? = 1;

? ? CW_SYSCTRL->AHBEN_f.GPIOE? = 1;

? ? CW_SYSCTRL->AHBEN_f.GPIOF? = 1;


? ? PB10_AFx_I2C1SCL();

? ? PB11_AFx_I2C1SDA();

? ? GPIO_InitStructure.Pins = I2C1_SCL_GPIO_PIN | I2C1_SDA_GPIO_PIN;

? ? GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;

? ? GPIO_Init(I2C1_SCL_GPIO_PORT, &GPIO_InitStructure);

}


4.配置嵌套矢量中斷控制器

void NVIC_Configuration(void)

{

? ? __disable_irq();

? ? NVIC_EnableIRQ(I2C1_IRQn);

? ? __enable_irq();

}

void I2C1_IRQHandler(void)

{

? ? I2c1EepromReadWriteInterruptFunction();

}


5.定義常量

#define? I2C1_SCL_GPIO_PORT? ? ? ?CW_GPIOB

#define? I2C1_SCL_GPIO_PIN? ? ? ? GPIO_PIN_10? ?

#define? I2C1_SDA_GPIO_PORT? ? ? ?CW_GPIOB

#define? I2C1_SDA_GPIO_PIN? ? ? ? GPIO_PIN_11? ??

//EEPROM內(nèi)部地址

uint8_t u8Addr = 0x00;? ? ? ? //地址字節(jié)

#define WRITELEN? ?8? ? ? ? ? //寫數(shù)據(jù)長度

#define READLEN? ?8? ? ? ? ? ?//讀數(shù)據(jù)長度

#define WriteReadCycle? 35? ? //寫讀次數(shù),每次寫入數(shù)據(jù)為n+i(n為次數(shù),i=0~7)


uint8_t u8Senddata[8] = {0x66,0x02,0x03,0x04,0x05,0x60,0x70,0x20};

uint8_t u8Senddata2[8] = {0x55,0xAA,0xAA,0x55,0x55,0xAA,0x55,0xAA};

uint8_t u8Recdata[16]= {0x00};

uint8_t u8SendLen=0;

uint8_t u8RecvLen=0;

uint8_t SendFlg = 0,Comm_flg = 0;

uint8_t u8recvflg=0;

uint8_t u8State = 0;

uint8_t receivedflag = 0;? ? //讀取完成標(biāo)志


6.主程序:利用I2C接口,采用中斷方式讀寫EEPROM芯片(CW24C02)。

int32_t main(void)

{

? ? I2C_InitTypeDef I2C_InitStruct = {0};

? ? uint16_t tempcnt = 0 ;

? ? RCC_Configuration();//時(shí)鐘初始化

? ? GPIO_Configuration();//IO口初始化

? ? //I2C初始化

? ? I2C_InitStruct.I2C_Baud = 0x01;//500K=(8000000/(8*(1+1)) ,波特率計(jì)數(shù)器配置

? ? I2C_InitStruct.I2C_BaudEn = ENABLE;// 波特率計(jì)數(shù)器使能

? ? I2C_InitStruct.I2C_FLT = DISABLE; //<FLT配置

? ? I2C_InitStruct.I2C_AA =? DISABLE; //<ACK配置

? ? I2C1_DeInit();

? ? I2C_Master_Init(CW_I2C1,&I2C_InitStruct);//初始化模塊

? ? NVIC_Configuration();//中斷設(shè)置

? ? //I2C模塊開始工作

? ? I2C_Cmd(CW_I2C1,ENABLE);? //模塊使能

? ? tempcnt =0;

? ? for(uint8_t i=0; i<8; i++)

? ? {

? ? ? ? u8Senddata[i] = i;

? ? }

? ? while(1)

? ? {

? ? ? ? I2C_GenerateSTART(CW_I2C1, ENABLE); //開始信號

? ? ? ? while(1)

? ? ? ? {

? ? ? ? ? ?

? ? ? ? ? ? while(!Comm_flg) ; //等待數(shù)據(jù)發(fā)送完成

? ? ? ? ? ? FirmwareDelay(3000);

? ? ? ? ?

? ? ? ? ? ? Comm_flg = 0; //啟動(dòng)讀數(shù)據(jù)過程

? ? ? ? ? ? receivedflag=0;

? ? ? ? ? ? I2C_GenerateSTART(CW_I2C1, ENABLE); //開始信號

? ? ? ? ? ? while(!receivedflag) ; //等待數(shù)據(jù)讀取完成

? ? ? ? ? ? receivedflag = 0; //初始化下一次寫數(shù)據(jù)

? ? ? ? ? ? SendFlg = 0;

? ? ? ? ? ? u8RecvLen = 0;

? ? ? ? ? ? tempcnt++;

? ? ? ? ? ? for(uint8_t i=0; i<8; i++)

? ? ? ? ? ? {

? ? ? ? ? ? ? ? u8Senddata[i] =tempcnt+i;

? ? ? ? ? ? }

? ? ? ? ? ? break;

? ? ? ? }

? ? ? ??

? ? ? ? if(tempcnt >=WriteReadCycle) //測試次數(shù)完成,退出

? ? ? ? {

? ? ? ? ? ? break;

? ? ? ? }

? ? }

? ? while(1);

}


7.程序流程

程序完成I2C主設(shè)備配置后,先將u8Senddata數(shù)組中的內(nèi)容寫入到EEPROM的第1頁(CW24C02每頁8字節(jié)):發(fā)送START信號后,I2C模塊會(huì)產(chǎn)生狀態(tài)改變中斷,在中斷服務(wù)程序中根據(jù)不同狀態(tài)值進(jìn)行不同處理,直到完成CW24C02的頁寫模式所有數(shù)據(jù)字節(jié)以及STOP信號發(fā)送,發(fā)送完成后置寫操作流程完成標(biāo)志。主循環(huán)中判斷到寫操作流程完成后,啟動(dòng)從EERROM的第1頁數(shù)據(jù)讀取流程:發(fā)送啟動(dòng)信號后,I2C模塊會(huì)產(chǎn)生狀態(tài)改變中斷,在中斷服務(wù)程序中根據(jù)不同狀態(tài)值進(jìn)行不同處理,直到完成CW24C02的順序讀模式所有數(shù)據(jù)字節(jié)發(fā)送及讀取,在發(fā)送完STOP信號后置讀操作流程完成標(biāo)志。主循環(huán)中判斷讀操作流程完成后,初始化u8Senddata數(shù)組內(nèi)容,重復(fù)下一次測試過程。完成WriteReadCycle變量設(shè)置的測試次數(shù)后退出。


CW32單片機(jī)I2C接口讀寫EEPROM芯片介紹的評論 (共 條)

分享到微博請遵守國家法律
永泰县| 梅河口市| 美姑县| 乐清市| 密云县| 页游| 五指山市| 云阳县| 中卫市| 密山市| 凤凰县| 偏关县| 子长县| 浑源县| 民丰县| 镇巴县| 格尔木市| 康保县| 工布江达县| 稷山县| 永宁县| 五指山市| 襄樊市| 平顶山市| 临西县| 扎赉特旗| 佳木斯市| 庆阳市| 临泽县| 塔城市| 龙岩市| 科尔| 九江县| 水富县| 时尚| 泾川县| 丰镇市| 远安县| 德阳市| 和静县| 永泰县|