找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5979|回复: 4
收起左侧

求助用单片机C语言写一个按键计数器设计

[复制链接]
ID:213119 发表于 2017-6-20 22:29 | 显示全部楼层 |阅读模式
本帖最后由 Elvis 于 2017-6-22 09:15 编辑


操作要求:KEY1 、KEY2分别用于加减预置计数次数,按下一次数字分别加减一,如果连续按下超过2秒,则数字快速连续加减变化;
KEY3用于计数器启动/预置状态切换,按第一次进入预置状态,再按一次回到计数状态;
KEY4用于模拟单片机外部计数脉冲,每按下一次显示的设置加一,如果计数次数到预置数,则数字闪烁,蜂鸣器发音
帮我看看有什么问题吧!

按键计数.zip

56.41 KB, 下载次数: 62

回复

使用道具 举报

ID:213119 发表于 2017-6-22 09:16 | 显示全部楼层
能写出程序流图最好了。
回复

使用道具 举报

ID:34298 发表于 2019-9-2 18:53 | 显示全部楼层
#include<reg51.h> #include<INTRINS.h> #define u16 unsigned int #define u8 unsigned char   u16 count=0;   //计数设定值 u16 countTemp=0;//计数 u8 zt=0;       //状态 sbit fmq=P1^0; //蜂鸣器 u16 jsflag=0;  //闪烁计时用     /*********************************************************/ u8 ds[4]; //数码管显示缓存 //共阴 code u8 w[]={0xf1,0xf2,0xf4,0xf8};    //位码 code u8 d[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//断码 void dispaly(){//显示函数     static u8 a;     if(++a>3)a=0;     P0=0xFF;     P2=w[a];     P0=d[ds[a]]; }     /****************************************/ void init()    //初始化函数 {   TMOD=0x01;     TH0=(65536-1000)/256;     TL0=(65536-1000)%256;     EA=1;     ET0=1;   }   /******************************************/ u8 key=0xff;//消抖后的有效按键值 u8 key_down=0x00;//按键下降沿扫描结果,1有效 u8 key_up=0x00;     //上升沿扫描结果,1有效 u8 key_sc=0xff;//上次扫描的按键值 //检测端下降沿检测    sbit k1=P2^4; sbit k2=P2^5; sbit k3=P2^6; sbit k4=P2^7; //按键扫描程序 void scanKey(){     static u8 temp0;     static u8 ms;     u8 temp=0;     if(k1==1)temp|=0x01;     if(k2==1)temp|=0x02;     if(k3==1)temp|=0x04;     if(k4==1)temp|=0x08;     if(temp==temp0){// 按键消抖         if(++ms>=5){//连续5次扫描的值一样,则认为是稳定状态             key=temp;             ms=0;           }     }else {         temp0=temp;         ms=0;     }     key_down=key_sc&(~key);//下降沿扫描     key_up=(~key_sc)&key;//下降沿扫描     key_sc=key; }   u8 readPIN(u8 port,u8 pin){     code u8 tab[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,};      return ((port&tab[pin])==0?0:1); }   /***********************************/ //预置状态 u16 anjs=0;//长按计数标志 void yzzt(){     ds[0]=count/1000%10;//设置值送入显示缓存     ds[1]=count/100%10;     ds[2]=count/10%10;     ds[3]=count%10;     if(readPIN(key,0)==0){//k1按下         if(readPIN(key_down,0)==1){//下降沿,即刚按下             if(++count>9999)count=0;//加1             anjs=2000;//倒计时2s         }         if(anjs==0){//倒计时到             anjs=200;//倒计时0.2s             if(++count>9999)count=0;//加1         }     }       //减1     if(readPIN(key,1)==0){         if(readPIN(key_down,1)==1){             if(--count>9999)count=9999;             anjs=2000;         }         if(anjs==0){             anjs=200;             if(--count>9999)count=9999;         }     }       if(readPIN(key_down,2)==1){//计入计数         zt=2;     } }   //计数状态 void jszt(){     if((countTemp==count)&&(jsflag<=500)){//闪烁        ds[0]=10;         ds[1]=10;         ds[2]=10;         ds[3]=10;     }else {//正常显示           ds[0]=countTemp/1000%10;         ds[1]=countTemp/100%10;         ds[2]=countTemp/10%10;         ds[3]=countTemp%10;     }     fmq=(countTemp==count?1:0);//蜂鸣器       if(readPIN(key_down,2)==1){//计入预置状态         zt=1;     }     if(readPIN(key_down,3)==1){//计数         if(++countTemp>9999)countTemp=0;     } } /*****************************/ void main()//主函数 {     while(1){         if(zt==0){             fmq=0;             init();//系统初始化              TR0=1; //定时器开始计时             zt=1;         }else if(zt==1){             yzzt();         }else if(zt==2){             jszt();         }         scanKey();     }   }     /****************************/ void timer0() interrupt 1//1ms定时器 {        TH0=(65536-1000)/256;//重载初值     TL0=(65536-1000)%256;     dispaly();//显示     if(++jsflag>=1000)jsflag=0;     if(anjs!=0)anjs--;   }
回复

