by ciclingman » Sun Feb 01, 2026 6:46 pm
Hello everyone. I still have communication problems; the PIC16F18877 receives what the PIC16F690 transmits; but the PIC16F690 does not receive what the PIC18877 transmits; I write the setting I wrote for the PIC16F18877:
PIC16F18877
// CONFIG1
#pragma config FEXTOSC = OFF // External Oscillator mode selection bits->Oscillator not enabled
#pragma config RSTOSC = HFINT32 // Power-up default value for COSC bits (HFINTOSC with OSCFRQ= 32 MHz and CDIV = 1:1)
#pragma config CLKOUTEN = OFF // Clock Out Enable bit->CLKOUT function is disabled; i/o or oscillator function on OSC2
#pragma config CSWEN = OFF // Clock Switch Enable bit->Writing to NOSC and NDIV is allowed
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit->FSCM timer enabled
// CONFIG2
#pragma config MCLRE = OFF // Master Clear Enable bit (MCLR pin is Master Clear function)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config LPBOREN = OFF // Low-Power BOR enable bit (ULPBOR disabled)
#pragma config BOREN = ON // Brown-out reset enable bits (Brown-out Reset Enabled, SBOREN bit is ignored)
#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (VBOR) set to 1.9V on LF, and 2.45V on F Devices)
#pragma config ZCD = OFF // Zero-cross detect disable (Zero-cross detect circuit is disabled at POR.)
#pragma config PPS1WAY = OFF // Peripheral Pin Select one-way control (The PPSLOCK bit can be set and cleared repeatedly by software)
#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable bit (Stack Overflow or Underflow will cause a reset)
// CONFIG3
#pragma config WDTCPS = WDTCPS_31// WDT Period Select bits (Divider ratio 1:65536; software control of WDTPS)
#pragma config WDTE = OFF // WDT operating mode (WDT Disabled, SWDTEN is ignored)
#pragma config WDTCWS = WDTCWS_7// WDT Window Select bits (window always open (100%); software control; keyed access not required)
#pragma config WDTCCS = SC // WDT input clock selector (Software Control)
// CONFIG4
#pragma config WRT = OFF // UserNVM self-write protection bits (Write protection off)
#pragma config SCANE = available// Scanner Enable bit (Scanner module is available for use)
#pragma config LVP = ON // Low Voltage Programming Enable bit (Low Voltage programming enabled. MCLR/Vpp pin function is MCLR.)
// CONFIG5
#pragma config CP = OFF // UserNVM Program memory code protection bit (Program Memory code protection disabled)
#pragma config CPD = OFF // DataNVM code protection bit (Data EEPROM code protection disabled)
#define _XTAL_FREQ 32000000
#include <xc.h>
#include <stdint.h>
#include <stdbool.h>
#include <pic.h>
void __interrupt() INTERRUPT_Intervallo (void) //Interrupt di TIMER0 settato a 1 ms
{
while (RCIF) {ValoreRicevuto = RCREG;} //Se buffer ricezione pieno
//e assenza di trasmissione passa valore
//Interrupt (verifica ogni millisecondo)-------------------------------------------
if(PIR0bits.TMR0IF)
{
if (tempo != 0) tempo--; //Decremento
TMR0H = 0XF8; //Caricamento nibble H del timer0 a 16 bit
TMR0L = 0XF0; //Caricamento nibble L del timer0 a 16 bit
PIR0bits.TMR0IF = 0; //Reset
}
}
//Funzione di trasmissione dati con tastiera
unsigned char Trasmissione(unsigned char ValTrasmissione)
{
//INIZIO TRASMISSIONE
Routine_Ritardo(100); //Assestamento linea
RCIE = 0; //Disabilitazione interrupt ricezione
TX1STAbits.TXEN = 1; //Abilitazione trasmissione seriale
EnableDati = 1; //Abilitazione trasmissione RS485
Routine_Ritardo(150); //Assestamento linea
while (TXIF)
{
TXREG = ValTrasmissione; //Invio byte fino a quando il flag non si resetta
}
Routine_Ritardo(100); //Assestamento linea
EnableDati = 0; //Abilitazione ricezione RS485
//FINE TRASMISSIONE
//SETTAGGIO RICEZIONE
Routine_Ritardo(100); //Assestamento linea
TX1STAbits.TXEN = 0;//Disabilitazione trasmissione seriale
RCIE = 1; //Abilitazione interrupt ricezione
return 0;
}
void main(void)
{
ADRESL = 0x00; //Esclusione porte analogiche, tutto digitale i/o
ADRESH = 0x00;
ANSELA = 0x00;
ANSELB = 0x00;
ANSELC = 0x00;
ANSELD = 0x00;
ANSELE = 0x00;
ADCON0bits.ADON = 0; //Convertitore analogico digitale spento
//LATx registers
LATE = 0x00;
LATD = 0x00;
LATA = 0x00;
LATB = 0x00;
LATC = 0x00;
//WPUx registers for pull-up
WPUD = 0x00;
WPUE = 0x00;
WPUB = 0x00;
WPUA = 0x00;
WPUC = 0x00;
//ODx registers
ODCONE = 0x00;
ODCONA = 0x00;
ODCONB = 0x00;
ODCONC = 0x00;
ODCOND = 0x00;
//SLRCONx registers
SLRCONA = 0xFF;
SLRCONB = 0xFF;
SLRCONC = 0xFF;
SLRCOND = 0xFF;
SLRCONE = 0x07;
//INLVLx registers
INLVLA = 0xFF;
INLVLB = 0xFF;
INLVLC = 0xFF;
INLVLD = 0xFF;
INLVLE = 0x0F;
// PORT A
TRISA = 0b11011111; //Port A tutto IN tranne bit 5
// PORT B
TRISB = 0b11111111; //Port B tutto IN
// PORT C
TRISC = 0b10001100; //Port C tutto OUT tranne bit 2 3 7
// PORT D
TRISD = 0b00000011; //Port D tutto OUT tranne bit 0 1
// PORT E
TRISE = 0b11101100; //Port D tutto IN tranne bit 0 1 4(per settare la porta D come in e out)
//Abilitazione Interrupt
PIE0bits.TMR0IE = 1;
INTCONbits.GIE = 1;
INTCONbits.PEIE = 0;
// OSCCON1bits.NDIV = 4; //Si divide per 4 per avere un clock di 8 MHz per la comunicazione
//Settaggio timer0 a 1 ms
T0CON1 = 0b01000010;//0b01110000; //0b01110000; 1000 = 2secondi
T0CON0 = 0b10010000;//0b10010000; //0b10010000; 1000 = 2secondi
TMR0H = 0XF8;//Caricamento nibble H del timer0 a 16 bit
TMR0L = 0XF0;//Caricamento nibble L del timer0 a 16 bit
//Settaggio comunicazione e abilitazione ricezione ricordando che il clock source è di 8 MHz
RCIE = 1; //Interrupt ricezione abilitato
TX1STAbits.SYNC = 0;
TX1STAbits.TX9 = 0;
BRGH = 1; BRG16 = 0; //Settaggio per velocità di comunicazione (baud rate)
SPBRG = 207;
RC1STAbits.SPEN = 1; //Settaggi per ricezione
RC1STAbits.CREN = 1;
PORTA = 0X00; PORTB = 0X00; PORTC = 0X00; //Reset delle porte
Routine_Ritardo(30); //Assestamento
while (1)
{
if (Ok == 0) {Routine_Ritardo(50); Trasmissione(21); Sirene = 1;} //prova led rosso acceso
if (Set == 0) {Routine_Ritardo(50); Trasmissione(22); Sirene = 0;}//led verde acceso
if (ValoreRicevuto == 23) {ControlloBatteria = 1;}// Scrittura_Car(ValoreRicevuto); ValoreRicevuto = 0;}
else if (ValoreRicevuto == 21) {Routine_Ritardo(30); ControlloBatteria = 0;}
}
}
PIC16F690
#include <pic.h>
//Fusibili di configurazione
#pragma config FOSC = INTRCIO // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/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 = ON // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#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)
#define _XTAL_FREQ 8000000 //Oscillatore impostato a 8 MHz
#define LedVerde RA4 //Led verde (stato antifurto)
#define LedRosso RA5 //Led rosso (stato antifurto)
#define EnableDati RB6 //Pin di gestione trasmissione porta seriale 485
//----------------------------------------------------------------------------
void __interrupt()intervallo(void) //Interrupt di TIMER0 settato a 1 ms
{
//RICEZIONE mediante interrupt (verifica ogni millisecondo)
while (RCIF) {ValoreRicevuto = RCREG;} //Se buffer ricezione pieno
//e assenza di trasmissione passa valore
if (T0IF) //Se overflow
{
if (tempo != 0)
{
tempo--; //Decremento
}
T0IF = 0; //Reset
}
}
unsigned char Trasmissione(unsigned char ValTrasmissione)
{
//INIZIO TRASMISSIONE
Routine_Ritardo(100); //Assestamento linea
RCIE = 0; //Disabilitazione interrupt ricezione
TXEN = 1; //Abilitazione trasmissione seriale
EnableDati = 1; //Abilitazione trasmissione RS485
Routine_Ritardo(150); //Assestamento linea
while (TXIF)
{
TXREG = ValTrasmissione; //Invio byte fino a quando il flag non si resetta
}
Routine_Ritardo(100); //Assestamento linea
EnableDati = 0; //Abilitazione ricezione RS485
//FINE TRASMISSIONE
//SETTAGGIO RICEZIONE
Routine_Ritardo(100); //Assestamento linea
TXEN = 0;//Disabilitazione trasmissione seriale
RCIE = 1; //Abilitazione interrupt ricezione
return 0;
}
void main(void)
{
// INIZIALIZZAZIONE HARDWARE
ANSEL = 0x00;
ANSELH= 0X00; //Esclusione porte analogiche, tutto digitale i/o
// PORT A
TRISA = 0b11001111; //Port A tutto IN tranne i bit 4, 5
// PORT B
TRISB = 0b00111111; //Port B tutto IN tranne i bit 6, 7
// PORT C
TRISC = 0b00001111; //Port C tutto IN //tranne i bit 4, 5, 6, 7
PORTC = 0b00000000; //Reset uscite
// Oscillatore impostato a 8MHz
OPTION_REG = 0b10000010; //Prescaler 1:8 e disabilitazione Pull-up
INTCON = 0b10100000;
OSCCON = 0b01110000; //Settaggio oscillatore interno a 8 MHz
TMR0 = 6; //Caricamento TIMER0 a 1 ms
RCIE = 1; //Interrupt ricezione abilitato
SYNC = 0; CREN = 1; SPEN = 1;//Settaggi per ricezione
BRGH = 1; BRG16 = 0; SPBRG = 51; //Settaggio per velocità di comunicazione (baud rate) 10417
PORTA = 0X00; PORTB = 0X00;// PORTC = 0X00; //Reset delle porte
EnableDati = 0; //Enable disabilitato per ricezione
Routine_Ritardo(30); //Assestamento
//----------------------------------------------------------------------------------------
while (1)
{
RC4 = 1;
if(RC3 == 0) {Routine_Ritardo(50); Trasmissione(23);}
else if(RC3 == 1) {Routine_Ritardo(50); Trasmissione(21); LedVerde = 0;}
switch (ValoreRicevuto)
{
case 21:
LedRosso = 1;
LedVerde = 0;
case 22:
LedVerde = 1;
LedRosso = 0;
}
if (ValoreRicevuto == 0) {LedVerde = 1; LedRosso = 0;}
else if (ValoreRicevuto != 0) {LedVerde = 0; LedRosso = 1;}
}
}