完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
楼主 是可以加的 但是自己做算法太麻烦了 不好弄 一般没人自己走
|
|
|
|
|
|
|
|
如果楼主只是单纯的想确保通讯的可靠 可以设置一时间段来等待从机应答,如果超时无应答的话可以设置重发机制,重发一次也就够了 如果还没有应答 就可以报警通知使用者检测总线了,一般我认为如果是模拟iic的话 还是比较可靠的
|
|
|
|
应该有应答信号就可以了。
|
|
|
|
超时检测肯定要的。。。至于其他的,就看自己的需求喽。。。
|
|
|
|
模拟I2C,不需要考虑那么多,严格按时序来就可以了。一定要按你从设备的时序来。
|
|
|
|
好的,谢谢给位大神的回复,我知道了。
|
|
|
|
主要是I2C操作完以后,要记得回复为空闲状态。遇到好几次因为单片机复位,但是外设没有断电情况下,I2C总线忙,导致通讯总是失败。
|
|
|
|
要的,卡在里面,多尴尬呀..
|
|
|
|
发一个我在用的IO模拟IIC程序给你,不需要判断超时
static void I2c_delay_us(uint32_t i) { for(i=0; i<72; i++) { ; } } static ErrorStatus I2C_Start(void) //I2C开始位 { Bsp_I2cSdaHigh(); Bsp_I2cSclHigh(); I2c_delay_us(5); if(!Bsp_IsI2cSda()) return ERROR; //SDA线为低电平则总线忙,退出 Bsp_I2cSdaLow(); I2c_delay_us(5); if(Bsp_IsI2cSda()) return ERROR; //SDA线为高电平则总线出错,退出 Bsp_I2cSdaLow(); //SCL为高电平时,SDA的下降沿表示停止位 I2c_delay_us(5); return SUCCESS; } static void I2C_Stop(void) //I2C停止位 { Bsp_I2cSclLow(); I2c_delay_us(5); Bsp_I2cSdaLow(); I2c_delay_us(5); Bsp_I2cSclHigh(); I2c_delay_us(5); Bsp_I2cSdaHigh(); //SCL为高电平时,SDA的上升沿表示停止位 I2c_delay_us(5); } static void I2C_Ack(void) //I2C响应位 { Bsp_I2cSclLow(); I2c_delay_us(5); Bsp_I2cSdaLow(); I2c_delay_us(5); Bsp_I2cSclHigh(); I2c_delay_us(5); Bsp_I2cSclLow(); I2c_delay_us(5); } static void I2C_NoAck(void) //I2C非响应位 { Bsp_I2cSclLow(); I2c_delay_us(5); Bsp_I2cSdaHigh(); I2c_delay_us(5); Bsp_I2cSclHigh(); I2c_delay_us(5); Bsp_I2cSclLow(); I2c_delay_us(5); } static ErrorStatus I2C_WaitAck(void) //I2C等待应答位 { Bsp_I2cSclLow(); I2c_delay_us(5); Bsp_I2cSdaHigh(); I2c_delay_us(5); Bsp_I2cSclHigh(); I2c_delay_us(5); if(Bsp_IsI2cSda()) { Bsp_I2cSclLow(); return ERROR; } Bsp_I2cSclLow(); return SUCCESS; } /******************************************************************************* * Function Name : I2C_SendByte * Description : 数据从高位到低位 * Input : - SendByte: 发送的数据 * Output : None * Return : None *******************************************************************************/ static void I2C_SendByte(uint8_t SendByte) { uint8_t i; for(i=0; i<8; i++) { Bsp_I2cSclLow(); I2c_delay_us(5); if(SendByte & 0x80) Bsp_I2cSdaHigh(); //在SCL为低电平时,允许SDA数据改变 else Bsp_I2cSdaLow(); SendByte <<= 1; I2c_delay_us(5); Bsp_I2cSclHigh(); I2c_delay_us(5); } Bsp_I2cSclLow(); } /******************************************************************************* * Function Name : I2C_ReceiveByte * Description : 数据从高位到低位 * Input : None * Output : None * Return : I2C总线返回的数据 *******************************************************************************/ static uint8_t I2C_ReceiveByte(void) { uint8_t i,ReceiveByte = 0; Bsp_I2cSdaHigh(); for(i=0; i<8; i++) { ReceiveByte <<= 1; Bsp_I2cSclLow(); I2c_delay_us(5); Bsp_I2cSclHigh(); I2c_delay_us(5); if(Bsp_IsI2cSda()) //在SCL为高电平时,SDA上的数据保持不变,可以读回来 { ReceiveByte |= 0x01; } } Bsp_I2cSclLow(); return ReceiveByte; } |
|
|
|
非常感谢,很有帮助 |
|
|
|
|
|
|
|
模拟I2C有必要吗?我记得有的程序里面有判断是否有ACK,也有的程序没有,可能如果在保证线路不会接触不良的情况下不需要判断是否有ACK吧
|
|
|
|
亲,有两个问题,(1)为什么起始信号中,对SDA有两次拉低,而SCLK拉高一次就不管了呢,我看别的例程就是将SDA拉低后将SCL也拉低;(2)每一个函数中不用设定IO的传输方向吗?比如ACK和等待ACK时SDA的传输方向是不同的啊? |
|
|
|
我是没加,不过我也支持加了能让程序变得更加谨慎
|
|
|
|
|
|
|
|
知道了,谢谢! |
|
|
|
|
|
|
|
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
STM32串口接受中断使用C++STL中的queue导致所有中断失效
2822 浏览 1 评论
2645 浏览 0 评论
STM32配合可编程加密芯片SMEC88ST的防抄板加密方案设计
1279 浏览 0 评论
3509 浏览 1 评论
AD7686芯片不传输数据给STM32,但是手按住就会有数据。
3306 浏览 4 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-31 12:59 , Processed in 0.913806 second(s), Total 111, Slave 94 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号