如何使用计时器计算按钮的总按下时间

问题描述 投票:0回答:2

我是Pic Controller的新手。我正在使用图片16F887。我想计算按钮按下的总时间。那段时间我想用作延迟眨眼指示灯。而且我可以更改按钮按下时间,以通过替换LED闪烁的先前延迟来更改延迟。我该如何通过更正下面的代码

#include <htc.h>
#define _XTAL_FREQ 8000000
#define SWITCH RB0
#define LED RD2



long int total_count = 0,count = 0,count1 = 0;
char flag =0,flag1 =0;
char i=0,k=0;



void Init_Timer1() // Timer Initialization at 0.6ms
{
    TMR1ON   = 0x01;
    TMR1IF   = 0;
    TMR1H    = 0xFB;
    TMR1L    = 0x4F;
    TMR1IE   = 1;
    INTCON  |= 0xC0;
}
void Extern()
{

    INTCON |= 0XD0;
    INTEDG = 1; // Rising Edge Detect
}

void interrupt ISR(void)
{       
   if(INTF)//External Interrupt Flag
   {
       INTF=0;
       TMR1IF = 0;
       TMR1H  = 0xFB;
       TMR1L  = 0x4F;
       TMR1ON = 0x01;  
       count++;
    }

       if(TMR1IF) // Timer1 Interrupt flag 
   {
       TMR1IF = 0;
       TMR1H  = 0xFB;
       TMR1L  = 0x4F;
       TMR1ON = 0x01;
   }  
}

void main()
{    
   Extern();
   Init_Timer1();
   TRISD2 = 0;
   TRISB0 = 1;
   LED=0;

    while(1)
    { 
    if(RB0 == 0 && flag==0)
    {
      flag=1;
    } 
    if(RB0 == 1 && flag==1)
    {

         LED=1;
         for(i=0;i<count;i++);
         LED=0;
         flag1=0;

    }

    }    
}
timer pic
2个回答
1
投票

您似乎掌握了一些大创意,但是可能错过了一些细节。

/*
 * File:   main.c
 * Author: dan1138
 * Target: PIC16F887
 * Compiler: XC8 v1.45
 * IDE: MPLABX v5.25
 *
 * Created on March 23, 2020, 4:22 PM
 */

// CONFIG1
#pragma config FOSC = INTRC_NOCLKOUT    // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF               // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF              // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON               // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#pragma config CP = OFF                 // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF                // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF              // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO = OFF               // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF              // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config LVP = OFF                // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)

// CONFIG2
#pragma config BOR4V = BOR40V           // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF                // Flash Program Memory Self Write Enable bits (Write protection off)

#include <xc.h>

#define _XTAL_FREQ 8000000ul
#define SWITCH          RB0
#define SWITCH_DIR      TRISB0
#define SWITCH_PRESSED  (0)
#define LED             RD2
#define LED_DIR         TRISD2
#define LED_OFF         (0)
#define LED_ON          (1)
#define GPIO_IN         (1)
#define GPIO_OUT        (0)

volatile unsigned long  ButtonPressedTicks;
volatile unsigned char  ButtonPressedState;
volatile unsigned char  T2_Ticks;
volatile unsigned long  TicksForLedToBlink;


void Init_TIMER2(void) // Initialize TIMER2 to assert an interrupt every 20 milliseconds
{
    TMR2IE = 0;                 // Disable TIMER2 interrupts
    T2CON  = 0;                 // Stop TIMER2
    T2CONbits.T2CKPS = 0b10;    // Set TIMER2 prescale for 1:16
    T2CONbits.TOUTPS = 0b0100;  // Set TIMER2 postscale for 1:10
    PR2 = (_XTAL_FREQ/(4ul*16ul*10ul*50ul))-1ul;
    TMR2IF = 0;                 // Clear pending interrupt requests
    TMR2IE = 1;                 // Enable TIMER2 interrupts
    PEIE   = 1;                 // Enable peripheral interrupts
    T2CONbits.TMR2ON = 1;       // Turn on TIMER2
}

void Init_INT(void)
{
    INTE = 0;                   // Disable external interrupts
    INTEDG = 0;                 // Falling Edge Detect
    INTF = 0;                   // Clear pending interrupt requests
}

void interrupt ISR(void)
{
    // Handle external interrupt assert
    if (INTE)
    {
        if (INTF)
        {
            INTF = 0;
            INTE = 0;               // Disable external interrupts
            LED = LED_ON;
            T2CONbits.TMR2ON = 0;   // Turn off TIMER2
            TMR2 = 0;
            TMR2IF = 0;             // Clear pending interrupt requests
            T2CONbits.TMR2ON = 1;   // Turn on TIMER2
            ButtonPressedTicks = 0;
            ButtonPressedState = 1;
        }
    }

    // TIMER2 interrupt assert
    if (TMR2IE)
    {
        if (TMR2IF)
        {
            TMR2IF = 0;
            T2_Ticks++;
            if(ButtonPressedState == 1)
            {
                if (SWITCH == SWITCH_PRESSED)
                {
                    ButtonPressedTicks++;
                }
                else
                {
                    if(ButtonPressedTicks < 2)      // SWITCH press too short, must be a bounce
                    {
                        ButtonPressedTicks = 0;     // Start over
                        LED = LED_OFF;
                        INTF = 0;
                        INTE = 1;                   // Enable external interrupts
                    }
                    else
                    {
                        TicksForLedToBlink = ButtonPressedTicks;
                    }
                    ButtonPressedState = 2;
                }
            }
        }
    }
}

void main(void)
{
    unsigned char T2_TicksStart;
    unsigned char BlinkTicks;
    unsigned long BlinkTime;

    ANSEL = 0;
    ANSELH = 0;

    Init_INT();
    Init_TIMER2();
    LED_DIR    = GPIO_OUT;
    LED        = LED_OFF;
    SWITCH_DIR = GPIO_IN;
    ButtonPressedTicks = 0;
    ButtonPressedState = 0;
    TicksForLedToBlink = 0;
    T2_Ticks = 0;

    GIE = 1;    // Enable the interrupt system

    while (1)
    {
        if((ButtonPressedState == 2) && (TicksForLedToBlink > 0))
        {
            LED = LED_OFF;
            BlinkTime = 0;
            while(BlinkTime < TicksForLedToBlink)
            {
                T2_TicksStart = T2_Ticks;
                BlinkTicks = 0;
                while(BlinkTicks < 1)
                {
                    BlinkTicks = T2_Ticks;
                    BlinkTicks -= T2_TicksStart;
                }
                BlinkTime += BlinkTicks;
            }

            LED = LED_ON;
            BlinkTime = 0;
            while(BlinkTime < TicksForLedToBlink)
            {
                T2_TicksStart = T2_Ticks;
                BlinkTicks = 0;
                while(BlinkTicks < 1)
                {
                    BlinkTicks = T2_Ticks;
                    BlinkTicks -= T2_TicksStart;
                }
                BlinkTime += BlinkTicks;
            }
        }
        if(INTE == 0) INTE = 1;    // Enable external interrupts
    }
}

我看不到“修复”您发布的代码的明确方法。

此代码使用的内容尚未包含在您的指导材料中。

如果您将其作为完成的作业提交,您的老师会知道您是从互联网上获得的。


0
投票

抱歉,我已完全忘记检查此邮件,所以回复晚。我正在使用免费的htc-lite编译器,它与给定的代码兼容吗?在这里,您已将RB0用作开关输入,但是在我的项目中,我需要除RB0之外的三个不同的按钮引脚来测量三个不同的按钮按下时间,一个按钮用于中度的时间短一秒钟,而第三按钮用于长按时间。启用电源后,按选择的按钮类型,LED的导通时间会有所不同。而且,我还可以通过按不同的按钮来更改开机期间的延迟。如何做到这一点并将此按时间存储在给定的控制器中?

© www.soinside.com 2019 - 2024. All rights reserved.