| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 6719 人关注过本帖
标题:请高手帮忙修改单片机加减计数器程序
只看楼主 加入收藏
mllwj
Rank: 1
等 级:新手上路
帖 子:22
专家分:0
注 册:2017-4-19
结帖率:50%
收藏
已结贴  问题点数:20 回复次数:35 
请高手帮忙修改单片机加减计数器程序
小弟根据实物画了一个电路图,电路原来是一个加减计数器,
按k1加,按k2减,
数码管是共阴极,
K3和K4原来闲置没用,可以写成设置按K1一次或者按K2一次递加的数值(比如按一次k1加0.1-----99,按k2一次减0.1----99 ),
k5清零。
我不懂写程序,现在网上找到两个类似的,不知道其中那个更适合修改,谁能帮忙修改一下能用在这电路上啊,万分感谢!!
程序要求按能任意设置K1一次或者按K2一次递加的数值(比如按一次k1加0.1-----99,按k2一次减0.1----99 ),四位数字,十位和百位之间显示小数点。下面是我在网上找到的程序
图片附件: 游客没有浏览图片的权限,请 登录注册

#include<reg52.h>
#define leddata P1 //数码管的段码输出
#define uchar unsigned char
#define uint unsigned int
uint shu;
sbit jia=P3^0; //加一按键
sbit jian=P3^1; //减一按键
sbit qw=P3^2; //数码管的千位
sbit bw=P3^3; //数码管的百位
sbit sw=P3^4; //数码管的十位
sbit gw=P3^5; //数码管的个位
uchar code tab[]={ 0xC0,/*0*/
0xF9,/*1*/
0xA4,/*2*/
0xB0,/*3*/
0x99,/*4*/
0x92,/*5*/
0x82,/*6*/
0xF8,/*7*/
0x80,/*8*/
0x90,/*9*/
};
void desplay();
void delay(uchar a) //延时函数
{
uchar x,y;
for(x=0;x for(y=0;y<200;y++);
}
void key() //按键扫描函数
{
if(jia==0)
{
delay(50);
if(jia==0)
{
while(!jia)desplay();
if(shu==9999)shu=0;
else shu++;
}
}
if(jian==0)
{
delay(50);
if(jian==0)
{
while(!jian)desplay();
if(shu==0)shu=9999;
else shu--;
}
}
}
void desplay() //显示函数
{
leddata=tab[shu/1000]; qw=0;delay(200);qw=1;
leddata=tab[shu%1000/100];bw=0;delay(200);bw=1;
leddata=tab[shu%100/10];sw=0;delay(200);sw=1;
leddata=tab[shu%10];gw=0;delay(200);gw=1;
}
void main() //主函数
{
while(1)
{
key();
desplay();
}
}


第二个

#include
#define Key_UP P3_6 //上调
#define Key_DOWN P3_7 //下调
#define LED P0
#define LED1 P2_2 //LED控制
#define LED2 P2_3 //LED控制
#define LED3 P2_4 //LED控制
#define LED4 P2_5 //LED控制
#define LED5 P2_6 //LED控制
#define LED6 P2_7 //LED控制
unsigned char code LEDDis[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
//共阳0-9的LED笔划
static unsigned char bdata Key; //可位寻址的状态寄存器
sbit NewKeyUP = Key ^ 0;
sbit NewKeyDOWN = Key ^ 1;
sbit OldKeyUP = Key ^ 2;
sbit OldKeyDOWN = Key ^ 3;
static unsigned long data Count;
static unsigned char LEDN[6];
void main(void)
{
void Delay_510(void);
Count = 0; //初始化变量
Key = 0;
EA = 1; //允许CPU中断
ET0 = 1; //定时器0中断打开
TMOD = 0x1; //设定时器0为模式1,16位模式
TH0=0xB1;
TL0=0xDF; //设定时值为20000us(20ms)
TR0 = 1; //开始定时
while(1);
}
//定时器0中断外理中键扫描和显示
void KeyAndDis_Time0(void) interrupt 1 using 2
{
TH0=0xB1;
TL0=0xDF; //设定时值为20000us(20ms)
NewKeyUP = Key_UP; //取新的键值
NewKeyDOWN = Key_DOWN;
if (!OldKeyUP && NewKeyUP) //键放开时,这里的中断为20ms左右(定时值非自动装载所以多于20ms)
Count++;
if (!OldKeyDOWN && NewKeyDOWN)
Count--; //这里Conut为int 没有做负数等处理,有需要自行加上
if (Count>999999)
Count = 999999;
LEDN[5]=Count/100000;
LEDN[4] = (Count-100000*(long)LEDN[5])/10000;
LEDN[3] = (Count-100000*(long)LEDN[5]-10000*(long)LEDN[4])/1000;
LEDN[2] = (Count-100000*(long)LEDN[5]-10000*(long)LEDN[4]-1000*(long)LEDN[3])/100;
LEDN[1] = (Count-100000*(long)LEDN[5]-10000*(long)LEDN[4]-1000*(long)LEDN[3]-100*(long)LEDN[2])/10;
LEDN[0] = (Count-100000*(long)LEDN[5]-10000*(long)LEDN[4]-1000*(long)LEDN[3]-100*(long)LEDN[2]-10*(long)LEDN[1]);
LED=LEDDis[LEDN[5]];
LED6 = 0;
Delay_510();
LED6 = 1;
LED=LEDDis[LEDN[4]];
LED5 = 0;
Delay_510();
LED5 = 1;
LED=LEDDis[LEDN[3]];
LED4 = 0;
Delay_510();
LED4 = 1;
LED=LEDDis[LEDN[2]];
LED3 = 0;
Delay_510();
LED3 = 1;
LED=LEDDis[LEDN[1]];
LED2 = 0;
Delay_510();
LED2 = 1;
LED=LEDDis[LEDN[0]];
LED1 = 0;
Delay_510();
LED1 = 1;
OldKeyUP = NewKeyUP;
OldKeyDOWN = NewKeyDOWN;
}
void Delay_510(void) //延时510微秒
{
#pragma asm
MOV R0,#7DH
MOV R1,#02H
TSR1:
DJNZ R0,TSR1
MOV R0,#7DH
DJNZ R1,TSR1
#pragma endasm
}

[此贴子已经被作者于2017-4-25 12:21编辑过]

搜索更多相关主题的帖子: 单片机 计数器 电路图 数码管 小数点 
2017-04-25 09:25
grmmylbs
Rank: 14Rank: 14Rank: 14Rank: 14
等 级:贵宾
威 望:54
帖 子:1409
专家分:5845
注 册:2016-2-14
收藏
得分:20 
1. 数码管共阴共阳不清楚,如果显示不对,可以自行修改LED_table里面的值。
2. K3和K4不知道干嘛用,没写。
3. 没调试环境,不保证代码正确性。

程序代码:
#include<reg52.h>


#define uchar unsigned char
#define uint unsigned int

//=======================================================================
void sendbyte(uint Num);

 void delay( int ms);

 //=======================================================================
 unsigned char code LED_table[]={       //使用附带“51单片机工具箱”可以很容易编码
 0x3f,                             //"0"
 0x06,                             //"1"
 0x5b,                             //"2"            AAAA
 0x4f,                             //"3"           F    B
 0x66,                             //"4"           F    B
 0x6d,                             //"5"            GGGG
 0x7d,                             //"6"           E    C
 0x07,                             //"7"           E    C
 0x7f,                             //"8"            DDDD    H
 0x6f,                             //"9"
 0x00,                             //black
 0x80                             //dot
 };

#define black 10                // 空白
#define dot   11                // 小数点

//                   定义通信端口
//===========================================================================
 sbit COM0=P1^0;

 sbit COM1=P1^6;                //对应口线由硬件确定
 sbit COM2=P1^5;

 sbit COM3=P1^4;

 //===========================================================================


 sbit k1=P1^1;//定义加加
 sbit k2=P3^4;//定义减减
 sbit k3=P3^5;//定义设置
 sbit k4=P1^2;//定义设置
 sbit k5=P1^3;//定义清零
 sbit CLK=P3^0;//164模拟时钟端
 sbit DAT=P3^1;//164模拟数据端
 uint z = 0;

 
void delay(uint t)//延时函数
{
      uint x,y;
      for(x=t;x>0;x--)
      for(y=120;y>0;y--);
}

 
void sendbyte(uint b)//传送显示字节函数
{
      uchar num,c;
    
      num=LED_table[b%10];//个位
      for(c=0;c<8;c++)//依次传送8位
    {
       CLK=0;
       DAT=num&0x01;
       CLK=1;
       num>>=1;
    }
    
      num=LED_table[b%100/10];//十位
      for(c=0;c<8;c++)//依次传送8位
    {
       CLK=0;
       DAT=num&0x01;
       CLK=1;
       num>>=1;
   }
    
   num=LED_table[b%1000/100] + LED_table[11];//百位,加上小数点
   for(c=0;c<8;c++)//依次传送8位
   {
       CLK=0;
       DAT=num&0x01;
       CLK=1;
       num>>=1;
   }
   
   num=LED_table[b/1000];//千位
   for(c=0;c<8;c++)//依次传送8位
   {
       CLK=0;
       DAT=num&0x01;
       CLK=1;
       num>>=1;
   }
}    


 void key()

 {
  if(k1==0)
  {
      delay(3);
      if(k1==0)
       {
           //TR0=0;
           z++;
           if(z==10000)
            z=0;
           sendbyte(z);
       }
      while(!k1);//放开按钮
    }
  if(k2==0)
  {
      delay(3);
      if(k2==0)
       {
           //TR0=1;
           z--;
           if(z<0)
            z=0;
           sendbyte(z);
       }
      while(!k2);//放开按钮
  }
  if(k5==0)
  {
      delay(3);
      if(k5==0)
       {
           //TR0=1;
           z=0;
           sendbyte(z);
       }
      while(!k5);//放开按钮
  }

 }

 void main()

 {
      TMOD=0X01;//定时器0定时方式1
      TH0=0XD8;//晶振12MHZ,定时10ms
      TL0=0XF0;
      EA=1;
      ET0=1;
      TR0=1;
      COM0 = COM1 =COM2 = COM3 = 0;    //点亮数码管
      sendbyte(0);
      while(1)
      key();
   

 }

 void time()interrupt 1//定时器中断
 {
      uint count;
      TH0=0XD8;
      TL0=0XF0;
      count++;
      if(count==100)//10毫秒X100=1秒
      {
       count=0;
       #if 0    //计时功能,不用
       z++;
       if(z==10000)
       {
       z=0;
       }
       sendbyte(z);//刷新显示
       #endif
      } 

 }



[此贴子已经被作者于2017-4-25 10:49编辑过]

2017-04-25 10:48
mllwj
Rank: 1
等 级:新手上路
帖 子:22
专家分:0
注 册:2017-4-19
收藏
得分:0 
非常感谢!!数码管是共阴极,K3和K4原来闲置没用,可以写成设置按K1一次或者按K2一次递加的数值(比如按一次k1加0.1-----99,按k2一次减0.1----99 )

[此贴子已经被作者于2017-4-25 12:22编辑过]

2017-04-25 11:32
mllwj
Rank: 1
等 级:新手上路
帖 子:22
专家分:0
注 册:2017-4-19
收藏
得分:0 
以下是引用grmmylbs在2017-4-25 10:48:20的发言:

1. 数码管共阴共阳不清楚,如果显示不对,可以自行修改LED_table里面的值。
2. K3和K4不知道干嘛用,没写。
3. 没调试环境,不保证代码正确性。

#include<reg52.h>


#define uchar unsigned char
#define uint unsigned int

//=======================================================================
void sendbyte(uint Num);
 void delay( int ms);
 //=======================================================================
 unsigned char code LED_table[]={       //使用附带“51单片机工具箱”可以很容易编码
 0x3f,                             //"0"
 0x06,                             //"1"
 0x5b,                             //"2"            AAAA
 0x4f,                             //"3"           F    B
 0x66,                             //"4"           F    B
 0x6d,                             //"5"            GGGG
 0x7d,                             //"6"           E    C
 0x07,                             //"7"           E    C
 0x7f,                             //"8"            DDDD    H
 0x6f,                             //"9"
 0x00,                             //black
 0x80                             //dot
 };

#define black 10                // 空白
#define dot   11                // 小数点

//                   定义通信端口
//===========================================================================
 sbit COM0=P1^0;
 sbit COM1=P1^6;                //对应口线由硬件确定
 sbit COM2=P1^5;
 sbit COM3=P1^4;
 //===========================================================================

 sbit k1=P1^1;//定义加加
 sbit k2=P3^4;//定义减减
 sbit k3=P3^5;//定义设置
 sbit k4=P1^2;//定义设置
 sbit k5=P1^3;//定义清零
 sbit CLK=P3^0;//164模拟时钟端
 sbit DAT=P3^1;//164模拟数据端
 uint z = 0;
 
void delay(uint t)//延时函数
{
      uint x,y;
      for(x=t;x>0;x--)
      for(y=120;y>0;y--);
}
 
void sendbyte(uint b)//传送显示字节函数
{
      uchar num,c;
   
      num=LED_table10];//个位
      for(c=0;c<8;c++)//依次传送8位
    {
       CLK=0;
       DAT=num&0x01;
       CLK=1;
       num>>=1;
    }
   
      num=LED_table100/10];//十位
      for(c=0;c<8;c++)//依次传送8位
    {
       CLK=0;
       DAT=num&0x01;
       CLK=1;
       num>>=1;
   }
   
   num=LED_table1000/100] + LED_table[11];//百位,加上小数点
   for(c=0;c<8;c++)//依次传送8位
   {
       CLK=0;
       DAT=num&0x01;
       CLK=1;
       num>>=1;
   }
   
   num=LED_table1000];//千位
   for(c=0;c<8;c++)//依次传送8位
   {
       CLK=0;
       DAT=num&0x01;
       CLK=1;
       num>>=1;
   }
}   

 void key()
 {
  if(k1==0)
  {
      delay(3);
      if(k1==0)
       {
           //TR0=0;
           z++;
           if(z==10000)
            z=0;
           sendbyte(z);
       }
      while(!k1);//放开按钮
    }
  if(k2==0)
  {
      delay(3);
      if(k2==0)
       {
           //TR0=1;
           z--;
           if(z<0)
            z=0;
           sendbyte(z);
       }
      while(!k2);//放开按钮
  }
  if(k5==0)
  {
      delay(3);
      if(k5==0)
       {
           //TR0=1;
           z=0;
           sendbyte(z);
       }
      while(!k5);//放开按钮
  }
 }
 void main()
 {
      TMOD=0X01;//定时器0定时方式1
      TH0=0XD8;//晶振12MHZ,定时10ms
      TL0=0XF0;
      EA=1;
      ET0=1;
      TR0=1;
      COM0 = COM1 =COM2 = COM3 = 0;    //点亮数码管
      sendbyte(0);
      while(1)
      key();
   
 }
 void time()interrupt 1//定时器中断
 {
      uint count;
      TH0=0XD8;
      TL0=0XF0;
      count++;
      if(count==100)//10毫秒X100=1秒
      {
       count=0;
       #if 0    //计时功能,不用
       z++;
       if(z==10000)
       {
       z=0;
       }
       sendbyte(z);//刷新显示
       #endif
      }
 }

