Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
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.
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
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.
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
#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.
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.