【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(...
上次给大家分享了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总线上的某一器件的某一起始地址中读取一定字节的数据到数组中
* @paramdriver_Addr:I2C器件地址
* @paramstart_Addr:起始字节地址
* @paramnumber_Bytes:要读取的字节数量(小于一页)
* @paramread_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 = 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的总线上的某一器件的某一起始地址中读取一定字节的数据到数组中
* @paramdriver_Addr:I2C器件地址
* @paramstart_Addr:起始字节地址
* @paramnumber_Bytes:要读取的字节数量(小于一页)
* @paramwrite_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);
}
I2C_Timeout = I2C_TIMEOUT;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_STOPF) == RESET)
{
if((I2C_Timeout--) == 0)
{
return I2C_FAIL;
}
}
return I2C_OK;
}
alisa123 发表于 2015-10-12 22:01
我用的也是标准库,cube库之前一直没用过,好看明白吗?我还没调试成功,我明早吧代码上传,请你帮我看看好 ...
我的i2c配置程序如下,请楼主帮忙看看那里有问题,谢谢!
void I2C_Configuration(void)
{
GPIO_InitTypeDefGPIO_InitStruct;
I2C_InitTypeDefI2C_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= 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= 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= 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;
}
/*******************************************************************************
* @briefWrites 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).
*
* @parampBuffer: pointer to the buffer containing the data to be written to
* the EEPROM.
* @paramWriteAddr: EEPROM's internal address to write to.
* @paramNumByteToWrite: 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));
/* 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;
}
/*******************************************************************************
* @briefWrites buffer of data to the I2C EEPROM.
* @parampBuffer: pointer to the buffercontaining the data to be written
* to the EEPROM.
* @paramWriteAddr: EEPROM's internal address to write to.
* @paramNumByteToWrite: 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();
}
}
}
}
/*******************************************************************************
* @briefWait for EEPROM Standby state.
*
* @noteThis 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.
*
* @paramNone
*
* @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));
}
} lkl0305 发表于 2016-3-14 15:58
我现在基本用HAL库,用起来放便些,我这两天给你看看,你没有逻辑分析仪之类的么,调试一下看看哪里有问题 ...
有逻辑分析仪的,就没怎么用过分析仪,我的这个只能进一次发送中断,然后就进不去了
我把我配置的程序发出来
void I2C_Configuration(void)
{
GPIO_InitTypeDefGPIO_InitStruct;
I2C_InitTypeDefI2C_InitStruct;
NVIC_InitTypeDefNVIC_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);
}
} alisa123 发表于 2015-10-12 18:08
你有做过stm32f030的i2c读写eeprom的吗?现在正做这一块,调试中有点问题,可否请你指导一下!谢谢!
...
你用的什么库做的,有什么问题?
手头有逻辑分析仪没,这个调起来很方便
还有CUBE库里有例程,而且函数封装的很完整,建议可以看看
回复:【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(操作BMP085气压传感器)
继续阅读原创汇总:STM32F030探索套件开发日志,中文教程,使用问答80篇
回复:【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(操作BMP085气压传感器)
帮了大忙了:LRE:【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(操作BMP085气压传感器)
请问有关I2C中断主从收发,能不能讲解指点一下呀?RE:【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(操作BMP085气压传感器)
谢谢分享RE:【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(操作BMP085气压传感器)
谢谢分享,学习一下回复:【STM32F030开发日志/评测/笔记】+(2)STM32F0处理器I2C实例(操作BMP085气压传感器)
硬件I2C不需要管SCL,SDA的时序问题吗 顶顶顶顶顶顶顶顶顶顶顶顶顶顶 youyou202 发表于 2014-8-23 12:44硬件I2C不需要管SCL,SDA的时序问题吗
硬件I2C使用片内外设发送时序,当然你还是要对I2C时序非常清楚,片内外设在发送数据时,不同的时间会置不同的标志位,编程通过判断标志位的状态就来决定下一步的工作。 学习了,可以看看! 学习很不错啊 谢谢分享 STM32F0处理器I2C实例 :loveliness::loveliness::loveliness::loveliness::loveliness::loveliness: :loveliness::loveliness::loveliness::loveliness::loveliness: