找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1068|回复: 5
打印 上一主题 下一主题
收起左侧

51单片机计数器程序修改功能增加,求大神帮忙指导如何改动下

[复制链接]
跳转到指定楼层
楼主
首先感谢ID:941754大佬提供的源程序,原文链接


源程序中:
无物品时,数码管显示P
有物品通过开始计数并在数码管上显示,每计满100个,蜂鸣器响一下。

单片机源程序如下:
  1. #include <reg51.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit FMQ=P3^7;
  5. //按键
  6. sbit K1=P3^0;
  7. sbit K2=P3^1;
  8. bit flag_KEY=0; //按键松开标志位
  9. //数码管引脚
  10. sbit Num1=P2^0;
  11. sbit Num2=P2^1;
  12. sbit Num3=P2^2;
  13. sbit Num4=P2^3;
  14. unsigned char ScanTime=1; //数码管4个位
  15. unsigned int Num=0;
  16. //数码管段码表
  17. unsigned char code SEG_Tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x00};
  18. /*-------------------------------------
  19.                             数码管显示
  20. ---------------------------------------*/
  21. void display()
  22. {
  23.         P0=0x00;
  24.         P2=0xFF;
  25.   switch(ScanTime)
  26.         {
  27.           //----------数码管第1位--------------
  28.                 case 1:
  29.                         if(Num==0)
  30.                         {
  31.                                 P0=0x00;
  32.                         }
  33.                         else
  34.                         {
  35.                                 P0=SEG_Tab[Num/1000];
  36.                         }
  37.                                 Num1=0;
  38.                 break;
  39.           //-----------数码管第2位-------------
  40.                 case 2:
  41.                         if(Num==0)
  42.                         {
  43.                                 P0=0x00;
  44.                         }
  45.                         else
  46.                         {
  47.                                 P0=SEG_Tab[Num/100%10];
  48.                         }
  49.                         Num2=0;
  50.                 break;
  51.                 //-----------数码管第3位-------------
  52.                 case 3:
  53.                         if(Num==0)
  54.                         {
  55.                                 P0=0x00;
  56.                         }
  57.                         else
  58.                         {
  59.                                 P0=SEG_Tab[Num/10%10];
  60.                         }
  61.                           Num3=0;
  62.                 break;
  63.                 //-----------数码管第4位-------------
  64.                 case 4:
  65.                         if(Num==0)
  66.                         {
  67.                                 P0=0x73;
  68.                         }
  69.                         else
  70.                         {
  71.                                 P0=SEG_Tab[Num%10];
  72.                         }
  73.                         Num4=0;
  74.                 break;
  75.          //------------------default---------------
  76.                 default: break;
  77.         }
  78.         //-----数码管循环------
  79.         ScanTime++;
  80.         if(ScanTime>4)
  81.         {
  82.                 ScanTime=1;//循环扫描
  83.         }
  84. }
  85. /*-------------------------------------
  86.                             按键扫描
  87. ---------------------------------------*/
  88. void keyscan()
  89. {
  90.         if(K1==0)
  91.         {
  92.                 if(flag_KEY==1)//按键只响应1次
  93.                 {
  94.                         flag_KEY=0;
  95.                         if(Num<999)
  96.                         {
  97.                                 Num++;
  98.                         }
  99.                 }
  100.         }
  101.         else if(K2==0)
  102.         {
  103.                 if(flag_KEY==1)//按键只响应1次
  104.                 {
  105.                         flag_KEY=0;
  106.                         if(Num>0)
  107.                         {
  108.                                 Num--;
  109.                         }
  110.                 }
  111.         }
  112.   else//按键松开
  113.   {
  114.           flag_KEY=1;
  115.   }
  116. }
  117. void delay_ms(unsigned int ms)// 延时子程序
  118. {
  119.   unsigned int a,b;
  120.   for(a=ms;a>0;a--)
  121.   for(b=123;b>0;b--);
  122. }
  123. /*-------------------------------------
  124.                             主函数
  125. ---------------------------------------*/
  126. void main()
  127. {
  128.         while(1)
  129.         {
  130.                 display();
  131.                 keyscan();
  132.                 delay_ms(10);
  133.                 if(Num>=100)
  134.                 {
  135.                         FMQ=0;
  136.                 }
  137.                 else
  138.                 {
  139.                         FMQ=1;
  140.                 }
  141.         }
  142. }
