Button 按钮去抖动pic16f877a代码不工作
在pic16f877a中,我试图用一个按钮生成一个用于软件去抖动的代码,但每当我单击该按钮时,它就会打开,并且不再关闭。下面是代码:Button 按钮去抖动pic16f877a代码不工作,button,pic,mplab,debouncing,Button,Pic,Mplab,Debouncing,在pic16f877a中,我试图用一个按钮生成一个用于软件去抖动的代码,但每当我单击该按钮时,它就会打开,并且不再关闭。下面是代码: #include "config.h" unsigned int ledToggle(void); void main(){ TRISCbits.TRISC0 = 1; TRISDbi
#include "config.h"
unsigned int ledToggle(void);
void main(){
TRISCbits.TRISC0 = 1;
TRISDbits.TRISD0 = 0;
PORTDbits.RD0 = 0;
while(1){
if(PORTCbits.RC0 == 1){
if(ledToggle()%2 == 0){
PORTDbits.RD0 = 1;
}else{
PORTDbits.RD0 = 0;
}
}
}
}
unsigned int ledToggle(){
static int i = 2;
i++;
return i;
}
编辑
我还制作了这个新代码,它有一个问题,它有时工作有时不在这里:
#include "config.h"
static char flag = 0;
static int counter = 0;
unsigned int ledToggle(void);
void main(){
TRISCbits.TRISC0 = 1;
TRISDbits.TRISD0 = 0;
PORTDbits.RD0 = 0;
while(1){
if(ledToggle()%2 == 0){
PORTDbits.RD0 = 1;
}else{
PORTDbits.RD0 = 0;
}
}
}
unsigned int ledToggle(){
if(PORTCbits.RC0 == 1 && flag == 0){
counter++;
flag = 1;
}else{
counter += 0;
flag = 0;
}
if(PORTCbits.RC0 == 0){
flag = 0;
}
return counter;
}
顺便说一句,我忘了提到config.h是我用来配置位和晶体频率的头文件,我在这里看到两个错误。首先,您仅在RC0高时更改输出的状态。因此,当RC0变低时,您的输出只是停留在其先前的状态,不管它是什么。例如,如果您希望在输入关闭时输出变低:
while(1){
if(PORTCbits.RC0 == 1){
if(ledToggle()%2 == 0){
PORTDbits.RD0 = 1;
}else{
PORTDbits.RD0 = 0;
}
}
else
PORTDbits.RD0 = 0;
}
我在这里看到的第二个错误与rmi的评论有关。您提到您正在尝试取消按钮反弹,但没有延迟或其他逻辑,此代码不会这样做。如果您的pic没有太多其他事情要做,一个简单的解决方案可以是:
while(1){
if(PORTCbits.RC0 == 1){
PORTDbits.RD0 = 1;//Or use you toggle, or something else
//This will waste more than 65025 cycles (255*255 + loop overhead)
//At 4MHz, thats 16ms minimum
for( char i = 0; i < 0xFF; i++ )
for( char j = 0; j < 0xFF; j++ )
Nop();
}
else
PORTDbits.RD0 = 0;
}
我为我的问题找到了最好、最简单的解决方案: 第二个代码不起作用有时起作用,而另一些则不起作用,因为当我按下按钮时,出现的信号是1和0的组合,这是演示 这是一张非常简单,实际上很糟糕的照片,我用颜料画出来给大家看。因此,你需要做的是跳过第一部分或按钮按下时带有1和0的部分1010101010,你这样做: 1.声明一个名为ButtonPress_Level的变量 2.在while循环中,创建另一个while循环,只要按下按钮,该循环就会不断向该变量添加1s 3.跳过0和1所在的第一部分,并在前500个信号后开启或关闭led 这似乎不可理解,但当您看到整个代码时,您就会明白:
#include "config.h"
static char flag = 0;
static int counter = 0;
static unsigned int Pressed_Level = 0;
unsigned int ledToggle(void);
void main(){
TRISDbits.TRISD0 = 0;
TRISCbits.TRISC0 = 1;
PORTDbits.RD0 = 0;
while(1){
if(ledToggle()%2 == 0){
PORTDbits.RD0 = 1;
}else{
PORTDbits.RD0 = 0;
}
}
}
unsigned int ledToggle(){
if(PORTCbits.RC0 == 1 && flag == 0){
while(PORTCbits.RC0 == 1){
Pressed_Level++;
}
flag = 1;
if(Pressed_Level >= 500){
counter++;
}
}else{
counter += 0;
flag = 0;
Pressed_Level = 0;
}
if(PORTCbits.RC0 == 0){
flag = 0;
}
return counter;
}
同样,config.h是一个头文件,其中只设置了配置位,所以不用担心它对您来说并不重要
因此,在这段代码中,去盎司只是一个计数器,如果是偶数,则将引脚打开;如果是奇数,则将引脚关闭。添加一个延迟,例如,当RC0变高时,将延迟50毫秒。这样可以防止开关反弹。在您的代码中,当按下按钮时,循环旋转得如此之快,切换LED。@rmi我也制作了一个新代码,但它有一些问题,我会编辑,这不是一个很好的去抖动,是吗?我认为,对于去抖动,延迟应该只在键的状态发生变化之后才适用,并且应该在两个方向上都适用。因为,当按下按钮时,探测器可能在两种状态之间摆动,直到按钮完全按下,同样,当按钮释放时,探测器也会摆动,直到按钮完全打开。因此,去抖动的本质是忽略抖动,这意味着在看到状态改变后的短时间内忽略按钮的状态。