Fireflying 发表于 2020-12-28 23:37:43

【求助】学习单片机C语言编程,头文件的困惑,以及消除按键抖动

在学习单片机C语言编程,用的STC12C4052AD,实验是通过一个按键来控制LED的亮灭,初始化的时候LED熄灭,然后按一下点亮,再按一下熄灭。
源程序如下图:

我发现,如果框出来的位置,两行的头文件都有效的话,编译就报错:
D:\Keil_v5\C51\Inc\STC\STC12C2052AD.H(249): error C231: 'PX1': redefinition
D:\Keil_v5\C51\Inc\STC\STC12C2052AD.H(250): error C231: 'PT0': redefinition
D:\Keil_v5\C51\Inc\STC\STC12C2052AD.H(251): error C231: 'PX0': redefinition
但是用双斜线“//"注释掉任意一个头文件的行,程序都能正常工作,莫非头文件还不能重复?我怎么才能知道怎样的头文件可能会有冲突?


另外编译成功并且下载到单片机之后,虽然实现了功能,但是发现按键非常灵敏,按的时候稍稍抖动一下就跳到另一个状态。通过编程方法怎样消除按键抖动?

isoimg2130 发表于 2020-12-29 08:22:01

本帖最后由 isoimg2130 于 2020-12-29 08:39 编辑

iffi123 发表于 2020-12-29 00:02
软件去抖动,就是先读取输入,延时约10ms左右(可长可短),再读取一次,比较一下,如果相同算有效

实际上 ...

硬件消抖不好。不是说不可靠,而是浪费钱。电阻电容也是要钱的。而且占板子空间。
软件消抖实际上也是很靠谱的。
但是延时再检测一遍这种方法不好。如果单片机需要执行大量计算,其他函数都在等着按键延时。

因此可以这么写:这样的话,除非按键按下超过设定值,否则就去执行别的程序。如果按键按下的时间达到了才执行触发。
避免别的程序一直在等待按键延时。

定义变量消抖自加;
定义变量触发;
定义变量自锁;

按键函数(void)
{
如果按键没有按下   //平时如果按键没按下,他只会执行蓝色部分。不费多少时间
{
    清空自锁;
    清空自加;
}
else if按键处于非自锁状态 //只有在蓝色部分条件不成立的时候才执行。如果消抖计数没达到设定值是不会执行紫色部分,因此也不费多少时间。只有达到了设定值,才触发按键,接着按键自锁了,避免一直按着就一直触发,触发完成后,要清空触发值,不然一直按着还是会一直触发。
{
      消抖延时自加;//如果没有累加到设定值就跳出去执行别的程序。
      如果消抖延时累加到设定值
      {
      清空消抖自加;
      按键自锁;//如果按键按过之后,还一直按着,接下来再进入按键函数,就只是判断如果按键没有按下这个条件,结果发现不成立,然后再判断,如果按键处于没有自锁状态这个条件,发现也不成立,就跳出去了,这个函数就执行了两条判断句,同样没浪费多少时间。
      按键触发;
      }
}
}

bigluo 发表于 2020-12-28 23:49:02

头文件里面定义了相同的名称。你可以看一下两个头文件,如果值相同,就删除一个,如果值不同,就改一下名称。
按钮抖动建议百度。

iffi123 发表于 2020-12-29 00:02:21

本帖最后由 iffi123 于 2020-12-29 00:10 编辑

软件去抖动,就是先读取输入,延时约10ms左右(可长可短),再读取一次,比较一下,如果相同算有效

实际上多加一个电阻和电容,就能实现硬件去抖动,既可靠又省事(中断的话更明显),我现在都不用软件处理:lol

示波器捕捉到的按下的抖动,大概出现在2-3ms之内



壹法拉 发表于 2020-12-29 04:24:43

只包含一个头文件就行了;安全起见,包含STC那个吧;
按键的软件消抖,可以先判读一下开关状态,然后延时几十毫秒,越过开关接触不好那段时间,(也可以再判断一次键值);再走下一步;

diy1997 发表于 2020-12-29 09:55:37

那个REG51的头文件只有一些通用的寄存器,

比如IO,定时器之类的.

各个厂家在这个基础上增加了一些外设,形成自己的产品.

厂家的头文件包含了REG51和自己外设的sfr,

所以用厂家的头文件就可以了.

diy1997 发表于 2020-12-29 10:04:18

你的按键问题,不只是消抖,还有松手检测.

你的程序就是按下后,LED会在亮-->灭-->亮一直循环,

松手后,LED是亮是灭取决于你松手时执行到的是亮还是灭.

iffi123 发表于 2020-12-29 11:05:22

本帖最后由 iffi123 于 2020-12-29 11:15 编辑

isoimg2130 发表于 2020-12-29 08:22
硬件消抖不好。不是说不可靠,而是浪费钱。电阻电容也是要钱的。而且占板子空间。
软件消抖实际上也是 ...

