找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 10923|回复: 0
收起左侧

51单片机数码管显示学号程序+Proteus仿真电路图

[复制链接]
ID:507059 发表于 2019-4-8 15:41 | 显示全部楼层 |阅读模式
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
0.png 0.png

单片机源程序如下:
  1. #include <reg52.h>
  2. sbit hang1=P2^0;
  3. sbit hang2=P2^1;
  4. sbit lie1=P2^2;
  5. sbit lie2=P2^3;
  6. sbit buzzer=P2^7;                                //蜂鸣器

  7. //与ADC相关的位声明
  8. sbit ADC_START=P3^4;                        //转换启动信号,高脉冲启动转换
  9. sbit ADC_EOC=P3^2;                                //转换结束信号,高电平转换结束
  10. sbit ADC_A=P3^5;
  11. sbit ADC_B=P3^6;
  12. sbit ADC_C=P3^7;
  13. unsigned char code table[]={0x03,0x9f,0x25,0x0d,
  14.                             0x99,0x49,0x41,0x1f,
  15.                             0x01,0x09,0x11,0xc1,
  16.                             0xe5,0x85,0x21,0x71,0xff};


  17. void sendstr(unsigned char);         //串口发送数字显示
  18. void delay(unsigned char );                 //延时函数
  19. void desplay();                                        //移动显示学号函数
  20. void keyscan();                                        //键盘扫描函数
  21. void desplay_key_number();
  22. void Get_ADC(void);        //ADC转换函数

  23. unsigned char b=0,i,counter=4,Time=0,flag=0,INT;
  24. float ADC_V;        //AD转换的电压值       
  25. int main()
  26. {

  27.         /*主程序初始化部分*/

  28.         EA=1;                //开总中断
  29.         SCON=0x00;          //串口初始化 ,工作方式0
  30.         EX1=1;                //开外部中断1
  31.         IT1=1;                //外部中断1电平触发
  32.         ET0=1;                //开启定时器0中断
  33.         ET1=1;                //开启定时器1中断
  34.         TMOD=0X11;        //定时器0工作方式1,定时器1工作方式1
  35.         TH0=(65536-50000)/256;
  36.         TL0=(65536-50000)%256;
  37.         TH1=(65536-500)/256;
  38.         TL1=(65536-500)%256;                               
  39.         hang1=hang2=0;
  40.         ADC_A=ADC_B=ADC_C=0;                //选择ADC转换通道0

  41.    


  42.         desplay();        //上电显示学号
  43.         while(1)
  44.         {
  45.                
  46.                 if(INT)                                                        //INT=1表示进入外部中断1,则可以进行键盘扫描
  47.                 {
  48.                         keyscan();                                        //扫描得到键值
  49.                         TR0=0;                                                //关闭定时器0,判断此时按键按下的时间
  50.                         INT=0;
  51.                         EX1=1;                                           //开外部中断1
  52.                 }
  53.                 if(counter!=4)
  54.                 {
  55.                                                                
  56.                         if(flag)                                 //到2.5秒执行
  57.                         {
  58.                                  switch (counter)
  59.                                 {
  60.                                         case 0:                                                                          //DA功能键,即梯形波
  61.                                                         TR1=1;                                                          //启动定时器1产生波形
  62.                                                         break;
  63.                                         case 1:                                                                           //学号显示键
  64.                                
  65.                                                         desplay();        //显示学号        delay(100);
  66.                                                         break;
  67.                                         case 2:
  68.                                
  69.                                                        
  70.                                                         break;
  71.                                         case 3:                                                                          //AD功能键

  72.                                                         for(i=0;i<8;i++)
  73.                                                                 {
  74.                                                                         sendstr(16);                          //将所有数码管清灭
  75.                                                                 }
  76.                                                         Get_ADC();
  77.                                                         SBUF=table[(int)(ADC_V)]&0xfe;          //与小数点一同显示
  78.                                                         while(!TI);
  79.                                                         TI=0;
  80.                                                         sendstr((int)(ADC_V*10)%10);
  81.                                                         sendstr((int)(ADC_V*100)%100%10);
  82.                                                         break;
  83.                                         default:
  84.                                                         break;
  85.                                 }
  86.                                 flag=0;                                  //在此将flag清零,而不在中断中清零
  87.                         }
  88.                         else                                         //未到2.5秒执行
  89.                         {
  90.                                
  91.                                         desplay_key_number();
  92.                                                                
  93.                         }
  94.                         counter=4;
  95.                 }
  96.         }
  97.        
  98. }




  99. void INT_1() interrupt 2                 //外部中断1函数
  100. {
  101.         TR0=1;                                                 //启动定时器0
  102.         TR1=0;                                                 //关闭定时器1,以免与定时器0冲突
  103.         Time=0;                                                 //不能在此将flag清零,放下按键也会产生抖动,
  104.                                                                 //此时进入中断将flag清零就错了,反应不了真实情况
  105.         buzzer=0;
  106.         delay(1);
  107.         buzzer=1;
  108.        
  109.         IE1=0;                                                //软件清零中断标志
  110.         EX1=0;                                                //关外部中断1,等待键盘扫描结束再重新打开
  111.         INT=1;                                                //进入中断标志位
  112. }

  113. void timer_0()        interrupt 1                //定时器0中断服务函数,用于判断2.5秒钟时间是否已到
  114. {
  115.         TH0=(65536-50000)/256;
  116.         TL0=(65536-50000)%256;                                              
  117.         Time++;
  118.         if(Time==50)
  119.                 {
  120.                         flag=1;                         //标志位置1
  121.                         /*蜂鸣器叫两声提示时间到*/
  122.                         buzzer=0;
  123.                         delay(1);
  124.                         buzzer=1;
  125.                         delay(1);
  126.                         buzzer=0;
  127.                         delay(1);
  128.                         buzzer=1;
  129.                 }                                               
  130. }

  131. void timer_1()        interrupt 3                  //矩形波发生中断函数
  132. {
  133.         TH1=(65536-500)/256;
  134.         TL1=(65536-500)%256;
  135.         TR0=0;                                                  //关闭定时器0,以免冲突
  136.         switch(b)
  137.         {
  138.                 case 0:
  139.                            P0=0x00;
  140.                            for(i=0;i<51;i++)
  141.                                 {
  142.                                         P0+=5;
  143.                                         ;;;;;;;;;;;;;;;;;;;                         //多个分号,用于延时
  144.                                 }
  145.                            b++;
  146.                            break;
  147.                 case 1:
  148.                            b++;
  149.                            break;
  150.                 case 2:
  151.                            for(i=0;i<51;i++)
  152.                                 {
  153.                                         P0-=5;
  154.                                         ;;;;;;;;;;;;;;;;;;;                         //多个分号,用于延时
  155.                                 }
  156.                                 b++;
  157.                            break;
  158.                 case 3:
  159.                            b=0;
  160.                            break;
  161.                 default:
  162.                                 break;
  163.         }
  164.        
  165. }



  166. void sendstr(unsigned char i) //串口发送数字显示
  167. {
  168.                 SBUF=table[i];
  169.                 while(!TI);
  170.                 TI=0;       
  171. }

  172. void keyscan()                                  //键盘扫描函数
  173. {

  174. //扫描第一行
  175.         hang1=0;
  176.         hang2=1;
  177.         if(lie1==0)
  178.                 {        delay(1);                        //消抖动
  179.                         while(!lie1);
  180.                         counter=0;
  181.                 }
  182.         if(lie2==0)
  183.                 {        delay(1);                        //消抖动
  184.                         while(!lie2);
  185.                         counter=1;
  186.                 }

  187. //扫描第二行
  188.         hang1=1;
  189.         hang2=0;
  190.         if(lie1==0)
  191.                 {        delay(1);                        //消抖动
  192.                         while(!lie1);
  193.                         counter=2;
  194.                 }
  195.         if(lie2==0)
  196.                 {        delay(1);                        //消抖动
  197.                         while(!lie2);
  198.                         counter=3;
  199.                 }

  200.         hang1=hang2=0;                                //出程序拉低按键行号
  201. }



  202. void desplay_key_number()                //显示按键值号函数
  203. {
  204.         unsigned char num;
  205.         for(num=0;num<8;num++)
  206.         {
  207.                 sendstr(counter);
  208.         }
  209. }



  210. void Get_ADC()        //ADC转换函数
  211. {
  212.         unsigned char ADC;
  213.         ADC_START=0;           ADC_START=1;         ADC_START=0;                                         //高脉冲启动转换       
  214.         while(ADC_EOC==0);                        //等待转换结束
  215.         ADC=P1;
  216.         ADC_V=(float)(ADC)/255*5;
  217. }





  218. void delay(unsigned char h)                //延时函数
  219. {
  220.         unsigned char j;
  221.         for(j=0;j<100;j++)
  222.         {
  223.                 while(h--);
  224.         }
  225. }

  226. void desplay()                           //移动显示学号函数
  227. {
  228.         unsigned char i;
  229.         for(i=0;i<8;i++)
  230.         {
  231.         sendstr(16);
  232.         }
  233.         i=250;
  234.         sendstr(0);
  235.         delay(i);
  236.         sendstr(1);
  237.         delay(i);
  238.         sendstr(1);
  239.         delay(i);
  240.         sendstr(1);
  241.         delay(i);
  242.         sendstr(0);
  243.         delay(i);
  244.         sendstr(1);
  245.         delay(i);
  246.         sendstr(5);
  247.         delay(i);
  248.         sendstr(0);
  249.         delay(i);               
  250. }
复制代码

所有资料51hei提供下载:
51单片机数码管显示学号.rar (47.04 KB, 下载次数: 34)

评分

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

查看全部评分

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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