1: /****************************************************************************** 2: * Objetivo: Este projeto visa monitorar uma tensão de um sensor e mostrar * 3: * e após a conversão necessária da escala de Fluxo mostra seu valor em um * 4: * display de LCD. * 5: * A finalidade deste programa é ser utilizado como um Fluxometro * 6: * * 7: * Compilador: CCS Versão 4.125 * 8: * * 9: * Atuor: Leandro R. Alves * 10: *******************************************************************************/ 11: #include < 16f876a. h > //Define o Dispositivo a ser utilizado 12: #device adc = 10 //Configura o compilador para conversor A/D de 10 bits 13: #use delay ( clock = 4000000 ) //Cristal 14: #fuses HS, NOWDT, PUT, PROTECT, BROWNOUT, NOLVP, NOWRT 15: #include < regs_16f87x. h > 16: #include < MATH. h > //biblioteca de funcóes matemáticas 17: #include < stdio. h > //biblioteca para manipulação com matrizes 18: 19: #define lcd_enable pin_a5 // pino enable do LCD 20: #define lcd_rs pin_a1 // pino rs do LCD 21: //#define lcd_rw pin_a3 // pino rw do LCD 22: #define lcd_d4 pin_b4 // pino de dados d4 do LCD 23: #define lcd_d5 pin_b5 // pino de dados d5 do LCD 24: #define lcd_d6 pin_b6 // pino de dados d6 do LCD 25: #define lcd_d7 pin_b7 // pino de dados d7 do LCD 26: 27: /****************************************************************************** 28: * definição dos port s de I/O * 29: /******************************************************************************/ 30: #use fast_io ( a ) // Para inicialização ra pida dos port s 31: #use fast_io ( b ) 32: #use fast_io ( c ) 33: 34: #byte porta = 0x05 35: #byte portb = 0x06 36: #byte portc = 0x07 37: 38: /********************************************************************** 39: * Envio de NIBBLE para o lcd 40: * 41: **********************************************************************/ 42: 43: void lcd_envia_nibble ( int dado ) 44: // envia um dado de quatro bits para o display 45: //Carrega as vias de dados (pnos) do lcd de acordo com o nibble lido 46: { 47: // coloca os quatro bits nas saidas 48: output_bit ( lcd_d4, bit_test ( dado, 0 )); 49: output_bit ( lcd_d5, bit_test ( dado, 1 )); 50: output_bit ( lcd_d6, bit_test ( dado, 2 )); 51: output_bit ( lcd_d7, bit_test ( dado, 3 )); 52: 53: // dá um pulso na linha enable 54: output_high ( lcd_enable ); //enable = 1 55: delay_us ( 2 ); 56: output_low ( lcd_enable ); //enable = 0 57: 58: return ; // retorna ao ponto de chamada da função 59: } 60: 61: 62: /*********************************************************************** 63: * Envio de um byte para o lcd 64: * 65: ************************************************************************/ 66: //Esta rotina irá enviar um byte ou um comando para o lcd conforme abaixo: 67: // endereco = 0 => a variavel dado será uma instrução 68: // endereco = 0 => a variavel dado será um caracter 1
69: 70: void lcd_envia_byte ( boolean endereco, int dado ) 71: { 72: 73: // aguarda o display ficar desocupado 74: //while ( bit_test(lcd_le_byte(),7) ) ; 75: // configura a linha rs dependendo do modo selecionado 76: output_bit ( lcd_rs, endereco ); // seta o bit rs para instrução ou caracter 77: delay_us ( 100 ); // aguarda 100 us 78: 79: //delay_cycles(1); 80: //output_low(lcd_rw); 81: // desativa linha enable 82: output_low ( lcd_enable ); // desativa a linha de enable 83: lcd_envia_nibble ( dado >> 4 ); // envia a primeira parte do byte 84: lcd_envia_nibble ( dado & 0x0f ); // limpa a primeira parte e envia a segunda 85: 86: delay_us ( 40 ); 87: return ; 88: } 89: 90: /*************************************************************************** 91: * Envio de caracter para o display 92: * 93: ***************************************************************************/ 94: 95: 96: void lcd_escreve ( char c ) 97: // envia caractere para o display 98: { 99: 100: lcd_envia_byte ( 1, c ); 101: } 102: 103: /************************************************************************ 104: * função para limpar o lcd 105: * 106: ************************************************************************/ 107: // como esta função pode vir a ser muito utilizada, transformando-a numa 108: // função deixa o código HEX menor 109: 110: void limpa_lcd () 111: { 112: lcd_envia_byte ( 0, 0x01 ); // envia a instrução para limpar o lcd 113: delay_us ( 10 );//2ms 16/04/10 114: return ; 115: } 116: 117: 118: /**************************************************************************** 119: * Inicialização do display 120: * 121: ****************************************************************************/ 122: 123: 124: void lcd_ini () 125: // rotina de inicialização do display 126: { 127: output_low ( lcd_d4 ); //garante que o pino d4 está em 0 128: output_low ( lcd_d5 ); //garante que o pino d5 está em 0 129: output_low ( lcd_d6 ); //garante que o pino d6 está em 0 130: output_low ( lcd_d7 ); //garante que o pino d7 está em 0 131: output_low ( lcd_rs ); //garante que o pino rs está em 0 132: //output_high(lcd_rw); 133: output_low ( lcd_enable ); //garante que o pino enable está em 0 134: delay_ms ( 10 );//15ms 16/04/10 135: 136: lcd_envia_nibble ( 0x03 ); // Envia comando para inicializar o display 2
137: delay_ms ( 5 ); // Aguarda 5ms para estabilizar o LCD 138: lcd_envia_nibble ( 0x03 ); // Envia comando para inicializar o display 139: delay_ms ( 5 ); // Aguarda 5ms para estabilizar o LCD 140: lcd_envia_nibble ( 0x03 ); // Envia comando para inicializar o display 141: delay_ms ( 5 ); // Aguarda 5ms para estabilizar o LCD 142: lcd_envia_nibble ( 0x02 ); // CURSOR HOME - Envia comando para zerar o 143: // contador de caracteres e retornar à posição 144: // inicial (0x80) 145: 146: delay_ms ( 1 ); // aguarda 1 ms 147: lcd_envia_byte ( 0, 0x28 ); // FUNCTION SET - Configura o LCD para 4 bits, 148: // 2 linhas, fonte 5X7 149: lcd_envia_byte ( 0, 0x0c ); // DISPLAY CONTROL - Display ligado, sem cursor 150: limpa_lcd (); // chama a função para limpar o lcd 151: lcd_envia_byte ( 0, 0x06 ); // ENTRY MODE SET - Desloca o cursor para a 152: // direita 153: delay_ms ( 1 ); 154: 155: return ; 156: 157: } 158: 159: 160: /****************************************************************************** 161: * Rotina Principal 162: * 163: *******************************************************************************/ 164: main () 165: { 166: long int valor, parcial_1, parcial_2 ; 167: float resultado, resp, med_1, med_2, med_3, med_4, med_5, med_6, med_7, med_8 ; 168: int i, media ; 169: int32 matriz_ad [] = { 176, 217, 247, 313, 368, 418, 460, 500, 530, 568, 592, 170: 625, 675, 711, 753, 777, 806, 841, 855 }; 171: int32 matriz_f [] = { 0, 30, 51, 101, 150, 200, 250, 300, 350, 401, 450, 172: 500, 603, 702, 801, 901, 1002, 1200, 1300 }; 173: int32 display ; 174: 175: porta = 0 ; 176: portb = 0 ; 177: portc = 0 ; 178: 179: // configura os tris 180: set_tris_a ( 0b11010101 ); // configuração da direção dos pinos de I/O 181: set_tris_b ( 0b00001111 ); 182: set_tris_c ( 0b11111111 ); 183: 184: 185: 186: limpa_lcd (); 187: lcd_ini (); 188: printf ( lcd_escreve," - JIG FLUXOMETRO - "); 189: 190: setup_adc_ports ( RA0_analog ); // RA0_RA1_RA3_analog 191: setup_adc ( ADC_CLOCK_INTERNAL ); 192: set_adc_channel ( 0 ); 193: 194: delay_ms ( 300 ); 195: delay_ms ( 300 ); 196: 197: limpa_lcd (); 198: lcd_ini (); 199: printf ( lcd_escreve," - # ELETROLOKOS # - "); 200: 201: delay_ms ( 300 ); 202: delay_ms ( 300 ); 203: 204: 3
205: while ( true ) 206: { 207: valor = read_adc (); // efetua a conversão A/D 208: // Se o valor é > 0,soma 1 ao valor 209: if ( valor ) 210: { 211: valor += 1 ; 212: } 213: //limpa_lcd();//lcd_escreve ('\f'); // apaga o display 214: 215: // calculo da curva de fluxo separada por intervalos entre os AD s 216: if ( valor <= 177 ) // fluxo = 0 217: { 218: limpa_lcd (); 219: printf ( lcd_escreve,"=> Fluxo = 0.0 l/min" ); 220: } 221: 222: else 223: { 224: for ( i = 0 ; i < sizeof ( matriz_ad )/ sizeof ( int ); i ++) 225: { 226: if ( valor < matriz_ad [ i ]) 227: { 228: // i--; 229: break ; 230: } 231: } 232: 233: parcial_1 = ((( matriz_f [ i ] - matriz_f [ i - 1 ])*( valor - matriz_ad [ i - 1 ])) 234: + ( matriz_f [ i - 1 ]*( matriz_ad [ i ] - matriz_ad [ i - 1 ]))); 235: parcial_2 = (( matriz_ad [ i ] - matriz_ad [ i - 1 ])* 10 ); 236: 237: resultado = (( float ) parcial_1 / parcial_2 ); 238: 239: media ++; 240: 241: if ( media == 1 ) 242: { 243: med_1 = resultado ; 244: } 245: if ( media == 2 ) 246: { 247: med_2 = resultado ; 248: } 249: if ( media == 3 ) 250: { 251: med_3 = resultado ; 252: } 253: if ( media == 4 ) 254: { 255: med_4 = resultado ; 256: } 257: if ( media == 5 ) 258: { 259: med_5 = resultado ; 260: } 261: if ( media == 6 ) 262: { 263: med_6 = resultado ; 264: } 265: if ( media == 7 ) 266: { 267: med_7 = resultado ; 268: } 269: if ( media == 8 ) 270: { 271: med_8 = resultado ; 272: } 4
273: if ( media == 9 ) 274: { 275: resp = (( med_1 + med_2 + med_3 + med_4 + med_5 + med_6 + med_7 + med_8 ) 276: media = 0 ; 277: } 278: 279: display ++; 280: if ( display = 4000000 ) 281: { 282: limpa_lcd ();//lcd_escreve ('\f'); // apaga o display 283: printf ( lcd_escreve,"=> Fluxo = %3.1f0 l/min", resp ); 284: 285: lcd_envia_byte ( 0, 0xc0 ); // vai para primeira colun 286: 287: printf ( lcd_escreve,"ad %lu", valor ); 288: display = 0 ; 289: delay_ms ( 175 ); 290: } 291: 292: } 293: 294: } 295: } 296: 297: 298: 299: 5