Autor Tema: Microcursillo en C  (Leído 178989 veces)

0 Usuarios y 4 Visitantes están viendo este tema.

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: Microcursillo en C
« Respuesta #60 en: 14 de Agosto de 2004, 19:31:00 »
¿Me tomas el pelo?

Desconectado Duende_Azul

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 902
RE: Microcursillo en C
« Respuesta #61 en: 14 de Agosto de 2004, 21:38:00 »
Como crees, en serio, tu explicación es muy buena.

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: Microcursillo en C
« Respuesta #62 en: 14 de Agosto de 2004, 21:41:00 »
Gracias,Duende,pero no,no soy profe.
Soy alumno!!
La verdad es que me tomo mi tiempo para construir estos ejemplos,no salen de corrido.Y en eso consiste la cosa...que mejor forma de asimilar una idea que con un ejemplo ¿no?
Saludotes

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
RE: Microcursillo en C
« Respuesta #63 en: 15 de Agosto de 2004, 01:28:00 »
Modulay, admiro tu dedicación y entrega.

Cada día me está gustando más el C.

Desconectado T0ni0

  • PIC16
  • ***
  • Mensajes: 196
RE: Microcursillo en C
« Respuesta #64 en: 16 de Agosto de 2004, 05:12:00 »
Gracias GFP por tu aportación, por lo visto no definia bien el string,

He podido captar un string,  y compararlo con otro, realizo un switch de esta comparación, espero que sea ilustrativo .

Problemas que me he encontrado:

---- NO puedo utilizar las funciones dentro de la Interrupción, se pueden definir punteros a función?  he intentado utilizar la función suma() ( anteriormente modificada por mi, con los dos valores como entrada y entero como salida)

---- Los string NO pueden ser más grandes de 80 bytes  (creo que 80 es el numero máximo de variables que puedo utilizar) esto en el caso del F876 Alguna solución? en teoría tendría que haber 2x80 + 2x96 bytes disponibles.

----  Como puedo inicializar un string ? el switch lo quería hacer entre el valor que llega y la frase SUMAR


Aquí hos dejo el código


http://www.goto10.net/probac/probc.c


http://www.goto10.net/probac/probc.h
 haber como salimos de esta, de momento voy a provar el A/D y enviar los resultados.
- T0ni0 -
30RCF112

Desconectado T0ni0

  • PIC16
  • ***
  • Mensajes: 196
RE: Microcursillo en C
« Respuesta #65 en: 16 de Agosto de 2004, 06:33:00 »
Haber que os parece la adquisición de las dos AD

http://www.goto10.net/probad/probc.c


Por cierto, solo pueda adquirir 8 bits? como cojo los otros 2 ? yo ya he puesto que sean 10 pero en la variable solo me coge esos como la defino?
- T0ni0 -
30RCF112

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: Microcursillo en C
« Respuesta #66 en: 16 de Agosto de 2004, 07:16:00 »
Creo que te faltó añadir #device adc=10 en la parte de preprocesado,sin esta línea el ADC trabaja a 8 bits.
En cuanto al tema de los punteros a funciones,se puede hacer sin ningun problema,pero(siemre hay un pero) he estado haciendo pruebas y CCS no se traga un puntero a una función ni por asomo,da error de compilación te pongas como te pongas,aún siendo el código correcto.He probado a compilar el código con visual C++ y no hay problema.No sé si será cuestión de que a CCS hay que dárselo de otra forma(cosa que dudo) ó es que simplemente no se lo traga.Es una pena.De todas formas,aquí va un ejemplo para que prueben suerte a ver si alguien consigue hacerlo funcionar

Codigo:

///////////////////////////////////// PREPROCESADO ////////////////////////////////////

#include <16F876.h>
#use delay(clock=20000000)
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT
#include "lcd.c"

#use fast_io(B)

////////////////////////////////////// GLOBALES ///////////////////////////////////////

int (*funcion) (int,int);  // Puntero a una función que lleva dos parámetros enteros
                          // y que devuelve un entero

////////////////////////////////////// RUTINAS ///////////////////////////////////////

int suma(int a,int b)
  {
  return(a+b);
  }


int resta(int a,int b)
  {
  return(a-b);
  }

//////////////////////////////////// PRINCIPAL //////////////////////////////////////

void main()
   {
   int resultado;
   lcd_init();
   funcion = suma;      // Hacemos que el puntero apunte a la función "suma"
   resultado = funcion(10,2);  // Asignamos a "resultado" el valor que devuelve la función
                               // apuntada por el puntero "funcion"
   printf(lcd_putc,"La suma es: %u",resultado);  // Al lcd
   funcion = resta;    // Ahora el puntero apunta a "resta"
   resultado = funcion(10,2);  // Asignamos
   lcd_gotoxy(1,2);  // Segunda línea del lcd
   printf(lcd_putc,"La resta es: %u",resultado);  // Al lcd
   for(;;) {}
   }




La solución que yo veo para poder definir arrays de mayor tamaño es usar un pic 18.Estoy usando un 18F258 en un proyecto y tengo definido en el código un array de 500 posiciones.Claro que este micro tiene 1 K y medio de memoria RAM :)

Desconectado oshow

  • PIC18
  • ****
  • Mensajes: 321
RE: Microcursillo en C
« Respuesta #67 en: 16 de Agosto de 2004, 07:50:00 »
Aunque el codigo esté bien, el compilador no lo acepta, lo he buscado en la ayuda y efectivamente este compilador no acepta punteros a funciones, además pone un ejemplo de como podría hacerse sin punteros. Mediante una variable enum y luego un switch ejecutar la función correspondiente. Pego el texto directamente.

////////////////////////////////////////////////////////////////////////////////
How do I make a pointer to a function?

The compiler does not permit pointers to functions so that the compiler can know at compile time the complete call tree.  This is used to allocate memory for full RAM re-use.  Functions that could not be in execution at the same time will use the same RAM locations.  In addition since there is no data stack in the PIC®, function parameters are passed in a special way that requires knowledge at compile time of what function is being called.  Calling a function via a pointer will prevent knowing both of these things at compile time.  Users sometimes will want function pointers to create a state machine.  The following is an example of how to do this without pointers:

Codigo:

enum tasks {taskA, taskB, taskC};

 

run_task(tasks task_to_run) {

 

    switch(task_to_run) {

    case taskA : taskA_main();  break;

    case taskB : taskB_main();  break;

    case taskC : taskC_main();  break;

    }

 

}



Saludos.

Desconectado T0ni0

  • PIC16
  • ***
  • Mensajes: 196
RE: Microcursillo en C
« Respuesta #68 en: 16 de Agosto de 2004, 09:21:00 »
 bueno ha decir verdad falta ver un archivo, aqui están los dos archivos:


http://www.goto10.net/probad/probc.c


http://www.goto10.net/probad/probc.h




veras como si esta definido adc=10

De la interupción creo que será mejor levantar un flag en una variable global y ya está, luego en el main actuar.

Ah!!    para inicializar un string, ya lo se al mismo tiempo que se define


ej. char car[10]="hola";
- T0ni0 -
30RCF112

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: Microcursillo en C
« Respuesta #69 en: 16 de Agosto de 2004, 10:16:00 »
Tonio creo que tu problema con la función se debe al hecho de que cualquier procedimiento debe estar declarado (ó al menos implementado) antes que el algoritmo llamante.
"Undefined identifier suma"...Si este es el error que te da corta la función "suma" y la pegas antes de la rutina de interrupción(si es dicha rutina quien quieres que llame a "suma").
Esto es una cuestión básica de C,se me ha escapado comentarla.
La forma mas correcta de solucionar esta cuestión es declarando siempre en nuestros programas todos y cada uno de los procedimientos..¿dónde y cómo se hace eso?...pues podemos hacerlo justo antes de la parte de variables globales,en la parte alta del código.La forma de declarar un procedimiento es copiar su cabecera tal cual está en la implementación del mismo.Sería de esta forma:

