本人菜鸟,初学STM32F4 在调试I2C程序时,用I2C1作为主发送,I2C2作为从接收,进行自发自收,可是程序一直卡在while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));上,一直找不出原因,求高手指导 以下是全部代码 #include"stm32F4xx.h" void RCC_Configuration(void); void GPIO_Configuration(void); void I2C_Configuration(void); void I2C_start(I2C_TypeDef* I2Cx, uint8_t address, uint8_t direction); void I2C_write(I2C_TypeDef* I2Cx, uint8_t data); uint8_t I2C_read_ack(I2C_TypeDef* I2Cx); uint8_t I2C_read_nack(I2C_TypeDef* I2Cx); void I2C_stop(I2C_TypeDef* I2Cx); void Delay(int nCount); int main(void) { RCC_Configuration(); GPIO_Configuration(); I2C_Configuration(); while(1) { int data=0; I2C_start(I2C1,0x300;c2--); }; } |
STM32F407 定时器触发DMA 求助大神
【MCU实战经验】基于STM32F407的音频播放器设计
盘古UE-STM32F407工控板原理图
【STM32F429心得\疑问】+STM32F4之FSMC和FMC
STM32F429读取IO口传输的数据速率
STM32F407ZGT6 手摸芯片背部重启
STM32F4 SPI 动作时,软件片选信号被拉高,IO口程序逻辑失控
STM32F401RE NUCLEO求助,串口一直不能进中断
读取STM32F407内部温度传感器值错误
STM32F429多路内部ADC独立采集的办法
RE:STM32F4 I2C 查询方式 自发自收问题
如果你把这两个函数理解好了,后面页写函数和随机写函数都能搞定了。
void I2C_Write_OneByte(unsigned char Write_Addr,unsigned char Data)
{
/*!< While the bus is busy */
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
{
}
/* Start the config sequence */
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) /* Test on EV5 and clear it */
{
}
I2C_Send7bitAddress(I2C1, EE_ADDRESS, I2C_Direction_Transmitter); /* Transmit the slave address and enable writing operation */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) /* Test on EV6 and clear it */
{
}
I2C_SendData(I2C1, Write_Addr); /* Transmit the first address for write operation */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING)) /* Test on EV8 and clear it */
{
}
I2C_SendData(I2C1, Data); /* Prepare the register value to be sent */
/*!< Wait till all data have been physically transferred on the bus */
while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF))
{
}
/* End the configuration sequence */
I2C_GenerateSTOP(I2C1, ENABLE);
}
unsigned char I2C_Read_OneByte(unsigned char Read_Addr)
{
unsigned char temp = 0;
unsigned int Timeout=0;
Timeout = I2C_Timeout ;
//I2C_AcknowledgeConfig(I2C1, ENABLE);
/*!< While the bus is busy */
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
{
if((Timeout--) == 0) return 1;
}
/* Start the config sequence */
I2C_GenerateSTART(I2C1, ENABLE);
Timeout = I2C_Timeout ;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) /* Test on EV5 and clear it */
{
if((Timeout--) == 0) return 1;
}
/* Transmit the slave address and enable writing operation */
I2C_Send7bitAddress(I2C1, EE_ADDRESS, I2C_Direction_Transmitter);
Timeout = I2C_Timeout ;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) /* Test on EV6 and clear it */
{
if((Timeout--) == 0) return 1;
}
/* Transmit the register address to be read */
I2C_SendData(I2C1, Read_Addr);
Timeout = I2C_Timeout ;
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF) == RESET) /* Test on EV8 and clear it */
{
if((Timeout--) == 0) return 1;
}
/*!< Send START condition a second time */
I2C_GenerateSTART(I2C1, ENABLE);
Timeout = I2C_Timeout ;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */
{
if((Timeout--) == 0) return 1;
}
/*!< Send device address for read */
I2C_Send7bitAddress(I2C1, EE_ADDRESS, I2C_Direction_Receiver);
/* Wait on ADDR flag to be set (ADDR is still not cleared at this level */
Timeout = I2C_Timeout ;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR) == RESET) //EV6
{
if((Timeout--) == 0) return 1;
}
/*!< Disable Acknowledgment */
I2C_AcknowledgeConfig(I2C1, DISABLE);
/* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */
(void)I2C1->SR2;
/*!< Send STOP Condition */
I2C_GenerateSTOP(I2C1, ENABLE);
/* Wait for the byte to be received */
Timeout = I2C_Timeout ;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET)
{
if((Timeout--) == 0) return 1;
}
/*!< Read the byte received from the device */
temp = I2C_ReceiveData(I2C1);
/* Wait to make sure that STOP flag has been cleared */
Timeout = I2C_Timeout ;
while(I2C1->CR1 & I2C_CR1_STOP)
{
if((Timeout--) == 0) return 1;
}
/*!< Re-Enable Acknowledgment to be ready for another reception */
I2C_AcknowledgeConfig(I2C1, ENABLE);
/* Clear AF flag for next communication */
I2C_ClearFlag(I2C1, I2C_FLAG_AF);
/* Return the byte read from device */
return temp;
}
RE:STM32F4 I2C 查询方式 自发自收问题
回复:STM32F4 I2C 查询方式 自发自收问题
RE:STM32F4 I2C 查询方式 自发自收问题
回复:STM32F4 I2C 查询方式 自发自收问题
ST的IIC为了规避专利,采用了独特的设计,楼主做硬件IIC时要严格遵守ST的设计思路才行,要不然容易出错。我花了一周的时间才把硬件IIC搞定,下面给你提供已经调试成功的两个函数作为参考:
如果你把这两个函数理解好了,后面页写函数和随机写函数都能搞定了。
void I2C_Write_OneByte(unsigned char Write_Addr,unsigned char Data)
{
/*!< While the bus is busy */
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
{
}
/* Start the config sequence */
I2C_GenerateSTART(I2C1, ENABLE);
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) /* Test on EV5 and clear it */
{
}
I2C_Send7bitAddress(I2C1, EE_ADDRESS, I2C_Direction_Transmitter); /* Transmit the slave address and enable writing operation */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) /* Test on EV6 and clear it */
{
}
I2C_SendData(I2C1, Write_Addr); /* Transmit the first address for write operation */
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING)) /* Test on EV8 and clear it */
{
}
I2C_SendData(I2C1, Data); /* Prepare the register value to be sent */
/*!< Wait till all data have been physically transferred on the bus */
while(!I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF))
{
}
/* End the configuration sequence */
I2C_GenerateSTOP(I2C1, ENABLE);
}
unsigned char I2C_Read_OneByte(unsigned char Read_Addr)
{
unsigned char temp = 0;
unsigned int Timeout=0;
Timeout = I2C_Timeout ;
//I2C_AcknowledgeConfig(I2C1, ENABLE);
/*!< While the bus is busy */
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY))
{
if((Timeout--) == 0) return 1;
}
/* Start the config sequence */
I2C_GenerateSTART(I2C1, ENABLE);
Timeout = I2C_Timeout ;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) /* Test on EV5 and clear it */
{
if((Timeout--) == 0) return 1;
}
/* Transmit the slave address and enable writing operation */
I2C_Send7bitAddress(I2C1, EE_ADDRESS, I2C_Direction_Transmitter);
Timeout = I2C_Timeout ;
while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)) /* Test on EV6 and clear it */
{
if((Timeout--) == 0) return 1;
}
/* Transmit the register address to be read */
I2C_SendData(I2C1, Read_Addr);
Timeout = I2C_Timeout ;
while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BTF) == RESET) /* Test on EV8 and clear it */
{
if((Timeout--) == 0) return 1;
}
/*!< Send START condition a second time */
I2C_GenerateSTART(I2C1, ENABLE);
Timeout = I2C_Timeout ;
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)) /*!< Test on EV5 and clear it (cleared by reading SR1 then writing to DR) */
{
if((Timeout--) == 0) return 1;
}
/*!< Send device address for read */
I2C_Send7bitAddress(I2C1, EE_ADDRESS, I2C_Direction_Receiver);
/* Wait on ADDR flag to be set (ADDR is still not cleared at this level */
Timeout = I2C_Timeout ;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_ADDR) == RESET) //EV6
{
if((Timeout--) == 0) return 1;
}
/*!< Disable Acknowledgment */
I2C_AcknowledgeConfig(I2C1, DISABLE);
/* Clear ADDR register by reading SR1 then SR2 register (SR1 has already been read) */
(void)I2C1->SR2;
/*!< Send STOP Condition */
I2C_GenerateSTOP(I2C1, ENABLE);
/* Wait for the byte to be received */
Timeout = I2C_Timeout ;
while(I2C_GetFlagStatus(I2C1, I2C_FLAG_RXNE) == RESET)
{
if((Timeout--) == 0) return 1;
}
/*!< Read the byte received from the device */
temp = I2C_ReceiveData(I2C1);
/* Wait to make sure that STOP flag has been cleared */
Timeout = I2C_Timeout ;
while(I2C1->CR1 & I2C_CR1_STOP)
{
if((Timeout--) == 0) return 1;
}
/*!< Re-Enable Acknowledgment to be ready for another reception */
I2C_AcknowledgeConfig(I2C1, ENABLE);
/* Clear AF flag for next communication */
I2C_ClearFlag(I2C1, I2C_FLAG_AF);
/* Return the byte read from device */
return temp;
}
请问下,就是在发送从地址时,到底address左不左移一位,我左移后从设备就没有应答了?如果不左移,从设备应答,但又卡在while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));这句,数据寄存器的数据一直发不出。。。
回复:STM32F4 I2C 查询方式 自发自收问题
用示波器或逻辑分析仪看看波形
看了,就是在时钟第九位时没有应答,我把address不左移,后用库函数就有应答,但是卡在while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));这句上,数据发不出去
回复:STM32F4 I2C 查询方式 自发自收问题
是不是硬件不通?
感觉有点儿像,不过我用的是开发板,是微雪电子的M4,portZ系列
RE:STM32F4 I2C 查询方式 自发自收问题
在配置I2C的接口地址时,向I2C_OAR1寄存器写的地址是自己随便确定的吗?只要保证与I2C设备不重复即可?