你误会了,我说的延时,肯定是检测到按键之后才延时啊,没按键延时干吗啊;P ,没写那么清楚而已

当然延时不使用软件延时,改用定时器中断,可避免连续占用时间,这个我也试过


但比较之后

还是硬件去抖动爽,按下和松开都能解决抖动问题,如果使用中断检测按键更不要说了,试过就知道它的好:lol

1个贴片电阻和电容值几个钱?占什么位置? ;P

按下和松开的波形, RC时间常数可根据需要调整




补充内容 (2020-12-29 13:52):
写错了,是循环延时

Fireflying 发表于 2020-12-29 12:51:02

感谢楼上各位!
头文件的问题已经明白了,消抖动的问题,硬件方法我是知道的,我是想学习软件方法处理抖动,刚开始学习编程,很多方法和技巧还在摸索。

Fireflying 发表于 2020-12-29 12:55:40

isoimg2130 发表于 2020-12-29 08:22
硬件消抖不好。不是说不可靠,而是浪费钱。电阻电容也是要钱的。而且占板子空间。
软件消抖实际上也是 ...

我正是考虑到硬件消抖动需要增加元器件,虽说电容器很便宜,但关键的是占用PCB位置,有时候PCB的空间很紧张,用软件处理抖动就比较有优势:省空间省钱。
您写的部分我还需要时间理解,具体代码也还不知道怎么写,不过您的思路给我帮助很大。感谢!

Fireflying 发表于 2020-12-29 12:56:58

iffi123 发表于 2020-12-29 11:05
你误会了,我说的延时,肯定是检测到按键之后才延时啊,没按键延时干吗啊 ,没写那么清楚而已

当 ...

0.1uF电容估计就能硬件消抖,软硬方法我都想尝试一下,谢谢!

iffi123 发表于 2020-12-29 13:54:13

本帖最后由 iffi123 于 2020-12-29 13:57 编辑

Fireflying 发表于 2020-12-29 12:55
我正是考虑到硬件消抖动需要增加元器件,虽说电容器很便宜,但关键的是占用PCB位置,有时候PCB的空间很紧 ...

突然对一个电阻电容较起真来,你设计多密的电路板,连2个元件都放不下,呵呵

isoimg2130 发表于 2020-12-29 13:58:01

Fireflying 发表于 2020-12-29 12:55
我正是考虑到硬件消抖动需要增加元器件,虽说电容器很便宜,但关键的是占用PCB位置,有时候PCB的空间很紧 ...

这还用理解?汉字都写的那么明白了。把汉字改成字母就完事了啊。。#include "reg52.h"

sbit p10=P1^0;
sbit led=P1^7;

#define shedingzhi 1000                        //设定值

unsigned int zijia;                                //定义变量消抖自加;
unsigned char chufa;                           //定义变量触发;
char zisuo;                                                  //定义变量自锁;

void anjian(void)
{
        if(p10)                                               //如果按键没有按下
        {                                                           //平时如果按键没按下,他只会清零下两个变量。不费多少时间
                zijia=0;                                //清空自加;
                zisuo=0;                                //清空自锁;
        }
        else if(zisuo==0)                       //按键处于非自锁状态
        {                                                        //这条只会在判断P10不等于1的时候执行
                zijia++;                                  //如果没有累加到设定值就跳出去执行别的程序。
                if(zijia>shedingzhi)           //如果消抖延时累加到设定值
                {
                  zijia=0;                                   //清空消抖自加;
                  zisuo=1;                                  //按键自锁,如果按键没放开此时P10=0不成立,自锁也不等于0也不成立
                                                                  //进入这个函数就判断了两次,不费多长时间。
                  chufa=1;                                  //按键触发;
                }       
        }
}

void main(void)
{
        while(1)
        {
                anjian();
                if(chufa)
                {
                        chufa=0;
                        led=~led;
                }
        }
}



你刷进你的单片机试试。如果觉得按键反应太快就把设定值改改就好,太慢改小,太快改大。

isoimg2130 发表于 2020-12-29 14:02:49

本帖最后由 isoimg2130 于 2020-12-29 14:04 编辑

Fireflying 发表于 2020-12-29 12:55
我正是考虑到硬件消抖动需要增加元器件,虽说电容器很便宜,但关键的是占用PCB位置,有时候PCB的空间很紧 ...

有强迫症,楼上注释看着不整齐。看图。。。

isoimg2130 发表于 2020-12-29 14:06:21

Fireflying 发表于 2020-12-29 12:55
我正是考虑到硬件消抖动需要增加元器件,虽说电容器很便宜,但关键的是占用PCB位置,有时候PCB的空间很紧 ...

附上源程序和仿真文件。不同场合不同应用,放在定时器定时检测的话,这个程序才合适。现在只是演示。
页: [1] 2
查看完整版本: 【求助】学习单片机C语言编程,头文件的困惑,以及消除按键抖动