// PIC16F877A Countdown Timer - Base Template (XC8 - MPLAB X) // Includes: Timer0 for millis, display multiplexing, LED, buzzer, buttons #include <xc.h> #include <stdint.h> // CONFIG #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable bit (enabled) #pragma config BOREN = ON // Brown-out Reset Enable bit (enabled) #pragma config LVP = OFF // Low-Voltage (single-supply) In-Circuit Serial Programming Enable bit #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (disabled) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (disabled) #pragma config CP = OFF // Flash Program Memory Code Protection bit (disabled) #define _XTAL_FREQ 20000000 // 20 MHz crystal // Pin definitions (adjust as needed) #define SEGMENTS_PORT LATD #define SEGMENTS_TRIS TRISD #define DIGIT1 LATCbits.LATC0 #define DIGIT2 LATCbits.LATC1 #define DIGIT3 LATCbits.LATC2 #define LED LATCbits.LATC3 #define BUZZER LATCbits.LATC4 #define BT_START PORTBbits.RB0 #define BT_UP PORTBbits.RB1 #define BT_DOWN PORTBbits.RB2 // Variables volatile unsigned long millis_counter = 0; unsigned int countdown = 120; // default countdown in seconds uint8_t digits[3]; // 7-segment digit patterns (common cathode) const uint8_t numbers[10] = { 0b00111111, // 0 0b00000110, // 1 0b01011011, // 2 0b01001111, // 3 0b01100110, // 4 0b01101101, // 5 0b01111101, // 6 0b00000111, // 7 0b01111111, // 8 0b01101111 // 9 }; // Interrupt for Timer0 (1ms) void __interrupt() isr(void) { if (TMR0IF) { TMR0IF = 0; TMR0 = 6; // preload for 1ms (with 1:256 prescaler) millis_counter++; } } unsigned long millis() { return millis_counter; } void setup_timer0() { OPTION_REG = 0b00000111; // prescaler 1:256, assigned to TMR0 TMR0 = 6; TMR0IE = 1; TMR0IF = 0; PEIE = 1; GIE = 1; } void display_number(uint16_t number) { digits[0] = number / 100; digits[1] = (number / 10) % 10; digits[2] = number % 10; } void update_display() { static uint8_t index = 0; DIGIT1 = 0; DIGIT2 = 0; DIGIT3 = 0; SEGMENTS_PORT = numbers[digits[index]]; if (index == 0) DIGIT1 = 1; else if (index == 1) DIGIT2 = 1; else if (index == 2) DIGIT3 = 1; index = (index + 1) % 3; } void beep(uint8_t times) { for (uint8_t i = 0; i < times; i++) { BUZZER = 1; __delay_ms(100); BUZZER = 0; __delay_ms(100); } } void main(void) { // Setup SEGMENTS_TRIS = 0x00; TRISC = 0x00; TRISB = 0xFF; // Buttons as input PORTB = 0xFF; // Enable pull-ups if needed setup_timer0(); unsigned long prev_time = 0; uint8_t running = 0; while (1) { update_display(); display_number(countdown); if (!BT_START) { __delay_ms(50); if (!BT_START) running = !running; while (!BT_START); } if (!BT_UP && !running && countdown < 999) { __delay_ms(50); if (!BT_UP) countdown++; while (!BT_UP); } if (!BT_DOWN && !running && countdown > 0) { __delay_ms(50); if (!BT_DOWN) countdown--; while (!BT_DOWN); } if (running && millis() - prev_time >= 1000) { prev_time = millis(); if (countdown > 0) countdown--; if (countdown == 0) { running = 0; beep(3); } } __delay_ms(5); // Small delay for multiplexing stability } }
Standard input is empty
// PIC16F877A Countdown Timer - Base Template (XC8 - MPLAB X) // Includes: Timer0 for millis, display multiplexing, LED, buzzer, buttons #include <xc.h> #include <stdint.h> // CONFIG #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = ON // Power-up Timer Enable bit (enabled) #pragma config BOREN = ON // Brown-out Reset Enable bit (enabled) #pragma config LVP = OFF // Low-Voltage (single-supply) In-Circuit Serial Programming Enable bit #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (disabled) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (disabled) #pragma config CP = OFF // Flash Program Memory Code Protection bit (disabled) #define _XTAL_FREQ 20000000 // 20 MHz crystal // Pin definitions (adjust as needed) #define SEGMENTS_PORT LATD #define SEGMENTS_TRIS TRISD #define DIGIT1 LATCbits.LATC0 #define DIGIT2 LATCbits.LATC1 #define DIGIT3 LATCbits.LATC2 #define LED LATCbits.LATC3 #define BUZZER LATCbits.LATC4 #define BT_START PORTBbits.RB0 #define BT_UP PORTBbits.RB1 #define BT_DOWN PORTBbits.RB2 // Variables volatile unsigned long millis_counter = 0; unsigned int countdown = 120; // default countdown in seconds uint8_t digits[3]; // 7-segment digit patterns (common cathode) const uint8_t numbers[10] = { 0b00111111, // 0 0b00000110, // 1 0b01011011, // 2 0b01001111, // 3 0b01100110, // 4 0b01101101, // 5 0b01111101, // 6 0b00000111, // 7 0b01111111, // 8 0b01101111 // 9 }; // Interrupt for Timer0 (1ms) void __interrupt() isr(void) { if (TMR0IF) { TMR0IF = 0; TMR0 = 6; // preload for 1ms (with 1:256 prescaler) millis_counter++; } } unsigned long millis() { return millis_counter; } void setup_timer0() { OPTION_REG = 0b00000111; // prescaler 1:256, assigned to TMR0 TMR0 = 6; TMR0IE = 1; TMR0IF = 0; PEIE = 1; GIE = 1; } void display_number(uint16_t number) { digits[0] = number / 100; digits[1] = (number / 10) % 10; digits[2] = number % 10; } void update_display() { static uint8_t index = 0; DIGIT1 = 0; DIGIT2 = 0; DIGIT3 = 0; SEGMENTS_PORT = numbers[digits[index]]; if (index == 0) DIGIT1 = 1; else if (index == 1) DIGIT2 = 1; else if (index == 2) DIGIT3 = 1; index = (index + 1) % 3; } void beep(uint8_t times) { for (uint8_t i = 0; i < times; i++) { BUZZER = 1; __delay_ms(100); BUZZER = 0; __delay_ms(100); } } void main(void) { // Setup SEGMENTS_TRIS = 0x00; TRISC = 0x00; TRISB = 0xFF; // Buttons as input PORTB = 0xFF; // Enable pull-ups if needed setup_timer0(); unsigned long prev_time = 0; uint8_t running = 0; while (1) { update_display(); display_number(countdown); if (!BT_START) { __delay_ms(50); if (!BT_START) running = !running; while (!BT_START); } if (!BT_UP && !running && countdown < 999) { __delay_ms(50); if (!BT_UP) countdown++; while (!BT_UP); } if (!BT_DOWN && !running && countdown > 0) { __delay_ms(50); if (!BT_DOWN) countdown--; while (!BT_DOWN); } if (running && millis() - prev_time >= 1000) { prev_time = millis(); if (countdown > 0) countdown--; if (countdown == 0) { running = 0; beep(3); } } __delay_ms(5); // Small delay for multiplexing stability } }