找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5579|回复: 7
收起左侧

单片机仿真—时钟,温度计和频率计

[复制链接]
ID:70650 发表于 2014-12-18 00:25 | 显示全部楼层 |阅读模式
这么好的资料当然要发到51hei论坛来 大家一起学习.
1)键盘、显示电路
利用单片机最小系统、6个7段LED数码管、12个按键,设计制作一个键盘、显示电路。可以使用8279键盘显示接口电路,也可以使用单片机的并行接口作为键盘显示接口。
2) 数字时钟
在键盘、显示电路的基础上完成一个数字时钟的设计,完成以下功能:
a. 要求以24小时计时方式显示时、分、秒;
b. 时、分、秒可以通过按键分别调整。
3) 数字温度计
在上题的硬基础上,制作一个数字温度计。完成以下功能:
a. 利用DS18B20可编程1-Wire数字温度传感器芯片,或利用AD590温度传感器芯片和A/D转换器芯片采集温度温度信号;
b. 当按下键盘上的温度显示按键时将实时温度信息显示在LED显示器上,当按下键盘上的时钟显示按键时,恢复时钟的正常显示;
c. 通过串行通信的方式,将采集到的实时温度信息送至第二个单片机系统,并在二个单片机系统显示实时温度。
4) 数字频率计
在上题的硬基础上,制作一个数字频率计。完成以下功能:
a. 利用MCU设计一个数字频率计,用于检测0~500kHz周期信号的频率,输入信号幅度范围:0.1~10V;
b. 当按下键盘上的频率显示按键时将测量的频率信息显示在LED显示器上,当按下键盘上的时钟显示按键时,恢复时钟的正常显示;

时钟显示
112829f03fwv00p9ez7809.png.thumb.jpg


温度显示
1128420kkbookwnbnkjr0w.png.thumb.jpg


频率显示
112845ddxshdrrafary2jh.png.thumb.jpg


串行通信
112850mn9msscewcjnaacj.jpg.thumb.jpg


实物时钟显示
112856npfxkn08n9ublu1f.jpg.thumb.jpg


实物温度显示
112859hhjod1wtudmd1ion.jpg.thumb.jpg


实物频率显示(由于程序中晶振为12M,板子上的晶振为11.0592M,故测出的频率有8%左右的误差) ...




实物串行通信



串行通信.rar

22.06 KB, 下载次数: 17, 下载积分: 黑币 -5

串行通信接收.rar

653 Bytes, 下载次数: 13, 下载积分: 黑币 -5

整个程序(包括发送程序).rar

2.1 KB, 下载次数: 31, 下载积分: 黑币 -5

整个电路.rar

18.38 KB, 下载次数: 25, 下载积分: 黑币 -5

回复

使用道具 举报

