Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Button 按钮去抖动pic16f877a代码不工作_Button_Pic_Mplab_Debouncing - Fatal编程技术网

Button 按钮去抖动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

在pic16f877a中,我试图用一个按钮生成一个用于软件去抖动的代码,但每当我单击该按钮时,它就会打开,并且不再关闭。下面是代码:

                #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我也制作了一个新代码,但它有一些问题,我会编辑,这不是一个很好的去抖动,是吗?我认为,对于去抖动,延迟应该只在键的状态发生变化之后才适用,并且应该在两个方向上都适用。因为,当按下按钮时,探测器可能在两种状态之间摆动,直到按钮完全按下,同样,当按钮释放时,探测器也会摆动,直到按钮完全打开。因此,去抖动的本质是忽略抖动,这意味着在看到状态改变后的短时间内忽略按钮的状态。