用这个程序编译出来后仿真时显示这样的结果
图片附件: 游客没有浏览图片的权限,请 登录注册

下面是仿真文件
仿真文件.rar (56.86 KB)
2017-04-25 14:34
grmmylbs
Rank: 14Rank: 14Rank: 14Rank: 14
等 级:贵宾
威 望:54
帖 子:1409
专家分:5845
注 册:2016-2-14
收藏
得分:0 
这就是我说的第一点,
有没有试着按动加1按钮,看看有没有变化。
你只要找到一点规律,就能通过改动来修正
2017-04-25 16:02
mllwj
Rank: 1
等 级:新手上路
帖 子:22
专家分:0
注 册:2017-4-19
收藏
得分:0 
回复 5楼 grmmylbs
仿真是时候按加一或者减一都没反应,把程序烧到单片机里这样显示
图片附件: 游客没有浏览图片的权限,请 登录注册

按加一或者减一就黑屏,什么都不显示,断电重新加电又显示这个笔画
对了,单片机实物是STC11F02E,Proteus里没有STC11F02E,所以我找了89c2051代替,电路图是一模一样的,不知道有没影响
数码管可以确定是共阴极的

[此贴子已经被作者于2017-4-25 17:00编辑过]

2017-04-25 16:54
grmmylbs
Rank: 14Rank: 14Rank: 14Rank: 14
等 级:贵宾
威 望:54
帖 子:1409
专家分:5845
注 册:2016-2-14
收藏
得分:0 
下班了,明天帮你看。
2017-04-25 18:17
mllwj
Rank: 1
等 级:新手上路
帖 子:22
专家分:0
注 册:2017-4-19
收藏
得分:0 
以下是引用grmmylbs在2017-4-25 18:17:44的发言:

