登录|立即注册|使用QQ帐号登录
论坛 > 51单片机
发帖|
看2142|回0|收藏
楼主 ID:707317 只看他
2020-3-12 21:56
这是我做的单片机减一秒表计数设计,包含硬件电路相关介绍以及各部分原理说明。
最后附上软件部分的程序设计流程图以及相关的程序编写内容。
大家有需要的可以下载参考。
1秒表设计(两位的LED数码减1数码显示,采用定时/计数器实现定时控制,能实现开始计数、停止计数和清零控制等功能)。
数值从99减到0,能启动开始计数、暂停、复位到99重新计数,对于实验室单片机硬件设备可用8255扩展的8位七段LED显示器选其两位进行显示,3种功能可用矩阵键盘来控制实现,1秒倒计时可用定时器T0选择模式2实现。
硬件设计(包括设计方案及说明、完整的硬件连接图等)
设计方案:2位七段LED显示器显示,定时器选用T0,选择模式2,采用内部中断,矩阵键盘控制不同情况。(停止计数可用使定时器停止工作和使LED显示当前数2种方法实现,这里选用使LED显示当前数暂停
说明:选其1,2位七段LED显示器分别作为十位和个位,读其矩阵键盘键值进行判断再改变工作状态:
硬件连接:8255扩展七段LED显示器及矩阵键盘即可。
LED显示原理:
①实验箱上8155扩展的有8位七段LED显示器,采用动态方式驱动。即一位LED显示器显示一小段时间,然后是下一位LED显示器显示一段小时间。只要刷新频率不小于50Hz,利用人眼的视觉误差,就可以获得清晰稳定的显示效果。
②LED显示器的各段由8155的B口驱动,各段的驱动位如表;段引脚为低电平则对应段发光,高电平则对应段熄灭,显示字的字形代码如表;8个LED的选择位由8255的A口驱动,高电平则选中对应位,低电平则对应位熄灭。
程序流程图
1584021074(1).png
                                                                                           1584021128(1).png
单片机源程序编写:

代码:

  1. #include <intrins.h>
  2. #include < absacc.h >
  3. #include<reg52.h>
  4. #define COM8155 XBYTE[0x1000]  //8155写命令地址口
  5. #define PA8155 XBYTE[0x1001]   //PA口读写地址口
  6. #define PB8155 XBYTE[0x1002]   //PB口读写地址口     
  7. #define PC8155 XBYTE[0x1003]   //PC口读写地址口
  8. code unsigned char led_font[] = {0xc0,0xf9,0xa4,0xb0,  
  9.                           0x99,0x92,0x82,0xf8,
  10.                                            0x80,0x90,0x88,0x83,  
  11.                                       0xc6,0xa1,0x86,0x8e,
  12.                                                        0xff
  13.                                                       }; //共阴数码管0-9、a-f及全熄的字形码
  14. code unsigned char key_code[]={0x11,0x12,0x14,0x18,
  15.                               0x21,0x22,0x24,0x28,
  16.                               0x41,0x42,0x44,0x48,
  17.                               0x81,0x82,0x84,0x88};  //此数组为键盘编码
  18. unsigned char key_read(void);                                            //读键盘函数
  19. unsigned char led_data[8]={16,16,16,16,16,16,16,16};//当前的显示数字
  20. void  delay_ms(unsigned charn);     //延时程序
  21. void  led_display(unsignedchar *p );  //LED动态显示子程序
  22. unsigned int m;
  23. void led_display(unsigned char *p)
  24. {  unsigned char i;
  25.    unsigned char j;
  26.    unsigned char led_bit[8]={0x10,0x20,0x40,0x80,0x01,0x02,0x04,0x08};
  27.                     //LED的位选码表
  28. for (i=0;i<2;i++)  
  29.   {
  30.          PB8155 =led_font[p[ i]];
  31.     PA8155 = led_bit[ i];
  32.       for (j=0;j<125;j++);
  33.   }
  34. }
  35. void delay_ms(unsigned char n)      //延时Nms
  36. {
  37. unsigned char i;
  38. while(n--)                                                   // 对于11.0592M时钟,约延时1ms
  39. {
  40. for (i=0;i<125;i++);
  41. }
  42. }
  43. unsigned char n=1;                     //用于暂停时等待再次启动的while循环
  44. unsigned char second;                                                                            //定义计数second
  45. void main (void)                                                                                       //主函数
  46. {
  47. TMOD=0X02;                                                                                        //选定时器0,工作方式2
  48. TH0=0X06;                                                                                              //设定定时器初值
  49.   TL0=0X06;
  50. ET0=1;                                                                                                      //开定时器中断
  51. EA=1;                                                                                                       //允许CPU中断
  52. second=99;                                                                                              //设定second初值99
  53. COM8155 = 0x03;                                                                                   //C口输入,A、B口输出
  54. while(1)                                                                                                       //等待启动键0按下
  55.   {  n=1;
  56.     if(key_read()==0)                                                                                //按下启动键0
  57.      {
  58.       TR0=1;                                                                                            //开始计数
  59. }
  60.   }
  61. }
  62. void t0(void) interrupt 1 using 0                                             //TL0计数溢出时进入中断函数
  63. {m++;                                                                                                 //每次进入中断函数m++
  64. {
  65. led_display(led_data);  //调用LED显示程序
  66. if(m==85)                                                                                  //m==85时一秒
  67.    {
  68. m=0;                                                                                      //使m=0,用于下次m再计时
  69.     second--;                                                                                  //到达一秒时当前值减1
  70.     led_data[0]=second/10;                                                        //送出当前值显示(十位)
  71.     led_data[1]=second%10;                                                       //(个位)
  72.    }
  73. else                                                                                                    //未到一秒时显示当前值
  74.   {
  75.    led_data[0]=second/10;
  76.    led_data[1]=second%10;
  77.    }
  78. if(second==-1)                                                                      //second<0时再赋值99循环
  79.          {
  80. second=99;
  81.          }  
  82. if(key_read()==1)                                                                 //按下暂停键1时
  83.          {
  84.       while(n)                                                                              //循环显示当前值
  85.           {
  86. led_data[0]=second/10;
  87.       led_data[1]=second%10;
  88.       led_display(led_data);                                                        //调用LED显示程序
  89.   if(key_read()==0)   //再次按下启动键0时,n==0,跳出while循环
  90.            {
  91. TR0=0;
  92.              n=0;
  93. }      
  94.    }
  95. }
  96.    if(key_read()==2)              //按下复位键时,second=99
  97.          {second=99;
  98.                    led_data[0]=second/10;
  99.    led_data[1]=second%10;
  100.    }
  101. }
  102. }
  103. unsigned char key_read(void)  //读键盘值,PA低四位为输出端即键盘列输出端,PC低四位为输入端即键盘行输入端
  104. {
  105. unsigned char i,scandata;
  106.                     //col_out输出PA口低四位,row_in获取PC口低四位,组合成键码
  107. unsigned char key_current,col_out,row_in;                 
  108. scandata=0x01;     //设定扫描初值
  109. PA8155=0x0f;  
  110. delay_ms(5);   
  111. if((PC8155&0x0f)==0x00) //无按键按下,防止读取不到键值,比如说是干扰
  112.       {
  113. return  0xff;
  114.        }
  115. for(i=0;i<4;i++)
  116.   {
  117.    PA8155=scandata;        //PA口低四位循环输出0,扫描键盘
  118. col_out=0x0f&scandata;   //存储PA口扫描的低四位
  119. if((PC8155&0x0f)!=0x00)   //再次检测PC口低四位是否有低电平
  120.      {
  121. row_in=(PC8155&0x0f)<<4;    //存储PC口的低四位
  122. key_current=row_in+col_out; //key存储键盘编码,键码为行(高4位)加列(低4位)
  123.       }
  124. scandata=_crol_(scandata,1);   //此函数功能为左循环移位
  125.    }
  126. for(i=0;i<16;i++)                           //查表获得相应的16进制值存放key_result中
  127.    {
  128. if(key_current==key_code)  
  129.      {
  130. return i;      
  131.      }
  132.    }
  133. return 0xff;

  134. }





51黑电子论坛

Powered by Discuz! X3.1

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