找回密码
 立即注册

QQ登录

只需一步,快速开始

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

用两组数码管加24C02实现倒计时(有记忆有按键)单片机源码

[复制链接]
跳转到指定楼层
楼主
很适初学者做的例程,两组数码管没有用74H595而是用N个IO直接控制,感觉这是我数码管时代最后一个作品,51单片机,一般工业用的也只是简单的控制,关键一点就是他是我们通向科技顶峰的天梯,一路走来感悟很多………致我们走过的青春。推荐个文本编辑器920,用手机上51黑更方便,只要有人贴个源代码,复制就OK,发贴也快(题外话)

制作出来的实物图如下:


单片机源程序如下:
  1. #include<reg51.h>
  2. #include <intrins.h>
  3. #define uchar unsigned char//只有256
  4. #define uint unsigned int//有16位但占内存。
  5. uchar count;//中断计数
  6. uint sec;//秒显示
  7. uint su;//秒显示
  8. sbit wei0=P1^2;//位
  9. sbit wei1=P1^1;//位
  10. sbit wei2=P1^0;//位

  11. sbit wei00=P2^4;//位
  12. sbit wei01=P2^3;//位
  13. sbit wei02=P2^2;//位

  14. sbit k2=P1^4;//按键
  15. sbit k1=P1^5;//按键
  16. sbit k3=P1^6;//按键
  17. sbit k4=P1^7;//按键
  18. sbit led=P2^7;//按键
  19. bit write_secbf=0;//定时溢出标志位,用来写24C02
  20. sbit scl_24=P2^1;//24c02时钟线
  21. sbit sda_24=P2^0;//24c02数据线

  22. bit k;//位变量取值只有0、1、黙认为0*/
  23. void delay (int a)//毫秒级延时
  24. {
  25. int x,y;
  26. for(x=a;x>0;x--)
  27.         for(y=110;y>0;y--);
  28. }
  29. void usdelay()
  30. {
  31. _nop_();_nop_();_nop_();
  32. _nop_();_nop_();_nop_();       
  33. }
  34. uchar code table[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  35. 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71}; //共阴表(wei=0;开反之关)加显示位(P0=table[shi]+0x80;(+或|))显小数点
  36. /*uchar code table1[16] ={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,
  37. 0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};//共阳表(wei=1;开反之关)加显示位(P0=table[shi]&0x7f;)显小数点*/
  38. uint qian,bai,shi,ge;
  39. void display(int dat)//4位显示子函数
  40. {
  41.     qian=dat/1000;
  42.         bai=dat%1000/100;
  43.         shi=dat%100/10;
  44.         ge=dat%10;
  45.         //wei3=0;
  46.         //P0=table[qian];
  47.         //delay(2);
  48.         //wei3=1;
  49.     wei2=1;
  50.         P0=table[bai];
  51.         delay(3);
  52.     wei2=0;
  53.         wei1=1;
  54.         P0=table[shi];//|0x80;
  55.         delay(3);
  56.         wei1=0;
  57.     wei0=1;
  58.         P0=table[ge];
  59.         delay(3);
  60.     wei0=0;
  61. }
  62. uint qian1,bai1,shi1,ge1;
  63. void display1(int dat)//4位显示子函数
  64. {       
  65.     qian1=dat/1000;
  66.         bai1=dat%1000/100;
  67.         shi1=dat%100/10;
  68.         ge1=dat%10;
  69.         //wei3=0;
  70.         //P0=table[qian1];
  71.         //delay(2);
  72.         //wei3=1;
  73.     wei02=1;
  74.         P3=table[bai1];
  75.         delay(3);
  76.     wei02=0;
  77.         wei01=1;
  78.         P3=table[shi1];//|0x80;
  79.         delay(3);
  80.         wei01=0;
  81.     wei00=1;
  82.         P3=table[ge1];
  83.         delay(3);
  84.     wei00=0;
  85. }
  86. /***************以下开始为24CXX用子程序**********************/
  87. void star24()         //开始信号
  88. {//时钟线在高电平时,数据线由高变低即为开始信号        由高变低即为开始信号
  89.         sda_24=1;
  90.         usdelay();
  91.         scl_24=1;
  92.         usdelay();
  93.         sda_24=0;//数据线由高变低即为开始信号
  94.         usdelay();
  95.         scl_24=0;
  96. }
  97. void stop24()         //结束信号
  98. {//时钟线在高电平时,数据线由低变高即为结束信号
  99.         sda_24=0;
  100.         usdelay();
  101.         scl_24=1;
  102.         usdelay();
  103.         sda_24=1;
  104.         usdelay();
  105.         sda_24=0;        //这句可有可无
  106.         scl_24=0;        //这句可有可无
  107. }
  108. void Ack24()//应答         
  109. {        uchar i;
  110.         scl_24=1;
  111.         usdelay();       
  112.     while((sda_24==1)&&(i<200))i++;
  113.         scl_24=0;
  114.     usdelay();
  115. }
  116. /*
  117. void NoAck24()  //不应答
  118. {
  119.         sda_24=1;        //时钟线高电平时,数据线高,即为不应答
  120.         usdelay();
  121.     scl_24=1;
  122.         usdelay();
  123.         scl_24=0;
  124.     usdelay();
  125. } */
  126. /**********24c0初始化***************************/
  127. void init_24()
  128. {
  129. sda_24=1;
  130. usdelay();
  131. scl_24=1;
  132. usdelay();
  133. }
  134. /**********读数据24c02***************************/
  135. void write_byte(uchar dat)
  136. {
  137. uchar i,temp;
  138. temp=dat;
  139. //scl_24=0;//低电平可以变数据,为高时是读,且不能变
  140. for(i=0;i<8;i++)
  141.   {
  142.    temp=temp<<1;
  143.    scl_24=0;
  144.    usdelay();
  145. sda_24=CY;//CY是PSW寄存器中的CY位,再把CY赋给SDA,再由SCL控制发出去
  146. //sda_24=(bit)(temp&0x80);//用这句也可以换掉上一句(bit)是强制转换命令,把数据转成非0即1
  147.    usdelay();
  148.    scl_24=1;
  149.    usdelay();
  150.   }
  151.   scl_24=0;
  152.   usdelay();
  153.   sda_24=1;//释放总线
  154.   usdelay();
  155. }
  156. /**********读数据24c02***************************/
  157. uchar read_byte()
  158. {

  159. uchar i,k;
  160. scl_24=0;         //这句可有可无
  161. usdelay(); //这句可有可无
  162. sda_24=1; //释放总线
  163. usdelay();
  164. for(i=0;i<8;i++)
  165.   {
  166.    scl_24=1;
  167.    usdelay();
  168.    k=(k<<1)|sda_24;//判断8次,移位7次
  169.    scl_24=0;
  170.    usdelay();
  171.    }
  172. return k;
  173. }
  174. /**********写24c02指定地址的数据***************************/
  175. void write_add(uchar add,uchar dat)
  176. {
  177. star24();
  178. write_byte(0xa0);//呼叫器件,高四位为定了的1010,即A,低四位三个接了地,所以为000,最后一个0是写标志
  179. Ack24();//写了后要马上应答
  180. write_byte(add);//写要往哪个地址写数据00-1023
  181. Ack24();//每写一次要给一个应答位
  182.   write_byte(dat);//把数据写入
  183.    Ack24();
  184.   stop24();//给一个停止位,结束写数据
  185. }

  186. /**********读数据24c02指定地址的数据***************************/
  187. uchar read_add(uchar add)
  188. {
  189. uchar dat;
  190. star24();
  191. write_byte(0xa0);//呼叫器件,高四位为定了的1010,即A,低四位三个接了地,所以为000,最后一个0是写标志
  192. Ack24();//写了后要马上应答
  193. write_byte(add);//写入要往哪个地址读数据00-1023
  194. Ack24();//每写一次要给一个应答位
  195. star24();                                                  
  196. write_byte(0xa1);//呼叫器件,高四位为定了的1010,即A,低四位三个接了地,所以为000,最后一个1是读标志
  197. Ack24();//写了后要马上应答
  198. dat=read_byte();
  199. stop24();//给一个停止位,结束读数据
  200. return dat;//返回一个DAT(数据)
  201. }
  202. void  keyscan()
  203. {         if(k3==0&&su>0)//按K1时停TR0=0;
  204.            {
  205.                 delay(3);
  206.                 if(k3==0&&su>0) //与上sec>0条件
  207.                 while(!k3);
  208.                 //TR1=1;
  209.             TR1=~TR1;//取反定时器TR0,按一次开0,再按关1;

  210.                 }
  211.                                                                        
  212.                 if(k2==0)                                                                                                                                                    
  213.           {
  214.         delay(3);
  215.                 if(k2==0)
  216.                 while(!k2);
  217.                 TR1=0;
  218.                 su++;
  219.                 if(su>255)        su=0;
  220.                 sec=su;       
  221.                 write_add(0,sec);//在地址2 写入min
  222.                 delay(1);            
  223.                 }
  224.                  if(k1==0)
  225.           {
  226.         delay(3);
  227.                 if(k1==0)
  228.                 while(!k1);
  229.                 TR1=0;
  230.                 su--;               
  231.                 if(su==0)        su=255;
  232.                 sec=su;       
  233.             write_add(0,sec);//在地址2 写入min
  234.                 delay(1);   
  235.                 }
  236.         }

  237. void main()
  238. {        init_24();//24c02初始化
  239.         TMOD=0X11;//定时器1   TMOD=0X11;方式1.
  240.         TH1=(65536-50000)/256;//装初值
  241.         TL1=(65536-50000)%256;//装初值
  242.         EA=1;
  243.         ET1=1;
  244.         TR1=0;//定时器先关。等开关键启动
  245.         led=0;//反相器0为关。       
  246.         sec=read_add(0);//从地址( )中读出以前保存的数据
  247.         delay(2);
  248.         su=sec;
  249. while(1)
  250. {   
  251.         keyscan();  
  252.         if(count==2*1)//50000个20=1秒。
  253.         {
  254.         count=0;
  255.         sec--;
  256.         if(sec==0)//如果秒>100秒清0并执行后面、
  257.    {
  258.          TR1=1;//定时器先关。等开关键启动
  259.          sec=su;
  260.          led=~led;
  261.          //delay(10);         
  262.          //led=0;                           
  263.          }                  
  264.         }
  265. display(sec); //实时数据
  266. display1(su);//设置数据
  267. }
  268. }
  269. void timer0() interrupt 3 //定时器0的中断子函数(外部0为0、定时0为1、外部1为2、定时1为3、串口4、)
  270. {
  271.    TH1=(65536-50000)/256;//装初值
  272.         TL1=(65536-50000)%256;//装初值
  273.         count++;//中断发生后中断计数加1
  274.         }

  275.                   
复制代码

所有资料51hei提供下载:
IIC定时双数码管OK.zip (37.59 KB, 下载次数: 30)


评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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