登录|立即注册|使用QQ帐号登录
论坛 > 51单片机
发帖|
看3537|回1|收藏
楼主 ID:239746 只看他
2017-10-15 21:05

代码:

  1. #include<iic.h>

  2. void delay10us(void){//误差 0us
  3.     unsigned char a,b;
  4.     for(b=1;b>0;b--)
  5.         for(a=2;a>0;a--);
  6. }

  7. void iicStart(){
  8.         SDA = 1;
  9.         delay10us();
  10.         SCL = 1;
  11.         delay10us();
  12.         SDA = 0;
  13.         delay10us();
  14.         SCL = 0;//SCL=0时,SDA状态允许变化
  15.         delay10us();

  16. }

  17. unsigned char iicSendDate(unsigned char dat){
  18.         unsigned char i,a=0;
  19.         for(i=0;i<8;i++){
  20.                 SDA        = dat>>7;
  21.                 dat<<=1;
  22.                 delay10us();
  23.                 SCL = 1;
  24.                 delay10us();
  25.                 SCL = 0;
  26.                 delay10us();
  27.         }
  28.         //等待应答. SCL、SDA释放   等待应答时,SCL=1,SDA=1,应答后,SDA=0
  29.         SDA = 1;
  30.         delay10us();
  31.         SCL = 1;
  32.         //delay10us();  不需要延时,后面通过a++延时,来判断是否发送成功
  33.         //应答与否—————_是否发送成功
  34.         while(SDA){//若应答,则SDA=0,从而结束循环,返回1.               
  35.            a++;
  36.            delay10us();
  37.            if(a>200){
  38.                    SCL = 0;
  39.                             delay10us();
  40.                    return 0;
  41.            }
  42.            
  43.         }
  44.         SCL = 0;//SCL=0时,允许SDA状态发生变化,为了下一次发送
  45.         delay10us();
  46.         return 1;
  47.                
  48. }
  49. //读取过程,主机先发送从机器件地址,要读取的地址,后要重复一次起始信号并发出器件地址和读取方向1 (发送函数包含等待从机应答过程即等待 SDA=0的过程)
  50. //发送完后,scl = 0; 才开始读取数据过程——iicReadDate()函开始数执行
  51. unsigned char iicReadDate(){
  52.         unsigned char i,dat = 0;        
  53.         //scl =0;之前已经等于0了,不用写
  54.         SDA = 1;//读取字节前,先释放SDA,SDA=1不是将端口固定位高电平,而是关闭单片机
  55.                 //内部下MOG管,让SDA线的电平由信号决定。
  56.         delay10us();//等待SDA为状态的更新
  57.         for(i=0;i<8;i++){//接受8个字节
  58.                 SCL = 1;//SDA为高电平时,数据是稳定的
  59.                 delay10us();
  60.                 dat<<=1;//iic是串行传输的,只能一位一位传输,并且最高位在前
  61.                 dat |=SDA;//将dat左移一位,然后将SDA位的状态放到dat的最后一位,赋值给dat,循环8次,依次写到dat的8个位中。dat的最初的首位被移出,
  62.                 delay10us();
  63.                 SCL = 0;//SCL=0时,SDA状态才允许发生变化。为后续的终止信号做准备。
  64.                 delay10us();
  65.                                 
  66.         }
  67.         return dat;                                

  68. }
  69. void iicStop(){
  70.         SDA = 0;
  71.         delay10us();
  72.         SCL = 1;  //释放
  73.         delay10us();
  74.         SDA = 1;  //释放
  75.         delay10us();

  76. }
  77. //iic总线  相当于数据线,由单片机模拟。

  78. //往24c02的一个地址写入数据
  79. void at24c02WriteDate(unsigned char addr,unsigned char dat){
  80.         
  81.         iicStart();//开始

  82.         iicSendDate(0xa0);//发送写器件地址        1010 000 0
  83.         iicSendDate(addr);//发送该器件的存储区的首地址
  84.         iicSendDate(dat);//发送数据

  85.         iicStop();//停止
  86.                                                 
  87. }

  88. //从24c02内读取数据
  89. unsigned char at24c02ReadDate(unsigned char addr ){        //addr:器件的存储区的首地址。器件的地址已知
  90.         unsigned char num;
  91.         iicStart();//开始

  92.         iicSendDate(0xa0);//发送器件地址+0               
  93.         iicSendDate(addr);//发送该器件的存储区的首地址
  94.         iicStart();
  95.         iicSendDate(0xa1);

  96.         num = iicReadDate();

  97.         iicStop();//结束               
  98.         
  99.         return num;
  100. }


沙发 ID:106422 只看他
2020-3-18 09:08
学习了

51黑电子论坛

Powered by Discuz! X3.1

首页|标准版|触屏版|电脑版