一個穩(wěn)定可靠的STM32 I2C程序_第1頁
一個穩(wěn)定可靠的STM32 I2C程序_第2頁
一個穩(wěn)定可靠的STM32 I2C程序_第3頁
一個穩(wěn)定可靠的STM32 I2C程序_第4頁
一個穩(wěn)定可靠的STM32 I2C程序_第5頁
已閱讀5頁,還剩11頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、/*File : i2c.hPurpose : */#ifndef _I2C_H_#define _I2C_H_/* Includes */* Defines */#define SENSORS_I2C I2C2#define I2C_SPEED 400000#define I2C_OWN_ADDRESS 0x00#define I2C_Config() I2cMaster_Init(); /* Prototypes */void I2cMaster_Init(void);unsigned long Sensors_I2C_WriteRegister(unsigned char Address

2、, unsigned char RegisterAddr, unsigned short RegisterLen, const unsigned char *RegisterValue);unsigned long Sensors_I2C_ReadRegister(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue);int Sensors_I2C_WriteRegister_swap(unsigned char slave_add

3、r,unsigned char reg_addr,unsigned char len, unsigned char *data_ptr);int Sensors_I2C_ReadRegister_swap(unsigned char slave_addr,unsigned char reg_addr,unsigned char len, unsigned char *data_ptr);int I2C_Reset_User();#endif / _I2C_H_/*File : i2c.cPurpose : I2c 3 to communicate with the sensorsAuthor

4、: * Includes */#include <stdio.h>#include "stm32l1xx.h"#include "i2c.h"#include "gpio.h"#include "log.h"#include "discover_board.h"#include "main.h"/* Defines */#define I2Cx_FLAG_TIMEOUT (uint32_t) 900)#define I2Cx_LONG_TIMEOUT (uint3

5、2_t)(300 * I2Cx_FLAG_TIMEOUT)#define SENSORS_I2C_SCL_GPIO_PORT GPIOB#define SENSORS_I2C_SCL_GPIO_CLK RCC_AHBPeriph_GPIOB#define SENSORS_I2C_SCL_GPIO_PIN GPIO_Pin_10#define SENSORS_I2C_SCL_GPIO_PINSOURCE GPIO_PinSource10 #define SENSORS_I2C_SDA_GPIO_PORT GPIOB#define SENSORS_I2C_SDA_GPIO_CLK RCC_AHBP

6、eriph_GPIOB#define SENSORS_I2C_SDA_GPIO_PIN GPIO_Pin_11#define SENSORS_I2C_SDA_GPIO_PINSOURCE GPIO_PinSource11#define SENSORS_I2C_RCC_CLK RCC_APB1Periph_I2C2#define SENSORS_I2C_AF GPIO_AF_I2C2#define WAIT_FOR_FLAG(flag, value, timeout, errorcode) I2CTimeout = timeout; while(I2C_GetFlagStatus(SENSORS

7、_I2C, flag) != value) if(I2CTimeout-) = 0) return I2Cx_TIMEOUT_UserCallback(errorcode); #define CLEAR_ADDR_BIT I2C_ReadRegister(SENSORS_I2C, I2C_Register_SR1); I2C_ReadRegister(SENSORS_I2C, I2C_Register_SR2); /* Globals */* Prototypes */* Function */static uint32_t I2Cx_TIMEOUT_UserCallback(char val

8、ue);void I2cMaster_Init(void) GPIO_InitTypeDef GPIO_InitStructure; I2C_InitTypeDef I2C_InitStructure; /* Enable I2Cx clock */ RCC_APB1PeriphClockCmd(SENSORS_I2C_RCC_CLK, ENABLE); /* Enable I2C GPIO clock */ RCC_AHBPeriphClockCmd(SENSORS_I2C_SCL_GPIO_CLK | SENSORS_I2C_SDA_GPIO_CLK, ENABLE); /* Config

9、ure I2Cx pin: SCL -*/ GPIO_InitStructure.GPIO_Pin = SENSORS_I2C_SCL_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; /* Connect pins to Periph */ GP

10、IO_PinAFConfig(SENSORS_I2C_SCL_GPIO_PORT, SENSORS_I2C_SCL_GPIO_PINSOURCE, SENSORS_I2C_AF); GPIO_Init(SENSORS_I2C_SCL_GPIO_PORT, &GPIO_InitStructure); /* Configure I2Cx pin: SDA -*/ GPIO_InitStructure.GPIO_Pin = SENSORS_I2C_SDA_GPIO_PIN; /* Connect pins to Periph */ GPIO_PinAFConfig(SENSORS_I2C_S

11、DA_GPIO_PORT, SENSORS_I2C_SDA_GPIO_PINSOURCE, SENSORS_I2C_AF); GPIO_Init(SENSORS_I2C_SDA_GPIO_PORT, &GPIO_InitStructure); I2C_DeInit(SENSORS_I2C); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = I2C_OWN_ADDRESS; I2

