0

在 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 是我为配置位和晶体频率(_XTAL_FREQUENCY)而制作的头文件

4

2 回答 2

0

我为我的问题找到了最好和最简单的解决方案:

第二个代码不起作用(有时起作用而其他代码不起作用),因为当我按下按钮时,出现的信号是 1 和 0 的组合,这是演示!

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

这是一张非常简单但实际上很糟糕的照片,我用颜料画给大家看。所以你需要做的是在按钮按下时跳过第一部分或带有一和零的部分(1010101010),你这样做:

1.声明一个名为ButtonPress_Level的变量

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

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

所以在这段代码中,去抖动只是作为一个计数器工作,如果数字是偶数则打开引脚,如果是奇数则关闭

于 2014-08-16T11:16:19.103 回答
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;
}
于 2014-08-15T13:14:01.757 回答