Codigo:

///////////////////////////////////// PREPROCESADO ////////////////////////////////////

#include <16F876.h>
#use delay(clock=10000000)
#fuses HS,NOWDT,NOPUT,NOLVP,NOBROWNOUT,NOWRT
#include "lcd.c"

#use fast_io(B)

////////////////////////////////////// CABECERAS ////////////////////////////////////

// Aquí declaramos todos los procedimientos a excepción del "main"
// Cuando el código comienza a adquirir unas dimensiones considerables,una ventaja
// que esto tiene es poder ordenar las rutinas por orden alfabético para poder
// localizarlas con facilidad.
// Las cabeceras también las ordenamos por orden alfabético

void fulanito(int var);
float manolito(int a,int b);
void pepito();  // OJO! No olvidar el ";"

////////////////////////////////////// GLOBALES ///////////////////////////////////////

int var_global;

////////////////////////////////////// RUTINAS ///////////////////////////////////////

void fulanito(int var)
  {
  // "pepito()" está implementada después del algoritmo llamante,pero
  // al estar ya declarado,será visible aunque esté después.
  pepito();
  }


float manolito(int a,int b)
  {
  return(a/b);
  }


void pepito()
  {
  printf(lcd_putc,"bla bla bla");
  }

//////////////////////////////////// PRINCIPAL //////////////////////////////////////

void main()
   {
   // ¿Cual puede ser el motivo por el cúal el "main" está siempre lo último? :)
   }




He probado tu programa(quitando alguna cosas,ya que no tengo ICD,ni tengo el micro con su max232 para el puerto serie) y he mostrado los valores capturados por el adc  en mi lcd y funciona bien,los valores son de 10 bits.No se que puede estar mal.Prueba a hacerlo más sencillo y que el programa en sí únicamente consista en la captura del adc a ver q tal va.
Saludos

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: Microcursillo en C
« Respuesta #70 en: 16 de Agosto de 2004, 11:58:00 »
Te felicito Modulay por tan valiosa dedicación, este minicursillo está pero que muy interesante.

Como vereis ultimamente entro poco al FORO ... vacaciones.

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: Microcursillo en C
« Respuesta #71 en: 16 de Agosto de 2004, 12:17:00 »
Gracias,pocher
Disfruta de la vacaciones
Saludos

Desconectado T0ni0

  • PIC16
  • ***
  • Mensajes: 196
RE: Microcursillo en C
« Respuesta #72 en: 18 de Agosto de 2004, 10:18:00 »
Pues ya llevas razón se me había escapado, cuando hago C pongo todas las funciones en un include y las cabeceras en un archivo .h , al hacerlo todo en un mismo archivo se me escapó.

Gracias por estar atento


Aki está el resultado:

//******************************************************+

//
//       Adquisición de dos entradas analógicas
//
//       Parpadeo de LED en RB1
//
//       AD0:
//       AD1: termómetro con LM35
//
//       Polling entrada digital RB0 ( 0 si activada)
//
//       Entrada string por Interrupción UART
//          Si es "SUMAR" entrar dos numeros y se suman
//
//       Visualización de los resultados por UART
//
//
//       Autor:   T0ni0
//
//******************************************************+
      #include <16F876.h>
      #device ICD=TRUE
      #device adc=10
      #use delay(clock=20000000)
      #fuses NOWDT,HS, NOPUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, DEBUG
      #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)

      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      #ZERO_RAM


//******************************************************+
//       Cabezeras
//******************************************************+
      long int suma(long int num1, long int num2);


//******************************************************+
//       Variables globals
//******************************************************+
      int glob;

