51_按键_计数器

51计数器,下降沿

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
/**********************51单片机学习例程************************
*  平台:Keil U4 + STC89C52
*  名称:使用计数器0,每次按键触发,计数加一,数码管显示
*  编写:Tony
*  日期:2022-2-10
*   QQ : 674749794
*  晶体:12MHZ
*    变更记录:无
******************************************************************/
 
#include <reg52.h>
#define GPIO_DIG P1      //数码管使用的段选IO
sbit K1=P3^6;            //按键检测,测试用
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;            //138译码器,数码管的位选
 
#define     GE      {LSA=1;LSB=1;LSC=1;}                //打开个位位选端
#define     SHI     {LSA=0;LSB=1;LSC=1;}                //打开十位位选端
#define     uchar   unsigned char
uchar Key_Num;
uchar code DIG_CODE[] = {
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
uchar num_ge,num_shi;       //分别定义个位和十位的数组编号存储器
void timer0_init(void);     //函数声明
void read_num(void);
void seg_display(unsigned char x,unsigned char y);
void Delay10ms();
void Read_Key();
/***************************************************
*                               计数器0初始化子函数
*                   计数模式,工作方式1,启动计数
****************************************************/
void timer0_init(void)
{
    TMOD = 0x05;        //计数模式,工作方式1    计数模式是计下降沿的个数,所以计数的按键必须有上拉电阻
    TH0 = 0x00;        
    TL0 = 0x00;         //计数单元从0开始
    TR0 = 1;            //启动计数器0
}
/***************************************************
*                                   取数子函数
*               读取TH0、TL0里面的值,确定个位和十位的数
****************************************************/
void read_num(void)
{
    unsigned int count;         //用来存储收到的负脉冲个数
    count = TH0*256 + TL0;      //计算负脉冲个数
    if(count >99)                //如果脉冲个数超过99
    {
        TH0 = 0x00;             //从0重新开始
        TL0 = 0x00;
        count = 0;
    }
 
    num_ge = count%10;          //计算个位数在数组中的编号
    num_shi = count/10%10;      //计算十位数在数组中的编号
}
void Read_Key()
{
    uchar i;
    if (K1==0)
    {
       Delay10ms();
       if(K1==0)
       {
         Key_Num++;
         if(Key_Num > 19)
         {
            Key_Num=0;
         }
         while((i<50)&&(K1==0))
         {
           Delay10ms();
           i++;
         }
         i=0;
       }   
    }
    num_ge = Key_Num%10;            //计算个位数在数组中的编号
    num_shi = Key_Num/10%10;   
}
/***************************************************
*                               数码显示子函数
*               根据个位和十位的数字进行显示
****************************************************/
void seg_display(unsigned char x,unsigned char y)
{
    unsigned int i;                 //延时用
    GE;                             //打开个位位选
    GPIO_DIG = DIG_CODE[y];
    //GPIO_DIG = DIG_CODE[9];               //显示个位段选
    for(i = 0;i<1000;i++);           //延时一段时间
    SHI;                            //打开十位位选
    GPIO_DIG = DIG_CODE[x];
    //GPIO_DIG = DIG_CODE[5];                   //显示十位段选
    for(i = 0;i<1000;i++);           //延时一段时间
}
 
//主函数
void main(void)
{
    GPIO_DIG = 0x00;                        //关闭数码管
    timer0_init();                  //定时器/计数器0初始化
    while(1)                        //循环
    {
        
        read_num();                 //读取个位和十位对应的数字
        //Read_Key();
        seg_display(num_shi,num_ge);//显示相应的数字
    }
}
 
void Delay10ms(void)   //误差 0us
{
    unsigned char a,b,c;
    for(c=1;c>0;c--)
        for(b=38;b>0;b--)
            for(a=130;a>0;a--);
}

  

posted @   xiaoberber  阅读(273)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 提示词工程——AI应用必不可少的技术
· 字符编码:从基础到乱码解决
· 地球OL攻略 —— 某应届生求职总结
点击右上角即可分享
微信分享提示