衡阳派盒市场营销有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

MM32F0140 MCU關于I2C的介紹、配置及實驗

海闊天空的專欄 ? 來源:靈動MM32MCU ? 作者:靈動MM32MCU ? 2022-05-20 17:08 ? 次閱讀

I2C簡介

I2C總線是一個兩線串行接口,包含串行數據線(SDA)與串行時鐘線(SCL),能夠在連接到總線的器件間傳遞信息,每一個連接總線的設備都有獨立的地址,主機可以通過該地址選擇連接總線的設備并與之通信。I2C通過對SCL和SDA線高低電平時序的控制,來產生I2C總線協議所需要的信號,從而進行數據傳輸,微控制器可通過I2C總線接口實現芯片間串行互聯。

I2C的功能框圖如圖1所示,當I2C采用主模式進行數據傳輸時,主機先發送從機設備地址與讀寫位數據,在從機地址匹配時可進行數據傳輸;I2C采用從模式時,從設備等待接收由主機發送來的地址數據,地址匹配時可進行數據傳輸。

poYBAGKHWEaAVCkKAADLsTmn1Hk923.png

主機與從機

主機是初始化總線的數據傳輸并產生允許傳輸的時鐘信號的器件。此時,任何被尋址的器件都被認為是從機,在主模式下只支持一個主機。

設備地址

在進行數據傳輸前需要發送從設備地址,只有當主機的發送設備地址與從機的設備地址匹配時才能進行數據傳輸。總線的每個器件都有一個唯一的地址識別,而且都可以作為一個發送或接收器

I2C信號

起始信號

當總線處于空閑狀態時,SCL和SDA同時被外部上拉電阻拉為高電平。當主機啟動數據傳輸時,必須先產生一個起始信號。在SCL線是高電平時, SDA線從高電平向低電平切換表示起始信號,如圖2所示。在起始信號產生后,總線處于忙碌狀態,除當前數據傳輸的主從設備外,其他I2C器件無法訪問總線。

pYYBAGKHWEqAFQ34AACIN5Olxgc566.png

停止信號

停止信號如圖2所示,當主機結束傳輸時要發送停止信號,在SCL線為高電平、SDA線由低電平向高電平切換時,產生停止信號,從而釋放總線,總線再次處于空閑狀態。

應答信號

I2C具有完善的應答機制,當主機發送完成地址與讀寫位或者主機發送一個字節的數據到從機上時,從機會回應一個應答信號(ACK),即在第9個SCL時鐘周期時拉低SDA,如圖3所示。

poYBAGKHWHWAR2NvAABvVwicb2o015.png

非應答信號

如圖3所示,當第9個SCL時鐘周期時拉高SDA,表示為非應答信號,主機或從機將產生一個停止信號中止傳輸。

讀寫位

在傳輸設備地址時會跟隨1bit的讀寫位數據,該讀寫位決定當前數據傳輸方向。如圖4所示,起始信號后發送從設備地址及讀寫位數據,當讀寫位為1時,執行讀操作;讀寫位為0時,執行寫操作。

pYYBAGKHWHuAT43jAAFUGXwXtbk059.png

I2C配置

I2C的配置包括傳輸速率、從設備地址、數據傳輸方向及主從模式選擇的配置,從而進行數據傳輸。

工作速率

I2C存在兩種工作速率模式:標準模式(數據傳輸速率為0 ~ 100Kbps),快速模式(數據傳輸速率最大為400Kbps);可通過I2C控制寄存器(I2C_CR)的SPEED位進行控制,由于I2C從機速率跟隨主機速率,因此只需在I2C為主模式下配置工作速率,如圖5所示。

poYBAGKHWMaAP71YAACZwGvsds0480.png

地址格式

I2C有兩種地址格式:7位地址格式和10位地址格式。

7位地址