复制代码
我想这个的基础上加以修改致用,原理图为:



其中为两种模式(按模式按键切换),模式一:
1.计数模式,上面数码管显示”----“
2.下面数码管显示计数,其中光电开关动作一次,数码管计数+1,直到9999
3.led状态指示灯点亮,图中未体现(可用空闲IO口)
4.按开始按键电机开始运转,暂停键电机暂停(P3.7口)
模式二:
1.通过矩阵键盘输入设定的数值于上面数码管显示
2.按开始按键后电机开始运转,光电开关开始检测数据并在下发数码管中显示
3.数据达到设定的数值后电机停止,也可手动按暂停按键暂停,再次按暂停按键或开始按键后数值继续增加。
4.led状态指示灯点亮,图中未体现(可用空闲IO口,与模式一区分开)

求大佬们指导指导

计数.zip

124.38 KB, 下载次数: 6

源程序及修改的

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:123289 发表于 2022-12-8 09:07 | 只看该作者
程序是自己写的吗?
回复

使用道具 举报

板凳
ID:480171 发表于 2022-12-8 14:15 | 只看该作者
有没有大佬指导下的
回复

使用道具 举报

地板
ID:213173 发表于 2022-12-8 21:59 | 只看该作者
给你改写了,只用两个键,一个用于设置选项,一个多功能键。用外部中断计数。仿真正常,你自己完善其它硬件。



  1. #include<reg51.h>
  2. #include<intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int

  5. sbit K1=P2^4;
  6. sbit K2=P2^5;
  7. sbit OUT=P2^6;
  8. sbit buzzer=P2^7;

  9. uchar code tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳LED段码表
  10. uchar displayData[4];//显示数据缓存
  11. uchar qian,bai,shi,ge;
  12. uchar Cnt5ms;
  13. uchar KeySec=0;
  14. uint num;
  15. int count;
  16. bit flashing=0;//闪烁标志

  17. void Timer0Init(void)                //5毫秒@12.000MHz
  18. {
  19.         TMOD |= 0x01;                //设置定时器模式
  20.         TL0 = 0x78;                //设置定时初始值
  21.         TH0 = 0xEC;                //设置定时初始值
  22.         TF0 = 0;                //清除TF0标志
  23.         TR0 = 1;                //定时器0开始计时
  24. }

  25. //按键扫描
  26. void keyscan()
  27. {
  28.         static unsigned int time=0;
  29.         static bit sign=0;
  30.         if(!K1||!K2)
  31.         {
  32.                 if(++time>=15 && sign==0)//短按消抖
  33.                 {
  34.                         sign=1;
  35.                         if(!K1)
  36.                         {
  37.                                 KeySec++;
  38.                                 if(KeySec>=5)
  39.                                 {
  40.                                         KeySec=0;
  41.                                         count=0;
  42.                                 }
  43.                         }

  44.                         if(!K2 && KeySec==0)
  45.                         {
  46.                                 if(count!=num)
  47.                                 {
  48.                                         EA = ~EA;//暂停/继续
  49.                                         OUT=EA;
  50.                                 }
  51.                                 else
  52.                                 {
  53.                                         count=0;
  54.                                         EA = 1;        //开始
  55.                                         OUT= 1;
  56.                                         buzzer=1;//蜂鸣器复位
  57.                                 }
  58.                         }
  59.                         if(!K2 && KeySec!=0)
  60.                         {
  61.                                 if(KeySec)
  62.                                 {
  63.                                         switch(KeySec)
  64.                                         {
  65.                                                 case 1: qian= ++qian%10; break;
  66.                                                 case 2: bai = ++bai%10; break;
  67.                                                 case 3: shi = ++shi%10; break;
  68.                                                 case 4: ge  = ++ge%10; break;
  69.                                         }
  70.                                         num=(qian*1000)+(bai*100)+(shi*10)+ge;
  71.                                         //        num写入EEPROM保存,下次上电直接调用
  72.                                 }       
  73.                         }
  74.                 }
  75.         }
  76.         else
  77.         {
  78.                 time=0;
  79.                 sign=0;
  80.         }
  81. }

  82. void display()//显示
  83. {
  84.         static uchar i=0;
  85.         if(KeySec==0)
  86.         {//显示计数值               
  87.                 displayData[0] = tab[count/1000%10];
  88.                 displayData[1] = tab[count/100%10];
  89.                 displayData[2] = tab[count/10%10];
  90.                 displayData[3] = tab[count%10];
  91.         }
  92.         if(KeySec!=0)
  93.         {//显示设定值
  94.                 displayData[0] = tab[num/1000%10];
  95.                 displayData[1] = tab[num/100%10];
  96.                 displayData[2] = tab[num/10%10];
  97.                 displayData[3] = tab[num%10];
  98.         }
  99.         P2&=0xf0;//消隐
  100.         if(KeySec==1 && i==0 && flashing==0)
  101.                 P0=0xff;//千位闪烁
  102.         else if(KeySec==2 && i==1 && flashing==0)
  103.                 P0=0xff;//百位闪烁
  104.         else if(KeySec==3 && i==2 && flashing==0)
  105.                 P0=0xff;//十位闪烁
  106.         else if(KeySec==4 && i==3 && flashing==0)
  107.                 P0=0xff;//个位闪烁
  108.         else
  109.                 P0=displayData[i];
  110.         P2|=0x01<<i;
  111.         i++;i%=4;
  112. }

  113. void main()//主函数
  114. {
  115.         OUT=0;
  116.         Timer0Init();//初始化定时器
  117. //        num=读取EEPROM
  118.         IT0 = 1;// 外部下降沿中断
  119.         EX0 = 1;
  120. //        EA = 1;   
  121.         while(1)
  122.         {
  123.                 if(TF0)//查询定时器中断请求位
  124.                 {
  125.                         TF0=0;
  126.                         TL0 = 0x78;                //设置定时初始值
  127.                         TH0 = 0xEC;                //设置定时初始值
  128.                         Cnt5ms++;
  129.                         if(Cnt5ms==40)
  130.                         {
  131.                                 Cnt5ms=0;
  132.                                 flashing=~flashing;
  133.                         }
  134.                         keyscan();                        //按键扫描
  135.                         display();                        //数码管显示
  136.                 }
  137.         }
  138. }
  139. void exint0() interrupt 0
  140. {
  141.         count++;
  142.         if(count>=num)       
  143.         {
  144.                 buzzer=0;
  145.                 EA = 0;
  146.                 OUT= 0;
  147.         }
  148. }


复制代码




回复

使用道具 举报

5#
ID:480171 发表于 2022-12-11 19:12 | 只看该作者
yzwzfyz 发表于 2022-12-8 09:07
程序是自己写的吗?

不是的,是ID:941754发布的,我只是想在这个基础上进行修改,文头已经标注原文链接
回复

使用道具 举报

6#
ID:480171 发表于 2022-12-11 19:19 | 只看该作者
wulin 发表于 2022-12-8 21:59
给你改写了,只用两个键,一个用于设置选项,一个多功能键。用外部中断计数。仿真正常,你自己完善其它硬件 ...

感谢帮忙修正,我修改成矩阵键盘输入模式了,想请教下矩阵键盘怎样实现长按功能呢
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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