上次给大家分享了STM32的I2C结构体中的时间寄存器配置工具的使用(【STM32F030开发日志/评测/笔记】+(1)STM32F0处理器I2C时间配置工具使用),为了测试STM32F0的I2C总线库变成,今天给大家分享一下I2C操作气压传感器BMP085的程序,至于完整的BMP085的说明文档及完整的程序,我放在附件中。 实现具体功能:STM32F030使用I2C1接口与BMP085通信,每个0.5s采集一次温度和气压值,然后通过USART1传送到电脑的SerialChart上,绘制曲线。 下图是用SerialChart接收到的气压和温度数据及曲线,绿色曲线是温度14.2度(温度值需要除10),红色曲线气压1.009MPa。 下图是用逻辑分析仪采集的I2C波形。 若要使用STM32F0操作硬件I2C外设,可使用下面的步骤。 1、配置GPIO引脚功能 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; GPIO_InitStructure.GPIO_OType = GPIO_OType_OD; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_PinAFConfig(GPIOB, GPIO_PinSource8, GPIO_AF_1); GPIO_PinAFConfig(GPIOB, GPIO_PinSource9, GPIO_AF_1); 2、初始化I2C外设 I2C_InitTypeDef I2C_InitStructure; RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_AnalogFilter = I2C_AnalogFilter_Enable; I2C_InitStructure.I2C_DigitalFilter = 0x01; I2C_InitStructure.I2C_OwnAddress1 = 0x00; I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_Timing = 0x30E32E44; I2C_Init(I2C1, &I2C_InitStructure); I2C_Cmd(I2C1, ENABLE); 3、调用I2C的外设库函数进行读写I2C 我采用的是查询方式 主要使用的库函数有: (A)void I2C_TransferHandling(I2C_TypeDef* I2Cx, uint16_t Address, uint8_t Number_Bytes, uint32_t ReloadEndMode, uint32_t StartStopMode) (B)uint8_t I2C_ReceiveData ( I2C_TypeDef * I2Cx ) (C)void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data) 详细说明可看标准外设库帮助文档。 (1)I2C设备读数据程序段 /** * @brief 从I2C1总线上的某一器件的某一起始地址中读取一定字节的数据到数组中 * @param driver_Addr:I2C器件地址 * @param start_Addr:起始字节地址 * @param number_Bytes:要读取的字节数量(小于一页) * @param read_Buffer:存放读取数据的数组指针 * @retval 是否读取成功 */ I2C_Status I2C1_Read_NBytes(uint8_t driver_Addr, uint8_t start_Addr, uint8_t number_Bytes, uint8_t *read_Buffer) { uint8_t read_Num; I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } I2C_TransferHandling(I2C1, driver_Addr, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write); I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } I2C_SendData(I2C1, start_Addr); I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TC) == RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } I2C_TransferHandling(I2C1, driver_Addr, number_Bytes, I2C_AutoEnd_Mode, I2C_Generate_Start_Read); for(read_Num = 0; read_Num < number_Bytes; read_Num++) { I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } read_Buffer[read_Num] = I2C_ReceiveData(I2C1); } I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } return I2C_OK; } (2)I2C设备写数据程序段 /** * @brief 从I2C1的总线上的某一器件的某一起始地址中读取一定字节的数据到数组中 * @param driver_Addr:I2C器件地址 * @param start_Addr:起始字节地址 * @param number_Bytes:要读取的字节数量(小于一页) * @param write_Buffer:存放读取数据的数组指针 * @retval 是否读取成功 */ I2C_Status I2C1_Write_NBytes(uint8_t driver_Addr, uint8_t start_Addr, uint8_t number_Bytes, uint8_t *write_Buffer) { uint8_t write_Num; I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY) != RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } I2C_TransferHandling(I2C1, driver_Addr, 1, I2C_Reload_Mode, I2C_Generate_Start_Write); I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } I2C_SendData(I2C1, start_Addr); I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TCR) == RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } I2C_TransferHandling(I2C1, driver_Addr, number_Bytes, I2C_AutoEnd_Mode, I2C_No_StartStop); for(write_Num = 0; write_Num < number_Bytes; write_Num++) { I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_TXIS) == RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } I2C_SendData(I2C1, write_Buffer[write_Num]); } I2C_Timeout = I2C_TIMEOUT; while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == RESET) { if((I2C_Timeout--) == 0) { return I2C_FAIL; } } return I2C_OK; } |
参与人数 1 | ST金币 -1 | 收起 理由 |
---|---|---|
superta2008 | -1 | 很给力! |
【MCU实战经验】STM32F030芯片极限超频测试
【STM32F0开发日志】+STM32F030 修改官方提供的例程
STM32F030F4核心板自己整理的几个程序可以当模板参考(Keil MDK...
CubeMX之STM32F0 UART DMA接收的bug
【STM32F0开发日志】STM32F030 TIM3 4路PWM 输出
stm32f030的i2c(eeprom)调试分享
STM32F030F4P6 PWM输出呼吸灯
【实战经验】STM32F030低温下RTC不工作
STM32F042Nucleo Mbed PWM+L298N驱动12V直流电机
[STM32F072 Nucleo]开发笔记(三) 修改USB代码用于游戏方向盘
我的i2c配置程序如下,请楼主帮忙看看那里有问题,谢谢!
void I2C_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
I2C_InitTypeDef I2C_InitStruct;
/* Configure the I2C clock source. The clock is derived from the HSI */
RCC_I2CCLKConfig(RCC_I2C1CLK_HSI);
/*Enable GPIOB and I2c1 clock*/
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 , ENABLE);
/*GPIO Configuration*/
/*Configure I2C1 pins: SCL */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB,&GPIO_InitStruct);
/*Configure sEE_I2C pins: SDA */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB , &GPIO_InitStruct);
/* Connect PXx to I2C_SCL*/
GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_1);
/* Connect PXx to I2C_SDA*/
GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_1);
/*I2C configuration*/
I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
I2C_InitStruct.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_InitStruct.I2C_DigitalFilter = 0x00;
I2C_InitStruct.I2C_OwnAddress1 =0x00;
I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStruct.I2C_Timing = 0x00210507;
I2C_Init(I2C1, &I2C_InitStruct);
I2C_Cmd(I2C1, ENABLE); /* I2C Peripheral Enable */
}
INT16U sEEAddress = 0;
INT32U sEETimeout = sEE_LONG_TIMEOUT;
INT16U sEEDataNum;
uint32_t sEE_ReadBuffer(uint8_t* pBuffer, uint16_t ReadAddr, uint16_t* NumByteToRead)
{
uint32_t NumbOfSingle = 0, Count = 0, DataNum = 0, StartCom = 0;
/* Get number of reload cycles */
Count = (*NumByteToRead) / 255;
NumbOfSingle = (*NumByteToRead) % 255;
/* Configure slave address, nbytes, reload and generate start */
I2C_TransferHandling(sEE_I2C, sEEAddress, 1, I2C_SoftEnd_Mode, I2C_Generate_Start_Write);
/* Wait until TXIS flag is set */
sEETimeout = sEE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXIS) == RESET)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/* Send memory address */
I2C_SendData(sEE_I2C, (uint8_t)ReadAddr);
/* Wait until TC flag is set */
sEETimeout = sEE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TC) == RESET)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/* If number of Reload cycles is not equal to 0 */
if (Count != 0)
{
/* Starting communication */
StartCom = 1;
/* Wait until all reload cycles are performed */
while( Count != 0)
{
/* If a read transfer is performed */
if (StartCom == 0)
{
/* Wait until TCR flag is set */
sEETimeout = sEE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TCR) == RESET)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
}
/* if remains one read cycle */
if ((Count == 1) && (NumbOfSingle == 0))
{
/* if starting communication */
if (StartCom != 0)
{
/* Configure slave address, end mode and start condition */
I2C_TransferHandling(sEE_I2C, sEEAddress, 255, I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
}
else
{
/* Configure slave address, end mode */
I2C_TransferHandling(sEE_I2C, sEEAddress, 255, I2C_AutoEnd_Mode, I2C_No_StartStop);
}
}
else
{
/* if starting communication */
if (StartCom != 0)
{
/* Configure slave address, end mode and start condition */
I2C_TransferHandling(sEE_I2C, sEEAddress, 255, I2C_Reload_Mode, I2C_Generate_Start_Read);
}
else
{
/* Configure slave address, end mode */
I2C_TransferHandling(sEE_I2C, sEEAddress, 255, I2C_Reload_Mode, I2C_No_StartStop);
}
}
/* Update local variable */
StartCom = 0;
DataNum = 0;
/* Wait until all data are received */
while (DataNum != 255)
{
/* Wait until RXNE flag is set */
sEETimeout = sEE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_RXNE) == RESET)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/* Read data from RXDR */
pBuffer[DataNum]= I2C_ReceiveData(sEE_I2C);
/* Update number of received data */
DataNum++;
(*NumByteToRead)--;
}
/* Update Pointer of received buffer */
pBuffer += DataNum;
/* update number of reload cycle */
Count--;
}
/* If number of single data is not equal to 0 */
if (NumbOfSingle != 0)
{
/* Wait until TCR flag is set */
sEETimeout = sEE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TCR) == RESET)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/* Update CR2 : set Nbytes and end mode */
I2C_TransferHandling(sEE_I2C, sEEAddress, (uint8_t)(NumbOfSingle), I2C_AutoEnd_Mode, I2C_No_StartStop);
/* Reset local variable */
DataNum = 0;
/* Wait until all data are received */
while (DataNum != NumbOfSingle)
{
/* Wait until RXNE flag is set */
sEETimeout = sEE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_RXNE) == RESET)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/* Read data from RXDR */
pBuffer[DataNum]= I2C_ReceiveData(sEE_I2C);
/* Update number of received data */
DataNum++;
(*NumByteToRead)--;
}
}
}
else
{
/* Update CR2 : set Slave Address , set read request, generate Start and set end mode */
I2C_TransferHandling(sEE_I2C, sEEAddress, (uint32_t)(NumbOfSingle), I2C_AutoEnd_Mode, I2C_Generate_Start_Read);
/* Reset local variable */
DataNum = 0;
/* Wait until all data are received */
while (DataNum != NumbOfSingle)
{
/* Wait until RXNE flag is set */
sEETimeout = sEE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_RXNE) == RESET)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/* Read data from RXDR */
pBuffer[DataNum]= I2C_ReceiveData(sEE_I2C);
/* Update number of received data */
DataNum++;
(*NumByteToRead)--;
}
}
/* Wait until STOPF flag is set */
sEETimeout = sEE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_STOPF) == RESET)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/* Clear STOPF flag */
I2C_ClearFlag(sEE_I2C, I2C_ICR_STOPCF);
/* If all operations OK, return sEE_OK (0) */
return sEE_OK;
}
/*******************************************************************************
* @brief Writes more than one byte to the EEPROM with a single WRITE cycle.
*
* @note The number of bytes (combined to write start address) must not
* cross the EEPROM page boundary. This function can only write into
* the boundaries of an EEPROM page.
* @note This function doesn't check on boundaries condition (in this driver
* the function sEE_WriteBuffer() which calls sEE_WritePage() is
* responsible of checking on Page boundaries).
*
* @param pBuffer: pointer to the buffer containing the data to be written to
* the EEPROM.
* @param WriteAddr: EEPROM's internal address to write to.
* @param NumByteToWrite: pointer to the variable holding number of bytes to
* be written into the EEPROM.
*
* @retval sEE_OK (0) if operation is correctly performed, else return value
* different from sEE_OK (0) or the timeout user callback.
*******************************************************************************/
uint32_t sEE_WritePage(uint8_t* pBuffer, uint16_t WriteAddr, uint8_t* NumByteToWrite)
{
uint32_t DataNum = 0;
/* Configure slave address, nbytes, reload and generate start */
I2C_TransferHandling(sEE_I2C, sEEAddress, 1, I2C_Reload_Mode, I2C_Generate_Start_Write);
/* Wait until TXIS flag is set */
sEETimeout = sEE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXIS) == RESET)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/* Send memory address */
I2C_SendData(sEE_I2C, (uint8_t)WriteAddr);
/* Wait until TCR flag is set */
sEETimeout = sEE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TCR) == RESET)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/* Update CR2 : set Slave Address , set write request, generate Start and set end mode */
I2C_TransferHandling(sEE_I2C, sEEAddress, (uint8_t)(*NumByteToWrite), I2C_AutoEnd_Mode, I2C_No_StartStop);
while (DataNum != (*NumByteToWrite))
{
/* Wait until TXIS flag is set */
sEETimeout = sEE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_TXIS) == RESET)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/* Write data to TXDR */
I2C_SendData(sEE_I2C, (uint8_t)(pBuffer[DataNum]));
/* Update number of transmitted data */
DataNum++;
}
/* Wait until STOPF flag is set */
sEETimeout = sEE_LONG_TIMEOUT;
while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_STOPF) == RESET)
{
if((sEETimeout--) == 0) return sEE_TIMEOUT_UserCallback();
}
/* Clear STOPF flag */
I2C_ClearFlag(sEE_I2C, I2C_ICR_STOPCF);
/* If all operations OK, return sEE_OK (0) */
return sEE_OK;
}
/*******************************************************************************
* @brief Writes buffer of data to the I2C EEPROM.
* @param pBuffer: pointer to the buffer containing the data to be written
* to the EEPROM.
* @param WriteAddr: EEPROM's internal address to write to.
* @param NumByteToWrite: number of bytes to write to the EEPROM.
* @retval None
*******************************************************************************/
void sEE_WriteBuffer(uint8_t* pBuffer, uint16_t WriteAddr, uint16_t NumByteToWrite)
{
uint16_t NumOfPage = 0, NumOfSingle = 0, count = 0;
uint16_t Addr = 0;
Addr = WriteAddr % sEE_PAGESIZE;
count = sEE_PAGESIZE - Addr;
NumOfPage = NumByteToWrite / sEE_PAGESIZE;
NumOfSingle = NumByteToWrite % sEE_PAGESIZE;
/*!< If WriteAddr is sEE_PAGESIZE aligned */
if(Addr == 0)
{
/*!< If NumByteToWrite < sEE_PAGESIZE */
if(NumOfPage == 0)
{
/* Store the number of data to be written */
sEEDataNum = NumOfSingle;
/* Start writing data */
sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
sEE_WaitEepromStandbyState();
}
/*!< If NumByteToWrite > sEE_PAGESIZE */
else
{
while(NumOfPage--)
{
/* Store the number of data to be written */
sEEDataNum = sEE_PAGESIZE;
sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
sEE_WaitEepromStandbyState();
WriteAddr += sEE_PAGESIZE;
pBuffer += sEE_PAGESIZE;
}
if(NumOfSingle!=0)
{
/* Store the number of data to be written */
sEEDataNum = NumOfSingle;
sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
sEE_WaitEepromStandbyState();
}
}
}
/*!< If WriteAddr is not sEE_PAGESIZE aligned */
else
{
/*!< If NumByteToWrite < sEE_PAGESIZE */
if(NumOfPage== 0)
{
/*!< If the number of data to be written is more than the remaining space
in the current page: */
if (NumByteToWrite > count)
{
/* Store the number of data to be written */
sEEDataNum = count;
/*!< Write the data conained in same page */
sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
sEE_WaitEepromStandbyState();
/* Store the number of data to be written */
sEEDataNum = (NumByteToWrite - count);
/*!< Write the remaining data in the following page */
sEE_WritePage((uint8_t*)(pBuffer + count), (WriteAddr + count), (uint8_t*)(&sEEDataNum));
sEE_WaitEepromStandbyState();
}
else
{
/* Store the number of data to be written */
sEEDataNum = NumOfSingle;
sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
sEE_WaitEepromStandbyState();
}
}
/*!< If NumByteToWrite > sEE_PAGESIZE */
else
{
NumByteToWrite -= count;
NumOfPage = NumByteToWrite / sEE_PAGESIZE;
NumOfSingle = NumByteToWrite % sEE_PAGESIZE;
if(count != 0)
{
/* Store the number of data to be written */
sEEDataNum = count;
sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
sEE_WaitEepromStandbyState();
WriteAddr += count;
pBuffer += count;
}
while(NumOfPage--)
{
/* Store the number of data to be written */
sEEDataNum = sEE_PAGESIZE;
sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
sEETimeout = sEE_LONG_TIMEOUT;
sEE_WaitEepromStandbyState();
WriteAddr += sEE_PAGESIZE;
pBuffer += sEE_PAGESIZE;
}
if(NumOfSingle != 0)
{
/* Store the number of data to be written */
sEEDataNum = NumOfSingle;
sEE_WritePage(pBuffer, WriteAddr, (uint8_t*)(&sEEDataNum));
sEE_WaitEepromStandbyState();
}
}
}
}
/*******************************************************************************
* @brief Wait for EEPROM Standby state.
*
* @note This function allows to wait and check that EEPROM has finished the
* last operation. It is mostly used after Write operation: after receiving
* the buffer to be written, the EEPROM may need additional time to actually
* perform the write operation. During this time, it doesn't answer to
* I2C packets addressed to it. Once the write operation is complete
* the EEPROM responds to its address.
*
* @param None
*
* @retval sEE_OK (0) if operation is correctly performed, else return value
* different from sEE_OK (0) or the timeout user callback.
*******************************************************************************/
uint32_t sEE_WaitEepromStandbyState(void)
{
__IO uint32_t sEETrials = 0;
/* Keep looping till the slave acknowledge his address or maximum number
of trials is reached (this number is defined by sEE_MAX_TRIALS_NUMBER define
in stm32373c_eval_i2c_ee.h file) */
/* Configure CR2 register : set Slave Address and end mode */
I2C_TransferHandling(sEE_I2C, sEEAddress, 0, I2C_AutoEnd_Mode, I2C_No_StartStop);
do
{
/* Initialize sEETimeout */
sEETimeout = sEE_FLAG_TIMEOUT;
/* Clear NACKF */
I2C_ClearFlag(sEE_I2C, I2C_ICR_NACKCF | I2C_ICR_STOPCF);
/* Generate start */
I2C_GenerateSTART(sEE_I2C, ENABLE);
/* Wait until timeout elapsed */
while (sEETimeout-- != 0);
/* Check if the maximum allowed numbe of trials has bee reached */
if (sEETrials++ == sEE_MAX_TRIALS_NUMBER)
{
/* If the maximum number of trials has been reached, exit the function */
return sEE_TIMEOUT_UserCallback();
}
}
while(I2C_GetFlagStatus(sEE_I2C, I2C_ISR_NACKF) != RESET);
/* Clear STOPF */
I2C_ClearFlag(sEE_I2C, I2C_ICR_STOPCF);
/* Return sEE_OK if device is ready */
return sEE_OK;
}
uint32_t sEE_TIMEOUT_UserCallback(void)
{
/* Block communication and all processes */
while (1)
{
}
}
int main(void)
{
I2C_Configuration();
sEE_WriteBuffer(temp1,0x00,8);
NumDataRead=8;
while(1)
{
sEE_ReadBuffer(temp2, 0x00,(INT16U *)(&NumDataRead));
}
}
有逻辑分析仪的,就没怎么用过分析仪,我的这个只能进一次发送中断,然后就进不去了
我把我配置的程序发出来
void I2C_Configuration(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
I2C_InitTypeDef I2C_InitStruct;
NVIC_InitTypeDef NVIC_InitStructure;
/* Configure the I2C clock source. The clock is derived from the HSI */
RCC_I2CCLKConfig(RCC_I2C1CLK_SYSCLK);
/*Enable GPIOB and I2c1 clock*/
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1 , ENABLE);
/* Connect PXx to I2C_SCL*/
GPIO_PinAFConfig(GPIOB,GPIO_PinSource6,GPIO_AF_1);
/* Connect PXx to I2C_SDA*/
GPIO_PinAFConfig(GPIOB,GPIO_PinSource7,GPIO_AF_1);
/*GPIO Configuration*/
/*Configure I2C1 pins: SCL */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOB,&GPIO_InitStruct);
/*Configure sEE_I2C pins: SDA */
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB , &GPIO_InitStruct);
/* Enable the USART1 gloabal Interrupt */
NVIC_InitStructure.NVIC_IRQChannel = I2C1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/*I2C configuration*/
I2C_InitStruct.I2C_Mode = I2C_Mode_I2C;
I2C_InitStruct.I2C_AnalogFilter = I2C_AnalogFilter_Enable;
I2C_InitStruct.I2C_DigitalFilter = 0x00;
I2C_InitStruct.I2C_OwnAddress1 =0x00;
I2C_InitStruct.I2C_Ack = I2C_Ack_Enable;
I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
I2C_InitStruct.I2C_Timing = 0x00210507;
I2C_Init(I2C1, &I2C_InitStruct);
I2C_ITConfig(I2C1,I2C_IT_RXI | I2C_IT_TXI | I2C_IT_TCI | I2C_IT_STOPI,ENABLE);
// I2C1->CR1|=0x7F<<1; //¿ªÆôÖжÏ
I2C_Cmd(I2C1, ENABLE);
}
中断程序如下:
void sI2CInterrupt(void)
{
INT32U I2CFlagStatus = 0x00000000;
I2CFlagStatus = (uint32_t)(I2C1->ISR & (uint16_t)0x0000000F6);
if(I2C_GetITStatus(I2C1,I2C_ISR_TXIS) != RESET)
{
I2C_SendData(I2C1, Data2);
}
else if(I2C_GetITStatus(I2C1,I2C_IT_RXNE) != RESET) //Êý¾Ý½ÓÊÕÖжÏ
{
Data1 = I2C_ReceiveData(I2C1);
// I2C_ClearITPendingBit(I2C1, I2C_IT_RXNE);
}
else if(I2C_GetITStatus(I2C1,I2C_IT_STOPF) != RESET)
{
I2C_ClearITPendingBit(I2C1,I2C_IT_STOPF);
}
if(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == SET)
{
I2C_ClearFlag(I2C1, I2C_ICR_STOPCF);
}
}
你用的什么库做的,有什么问题?
手头有逻辑分析仪没,这个调起来很方便
还有CUBE库里有例程,而且函数封装的很完整,建议可以看看
回复:【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(操作BMP085气压传感器)
STM32F030探索套件开发日志,中文教程,使用问答80篇
回复:【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(操作BMP085气压传感器)
RE:【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(操作BMP085气压传感器)
RE:【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(操作BMP085气压传感器)
RE:【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(操作BMP085气压传感器)
回复:【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(操作BMP085气压传感器)
硬件I2C使用片内外设发送时序,当然你还是要对I2C时序非常清楚,片内外设在发送数据时,不同的时间会置不同的标志位,编程通过判断标志位的状态就来决定下一步的工作。