Advertisement
Electgpl

8051 - Estacion Interna Silabs C8051F832

Sep 30th, 2017
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 26.55 KB | None | 0 0
  1. //*********************************************************************************************************
  2. // Programa para la estacion meteorologica Interna inalámbrica
  3. // El programa recibe Temperatura, Humedad y Luminosidad por interrupcion
  4. // El sistema mide Temperatura y Humedad interior
  5. // El enlace se realiza mediante una comunicacion ASK OOK UHF sobre UART Invertido a 600bps
  6. // Se muestra medicion interna y externa en un LCD de 2x16
  7. // Microcontrolador Silabs C8051F832
  8. //*********************************************************************************************************
  9. #include <REG51F800.H>
  10. #include <reg52.h>
  11. #include <intrins.h>
  12. #include <stdio.h>
  13. //*********************************************************************************************************
  14. // Variables
  15. //*********************************************************************************************************
  16. #define HEADER 200                                           //Definicion de valor Header para el payload
  17. sbit DATA = P1^0;                                            //Pin del bus de un hilo para el DHT11
  18. static int datoInt[2];                                       //Variable donde se alojan los datos internos
  19. static int payload[5];                                       //Variable donde se aloja el payload
  20. static int datoExt[3];                                       //Variable donde se alojan los datos externos
  21. //*********************************************************************************************************
  22. // Configuracion de pines del LCD
  23. //*********************************************************************************************************
  24. extern bit RS;                                               //Definicion de pines
  25. extern bit EN;                                               //Definicion de pines                            
  26. extern bit D4;                                               //Definicion de pines
  27. extern bit D5;                                               //Definicion de pines
  28. extern bit D6;                                               //Definicion de pines
  29. extern bit D7;                                               //Definicion de pines
  30. sbit RS = P2^0;                                              //Definicion de pines
  31. sbit EN = P2^1;                                              //Definicion de pines                            
  32. sbit D4 = P2^4;                                              //Definicion de pines
  33. sbit D5 = P2^5;                                              //Definicion de pines
  34. sbit D6 = P2^6;                                              //Definicion de pines
  35. sbit D7 = P2^7;                                              //Definicion de pines
  36. //*********************************************************************************************************
  37. // delay_us Bloqueante Micro Segundos
  38. //*********************************************************************************************************
  39. void delay_us(unsigned int us_count){                        //Funcion para delay_ms de micro-segundos
  40.    int t=0;
  41.    while(us_count!=0){                                       //Mientras que el contador es distinto de cero
  42.       for(t=0;t<16;t++){                                     //16MIPS dividido en 16 para 1us
  43.          _nop_();                                            //Ejecuta funcion NOP de ensamblador
  44.       }
  45.       us_count--;                                            //Decremento del valor de delay_ms
  46.    }
  47. }
  48. //*********************************************************************************************************
  49. // delay_ms Bloqueante Mili Segundos
  50. //*********************************************************************************************************
  51. void delay_ms(unsigned int us_count){                        //Funcion para delay_ms de micro-segundos
  52.    while(us_count!=0){                                       //Mientras que el contador es distinto de cero
  53.       delay_us(1000);                                        //Ejecuta funcion delay_ms micro segundos
  54.       us_count--;                                            //Decremento del valor de delay_ms
  55.    }
  56. }
  57. //*********************************************************************************************************
  58. // Funcion que escribe en puerto
  59. //*********************************************************************************************************
  60. void lcdPort(char a){                                        //Funcion para escribir el puerto en 4bit
  61.     if(a&1) D4=1;                                            //Evalua si a AND 0001, D4 a HIGH
  62.       else  D4=0;                                            //Caso contrario D4 a LOW
  63.     if(a&2) D5=1;                                            //Evalua si a AND 0010, D5 a HIGH
  64.       else  D5=0;                                            //Caso contrario D5 a LOW
  65.     if(a&4) D6=1;                                            //Evalua si a AND 0100, D6 a HIGH
  66.       else  D6=0;                                            //Caso contrario D6 a LOW
  67.     if(a&8) D7=1;                                            //Evalua si a AND 1000, D7 a HIGH
  68.       else  D7=0;                                            //Caso contrario D7 a LOW
  69.  }
  70.  //*********************************************************************************************************
  71.  // Funcion que envia comando
  72.  //*********************************************************************************************************
  73.  void lcdCmd(char a){                                        //Funcion para realizar comandos en LCD
  74.     RS=0;                                                    //Control RS a LOW
  75.     lcdPort(a);                                              //Llamado a lcdPort
  76.     EN=1;                                                    //Control EN a HIGH
  77.     delay_ms(5);                                             //Espera de 5ms
  78.     EN=0;                                                    //Control EN a LOW
  79.  }
  80.  //*********************************************************************************************************
  81.  // Borrado de LCD
  82.  //*********************************************************************************************************
  83.  lcdClear(){                                                 //Funcion para borrar el LCD
  84.     lcdCmd(0);                                               //Se envia comando LOW
  85.     lcdCmd(1);                                               //Se envia comando HIGH
  86.  }
  87.  //*********************************************************************************************************
  88.  // Funcion para ir a la posicion especifica
  89.  //*********************************************************************************************************
  90.  void lcdGotoxy(char b, char a){                             //Funcion para posicionar el cursor
  91.     char temp,z,y;                                           //Declaracion de variables
  92.     if(a==1){                                                //Si se encuentra en renglon 1
  93.       temp=0x80+b;                                           //Se incremena la columna
  94.        z=temp>>4;                                            //Se realiza el desplazamiento
  95.        y=temp&0x0F;                                          //Se aplica la mascara de bits
  96.        lcdCmd(z);                                            //Envia comandos
  97.        lcdCmd(y);                                            //Envia comandos
  98.     }else{                                                   //Si no esta en renglon 1
  99.        if(a==2){                                             //Si se encuentra en renglon 2
  100.           temp=0xC0+b;                                       //Se incrementa la columna
  101.           z=temp>>4;                                         //Se realiza el desplazamiento
  102.           y=temp&0x0F;                                       //Se realiza la mascara
  103.           lcdCmd(z);                                         //Envia comandos
  104.           lcdCmd(y);                                         //Envia comandos
  105.        }
  106.     }      
  107.  }
  108.  //*********************************************************************************************************
  109.  // Inicializa LCD
  110.  //*********************************************************************************************************
  111.  void lcdInit(){                                             //Funcion para inicializar el LCD
  112.     lcdPort(0x00);                                           //Se envia 0000 0000
  113.     delay_ms(200);                                           //Delay de 200ms
  114.     lcdCmd(0x03);                                            //Se envia 0000 0011
  115.     delay_ms(50);                                            //Delay de 50ms
  116.     lcdCmd(0x03);                                            //Se envia 0000 0011
  117.     delay_ms(110);                                           //Delay de 110ms
  118.     lcdCmd(0x03);                                            //Se envia 0000 0011
  119.     lcdCmd(0x02);                                            //Se envia 0000 0010
  120.     lcdCmd(0x02);                                            //Se envia 0000 0010
  121.     lcdCmd(0x08);                                            //Se envia 0000 1000
  122.     lcdCmd(0x00);                                            //Se envia 0000 0000
  123.     lcdCmd(0x0C);                                            //Se envia 0000 1100
  124.     lcdCmd(0x00);                                            //Se envia 0000 0000
  125.     lcdCmd(0x06);                                            //Se envia 0000 0110
  126.  }
  127.  //*********************************************************************************************************
  128.  // Funcion para escribir caracter
  129.  //*********************************************************************************************************
  130.  void lcdWriteChar(char a){                                  //Funcion para escribir un caracter
  131.     char temp,y;                                             //Declaracion de variables
  132.     temp=a&0x0F;                                             //Se realiza la mascara de bits 0000 1111
  133.     y=a&0xF0;                                                //Se realiza la mascara de bits 0000 1111
  134.     RS=1;                                                    //Control RS a HIGH
  135.     lcdPort(y>>4);                                           //Se desplaza 4 lugares a la derecha
  136.     EN=1;                                                    //Control EN a HIGH
  137.     delay_ms(5);                                             //Delay de 5ms
  138.     EN=0;                                                    //Control EN a LOW
  139.     lcdPort(temp);                                           //Se envia el valor
  140.     EN=1;                                                    //Control EN a HIGH
  141.     delay_ms(5);                                             //Delay de 5ms
  142.     EN=0;                                                    //Control EN a LOW
  143.  }
  144.  //*********************************************************************************************************
  145.  // Funcion para escribir string
  146.  //*********************************************************************************************************
  147.  void lcdWriteString(char *a){                               //Funcion para escribir string
  148.     int i;                                                   //Declaracion de variables
  149.     for(i=0;a[i]!='\0';i++)                                  //Iteracion de caracteres hasta el NULL
  150.        lcdWriteChar(a[i]);                                   //Se carga cada caracter para formar string
  151.  }
  152. //*********************************************************************************************************
  153. // Funcion ITOA para convertir entero en ascii
  154. //*********************************************************************************************************
  155. char *itoa(long int num, char *s){                           //Funcion ITOA (Entero to ASCII)
  156.    unsigned long int temp=1;                                 //Declaración de valor temporal
  157.    unsigned int i, cnt=0;                                    //Declaración de indices y contadores
  158.    char c;                                                   //Declaración de variable de carácter de salida
  159.    while(temp>0){                                            //Rutina de Conversión (Queda invertida)
  160.       temp=(num/10);                                         //Conversión de carácter a carácter
  161.       s[cnt]=(num%10)+'0';                                   //utilizando divisiones y resto
  162.       if(s[cnt]>0x39)                                        //sumando el offset de la tabla ASCII
  163.          s[cnt]+=0x7;
  164.       cnt++;
  165.       num=temp;
  166.    }
  167.    for(i=0;i<(int)(cnt/2);i++){                              //Rutina para invertir el numero convertido
  168.       c=s[i];                                                //Intercambio de variables
  169.       s[i]=s[cnt-i-1];
  170.       s[cnt-i-1]=c;
  171.    }
  172.    s[cnt]='\0';                                              //Carácter nulo, fin de la conversión ITOA
  173.    return s;                                                 //Retorno del valor ASCII
  174. }
  175. //*********************************************************************************************************
  176. // Funcion para inicializar el puerto serie 9600 @ 11.059MHz
  177. //*********************************************************************************************************
  178. void serialInit(void){                                       //Funcion para configurar UART
  179.     TMOD=0x20;                                               //Timer 1 en modo 2 - Auto recarga para generar Baudrate
  180.     SCON=0x50;                                               //Serial modo 1, 8bit de dato, 1bit de start, 1bit de stop
  181.     TH1=0xFD;                                                //Carga el baudrate en el timer a 9600bps
  182.     TR1=1;                                                   //Dispara el timer
  183.  }
  184.  //*********************************************************************************************************
  185.  // Función Interrupción UART que realiza el parse de datos, validación de Header y Checksum
  186.  // Si validación y Checksum son validos, carga el vector DATO para ser utilizado
  187.  //*********************************************************************************************************
  188.  char i=0;                                                   //Variable para el contador de bytes de entrada
  189.  void serial_ISR(void) interrupt 4{                          //Función de servicio de interrupción
  190.       if(RI==1){                                             //Si hay dato pendiente en UART
  191.        payload[i++]=SBUF;                                    //Guarda byte de entrada en payload. incrementa indice
  192.        RI=0;                                                 //Pone a cero el flag
  193.     }                                      
  194.     if(i>5){                                                 //Si el indice es mayor que 5 se asume que se completa el payload
  195.        if(payload[0]==HEADER){                               //Validación que el Header sea 200 (seteado en el transmisor)
  196.           if(payload[1]+payload[2]+payload[3]-payload[4]==0){//Validación de checksum, si datos leídos son igual a checksum
  197.              datoExt[0]=payload[1];                          //Cargamos los datos en el vector
  198.              datoExt[1]=payload[2];                          //Cargamos los datos en el vector
  199.              datoExt[2]=payload[3];                          //Cargamos los datos en el vector
  200.           }
  201.        }
  202.        i=0;                                                  //Una vez que se completan los 5 bytes, se reinicia el contador
  203.     }    
  204.     RI=0;                                                    //Pone a cero el flag
  205.  }
  206. //*********************************************************************************************************
  207. // Trama DHT11 - Segun Datasheet
  208. // ____             ____      ____                                       ___
  209. //     |___________|    |____|    |.....................................|
  210. //     |   18ms    |    |80us|80us|               5x8 bit               |
  211. //     |    PIC    |    |                  DHT11 respuesta              | Fin de
  212. //     |  request  |    |  2x80us, intRH, decRH, intT, decT, checksum   | Trama
  213. // ____          ________
  214. //     |________|        |...                        0 bit
  215. //      <-50us-> <-27us->
  216. // ____          _________________________
  217. //     |________|                         |...       1 bit
  218. //      <-50us-> <---------70us---------->
  219. //*********************************************************************************************************
  220. unsigned int trama[5];                                       //Vector donde se alojan los datos
  221. //*********************************************************************************************************
  222. // Funcion de recepcio de Byte
  223. // Lee el valor leido en la trama y lo separa realizando shift
  224. // Retorna el valor en forma de byte, es utilizado en la funcion recibeDato()
  225. //*********************************************************************************************************
  226. unsigned int recibeByte(){                                   //Funcion que recibe un Byte
  227.    unsigned int valorLeido = 0;                              //Valor de retorno de la funcion
  228.    int i=0;                                                  //Inicializacion del indice
  229.    for(i=0; i<8; i++){                                       //Iteracion para recepcion de bits
  230.       valorLeido <<= 1;                                      //Registro de desplazamiento de bits
  231.       while(DATA==0);                                        //Espera a DATA = 0
  232.       delay_us(30);                                          //Demora de 30us (Del Datasheet)
  233.       if(DATA==1){                                           //Pregunta si DATA = 1
  234.           valorLeido |= 1;                                   //Realiza toggle del valor leido
  235.       }
  236.       while(DATA==1);                                        //Espera a DATA = 1
  237.    }
  238.    return valorLeido;                                        //Retorna el valor leido
  239. }
  240. //*********************************************************************************************************
  241. // Funcion de recepcion de dato para el DHT11
  242. // Recive los valores de temperatura y humedad (parte entera y decimales por separado)
  243. // Recive el checksum enviado por el DHT11 y lo compara con el leido en el programa
  244. //*********************************************************************************************************
  245. unsigned int recibeDato(){                                   //Funcion que recibe el Dato
  246.    int validacion = 0;                                       //Variable de Validacion
  247.    int checksum = 0;                                         //Variable de deteccion de cambios de secuencia
  248.    int j=0;                                                  //Variable para el lazo for
  249.    DATA = 1;                                                 //Set DATA = 1  
  250.    DATA = 0;                                                 //Set DATA = 0
  251.    delay_ms(18);                                             //Demora de 18ms (Del Datasheet)
  252.    DATA = 1;                                                 //Set DATA = 1
  253.    delay_us(25);                                             //Demora de 25ms (Del Datasheet)
  254.    validacion = DATA;                                        //Mueve valor de DATA a Validacion
  255.    delay_us(80);                                             //Espera 80us (Del Datasheet)
  256.    validacion = DATA;                                        //Mueve valor de DATA a Validacion
  257.    if(!validacion){                                          //Si Validacion = 0, Error de secuencia
  258.       printf( "Error en Checksum \r");                       //Muestra leyenda de error
  259.    }
  260.    delay_us(80);                                             //Espera 80us (Del Datasheet)
  261.    for(j=0; j<5; j++){                                       //Lazo de carga de bytes de datos
  262.        trama[j] = recibeByte();                              //Carga del vector de datos
  263.    }
  264.    DATA = 1;                                                 //Set DATA = 1
  265.    for(j=0; j<4; j++){                                       //Lazo de carga de bytes de verificacion
  266.        checksum += trama[j];                                 //Carga de bytes de verificacion
  267.    }
  268.    if(checksum == trama[4]){                                 //Si la secuencia de verificacion es correcta
  269.       return 0;                                              //Se retorna 0 y se realiza la lectura
  270.    }
  271. }
  272. //*********************************************************************************************************
  273. // Lee DHT11
  274. //*********************************************************************************************************
  275. void leeDHT11(void){                                         //Funcion que lee el DHT11
  276.    if(recibeDato()==0){                                      //Consulta si hay dato en la entrada del DHT11
  277.       datoInt[0]=trama[2];                                   //Carga el valor de temperatura DHT en byte 1 del payload
  278.       datoInt[1]=trama[0];                                   //Carga el valor de humedad DHT en byte 2 del payload
  279.    }
  280. }
  281. //*********************************************************************************************************
  282. // Saludo de Pantalla
  283. //*********************************************************************************************************
  284. void saludoPantalla(void){                                   //Funcion que realiza un saludo inicial
  285.    lcdGotoxy(1,1);                                           //Posiciona el cursor en la pantalla
  286.    lcdWriteString(" Est.Inalambrica");                       //Imprime mensaje renglon 1
  287.    lcdGotoxy(1,2);                                           //Posiciona el cursor en la pantalla
  288.    lcdWriteString(" v1.1  UTN INSPT");                       //Imprime mensaje renglon 2
  289.    delay_ms(2000);                                           //delay_ms de saludo
  290.    lcdInit();                                                //Inicializa LCD
  291.    lcdClear();                                               //Borra LCD
  292. }
  293. //*********************************************************************************************************
  294. // Impresion de Pantalla
  295. //*********************************************************************************************************
  296. void impPantalla(void){                                      //Funcion que imprime pantalla
  297.    char string[4];                                           //Declaración de vector para mostrar en LCD
  298.    lcdGotoxy(1,2);                                           //Posiciona el cursor en la pantalla
  299.    itoa(datoExt[0],string);                                  //Funcion que convierte entero en ascii
  300.    lcdWriteString(string);                                   //Muestra en el LCD
  301.    lcdGotoxy(3,2);                                           //Posiciona el cursor en la pantalla
  302.    lcdWriteString(0xDF);                                     //Imprime unidad de medida
  303.    lcdGotoxy(4,2);                                           //Posiciona el cursor en la pantalla
  304.    lcdWriteString("C");                                      //Imprime unidad de medida
  305.    lcdGotoxy(6,2);                                           //Posiciona el cursor en la pantalla
  306.    itoa(datoExt[1],string);                                  //Funcion que convierte entero en ascii
  307.    lcdWriteString(string);                                   //Muestra en el LCD
  308.    lcdGotoxy(8,2);                                           //Posiciona el cursor en la pantalla
  309.    lcdWriteString("%RH");                                    //Imprime unidad de medida
  310.    lcdGotoxy(12,2);                                          //Posiciona el cursor en la pantalla
  311.    itoa(datoExt[2],string);                                  //Funcion que convierte entero en ascii
  312.    lcdWriteString(string);                                   //Muestra en el LCD
  313.    lcdGotoxy(15,2);                                          //Posiciona el cursor en la pantalla
  314.    lcdWriteString("L");                                      //Imprime unidad de medida
  315.    lcdGotoxy(3,1);                                           //Posiciona el cursor en la pantalla
  316.    itoa(datoInt[0],string);                                  //Funcion que convierte entero en ascii
  317.    lcdWriteString(string);                                   //Muestra en el LCD
  318.    lcdGotoxy(5,1);                                           //Posiciona el cursor en la pantalla
  319.    lcdWriteString(0xDF);                                     //Imprime unidad de medida
  320.    lcdGotoxy(6,1);                                           //Posiciona el cursor en la pantalla
  321.    lcdWriteString("C");                                      //Imprime unidad de medida
  322.    lcdGotoxy(10,1);                                          //Posiciona el cursor en la pantalla
  323.    itoa(datoInt[1],string);                                  //Funcion que convierte entero en ascii
  324.    lcdWriteString(string);                                   //Muestra en el LCD
  325.    lcdGotoxy(12,1);                                          //Posiciona el cursor en la pantalla
  326.    lcdWriteString("%RH");                                    //Imprime unidad de medida
  327. }
  328. //*********************************************************************************************************
  329. // Programa principal, Realiza la lectura de DHT11, lectura de bateria y recibe los datos por UART
  330. // Lee la temperatura y humedad interna, realiza un pronóstico aproximado
  331. //*********************************************************************************************************
  332. void main(){                                                 //Funcion principal
  333.    saludoPantalla();                                         //Función de saludo de pantalla
  334.    P1=0x00;                                                  //Usado para aplicacion
  335.    P3=0x03;                                                  //Usado para el serie
  336.    serialInit();                                             //Inicializa puerto serie
  337.    EA=1;                                                     //Habilitacion de interrupcion Global
  338.    ES=1;                                                     //Habilitacion de interrupcion Serie
  339.    while(1){                                                 //Loop principal infinito
  340.       leeDHT11();                                            //Funcion que lee DHT11
  341.       delay_ms(2000);                                        //delay_ms de Actualizacion
  342.       impPantalla();                                         //Imprime pantalla LCD
  343.       delay_ms(2000);                                        //delay_ms de Actualizacion
  344.    }
  345. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement