搜索
bottom↓
回复: 45

我也发一个IIC的程序吧,是IAR+24系列读写。支持24C01到24C512,直接粘贴即可以用。

[复制链接]

出0入0汤圆

发表于 2006-3-21 16:08:35 | 显示全部楼层 |阅读模式
//我也发一个IIC的程序吧,是IAR+24系列读写。支持24C01到24C512,直接粘贴即可以用。



#define uchar unsigned char

#define uint unsigned int



#include<iom16.h>

#include<ioavr.h>

#include<comp_a90.h>

#include"oil_include.h"



extern uchar iic_data[8];

extern volatile uchar temp_iic;



//设置IIC的延时时间

void delay_iic(void)

{

  delay_1us();

}



//IIC初始化SCL SDA均为输出 "1"

void iic_init(void)

{

  SETBIT(PORTIIC,SCL);

  SETBIT(DDRIIC,SCL);

  SETBIT(PORTIIC,SCL);



  SETBIT(PORTIIC,SDA);

  SETBIT(DDRIIC,SDA);

  SETBIT(PORTIIC,SDA);

}



//IIC写一个字节

uchar iic_write_byte(uchar write_byte)

{

  uchar i;

  for(i=0;i<8;i++)

  {

    CLEARBIT(PORTIIC,SCL);

    if(((write_byte<<i) & 0x80) == 0)CLEARBIT(PORTIIC,SDA);

    else SETBIT(PORTIIC,SDA);

    SETBIT(PORTIIC,SCL);

  }

  CLEARBIT(PORTIIC,SCL);

  SETBIT(PORTIIC,SDA);

  CLEARBIT(DDRIIC,SDA);

  SETBIT(PORTIIC,SDA);

  SETBIT(PORTIIC,SCL);

  delay_1us();

  i=TESTBIT(PINIIC,SDA);

  CLEARBIT(PORTIIC,SCL);

  SETBIT(DDRIIC,SDA);

  return(i);

}



//IIC写N个字节

uchar iic_write_nbyte(uint data_address,uchar write_nbyte)

{

  uchar chip_address=IIC_ADDRESS;

  uchar data_addressh,data_addressl;

  uchar iic_dpr=0x00;

  data_addressl=data_address;

  data_addressh=data_address>>8;

  iic_start();

  temp_iic=iic_write_byte(chip_address);

  temp_iic=iic_write_byte(data_addressh);

  temp_iic=iic_write_byte(data_addressl);

  while(write_nbyte--)

  {

    temp_iic=iic_write_byte(iic_data[iic_dpr++]);

  }

  iic_stop();



    return(temp_iic);

}



//IIC读一个字节

uchar iic_read_byte(void)

{

  uchar i;

  CLEARBIT(PORTIIC,SCL);

  CLEARBIT(DDRIIC,SDA);

  SETBIT(PORTIIC,SDA);

  temp_iic=0x00;

  for(i=0;i<8;i++)

  {

    SETBIT(PORTIIC,SCL);

    if(TESTBIT(PINIIC,SDA))

    {

      SETBIT(temp_iic,(7-i));

    }

    else

    {

      CLEARBIT(temp_iic,(7-i));

    }

    CLEARBIT(PORTIIC,SCL);

  }

  SETBIT(DDRIIC,SDA);



    return(temp_iic);

}



//IIC读N个字节

uchar iic_read_nbyte(uint data_address,uchar read_nbyte)

{

  uchar chip_address=IIC_ADDRESS;

  uchar data_addressh,data_addressl;

  uchar iic_dpr=0x00;

  data_addressl=data_address;

  data_addressh=data_address>>8;

  iic_start();

  temp_iic=iic_write_byte(chip_address);

  temp_iic=iic_write_byte(data_addressh);

  temp_iic=iic_write_byte(data_addressl);

  iic_start();

  temp_iic=iic_write_byte(chip_address | 0x01);

  while(read_nbyte--)

  {

    iic_data[iic_dpr++]=iic_read_byte();

    if(read_nbyte != 0x00)

    {

      CLEARBIT(PORTIIC,SDA);

      NOP;

      NOP;

      NOP;

      NOP;

      SETBIT(PORTIIC,SCL);

    }

  }

  iic_stop();



    return(temp_iic);

}



//IIC写命令

uchar iic_write_command(uchar write_byte)

{

    return(0);

}



//IIC起始

uchar iic_start(void)