下班了,明天帮你看。



好的,感谢!非常感谢!!我是个只懂点硬件的人,软件完全不懂
2017-04-25 18:19
grmmylbs
Rank: 14Rank: 14Rank: 14Rank: 14
等 级:贵宾
威 望:54
帖 子:1409
专家分:5845
注 册:2016-2-14
收藏
得分:0 
试试这个
程序代码:
#include<reg52.h>


#define uchar unsigned char
#define uint unsigned int

//=======================================================================
void sendbyte(uint Num);

 void delay( int ms);

 //=======================================================================
 unsigned char code LED_table[]={       //使用附带“51单片机工具箱”可以很容易编码
 0x3f,                             //"0"
 0x06,                             //"1"
 0x5b,                             //"2"            AAAA
 0x4f,                             //"3"           F    B
 0x66,                             //"4"           F    B
 0x6d,                             //"5"            GGGG
 0x7d,                             //"6"           E    C
 0x07,                             //"7"           E    C
 0x7f,                             //"8"            DDDD    H
 0x6f,                             //"9"
 0x00,                             //black
 0x80                             //dot
 };

#define black 10                // 空白
#define dot   11                // 小数点

//                   定义通信端口
//===========================================================================
 sbit COM0=P1^0;

 sbit COM1=P1^6;                //对应口线由硬件确定
 sbit COM2=P1^5;

 sbit COM3=P1^4;

 //===========================================================================


 sbit k1=P1^1;//定义加加
 sbit k2=P3^4;//定义减减
 sbit k3=P3^5;//定义设置
 sbit k4=P1^2;//定义设置
 sbit k5=P1^3;//定义清零
 sbit CLK=P3^0;//164模拟时钟端
 sbit DAT=P3^1;//164模拟数据端
 uint z = 0;

 