如圖6所示,在起始條件(S)后發送的一個字節的前7位(A6 ~ A0)為從機地址,最低位(R/W)是數據方向位,當R/W位為0,表示主機寫數據到從機,R/W位為1表示主機從從機讀數據。

pYYBAGKHWMuABBZGAACu68oR-S4913.png

10位地址

在10位的地址格式中,發送2個字節來傳輸10位地址。發送的第一個字節的起始位后的5位(bit7:3)用于告示從機接下來是10位的傳輸,第一個字節的后兩位(bit2:1)是從機地址的bit9:8,最低位(bit 0)是數據方向位(R/W)。傳輸的第二個字節為10位地址的低八位,如圖7所示。

poYBAGKHWO2Aarr2AACSVE7LJl4662.png

寫操作

I2C進行寫操作時,先通過I2C目標地址寄存器(I2C_TAR)配置從設備地址,再配置讀寫位,令控制數據命令寄存器(I2C_DR)的CMD位為0,所需傳輸數據放入I2C_DR寄存器的DR位,進行寫操作。

讀操作

I2C進行讀操作時,先由主機寫從設備地址及設備內寄存器地址,當從設備地址及設備內寄存器地址發送完成后,將控制數據命令寄存器(I2C_DR)的CMD位為1,進行讀操作,讀出設備內寄存器地址中的數值。

poYBAGKHWPOAMtkdAABzOhFaN3M167.png

主模式

I2C主模式配置需在I2C未使能狀態下進行,將I2C使能寄存器(I2C_IMR)的ENABLE位置0。通過配置控制寄存器(I2C_CR)的SPEED位選擇速率模式,MASTER10位選擇地址格式,DISSLAVE位為1使從模式禁止,MASTER位為1選擇主模式。向目標地址寄存器(I2C_TAR)寫入從設備地址,I2C_IMR寄存器的ENABLE位置1,使能I2C。

I2C 接口支持讀寫的動態切換,當發送數據時,寫數據到I2C的RX/TX數據緩沖及命令寄存器(DR)的低字節中,配置CMD位為0產生寫操作。接下來的讀命令,需要確保CMD位為1。如果發送FIFO為空,I2C模塊拉低SCL直到下個命令寫入到發送FIFO中。

從模式

I2C做從機時,等待其他主機的訪問,只有其他主機發送了I2C從機對應的設備地址,才能進行數據傳輸。配置I2C為從模式,將I2C使能寄存器(I2C_IMR)的ENABLE位置0,禁止I2C使能,將I2C自身從地址寫入從機地址寄存器(I2C_SAR),配置控制寄存器(I2C_CR)的SLAVE10選擇尋址格式,DISSLAVE位為0,選擇從模式,MASTER位為0,禁止主模式;I2C_IMR寄存器的ENABLE位置1,使能I2C。

當其他主機發送地址與 SAR 寄存器中的從機地址匹配,I2C接口響應發送的地址,并識別傳輸方向;當I2C產生讀請求,從機將數據發送至主機;當主機為寫操作時,I2C從機接收到主機的數據并將數據存儲在接收緩沖中,軟件通過讀DR寄存器中的bit7:0來獲得接收到的數據。

實驗

本實驗使用輪詢進行數據的寫操作與讀操作,初始化配置I2C為主模式,從設備地址為0x50,速率為100KHz,使用7位地址格式。I2C初始化后,按下一次任意按鍵,進行8字節數據的寫操作,其中第一字節寫入數據設置為設備內的寄存器地址,串口顯示寫入數據;寫操作完成后,再次按下任意按鍵,進行7位數據的讀操作,從設備的寄存器地址中讀出相關數據。

啟用I2C外設時鐘 enable_clock()

實驗使用I2C1,串口打印輸出結果,串口使用引腳屬于GPIOA組,I2C使用引腳屬于GPIOB組,因此需要啟用I2C1、UART1、GPIOA及GPIOB的外設時鐘。

