Ir ao conteúdo
  • Cadastre-se

Valmir R Gregio

Membro Júnior
  • Posts

    1
  • Cadastrado em

  • Última visita

Reputação

0
  1. Olá galera, sou novo aqui no fórum e tenho pouca experiência com programação em C. Estou com dificuldades pois ao compilar meu programa no mikroc aparecem vários erros e não consigo simular o circuito no proteus. Vou postar aqui embaixo o programa e anexo os erros, se alguém puder me ajudar por gentileza. Desde já meu muito obrigado! // Controlador de temperatura PID para forno industrial // Microcontrolador: PIC 18F4520 / Clock: 4MHz / Ciclo de máquina: 1us // Linguagem de programação: C / Software Compilador: Mikroc pro for pic // Ligação entre o Pic e o display LCD 16x2 sbit LCD_RS at RD2_bit; // pino RD2 (21) pic envia dados para pino RS (4) do display LCD sbit LCD_EN at RD3_bit; // pino RD3 (22) pic envia dados para pino Enable (6) do display LCD sbit LCD_D4 at RD4_bit; // pino RD4 (27) pic envia dados para pino D4 (11) do display LCD sbit LCD_D5 at RD5_bit; // pino RD5 (28) pic envia dados para pino D5 (12) do display LCD sbit LCD_D6 at RD6_bit; // pino RD6 (29) pic envia dados para pino D6 (13) do display LCD sbit LCD_D7 at RD7_bit; // pino RD7 (30) pic envia dados para pino D7 (14) do display LCD sbit LCD_RS_Direction at TRISD2_bit; // define pino RD2 (21) pic como saída para pino RS (4) do display LCD sbit LCD_EN_Direction at TRISD3_bit; // define pino RD3 (22) pic como saída para pino Enable (6) do display LCD sbit LCD_D4_Direction at TRISD4_bit; // define pino RD4 (27) pic como saída para pino D4 (11) do display LCD sbit LCD_D5_Direction at TRISD5_bit; // define pino RD5 (28) pic como saída para pino D5 (12) do display LCD sbit LCD_D6_Direction at TRISD6_bit; // define pino RD6 (29) pic como saída para pino D6 (13) do display LCD sbit LCD_D7_Direction at TRISD7_bit; // define pino RD7 (30) pic como saída para pino D7 (14) do display LCD // Função dos três botões #define menos RB4_bit //Botão para decremento #define mais RB3_bit //Botão para incremento #define set RB2_bit //Botão para trocar menu // Definição das flags e constantes #define nTela 3 //número de telas para o sistema de menus #define flag_menos flags.B0 //flag de controle do botão de decremento #define flag_mais flags.B1 //flag de controle do botão de incremento #define lcd_clr flags.B2 //flag de controle de limpeza do LCD #define flag_set flags.B3 //flag para trocar menu #define temp_atual_prog flags.B4 //flag de seleção entre temperatura atual, temperatura programada e o tempo de ensaio #define Led RB5_bit //Led indicativo set point (valor desejado) // Funções principais void read_buts(); //Função para leitura dos botões void clear_LCD(); //Função para limpeza inteligente do display void menu1(); //Função para o menu1 void menu2(); //Função para o menu2 void menu3(); //Função para o menu3 void celsius(); //Converte tensão analógica em graus Celsius void atual_prog(); //Função para exibir a temperatura atual e programada void CustomChar(char pos_row, char pos_char); //Gera caractere especial para o LCD void segundos(); //Função para exibir contagem de segundos void pid_control(); //Controle PID void disp_value(); //Função para exibir valores no LCD void timeBase(); //Função para a base de tempo // Principais Variáveis float celsius; // declarada variável celsius int voltage; // declarada variável voltage unsigned short flags = 0x00, //registrador auxiliar de flags screen = 0x01, //armazena número da tela atual do menu counterT0 = 0x00, //contador auxiliar para o timer 0 counterTs = 0x00; //contador auxiliar para exibir temperaturas atual e programada int result_ADC = 0x00; //armazena valor do ADC unsigned long count_secs = 0x00; //variável para contagem de segundos float temperature = 0.0, //Armazena a temperatura em graus Celsius temp_atual = 100.0, //Armazena a temperatura programada temp_prog = 0.0, //Armazena a temperatura atual char txt[15], //String para texto txt2[15], //String para texto txt3[15], //String para texto pulsos_txt[12], //String para texto secs_txt[12]; //String para texto const char character[] = {6,9,6,0,0,0,0,0}; //Matriz para caractere especial de graus em LCD double error_meas, // varíavel para erro de medição (valor programado - valor atual) kp = 1.5, // Constante proporcional ki = 0.1, // Constante integral kd = 0.1, // Constante derivativo proportional, // Função proporcional (constante kp * erro) integral, // Função integral (constante ki * somatório do erro) derivative, // Função derivativo (constante kd * derivada do erro pelo tempo) PID, // Somatório das funções proporcional integral derivativo ideal_value = 512.0; // Valor Set Point desejado int measure, // Medição lastMeasure, // Última medição TO_baseTime =0x00, // baseTime igual a zero pwm = 128; // Inicia o PWM (modulação por largura de pulso) com 50% duty cicle // Interrupções void interrupt() { if(INT0IF_bit) //Houve interrupção externa 0? { //Sim... INT0IF_bit = 0x00; //Limpa flag TMR0 = 0x06; T0_baseTime += 0x01; }//end TMR0IF_bit } //end interrupt // Interrupção do Timer 0 // Base de tempo de 1 segundo if(TMR0IF_bit) //Houve overflow do Timer 0? { //Sim... TMR0IF_bit = 0x00; //Limpa flag TMR0L = 0xB0; //Reinicia byte menos significativo do Timer 0 TMR0H = 0x3C; //Reinicia byte mais significativo do Timer 0 counterT0++; //Incrementa contador auxiliar if(counterT0 == 20) //counter igual a 20? { //Sim... counterT0 = 0x00; //Reinicia counterT0 counterTs++; //incrementa counterTs count_secs++; //incrementa segundos if(counterTs == 0x03) //counterTs igual a 3? { //Sim, passaram-se 3 segundos counterTs = 0x00; //reinicia counterTs temp_atual_prog = ~temp_atual_prog; //inverte estado da flag temp_atual_prog } //end if counterTs } //end if counterT0 }//end if TMR0IF }//end interrupt // Programa principal void main() { CMCON = 0x07; // ADCON0 = 0x01; //Liga conversor AD ADCON1 = 0x0C; //Configura os pinos do PORTB como digitais, e RA0, RA1, RA2 como analógicos ADCON2 = 0b00011000; // Configura a fonte de clock e a taxa de aquisição TRISB = 0x7F; //RB7 configurados como saída TRISD = 0x03; //Configura PORTD como saída, exceto RD0 e RD1 PORTB = 0x7F; //Inicializa PORTB INTCON = 0xF0; //Habilita interrupção global, timer 0 e externa 0 INTEDG0_bit = 0x01; //Configura interrupção externa 0 por borda de subida TMR0ON_bit = 0x01; //bit 7: Liga o Timer 0 T08BIT_bit = 0x00; //bit 6: Habilita o modo de 16 bits para o Timer 0 T0CS_bit = 0x00; //bit 5: Timer 0 incrementa com o ciclo de máquina PSA_bit = 0x01; //bit 3: Timer 0 sem prescaler (1:1) TMR0L = 0x3C; //byte menos significativo TMR0H = 0xB0; //byte mais significativo OPTION_REG = 0x83; //desabilita o resistor de pull-up e define prescaler 1:16 INTCON = 0xA0; //160 TMR0 = 0x06; //timer 0=6 PWM1_Init(1000); //frequência pwm em 1kHz PWM1_Start(); // inicio pwm PWM1_Set_Duty(pwm); //dutt cicle conforme variável pwm Lcd_Init(); //Inicia módulo LCD Lcd_Cmd(_LCD_CLEAR); //Limpa display Lcd_Cmd(_LCD_CURSOR_OFF); //Apaga cursor while(1) //Loop infinito { measure = ADC_Read(0); PWM1_Set_Duty(pwm); if(T0_baseTime == 1000) //baseTime é 1s ? { //sim... T0_baseTime = 0x00; //zera a basetime RC0_bit = ~RC0_bit; //inverte variável RCO_bit pid_control(); //chama função controle PID read_buts(); //Chama função para leitura dos botões switch(screen) //chaveia entre menus { case 0x01: menu1(); break; //caso 1, menu 1 case 0x02: menu2(); break; //caso 2, menu 2 case 0x03: menu3(); break; //caso 3, menu 3 } //end switch screen } // end while } // end main // Controle PID void pid_control() //chama função PID { measure = temperature; //atualiza variável temperature = medição error_meas = ideal_value - measure; //erro= set point - medição proportional = error_meas * kp; //proporcional = erro * constante kp integral += (error_meas * ki); //integral = somatório erro * constante ki derivative = ((lastMeasure - measure) * kd); //derivativo = diferença erro * constante kd lastMeasure = measure; //ultima medição = medição PID = proportional + integral + derivative; //PID = somatório das três funções PID = PID/4; //10 bits conversor AD pwm = PID + 128; //Duty cicle = 50% if(pwm == 256) pwm = 255; // se valor for maior que 255, variável = 255 } //end pid_control void timeBase() //Função para a base de tempo { //base de tempo de 100ms (4 x 25ms) if(baseT1 == 4) //baseT1 igual a 4? { //sim... baseT1 = 0x00; //reinicia pid_control(); // função controle PID } //end if baseT1 } //end timeBase void read_buts() //Função para leitura dos botões { if(!menos) flag_menos = 0x01; //seta flag_menos, se botão pressionado if(!mais) flag_mais = 0x01; //seta flag_mais, se botão pressionado if(!set) flag_set = 0x01; //seta flag_set, se botão pressionado if(menos && flag_menos) //botão menos solto e flag setada? { //sim... flag_menos = 0x00; //limpa flag screen--; //decrementa screen } //end if menos solto if(mais && flag_mais) //botão mais solto e flag setada? { //sim... flag_mais = 0x00; //limpa flag screen++; //incrementa screen } //end if mais solto if(set && flag_set) //botão set solto e flag setada? { //sim... flag_set = 0x00; //limpa flag lcd_clr = 0x01; //seta flag indicando mudança de menu } //end if set solto } //end read_but void clear_LCD() //Função para limpeza inteligente do display { if(lcd_clr) //lcd_clr setada? { //sim... Lcd_Cmd(_LCD_CLEAR); //limpa display lcd_clr = 0x00; //limpa flag para invalidar laço } //end if lcd_clr } //end clear_LCD void menu1() //Função para exibir temperatura atual { clear_LCD(); Lcd_Chr(1,1,'T'); Lcd_Chr_Cp ('E'); Lcd_Chr_Cp ('M'); Lcd_Chr_Cp ('P'); Lcd_Chr_Cp ('E'); Lcd_Chr_Cp ('R'); Lcd_Chr_Cp ('A'); Lcd_Chr_Cp ('T'); Lcd_Chr_Cp ('U'); Lcd_Chr_Cp ('R'); Lcd_Chr_Cp ('A'); Lcd_Chr_Cp (' '); Lcd_Chr(2,1,'A'); Lcd_Chr_Cp ('T'); Lcd_Chr_Cp ('U'); Lcd_Chr_Cp ('A'); Lcd_Chr_Cp ('L'); Lcd_Chr_Cp (':'); celsius(); } //end menu1 void menu2() //Função para exibir temperatura programada { clear_LCD(); Lcd_Chr(1,1,'T'); Lcd_Chr_Cp ('E'); Lcd_Chr_Cp ('M'); Lcd_Chr_Cp ('P'); Lcd_Chr_Cp ('E'); Lcd_Chr_Cp ('R'); Lcd_Chr_Cp ('A'); Lcd_Chr_Cp ('T'); Lcd_Chr_Cp ('U'); Lcd_Chr_Cp ('R'); Lcd_Chr_Cp ('A'); Lcd_Chr_Cp (' '); Lcd_Chr(2,1,'P'); Lcd_Chr_Cp ('R'); Lcd_Chr_Cp ('O'); Lcd_Chr_Cp ('G'); Lcd_Chr_Cp (':'); celsius(); } //end menu2 void menu3() //Função para exibir contagem de tempo { clear_LCD(); Lcd_Chr(1,1,'T'); Lcd_Chr_Cp ('E'); Lcd_Chr_Cp ('M'); Lcd_Chr_Cp ('P'); Lcd_Chr_Cp ('O'); Lcd_Chr_Cp (' '); Lcd_Chr_Cp ('E'); Lcd_Chr_Cp ('N'); Lcd_Chr_Cp ('S'); Lcd_Chr_Cp ('A'); Lcd_Chr_Cp ('I'); Lcd_Chr_Cp ('O'); Lcd_Chr_Cp (':'); segundos(); } //end menu3 void celsius() //Cálculo da temperatura em Celsius { voltage=(5 * result_ADC); // Vref= 5V celsius=(-8.072 + 0.099 * voltage); // cálculo da temperatura temperature = celsius; //atualiza temperatura atual FloatToStr(temperature, txt); //Converte float em string Lcd_Chr(2,7,txt[0]); //Imprime no LCD posição 0 da string txt Lcd_Chr_Cp (txt[1]); //Imprime no LCD posição 1 da string txt Lcd_Chr_Cp (txt[2]); //Imprime no LCD posição 2 da string txt Lcd_Chr_Cp (txt[3]); //Imprime no LCD posição 3 da string txt Lcd_Chr_Cp (txt[4]); //Imprime no LCD posição 4 da string txt CustomChar(2,12); //Imprime no LCD caractere especial º Lcd_Chr(2,13, 'C'); //Imprime no LCD } //end if if(temperature > temp_prog) temp_prog = temperature; else temp_prog = temp_prog; if(temperature < temp_atual) temp_atual = temperature; else temp_atual = temp_atual; if (temp_prog == temp_atual) PORTB.RB5 = 0X01; //acende o led caso set point seja alcançado else PORTB.RB5= 0X00; //senão led fica apagado } //end celsius void atual_prog() //Função para exibir a temperatura atual e programada { if(temp_atual_prog) //flag temp_atul_prog setada? { //sim... FloatToStr(temp_atual, txt2); //Converte float em string Lcd_Chr(2,7,txt2[0]); //Imprime no LCD posição 0 da string txt2 Lcd_Chr_Cp (txt2[1]); //Imprime no LCD posição 1 da string txt2 Lcd_Chr_Cp (txt2[2]); //Imprime no LCD posição 2 da string txt2 Lcd_Chr_Cp (txt2[3]); //Imprime no LCD posição 3 da string txt2 Lcd_Chr_Cp (txt2[4]); //Imprime no LCD posição 4 da string txt2 CustomChar(2,12); //Imprime no LCD caractere especial Lcd_Chr(2,13, 'C'); //Imprime no LCD } //end if temp_atual_prog else //senão { //flag temp_atual_prog limpa FloatToStr(temp_prog, txt3); //Converte float em string Lcd_Chr(2,7,txt3[0]); //Imprime no LCD posição 0 da string txt3 Lcd_Chr_Cp (txt3[1]); //Imprime no LCD posição 1 da string txt3 Lcd_Chr_Cp (txt3[2]); //Imprime no LCD posição 2 da string txt3 Lcd_Chr_Cp (txt3[3]); //Imprime no LCD posição 3 da string txt3 Lcd_Chr_Cp (txt3[4]); //Imprime no LCD posição 4 da string txt3 CustomChar(2,12); //Imprime no LCD caractere especial Lcd_Chr(2,13, 'C'); //Imprime no LCD } //end else } //end atual_prog void CustomChar(char pos_row, char pos_char) //gera o caracter especial grau { char i; Lcd_Cmd(72); for (i = 0; i<=7; i++) Lcd_Chr_CP(character); Lcd_Cmd(_LCD_RETURN_HOME); Lcd_Chr(pos_row, pos_char, 1); } //end CustomChar void segundos() //Função para exibir contagem de segundos { LongToStr(count_secs, secs_txt); //converte count_secs em string Lcd_Out(2,2,secs_txt); //imprime no LCD Lcd_Out_Cp(" seg"); } //end pulsos

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!