EFM32 硬體I2C操作
有關的例程,請參考如下:
#include "efm32.h" #include "em_chip.h" #include "em_cmu.h" #include "em_emu.h" #include "em_gpio.h" #include "em_i2c.h" #include "I2C_hw.h" unsigned long i2c_error = 0; void I2C_WaitForAck(void); void I2C_Buslock_Process(void); void I2C_IO_Initial(void) { i2c_error = 0; /* Enabling clock to the I2C, GPIO*/ CMU_ClockEnable(cmuClock_GPIO, true); CMU_ClockEnable(cmuClock_I2C0, true); /* Using PC6 (SDA) and PC7 (SCL) */ GPIO_PinModeSet(gpioPortD, 6, gpioModeWiredAndPullUpFilter, 1); GPIO_PinModeSet(gpioPortD, 7, gpioModeWiredAndPullUpFilter, 1); /* Enable pins at location 2 */ I2C0->ROUTE = (I2C_ROUTE_SDAPEN |I2C_ROUTE_SCLPEN |I2C_ROUTE_LOCATION_LOC1); I2C0->CMD = I2C_CMD_CLEARPC | I2C_CMD_CLEARTX | I2C_CMD_ABORT; I2C0->CTRL &= ~_I2C_CTRL_MASK; /* Set the CLHR (clock low to high ratio). */ I2C0->CTRL |= i2cClockHLRStandard <<_I2C_CTRL_CLHR_SHIFT; // Set SCK clock low timeout and bus idle timeout I2C0->CTRL |= I2C_CTRL_CLTO_1024PPC | I2C_CTRL_GIBITO | I2C_CTRL_BITO_160PCC; // Set auto STOP when NACK I2C0->CTRL |= I2C_CTRL_AUTOSN; /* Frequency is given by fSCL = fHFPERCLK/((Nlow + Nhigh)(DIV + 1) + 4), thus */ /* DIV = ((fHFPERCLK - 4fSCL)/((Nlow + Nhigh)fSCL)) - 1 */ //Assume system clock = 1000000, i2c clock = 30kHz; //div = (1000000 - (4 * 30000)) / (8 * 30000) = 3.67 = 4; //CLKDIV = div - 1; I2C0->CLKDIV = 16; NVIC_ClearPendingIRQ(I2C0_IRQn); I2C0->IFC = _I2C_IFC_MASK; //I2C0->IEN = I2C_IEN_ARBLOST | I2C_IEN_CLTO | I2C_IEN_BITO | I2C_IEN_NACK | I2C_IEN_BUSERR; //NVIC_EnableIRQ(I2C0_IRQn); BITBAND_Peripheral(&(I2C0->CTRL),_I2C_CTRL_EN_SHIFT,true); } unsigned char I2C_SentData(unsigned char Address, unsigned short Offset, unsigned char Data) { //Perpare for a new transmit I2C0->CMD = I2C_CMD_ABORT; I2C0->CMD = I2C_CMD_CLEARPC | I2C_CMD_CLEARTX; //Clear all the flags I2C0->IFC = _I2C_IFC_MASK; //Begin to transmit I2C0->CMD = I2C_CMD_START; //Start I2C0->TXDATA = Address | I2C_WRITE_COMMAND; //I2C hardware address I2C_WaitForAck(); I2C0->TXDATA = Offset; //I2C internal address I2C_WaitForAck(); I2C0->TXDATA = Data; //I2C data I2C_WaitForAck(); I2C0->CMD = I2C_CMD_STOP; //Stop unsigned char Result = i2c_error; i2c_error = 0; return Result; } unsigned char I2C_ReadData(unsigned char Address, unsigned short Offset, unsigned char *Rx) { //Perpare for a new transmit I2C0->CMD = I2C_CMD_ABORT; I2C0->CMD = I2C_CMD_CLEARPC | I2C_CMD_CLEARTX; //Clear all the flags I2C0->IFC = _I2C_IFC_MASK; //Begin to transmit I2C0->CMD = I2C_CMD_START; //S I2C0->TXDATA = Address | I2C_WRITE_COMMAND; //AD+W hardware address I2C_WaitForAck(); I2C0->TXDATA = Offset; //internal register address I2C_WaitForAck(); I2C0->CMD = I2C_CMD_START; //S I2C0->TXDATA = Address | I2C_READ_COMMAND; //AD+R internal register address I2C_WaitForAck(); while(!((I2C0->IF) & I2C_IF_RXDATAV)); *Rx = (unsigned char)(I2C0->RXDATA); I2C0->CMD = I2C_CMD_NACK; //NACK I2C0->CMD = I2C_CMD_STOP; //P unsigned char Result = i2c_error; i2c_error = 0; return Result; } void I2C_WaitForAck(void) { while(!((I2C0->IF) & I2C_IF_ACK)) { //STOP auto send if(i2c_error) { break; } } I2C0->IFC = _I2C_IFC_MASK; } void I2C0_IRQHandler(void) { static unsigned char Arblost = 0; unsigned long Flag = I2C0->IF; if(Flag & I2C_IF_NACK) { //auto STOP send i2c_error = 1; } if(Flag & I2C_IF_BUSERR) { I2C0->CMD = I2C_CMD_ABORT; I2C0->CMD = I2C_CMD_CLEARPC | I2C_CMD_CLEARTX; i2c_error = 1; } if(Flag & I2C_IF_ARBLOST) { //arbitration losses, maybe SDA is stuck if(Arblost++ > 5) { Arblost = 0; I2C_Buslock_Process(); } i2c_error = 1; } if((Flag & I2C_IF_CLTO) || (Flag & I2C_IF_BITO)) { I2C_Buslock_Process(); i2c_error = 1; } I2C0->IFC = Flag; } void I2C_Buslock_Process(void) { unsigned long Delay = 1000; //Disable I2C module, and clearing the route register BITBAND_Peripheral(&(I2C0->CTRL),_I2C_CTRL_EN_SHIFT,false); I2C0->ROUTE = 0; //Set as pushpull mode GPIO_PinModeSet(gpioPortD, 6, gpioModePushPull, 1);//SDA GPIO_PinModeSet(gpioPortD, 7, gpioModePushPull, 1);//SCL //send 9 clock of SCL for(unsigned char i = 0; i < 9; i++) { Delay = 3000; GPIO_PinOutClear(gpioPortD, 7); while(Delay--); Delay = 3000; GPIO_PinOutSet(gpioPortD, 7); while(Delay--); } /* Using PD6 (SDA) and PD7 (SCL) */ GPIO_PinModeSet(gpioPortD, 7, gpioModeWiredAndPullUpFilter, 1); GPIO_PinModeSet(gpioPortD, 6, gpioModeWiredAndPullUpFilter, 1); /* Enable pins at location 2 */ I2C0->ROUTE = (I2C_ROUTE_SDAPEN |I2C_ROUTE_SCLPEN |I2C_ROUTE_LOCATION_LOC1); //enable again BITBAND_Peripheral(&(I2C0->CTRL),_I2C_CTRL_EN_SHIFT,true); }
在以上程式碼中,並沒有使能硬體I2C的中斷,因此也不會呼叫I2C_Buslock_Process()函式。另外,針對該函式,目前也還沒有做過功能驗證,我只能通過短接SCL和SDA來測試。
I2C_Buslock_Process()原意是當I2C匯流排死鎖的時候,控制I2C中的SCL時鐘線產生9個時鐘脈衝(針對8位資料的情況),這樣I2C從裝置就可以完成被掛起的讀操作,從死鎖狀態中恢復過來。
在主函式中的呼叫方式如下:I2C_SentData(SLAVE_ADDRESS, PWR_MGMT_1, 0x00);
I2C_ReadData(Address, RegAddress+1, &L);
相關推薦
EFM32 硬體I2C操作
有關的例程,請參考如下: #include "efm32.h" #include "em_chip.h" #include "em_cmu.h" #include "em_emu.h" #include "em_gpio.h" #include "em_i2c.h" #in
STM32硬體I2C除錯
除錯情況1 現象:主I2C傳送資料而沒有收到應答,則下一次不能正常傳送資料 背景:主I2C每次應該都能正常傳送資料 硬體:野火STM32-MINI,1主0從,SCL和SDA直接上拉 軟體:按鍵觸發中斷,主I2C傳送一次資料,中斷優先順序,按鍵最低,I2C最高,且主I2C中有TIMEOUT計時
STM32微控制器硬體I2C驅動程式(查詢方式)
本文章原始地址:http://feotech.com/?p=69 本程式主要用於驅動STM32微控制器晶片的硬體I2C暫存器,實現通過使用晶片自帶的I2C暫存器進行資料的傳送與接收. 本例程中採用I2C暫存器查詢的方式來實現資料傳輸,當I2C對應暫存器指定狀態時方可執行下一步操作.
STM32微控制器硬體I2C驅動程式(軟體輪詢方式)---摘自:FeoTech
感謝原作者:FeoTech 原文網址:http://feotech.com/?p=69 本程式主要用於驅動STM32微控制器晶片的硬體I2C暫存器,實現通過使用晶片自帶的I2C暫存器進行資料的傳送與接收. 本例程中採用I2C暫存器查詢的方式來實現資料傳輸,當I2C對應
STM32CubeMX學習筆記——STM32H743_硬體I2C
STM32CubeMX學習筆記——STM32H743_硬體I2C Github STM32CubeMX配置 Pinout配置 GPIO Clock Configuration配置 程式碼部分 main.
C#對window 硬體類操作,ManagementObjectSearcher
用ManagementObjectSearcher 竟然不能解析到標頭檔案,需要手動 Add Referance.. 在解決方案--引用--右鍵--新增引用---程式集---框架---勾選System.Management 前言: 我們在很多情況下想要獲得
STM32F1 硬體I2C驅動DAC(LTC2605)
#include "i2c_drive_mcp.h" #define I2C_Speed 100000 #define Master_Address 0x0A //全部通道 static void I2C_GPIO_Config(void) { &
STM32CubeMX學習教程之十:硬體I2C讀寫AT24C02
完整原始碼下載:https://github.com/simonliu009/STM32CubeMX-hardware-I2C-AT24C02網上有流傳已久一種說法,就是STM的I2C有bug,不好用。確實很多人在實際應用中都遇到了各種問題,所以絕大部分人都是在用軟體模擬II
硬體I2C(TWI)讀寫PCF8563和24CXX程式
//ICC-AVR application builder : 2010-3-5 13:51:50 // Target : M88 // Crystal: 8.0000Mhz #include <iom88v.h> #include <macro
EFM32-筆記-IO操作
GPIO->P[4].DOUT共有16位,因此需要使用一個0xFFFF來表示 2.向GPIO_Px_DOUTSET的對應位上寫1,就可以將該位設定為高電平。 3.向GPIO_Px_DOUTCLR的對應位上寫1,就可以將該位設定為低電平。 4.向GPIO_Px_DOUTTGL的對應位上寫1,就可以將該位
STM32硬體IIC操作 (轉)
轉自:http://blog.csdn.net/dengrengong/article/details/39831577 Stm32具有IIC介面,介面有以下主要特性 多主機功能:該模組既可做主裝置也可做從裝置 主裝置功能 C地址檢測 產生和檢測7位/10位地
STM32 硬體I2C 到底是不是個坑?
/** ****************************************************************************** * @author Maoxiao Hu * @version V1.0.0 * @date May-2015
GPIO模擬I2C操作除錯注意事項
I2C作為板級序列資料匯流排,其規格相對簡單,但除錯過程中的一些細節問題容易被忽視,產生意想不到的時序錯誤。寫這邊文章為了記錄我在除錯I2C過程中遇到的問題,以便今後查閱並作為經驗與大家分享。 關於I2C匯流排的規格可以參考I2C的規格書,描述準確詳細,此不贅述。 使用M
基於 STM32 的硬體 I2C 讀取 MPU6050 資料
MPU6050其實就是一個 I2C 器件,裡面有很多暫存器(但是我們用到的只有幾個),我們通過讀寫暫存器來操作這個晶片。所以首要問題就是 STM32 和 MPU6050 的 I2C 通訊。1、配置 STM32 (用I2C1:PB6——SCL;PB7——SDA)
STM32F10x_硬體I2C讀寫EEPROM(標準外設庫版本)
Ⅰ、寫在前面 上一篇文章是“STM32F10x_模擬I2C讀寫EEPROM”,講述使用IO口模擬I2C匯流排通訊,對EEPROM(AT24Xxx)進行讀寫操作的過程。 上一篇文章主要內容:I2C協議、模擬I2C底層驅動、EEPROM(AT24Xxx)單位元組讀寫操作。 本文
STM32 硬體IIC操作
就三個函式 簡單明瞭 初始化 讀 寫 int main(void){ u8 i; SystemInit(); Iic1_Init(); LED_GPIO_Config(); I2C1_WriteByte(0xA0,1,0x89); //寫EEPRO
STM32F103使用硬體i2c作為從機模式
一、簡單說明 本例子參考了ST官方歷程,官方歷程的連結如下 關於i2c的協議這裡就不做描述了 關於STM32 i2c的模式可以在中文資料手冊中檢視 手冊中已經描述,該模組預設工作在從模式,要想變為主模式,主要生產一個起始條件。(主模式的程式碼可以參考野火開發板的硬體i2
stm32硬體I2C測試例程,親測可用
對於stm32的硬體I2C確實有不盡人意的地方。但是還是可以實現的,畢竟使用stm32的硬體I2C確實比使用IO口來模擬簡單的多。下面的程式程式碼是使用stm32F03ZET6的I2C1(PB6,PB7)和AT24C02的EEPROM來測試的。希望對於需要的朋
STM32F10x_硬體I2C主從通訊(輪詢傳送,中斷接收)
Ⅰ、寫在前面 關注我分享文章的朋友應該知道我在前面講述過(軟體、硬體)I2C主機控制從機EEPROM的例子。在I2C通訊主機控制程式是比較常見的一種,可以說在實際專案中,很多應用都會使用到I2C通訊。但在實際專案中作為I2C從機的應用相對要少的多,本文主要講述關於【STM3
STM32中FSMC與硬體I2C衝突
ST官網勘誤表中列到,FSMC與I2C不能同時開啟。解決的辦法可以有 1:將I2C對映到PB9,PB8. 2:使用模擬的I2C. I/O重對映步驟:(以串列埠為例) 1.開啟重對映時鐘和USART重對映後的I/O口引腳時鐘, RCC_APB2PeriphClockCmd(