voidenable_clock()
{
/*EnableI2C1clock.*/
RCC->APB1ENR|=RCC_APB1_PERIPH_I2C1;
/*EnableGPIOAclock.*/
RCC->AHB1ENR|=RCC_AHB1_PERIPH_GPIOA;
/*EnableGPIOBclock.*/
RCC->AHB1ENR|=RCC_AHB1_PERIPH_GPIOB;
/*EnableUART1clock.*/
RCC->APB2ENR|=RCC_APB2_PERIPH_UART1;
}

配置引腳 pin_init()

配置I2C1引腳,I2C1_SCL為PB6引腳,I2C1_SDA為PB7引腳,復用通道為AF1;由于實驗現象通過串口顯示,故配置UART的TX(PA9)與RX(PA10)引腳。

voidpin_init()
{
/*PB6-I2C1_SCL.*/
GPIOB->CRL&=~GPIO_CRL_MODE6_MASK;
GPIOB->CRL&=~GPIO_CRL_CNF6_MASK;
GPIOB->CRL|=GPIO_CRL_MODE6(GPIO_Speed_50MHz);
GPIOB->CRL|=GPIO_CRL_CNF6(GPIO_PinMode_AF_OpenDrain);
GPIOB->AFRL&=~GPIO_AFRL_AFRY_MASK;
GPIOB->AFRL|=(GPIO_AF_1<

/*PB7-I2C1_SDA.*/
GPIOB->CRL&=~GPIO_CRL_MODE7_MASK;
GPIOB->CRL&=~GPIO_CRL_CNF7_MASK;
GPIOB->CRL|=GPIO_CRL_MODE7(GPIO_Speed_50MHz);
GPIOB->CRL |= GPIO_CRL_CNF7(GPIO_PinMode_AF_OpenDrain);
GPIOB->AFRL|=(GPIO_AF_1<

/*PA9-UART_TX.*/
GPIOA->CRH&=~GPIO_CRH_MODE9_MASK;
GPIOA->CRH&=~GPIO_CRH_CNF9_MASK;
GPIOA->CRH|=GPIO_CRH_MODE9(GPIO_Speed_50MHz);
GPIOA->CRH|=GPIO_CRH_CNF9(GPIO_PinMode_AF_PushPull);
GPIOA->AFRH|=(GPIO_AF_1<

/*PA10-UART_RX.*/
GPIOA->CRH&=~GPIO_CRH_MODE10_MASK;
GPIOA->CRH&=~GPIO_CRH_CNF10_MASK;
GPIOA->CRH|=GPIO_CRH_CNF10(GPIO_PinMode_In_Floating);
GPIOA->AFRH|=(GPIO_AF_1<
}

UART初始化 uart_init()

初始化UART,配置時鐘頻率、波特率、數據長度、停止位、傳輸模式及是否使用校驗。

voiduart_init()
{
/*Clearthecorrespondingbittobeused.*/
UART1->CCR&=~(UART_CCR_PEN_MASK|UART_CCR_PSEL_MASK|UART_CCR_SPB0_MASK|UART_CCR_SPB1_MASK|UART_CCR_CHAR_MASK);
UART1->GCR&=~(UART_GCR_AUTOFLOWEN_MASK|UART_GCR_RXEN_MASK|UART_GCR_TXEN_MASK);
/*WordLength.*/
UART1->CCR|=UART_CCR_CHAR_MASK;
/*XferMode.*/
UART1->GCR|=(UART_XferMode_RxTx<
/*Setupbaudrate,BOARD_DEBUG_UART_FREQ=48000000u,BOARD_DEBUG_UART_BAUDRATE=9600u.*/
UART1->BRR=(BOARD_DEBUG_UART_FREQ/BOARD_DEBUG_UART_BAUDRATE)/16u;
UART1->FRA=(BOARD_DEBUG_UART_FREQ/BOARD_DEBUG_UART_BAUDRATE)%16u;
/*EnableUART1.*/
UART1->GCR|=UART_GCR_UARTEN_MASK;
}

I2C初始化 i2c_init()

I2C通過操作配置寄存器(I2C_CR)實現初始化,配置I2C為主模式、速率為100KHz、7位地址格式、時鐘頻率為60000000u,設置從設備地址為0x50,使能I2C。

voidi2c_init()
{
I2C1->ENR&=~I2C_ENR_ENABLE_MASK;
uint32_ttmp=BOARD_I2C_FREQ/I2C_BaudRate_100K;/*BOARD_I2C_FREQ=60000000u,I2C_BaudRate_100K=100000u.*/
I2C1->SSHR=tmp/2u-12u;/*Configurehighlevelcountinnormalspeed.*/
I2C1->SSLR=tmp/2u-1u; /*Configurelowlevelcountinnormalspeed.*/
I2C1->CR=I2C_CR_SPEED(1u);
I2C1->CR&=~I2C_CR_MASTER10_MASK; /*Addressformat.*/
I2C1->CR|=I2C_CR_RESTART_MASK /*Generaterestartsignal.*/
|I2C_CR_DISSLAVE_MASK /*Disableslavemodule.*/
|I2C_CR_REPEN_MASK /*Enablesendingrestartcondition.*/
|I2C_CR_EMPINT_MASK /*Controltx_emptyinterruptgeneration.*/
|I2C_CR_MASTER_MASK; /*Enablemastermodule.*/

I2C1->RXTLR=0u; /*Configurethesendingreceivevalue.*/
I2C1->TXTLR=0u; /*Configurethesendingthresholdvalue.*/

/*Setuptargetaddress.*/
I2C1->TAR=I2C_TAR_ADDR(APP_I2C_TARGET_ADDR);/*APP_I2C_TARGET_ADDR=0x50.*/
I2C1->ENR|=I2C_ENR_ENABLE_MASK; /*EnableI2C.*/
}

I2C寫操作 i2c_write()

設置I2C發送數組i2c_tx_buf及發送數據長度i2c_tx_len,將數組i2c_tx_buf的第一個數值設置為寄存器地址,發送8字節數據。數據發送后讀取狀態寄存器(I2C_SR),等待發送緩沖空,再進行下一次發送;數據傳輸完成,操作使能寄存器的ABORT位為1,使I2C停止數據傳輸;讀清除TX_ABRT中斷寄存器(I2C_TXABRT),將TX FIFO從刷新/復位狀態中釋放。

voidi2c_write()
{
I2C1->DR=I2C_DR_DAT(i2c_tx_buf[0]);
while(0u==(I2C1->SR&I2C_STATUS_TX_EMPTY))
{
}
for(uint32_ti=1u;i
{
I2C1->DR=I2C_DR_DAT(i2c_tx_buf[i]);

while(0u==(I2C1->SR&I2C_STATUS_TX_EMPTY)) /*Waittotxfifoempty.*/
{
}
}
I2C1->ENR|=I2C_ENR_ABORT_MASK; /*Prepareforthestop.*/
I2C1->TXABRT; /*Readregistertoreleasetxfifo.*/
while(I2C1->SR&I2C_STATUS_ACTIVE) /*WaittoI2Cnotactive,whichmeansstopistakingeffect.*/
{
}
}

I2C讀操作 i2c_read()

設置I2C接收數組i2c_rx_buf及接收長度i2c_rx_len,在進行數據讀取前,需要發送從設備地址及寄存器地址,本實驗設置發送數組的第一個數據為寄存器地址,發送完成后再將I2C_DR寄存器的讀寫位(CMD)置1,讀取I2C_DR寄存器進行讀操作。讀操作結束后,操作使能寄存器的ABORT位為1,使I2C停止數據傳輸。

voidi2c_read()
{
I2C1->DR=I2C_DR_DAT(i2c_tx_buf[0]);
while(0u==(I2C1->SR&I2C_STATUS_TX_EMPTY))
{
}
/*Readdatafromtargetdevice.*/
for(uint32_ti=0u;i
{
I2C1->DR=I2C_DR_CMD_MASK; /*Swichread-writebittoread,preparetogetdata.*/

while(0u==(I2C1->SR&I2C_STATUS_RX_NOTEMPTY)) /*Waittorxfifonotempty.*/
{
}
i2c_rx_buf[i]=(uint8_t)I2C1->DR;
}
I2C1->ENR|=I2C_ENR_ABORT_MASK; /*Prepareforthestop.*/
I2C1->TXABRT; /*Readregistertoreleasetxfifo.*/
while(I2C1->SR&I2C_STATUS_ACTIVE) /*WaittoI2Cnotactive,whichmeansstopistakingeffect.*/
{
}
}

main()函數

main()函數結合上述操作,串口打印“i2c_master_basic example”,初始化I2C后,將發送數組設置為0到7,按下一次任意按鍵,進行數據發送,串口顯示發送數據;再次按下任意按鍵,進行數據讀取,從寄存器地址中讀出數值,設置寄存器地址設置為發送數據的首個數據,串口顯示接收數據,實驗結果如圖9所示。

intmain()
{
enable_clock();
pin_init();
uart_init();
printf("\r\ni2c_master_basicexample\r\n");
i2c_init();
for(uint32_ti=0u;i
{
i2c_tx_buf[i]=i;
}
while(1)
{
printf("pressanykeytowritei2c-eeprom.\r\n");
getchar();
i2c_write();
printf("writedata:");
for(uint32_ti=0u;i
{
printf("0x%02X,",i2c_tx_buf[i]);
}
printf("\r\n");

printf("pressanykeytoreadi2c-eeprom.\r\n");
getchar();
i2c_read();
printf("readdatafromdeviceregisteraddress:0x%02X\r\n",i2c_tx_buf[0u]);
printf("readdata:");
for(uint32_ti=0u;i
{
printf("0x%02X,",i2c_rx_buf[i]);
}
printf("\r\n");
}

pYYBAGKHWbGAeyxrAACu9-GW9Cs322.png

來源: 靈動MM32MCU

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • mcu
    mcu
    +關注

    關注

    146

    文章

    17317

    瀏覽量

    352631
  • I2C
    I2C
    +關注

    關注

    28

    文章

    1495

    瀏覽量

    124547
  • 靈動微
    +關注

    關注

    4

    文章

    174

    瀏覽量

    22720
  • MM32
    +關注

    關注

    1

    文章

    106

    瀏覽量

    807
收藏 人收藏

    評論

    相關推薦

    I2CMM32F032/MM32F0140系列MCU上的實現

    概述:I2C通訊接口,是我們日常應用中使用最多的MCU外設。最早在MCU沒有硬件I2C之前,都是通過GPIO口模擬I2C的時序來完成
    發表于 09-22 14:22 ?776次閱讀

    基于MM32F0140系列MCU實現UDS Bootloader的設計

    1、使用MM32F0140系列MCU實現UDS Bootloader  MM32F0140 使用高性能的 Arm?Cortex-M0 內核的 32 位微控制器,最高工作頻率可達 72MHz,內置
    發表于 09-15 16:35

    靈動微MM32F0140可替換瑞薩單片機LPC11C14

    靈動微 超值型MM32F0140系列MCU是靈動第一款基于12寸晶圓打造的產品系列,其搭載72兆赫茲,Arm Cortex-M0內核,提供最高64KB Flash和8KB SRAM,并集成了性能升級
    發表于 01-12 15:18 ?752次閱讀

    AN0052從MM32F0130移植到MM32F0140(英文版)

    AN0052 從MM32F0130移植到MM32F0140(英文版)
    發表于 02-22 18:43 ?0次下載
    AN0052從<b class='flag-5'>MM32F</b>0130移植到<b class='flag-5'>MM32F0140</b>(英文版)

    MM32F0140 產品手冊(中文版)

    MM32F0140 產品手冊(中文版)
    發表于 02-22 18:45 ?0次下載
    <b class='flag-5'>MM32F0140</b> 產品手冊(中文版)

    MM32F0140 用戶手冊(英文版)

    MM32F0140 用戶手冊(英文版)
    發表于 02-22 18:46 ?0次下載
    <b class='flag-5'>MM32F0140</b> 用戶手冊(英文版)

    MM32F0140 勘誤表(中文版)

    MM32F0140 勘誤表(中文版)
    發表于 02-22 18:47 ?0次下載
    <b class='flag-5'>MM32F0140</b> 勘誤表(中文版)

    MM32F0140 勘誤表(英文版)

    MM32F0140 勘誤表(英文版)
    發表于 02-22 18:48 ?0次下載
    <b class='flag-5'>MM32F0140</b> 勘誤表(英文版)

    基于MM32F0140的UDS Bootloader學習筆記

    基于MM32F0140的UDS Bootloader學習筆記
    的頭像 發表于 10-30 17:11 ?820次閱讀
    基于<b class='flag-5'>MM32F0140</b>的UDS Bootloader學習筆記

    MM32F0140學習筆記——CRC

    MM32F0140學習筆記——CRC
    的頭像 發表于 11-10 18:27 ?689次閱讀
    <b class='flag-5'>MM32F0140</b>學習筆記——CRC

    MM32F0140 FlexCAN一致性測試 (2)

    MM32F0140 FlexCAN一致性測試 (2)
    的頭像 發表于 11-10 18:23 ?725次閱讀
    <b class='flag-5'>MM32F0140</b> FlexCAN一致性測試 (<b class='flag-5'>2</b>)

    MM32F0140 SPI學習筆記

    MM32F0140 SPI學習筆記
    的頭像 發表于 09-26 16:51 ?641次閱讀
    <b class='flag-5'>MM32F0140</b> SPI學習筆記

    MM32F0140 DMA學習筆記

    MM32F0140 DMA 學習筆記
    的頭像 發表于 09-18 16:57 ?752次閱讀
    <b class='flag-5'>MM32F0140</b> DMA學習筆記

    MM32F0140 UART學習筆記

    MM32F0140 UART學習筆記
    的頭像 發表于 09-26 16:45 ?805次閱讀
    <b class='flag-5'>MM32F0140</b> UART學習筆記

    MM32F0140 GPIO學習筆記

    MM32F0140 GPIO學習筆記
    的頭像 發表于 09-26 16:42 ?594次閱讀
    <b class='flag-5'>MM32F0140</b> GPIO學習筆記
    大发888娱乐城官网下载| 百家乐官网技巧平注常赢法| 利辛县| 大发888大发888体育| 大发888ber| 手机棋牌游戏| 电动扑克| 安岳县| 百家乐官网视频双扣游戏| 挖掘百家乐赢钱秘籍| 百家乐推广| 网上百家乐记牌软件| 百家乐筹码托盘| 大发888娱乐场下载iypu| 澳门体育博彩| 遵义县| 百家乐官网如何投注法| 大发888官方指定下载| 澳门赌场招聘网| 百家乐官网视频计牌器| 百家乐官网正品地址| 风水学坐向24山| 搓牌百家乐技巧| 大发888娱乐城下载新澳博| 投注平台网| 澳门百家乐官网真人版| 明珠百家乐官网的玩法技巧和规则| 百家乐游戏开发技术| 百家乐牡丹娱乐城| 百家乐官网大路小路三珠路| 做生意的十大风水禁忌 | 百家乐官网最新心得| 狮威百家乐官网娱乐| 新2百家乐现金网百家乐现金网| 百家乐下注法| 大发888老虎机苹果版| 虚拟百家乐官网游戏下载| 百家乐官网如何赚洗码| 博狗百家乐的玩法技巧和规则| bet365官网| 百家乐官网真人游戏娱乐网|