完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
#include
#include #define OP_READ 0xa1 // 器件地址以及读取操作,0xa1即为1010 0001B #define OP_WRITE 0xa0 // 器件地址以及写入操作,0xa1即为1010 0000B ***it SDA=P3^4; //将串行数据总线SDA位定义在为P3.4引脚 ***it SCL=P3^3; //将串行时钟总线SDA位定义在为P3.3引脚 /***************************************************** 函数功能:延时1ms (3j+2)*i=(3×33+2)×10=1010(微秒),可以认为是1毫秒 ***************************************************/ void delay1ms() { unsigned char i,j; for(i=0;i<10;i++) for(j=0;j<33;j++) ; } /***************************************************** 函数功能:延时若干毫秒 入口参数:n ***************************************************/ void delaynms(unsigned char n) { unsigned char i; for(i=0;i } /*************************************************** 函数功能:开始数据传送 ***************************************************/ void start() // 开始位 { SDA = 1; //SDA初始化为高电平“1” SCL = 1; //开始数据传送时,要求SCL为高电平“1” _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 SDA = 0; //SDA的下降沿被认为是开始信号 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 SCL = 0; //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递) } /*************************************************** 函数功能:结束数据传送 ***************************************************/ void stop() // 停止位 { SDA = 0; //SDA初始化为低电平“0” _n SCL = 1; //结束数据传送时,要求SCL为高电平“1” _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 SDA = 1; //SDA的上升沿被认为是结束信号 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 SDA=0; SCL=0; } /*************************************************** 函数功能:从AT24Cxx读取数据 出口参数:x ***************************************************/ unsigned char ReadData() // 从AT24Cxx移入数据到MCU { unsigned char i; unsigned char x; //储存从AT24Cxx中读出的数据 for(i = 0; i < 8; i++) { SCL = 1; //SCL置为高电平 x<<=1; //将x中的各二进位向左移一位 x|=(unsigned char)SDA; //将SDA上的数据通过按位“或“运算存入x中 SCL = 0; //在SCL的下降沿读出数据 } return(x); //将读取的数据返回 } /*************************************************** 函数功能:向AT24Cxx的当前地址写入数据 入口参数:y (储存待写入的数据) ***************************************************/ //在调用此数据写入函数前需首先调用开始函数start(),所以SCL=0 bit WriteCurrent(unsigned char y) { unsigned char i; bit ack_bit; //储存应答位 for(i = 0; i < 8; i++) // 循环移入8个位 { SDA = (bit)(y&0x80); //通过按位“与”运算将最高位数据送到S //因为传送时高位在前,低位在后 _nop_(); //等待一个机器周期 SCL = 1; //在SCL的上升沿将数据写入AT24Cxx _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 SCL = 0; //将SCL重新置为低电平,以在SCL线形成传送数据所需的8个脉冲 y <<= 1; //将y中的各二进位向左移一位 } SDA = 1; // 发送设备(主机)应在时钟脉冲的高电平期间(SCL=1)释放SDA线, //以让SDA线转由接收设备(AT24Cxx)控制 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 SCL = 1; //根据上述规定,SCL应为高电平 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 _nop_(); //等待一个机器周期 ack_bit = SDA; //接受设备(AT24Cxx)向SDA送低电平,表示已经接收到一个字节 //若送高电平,表示没有接收到,传送异常 SCL = 0; //SCL为低电平时,SDA上数据才允许变化(即允许以后的数据传递) return ack_bit; // 返回AT24Cxx应答位 } /*************************************************** 函数功能:向AT24Cxx中的指定地址写入数据 入口参数:add (储存指定的地址);dat(储存待写入的数据) ***************************************************/ void WriteSet(unsigned char add, unsigned char dat) // 在指定地址addr处写入数据WriteCurrent { start(); //开始数据传递 WriteCurrent(OP_WRITE); //选择要操作的AT24Cxx芯片,并告知要对其写入数据 WriteCurrent(add); //写入指定地址 WriteCurrent(dat); //向当前地址(上面指定的地址)写入数据 stop(); //停止数据传递 delaynms(4); //1个字节的写入周期为1ms, 最好延时1ms以上 } /*************************************************** 函数功能:从AT24Cxx中的当前地址读取数据 出口参数:x (储存读出的数据) ***************************************************/ unsigned char ReadCurrent() { unsigned char x; start(); //开始数据传递 WriteCurrent(OP_READ); //选择要操作的AT24Cxx芯片,并告知要读其数据 x=ReadData(); //将读取的数据存入x stop(); //停止数据传递 return x; //返回读取的数据 } /*************************************************** 函数功能:从AT24Cxx中的指定地址读取数据 入口参数:set_addr 出口参数:x ***************************************************/ unsigned char ReadSet(unsigned char set_addr) // 在指定地址读取 { start(); //开始数据传递 WriteCurrent(OP_WRITE); //选择要操作的AT24Cxx芯片,并告知要对其写入数据 WriteCurrent(set_addr); //写入指定地址 return(ReadCurrent()); //从指定地址读出数据并返回 } /*************************************************** 函数功能:主函数 ***************************************************/ main(void) { SDA = 1; // SDA=1,SCL=1,使主从设备处于空闲状态 SCL = 1; WriteSet(0x36,0x0f); //在指定地址“0x36”中写入数据“0x0f” P1=ReadSet(0x36); //从指定地址“0x36中读取数据并送P1口显示 } 图片在附件中
|
|
相关推荐
7个回答
|
|
看看IIC协议吧,这个由协议来决定。时序是重要因素。
最佳答案
|
|
|
|
忘了给分了,我会补上的,大侠们求帮忙
|
|
|
|
怎么判定搞出来的它写入地址和写入的数据,它调用的是一个函数啊,怎么区分的呢
|
|
|
|
我觉得你的程序注释已经可以解答你的疑惑了吧……
|
|
|
|
一般有注释的程序都可以看出个大概来
|
|
|
|
地址+1就是读取,直接地址就是写。
|
|
|
|
你应该好好看看IIC协议
|
|
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
【敏矽微ME32G070开发板免费体验】使用coremark测试敏矽微ME32G070 跑分
250 浏览 0 评论
【敏矽微ME32G070开发板免费体验】开箱+点灯+点亮OLED
473 浏览 2 评论
571 浏览 0 评论
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-内核编译之初次编译
260 浏览 0 评论
400 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11974 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-20 02:18 , Processed in 0.502375 second(s), Total 53, Slave 45 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号