找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机秒表程序,不知道错在哪里

[复制链接]
ID:1096616 发表于 2023-10-19 20:16 | 显示全部楼层 |阅读模式
要求:按键1启动秒表,数码管共阳
               按键2停止秒表,显示当前值
再按下按键1则从0开始计时,重复上述过程
计时范围0-59,采用显示缓冲器的方法编程,按键采用外部中断处理

单片机源程序如下:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf}; //段码
uchar code seg_scan[]={16,16,16,16};//位选码
uchar seg_buf[2]={0x01,0x02};//数码管显示缓冲区
void t0();//t0初始化
void ex();//外部中断初始化
void display();//数码管显示函数
void delayme(uint xms);//延时函数
uchar a=0,count=0;
void Time();


void main()
{  t0();
   ex();
while(1)
  {   Time();
     display();
  }
}
/***************显示函数**************/


void display()
{  uchar i,n=0x01;
  for(i=0;i<4;i++)
  {  P2=~n;//送位选
    P0=seg[seg_buf[ i]];//段码[ i]
     delayme(2);
     n=n<<1;
     P0=0XFF;//消隐
     P2=0XFF;
  }


}


void t0()
{   TMOD=0X01;
    TH0=(65536-50000)/256;
    TL0=(65536-50000)%256;
    ET0=1;   //打开t0中断开关
    PT0=0;   
    EA=1;   //打开中断总开关
}


void ex()
{  IT0=1;
   EX0=1;
   PX0=1;


   IT1=1;
   EX1=1;
   PX1=1;


   EA=1;


}


void t0_int() interrupt 1
{    TH0=(65536-50000)/256;
    TL0=(65536-50000)%256;
   count++;
   if(count>=20)
   {count=0;a++;}
    if(a>=60)a=0;
  
}


void key1()interrupt 0
{
        TR0=1;//启动t0
        a=0x00;
        IE0=0;//清int0中断标志位
}


void key2()interrupt 2
{
        TR0=0;//启动t0
        IE1=0;//清int1中断标志位
}
void delayme(uint xms)
{ uint i,j;
for(i=0;i<xms;i++)
  for(j=0;j<120;j++);
}
void Time()
{   seg_buf[0]=seg[a%10];  //低位--个位
    seg_buf[1]=seg[a/10];   //高位--十位
}
回复

使用道具 举报

ID:1096616 发表于 2023-10-19 21:11 | 显示全部楼层
后来修改成这个样子,但还是两个同时计时,而且按下按键1不可以从0开始,而是从1开始,而且为什么从一到二需要的时间比二到三时间更多
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
uchar code seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf}; //段码
uchar code seg_scan[]={10,10,10,10};//位选码
uchar seg_buf[2]={0x01,0x02};//数码管显示缓冲区
void t0();//t0初始化
void ex();//外部中断初始化
void display(uchar date,uchar get);//数码管显示函数
void delayme(uint xms);//延时函数
uchar a=0,count=0;
uchar flags=0;//定时标志

void main()
{  t0();
   ex();
while(1)
  {if(flags==0)
   {  
     flags=1;
     a++;
     if(a>=60)
     {
       a=0;
     }
    seg_buf[0]=seg[a%10];  //低位
    seg_buf[1]=seg[a/10];   //高位

   }
  }
}


void display(uchar date,uchar get)
{  P2 = (P2&0x1f)|0xc0;
   P0=0X01<<get;
   P2 = (P2&0x1f)|0xf9;
   P0=date;
}

void t0()
{   TMOD=0X01;
    TH0=(65536-50000)/256;
    TL0=(65536-50000)%256;
    ET0=1;   //打开t0中断开关
    PT0=0;   
    EA=1;   //打开中断总开关
}

void ex()
{  IT0=1;
   EX0=1;
   PX0=1;

   IT1=1;
   EX1=1;
   PX1=1;

   EA=1;

}

void t0_int() interrupt 1
{    uchar i=0;
   TH0=(65536-50000)/256;
    TL0=(65536-50000)%256;
   count++;
   if(count>=20)
   {count=0;
    flags=0;
    }
    P0=0XFF;
   switch(i)
   { case 0:i++;display(seg_buf[0],1);break;
      case 1:i++;display(seg_buf[1],0);break;
      default:break;
   }
  
}

