【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代码用于游戏方向盘
你有做过stm32f030的i2c读写eeprom的吗?现在正做这一块,调试中有点问题,可否请你指导一下!谢谢!
你用的什么库做的,有什么问题?
手头有逻辑分析仪没,这个调起来很方便
还有CUBE库里有例程,而且函数封装的很完整,建议可以看看
我的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));
}
}
你好,用过的,怎么了,你用的哪个库
我用的的标准库stm32f0_stdperiph_lib.zip,你用的是哪个库,可否分享下你的中断方式啊?调了3天了,还是不能进入接收中断,我是用stm32f030的i2c读写EEPROM的数据。谢谢了
有逻辑分析仪的,就没怎么用过分析仪,我的这个只能进一次发送中断,然后就进不去了
我把我配置的程序发出来
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);
}
}
您好,您的程序能发我一份吗?我参考下。。。99834014@qq.com
谢谢您!
你要查询方式的代码吗??