{

  SETBIT(PORTIIC,SCL);

  delay_1us();

  SETBIT(PORTIIC,SDA);

  SETBIT(DDRIIC,SDA);

  CLEARBIT(PORTIIC,SDA);

  delay_1us();

  CLEARBIT(PORTIIC,SCL);



    return(0);

}



//IIC结束

uchar iic_stop(void)

{

  SETBIT(DDRIIC,SDA);

  CLEARBIT(PORTIIC,SDA);

  CLEARBIT(PORTIIC,SCL);

  SETBIT(PORTIIC,SCL);

  delay_1us();

  SETBIT(PORTIIC,SDA);

  delay_1us();



    return(0);

}

出0入0汤圆

发表于 2006-3-21 17:07:50 | 显示全部楼层
中间delay_1us(); 延时时间不是精确的吧?应该要长一点时间的吧?

出0入0汤圆

 楼主| 发表于 2006-4-2 14:18:58 | 显示全部楼层
阿莫:我共享我我的IAR IIC 的程序,强烈要求把这个帖子也加为酷帖。

出0入0汤圆

发表于 2006-4-2 23:53:37 | 显示全部楼层
不错!

出0入0汤圆

发表于 2006-4-3 00:32:47 | 显示全部楼层
问个问题,为什么不用AVR自己的TWI而要用软件模拟?姑且不论CPU开销上的差距,就单以硬件TWI的每TWI时钟周期8次采样来说,软件要做到同样效果需要的代价是否已然太大了?何况楼主的程序根本没有做到这一点



喜欢DIY是好习惯,但坚持DIY以至于连MCU开发最基本的原则及目标都不要了,是否就有些本末倒置了?

出0入0汤圆

 楼主| 发表于 2006-4-3 09:15:06 | 显示全部楼层
老大,现在用硬件IIC接口的人毕竟不多,因为硬件IIC对硬件要求较高。

特别是对于IIC芯片的更换不利,所以我一般还是喜欢用软件模拟的,这样不但以后换IIC的型号或者厂家什么的都不受硬件接口的影响,还有一个更大的好处是我随便用哪个IO口都可以的哦。



硬件作IIC当然是好事,以后肯定也会用,但暂时不会,只有当CPU座软件IIC速度跟不上的时候,或者是CPU的工作效率低的时候会考虑的。

出0入0汤圆

发表于 2006-4-3 09:15:26 | 显示全部楼层
模拟的看起来清晰但是要占用更多的资源,软件空间要更多。

出0入0汤圆

发表于 2006-4-3 09:28:59 | 显示全部楼层
==================

老大,现在用硬件IIC接口的人毕竟不多,因为硬件IIC对硬件要求较高。

==================



恰恰相反,我看了那么许多国外作品,就没见过一个AVR访问IIC子设备不用硬件TWI的例子,同时,TWI硬件是和CPU核同时工作的,并且遵循严格的规范——这一点上,软件是绝对比不上的,更加谈不上什么“对硬件要求较高”——除非你用的根本不是标准IIC协议



==================

特别是对于IIC芯片的更换不利,所以我一般还是喜欢用软件模拟的,这样不但以后换IIC的型号或者厂家什么的都不受硬件接口的影响

==================



烦请举一例说明,哪款用IIC接口对外通讯的下位IC不能被AVRmega系列的硬件TWI接口100%兼容的,若举不出例子,请自承自信不足,多谢合作



==================

还有一个更大的好处是我随便用哪个IO口都可以的哦。

==================



固然你如果打算用AVR做IIC路由器,是必须有一个软件模拟IIC接口的,但除此以外,能给我解释下什么样的系统会用尽哪怕是7位IIC的地址空间呢?



==================

硬件作IIC当然是好事,以后肯定也会用,但暂时不会,只有当CPU座软件IIC速度跟不上的时候,或者是CPU的工作效率低的时候会考虑的。

==================



软件模拟的话,需要花费大量的时间在循环等待上,此时你的MCU必然要以最高功率运转却完全得不到任何回报



而直接使用硬件TWI的话,即使你不打算让CPU核同时作一些其他更有意义的事情,至少也可以让它sleep掉,这也就意味着你至少能把 MCU 的功耗降低4/5以上——对于嵌入式系统,功耗减小的意义不用我说了吧?



说到底,自己把握不了MCU就要自承,大家都是从新手过来的,没人会因为你用不好MCU的全部功能而嘲笑你,但绝对会有人因为你不敢尝试用好MCU的全部功能而看不起你,话虽难听,但道理实际上就是这个样子



