fbpx

Expresate

Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:

Transmitir datos en...
 
Avisos
Vaciar todo

Transmitir datos entre 2 pics

20 Respuestas
4 Usuarios
0 Reactions
15.1 K Visitas
wirry
Respuestas: 16
Topic starter
(@wirry)
Active Member
Registrado: hace 15 años

PIC que envia

#include <16F876A.h>
#device adc=10
#FUSES XT,NOWDT
#define use_portb_lcd TRUE
#use delay(clock=4000000)
#include <math.h>
#include <lcd.c>
#use RS232(baud=9600, xmit=pin_c6, rcv=pin_c7)
#BYTE TRISA = 0X85
#BYTE PORTA = 0X05
#BYTE TRISC = 0X87
#BYTE PORTC = 0X07

void main() {

int16 pre,temp,hum ;
int presiol,presioh;
int temperatural,temperaturah;
int humedadl,humedadh;
int dato[6];
int i=0;

setup_adc_ports(all_analog);
setup_adc (ADC_CLOCK_INTERNAL);

lcd_init();

while(TRUE){

//TEMPERATURA POSITIVA
set_adc_channel(0);
delay_us(20);
temp=read_adc();
temperatural=make8(temp,0); // parte temperatura baja
temperaturah=make8(temp,1); // parte temperatura alta

//TEMPERATURA NEGATIVA

//PRESIÓN
set_adc_channel(2);
delay_us(20);
pre=read_adc();
presiol=make8(pre,0); // parte presión baja
presioh=make8(pre,1); // parte presión alta

//HUMEDAD
set_adc_channel(3);
delay_us(20);
hum=read_adc();
humedadl=make8(hum,0); // parte humedad baja
humedadh=make8(hum,1); // parte humedad alta

dato[0]=temperatural;
dato[1]=temperaturah;
dato[2]=presiol;
dato[3]=presioh;
dato[4]=humedadl;
dato[5]=humedadh;

for(i=0;i<=5;i++){
putc(dato); //Envia los 6 datos

if(i==5)
i==0; //Reseteo de la variable i

lcd_gotoxy (1,1);
printf (lcd_putc, "T=%3.2ld ", temp);
printf (lcd_putc, "P=%3.2ld ", pre);
lcd_gotoxy (1,2);
printf (lcd_putc, "H=%3.2ld ", hum);
delay_ms(250);

}

}
}

PIC que recibe

#include <16F876A.h>
#device adc=10
#FUSES XT,NOWDT
#define use_portb_lcd TRUE
#use delay(clock=4000000)
#include <math.h>
#include <lcd.c>
#use RS232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8)
#BYTE TRISA = 0X85
#BYTE PORTA = 0X05

int temperatural, temperaturah;
int presiol, presioh;
int humedadl, humedadh;
int16 presio, temperatura, humedad;
int dato[6];
int i;

#int_RDA

RDA_isr(){

for(i=0;i<=5;i++){
dato=GETC(); //recibe los datos

}
}

void main() {
lcd_init();
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);

temperatural=dato[0];
temperaturah=dato[1];
presiol=dato[2];
presioh=dato[3];
humedadl=dato[4];
humedadh=dato[5];

temperatura=((int16)temperaturah<<8)|((int16)temperatural); //Deshago el cambio
presio=((int16)presioh<<8)|((int16)presiol); //Deshago el cambio
humedad=((int16)humedadh<<8)|((int16)humedadl); //Deshago el cambio

lcd_gotoxy (1,1);
printf (lcd_putc, "T=%4.2ld ",temperatura);
printf (lcd_putc, "P=%4.2ld ", presio);
lcd_gotoxy (1,2);
printf (lcd_putc, "H=%4.2ld ", humedad);
}

Se trata de una estación meteorológica inalámbrica que mide la temperatura, presión atmosférica y humedad, lo que hago es medir los valores con los sensores, después hago una conversión de un int16 a int8, envió todos los int8 que en mi caso son 6, y luego el otro pic deshace el cambio y saca por pantalla los datos.

Muchas gracias.

Responder
19 respuestas
ranganok
Respuestas: 3875
(@ranganok)
Ardero
Registrado: hace 19 años

Sigo diciendo que elimines el for de la interrupción. Usa una variable global como contador y un flag (otra variable global) para indicar fin de cuenta.

S2

Ranganok Schahzaman

Responder
wirry
Respuestas: 16
Topic starter
(@wirry)
Active Member
Registrado: hace 15 años

PIC 1

#include <16F876A.h>
#device adc=10
#FUSES XT,NOWDT
#define use_portb_lcd TRUE
#use delay(clock=4000000)
#include <math.h>
#include <lcd.c>
#use rs232 (baud=9600, xmit=pin_c6, rcv=pin_c7)
#BYTE TRISA = 0X85
#BYTE PORTA = 0X05
#BYTE TRISC = 0X87
#BYTE PORTC = 0X07

void main() {

int16 pre,temp,hum ;
int presiol,presioh;
int temperatural,temperaturah;
int humedadl,humedadh;
char checksum = 0x00;

setup_adc_ports(all_analog);
setup_adc (ADC_CLOCK_INTERNAL);

lcd_init();

while(1){

//TEMPERATURA POSITIVA
set_adc_channel(0);
delay_us(20);
temp=read_adc();
temperatural=make8(temp,0); // parte temperatura baja
temperaturah=make8(temp,1); // parte temperatura alta

//TEMPERATURA NEGATIVA

//PRESIÓN
set_adc_channel(2);
delay_us(20);
pre=read_adc();
presiol=make8(pre,0); // parte presión baja
presioh=make8(pre,1); // parte presión alta

//HUMEDAD
set_adc_channel(3);
delay_us(20);
hum=read_adc();
humedadl=make8(hum,0); // parte humedad baja
humedadh=make8(hum,1); // parte humedad alta

// Calculamos el checksum como una XOR
checksum = temperatural ^ temperaturah ^ presiol ^ presioh ^ humedadl ^ humedadh;

putc(0xAA); //Envio 170
delay_ms(250);
putc(0xAA); //Envio 170
delay_ms(250);
putc(temperatural); //Envio 1º dato
delay_ms(250);
putc(temperaturah); //Envio 2º dato
delay_ms(250);
putc(presiol); //Envio 3º dato
delay_ms(250);
putc(presioh); //Envio 4º dato
delay_ms(250);
putc(humedadl); //Envio 5º dato
delay_ms(250);
putc(humedadh); //Envio 6º dato
delay_ms(250);
putc(checksum); //Enviamos el checksum

lcd_gotoxy (1,1);
printf (lcd_putc, "T=%3.1ld ", temp);
printf (lcd_putc, "P=%3.2ld ", pre);
lcd_gotoxy (1,2);
printf (lcd_putc, "H=%3.2ld ", hum);
printf (lcd_putc, "CHK=%3.1X", checksum);

delay_ms(250);

}
}

PIC 2

#include <16F876A.h>
#device adc=10
#FUSES XT,NOWDT
#define use_portb_lcd TRUE
#use delay(clock=4000000)
#include <math.h>
#include <lcd.c>
#use RS232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8)
#BYTE TRISA = 0X85
#BYTE PORTA = 0X05

int temperatural, temperaturah;
int presiol, presioh;
int humedadl, humedadh;
int16 presio, temperatura, humedad;
int dato[7];
int i=0;
int lectura, lectura2, checksum;

#int_RDA

RDA_isr()
{

lectura=GETC(); //Lee el primer valor

if (lectura==0xAA){ // El primer valor tiene que ser un 170

lectura2=GETC();

if (lectura2==0xAA){ // El segundo valor tiene que ser un 170
for(i=0;i<=6;i++){ //Hace el bucle
dato=GETC();

checksum=dato[0]^dato[1]^dato[2]^dato[3]^dato[4]^dato[5]; //Hago el checksum
// de los datos recividos

if (checksum=dato[6]){ // Compruebo el checksum

temperatural=dato[0];
temperaturah=dato[1];
presiol=dato[2];
presioh=dato[3];
humedadl=dato[4];
humedadh=dato[5];
}
}
}
}
}

void main() {
lcd_init();
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);

temperatura=((int16)temperaturah<<8)|((int16)temperatural); //Deshago el cambio
presio=((int16)presioh<<8)|((int16)presiol); //Deshago el cambio
humedad=((int16)humedadh<<8)|((int16)humedadl); //Deshago el cambio

