Me da los siguientes errores a la hora de compilar :
Executing: "C:\Program Files\PICC\Ccsc.exe" "main.c" +FM +DF +LN +T -A +M +Z +Y=9 +EA
*** Error 51 "C:\Users\Pacote\Desktop\Nueva carpeta (2)\funciones.c" Line 126(0,1): A numeric expression must appear here
*** Error 117 "C:\Users\Pacote\Desktop\Nueva carpeta (2)\funciones.c" Line 194(1,2): Improper use of a function identifier
*** Error 117 "main.c" Line 92(1,2): Improper use of a function identifier
*** Error 12 "main.c" Line 192(12,13): Undefined identifier -- change_duty
*** Error 79 "main.c" Line 214(0,1): Expect }
5 Errors, 0 Warnings.
Aquí les dejo los códigos del main y funciones.
#include "16F877A.h"
#device adc=10
#use delay (clock=4000000)
#use I2C (MASTER,SDA=PIN_C4,SCL=PIN_C3,FORCE_HW)
#fuses XT,NOWDT,NOPROTECT,NOLVP,BROWNOUT,NOLVP,NOCPD,NOWRT
#use fast_io(all)
//////////////////////////////////////
////// DEFINICION DE PUERTOS ///////
////// Y PATAS //////
//////////////////////////////////////
#byte PORTA=0x05 #byte PORTB=0x06
#byte TRISA=0x85 #byte TRISB=0x86
#bit RA0=PORTA.0 #bit RB0=PORTB.0
#bit RB1=PORTB.1
#bit RB2=PORTB.2
#bit RB3=PORTB.3
#bit RB4=PORTB.4
#bit RB5=PORTB.5
#bit RB6=PORTB.6
#bit RB7=PORTB.7
//////////////////////////////////////
//////// VARIABLES GLOBALES ////////
//////////////////////////////////////
/* CONFIGURACION */
int1 config_t=0; // Variables para indicar que quiero ajustar alguno
int1 config_v=0; // correspondiente que me permite tal accion
// de los parametros y poder llamar a la funcion
int cont_dt=0; // Contadores, para la configuracion del de los distintos
int cont_dv=0; // parametros, que nos permitira saber cuando se termino
// de modificar las decenas y automaticamente se pasara a
// las unidades del valor correspondiente en el que
// estemos
/* TECLADO */
int fil,col; // Determinan la posición en el teclado
int paso; // Almacena el valor de PORTB
char tecla; // Guarda el valor de la tecla pulsada en el teclado
int pulsada; // Indica si se ha pulsado alguna tecla
char teclado[4][4]={{'T','V','N','E'}, // Asigno los valores y funciones de cada
{ 1, 2, 3, 'N'}, // fila y columna al teclado
{ 4, 5, 6, 'N'},
{ 7, 8, 9, 0}};
/* SENSOR */
int t_max=60; // Variable para la temperatura maxima admitida
int t_act; // Variable donde se guarda la temperatura actual
/* PWM */
int1 iniciado=0; // Variable para esperar a que todos los valores sean estables
// antes de empezar a utilizar el PWM
int16 carga; // carga=(Fosc*d)/(Prescaler*Fpwm) Vout=Ve por defecto
float v_in; // Variable para indicar el voltaje de entrada
float v_out=20.0; // Variable para poner el voltaje de salida deseado
float g_v_out; // Guarda el valor de v_out por si se necesitase
int change_d=0; // Variable que indica con que opcion tendremos que cambiar
// el duty. La primera vez que se inicia el programa debera
// hacerse segun la opcion 3
int actualizar_duty=1; // Variable para conseguir que el apagado del
// PWM sea progresivo
//////////////////////////////////////
///////////// LIBRERIAS ////////////
//////////////////////////////////////
#include "lcd.c"
#include "funciones.c"
//////////////////////////////////////
//////// CONFIGURACION PREVIA //////
//////////////////////////////////////
void configuracion(){
/* TEMPORIZADOR PARADA (TIMER1) */
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); // Reloj intero con preescaler 1
set_timer1(15536); // Para contar 0.05 seg
/* TECLADO */
PORTB=0; // Define RB<7:4> como entradas y RB<3:0> como
set_tris_b(0b11110000); // salidas por las que saca sendos 0s.
delay_cycles(4); // Espera para estabilizar el valor de PORTB.
port_b_pullups(TRUE); // Habilita resistencias de pull-up.
PORTB=PORTB; // Lee PORTB para preparar interrupciones.
/* CONVERSOR AD */
setup_adc_ports(AN0); // Pone AN0 como entrada analogica
setup_adc(ADC_CLOCK_INTERNAL); // Frecuencia de conversión interna
set_adc_channel(0); // Selecciona AN0<=>RA0
/* PWM */
g_v_out=v_out;
carga=((v_out-(4.0/1023.0*read_adc()+8.0))/v_out)*200.0; // Para saber la carga inicial
setup_timer_2 (T2_DIV_BY_1,49.5,1); // Señal PWM de 20kHz (@Fosc=4MHz)
setup_ccp2(CCP_PWM); // Genera PWM con el CCP2.
set_pwm2_duty(carga);
/* LCD */
lcd_init(); // Inicializar pantalla LCD
/* GENERAL */
enable_interrupts(INT_RB); // Habilita interrupciones del PORTB
enable_interrupts(GLOBAL); // Habilita interrupciones
/* CONFIGURACION DE VALORES */
ponertmax();
delay_ms(200);
ponervoltaje();
delay_ms(200);
enable_interrupts(int_timer1); // Habilita la interrupcion del T1
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// PROGRAMA PRINCIPAL //
/////////////////////////////////////////////////////////////////////////////////////////////////
void main(){
configuracion();
while(TRUE){
v_in=4.0/1023.0*read_adc()+8;
// Llamo a las funciones desde el programa principal para evitar llenar la memoria poniendolas
// en las interrupciones o dentro de otras funciones. Como el tiempo de ejecucion no necesito
// que sea instantaneo no importa que este chequeando continuamente si se tiene que ejecutar la
// funcion que corresponda.
/* MUESTRA LA TEMP ACTUAL Y LA TENSION DE SALIDA ESCOGIDA */
lcd_gotoxy(1,1);
printf(lcd_putc,"Tact=%d%cC ",t_act,0xDF);
lcd_gotoxy(1,2);
printf(lcd_putc,"Vsal=%1.1fV ",v_out);
/*COMPRUEBA SI EL USUARIO HA DECIDIDO CAMBIAR ALGUNA VARIABLE*/
if(config_t==1)
ponertmax();
if(config_v==1)
ponervoltaje();
/* CHEQUEA SI HA DE APAGARSE EL CONVERTIDOR POR ALGUN MOTIVO */
if((change_d==1||(t_act>=t_max))&&iniciado){
// Si estoy en la opcion 1 quiere decir que he pulsado el boton de parada, se ha
// superado la temperatuma maxima permitida o que se ha llegado a la hora temporizada
// y por lo tanto el la tension de salida y la de entrada tendrán que ser iguales,
// lo que hace que el valor del duty sea 0% y por lo tanto su carga tambien lo sera
// Los cambios de la tension de salida solo seran progresivos en caso del apagado
// del convertidor. Para cambios de una tension de salida a otra posteriormente
// definida (que podra ser mayor o menor) el cambio será brusco. Esto es debido a
// la dificultad de hacer el cambio progresivo usando el timer en vez de delays
// para poder usar otras funciones en tiempo real.
if(t_act>=t_max){
carga=((v_out-(4.0/1023.0*read_adc()+8.0))/v_out)*200.0;
change_duty(carga,0); // Desde hasta
}
else{
change_d=0;
carga=((v_out-(4.0/1023.0*read_adc()+8.0))/v_out)*200.0;
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCION PARA LEER LA TEMPERATURA //
/////////////////////////////////////////////////////////////////////////////////////////////////
void lee_t_act(){
i2c_start(); // Genera secuencia de START.
i2c_write(0b10011010); // Envía byte de control para escribir.
i2c_write(0x00); // Envía la dirección del sensor;
i2c_start(); // Genera otra secuencia de STAR
i2c_write(0b10011011); // Envía byte de control para leer.
t_act=i2c_read(0); // Lee el dato.
i2c_stop(); // Genera una secuencia de STOP.
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCION PARA INDICAR LA TEMPERATURA MAXIMA ADMITIDA //
/////////////////////////////////////////////////////////////////////////////////////////////////
void ponertmax(){
pulsada=0;
lcd_putc('\f');
lcd_gotoxy(1,1);
lcd_putc("Introduce Tmax");
do{
if(pulsada==1&&cont_dt==0&&tecla>=0&&tecla<=9){
pulsada=0;
cont_dt++;
t_max=tecla*10;
delay_ms(200);
}
if(pulsada==1&&cont_dt==1&&tecla>=0&&tecla<=9){
pulsada=0;
cont_dt++;
t_max=t_max+tecla;
delay_ms(200);
}
lcd_gotoxy(1,2);
printf(lcd_putc,"[%u]%cC",t_max,0xDF);
}while(cont_dt<=2&&tecla!='E');
delay_ms(300);
cont_dt=0;
lcd_putc('\f');
config_t=0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCION PARA INDICAR EL VOLTAJE DESEADO //
/////////////////////////////////////////////////////////////////////////////////////////////////
void ponervoltaje(){
change_d=0; // Al cambiar el voltaje deseado indica que tengo que cambiar el duty
pulsada=0;
lcd_putc('\f');
lcd_gotoxy(1,1);
lcd_putc("Introduce Vout");
do{
if(pulsada==1&&cont_dv==0&&tecla>=1&&tecla<=9){
pulsada=0;
cont_dv++;
v_out=tecla*10;
delay_ms(200);
}
if(pulsada==1&&cont_dv==1&&tecla>=0&&tecla<=9){
pulsada=0;
cont_dv++;
v_out=v_out+tecla;
delay_ms(200);
}
if(pulsada==1&&cont_dv==2&&tecla>=0&&tecla<=9){
pulsada=0;
cont_dv++;
v_out=v_out+tecla/10.0;
delay_ms(200);
}
lcd_gotoxy(1,2);
printf(lcd_putc,"[%1.1f]V",v_out);
}while(cont_dv<=2&&tecla!='E');
delay_ms(300);
cont_dv=0;
change_d=1;
g_v_out=v_out;
lcd_putc('\f');
config_v=0;
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCION PARA INDICAR LAS FUNCIONES DEL TECLADO //
/////////////////////////////////////////////////////////////////////////////////////////////////
void tecladofunc(){
switch(tecla){
case 'T':
config_t=1; // Indico que quiero configurar la Tmax
break;
case 'V':
config_v=1; // Indico que quiero configurar la V_out
break;
case 'N': // Tecla sin función.
break;
}
pulsada=0; // Recupera el marcador de “tecla no pulsada”.
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// INTERRUPCION PARA PARADA //
/////////////////////////////////////////////////////////////////////////////////////////////////
#INT_TIMER1
void parada(){ // Reloj normal y corriente con formato 24H que solo se muestra
iniciado=1; // en la pantalla principal si no se esta ajustando ninguna
actualizar_duty=1; // variable
/////////////////////////////////////////////////////////////////////////////////////////////////
// INTERRUPCION PARA LAS FUNCIONES DEL TECLADO //
///////////////////////////////////////////////////////////////////////////////////////////////// +
#INT_RB
void pulsado(){
/* Se identifica la columna en que está la tecla pulsada determinando cuál
de los cuatro bits más altos de PORTB está a 0. Si no hay ninguno, es que
se ha entrado en la interrupción al soltar la tecla, por lo que se sale
inmediatamente */
if(!RB4)
col=0;
else
if(!RB5)
col=1;
else
if(!RB6)
col=2;
else
if(!RB7)
col=3;
else return;
pulsada=1; // Indica que se ha pulsado una tecla.
paso=PORTB; // Guarda el valor de PORTB.
set_tris_b(0b00001111); // Cambia entradas por salidas.
PORTB=paso; // Saca el valor almacenado a PORTB.
delay_cycles(4); // Espera para estabilizar señal.
/* Se identifica la fila en que está la tecla pulsada determinando cuál de
los cuatro bits más bajos de PORTB está a 0. Si no hay ninguno,es que se
ha producido algún error y se indica que no hay ninguna tecla pulsada */
if(!RB0)
fil=0;
else
if(!RB1)
fil=1;
else
if(!RB2)
fil=2;
else
if(!RB3)
fil=3;
else
pulsada=0;
tecla=teclado[fil][col]; // Se guarda el valor de la tecla pulsada.
set_tris_b(0b11110000); // Se deja todo como estaba recuperando la
PORTB=0; // definición inicial de E/S en PORTB y
delay_cycles(4); // poniendo todas las salidas a 0 y leyendo
PORTB=PORTB; // PORTB para preparar las interrupciones.
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCION PARA CAMBIAR LA CARGA DEL PWM //
/////////////////////////////////////////////////////////////////////////////////////////////////
void change_duty(int16 desde,int16 hasta){
// Si la resta es positiva quiere decir que estoy apagando el PWM y por lo tanto
// debo decrementar la cargahasta llegar a 0 (lo hago en decrementos de 2 para
// sea algo mas rapido). Estos decrementos se haran cada vez que pasen 50ms
// (en la practica tarda algo mas ya que antes de detectar como esta la variable
// actualizar_duty tiene que pasar por otras instrucciones). Cuando la carga sea
// negativa o 0 querra decir que ya se ha terminado de apagar el PWM y tendremos
// que resetear la variable change_d. Carga es una variable sin signo por lo
// tanto no podra tomar valores negativos y al restarle un valor en el momento
// que valga 0 pasara a valer 65536. Por esta razon asumo que cuando carga
// tenga un alor muy alto en realidad su valor real deberia de ser 0
if((desde-hasta)>=0&&actualizar_duty==1){
carga=carga-2;
if(carga>65000){
carga=0;
change_d=0;
}
set_pwm2_duty(carga);
actualizar_duty=0;
}