STM32单片机硬件I2C驱动程序(软件轮询方式)---摘自:FeoTech
生活随笔
收集整理的這篇文章主要介紹了
STM32单片机硬件I2C驱动程序(软件轮询方式)---摘自:FeoTech
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
感謝原作者:FeoTech?? 原文網址:http://feotech.com/?p=69
本程序主要用于驅動STM32單片機芯片的硬件I2C寄存器,實現通過使用芯片自帶的I2C寄存器進行數據的發送與接收.
本例程中采用I2C寄存器查詢的方式來實現數據傳輸,當I2C對應寄存器指定狀態時方可執行下一步操作.
/********************************************************************************* @file Hardware_I2C.c * @author Ryan Zhao* @version V1.0.0* @date 2017-04-27* @brief STM32硬件I2C底層驅動.******************************************************************************* @attention Null* *******************************************************************************//** * @brief I2C引腳與寄存器功能配置. * @param None. * @retval None. */ void I2C_Configuration(void) {/*GPIO與IIC初始化結構體*/ GPIO_InitTypeDef GPIO_InitStructure; I2C_InitTypeDef I2C_InitStructure; /*GPIO與IIC時鐘使能*/ RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //GPIOB時鐘使能 RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C1, ENABLE ); //I2C時鐘使能 /*初始化GPIO*/ GPIO_InitStructure.GPIO_Pin = HW_I2C_SDA_PIN | HW_I2C_SCL_PIN; //初始化 IIC GPIO GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //最高輸出速度50Hz GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //輸入輸出模式為復用功能開漏輸出 GPIO_Init( GPIOB, &GPIO_InitStructure ); //根據GPIO初始化結構體初始化GPIOB /*初始化I2C*/ I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; //設置為I2C模式 I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; //設置I2C的占空比,低電平除以高電平值為2 I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; //使能ACK信號 I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //指定7位地址 I2C_InitStructure.I2C_ClockSpeed = 400000; //時鐘頻率,必須小于等于400KHz I2C_Cmd( HW_I2C, ENABLE ); //使能I2C I2C_Init( HW_I2C, &I2C_InitStructure ); //根據I2C初始化結構體初始化I2C /*允許一字節一應答模式*/ I2C_AcknowledgeConfig( HW_I2C, ENABLE ); //使能I2C應答狀態 }/** * @brief 從I2C指定地址中讀取數據; * @param 讀取的地址,讀取后返回的數據; * @retval 1:讀取數據成功,0:讀取數據無效; */ unsigned char I2C_ReadByte(unsigned char Read_Address,unsigned char * Read_Data) { unsigned char wait_time_out = wait_time_value;//等待I2C器件響應的延時* Read_Data = 0;while (I2C_GetFlagStatus(HW_I2C, I2C_FLAG_BUSY)) //判斷IIC接口狀態.當IIC狀態為BUSY時,一直停在這里循環 {if((wait_time_out --) == 0) //延時等待{return 0; //響應超時,返回無效標志}}/*發送START之后要等待,意味著START條件被正確釋放,此時IIC總線上沒有其它外設*/ I2C_GenerateSTART( HW_I2C, ENABLE ); //產生START條件 while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_MODE_SELECT)) //判斷開始信號是否已經發送完成 {if((wait_time_out --) == 0) //延時等待{return 0; //響應超時,返回無效標志}}I2C_Send7bitAddress(HW_I2C, ADXL_WRITE, I2C_Direction_Transmitter ); //發送從機地址ADXL_WRITE以選擇從機,主機為發送模式 while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) //如果主機發射模式被選中(死循環等待從機發送ACK信號) {if((wait_time_out --) == 0) //延時等待{return 0; //響應超時,返回無效標志}}I2C_SendData(HW_I2C, Read_Address ); //將write_address,即要讀的地址通過IIC2發送出去 while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) //如果地址已經從IIC成功發射出去(死循環等待ACK信號{if((wait_time_out --) == 0) //延時等待{return 0; //響應超時,返回無效標志}}I2C_GenerateSTART(HW_I2C, ENABLE ); //產生START條件 while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_MODE_SELECT)) //如果主機被選中(死循環等待ACK信號){if((wait_time_out --) == 0) //延時等待{return 0; //響應超時,返回無效標志}}/***主機接收數據***/ I2C_Send7bitAddress(HW_I2C, ADXL_READ, I2C_Direction_Receiver ); //主機設置為接收模式 while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) //如果主機接收模式被選中(死循環等待ACK信號) {if((wait_time_out --) == 0) //延時等待{return 0; //響應超時,返回無效標志}}I2C_AcknowledgeConfig(HW_I2C, DISABLE ); //失能IIC的應答狀態 NACK I2C_GenerateSTOP( HW_I2C, ENABLE ); //產生STOP條件 while (!(I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED))) //判斷數據是否接收完成 {if((wait_time_out --) == 0) //延時等待{return 0; //響應超時,返回無效標志}}I2C_AcknowledgeConfig(HW_I2C, ENABLE ); //再一次使能IIC的應答狀態 * Read_Data = I2C_ReceiveData(HW_I2C); //返回IIC接收的數據 return 1; }/** * @brief 通過I2C接口將數據寫入從機指定地址中. * @param 要寫入的數據,接收數據的地址; * @retval 1:數據寫入成功 0:數據寫入失敗 */ unsigned char I2C_Write_Byte(uint8_t Point_Buffer,uint8_t Write_Address) {unsigned char wait_time_out = wait_time_value;//等待I2C器件響應的延時while (I2C_GetFlagStatus(HW_I2C, I2C_FLAG_BUSY)) //判斷當前I2C接口狀態是否為Busy {if((wait_time_out --) == 0) //延時等待{return 0; //響應超時,返回無效標志}}I2C_GenerateSTARTHW_I2C, ENABLE ); //產生Start信號 while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_MODE_SELECT)) //判斷Start信號是否已經發送{if((wait_time_out --) == 0) //延時等待{return 0; //響應超時,返回無效標志}}I2C_Send7bitAddress(HW_I2C, ADXL_WRITE, I2C_Direction_Transmitter ); //發送從機地址以選擇從機,主機為發送模式 while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) //判斷發送的地址是否與從機匹配,等待從機發送ACK信號{if((wait_time_out --) == 0) //延時等待{return 0; //響應超時,返回無效標志}} I2C_SendData(HW_I2C, Write_Address ); //將write_address,即要寫的寄存器地址通過IIC發送出去 while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) //判斷數據是否發送完成{if((wait_time_out --) == 0) //延時等待{return 0; //響應超時,返回無效標志}}/*往寄存器發送數據data*/ I2C_SendData(HW_I2C, Point_Buffer ); while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) //判斷數據是否發送完成{if((wait_time_out --) == 0) //延時等待{return 0; //響應超時,返回無效標志}}I2C_GenerateSTOP( HW_I2C, ENABLE ); //IIC2產生STOP條件 return 1;//數據寫入完成 1 } /********************************************************************************* @file Hardware_I2C.h * @author Ryan Zhao* @version V1.0.0* @date 2017-04-27* @brief STM32硬件I2C底層驅動.******************************************************************************* @attention Null* *******************************************************************************//*********************I2C 物理層GPIO定義*******************/ #define HW_I2C I2C1 //第一組I2C接口 #define HW_I2C_SDA_PIN GPIO_Pin_7 #define HW_I2C_SDA_GPIO_PORT GPIOB #define HW_I2C_SCL_PIN GPIO_Pin_6 #define HW_I2C_SCL_GPIO_PORT GPIOB #define wait_time_value 200 //等待I2C器件響應的延時?
總結
以上是生活随笔為你收集整理的STM32单片机硬件I2C驱动程序(软件轮询方式)---摘自:FeoTech的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 常用软件滤波算法---摘自:FeoTec
- 下一篇: 0R电阻的12种妙用---摘自:俸禄的小