Olá galera, sou novo aqui no fórum e tenho pouca experiência com programação em C.
Estou com dificuldades de corrigir alguns erros ao compilar no mikroC.
Vou postar aqui embaixo meu programa e os erros, se alguém puder me ajudar por gentileza, eu agradeço, desde já 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