完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
#include
#include #define I2CDelay() {_nop_();_nop_();_nop_();_nop_();} ***it SDA=P3^6; ***it SCL=P3^7; //产生总线起始信号号 void I2CStart() { SCL=1; SDA=1; I2CDelay(); //确保SDA产生下降沿信号时SCL为高电平 SDA=0; //拉低SDA产生一个下降沿 I2CDelay(); //延时确保产生下降沿后稳定 SCL=0; //此时拉低SCL后SDA可变,即可以准备发送的信号 } //产生总线停止信号 void I2CStop() { SCL=0; //拉低SDA,SCL SDA=0; I2CDelay(); SCL=1; // 拉低SCL I2CDelay(); //确保SDA产生上升沿时,SCL为低电平。 SDA=1; //产生一个上升沿 I2CDelay(); // } //I2C总线写操作,dat为待写入的字节 bit IC2Write(unsigned char dat) { bit ACK; //用与暂存丛机应答的值 unsigned char mask; //用于探测写入字节内某一位掩码的变量 for(mask=0x80;mask!=0;mask>>=1) //主机要发送的数据,先发送高位再发送低位 此处有疑问 { if(mask&dat==0) //dat不是一位么,I2C总线是一位一位的发送的,这里按位与后不是一个char型与一位与么。懵逼请教大能。萌新。后面读操作也类似。 { SDA=0; } else { SDA=1; } I2CDelay(); //延时使其保持一段时间 SCL=1; //拉高SCL I2CDelay(); //再拉高SCL期间,SDA不可变。因为此时丛机会读取SDA,若SDA改变,则读取可能错误 SCL=0; //再拉低SCL完成一个位周期 } SDA=1; //8位数据发送完毕后,主机必须释放SDA线,以便从机进行应答 I2CDelay(); //丛机通过拉低或拉高SDA进行应答 SCL=1; //拉高SCL从机即能应答 ACK=SDA; //读取此时SDA的值即为从机的应答值 I2CDelay(); SCL=0; //再拉低SCL完成应答位 return ~ACK; //将应答值返回调用其的函数0表示成功,1表示发送失败。此处~为正常逻辑 } //I2C总线的读操作,并发送非应答信号,返回值为读到的字节 unsigned char I2CReadyNAck() { unsigned char mask; unsigned char dat; //所读数据缓冲区 SDA=1; //读之前自己引脚为高电平 与按键类似,避免占用总线 for(mask=0x80;mask!=0;mask>>=1) { I2CDelay(); SCL=1; if(SDA==0) { dat&=~mask; //将dat对应的位清零 } else { dat|=mask; } I2CDelay(); SCL=0; //再拉低SCL以使丛机发送下一位 } SDA=1; //当丛机将8位数据发送完毕后,拉高SDA,发送非应答信号 I2CDelay(); SCL=1; I2CDelay(); SCL=0; //再次拉低SCL完成非应答位,并保持住总线 return dat; //将读到的数据返回 } //I2C总线读操作,并发送应答信号,返回值位为读到的字节 unsigned char I2CReadyAck() { unsigned char mask; unsigned char dat; //所读字节缓冲区 SDA=1; //确保主机释放SDA for(mask=0x08;mask!=0;mask>>=1) { I2CDelay(); SCL=1; if(SDA==0) { dat&=~mask; } else(dat|=mask); I2CDelay(); SCL=0; //在拉低SCL,以使丛机发送出下一位 } SDA=0; //8为数据发送完毕后,拉低SDA,发送应答信号 I2CDelay(); SCL=1; //拉高SCL I2CDelay(); SCL=0; //再拉低SCL完成应答位,并保持住总线 此处保持住总线是扫描意思? return dat; } 请教老司机解答,实在蒙蔽,有些注释是我自己理解注释的有错误老司机见谅 |
|
相关推荐
3个回答
|
|
1. dat不是1位,而是1个字节。
函数IC2Write的作用就是发送1个字节的数据,当然也是1位1位发送的。 掩码mask从10000000b到00000001b对dat进行8次扫描,如果是0就发送0(SDA=0)否则发送1(SDA=1) 2. 总线保持有2个意义: (1)表示传输过程未结束(一般指还有别的数据要传) (2)如果总线上存在多个主设备,SCL总线置零是为了告诉其他主设备:现在总线正在被占用,请稍后使用。
最佳答案
|
|
|
|
Ansersion 发表于 2018-7-1 17:04 感谢解答,谢谢老哥。 |
|
|
|
学习楼上。
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
386 浏览 0 评论
求助一下关于51系列单片机的Timer0的计时问题,TH0、TL0+1的时间是怎么算的?
1670 浏览 1 评论
【RA-Eco-RA4E2-64PIN-V1.0开发板试用】开箱+Keil环境搭建+点灯+点亮OLED
1123 浏览 0 评论
【敏矽微ME32G070开发板免费体验】使用coremark测试敏矽微ME32G070 跑分
1005 浏览 0 评论
【敏矽微ME32G070开发板免费体验】开箱+点灯+点亮OLED
1229 浏览 2 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
12018 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 12:38 , Processed in 0.646479 second(s), Total 77, Slave 60 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号