生活随笔
收集整理的這篇文章主要介紹了
STM32单片机硬件I2C驱动程序(查询方式)
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
本文章原始地址:http://feotech.com/?p=69
本程序主要用于驅(qū)動(dòng)STM32單片機(jī)芯片的硬件I2C寄存器,實(shí)現(xiàn)通過使用芯片自帶的I2C寄存器進(jìn)行數(shù)據(jù)的發(fā)送與接收.
本例程中采用I2C寄存器查詢的方式來(lái)實(shí)現(xiàn)數(shù)據(jù)傳輸,當(dāng)I2C對(duì)應(yīng)寄存器指定狀態(tài)時(shí)方可執(zhí)行下一步操作.
/********************************************************************************* @file Hardware_I2C.c * @author Ryan Zhao* @version V1.0.0* @date 2017-04-27* @brief STM32硬件I2C底層驅(qū)動(dòng).******************************************************************************* @attention Null* *******************************************************************************//**
* @brief I2C引腳與寄存器功能配置.
* @param None.
* @retval None.
*/
void I2C_Configuration(void)
{/*GPIO與IIC初始化結(jié)構(gòu)體*/ GPIO_InitTypeDef GPIO_InitStructure; I2C_InitTypeDef I2C_InitStructure; /*GPIO與IIC時(shí)鐘使能*/ RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //GPIOB時(shí)鐘使能 RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C1, ENABLE ); //I2C時(shí)鐘使能 /*初始化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; //輸入輸出模式為復(fù)用功能開漏輸出 GPIO_Init( GPIOB, &GPIO_InitStructure ); //根據(jù)GPIO初始化結(jié)構(gòu)體初始化GPIOB /*初始化I2C*/ I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; //設(shè)置為I2C模式 I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; //設(shè)置I2C的占空比,低電平除以高電平值為2 I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; //使能ACK信號(hào) I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //指定7位地址 I2C_InitStructure.I2C_ClockSpeed = 400000; //時(shí)鐘頻率,必須小于等于400KHz I2C_Cmd( HW_I2C, ENABLE ); //使能I2C I2C_Init( HW_I2C, &I2C_InitStructure ); //根據(jù)I2C初始化結(jié)構(gòu)體初始化I2C /*允許一字節(jié)一應(yīng)答模式*/ I2C_AcknowledgeConfig( HW_I2C, ENABLE ); //使能I2C應(yīng)答狀態(tài)
}/**
* @brief 從I2C指定地址中讀取數(shù)據(jù);
* @param 讀取的地址,讀取后返回的數(shù)據(jù);
* @retval 1:讀取數(shù)據(jù)成功,0:讀取數(shù)據(jù)無(wú)效;
*/
unsigned char I2C_ReadByte(unsigned char Read_Address,unsigned char * Read_Data)
{ unsigned char wait_time_out = wait_time_value;//等待I2C器件響應(yīng)的延時(shí)* Read_Data = 0;while (I2C_GetFlagStatus(HW_I2C, I2C_FLAG_BUSY)) //判斷IIC接口狀態(tài).當(dāng)IIC狀態(tài)為BUSY時(shí),一直停在這里循環(huán) {if((wait_time_out --) == 0) //延時(shí)等待{return 0; //響應(yīng)超時(shí),返回?zé)o效標(biāo)志}}/*發(fā)送START之后要等待,意味著START條件被正確釋放,此時(shí)IIC總線上沒有其它外設(shè)*/ I2C_GenerateSTART( HW_I2C, ENABLE ); //產(chǎn)生START條件 while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_MODE_SELECT)) //判斷開始信號(hào)是否已經(jīng)發(fā)送完成 {if((wait_time_out --) == 0) //延時(shí)等待{return 0; //響應(yīng)超時(shí),返回?zé)o效標(biāo)志}}I2C_Send7bitAddress(HW_I2C, ADXL_WRITE, I2C_Direction_Transmitter ); //發(fā)送從機(jī)地址ADXL_WRITE以選擇從機(jī),主機(jī)為發(fā)送模式 while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) //如果主機(jī)發(fā)射模式被選中(死循環(huán)等待從機(jī)發(fā)送ACK信號(hào)) {if((wait_time_out --) == 0) //延時(shí)等待{return 0; //響應(yīng)超時(shí),返回?zé)o效標(biāo)志}}I2C_SendData(HW_I2C, Read_Address ); //將write_address,即要讀的地址通過IIC2發(fā)送出去 while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) //如果地址已經(jīng)從IIC成功發(fā)射出去(死循環(huán)等待ACK信號(hào){if((wait_time_out --) == 0) //延時(shí)等待{return 0; //響應(yīng)超時(shí),返回?zé)o效標(biāo)志}}I2C_GenerateSTART(HW_I2C, ENABLE ); //產(chǎn)生START條件 while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_MODE_SELECT)) //如果主機(jī)被選中(死循環(huán)等待ACK信號(hào)){if((wait_time_out --) == 0) //延時(shí)等待{return 0; //響應(yīng)超時(shí),返回?zé)o效標(biāo)志}}/***主機(jī)接收數(shù)據(jù)***/ I2C_Send7bitAddress(HW_I2C, ADXL_READ, I2C_Direction_Receiver ); //主機(jī)設(shè)置為接收模式 while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)) //如果主機(jī)接收模式被選中(死循環(huán)等待ACK信號(hào)) {if((wait_time_out --) == 0) //延時(shí)等待{return 0; //響應(yīng)超時(shí),返回?zé)o效標(biāo)志}}I2C_AcknowledgeConfig(HW_I2C, DISABLE ); //失能IIC的應(yīng)答狀態(tài) NACK I2C_GenerateSTOP( HW_I2C, ENABLE ); //產(chǎn)生STOP條件 while (!(I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_BYTE_RECEIVED))) //判斷數(shù)據(jù)是否接收完成 {if((wait_time_out --) == 0) //延時(shí)等待{return 0; //響應(yīng)超時(shí),返回?zé)o效標(biāo)志}}I2C_AcknowledgeConfig(HW_I2C, ENABLE ); //再一次使能IIC的應(yīng)答狀態(tài) * Read_Data = I2C_ReceiveData(HW_I2C); //返回IIC接收的數(shù)據(jù) return 1;
}/**
* @brief 通過I2C接口將數(shù)據(jù)寫入從機(jī)指定地址中.
* @param 要寫入的數(shù)據(jù),接收數(shù)據(jù)的地址;
* @retval 1:數(shù)據(jù)寫入成功 0:數(shù)據(jù)寫入失敗
*/
unsigned char I2C_Write_Byte(uint8_t Point_Buffer,uint8_t Write_Address)
{unsigned char wait_time_out = wait_time_value;//等待I2C器件響應(yīng)的延時(shí)while (I2C_GetFlagStatus(HW_I2C, I2C_FLAG_BUSY)) //判斷當(dāng)前I2C接口狀態(tài)是否為Busy {if((wait_time_out --) == 0) //延時(shí)等待{return 0; //響應(yīng)超時(shí),返回?zé)o效標(biāo)志}}I2C_GenerateSTARTHW_I2C, ENABLE ); //產(chǎn)生Start信號(hào) while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_MODE_SELECT)) //判斷Start信號(hào)是否已經(jīng)發(fā)送{if((wait_time_out --) == 0) //延時(shí)等待{return 0; //響應(yīng)超時(shí),返回?zé)o效標(biāo)志}}I2C_Send7bitAddress(HW_I2C, ADXL_WRITE, I2C_Direction_Transmitter ); //發(fā)送從機(jī)地址以選擇從機(jī),主機(jī)為發(fā)送模式 while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) //判斷發(fā)送的地址是否與從機(jī)匹配,等待從機(jī)發(fā)送ACK信號(hào){if((wait_time_out --) == 0) //延時(shí)等待{return 0; //響應(yīng)超時(shí),返回?zé)o效標(biāo)志}} I2C_SendData(HW_I2C, Write_Address ); //將write_address,即要寫的寄存器地址通過IIC發(fā)送出去 while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) //判斷數(shù)據(jù)是否發(fā)送完成{if((wait_time_out --) == 0) //延時(shí)等待{return 0; //響應(yīng)超時(shí),返回?zé)o效標(biāo)志}}/*往寄存器發(fā)送數(shù)據(jù)data*/ I2C_SendData(HW_I2C, Point_Buffer ); while (!I2C_CheckEvent(HW_I2C, I2C_EVENT_MASTER_BYTE_TRANSMITTED)) //判斷數(shù)據(jù)是否發(fā)送完成{if((wait_time_out --) == 0) //延時(shí)等待{return 0; //響應(yīng)超時(shí),返回?zé)o效標(biāo)志}}I2C_GenerateSTOP( HW_I2C, ENABLE ); //IIC2產(chǎn)生STOP條件 return 1;//數(shù)據(jù)寫入完成 1
}
/********************************************************************************* @file Hardware_I2C.h * @author Ryan Zhao* @version V1.0.0* @date 2017-04-27* @brief STM32硬件I2C底層驅(qū)動(dòng).******************************************************************************* @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器件響應(yīng)的延時(shí)
總結(jié)
以上是生活随笔為你收集整理的STM32单片机硬件I2C驱动程序(查询方式)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。