最后,AVR是AVR,51是51,请不要把51时代的思考习惯带到AVR上——当然,同理可证,使用AVR的思考习惯也不应该带到ARM或PC上,不过这是后话了
-----此内容被watercat于2006-04-03,09:30:32编辑过

出0入0汤圆

 楼主| 发表于 2006-4-3 10:43:49 | 显示全部楼层
watercat老大,您批评的对,我确实不应该把51的思维带到这里,可现实情况确实是硬件IIC用的人少,至少我周围的人是这样。



我也说了,现在我作的东西都比较简单,还谈不上速度效率之类的,但将来会考虑的,到时候有问题还要多请教亚。



这个程序只是给大家提供一个范例,并不是要求大家都这样用,毕竟软件模拟IIC协议也是搞硬件必须要掌握的嘛,我是看这里用IAR 的人少,所以贴一个自己做的IAR上用的IIC范例罢了。



我用51时间长,接触AVR时间短,IAR也是头回用,错误也难免,希望老大多赐教呀 。

出0入0汤圆

发表于 2006-4-3 11:06:49 | 显示全部楼层
楼主还没有回答我1楼的问题呢?因为我不懂IAR!如果是CV,GCC的话,delay_1us(); 延时时间是精确的,那样的话,延时时间可能不是很够。4.7us是标准的吧?



另外硬件IIC可以达到的速度更高,用软件模拟的话速度难以达到。

出0入0汤圆

发表于 2006-4-3 11:10:52 | 显示全部楼层
搞硬件未必就需要知道如何掌握软件模拟IIC协议——固然IIC协议简单容易模拟,但如果是CAN呢?Ethernet呢?



尽可能多的利用别人已经做好的优秀的东西,把精力集中在自己项目必须的内容上,才能更快的提高自身——起码,我是这么认为的

出0入0汤圆

发表于 2006-4-3 11:15:41 | 显示全部楼层
我也用的是软件模拟的, 也没有什么问题,





watercat 能不能上个硬件的范例呢?

出0入0汤圆

发表于 2006-4-3 11:20:08 | 显示全部楼层
赞成watercat“尽可能多的利用别人已经做好的优秀的东西,把精力集中在自己项目必须的内容上”的观点。



人的精力是有限的,吸取前人的精华,缩短开发时间,把精力放在主要问题上。

出0入0汤圆

 楼主| 发表于 2006-4-3 12:01:41 | 显示全部楼层
IIC芯片的速度跟电压有关,在5V时能达到1M,2.7V时达到400K,1.8V时只有100K。可以查看具体器件的手册。



我是按照400K的速度进行模拟IIC的,用的是8M的内部时钟频率,程序我都使用过了,实际上速度也不错。这个程序使目前我的一个项目中用的。



对于延时我有的用几个NOP就可以,有的用delay延时。

delay()

{

NOP;

}

象这样的一个延时在调用到返回差不多就是8个指令周期,也就是1us,这是我看C编译后的汇编查到的。



但不一定很准确,毕竟优化不一样,编译器不一样,结果也就不打一样罢了。

出0入0汤圆

发表于 2006-4-3 13:23:25 | 显示全部楼层
watercat:

M48的IIC速度很慢。不知怎么设计的。

出0入0汤圆

发表于 2006-4-3 14:10:52 | 显示全部楼层
楼主,还要请教你一个问题:

你说“支持24C01到24C512”,我想时序应该是没有问题的,我用的比较多的是24C02,地址只需要1个字节就可以了,但是我发现你的程序中的地址是用uint data_address,不知道这样行不行呢?是否要判断是否该发送高地址呢?你现在是



temp_iic=iic_write_byte(data_addressh);

temp_iic=iic_write_byte(data_addressl);



高低地址一起发的。

出0入0汤圆

 楼主| 发表于 2006-4-3 15:39:33 | 显示全部楼层
没错,这是为了支持16位地址,所以要发送两次地址,如果只支持8位地址,少发一个即可。

出0入0汤圆

发表于 2006-4-3 19:13:48 | 显示全部楼层
看看这里吧

http://www.ouravr.com/bbs/bbs_content.jsp?bbs_sn=544794&bbs_page_no=1&sub_kind_id=2065&bbs_id=1000

出0入0汤圆

发表于 2006-4-3 22:24:01 | 显示全部楼层
楼上那个我以前就下载过了。

出0入0汤圆

 楼主| 发表于 2006-4-9 09:33:51 | 显示全部楼层
////////////////////////////////////////////////////////

////////////////////////////////////////////////////////

