PIC16F883 LED闪烁

3
我需要编程一个PIC16F883来同时闪烁/点亮LED灯。振荡器运行在3.2768,我使用TIMER0来帮助我计时。
现在,我设置了1:256的分频器,所以我每50毫秒就会收到一个中断,并且我有一个变量从中计算出来,以显示已经过去了多少秒。
如果输入发生变化,那么秒数变量当然会再次重置。
这是我的老师布置的任务:
如果输入为0(关闭): 红色和绿色LED灯应该同时点亮15秒钟。之后,绿色LED应完全关闭,红色LED应每5秒闪烁一次,持续10分钟。
如果输入为1(打开): 红色LED应完全关闭,绿色LED应点亮10分钟,之后也应该关闭。
我的计时器运行良好,我已经测试过了。程序也正常运行,并将两个LED灯保持关闭状态15秒钟,然后关闭它们,但我的红色LED没有闪烁。我一整天都坐在桌子前拼命寻找代码中的错误。 打印图像: enter image description here

这是我的C代码。我正在使用MPLab和HI-TECH C编译器 :)

#include <pic.h>

//Variabler
int B = 0;              //Definerer variablen B, used as a flag
int A = 0;              //Definerer veriablen A, used as a flag
int E = 0;
int savedstatus = 1;    //Definere variablen savedstatus used to check last status for input
int millicounter = 0;   //Variabel to calculate seconds
int sec = 0;            //Variabel holding seconds gone
int count = 0;          //For counting seconds passed, used in input0 subroutine
int onesec = 0;         //Used to counting seconds for blinking LED in input0 subroutine
int scount = 0;
//Variabler slut



void interrupt jesper(void)
{
    T0IF = 0x00;
    TMR0 = 96;
    millicounter++;
    if(millicounter == 20)
    {
        sec++;
        millicounter = 0;
    }
}


//Subrutines
void input0()
{
    if(sec<=15 && E==0)
    {
        PORTA = 0x21;
    }
    else if(A==0)
    {
        scount = 0;
        sec = 0;
        count = sec;
        A = 1;
        E = 1;
    }
    else if(sec<=600 && sec>count)
    {
        count++;
        if((scount+5)>=count)
        {
            if(B==0)
            {
                onesec = sec;
                B = 1;
                PORTA = 0x01;
            }
            else if(sec>onesec)
            {
                PORTA = 0x00;
                B = 0;
                scount = count;
                scount;
            }
            else
            {
                PORTA = 0x01;
            }
        }
        else
        {
            PORTA = 0x00;
        }
    }
    else PORTA = 0x00;
}


void input1()
{
    if(sec<=600)
    {
        PORTA = 0x20;
    }
    else
    {
        PORTA = 0x00;
    }
}
//Subrutines over


int main(void)
{
    TRISA = 0x00;           //Sets all A-PORTS to output
    TRISB = 0x01;           //Sets all PORTB to output with the exception of BIT0
    TRISC = 0x00;           //Sets All PORTC to output
    ANSEL = 0x00;           //Disable Analog ports
    ANSELH = 0x00;          //Disable Analog ports

    //Timer Config
    PSA = 0x00; 
    PS0 = 0x01;
    PS1 = 0x01;
    PS2 = 0x01;
    TMR0 = 0x60;
    GIE = 0x01;
    T0IE = 0x01;
    T0IF = 0x00;
    T0CS = 0x00;
    //Timer Config Over

    while(0x01)
    {
        if(savedstatus != RB0)
        {
            savedstatus = RB0;
            sec = 0;
            E = 0;
            A = 0;
        }
        if(savedstatus == 1)
        {
            input1();
        }
        else
        {
            input0();
        }
    }
}

我希望你能在这里帮助我 :)
这是我的子程序input0的流程图,其中出现了问题。顺便说一下,代码中有些变量的名称不同,但应该不难看出来。

enter image description here


我知道你为自己所做的感到自豪,但请不要发布不必要的图片。相反,请发布文本并正确缩进和格式化你的代码! - too honest for this site
曾经见过的最差的代码格式... - LPs
1
如果您在中断中修改了一个变量并使用它,请将其声明为volatile,以避免编译器对其进行优化。 - LPs
各位,请帮帮我,我一个月前开始学习编程,对此非常陌生,需要帮助。如果我的代码格式不正确,请不要只告诉我它错了,而是请告诉我如何正确地格式化它。 - Emil Wismann Kirkebæk-Jensen
1个回答

1
您的main()尽可能经常调用input0()。当input0()处于闪烁状态时,它使用条件语句sec > count。我猜想您的意图是input0()应该只在每秒间隔时改变LED状态。但是,在该条件语句的else部分中,您关闭了两个LED。由于main()经常调用input0(),所以该else部分执行多次。尝试删除关闭LED的else条件语句。
void input0()
{
    <snip>
    else if(sec<=600 && sec>count)
    {
        <snip>
    }
    else PORTA = 0x00;  // <-- delete this line so you're not always turning the LED off
}

现在我又有一个问题:/ 代码在模拟器中运行良好,但是当我将其转移到PIC时,它就无法正常工作。两个LED没有执行它们应该执行的操作。相反,它们随机闪烁 :/ - Emil Wismann Kirkebæk-Jensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接