按钮debouncing pic16f877a代码无法正常工作

时间:2014-08-15 10:12:30

标签: button pic mplab debouncing

在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;

        }

和btw我忘了提到config.h是我用来配置位和晶体频率的头文件(_XTAL_FREQUENCY)

2 个答案:

答案 0 :(得分:0)

我在这里看到两件事情错了。首先,您只在RC0为高电平时更改输出状态。因此,当RC0变低时,您的输出将保持其先前的状态,无论它可能是什么。例如,如果您希望在输入关闭时输出变低:

while(1){
    if(PORTCbits.RC0 == 1){
        if(ledToggle()%2 == 0){
            PORTDbits.RD0 = 1;
        }else{
            PORTDbits.RD0 = 0;
        }
    }
    else
        PORTDbits.RD0 = 0;
}

我在这里看到的第二件事与rmi的评论有关。你提到你试图取消一个按钮,但没有延迟或其他逻辑,这段代码不会这样做。如果您的图片没有其他许多工作要做,一个简单的解决方案可能是:

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的组合,这是演示!

http://i.imgur.com/gTDHavI.png

这是一张非常简单且实际上很糟糕的照片我画了画给大家展示。所以你需要做的就是在按下按钮的情况下跳过第一部分或零和零部分(1010101010)并按你这样做:

1.declare一个名为ButtonPress_Level的变量

2.在while循环中创建另一个while循环,只要按下按钮就不断向此变量添加1s

3.浏览0和1所在的第一部分,然后在前500个信号之后开启或关闭

这可能看起来不太明白,但是当你看到整个代码::

时,你会得到它
                #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是一个头文件,只需设置配置位,所以不要担心它对你来说不重要

所以在这段代码中,debounce只是作为一个计数器工作,如果是偶数则关闭引脚,如果是偶数则关闭