////////////////////////////////////////////////////////







强烈要求我这个帖子变为酷帖。



////////////////////////////////////////////////////////

////////////////////////////////////////////////////////

////////////////////////////////////////////////////////

出0入0汤圆

发表于 2006-4-9 11:23:57 | 显示全部楼层
楼主呀,你没有发觉这段时间armok等人都没有上网吗?网站工作人员都不在呀,你现在要求没有什么用呀,再另外找时间把帖子顶上来吧。



发现你已经有很多酷帖了,佩服。

出0入0汤圆

发表于 2006-4-9 13:21:17 | 显示全部楼层
很高兴在这里看到我一直关注的问题就是用软件模拟IIC,还是用硬件自带的TWI,我之前就是做了一个软件模拟的,这个就成功了,但是在做TWI时就无使用,我的从机是ZLG7290,和AT24C01差不多,但是做出来就不成功,请问大家,在用MEGA16的TWI时有驱动ZLG7290成功的例子吗,谢谢大家,是不是TWI比软件模拟还有些注意的问题目,请大家指点下,谢谢

出0入0汤圆

发表于 2006-4-9 13:31:44 | 显示全部楼层
网站上应该有TWI的例子,你搜索看看。

出0入0汤圆

发表于 2006-8-27 12:48:01 | 显示全部楼层
那位有硬件i2c的例子呢?

同顶

出0入0汤圆

发表于 2006-8-28 16:51:09 | 显示全部楼层
LZ有没有测试过,24系列单字节写的每个字节至少要等3ms,为什么不用页写。

出0入0汤圆

 楼主| 发表于 2006-8-28 17:24:40 | 显示全部楼层
呵呵,单字节更通用的哦。

我现在一个项目每次只写10字节,所以我喜欢单字节写的。

出0入0汤圆

发表于 2008-6-24 11:11:12 | 显示全部楼层
以为是好贴。  ....   


  watercat  的见解倒是值得一看

出0入0汤圆

发表于 2008-6-24 12:38:16 | 显示全部楼层
有硬件非得用硬件么?各取所需,LZ只是给出另一种方法而已.

出0入0汤圆

发表于 2009-4-15 17:25:54 | 显示全部楼层
加厚  记号

出0入0汤圆

发表于 2009-11-4 15:52:53 | 显示全部楼层
我觉得硬件IIC是个必然趋势,现在新型的单片机基本有硬件IIC接口了。个人感觉用了硬件IIC之后,速度上去了,效率高,最重要的是出错的几率大大降低

出0入0汤圆

发表于 2010-11-9 19:22:09 | 显示全部楼层
我把它用在stm32 ,MDK环境中,搞不定!

出0入0汤圆

发表于 2011-8-2 15:03:54 | 显示全部楼层
谢谢楼主,正好用到,借来用用。不过要改成NEC的小日本的,真不想用NEC的。

出0入0汤圆

发表于 2011-8-8 14:14:39 | 显示全部楼层
拿来借鉴一下

出0入0汤圆

发表于 2011-10-28 14:21:25 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-12-10 16:08:30 | 显示全部楼层
学习,

出0入0汤圆

发表于 2012-3-29 11:17:20 | 显示全部楼层
学习 学习

出0入10汤圆

发表于 2012-3-29 12:19:23 | 显示全部楼层
基本上我也一直用IO口模拟IIC线,呵呵

出0入0汤圆

发表于 2012-6-26 17:05:13 | 显示全部楼层
mark,学习力!

出0入0汤圆

发表于 2012-7-31 17:35:38 | 显示全部楼层
硬件IIC不是很好用的么,模拟的速度等各方面好像不算很理想

出0入0汤圆

发表于 2012-12-24 09:04:28 | 显示全部楼层
正在学这个,顶!

出0入0汤圆

发表于 2012-12-24 12:50:49 | 显示全部楼层
正准备用一下24C02   学习了。。。先软件模拟,在TWI吧

出0入0汤圆

发表于 2013-1-20 18:39:25 | 显示全部楼层
模拟的看起来清晰但是要占用更多的资源,软件空间要更多

出0入0汤圆

发表于 2013-7-22 14:41:54 | 显示全部楼层
刚刚试试写iic的程序,搞了好久,还是搞不懂,

出0入0汤圆

发表于 2013-8-25 21:24:24 | 显示全部楼层
以前学习没用过。

出0入0汤圆

发表于 2013-8-26 10:23:07 | 显示全部楼层
学习啦、
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-6 05:48

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表