找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1087|回复: 7
打印 上一主题 下一主题
收起左侧

求大神帮我看看这个程序

[复制链接]
跳转到指定楼层
楼主
ID:881715 发表于 2021-11-5 11:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
          各位大神大家好,一个程序我弄了很久多天了实在弄不了,特来求教!!! 程序功能:我设置了四个按键,一个加键(k1jia),一个减键(k2jian),用来设置数据的,开机从24C02里读取数据,用这两键调节读出的数据,这数据是调用延时函数次数的,如不调节则调用延时函数的次数为读出的数据
,第三个键是开关键(kaiguan),点动一下开关键,小灯(out)点亮,经延时后熄灭。第四个键是写入键(k3ws),按下后将数据写入AT24C02为下次上电做读数据准备。
  1. #include<reg51.h>               
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. sbit k1jia=P1^1;
  5. sbit k2jian=P1^3;
  6. sbit k3ws=P1^4;        //写入数据键
  7. sbit out=P2^7; //小灯,为1时点亮
  8. sbit scl=P2^0;
  9. sbit sda=P2^1;
  10. sbit kaiguan=P3^3;//开关键
  11. unsigned char a=0,b=1,c;
  12. void delay100ms()   //误差 0us
  13. {
  14.     unsigned char a,b,c;
  15.     for(c=7;c>0;c--)
  16.         for(b=74;b>0;b--)
  17.             for(a=95;a>0;a--);
  18. }
  19. void delay88ms()
  20.   
  21. {
  22.     unsigned char a,b,c;
  23.     for(c=5;c>0;c--)
  24.         for(b=212;b>0;b--)
  25.             for(a=40;a>0;a--);
  26. }
  27. uchar anzhi()
  28. {
  29. if((k1jia==0)&&(a<36))
  30.   {        delay88ms();
  31.         if((k1jia==0)&&(a<36))
  32.          {        a=a+1;
  33.                 while(!k1jia);
  34.                 return a;
  35.          }
  36. }
  37.   if((k2jian==0)&&(a>1))
  38.   {        delay88ms();
  39.         if((k2jian==0)&&(a>1))
  40.          {        a=a-1;
  41.                 while(!k2jian);
  42.                 return a;
  43.          }

  44.   }
  45.    else
  46.    return a;
  47. }

  48. void delay7us()  //  延时函数
  49. {                                                 
  50.     unsigned char a;
  51.     for(a=2;a>0;a--);
  52. }
  53.    void init()
  54. {sda=1;
  55.   delay7us();
  56.    scl=1;
  57. delay7us();
  58. }        
  59. /*启动信号函数*/
  60. void start()  //启动信号函数
  61. { scl=1;         
  62.    sda=1;
  63.    delay7us();
  64.   sda=0;
  65.    delay7us();       
  66. }       
  67. /*写一个字节的函数*/
  68. void write_iic_byte(uchar dat)       
  69.                               
  70. { uchar i;
  71.    scl=0;  /*主机拉低为的是SDA数据线
  72.                    可以发生变化并为SDA拉高,让
  73.                    接受设备接收数据做准备*/
  74.         /*发送八位数据*/
  75.    for(i=0;i<8;i++)
  76.     { if(dat&0X80)
  77.              sda=1;/*主机将数据1存入SDA*/
  78.          else
  79.                  sda=0;/*主机将数据0存入SDA
  80.                                 ,也可认为是存入一个
  81.                                 存储器*/
  82.           scl=1;  /*主机将时钟数据线拉高*/
  83.            delay7us(); /*延时接收设备在此期间
  84.                                   自动取走*/
  85.            dat=dat<<1;/* 数据左移一位,次高位
  86.                               变成发送数据位*/
  87.                 scl=0;/*时钟线拉低为更改发送数据
  88.                            位做准备,只有其为低数据线
  89.                            上的数据才会发生改变。*/
  90.            delay7us();                  
  91. }         
  92.      sda=1;
  93.               /*释放数据线*/       
  94.   }                        
  95. /*读一个字节的函数*/
  96. uchar read_iic_byte()
  97. { uchar i,v;/*暂时为空变量,8次后
  98.                              存储要保存的数据*/
  99.    sda=1;/*主机释放数据线,这数据
  100.                   状态以后有发送设备决定*/
  101.    scl=0;/*主机将时钟信号线拉低,
  102.                    /*SDA线上的数据才会改变*/
  103.    /*从设备发送八位数据*/
  104.    for(i=0;i<8;i++)
  105.         { v=v<<1; /*第一次循环无意义,以后
  106.                           发送用*/
  107.           scl=1;  /*以后发送期间数据稳定*/
  108.          delay7us();/*延时使主机有时间取走
  109.                            数据*/
  110.          if(sda) /*SDA发送从设备里最高位数据
  111.                           1,第一次循环从此发送第一
  112.                           位数据*/
  113.                 v=v|0X01;/*把1传入变量V的最低位*/
  114.         scl=0;         /*时钟线拉低发送数据由发送
  115.                            设备自动改变*/

  116.         delay7us();/*延时使时钟线可靠拉低
  117.                                  ,有充足时间数据被读走
  118.                                  */
  119.         }
  120.         return v; /*被读的数据存在V中,
  121.                           作为返回值/*返回*/
  122. }        
  123.           
  124. void stop()//停止信号函数
  125. {scl=1;
  126.   sda=0;
  127.   delay7us();
  128.   sda=1;
  129.   delay7us();
  130. }          
  131.   /*检测应答信号        */
  132. void checkack()
  133. {uchar i;
  134.   scl=0;
  135.   sda=0;
  136.   delay7us();       
  137.   scl=1;       
  138.   delay7us();
  139.   while((sda==1)&&(i<250) )
  140.            i++;
  141.    scl=0;
  142.    }
  143. /* 产生非应答信号*/         
  144. void noack()
  145. {scl=0;
  146.   sda=1;
  147.   delay7us();
  148.   scl=1;
  149.   delay7us();
  150.   scl=0;
  151. }
  152. /*产生应答*/
  153. /*void ack()
  154. { scl=0;
  155.    sda=0;
  156.    delay7us();
  157.    scl=1;
  158.    delay7us();
  159.    scl=0;
  160. }        */          
  161. void main()
  162. {EA=1;
  163. IT0=0;
  164. EX0=1;
  165. while(1)
  166.   {         
  167.   do
  168.     {
  169.           init();
  170.           start();
  171.           write_iic_byte(0XA0);
  172.           checkack();
  173.           write_iic_byte(0);
  174.           checkack();
  175.           start();
  176.           write_iic_byte(0XA1);
  177.           checkack();
  178.            a=read_iic_byte();
  179.            noack();
  180.            stop();
  181.           
  182.           // delay88ms();
  183.           // b=b-1;       
  184.         }
  185.         while(0);

  186.          out=0;
  187.          
  188.                
  189.                 }  
  190.                  
  191.         while(1)

  192.           {if(kaiguan==0)
  193.            {out=1;
  194.                 for(c=0;c<a;c++)
  195.                       {
  196.                             delay100ms();
  197.                    }
  198.                   out=0;
  199.            }
  200.         }
  201.         }
  202. void ex0_iic() interrupt 0
  203. {         
  204.                init();
  205.                   start();
  206.                   write_iic_byte(0XA0);
  207.                   checkack();
  208.                              write_iic_byte(0);
  209.                            checkack();
  210.                           write_iic_byte(a);
  211.                            checkack();
  212.                            stop();

  213. }
  214.           