12、C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED; /* Enable the I2C peripheral */ I2C_Cmd(SENSORS_I2C, ENABLE); /* Initialize the I2C peripheral */ I2C_Init(SENSORS_I2C, &I2C_InitStruc

13、ture);/* * brief Basic management of the timeout situation. * param None. * retval None. */static uint32_t I2Cx_TIMEOUT_UserCallback(char value) /* The following code allows I2C error recovery and return to normal communication if the error source doesn't still exist (ie. hardware issue.) */ I2C

14、_InitTypeDef I2C_InitStructure; I2C_GenerateSTOP(SENSORS_I2C, ENABLE); I2C_SoftwareResetCmd(SENSORS_I2C, ENABLE); I2C_SoftwareResetCmd(SENSORS_I2C, DISABLE); I2C_DeInit(SENSORS_I2C); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_O

15、wnAddress1 = I2C_OWN_ADDRESS; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = I2C_SPEED; /* Enable the I2C peripheral */ I2C_Cmd(SENSORS_I2C, ENABLE); /* Initialize the I2C peripheral */ I2C_Init

16、(SENSORS_I2C, &I2C_InitStructure); #ifdef User_debug MPL_LOGI("I2C Restarted.n");#endif return 1;int I2C_Reset_User() return I2Cx_TIMEOUT_UserCallback(0); /* * brief Writes a Byte to a given register to the sensors through the control interface (I2C) * param RegisterAddr: The address (

17、location) of the register to be written. * param RegisterValue: the Byte value to be written into destination register. * retval 0 if correct communication, else wrong communication */unsigned long Sensors_I2C_WriteRegister(unsigned char Address, unsigned char RegisterAddr, unsigned short RegisterLe

18、n, const unsigned char *RegisterValue) uint32_t result = 0; uint32_t i = RegisterLen; _IO uint32_t I2CTimeout = I2Cx_LONG_TIMEOUT; /RegisterValue = RegisterValue + (RegisterLen - 1); /* Wait for the busy flag to be cleared */ WAIT_FOR_FLAG (I2C_FLAG_BUSY, RESET, I2Cx_LONG_TIMEOUT, 1); /* Start the c

19、onfig sequence */ I2C_GenerateSTART(SENSORS_I2C, ENABLE); /* Wait for the start bit to be set */ WAIT_FOR_FLAG (I2C_FLAG_SB, SET, I2Cx_FLAG_TIMEOUT, 2); /* Transmit the slave address and enable writing operation */ I2C_Send7bitAddress(SENSORS_I2C, (Address<<1), I2C_Direction_Transmitter); /* W

20、ait for address bit to be set */ WAIT_FOR_FLAG (I2C_FLAG_ADDR, SET, I2Cx_FLAG_TIMEOUT, 3); /* clear the ADDR interrupt bit - this is done by reading SR1 and SR2*/ CLEAR_ADDR_BIT /* Wait for address bit to be set */ WAIT_FOR_FLAG (I2C_FLAG_TXE, SET, I2Cx_FLAG_TIMEOUT, 4); /* Transmit the first addres

21、s for write operation */ I2C_SendData(SENSORS_I2C, RegisterAddr); while (i-) /* Wait for address bit to be set */ WAIT_FOR_FLAG (I2C_FLAG_TXE, SET, I2Cx_FLAG_TIMEOUT, 5); /* Prepare the register value to be sent */ /I2C_SendData(SENSORS_I2C, *RegisterValue-); I2C_SendData(SENSORS_I2C, *RegisterValue

22、+); /* Wait for address bit to be set */ WAIT_FOR_FLAG (I2C_FLAG_BTF, SET, I2Cx_FLAG_TIMEOUT, 6); /* End the configuration sequence */ I2C_GenerateSTOP(SENSORS_I2C, ENABLE); /* Return the verifying value: 0 (Passed) or 1 (Failed) */ return result; unsigned long Sensors_I2C_ReadRegister(unsigned char

23、 Address, unsigned char RegisterAddr, unsigned short RegisterLen, unsigned char *RegisterValue) uint32_t result = 0; uint8_t bytesRemaining = RegisterLen; _IO uint32_t I2CTimeout = I2Cx_LONG_TIMEOUT; /* Wait for the busy flag to be cleared */ WAIT_FOR_FLAG (I2C_FLAG_BUSY, RESET, I2Cx_LONG_TIMEOUT, 7

24、); /* Start the config sequence */ I2C_GenerateSTART(SENSORS_I2C, ENABLE); /* Wait for the start bit to be set */ WAIT_FOR_FLAG (I2C_FLAG_SB, SET, I2Cx_FLAG_TIMEOUT, 8); /* Transmit the slave address and enable writing operation */ I2C_Send7bitAddress(SENSORS_I2C, (Address<<1), I2C_Direction_T

25、ransmitter); /* Wait for the start bit to be set */ WAIT_FOR_FLAG (I2C_FLAG_ADDR, SET, I2Cx_FLAG_TIMEOUT, 9); /* clear the ADDR interrupt bit - this is done by reading SR1 and SR2*/ CLEAR_ADDR_BIT; /* Wait for address bit to be set */ WAIT_FOR_FLAG (I2C_FLAG_TXE, SET, I2Cx_FLAG_TIMEOUT, 10); /* Tran

26、smit the register address to be read */ I2C_SendData(SENSORS_I2C, RegisterAddr); /* Wait for address bit to be set */ WAIT_FOR_FLAG (I2C_FLAG_TXE, SET, I2Cx_FLAG_TIMEOUT, 11); /*!< Send START condition a second time */ I2C_GenerateSTART(SENSORS_I2C, ENABLE); /* Wait for the start bit to be set */

