矿石收音机论坛

 找回密码
 加入会员

QQ登录

只需一步,快速开始

搜索
查看: 3474|回复: 23

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

[复制链接]
     
发表于 2020-12-28 23:37:43 | 显示全部楼层 |阅读模式
在学习单片机C语言编程,用的STC12C4052AD,实验是通过一个按键来控制LED的亮灭,初始化的时候LED熄灭,然后按一下点亮,再按一下熄灭。
源程序如下图:
头文件的困惑.png
我发现,如果框出来的位置,两行的头文件都有效的话,编译就报错:
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
但是用双斜线“//"注释掉任意一个头文件的行,程序都能正常工作,莫非头文件还不能重复?我怎么才能知道怎样的头文件可能会有冲突?


另外编译成功并且下载到单片机之后,虽然实现了功能,但是发现按键非常灵敏,按的时候稍稍抖动一下就跳到另一个状态。通过编程方法怎样消除按键抖动?
     
发表于 2020-12-29 08:22:01 | 显示全部楼层
本帖最后由 isoimg2130 于 2020-12-29 08:39 编辑
iffi123 发表于 2020-12-29 00:02
软件去抖动,就是先读取输入,延时约10ms左右(可长可短),再读取一次,比较一下,如果相同算有效

实际上 ...


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

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

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

按键函数(void)
{
  如果按键没有按下   //平时如果按键没按下,他只会执行蓝色部分。不费多少时间
  {
    清空自锁;
    清空自加;
  }

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

      }
  }

}

评分

2

查看全部评分

回复 支持 1 反对 0

使用道具 举报

     
发表于 2020-12-28 23:49:02 | 显示全部楼层
头文件里面定义了相同的名称。你可以看一下两个头文件,如果值相同,就删除一个,如果值不同,就改一下名称。
按钮抖动建议百度。

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2020-12-29 00:02:21 | 显示全部楼层
本帖最后由 iffi123 于 2020-12-29 00:10 编辑

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

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

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


评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2020-12-29 04:24:43 | 显示全部楼层
只包含一个头文件就行了;安全起见,包含STC那个吧;
按键的软件消抖,可以先判读一下开关状态,然后延时几十毫秒,越过开关接触不好那段时间,(也可以再判断一次键值);再走下一步;

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2020-12-29 09:55:37 | 显示全部楼层
那个REG51的头文件只有一些通用的寄存器,

比如IO,定时器之类的.

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

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

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

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2020-12-29 10:04:18 | 显示全部楼层
你的按键问题,不只是消抖,还有松手检测.

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

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

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
发表于 2020-12-29 11:05:22 | 显示全部楼层
本帖最后由 iffi123 于 2020-12-29 11:15 编辑
isoimg2130 发表于 2020-12-29 08:22
硬件消抖不好。不是说不可靠,而是浪费钱。电阻电容也是要钱的。而且占板子空间。
软件消抖实际上也是 ...


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

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


但比较之后

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

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

按下和松开的波形, RC时间常数可根据需要调整
输出加RC-1.png

输出加RC-2.png

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

评分

1

查看全部评分

回复 支持 反对

使用道具 举报

     
 楼主| 发表于 2020-12-29 12:51:02 | 显示全部楼层
感谢楼上各位!
头文件的问题已经明白了,消抖动的问题,硬件方法我是知道的,我是想学习软件方法处理抖动,刚开始学习编程,很多方法和技巧还在摸索。
回复 支持 反对

使用道具 举报

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

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

使用道具 举报

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

当 ...

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

使用道具 举报

     
发表于 2020-12-29 13:54:13 | 显示全部楼层
本帖最后由 iffi123 于 2020-12-29 13:57 编辑
Fireflying 发表于 2020-12-29 12:55
我正是考虑到硬件消抖动需要增加元器件,虽说电容器很便宜,但关键的是占用PCB位置,有时候PCB的空间很紧 ...


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

使用道具 举报

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


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

  2. sbit p10=P1^0;
  3. sbit led=P1^7;

  4. #define shedingzhi 1000                        //设定值

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

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

  27. void main(void)
  28. {
  29.         while(1)
  30.         {
  31.                 anjian();
  32.                 if(chufa)
  33.                 {
  34.                         chufa=0;
  35.                         led=~led;
  36.                 }
  37.         }
  38. }


复制代码

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

使用道具 举报

     
发表于 2020-12-29 14:02:49 | 显示全部楼层
本帖最后由 isoimg2130 于 2020-12-29 14:04 编辑
Fireflying 发表于 2020-12-29 12:55
我正是考虑到硬件消抖动需要增加元器件,虽说电容器很便宜,但关键的是占用PCB位置,有时候PCB的空间很紧 ...


有强迫症,楼上注释看着不整齐。看图。。。
QQ截图20201229140026.png
回复 支持 反对

使用道具 举报

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

  附上源程序和仿真文件。不同场合不同应用,放在定时器定时检测的话,这个程序才合适。现在只是演示。
QQ截图20201229140101.png

C51按键消抖.rar

29.04 KB, 下载次数: 36

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 加入会员

本版积分规则

小黑屋|手机版|矿石收音机 ( 蒙ICP备05000029号-1 )

蒙公网安备 15040402000005号

GMT+8, 2024-5-7 13:52

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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