使用道具 举报

ID:34298 发表于 2019-9-2 18:54 | 显示全部楼层
#include<reg51.h>
#include<INTRINS.h>
#define u16 unsigned int
#define u8 unsigned char

u16 count=0;   //计数设定值
u16 countTemp=0;//计数
u8 zt=0;       //状态
sbit fmq=P1^0; //蜂鸣器
u16 jsflag=0;  //闪烁计时用


/*********************************************************/
u8 ds[4]; //数码管显示缓存
//共阴
code u8 w[]={0xf1,0xf2,0xf4,0xf8};    //位码
code u8 d[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};//断码
void dispaly(){//显示函数
    static u8 a;
    if(++a>3)a=0;
    P0=0xFF;
    P2=w[a];
    P0=d[ds[a]];
}


/****************************************/
void init()    //初始化函数
{   TMOD=0x01;
    TH0=(65536-1000)/256;
    TL0=(65536-1000)%256;
    EA=1;
    ET0=1;

}

/******************************************/
u8 key=0xff;//消抖后的有效按键值
u8 key_down=0x00;//按键下降沿扫描结果,1有效
u8 key_up=0x00;     //上升沿扫描结果,1有效
u8 key_sc=0xff;//上次扫描的按键值
//检测端下降沿检测   
sbit k1=P2^4;
sbit k2=P2^5;
sbit k3=P2^6;
sbit k4=P2^7;
//按键扫描程序
void scanKey(){
    static u8 temp0;
    static u8 ms;
    u8 temp=0;
    if(k1==1)temp|=0x01;
    if(k2==1)temp|=0x02;
    if(k3==1)temp|=0x04;
    if(k4==1)temp|=0x08;
    if(temp==temp0){// 按键消抖
        if(++ms>=5){//连续5次扫描的值一样,则认为是稳定状态
            key=temp;
            ms=0;  
        }
    }else {
        temp0=temp;
        ms=0;
    }
    key_down=key_sc&(~key);//下降沿扫描
    key_up=(~key_sc)&key;//下降沿扫描
    key_sc=key;
}

u8 readPIN(u8 port,u8 pin){
    code u8 tab[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,};
     return ((port&tab[pin])==0?0:1);
}

/***********************************/
//预置状态
u16 anjs=0;//长按计数标志
void yzzt(){
    ds[0]=count/1000%10;//设置值送入显示缓存
    ds[1]=count/100%10;
    ds[2]=count/10%10;
    ds[3]=count%10;
    if(readPIN(key,0)==0){//k1按下
        if(readPIN(key_down,0)==1){//下降沿,即刚按下
            if(++count>9999)count=0;//加1
            anjs=2000;//倒计时2s
        }
        if(anjs==0){//倒计时到
            anjs=200;//倒计时0.2s
            if(++count>9999)count=0;//加1
        }
    }

    //减1
    if(readPIN(key,1)==0){
        if(readPIN(key_down,1)==1){
            if(--count>9999)count=9999;
            anjs=2000;
        }
        if(anjs==0){
            anjs=200;
            if(--count>9999)count=9999;
        }
    }

    if(readPIN(key_down,2)==1){//计入计数
        zt=2;
    }
}

//计数状态
void jszt(){
    if((countTemp==count)&&(jsflag<=500)){//闪烁
       ds[0]=10;
        ds[1]=10;
        ds[2]=10;
        ds[3]=10;
    }else {//正常显示
          ds[0]=countTemp/1000%10;
        ds[1]=countTemp/100%10;
        ds[2]=countTemp/10%10;
        ds[3]=countTemp%10;
    }
    fmq=(countTemp==count?1:0);//蜂鸣器

    if(readPIN(key_down,2)==1){//计入预置状态
        zt=1;
    }
    if(readPIN(key_down,3)==1){//计数
        if(++countTemp>9999)countTemp=0;
    }
}
/*****************************/
void main()//主函数
{
    while(1){
        if(zt==0){
            fmq=0;
            init();//系统初始化
            TR0=1; //定时器开始计时
            zt=1;
        }else if(zt==1){
            yzzt();
        }else if(zt==2){
            jszt();
        }
        scanKey();
    }

}


/****************************/
void timer0() interrupt 1//1ms定时器
{   
    TH0=(65536-1000)/256;//重载初值
    TL0=(65536-1000)%256;
    dispaly();//显示
    if(++jsflag>=1000)jsflag=0;
    if(anjs!=0)anjs--;

}
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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