27、 WAIT_FOR_FLAG (I2C_FLAG_SB, SET, I2Cx_FLAG_TIMEOUT, 12); /*!< Send address for read */ I2C_Send7bitAddress(SENSORS_I2C, (Address<<1), I2C_Direction_Receiver); /* Wait for the start bit to be set */ WAIT_FOR_FLAG (I2C_FLAG_ADDR, SET, I2Cx_FLAG_TIMEOUT, 13); if (RegisterLen = 1) /*!< Disa

28、ble Acknowledgment */ I2C_AcknowledgeConfig(SENSORS_I2C, DISABLE); /* clear the ADDR interrupt bit - this is done by reading SR1 and SR2*/ CLEAR_ADDR_BIT; /*!< Send STOP Condition */ I2C_GenerateSTOP(SENSORS_I2C, ENABLE); /* Wait for the RXNE bit to be set */ WAIT_FOR_FLAG (I2C_FLAG_RXNE, SET, I2

29、Cx_FLAG_TIMEOUT, 14); /bytesRemaining-; /RegisterValuebytesRemaining = I2C_ReceiveData(SENSORS_I2C); RegisterValue0 = I2C_ReceiveData(SENSORS_I2C); else if( RegisterLen = 2) /*!< Disable Acknowledgment */ I2C_AcknowledgeConfig(SENSORS_I2C, DISABLE); /* Set POS bit */ SENSORS_I2C->CR1 |= I2C_CR

30、1_POS; /* clear the ADDR interrupt bit - this is done by reading SR1 and SR2*/ CLEAR_ADDR_BIT; /* Wait for the buffer full bit to be set */ WAIT_FOR_FLAG (I2C_FLAG_BTF, SET, I2Cx_FLAG_TIMEOUT, 15); /*!< Send STOP Condition */ I2C_GenerateSTOP(SENSORS_I2C, ENABLE); /* Read 2 bytes */ /bytesRemaini

31、ng-; /RegisterValuebytesRemaining = I2C_ReceiveData(SENSORS_I2C); /RegisterValuebytesRemaining = I2C_ReceiveData(SENSORS_I2C); RegisterValue0 = I2C_ReceiveData(SENSORS_I2C); RegisterValue1 = I2C_ReceiveData(SENSORS_I2C); else /* more than 2 bytes */ /* clear the ADDR interrupt bit - this is done by

32、reading SR1 and SR2*/ CLEAR_ADDR_BIT; while(bytesRemaining) if( bytesRemaining = 3) /* Wait for the buffer full bit to be set */ WAIT_FOR_FLAG (I2C_FLAG_BTF, SET, I2Cx_FLAG_TIMEOUT, 16); /*!< Disable Acknowledgment */ I2C_AcknowledgeConfig(SENSORS_I2C, DISABLE); /* Read 1 bytes */ bytesRemaining-

33、; /RegisterValuebytesRemaining = I2C_ReceiveData(SENSORS_I2C); *RegisterValue+ = I2C_ReceiveData(SENSORS_I2C); /*!< Send STOP Condition */ I2C_GenerateSTOP(SENSORS_I2C, ENABLE); /* Read 1 bytes */ bytesRemaining-; /RegisterValuebytesRemaining = I2C_ReceiveData(SENSORS_I2C); *RegisterValue+ = I2C_

34、ReceiveData(SENSORS_I2C); /* Wait for the buffer full bit to be set */ WAIT_FOR_FLAG (I2C_FLAG_RXNE, SET, I2Cx_FLAG_TIMEOUT, 17); /* Read 1 bytes */ bytesRemaining-; /RegisterValuebytesRemaining = I2C_ReceiveData(SENSORS_I2C); *RegisterValue+ = I2C_ReceiveData(SENSORS_I2C); else /* Wait for the RXNE

35、 bit to be set */ WAIT_FOR_FLAG (I2C_FLAG_RXNE, SET, I2Cx_FLAG_TIMEOUT, 18); /* Read 2 bytes */ bytesRemaining-; /RegisterValuebytesRemaining = I2C_ReceiveData(SENSORS_I2C); *RegisterValue+ = I2C_ReceiveData(SENSORS_I2C); /* Clear BTF flag */ I2C_ClearFlag(SENSORS_I2C, I2C_FLAG_BTF); /* Wait for the busy flag to be cleared */ WAIT_FOR_FLAG (I2C_FLAG_BUSY, RESET, I2Cx_LONG_TIMEOUT, 19); /*!< Re-Enable Acknowledgment to be ready for another reception */ I2C_AcknowledgeConfig(SENSORS_I2C, ENABLE); /Disable POS - TODO SENSORS_I2C->CR1 &= I

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論