ID:70650 发表于 2014-12-18 00:28 | 显示全部楼层
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. #define ulong unsigned long
  6. #define _Nop() _nop_()

  7. sbit DQ =P2^2;  //定义DS18B20通信端口
  8. sbit DULA=P2^6;
  9. sbit WELA=P2^7;
  10. sbit K1=P3^0;
  11. sbit K2=P3^1;
  12. sbit K3=P3^2;
  13. sbit K4=P3^4;
  14. sbit K5=P3^5;
  15. sbit K6=P3^6;
  16. bit settime=0;
  17. float tt=0;
  18. uchar ms,h=0,m=0,s=0,change=0,num=0;
  19. ulong count=0;
  20. uchar code S_Data[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
  21. uchar  table[6]={0x3F,0x3F,0x3F,0x3F,0x3F,0x3F};//时钟0-5号SLED缓冲值
  22. uchar  table1[]={0x00,0x00,0x00,0x00,0x00,0x00};//频率计0-5号SLED缓冲值
  23. uchar data sled_data[]={0x00,0x00,0x00,0x00,0x00,0x00}; //温度0-5号SLED缓冲值
  24. uchar code Line_Value[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
  25. uchar code Line_Value1[]={0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
  26. void delay(uint i)
  27. {
  28.         while(i--);
  29. }

  30. void delayms(uint x)
  31. {
  32.   uchar i;
  33.   while(x--) for(i=0;i<120;i++);
  34. }

  35. void display(uchar h,m,s)
  36. {  uchar i;
  37.    table[5]= S_Data[h/10];
  38.    table[4]= S_Data[h%10];
  39.    table[3]= S_Data[m/10];
  40.    table[2]= S_Data[m%10];
  41.    table[1]= S_Data[s/10];
  42.    table[0]= S_Data[s%10];

  43. for (i=0;i<6;i++)
  44. {
  45.    P0=0xff;
  46.    WELA=1;
  47.    P0=Line_Value1[ i];
  48.    WELA=0;
  49.    DULA=1;
  50.    P0=table[ i];
  51.    DULA=0;
  52.    delayms(1);
  53. }
  54. }

  55. void Change_Time()
  56. {
  57. settime=0;
  58. if(K1==0||K2==0||K3==0)
  59. {
  60.   TR0=0;
  61.   settime=1;
  62.   }
  63.   while(settime)
  64.   {
  65.    if(K1==0)
  66.    {
  67.    while(K1==0);
  68.    change=(change+1)%3;
  69.    }
  70.    else if(K2==0)
  71.    {
  72.    while(K2==0);
  73.    if(change==0)
  74.    {if(++h==24) h=0;}
  75.    if(change==1)
  76.    {if(++m==60) m=0;}
  77.    if(change==2)
  78.    {if(++s==60) s=0;}
  79.    }
  80.    else if(K3==0)
  81. {
  82.    while(K3==0);
  83.    if(change==0)
  84.    {if(--h==0xff) h=23;}
  85.    if(change==1)
  86.    {if(--m==0xff) m=59;}
  87.    if(change==2)
  88.    {if(--s==0xff) s=59;}
  89.   }
  90.    else if(K4==0)
  91.    {
  92.    while(K4==0);
  93.    settime=0;
  94.    TR0=1;
  95.    }
  96.    display(h,m,s);
  97.    }
  98.    }

  99. Init_DS18B20(void)
  100. {
  101.         uchar x=0;
  102.         DQ = 1; //DQ复位
  103.         delay(8); //稍做延时
  104.         DQ = 0; //单片机将DQ拉低
  105.         delay(80); //精确延时 大于 480us
  106.         DQ = 1; //拉高总线
  107.         delay(14);
  108.         x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
  109.         delay(20);
  110. }

  111. //读一个字节
  112. ReadOneChar(void)
  113. {
  114.         uchar i=0;
  115.         uchar dat = 0;
  116.         for (i=8;i>0;i--){
  117.                 DQ = 0; // 给脉冲信号
  118.                 dat>>=1;
  119.                 DQ = 1; // 给脉冲信号
  120.                 if(DQ)  dat|=0x80;
  121.                 delay(4);
  122.                 }
  123.         return(dat);
  124. }

  125. //写一个字节
  126. WriteOneChar(uchar dat)
  127. {
  128.         uchar i=0;
  129.         for (i=8; i>0; i--){
  130.                 DQ = 0;
  131.                 DQ = dat&0x01;
  132.                 delay(5);
  133.                 DQ = 1;
  134.                 dat>>=1;
  135.                 }
  136. }

  137. //读取温度
  138. ReadTemperature(void)
  139. {
  140.         uchar a=0;
  141.         uchar b=0;
  142.         uint t=0;
  143.        
  144.         Init_DS18B20();
  145.         WriteOneChar(0xCC); // 跳过读序号列号的操作
  146.         WriteOneChar(0x44); // 启动温度转换
  147.         Init_DS18B20();
  148.         WriteOneChar(0xCC); //跳过读序号列号的操作
  149.         WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
  150.         a=ReadOneChar();
  151.         b=ReadOneChar();
  152.         t=b;
  153.         t<<=8;
  154.         t=t|a;
  155.         tt=t*0.0625; //将温度的高位与低位合并
  156.         t= tt*10+0.5; //对结果进行4舍5入
  157.         return(t);
  158. }

  159. void Time0() interrupt 1
  160. {
  161. TH0=(65536-50000)/256;
  162. TL0=(65536-50000)%256;
  163. if(++ms==20)
  164. {
  165.   ms=0;
  166.   if(++s==60)
  167.   {
  168.   s=0;
  169.   if(++m==60)
  170.   {
  171.   m=0;
  172.   if(++h==24)
  173.   {
  174.   h=0;m=0;s=0;
  175.   }
  176.   }
  177.   }
  178.   }
  179.   }

  180. void INT_T1() interrupt 3
  181. {
  182.    
  183.    TH1=(65536-50000)/256;
  184.    TL1=(65536-50000)%256;
  185.    if(++num==20)
  186.    {
  187.      TR1=0;
  188.      EX0=0;
  189.      table1[0]=S_Data[count%10];
  190.      table1[1]=S_Data[count%100/10];
  191.      table1[2]=S_Data[count/100%10];
  192.      table1[3]=S_Data[count/1000%10];
  193.      table1[4]=S_Data[count/10000%10];
  194.      table1[5]=S_Data[count/10000/10];
  195.      count=0;
  196.          num=0;
  197.        
  198.          }
  199.          }

  200. void EX_INT0() interrupt 2
  201. {
  202.     count++;
  203.    
  204.        
  205. }


  206. void main()
  207. {
  208. uint temp_buff;
  209. uchar i,j;#include <reg51.h>
  210. #include <intrins.h>
  211. #define uchar unsigned char
  212. #define uint unsigned int
  213. #define ulong unsigned long
  214. #define _Nop() _nop_()

  215. sbit DQ =P2^2;  //定义DS18B20通信端口
  216. sbit DULA=P2^6;
  217. sbit WELA=P2^7;
  218. sbit K1=P3^0;
  219. sbit K2=P3^1;
  220. sbit K3=P3^2;
  221. sbit K4=P3^4;
  222. sbit K5=P3^5;
  223. sbit K6=P3^6;
  224. bit settime=0;
  225. float tt=0;
  226. uchar ms,h=0,m=0,s=0,change=0,num=0;
  227. ulong count=0;
  228. uchar code S_Data[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
  229. uchar  table[6]={0x3F,0x3F,0x3F,0x3F,0x3F,0x3F};//时钟0-5号SLED缓冲值
  230. uchar  table1[]={0x00,0x00,0x00,0x00,0x00,0x00};//频率计0-5号SLED缓冲值
  231. uchar data sled_data[]={0x00,0x00,0x00,0x00,0x00,0x00}; //温度0-5号SLED缓冲值
  232. uchar code Line_Value[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
  233. uchar code Line_Value1[]={0xdf,0xef,0xf7,0xfb,0xfd,0xfe};
  234. void delay(uint i)
  235. {
  236.         while(i--);
  237. }

  238. void delayms(uint x)
  239. {
  240.   uchar i;
  241.   while(x--) for(i=0;i<120;i++);
  242. }

  243. void display(uchar h,m,s)
  244. {  uchar i;
  245.    table[5]= S_Data[h/10];
  246.    table[4]= S_Data[h%10];
  247.    table[3]= S_Data[m/10];
  248.    table[2]= S_Data[m%10];
  249.    table[1]= S_Data[s/10];
  250.    table[0]= S_Data[s%10];

  251. for (i=0;i<6;i++)
  252. {
  253.    P0=0xff;
  254.    WELA=1;
  255.    P0=Line_Value1[ i];
  256.    WELA=0;
  257.    DULA=1;
  258.    P0=table[ i];
  259.    DULA=0;
  260.    delayms(1);
  261. }
  262. }

  263. void Change_Time()
  264. {
  265. settime=0;
  266. if(K1==0||K2==0||K3==0)
  267. {
  268.   TR0=0;
  269.   settime=1;
  270.   }
  271.   while(settime)
  272.   {
  273.    if(K1==0)
  274.    {
  275.    while(K1==0);
  276.    change=(change+1)%3;
  277.    }
  278.    else if(K2==0)
  279.    {
  280.    while(K2==0);
  281.    if(change==0)
  282.    {if(++h==24) h=0;}
  283.    if(change==1)
  284.    {if(++m==60) m=0;}
  285.    if(change==2)
  286.    {if(++s==60) s=0;}
  287.    }
  288.    else if(K3==0)
  289. {
  290.    while(K3==0);
  291.    if(change==0)
  292.    {if(--h==0xff) h=23;}
  293.    if(change==1)
  294.    {if(--m==0xff) m=59;}
  295.    if(change==2)
  296.    {if(--s==0xff) s=59;}
  297.   }
  298.    else if(K4==0)
  299.    {
  300.    while(K4==0);
  301.    settime=0;
  302.    TR0=1;
  303.    }
  304.    display(h,m,s);
  305.    }
  306.    }

  307. Init_DS18B20(void)
  308. {
  309.         uchar x=0;
  310.         DQ = 1; //DQ复位
  311.         delay(8); //稍做延时
  312.         DQ = 0; //单片机将DQ拉低
  313.         delay(80); //精确延时 大于 480us
  314.         DQ = 1; //拉高总线
  315.         delay(14);
  316.         x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
  317.         delay(20);
  318. }

  319. //读一个字节
  320. ReadOneChar(void)
  321. {
  322.         uchar i=0;
  323.         uchar dat = 0;
  324.         for (i=8;i>0;i--){
  325.                 DQ = 0; // 给脉冲信号
  326.                 dat>>=1;
  327.                 DQ = 1; // 给脉冲信号
  328.                 if(DQ)  dat|=0x80;
  329.                 delay(4);
  330.                 }
  331.         return(dat);
  332. }

  333. //写一个字节
  334. WriteOneChar(uchar dat)
  335. {
  336.         uchar i=0;
  337.         for (i=8; i>0; i--){
  338.                 DQ = 0;
  339.                 DQ = dat&0x01;
  340.                 delay(5);
  341.                 DQ = 1;
  342.                 dat>>=1;
  343.                 }
  344. }

  345. //读取温度
  346. ReadTemperature(void)
  347. {
  348.         uchar a=0;
  349.         uchar b=0;
  350.         uint t=0;
  351.        
  352.         Init_DS18B20();
  353.         WriteOneChar(0xCC); // 跳过读序号列号的操作
  354.         WriteOneChar(0x44); // 启动温度转换
  355.         Init_DS18B20();
  356.         WriteOneChar(0xCC); //跳过读序号列号的操作
  357.         WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
  358.         a=ReadOneChar();
  359.         b=ReadOneChar();
  360.         t=b;
  361.         t<<=8;
  362.         t=t|a;
  363.         tt=t*0.0625; //将温度的高位与低位合并
  364.         t= tt*10+0.5; //对结果进行4舍5入
  365.         return(t);
  366. }

  367. void Time0() interrupt 1
  368. {
  369. TH0=(65536-50000)/256;
  370. TL0=(65536-50000)%256;
  371. if(++ms==20)
  372. {
  373.   ms=0;
  374.   if(++s==60)
  375.   {
  376.   s=0;
  377.   if(++m==60)
  378.   {
  379.   m=0;
  380.   if(++h==24)
  381.   {
  382.   h=0;m=0;s=0;
  383.   }
  384.   }
  385.   }
  386.   }
  387.   }

  388. void INT_T1() interrupt 3
  389. {
  390.    
  391.    TH1=(65536-50000)/256;
  392.    TL1=(65536-50000)%256;
  393.    if(++num==20)
  394.    {
  395.      TR1=0;
  396.      EX0=0;
  397.      table1[0]=S_Data[count%10];
  398.      table1[1]=S_Data[count%100/10];
  399.      table1[2]=S_Data[count/100%10];
  400.      table1[3]=S_Data[count/1000%10];
  401.      table1[4]=S_Data[count/10000%10];
  402.      table1[5]=S_Data[count/10000/10];
  403.      count=0;
  404.          num=0;
  405.        
  406.          }
  407.          }

  408. void EX_INT0() interrupt 2
  409. {
  410.     count++;
  411.    
  412.        
  413. }


  414. void main()
  415. {
  416. uint temp_buff;
  417. uchar i,j,k;
  418. char *p;
  419. SCON=0x80;                //串口模式2
  420. PCON=0x00;                //波特率不倍增
  421. TMOD=0x11;
  422. TH0=(65536-50000)/256;
  423. TL0=(65536-50000)%256;
  424. TH1=(65536-50000)/256;
  425. TL1=(65536-50000)%256;
  426. EA=1;
  427. ET0=1;
  428. ET1=1;
  429. TR0=1;
  430. IT1=1;
  431. EX1=1;
  432. TR1=1;
  433. P1=0xff;//复位K1-K7键位
  434. P3=0x7f;
  435. while(1)
  436. {
  437. display(h,m,s);
  438. delayms(1);
  439. Change_Time();
  440. if(K5==0)
  441. {
  442. while(1)
  443. { while(K5==0);
  444.                 temp_buff=ReadTemperature(); /*读取当前温度*/
  445.                 sled_data[2] = S_Data[temp_buff/100];
  446.                 sled_data[1] = S_Data[temp_buff%100/10];
  447.                 sled_data[0] = S_Data[temp_buff%10];
  448.         for(j=0;j<30;j++)
  449.         {
  450.                 for(i=0;i<6;i++)
  451.                 {
  452.                     
  453.                                     _Nop();
  454.                                         _Nop();
  455.                                         _Nop();
  456.                     P0=0xff;
  457.                                         WELA=1;
  458.                                         P0 = Line_Value1[ i]; /*输出位码数据到数码管*/
  459.                     WELA=0;
  460.                     P0=0xff;
  461.                     DULA=1;
  462.                                         P0 = sled_data[ i]; /*输出段码数据到数码管*/
  463.                                         if(i==1) P0 = P0|0x80; /*显示小数点*/
  464.                     DULA=0;
  465.                                         delayms(1);
  466.                                         }
  467.                                         }
  468.      k++;
  469.     if(k==5)
  470. {
  471.      k=0;
  472.      p=sled_data;   
  473.     for(i=0;i<3;i++)
  474.        {  
  475.           SBUF=*p;
  476.           p++;
  477.           while(TI==0);
  478.           TI=0;               
  479.                 }
  480. }        

  481.                                         if(K4==0) break;
  482.                 }

  483.   }
  484. if(K6==0)
  485. { while(K6==0);               
  486. while(1)
  487. {   EX1=1;
  488.      TR1=1;

  489.    

  490.      
  491.         for(j=0;j<30;j++)
  492.         {
  493.          for(i=0;i<6;i++)
  494.          {
  495.       P0=0xff;
  496.            WELA=1;
  497.        P0= Line_Value1[ i];
  498.        WELA=0;
  499.        DULA=1;
  500.            P0= table1[ i];
  501.        DULA=0;
  502.            delayms(1);
  503.          }
  504.      }
  505.          if(K4==0) break;
  506.          }
  507.      
  508.      }
  509. }
  510. }



  511. TMOD=0x11;
  512. TH0=(65536-50000)/256;
  513. TL0=(65536-50000)%256;
  514. TH1=(65536-50000)/256;
  515. TL1=(65536-50000)%256;
  516. EA=1;
  517. ET0=1;
  518. ET1=1;
  519. TR0=1;
  520. IT1=1;
  521. EX1=1;
  522. TR1=1;
  523. P1=0xff;//复位K1-K7键位
  524. P3=0x7f;
  525. while(1)
  526. {
  527. display(h,m,s);
  528. delayms(1);
  529. Change_Time();
  530. if(K5==0)
  531. {
  532. while(1)
  533. { while(K5==0);
  534.                 temp_buff=ReadTemperature(); /*读取当前温度*/
  535.                 sled_data[2] = S_Data[temp_buff/100];
  536.                 sled_data[1] = S_Data[temp_buff%100/10];
  537.                 sled_data[0] = S_Data[temp_buff%10];
  538.         for(j=0;j<30;j++)
  539.         {
  540.                 for(i=0;i<6;i++)
  541.                 {
  542.                     
  543.                                     _Nop();
  544.                                         _Nop();
  545.                                         _Nop();
  546.                     P0=0xff;
  547.                                         WELA=1;
  548.                                         P0 = Line_Value1[ i]; /*输出位码数据到数码管*/
  549.                     WELA=0;
  550.                     P0=0xff;
  551.                     DULA=1;
  552.                                         P0 = sled_data[ i]; /*输出段码数据到数码管*/
  553.                                         if(i==1) P0 = P0|0x80; /*显示小数点*/
  554.                     DULA=0;
  555.                                         delayms(1);
  556.                                         }
  557.                                         }


  558.                                         if(K4==0) break;
  559.                 }

  560.   }
  561. if(K6==0)
  562. { while(K6==0);               
  563. while(1)
  564. {   EX1=1;
  565.      TR1=1;

  566.    

  567.      
  568.         for(j=0;j<30;j++)
  569.         {
  570.          for(i=0;i<6;i++)
  571.          {
  572.       P0=0xff;
  573.            WELA=1;
  574.        P0= Line_Value1[ i];
  575.        WELA=0;
  576.        DULA=1;
  577.            P0= table1[ i];
  578.        DULA=0;
  579.            delayms(1);
  580.          }
  581.      }
  582.          if(K4==0) break;
  583.          }
  584.      
  585.      }
  586. }
  587. }


复制代码
回复

使用道具 举报

ID:77760 发表于 2015-4-23 09:03 | 显示全部楼层
楼主强大
回复

使用道具 举报

ID:77760 发表于 2015-4-23 09:03 | 显示全部楼层
谢谢楼主
回复

使用道具 举报

ID:32941 发表于 2015-4-28 10:40 | 显示全部楼层
用的吗,试验一下
回复

使用道具 举报

ID:84705 发表于 2015-9-18 18:42 | 显示全部楼层
强大啊
回复

使用道具 举报

ID:90704 发表于 2015-9-21 23:07 | 显示全部楼层
好強阿~~
回复

使用道具 举报

ID:99989 发表于 2015-12-22 15:28 | 显示全部楼层
能不能用汇编?感谢撸主
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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