PIC16F877A-I/P
Controls
Properties
Availability & Pricing
Assets
id=FP_DIP1550W56P254L5219H483Q40N
id=3D_PIC16F877A-I_P
id=image-removebg-preview (1)
Simulation
Simulation with ProteusC
#define BUTTON1 PORTBbits.RB0 #define BUTTON2 PORTBbits.RB1 #define BUTTON3 PORTBbits.RB2 #define RELAY1 PORTDbits.RD0 #define RELAY2 PORTDbits.RD1 void main() { TRISB = 0b00000111; // Set RB0, RB1, RB2 as input TRISD = 0b11111100; // Set RD0, RD1 as output (relays) while (1) { if (BUTTON1 == 1) { // If Button 1 is pressed RELAY1 = 1; // Activate Relay 1, Lamp 1 ON RELAY2 = 0; // Ensure Relay 2 is OFF } if (BUTTON2 == 1) { // If Button 2 is pressed RELAY2 = 1; // Activate Relay 2, Lamp 2 ON RELAY1 = 0; // Ensure Relay 1 is OFF } if (BUTTON3 == 1) { // If Button 3 is pressed RELAY1 = 0; // Deactivate Relay 1, Lamp 1 OFF RELAY2 = 0; // Deactivate Relay 2, Lamp 2 OFF } } }
d0
, d1
, and d2
for inputs and b0
, b1
for outputs.set_tris_d(0x07);
sets the lower three bits of Port D as inputs (correct since you are using d0
, d1
for input).set_tris_b(0x0);
sets all bits of Port B as outputs. This is correct for b0
and b1
being outputs.C
if(input(d0)){ output_HIGH(b0); } if(input(d1)){ output_HIGH(b1); } if(input(d1)){ output_LOW(b0); output_LOW(b1); }
if(input(d1))
twice. The current logic will immediately turn off both b0
and b1
whenever d1
is high, also affecting b0
prematurely if your intent is to only allow b1
to be high.b0
high when d0
is high, b1
high when d1
is high, and both low under some condition related to d1
. Assuming d2
might be used to turn both b0
and b1
low, try the following code structure:C
while(true){ if(input(d0)){ output_HIGH(b0); // Lamp 1 ON output_LOW(b1); // Ensure Lamp 2 is OFF } if(input(d1)){ output_HIGH(b1); // Lamp 2 ON output_LOW(b0); // Ensure Lamp 1 is OFF } if(input(d2)){ // Assuming you wanted to use d2 output_LOW(b0); // Both Lamps OFF output_LOW(b1); } delay_ms(330); }
d2
) is used in your circuit since your original code does not make use of it.Basic
DEFINE ADC_BITS 10 ' Configuración de bits del ADC DEFINE ADC_CLOCK 3 ' Reloj del ADC DEFINE ADC_SAMPLEUS 10 ' Tiempo de muestreo del ADC
Basic
BatteryLevel VAR WORD ' Variable para el nivel de batería ADCIN 0, BatteryLevel ' Leer el voltaje en el canal AN0
Basic
IF BatteryLevel > 900 THEN ' Código para indicar "Carga rápida" ELSEIF BatteryLevel > 600 THEN ' Código para indicar "Carga lenta" ELSE ' Código para "Batería dañada" ENDIF
4. Simulación en Proteus:Basic
' Usar comandos LCDOUT para mandar las cadenas al Display LCDOUT $FE, 1, "Carga:", DEC BatteryLevel
Python
def verificar_estado_bateria(voltaje, corriente, capacidad): umbral_danio = 3.0 # Voltaje en el que consideramos que la batería puede estar dañada (arbitrario) corriente_rapida = capacidad # 1C en términos de corriente corriente_lenta = 0.1 * capacidad # 0.1C en términos de corriente if voltaje < umbral_danio: return "Pila dañada" elif corriente > corriente_rapida: return "Carga rápida" elif corriente_lenta <= corriente <= corriente_rapida: return "Carga lenta" else: return "Estado de carga desconocido" # Ejemplo de uso: voltaje_bateria = 3.7 # voltaje actual de la batería corriente_de_carga = 2.5 # corriente de carga actual en amperios capacidad_bateria = 2.0 # capacidad de batería en amperios-hora (Ah) estado = verificar_estado_bateria(voltaje_bateria, corriente_de_carga, capacidad_bateria) print(f"Estado de la batería: {estado}")
voltaje_bateria
: el voltaje actual de la batería.corriente_de_carga
: corriente de carga en amperios.capacidad_bateria
: capacidad de la batería en Ah.Image
ExplanationC
#include // Configuration bits #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled) #pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) // Variables to store the counter value unsigned char counterLow = 0; unsigned char counterHigh = 0; // Function to display the counter on the 7-segment displays void displayCount() { PORTB = counterLow; // Display low digit on 7-segment display via 74LS47 PORTC = counterHigh; // Display high digit on 7-segment display via 74LS47 } // Interrupt service routine void __interrupt() ISR() { if (INTF) { // If the external interrupt occurred INTF = 0; // Clear the interrupt flag counterLow = 0; counterHigh = 0; displayCount(); } } void main(void) { // Initialize ports TRISB = 0x00; // Set PORTB as output TRISC = 0x00; // Set PORTC as output TRISA2 = 1; // Set RA2 as input for the switch OPTION_REGbits.INTEDG = 0; // Interrupt on falling edge INTE = 1; // Enable external interrupt GIE = 1; // Enable global interrupt while (1) { for (int i = 0; i < 99; i++) { displayCount(); __delay_ms(1000); // Delay of 1 second (1000 ms) if (counterLow < 9) { counterLow++; } else { counterLow = 0; counterHigh++; } } } }
Image
Image
Steps to Use the ProgramC
#include // CONFIG #pragma config FOSC = HS // Oscillator Selection bits (HS oscillator) #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled) #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled) #pragma config BOREN = OFF // Brown-out Reset Enable bit (BOR disabled) #pragma config LVP = OFF // Low-Voltage (single-supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function, low-voltage programming disabled) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off) #pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off) void main(void) { // 1. Set RB0 as output TRISB0 = 0; // Configure RB0 as output // 2. Set RB0 to high to turn on the LED RB0 = 1; // Set RB0 high // Keeping the LED on indefinitely while (1) { // Infinite loop to keep the microcontroller running } }
main.c
file of your project.Explicaciones del CódigoC
#include // Configuración del microcontrolador #pragma config FOSC = HS #pragma config WDTE = OFF #pragma config PWRTE = OFF #pragma config BOREN = ON #pragma config LVP = OFF #pragma config CPD = OFF #pragma config WRT = OFF #pragma config CP = OFF // Declaración de funciones void init_config(void); // Variables globales unsigned char contador = 0; void main(void) { init_config(); while (1) { if (RB0 == 1) { // Si se pulsa el botón de incrementar __delay_ms(50); // Antirrebote if (RB0 == 1) { contador++; if (contador > 255) { // Si excede 8 bits, reinicia a 0 contador = 0; } PORTD = contador; // Mostrar contador en LEDs while (RB0 == 1); // Esperar a que suelten el botón } } if (RB1 == 1) { // Si se pulsa el botón de decrementar __delay_ms(50); // Antirrebote if (RB1 == 1) { contador--; if (contador < 0) { // Si desciende de 0, vuelve a 255 contador = 255; } PORTD = contador; // Mostrar contador en LEDs while (RB1 == 1); // Esperar a que suelten el botón } } } } void init_config(void) { TRISB = 0x03; // RB0 y RB1 como entradas TRISD = 0x00; // Puerto D como salida PORTB = 0x00; // Limpiar puerto B PORTD = 0x00; // Limpiar puerto D }
init_config()
inicializa la configuración de los puertos del PIC16F877A.while (1)
, se verifica constantemente si uno de los botones está presionado.Explicación del CódigoC
#include <16F877A.h> #device *=16 #FUSES NOWDT //No Watch Dog Timer #FUSES XT //Low power xtal #FUSES PUT //Power Up Timer #FUSES NOPROTECT //Code not protected from reading #FUSES BROWNOUT //Reset when brownout detected #FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O #use delay(crystal=4MHz) //Cristal de 4 MHz #include //Incluye la librería LCD void main() { unsigned int contador = 0; // Contador char buffer[5]; // Buffer para el número a mostrar en el LCD // Inicialización del LCD lcd_init(); // Configuración de los pines del puerto B set_tris_b(0x03); // RB0 y RB1 como entradas while(TRUE) { // Detección del botón de incremento if(input(PIN_B0)) { delay_ms(50); // Antirrebote if(input(PIN_B0)) { contador++; if (contador > 9999) // Limitar el contador a cuatro dígitos contador = 0; while(input(PIN_B0)); // Espera a que se suelte el botón } } // Detección del botón de decremento if(input(PIN_B1)) { delay_ms(50); // Antirrebote if(input(PIN_B1)) { if(contador == 0) // Manejo del desbordamiento bajo contador = 9999; else contador--; while(input(PIN_B1)); // Espera a que se suelte el botón } } // Mostrar el contador en el LCD sprintf(buffer, "%04u", contador); // Convertir el contador a string de 4 dígitos lcd_gotoxy(1, 1); // Posicionar el cursor en la posición inicial lcd_putc(buffer); // Mostrar el contador en el LCD } }
lcd.c
es utilizada para controlar el display LCD. Asegúrate de que esta librería esté disponible y configurada correctamente.lcd_init()
.set_tris_b(0x03)
.sprintf(buffer, "%04u", contador)
para convertir el valor del contador a un string de 4 dígitos con ceros a la izquierda.lcd_gotoxy(1, 1)
posiciona el cursor al inicio de la primera línea del LCD.lcd_putc(buffer)
muestra el valor del contador en el LCD.lcd.c
y de realizar las conexiones apropiadas. $$\text{PIC16F877A}$$
MCLR (Pin 1) -------------------$$10k\Omega$$------------------- 5V
VDD_1 (Pin 11) ----------------------------------------- 5V
VSS_1 (Pin 12) ----------------------------------------- GND
VDD_2 (Pin 32) ----------------------------------------- 5V
VSS_2 (Pin 31) ----------------------------------------- GND
RB0 (Pin 33) ----------------------$$\text{Button Increment}$$----- GND
RB1 (Pin 34) ----------------------$$\text{Button Decrement}$$----- GND
LCD
RS ------------------------------- RC0 (Pin 15)
E -------------------------------- RC1 (Pin 16)
D4 ------------------------------- RD4 (Pin 27)
D5 ------------------------------- RD5 (Pin 28)
D6 ------------------------------- RD6 (Pin 29)
D7 ------------------------------- RD7 (Pin 30)
VSS ------------------------------ GND
VDD ------------------------------ 5V
V0 ------------------------------- $$\text{Potenciometer}$$
$$ $$
$$ $$
5V GND
R/W ------------------------------ GND
RB0
a RB7
(PIN 33 a PIN 40) para leer las posiciones del DIP switch. Este puerto se elige por su facilidad de uso como entradas digitales.RD0
a RD7
(PIN 19 a PIN 30, saltando el VDD y VSS en los pines 11, 12, 31 y 32) para controlar los LEDs. Escogemos este puerto ya que es conveniente para manejar salidas digitales.RB0:33
, DIP2 a RB1:34
, ..., DIP8 a RB7:40
.RD0:19
, el ánodo del LED2 al RD1:20
, ..., y el ánodo del LED8 al RD7:30
a través de sus respectivas resistencias.RB0
a RB7
como entradas y RD0
a RD7
como salidas. Luego, en un bucle continuo, lee los estados de los switches y escribe esos estados a los pines correspondientes de los LEDs.C
void setup() { // Configura RB0-RB7 como entradas TRISB = 0xFF; // Configura RD0-RD7 como salidas TRISD = 0x00; } void loop() { // Lee el estado de los switches y escribe en los LEDs PORTD = PORTB; }
saucrak
copilot
MCLR/VPP (Pin 1) a +5V a través de una resistencia de 10kΩlcd.c
. Normalmente, esto puede variar, pero una configuración típica podría ser:lcd.c
si no están definidos.lcd.c
para las conexiones correctas. Con esto en mente, puedes simular y probar el programa utilizando un entorno que soporte el compilador del Microchip y simulación de hardware, como MPLAB X y Proteus.lcd.c
, por favor házmelo saber para que pueda asistirte más.