void delay(uint t)//延时函数
{
      uint x,y;
      for(x=t;x>0;x--)
      for(y=120;y>0;y--);
}

 
void sendbyte(uint b)//传送显示字节函数
{
      uchar num,c;
    COM0 = COM1 =COM2 = COM3 = 1;    //熄灭数码管

    COM0 = 0;
      num=LED_table[b%10];//个位
      for(c=0;c<8;c++)//依次传送8位
    {
       CLK=0;
       DAT=num&0x01;
       CLK=1;
       num>>=1;
    }

    COM0 = 1;

    COM1 = 0;
      num=LED_table[b%100/10];//十位
      for(c=0;c<8;c++)//依次传送8位
    {
       CLK=0;
       DAT=num&0x01;
       CLK=1;
       num>>=1;
   }
    COM1 = 1;

    COM2 = 0;
   num=LED_table[b%1000/100] + LED_table[11];//百位,加上小数点
   for(c=0;c<8;c++)//依次传送8位
   {
       CLK=0;
       DAT=num&0x01;
       CLK=1;
       num>>=1;
   }
   COM2 = 1;

   COM3 = 0;
   num=LED_table[b/1000];//千位
   for(c=0;c<8;c++)//依次传送8位
   {
       CLK=0;
       DAT=num&0x01;
       CLK=1;
       num>>=1;
   }
   COM3 = 1;
}    


 void key()

 {
  if(k1==0)
  {
      delay(3);
      if(k1==0)
       {
           //TR0=0;
           z++;
           if(z==10000)
            z=0;
           //sendbyte(z);
       }
      while(!k1);//放开按钮
    }
  if(k2==0)
  {
      delay(3);
      if(k2==0)
       {
           //TR0=1;
           z--;
           if(z<0)
            z=0;
           //sendbyte(z);
       }
      while(!k2);//放开按钮
  }
  if(k5==0)
  {
      delay(3);
      if(k5==0)
       {
           //TR0=1;
           z=0;
           //sendbyte(z);
       }
      while(!k5);//放开按钮
  }
  sendbyte(z);
  delay(10);

 }

 void main()

 {
      TMOD=0X01;//定时器0定时方式1
      TH0=0XD8;//晶振12MHZ,定时10ms
      TL0=0XF0;
      EA=1;
      ET0=1;
      TR0=1;
      COM0 = COM1 =COM2 = COM3 = 0;    //点亮数码管
      sendbyte(0);
      while(1)
      key();
   

 }

 void time()interrupt 1//定时器中断
 {
      uint count;
      TH0=0XD8;
      TL0=0XF0;
      count++;
      if(count==100)//10毫秒X100=1秒
      {
       count=0;
       #if 0    //计时功能,不用
       z++;
       if(z==10000)
       {
       z=0;
       }
       sendbyte(z);//刷新显示
       #endif
      } 

 }

2017-04-26 09:47
mllwj
Rank: 1
等 级:新手上路
帖 子:22
专家分:0
注 册:2017-4-19
收藏
得分:0 
回复 9楼 grmmylbs
刚才试了,在百位上显示一笔在闪烁
图片附件: 游客没有浏览图片的权限,请 登录注册

按任何键没反应,烧到单片机里什么也不显示,按键也没反应
2017-04-26 10:19
快速回复:请高手帮忙修改单片机加减计数器程序
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.086391 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved