У вас, кажется, есть гр asp больших идей, но, возможно, пропустили несколько деталей.
/*
* 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
}
}
Я не вижу четкого способа "исправить" код, который вы опубликовали.
В этом коде используются концепции, еще не охваченные вашими учебными материалами.
Если вы отправите это в качестве выполненного задания, ваш инструктор узнает, что вы получили его из inte rnet.