The provided code is a program for a microcontroller (likely...

September 4, 2025 at 01:08 AM

#include <xc.h> #include "config.h" // Set up for 8MHz internal oscillator #define _XTAL_FREQ 8000000UL // ========================== // Definitions // ========================== #define DIGIT1 LATCbits.LATC0 // First digit select (tens) #define DIGIT2 LATCbits.LATC1 // Second digit select (ones) #define STORE_BTN PORTDbits.RD0 // Store button #define READ_BTN PORTDbits.RD1 // Read button // 7-seg digit patterns (common cathode) const unsigned char SSD_digits[] = { 0x3F, // 0 0x06, // 1 0x5B, // 2 0x4F, // 3 0x66, // 4 0x6D, // 5 0x7D, // 6 0x07, // 7 0x7F, // 8 0x6F // 9 }; // ========================== // Global Variables for State // ========================== volatile int display_value = 0; volatile unsigned char multiplex_counter = 0; int current_temp = 0; int last_temp = 0; unsigned char display_mode = 0; // 0: live temp, 1: stored temp // ========================== // ADC Functions // ========================== unsigned int readADC(void) { ADCON0bits.GO = 1; while(ADCON0bits.GO); return ((unsigned int)ADRESH << 8) + ADRESL; } int readTemperature(void) { unsigned int adc_val = readADC(); // Assuming LM35: 10mV/°C, 5V Vref, 10-bit ADC (1024 steps) return (int)(adc_val * 0.488); // Conversion to °C } // ========================== // Interrupt Service Routine (ISR) // ========================== void __interrupt() isr(void) { if (PIR1bits.TMR2IF) { PIR1bits.TMR2IF = 0; // --- Alternate between digits --- if (multiplex_counter == 0) { LATB = SSD_digits[(display_value / 10) % 10]; // Tens DIGIT1 = 1; DIGIT2 = 0; } else { LATB = SSD_digits[display_value % 10]; // Ones DIGIT1 = 0; DIGIT2 = 1; } multiplex_counter ^= 1; // Toggle digit } } // ========================== // Main // ========================== void main(void) { // I/O setup TRISA = 0x01; // RA0 = analog input TRISB = 0x00; // PORTB = SSD segments TRISC = 0x00; // RC0, RC1 = digit select TRISD = 0xFF; // RD0, RD1 = buttons (inputs) // ADC setup ADCON1 = 0x0E; // AN0 analog, others digital ADCON2 = 0x8D; // Right justified, 8TAD, Fosc/32 ADCON0 = 0x01; // Enable ADC, channel 0 __delay_ms(1); // Timer2 Setup for 500 Hz ISR (250 Hz per digit) T2CON = 0b00000101; // Timer2 ON, Prescaler = 1:4 PR2 = 249; // PR2 = 249 → 500 µs per overflow T2CONbits.T2OUTPS = 4 - 1; // Postscaler = 1:4 → 2 ms interrupt = 500 Hz PIR1bits.TMR2IF = 0; // Clear flag PIE1bits.TMR2IE = 1; // Enable Timer2 interrupt INTCONbits.GIE = 1; // Global interrupts INTCONbits.PEIE = 1; // Peripheral interrupts unsigned int button_debounce_timer = 0; unsigned char store_btn_state = 1; unsigned char read_btn_state = 1; while(1) { // --- Buttons --- if (STORE_BTN == 0 && store_btn_state) { button_debounce_timer = 250; store_btn_state = 0; } if (READ_BTN == 0 && read_btn_state) { button_debounce_timer = 250; read_btn_state = 0; } if (button_debounce_timer > 0) { button_debounce_timer--; if (button_debounce_timer == 0) { if (STORE_BTN == 0) { last_temp = current_temp; display_mode = 0; } else if (READ_BTN == 0) { display_mode = 1; } } } if (STORE_BTN == 1) store_btn_state = 1; if (READ_BTN == 1) read_btn_state = 1; // --- Temperature update --- current_temp = readTemperature(); if (display_mode == 0) { display_value = current_temp; } else { display_value = last_temp; } } }

The provided code is a program for a microcontroller (likely a PIC microcontroller) to:

  1. Measure temperature using a sensor like the LM35.
  2. Display the temperature on a 2-digit 7-segment display.
  3. Allow switching between live temperature readings and last stored temperature via buttons.

Explanation:

1. Setup and Initialization:

  • The code initializes and configures:
    • I/O ports (AN0 as an analog input for the temperature sensor, PORTB for the 7-segment display, and PORTD for buttons).
    • ADC (Analog-to-Digital Converter) for reading the analog temperature sensor's output.
    • Timer2 for generating periodic interrupts that handle the multiplexing of the 7-segment display.
  • The internal oscillator is set to 8 MHz.

2. Temperature Measurement:

  • The function readTemperature() reads the ADC value from the sensor and converts it into a temperature in degrees Celsius.
  • The LM35 provides a linear output of 10 mV per °C. Using a 10-bit ADC with a reference voltage of 5V, the conversion is calculated as: [ \text{Temperature in °C} = \text{ADC Value} \times 0.488 ]

3. Displaying the Temperature:

  • The 7-segment digit patterns are stored in SSD_digits, where each entry corresponds to a digit (0 to 9).
  • Since the microcontroller only has enough pins to drive one digit of the display at a time, multiplexing is used.
    • It alternates between the tens (DIGIT1) and ones (DIGIT2) displays at high speed (500 Hz interrupt frequency, but each digit updates at 250 Hz) to make it appear as if both digits are on simultaneously.
    • The ISR (Interrupt Service Routine) performs this multiplexing by toggling the active digit and updating the display with the appropriate value.

4. Buttons for Storing and Viewing Data:

  • The user can interact with the system using two buttons:
    • STORE_BTN (RD0): When pressed, the current live temperature is saved in last_temp.
    • READ_BTN (RD1): When pressed, the device switches to stored mode, and the last saved value is displayed instead of the live temperature.
    • A basic debouncing mechanism is implemented to ensure reliable button interaction.

5. Main Loop Workflow:

  • The main loop continuously:
    • Monitors and debounces button presses to switch display modes or update the stored value.
    • Reads the live temperature from the sensor.
    • Updates the display:
      • If display_mode == 0, it shows the live temperature (current_temp).
      • If display_mode == 1, it shows the last stored temperature (last_temp).

6. Timer2 Interrupt Service Routine (ISR):

  • The ISR alternates between enabling DIGIT1 (tens) and DIGIT2 (ones) to display the appropriate part of the current display_value.
  • Updates the 7-segment display (PORTB) with the appropriate digit pattern.

Summary:

  • What this code does:
    The program reads temperature data from a sensor, displays it on a 2-digit 7-segment display, and allows the user to store the current temperature for later viewing by pressing a button. It uses ADC for temperature conversion, Timer2 for efficient display multiplexing, and simple debouncing logic for buttons.
Generate your own explanations
Download our vscode extension
Read other generated explanations

Built by @thebuilderjr
Sponsored by beam analytics
Read our terms and privacy policy
Forked from openai-quickstart-node