//******************************************************+
//       INTERRUPCIÓN DE LA UART
//******************************************************+
#int_RDA
RDA_isr()
{

char caract[30];
long int x,y;
char sumes[6]="SUMAR";

   gets(caract); //Guarda caracteres hasta que recibe enter.


switch (strcmp(sumes,caract)) {

// SI SON LOS DOS STRINGS IGUALES

    case 0:    printf("
ENTRA EL PRIMER NUMERO
" );
               gets(caract); //Guarda caracteres hasta que recibe enter.
               x= atoi32(caract);
               printf( " EL PRIMER NUMERO ES %lu
",x);

               printf(" ENTRA EL SEGUNDO NUMERO
" );
               gets(caract); //Guarda caracteres hasta que recibe enter.
               y= atoi32(caract);
               printf( " EL SEGUNDO NUMERO ES %lu
", y);

               x= suma(x,y);
     //          x=x + y;

               printf(__DATE__);
               printf(" LA SUMA ES  = %lu
",x); // La mostramos
           break;

// SI EL PRIMERO ES MAYOR
    case 1: printf("PRIMERO MAS GRANDE
" );
            printf("
ENTRAR "SUMAR" PARA EMPEZAR
" );
            break;

// SI EL PRIMERO ES MENOR
    case -1:printf("PRIMERO MENOR
" );
            printf("
ENTRAR "SUMAR" PARA EMPEZAR
" );
            break;

// PARA ESTA EVALUACIÓN TIENE QUE SER UN VALOR DE LOS ANTERIORES
    default:printf("NO ENCONTRADO
" );

            break; } //FINAL DEL SWITCH


}                    //FINAL DE LA INTERRUPCIÓN



//******************************************************+
//       Funciones
//******************************************************+

long int suma(long int num1, long int num2)
   {
   return(num1 + num2);        // Valor a retornar
   }


//******************************************************+
//      MAIN
//******************************************************+
void main()
{
//******************************************************+
//       Variables
//******************************************************+

   long int val1,val2;


//******************************************************+
//       INICIO
//******************************************************+
   setup_adc_ports(RA0_RA1_RA3_ANALOG);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_spi(FALSE);
   setup_counters(RTCC_INTERNAL,RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   enable_interrupts(INT_RDA);
   enable_interrupts(GLOBAL);

//******************************************************+
//       BUCLE PRINCIPAL
//******************************************************+
  while (TRUE)
    {

      printf("
$AD0: EL VALOR MESURADO EN A/D 0 ES=%4lu
",val1);

      delay_ms(2000);

      printf("
$TEMPERATURA EXTERIOR:%2luC
",val2);

      if (!input(PIN_B0))
      {
      printf("
$ENTRADA1: SE HA ACTIVADO" );
      }

      output_high(PIN_B1);

      set_adc_channel(0);       //observamos el canal 0
       delay_ms(1000);
      val1 = read_adc();        //Realizamos la adquisición

      output_low(PIN_B1);

      set_adc_channel(1);       //observamos el canal 1
      delay_ms(1000);
      val2 = read_adc();        //Realizamos la adquisición
      val2= val2/25.3;          //Relación del (LM35 * 10)

   }              // FINAL DEL BUCLE PRINCIPAL
}                 // FINAL DEL MAIN


- T0ni0 -
30RCF112

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
RE: Microcursillo en C
« Respuesta #73 en: 18 de Agosto de 2004, 10:27:00 »
Olvidaste la cabecera de la rutina de interrupción.No se trata de declarar sólo las funciones,sino todas las rutinas a excepción del main.Aunque viéndolo en cierto modo,no sería necesario puesto que no va a ser llamada por ninguna rutina del programa.
¿Resolviste lo de los 10 bits en el ADC?

Desconectado T0ni0

  • PIC16
  • ***
  • Mensajes: 196
RE: Microcursillo en C
« Respuesta #74 en: 18 de Agosto de 2004, 10:38:00 »
Pues si, asunto resuelto, mi fallo era declarar las variables como int, luego solo cogían 8 bits ahora están declaradas como long int.  
- T0ni0 -
30RCF112


 

anything