#include <16f870.h>
#device ADC=10
//#fuses NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT, INTRC_IO
#fuses HS, NOWDT, NOLVP, NOBROWNOUT, NOPROTECT, PUT
//#use delay (internal=8MHz)
#use delay (clock=8MHz)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS) //CONFIGURO PUERTO SERIE
//#use RS232(UART1, ERRORS)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//**VARIABLES PARA GESTIONAR LA TRAMA RECIBIDA Y LA TRAMA A ENVIAR POR PUERTO SERIE**//
long valor_adc=0; //Variable de 16 bits para lectura ADC
int P_W=0; //indice escritura
int P_R=0; //indice lectura
int i=0;
int j=0;
int inicio=0;
int final=0;
char string_valor_adc[5]="0000";//Cadena de caracteres para guardar valor ADC en Carcteres
char trama_entrada[51]={0}; //String para guardar el dato de entrada por UART
char direccion_pic[4]="P02";
char tipo_dato[5]="$ADQ";
char canal[4]="CH0";
char dato[14]="$ADQ,P02,CH0\r";
char miretorno[2]="\r";
char misimbolo[2]="$";
short flag_final=0;
short flag_permiso=0;
short flag_tst=0;
short flag_envio=0;
//FUNCIÓN PARA LEER LOS DATOS PROCEDENTES DEL PUERTO SERIE//
void lectura(){
for(P_R=0; P_R<51; P_R++){
if(trama_entrada[P_R]==misimbolo[0]){
inicio=P_R;
for(P_R=inicio; P_R<51; P_R++){
if(trama_entrada[P_R]==miretorno[0]){
P_W=0;
final=P_R;
flag_permiso=1;
break;
}
}
break;
}
}
}
//FUNCIÓN PARA COPIAR EL DATO PROCEDENTE DEL BUFFER DEL PUERTO SERIE//
void escritura(){
for(i=inicio; i<=final; i++){
dato[j]=trama_entrada[i];
j++;}
i=0;
j=0;
memset(trama_entrada, 0, sizeof(trama_entrada));
return;
}
//FUNCIÓN PARA PROCESAMIENTO DEL DATO PROCEDENTE DEL PUERTO SERIE//
void procesamiento(){
//Se copia la dirección de la solicitud para saber a qué pic va dirigido//
//Éste pic tiene la dirección "P01"//
for(i=0; i<3; i++){
direccion_pic[i]=dato[i+5];}
direccion_pic[3]='\0';
//Se compara la dirección obtenida con la de éste pic//
if(strcmp(direccion_pic, (char*)"P02")==0){
memset(direccion_pic, 0, sizeof(direccion_pic));
//Se copia el tipo de dato que puede ser "$ADQ" o "$TST"//
for(i=0; i<4; i++){
tipo_dato[i]=dato[i];}
tipo_dato[4]='\0';
//Se compara el tipo de dato con "$ADQ" que es para obtener medidas del ADC//
if(strcmp(tipo_dato, (char*)"$ADQ")==0){
memset(tipo_dato, 0, sizeof(tipo_dato));
flag_tst=0;//flag para el case de la función enviar
//Se copia el canal para ver qué canal se quiere escoger "CH0" o "CH1"//
for(i=0; i<3; i++){
canal[i]=dato[i+9];}
canal[3]='\0';
//Se compara el canal//
if(strcmp(canal,(char*)"CH0")==0){
set_adc_channel(0);}
else if(strcmp(canal,(char*)"CH1")==0){
set_adc_channel(1);}
//Lectura del ADC//
delay_us(20);//retardo para leer ADC
valor_adc=read_adc();//lectura ADC
sprintf(string_valor_adc,"%04ld",valor_adc);
}
//Se compara el tipo de dato con "$TST" que es para que éste pic responda con "$TST,P01\r"//
else if(strcmp(tipo_dato,(char*)"$TST")==0){
memset(tipo_dato, 0, sizeof(tipo_dato));
flag_tst=1;
}
//Se da permiso para enviar dato//
flag_envio=1;//flag para el case de la función enviar
}
return;
}
void enviar(){
switch(flag_tst){
case 0:
output_high(PIN_B0);
delay_ms(3);
printf("$ADQ,P02,%s,%s\r", canal,string_valor_adc);
delay_ms(3);
output_low(PIN_B0);
break;
case 1:
output_high(PIN_B0);
delay_ms(3);
printf("$TST,P02\r");
delay_ms(3);
output_low(PIN_B0);
flag_tst=0;
break;
}
return;
}
void main(){
output_low(PIN_B0);
output_high(PIN_C4);
disable_interrupts(INT_RDA);
enable_interrupts(GLOBAL); //HABIlLITO TODAS LAS INTERRUPCIONES GLOBALES
enable_interrupts(INT_RDA); //HABILITO LA INTERRUPCIÓN UART
setup_adc_ports(ALL_ANALOG); //INDICO EL PIN A0/A1/A2/A3/A4/A5 COMO ENTRADA ANALÓGICA
setup_adc(ADC_CLOCK_INTERNAL); //CLOCK INTERNO PARA CONVERSIÓN ADC
while(1){
output_high(PIN_C4);
delay_ms(1000);
output_low(PIN_C4);
delay_ms(1000);
if(flag_final==1){
flag_final=0;
lectura();
if(flag_permiso==1){
flag_permiso=0;
escritura();
procesamiento();
if(flag_envio==1){
flag_envio=0;
enviar();
}
}
}
}
}
#INT_RDA
void INT_UART(void) {
trama_entrada[P_W]=getc();
if(trama_entrada[P_W]=='\r'){
P_W=0;
flag_final=1;
}
else{
P_W++;
if(P_W >=21 ){
P_W=0;
}
}
}