完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本人菜鸟,初学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--); }; } |
|
相关推荐
10个回答
|
|
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; } |
|
|
|
用示波器或逻辑分析仪看看波形
|
|
|
|
是不是硬件不通?
|
|
|
|
示波器观察数据是否发出,数据石头接收到
|
|
|
|
回复第 2 楼 于2014-01-12 12:36:11发表:
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));这句,数据寄存器的数据一直发不出。。。 |
|
|
|
回复第 3 楼 于2014-01-12 15:07:50发表:
用示波器或逻辑分析仪看看波形 看了,就是在时钟第九位时没有应答,我把address不左移,后用库函数就有应答,但是卡在while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));这句上,数据发不出去 |
|
|
|
|
|
|
|
我们不使用STM32的硬件IIC来读写24C02,而是通过软件模拟。STM32的硬件IIC非常复杂,更重要的是不稳定,故不推荐使用
|
|
|
|
学习了。。。哈
|
|
|
|
maruidiyi 发表于 2018-10-23 15:23 在配置I2C的接口地址时,向I2C_OAR1寄存器写的地址是自己随便确定的吗?只要保证与I2C设备不重复即可? |
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
1129 浏览 0 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
1075 浏览 2 评论
2175 浏览 0 评论
如何解决MPU-9250与STM32通讯时,出现HAL_ERROR = 0x01U
1269 浏览 1 评论
hal库中i2c卡死在HAL_I2C_Master_Transmit
1693 浏览 1 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-26 03:29 , Processed in 0.818362 second(s), Total 92, Slave 73 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号