【求助】学习单片机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:39 编辑
iffi123 发表于 2020-12-29 00:02
软件去抖动,就是先读取输入,延时约10ms左右(可长可短),再读取一次,比较一下,如果相同算有效
实际上 ...
硬件消抖不好。不是说不可靠,而是浪费钱。电阻电容也是要钱的。而且占板子空间。
软件消抖实际上也是很靠谱的。
但是延时再检测一遍这种方法不好。如果单片机需要执行大量计算,其他函数都在等着按键延时。
因此可以这么写:这样的话,除非按键按下超过设定值,否则就去执行别的程序。如果按键按下的时间达到了才执行触发。
避免别的程序一直在等待按键延时。
定义变量消抖自加;
定义变量触发;
定义变量自锁;
按键函数(void)
{
如果按键没有按下 //平时如果按键没按下,他只会执行蓝色部分。不费多少时间
{
清空自锁;
清空自加;
}
else if按键处于非自锁状态 //只有在蓝色部分条件不成立的时候才执行。如果消抖计数没达到设定值是不会执行紫色部分,因此也不费多少时间。只有达到了设定值,才触发按键,接着按键自锁了,避免一直按着就一直触发,触发完成后,要清空触发值,不然一直按着还是会一直触发。
{
消抖延时自加;//如果没有累加到设定值就跳出去执行别的程序。
如果消抖延时累加到设定值
{
清空消抖自加;
按键自锁;//如果按键按过之后,还一直按着,接下来再进入按键函数,就只是判断如果按键没有按下这个条件,结果发现不成立,然后再判断,如果按键处于没有自锁状态这个条件,发现也不成立,就跳出去了,这个函数就执行了两条判断句,同样没浪费多少时间。
按键触发;
}
}
}
头文件里面定义了相同的名称。你可以看一下两个头文件,如果值相同,就删除一个,如果值不同,就改一下名称。
按钮抖动建议百度。 本帖最后由 iffi123 于 2020-12-29 00:10 编辑
软件去抖动,就是先读取输入,延时约10ms左右(可长可短),再读取一次,比较一下,如果相同算有效
实际上多加一个电阻和电容,就能实现硬件去抖动,既可靠又省事(中断的话更明显),我现在都不用软件处理:lol
示波器捕捉到的按下的抖动,大概出现在2-3ms之内
只包含一个头文件就行了;安全起见,包含STC那个吧;
按键的软件消抖,可以先判读一下开关状态,然后延时几十毫秒,越过开关接触不好那段时间,(也可以再判断一次键值);再走下一步; 那个REG51的头文件只有一些通用的寄存器,
比如IO,定时器之类的.
各个厂家在这个基础上增加了一些外设,形成自己的产品.
厂家的头文件包含了REG51和自己外设的sfr,
所以用厂家的头文件就可以了.
你的按键问题,不只是消抖,还有松手检测.
你的程序就是按下后,LED会在亮-->灭-->亮一直循环,
松手后,LED是亮是灭取决于你松手时执行到的是亮还是灭. 本帖最后由 iffi123 于 2020-12-29 11:15 编辑
isoimg2130 发表于 2020-12-29 08:22
硬件消抖不好。不是说不可靠,而是浪费钱。电阻电容也是要钱的。而且占板子空间。
软件消抖实际上也是 ...
你误会了,我说的延时,肯定是检测到按键之后才延时啊,没按键延时干吗啊;P ,没写那么清楚而已
当然延时不使用软件延时,改用定时器中断,可避免连续占用时间,这个我也试过
但比较之后
还是硬件去抖动爽,按下和松开都能解决抖动问题,如果使用中断检测按键更不要说了,试过就知道它的好:lol
1个贴片电阻和电容值几个钱?占什么位置? ;P
按下和松开的波形, RC时间常数可根据需要调整
补充内容 (2020-12-29 13:52):
写错了,是循环延时 感谢楼上各位!
头文件的问题已经明白了,消抖动的问题,硬件方法我是知道的,我是想学习软件方法处理抖动,刚开始学习编程,很多方法和技巧还在摸索。 isoimg2130 发表于 2020-12-29 08:22
硬件消抖不好。不是说不可靠,而是浪费钱。电阻电容也是要钱的。而且占板子空间。
软件消抖实际上也是 ...
我正是考虑到硬件消抖动需要增加元器件,虽说电容器很便宜,但关键的是占用PCB位置,有时候PCB的空间很紧张,用软件处理抖动就比较有优势:省空间省钱。
您写的部分我还需要时间理解,具体代码也还不知道怎么写,不过您的思路给我帮助很大。感谢! iffi123 发表于 2020-12-29 11:05
你误会了,我说的延时,肯定是检测到按键之后才延时啊,没按键延时干吗啊 ,没写那么清楚而已
当 ...
0.1uF电容估计就能硬件消抖,软硬方法我都想尝试一下,谢谢! 本帖最后由 iffi123 于 2020-12-29 13:57 编辑
Fireflying 发表于 2020-12-29 12:55
我正是考虑到硬件消抖动需要增加元器件,虽说电容器很便宜,但关键的是占用PCB位置,有时候PCB的空间很紧 ...
突然对一个电阻电容较起真来,你设计多密的电路板,连2个元件都放不下,呵呵 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:04 编辑
Fireflying 发表于 2020-12-29 12:55
我正是考虑到硬件消抖动需要增加元器件,虽说电容器很便宜,但关键的是占用PCB位置,有时候PCB的空间很紧 ...
有强迫症,楼上注释看着不整齐。看图。。。
Fireflying 发表于 2020-12-29 12:55
我正是考虑到硬件消抖动需要增加元器件,虽说电容器很便宜,但关键的是占用PCB位置,有时候PCB的空间很紧 ...
附上源程序和仿真文件。不同场合不同应用,放在定时器定时检测的话,这个程序才合适。现在只是演示。
页:
[1]
2