hola, buenas tardes,
tengo un 877 que envía datos a un 628 (24 bits, char de comandos más un unsigned short (16 bits) de datos), el 628 escucha y cumple, los datos van en un solo sentido, no utilizo el serial porque está ocupado (la placa ya está diseñada)
el funcionamiento es este:
el 877 verifica que el pin de escucha (ra2 877 - rb2 628) esté bajo, escribe un dato en el pin de datos (ra1 877 - rb1 628), levanta el clock (ra0 877 - rb0 628) y la int del 628 en flanco ascendente lee el dato y lo almacena, el 877 espera 1 ms (también hice pruebas con 10 ms) para que el 628 lea el dato y baja el clock, repite el proceso hasta completar el envío
cuando el 628 leyo los 24 bits, levanta el pin escucha, procesa los datos y cuando termina, baja el pin escucha y queda a la espera
el tema está en que el 877 envía los 24 bits pero el 628 solamente almacena los primeros 18, el resto ni cinco de bola,
este es el código:
tengan en cuenta que para el envío y para la recepción usaba OR pero lo saqué para ubicar el error
main_877.c
#include "main_877.h"
#include "comunicacion_877.h"
//------------------------------------------------------------------------------
//#### inicializacion del pic ##################################################
//------------------------------------------------------------------------------
void inicializar_valores(void)
{
contador_interrupciones_timer1 = 0;
}
void activar_interrupciones_PORTB_TIMER(void)
{
INTCONbits.RBIF = 1;
INTCONbits.INTF = 1;
/**** INTERRUPCIONES ****/
INTCONbits.PEIE = 1; // Enables all unmasked peripheral interrupts
INTCONbits.RBIE = 1; // Enables the RB port change interrupt
// PORTB pull-ups are enabled by individual port latch values
OPTION_REGbits.nRBPU = 1;
// Interrupt on rising (creciente) edge of RB0/INT pin
OPTION_REGbits.INTEDG = 1;
INTCONbits.RBIF = 0;
INTCONbits.INTF = 0;
INTCONbits.GIE = 1; // Enables all unmasked interrupts
T1CONbits.TMR1ON = 1; // Timer1 On bit
}
//------------------------------------------------------------------------------
void configurar_pic(void)
{
/*****************************
******** T I M E R 1 ********
*****************************/
T1CONbits.TMR1CS = 0; // Timer1 Clock Source - 0 Internal clock (FOSC/4)
T1CONbits.T1CKPS1 = 1; // prescaler
T1CONbits.T1CKPS0 = 1; // 1:8
TMR1H = VALOR_TMR1H; // 3036
TMR1L = VALOR_TMR1L; // 500 ms
T1CONbits.TMR1ON = 0; // Timer1 On bit
PIE1bits.TMR1IE = 1; // TMR1 Overflow Interrupt Enable bit
/*********************
*** P U E R T O S ***
*********************/
/**** PORTD I/O ****/
TRISEbits.PSPMODE = 0; // PORTD functions in general purpose I/O mode
/**** PORTE I/O ****/
TRISEbits.TRISE2 = 0; // Output
TRISEbits.TRISE1 = 0; // Output
TRISEbits.TRISE0 = 0; // Output
/**** PORTA / PORTE I/O ****/
ADCON1bits.PCFG3 = 0; // RA5:RA0 y RE2:RE0 Digital
ADCON1bits.PCFG2 = 1; // RA5:RA0 y RE2:RE0 Digital
ADCON1bits.PCFG1 = 1; // RA5:RA0 y RE2:RE0 Digital
ADCON1bits.PCFG0 = 1; // RA5:RA0 y RE2:RE0 Digital
/*
* RA0 Clock salida
* RA1 Data salida
* RA2 Listo para escucha ( 1 ) entrada
*/
TRISA = 0b00100100;
TRISB = 0b11110010;
TRISC = 0b00000000; // Salida
TRISD = 0b00000000; // Salida
TRISE = 0b00000000; // Salida
}
//------------------------------------------------------------------------------
/*
* M A I N
*/
int main(void)
{
configurar_pic();
activar_interrupciones_PORTB_TIMER();
PORTA = 0b00000000;
PORTB = 0b00000000;
PORTC = 0b00000000;
PORTD = 0b00000000;
PORTE = 0b00000000;
t_byte comando;
t_int dato;
comando.variable = 23;
dato.variable = 54;
enviar_datos( comando, dato );
while ( true ) ;
}
main_877.h
#include <stdio.h>
#include <stdlib.h>
#include <xc.h>
#include <pic16f877a.h>
#include <stdbool.h>
#include "interrupciones_877.h"
//------------------------------------------------------------------------------
//######## configuracion del pic ###############################################
//------------------------------------------------------------------------------
#define _XTAL_FREQ 4000000 // Velocidad clock en Hz
#pragma config FOSC = XT // Oscillator Selection bits
// (XT 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 usedfor 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;
// all program memory may be written
// to by EECON control)
#pragma config CP = ON // Flash Program Memory
// Code Protection bit
// (Code protection off)
//------------------------------------------------------------------------------
//######## configuracion del TIMER1 ############################################
//------------------------------------------------------------------------------
/**** Reloj a 4 MHz ****/
#define VALOR_TMR1H 0b01011101 // 23869
#define VALOR_TMR1L 0b00111101 // 500 ms
#define NRO_INT_TIMER1_X_SEG 2 // 500 ms * 2 = 1 seg
//------------------------------------------------------------------------------
//######## macros generales ######################
//------------------------------------------------------------------------------
#define testbit(var, bitnro) ((var) & (1 <<(bitnro)))
#define bitset(var, bitnro) ((var) |= 1UL << (bitnro))
#define bitclr(var, bitnro) ((var) &= ~(1UL << (bitnro)))
#define __delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0)))
#define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
//------------------------------------------------------------------------------
//######## variables globales ######################
//------------------------------------------------------------------------------
near int contador_interrupciones_timer1;
//------------------------------------------------------------------------------
//######## puertos ############################
//------------------------------------------------------------------------------
#define COMU_CLOCK PORTAbits.RA0
#define COMU_DATA PORTAbits.RA1
#define COMU_ESCUCHA PORTAbits.RA2
comunicacion_877.c
void enviar_datos( t_byte comando, t_int dato )
{
if ( COMU_ESCUCHA )
{
COMU_DATA = comando.d0;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = comando.d1;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = comando.d2;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = comando.d3;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = comando.d4;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = comando.d5;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = comando.d6;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = comando.d7;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = dato.d0;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = dato.d1;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = dato.d2;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = dato.d3;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = dato.d4;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = dato.d5;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = dato.d6;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = dato.d7;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = dato.d8;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = dato.d9;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = dato.d10;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = dato.d11;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = dato.d12;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = dato.d13;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = dato.d14;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_DATA = dato.d15;
COMU_CLOCK = 1; __delay_ms( RETARDO_ENVIO_DATOS_MS );
COMU_CLOCK = 0; PORTAbits.RA3 = 1;
}
}
comunicacion_877.h
#define RETARDO_ENVIO_DATOS_MS 10
//------------------------------------------------------------------------------
typedef union {
unsigned char variable;
struct {
unsigned d7:1, d6:1, d5:1, d4:1, d3:1, d2:1, d1:1, d0:1;
//unsigned b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
};
} t_byte;
typedef union {
unsigned int variable;
struct {
unsigned d15:1, d14:1, d13:1, d12:1, d11:1, d10:1, d9:1, d8:1, d7:1, d6:1, d5:1, d4:1, d3:1, d2:1, d1:1, d0:1;
//unsigned b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1;
};
} t_int;
void enviar_datos( t_byte comando, t_int dato );
main_628.c
void activar_interrupciones_PORTB_TIMER(void)
{
INTCONbits.RBIF = 1;
INTCONbits.INTF = 1;
/***** configuracion del timer 1 ******************************************/
T1CONbits.TMR1CS = 0; // Timer1 Clock Source - 0 Internal clock (FOSC/4)
T1CONbits.T1CKPS1 = 1; // prescaler
T1CONbits.T1CKPS0 = 1; // 1:8
TMR1H = VALOR_TMR1H; // 3036
TMR1L = VALOR_TMR1L; // 500 ms
T1CONbits.TMR1ON = 0; // Timer1 On bit
PIE1bits.TMR1IE = 1; // TMR1 Overflow Interrupt Enable bit
/***** configuracion de los puertos ***************************************/
INTCONbits.PEIE = 1; // Enables all unmasked peripheral interrupts
INTCONbits.RBIE = 1; // Enables the RB port change interrupt
// PORTB pull-ups are enabled by individual port latch values
OPTION_REGbits.nRBPU = 1;
// 1 = Interrupcion en flanco ascendente del pin RB0/INT
// 0 = Interrupcion en flanco descendente del pin RB0/INT
OPTION_REGbits.INTEDG = 1;
INTCONbits.RBIF = 0; // When at least one of the RB<7:4> pins changes state
// (must be cleared in software)
INTCONbits.INTF = 0; // The RB0/INT external interrupt occurred
// (must be cleared in software)
INTCONbits.INTE = 1; // Enables the RB0/INT external interrupt
INTCONbits.GIE = 1; // Enables all unmasked interrupts
/***** activacion de la int del timer1 ************************************/
T1CONbits.TMR1ON = 1; // Timer1 On bit
GIE = 1; // Enable all unmasked interrupts
PEIE = 1; // Enable all unmasked peripheral interrupts
}
//------------------------------------------------------------------------------
void inicializar_puertos()
{
/***** configuración del oscilador interno ********************************/
PCON |= 0b00001000; /* OSCF bit = 0b1 -> Fosc = 4MHz */
/***** configuración de los puertos ***************************************/
/*
* RA0 D0 LCD
* RA1 D1 LCD
* RA2 D2 LCD
* RA3 D3 LCD
* RA4 D4 LCD
* RA5 D5 LCD
* RA6 D6 LCD
* RA7 D7 LCD
*/
TRISA = 0xFF;
PORTA = 0x00; /* clear PORTA buffer */
CMCON |= 0b00000111; /* CM = 0b111, desactiva comparadores */
VRCON = 0x00; /* Vref desconectado de RA2 */
/*
* RB7 E LCD
* RB6 RW LCD
* RB5 RS LCD
* RB4 Luz LCD
* RB3
* RB2 Listo para escucha ( 1 ) salida
* RB1 Data entrada
* RB0 Clock entrada
*/
TRISB = 0b00000011;
OPTION_REG |= 0b10000000; /* desactiva pull-ups internos */
PORTB = 0x00; /* clear PORTB buffer */
}
int main(void)
{
pos = 0;
comando.variable = 0;
dato.variable = 0;
listoParaEscucha = true;
inicializar_puertos();
activar_interrupciones_PORTB_TIMER();
COMU_ESCUCHA = listoParaEscucha;
while ( true ) ;
}
main_628.h
/*******************************
**** Configuracion del PIC ****
*******************************/
#define _XTAL_FREQ 4000000 /* frecuencia del oscilador 4Mhz */
#pragma config FOSC = INTOSCIO // Uso de osc. interno
// E/S en RA6 y RA7
#pragma config WDTE = OFF // Deshabilita "Watchdog Timer"
#pragma config PWRTE = OFF // Deshabilita "Power-up Timer"
#pragma config MCLRE = OFF // Configura MCLR como E/digital
#pragma config CP = ON // Habilita proteccion de codigo
#pragma config CPD = OFF // Deshabilita proteccion de
// memoria de datos
#pragma config BOREN = OFF // Deshabilita "Brown Out Detect"
#pragma config LVP = OFF // Deshabilita programacion de
// bajo voltage
//------------------------------------------------------------------------------
//######## definiciones del TIMER1 ##################
//------------------------------------------------------------------------------
/**** Timer1 - para 1 seg ***********************/
/**** Reloj a 4 MHz ****/
//------------------------------------------------------
// TMR1H TMR1L
// 500 ms - 3036 - 00001011 11011100 0xBDC - 0xB / 0xDC
//------------------------------------------------------
#define VALOR_TMR1H 0xB // 0b00001011
#define VALOR_TMR1L 0xDC // 0b11011100
#define NRO_INT_TIMER1_X_SEG 2 // 500 ms * 2 = 1 seg
//------------------------------------------------------------------------------
//######## variables ############################
//------------------------------------------------------------------------------
bool listoParaEscucha;
unsigned int pos;
//------------------------------------------------------------------------------
typedef union {
unsigned char variable;
struct {
unsigned d7:1, d6:1, d5:1, d4:1, d3:1, d2:1, d1:1, d0:1;
};
} t_byte;
t_byte comando;
typedef union {
unsigned int variable;
struct {
unsigned d15:1, d14:1, d13:1, d12:1, d11:1, d10:1, d9:1, d8:1, d7:1, d6:1, d5:1, d4:1, d3:1, d2:1, d1:1, d0:1;
};
} t_int;
t_int dato;
//------------------------------------------------------------------------------
//######## puertos #############################
//------------------------------------------------------------------------------
#define COMU_CLOCK PORTBbits.RB0
#define COMU_DATA PORTBbits.RB1
#define COMU_ESCUCHA PORTBbits.RB2
//------------------------------------------------------------------------------
#define LCD_LUZ PORTBbits.RB4
#define LCD_RS PORTBbits.RB5
#define LCD_RW PORTBbits.RB6
#define LCD_E PORTBbits.RB7
//------------------------------------------------------------------------------
//######## macros #############################
//------------------------------------------------------------------------------
#define testbit(var, bit) ((var) & (1 <<(bit)))
#define bitset(var, bitno) ((var) |= 1UL << (bitno))
#define bitclr(var, bitno) ((var) &= ~(1UL << (bitno)))
#define __delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0)))
#define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
interrupciones_628.c
void atender_interrupcion_clock( void )
{
if ( listoParaEscucha )
{
if ( pos == 0 ) comando.d0 = COMU_DATA;
else if ( pos == 1 ) comando.d1 = COMU_DATA;
else if ( pos == 2 ) comando.d2 = COMU_DATA;
else if ( pos == 3 ) comando.d3 = COMU_DATA;
else if ( pos == 4 ) comando.d4 = COMU_DATA;
else if ( pos == 5 ) comando.d5 = COMU_DATA;
else if ( pos == 6 ) comando.d6 = COMU_DATA;
else if ( pos == 7 ) comando.d7 = COMU_DATA;
else if ( pos == 8 ) dato.d0 = COMU_DATA;
else if ( pos == 9 ) dato.d1 = COMU_DATA;
else if ( pos == 10 ) dato.d2 = COMU_DATA;
else if ( pos == 11 ) dato.d3 = COMU_DATA;
else if ( pos == 12 ) dato.d4 = COMU_DATA;
else if ( pos == 13 ) dato.d5 = COMU_DATA;
else if ( pos == 14 ) dato.d6 = COMU_DATA;
else if ( pos == 15 ) dato.d7 = COMU_DATA;
else if ( pos == 16 ) dato.d8 = COMU_DATA;
else if ( pos == 17 ) dato.d9 = COMU_DATA;
else if ( pos == 18 ){ dato.d10 = COMU_DATA; LCD_LUZ = 1; }
else if ( pos == 19 ) dato.d11 = COMU_DATA;
else if ( pos == 20 ) dato.d12 = COMU_DATA;
else if ( pos == 21 ) dato.d13 = COMU_DATA;
else if ( pos == 22 ) dato.d14 = COMU_DATA;
else if ( pos == 23 ) dato.d15 = COMU_DATA;
if ( pos > 23 )
{
COMU_ESCUCHA = 0;
LCD_LUZ = 1;
pos = 0;
}
else
pos++;
}
}
//------------------------------------------------------------------------------
void atender_interrupcion_timer1( void )
{
}
//------------------------------------------------------------------------------
void interrupt interrupcion(void)
{
if ( INTCONbits.INTF )
atender_interrupcion_clock();
if ( PIR1bits.TMR1IF )
atender_interrupcion_timer1();
/* Reinicializa las banderas de las interrupciones de los puertos */
INTCONbits.RBIF = 0;
INTCONbits.INTF = 0;
}
muchas gracias