void key1()interrupt 0
{
        TR0=1;//启动t0
        a=0x00;
        IE0=0;//清int0中断标志位
}

void key2()interrupt 2
{
        TR0=0;//启动t0
        IE1=0;//清int1中断标志位
}


回复

使用道具 举报

ID:170318 发表于 2023-10-20 10:40 | 显示全部楼层
程序中当“flags==0”时,“a+1”,所以,显示不可能有0的,需将“seg_buf[0]=seg[a%10];  //低位
    seg_buf[1]=seg[a/10];   //高位”调整到flags==0的外面
回复

使用道具 举报

ID:170318 发表于 2023-10-20 10:44 | 显示全部楼层
程序中修改的地方较多,可以先用仿真软件调试,将程序调通。如果有板子,可以调整修改程序,理清程序运行流程
回复

使用道具 举报

ID:213173 发表于 2023-10-20 11:16 | 显示全部楼层
错误比比皆是,给你改了。 无标题.jpg

  1. #include<reg52.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int

  4. uchar code seg[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf}; //段码
  5. uchar seg_buf[2]={0xc0,0xc0};//数码管显示缓冲区

  6. void t0();//t0初始化
  7. void ex();//外部中断初始化
  8. void display();//数码管显示函数

  9. uchar a=0,sec;
  10. bit flags=0;//定时标志
  11. bit start;

  12. void main()
  13. {
  14.         t0();
  15.         ex();
  16.         while(1)
  17.         {
  18.                 if(flags && start)
  19.                 {  
  20.                         flags=0;
  21.                         if(++a>=200)
  22.                         {
  23.                                 a=0;
  24.                                 sec=++sec%60;
  25.                         }
  26.                         seg_buf[0]=seg[sec%10];  //低位
  27.                         seg_buf[1]=seg[sec/10];   //高位
  28.                 }
  29.         }
  30. }

  31. void t0()
  32. {
  33.         TMOD=0X01;
  34.         TH0=(65536-5000)/256;
  35.         TL0=(65536-5000)%256;
  36.         TR0=1;   
  37.         ET0=1;   //打开t0中断开关
  38.         EA=1;   //打开中断总开关
  39. }

  40. void ex()
  41. {
  42.         IT0=1;
  43.         EX0=1;
  44.         IT1=1;
  45.         EX1=1;
  46. }

  47. void display()
  48. {
  49.         static uchar i;
  50.         P0=0xff;
  51.         P2=0x01<<i;
  52.         P0=seg_buf[i];
  53.         if(++i==2)i=0;               
  54. }

  55. void t0_int() interrupt 1
  56. {
  57.         TH0=(65536-5000)/256;
  58.         TL0=(65536-5000)%256;
  59.         flags=1;
  60.         display();
  61. }

  62. void key1()interrupt 0
  63. {
  64.         sec=0;
  65.         a=0;
  66.         start=1;
  67. }

  68. void key2()interrupt 2
  69. {
  70.         start=0;
  71. }
复制代码



回复

使用道具 举报

ID:1096616 发表于 2023-10-20 15:06 | 显示全部楼层
jhczy 发表于 2023-10-20 10:40
程序中当“flags==0”时,“a+1”,所以,显示不可能有0的,需将“seg_buf[0]=seg[a%10];  //低位
    seg ...

按照你说的确实是可以从0开始计时,这个主意好棒。

回复

使用道具 举报

ID:1096616 发表于 2023-10-20 15:08 | 显示全部楼层
jhczy 发表于 2023-10-20 10:44
程序中修改的地方较多,可以先用仿真软件调试,将程序调通。如果有板子,可以调整修改程序,理清程序运行流 ...

用仿真的软件调试过了,但还是个十位同时计时,这就是问题

回复

使用道具 举报

ID:1096616 发表于 2023-10-20 19:23 | 显示全部楼层
wulin 发表于 2023-10-20 11:16
错误比比皆是,给你改了。

我试过你的方法确实可以实现要求,但问题是,我对于这部分代码其实不怎么明白,不知道这样设计的道理。
屏幕截图 2023-10-20 192230.png
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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