复制代码


分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:313048 发表于 2021-11-5 13:58 | 只看该作者
首先,你在main函数里面的第一个do{}while读取EEPROM数据最好是写个函数封装一下,然后在进入main函数初始化之后调用,这样代码看起来顺心点。
其次是ex0的外部中断,这个里面不建议做这么麻烦的eeprom数据的读写操作,你可以同样封装为一个函数,然后放在main函数的while里面,通过标志位去操作。在外部中断里面只执行标志位置位的操作。
最后不知道你到底是想问什么问题,你把你的功能说出来了,然后放一段代码在这儿让别人看,能看出啥,是功能无法实现还是代码哪里有问题?单纯的一段代码反正我是没心情看下去的,更何况是这种层次感不明确的代码。
回复

使用道具 举报

板凳
ID:401564 发表于 2021-11-5 15:03 | 只看该作者
我在另一个帖子里就告诉你了, sda=0;再应答是错误的,就是不理会
回复

使用道具 举报

地板
ID:881715 发表于 2021-11-5 15:05 来自触屏版 | 只看该作者
我的功能是用两个按键改变量数值,把数值再用另一个按键写入2402,然后再次上电后读取数据,谢谢您的指导,我封装一下函致试试看,如果不封函数,而是在主函数中写出读写操作的流程程序,两个语句中加了个while结果仿真就既不读也不写干脆罢工了,电平指示不在交替变化了,if语句也不行
回复

使用道具 举报

5#
ID:881715 发表于 2021-11-5 15:08 来自触屏版 | 只看该作者
Y_G_G 发表于 2021-11-5 15:03
我在另一个帖子里就告诉你了, sda=0;再应答是错误的,就是不理会

多谢指导
回复

使用道具 举报

6#
ID:881715 发表于 2021-11-5 15:12 来自触屏版 | 只看该作者
Y_G_G 发表于 2021-11-5 15:03
我在另一个帖子里就告诉你了, sda=0;再应答是错误的,就是不理会

大神我这是单字节操作,应答函数并没有调用呀?我注释掉了呀?怎么还会出问题吗
回复

使用道具 举报

7#
ID:401564 发表于 2021-11-5 15:28 | 只看该作者
创造生活 发表于 2021-11-5 15:12
大神我这是单字节操作,应答函数并没有调用呀?我注释掉了呀?怎么还会出问题吗

checkack();
这个函数是错误的
每个向24Cxx写入一个字节的数据之后都要应答
回复

使用道具 举报

8#
ID:881715 发表于 2021-11-5 15:33 来自触屏版 | 只看该作者
原来是主机检测应答错了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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