lcd_gotoxy (1,1);
printf (lcd_putc, "T=%3ld ",temperatura);
printf (lcd_putc, "P=%3ld ", presio);
lcd_gotoxy (1,2);
printf (lcd_putc, "H=%3ld ", humedad);
printf (lcd_putc, "CHK=%3X ", checksum);
}

Perdona Ranganok pero no sé cómo se hace lo que quieres decir. Ponme un ejemplo con lo que me quieres decir, lo siento por mi torpeza.
FJ_Sanchez, me puedes corregir el código, lo simulo con el Proteus y se ve que funciona bien.
Muchísimas gracias.

Responder
ranganok
Respuestas: 3875
(@ranganok)
Ardero
Registrado: hace 19 años

Tan fácil como esto:


#define NUM_MAX_DATOS (7)

bit flag;
byte buff[NUM_MAX_DATOS];
int i;

RDA_isr()
{
buff=GETC();
i++;
if(i == NUM_MAX_DATOS)
flag = 1;
}

main()
{
while(1)
{
if(flag == 1)
{
flag = 0;
i=0; // reseteamos el contador para recibir más datos
// En el buffer buff estarán los datos a leer
// ...
}
}
}

El código es ese más o menos (no se si las directivas byte y bit son correctas en el CCS).

S2

Ranganok Schahzaman

Responder
wirry
Respuestas: 16
Topic starter
(@wirry)
Active Member
Registrado: hace 15 años

#include <16F876A.h>
#device adc=10
#FUSES XT,NOWDT
#define use_portb_lcd TRUE
#use delay(clock=4000000)
#include <math.h>
#include <lcd.c>
#use RS232(baud=9600, xmit=pin_c6, rcv=pin_c7, bits=8)
#BYTE TRISA = 0X85
#BYTE PORTA = 0X05

int temperatural, temperaturah;
int presiol, presioh;
int humedadl, humedadh;
int16 presio, temperatura, humedad;
int dato[7];
int i=0;
int lectura, lectura2, checksum;
short flag;

#int_RDA

RDA_isr()
{

lectura=GETC(); //Lee el primer valor

if (lectura==0xAA){ // El primer valor tiene que ser un 170

lectura2=GETC();

if (lectura2==0xAA){ // El segundo valor tiene que ser un 170

dato=GETC();
i++;
if(i==7);
flag=1;

checksum=dato[0]^dato[1]^dato[2]^dato[3]^dato[4]^dato[5]; //Hago el checksum
// de los datos recividos

if (checksum==dato[6]){ // Compruebo el checksum

temperatural=dato[0];
temperaturah=dato[1];
presiol=dato[2];
presioh=dato[3];
humedadl=dato[4];
humedadh=dato[5];
}
}
}
}

void main() {

enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
lcd_init();

while(1){

if(flag==1)
{
flag=0;
i=0;

temperatura=((int16)temperaturah<<8)|((int16)temperatural); //Deshago el cambio
presio=((int16)presioh<<8)|((int16)presiol); //Deshago el cambio
humedad=((int16)humedadh<<8)|((int16)humedadl); //Deshago el cambio

lcd_gotoxy (1,1);
printf (lcd_putc, "T=%3ld ",temperatura);
printf (lcd_putc, "P=%3ld ", presio);
lcd_gotoxy (1,2);
printf (lcd_putc, "H=%3ld ", humedad);
printf (lcd_putc, "CHK=%3X ", checksum);
}
}
}

Ranganok he intentado hacer lo que tu mes has dicho pero no me funciona, ¿tú qué crees que está mal?
Gracias.

Responder
fj_sanchez
Respuestas: 1083
(@fj_sanchez)
Ardero
Registrado: hace 19 años

A ver, lo que has hecho está mal. Lo primero es que entiendas qué hace la interrupción. La interrupción llamará a tu función cada vez que se reciba un dato, en este caso, cada vez que esté listo un byte en la entrada. Por tanto, ya no vale que compares al principio con 0xAA, ya que sino lo harías para cada byte que te llega.

Lo que tendrías que hacer es comprobar que si i==0, entonces lo leido debe de ser 0xAA, después de eso incrementas la variable i (i++) y ya entonces no comprobarías esa condición.

Responder
Página 3 / 4
Compartir: