TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: RedPic en 23 de Febrero de 2006, 13:36:00

Título: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 23 de Febrero de 2006, 13:36:00
Iniciamos aquí otra serie de posteos, que espero sea larga y fructífera,
con la sana intención de facilitarle el camino a nuestros amables visitantes
Picmaníacos.

La titúlo Mis Funciones favoritas en CCS C ya que pretendo ir subiendo
aquellas funciones que me van haciendo falta en mi otra serie de
Ejemplitos 16F876A: Indice de contenidos (http://www.todopic.com.ar/foros/index.php?topic=4531.0) y tambien aquellas funciones que detecte que son muy
buscadas y necesitadas por los amigos principiantes.

Empezamos pues con una de la mas famosas ...

Titulo: ASCII Hex to Int
=================

Descripción:

Convierte un carácter ASCII Hex (0..9 A..F) al valor
entero (0..15) correspondiente (4 bits)

Declaración:

#include <stdlib.h>

int  aschex2int(char d);

Función y ejemplo de uso:

<span class="texto_mini">Codigo:</span>[hr /
]
int aschex2int(char d){          // Convierte un caracter ascii hex a int

   int r=0;                       // Declaro e inicializo a cero el resultado
   if(isxdigit(d)){               // Si es un digito hexadecimal ...
      if(isdigit(d)){             // si es un digito decimal ...
         r=d-'0';                 // devuelvo su diferencia con el valor ascii del caracter "0"
      }
      if(isalpha(d)){             // si es alfanumerico ...
         d=toupper(d);            // lo paso a mayusculas y ...
         r=10+(d-'A');            // devuelvo 10 mas su diferencia con el valor ascii de la letra "A"
      }
   }
   return(r);
}

   // Ejemplo de uso con 1 caracter

   int x;
   x = aschex2int('F');          // x toma el valor 15


   // Ejemplo de uso con dos caracteres

   char *ptr;
   strcopy(ptr,"ff" );

   int x;
   x =(16*aschex2int(ptr[0]));             // Convierto el dígito mas significativo
   x+=(aschex2int(ptr[1]));                // Convierto el dígito menos significativo
                                           // y lo sumo a lo anterior, x toma el valor 255




Y ahora vamos con una función muy util a la hora de manejar los Displays
de 7 segmentos; sobre todo para su uso con los Drivers estilo <a href="http://picmania.garcia-cuervo.com/recursos/74LS48.pdf" target="_blank">74LS48[/url]
Esta función es facilmente adaptable a su uso con solo dos dígitos ...

Titulo: Int to BCD
==============

Descripción:

Convierte un entero a su representación BCD (Binary Code Decimal)

Declaración:

int h_digit, m_digit, l_digit;

void int2bcd(int valor);

Función y ejemplo de uso:

<span class="texto_mini">Codigo:</span>[hr /
]
void int2bcd(int valor){         // Funcion que convierte de Entero a 3 x BCD

   h_digit = (int) valor / 100;  // 1er Dígito o Centenas
   valor -= h_digit * 100;       // y se lo resto al valor
   m_digit = (int) valor / 10;   // 2do Dígito o Decenas
   valor -= m_digit * 10;        // y también se lo resto
   l_digit = valor;              // y por último solo me quedan las unidades
}

   int x=255;

   int2bcd(x);
  
   printf("
Test %u %u %u
",h_digit,m_digit,l_digit);





Titulo : Funciones Date y Time
=====================

Y ahora en otro orden de cosas vamos a tratar una serie de funciones
bajo el denominador común de Date y Time.

Estas funciones no son mías, son una traducción de lo originalmente publicado
en el <a href="http://www.ccsinfo.com/forum/viewtopic.php?t=25611" target="_blank">Foro CCS Library[/url] y su autor es <a href="mailto:nicksubzero@yahoo.com ">Aurelian Nichita[/url]
Yo me he limitado a traducirlas al español y probar que funcionan.

Incluye las funciones:

esAgnoBisiesto(int y)
diasDesdeAgno1(int y, int m, int d)
segundosDesdeHora0(int h, int m, int s)
segundosDesdeAgno1(int yr, mo, dy, hr, mi, se)
segundosEntre(int yr1, mo1, dy1, hr1, mi1, se1, yr2, mo2, dy2, hr2, mi2, se2)
ISODiaDeLaSemana(int YY, int MM, int DD)
ISONumeroDeLaSemana(int YY, int MM, int DD, int& weekOfYear, int& actualYear)

<span class="texto_mini">Codigo:</span>[hr /
]

// Definiciones y Funciones de Date Time ////////////////////////////////////////////////

// Números ISO de los dias de la semana
 
#define LUNES     1
#define MARTES    2
#define MIERCOLES 3
#define JUEVES    4
#define VIERNES   5
#define SABADO    6
#define DOMINGO   7

const int Dias_de_cada_Mes[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
                                      {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} };

const int Orden_Dias_Semana[7] = {6, 7, 1, 2, 3, 4, 5};

#define SEGUNDOS_EN_UN_DIA 86400

#define SEGUNDOS_EN_UNA_HORA 3600
#define SEGUNDOS_EN_UN_MINUTO 60
#define MINUTOS_EN_UN_DIA 1440
#define MINUTOS_EN_UNA_HORA 60
#define HORAS_EN_UN_DIA 24


// Algunas funciones que seran usadas mas adelante

#inline
short esAgnoBisiesto(int y) {
  return (y % 4 == 0);
}

#separate
int32 diasDesdeAgno1(int y, int m, int d) {
  int32 dias = 0;
  int i;
  short es_bisiesto;

  es_bisiesto = esAgnoBisiesto(y);
  for (i=1; i<y; i++) {
    if (esAgnoBisiesto(i))
      dias += 366;
    else
      dias += 365;
  }
  for (i=1; i<m; i++)
    dias += Dias_de_cada_Mes[es_bisiesto][ i ];
  dias += d;

  return dias;
}

#separate
int32 segundosDesdeHora0(int h, int m, int s) {
  int32 segundos;
  segundos = (int32)h * SEGUNDOS_EN_UNA_HORA;
  segundos += (int32)m * SEGUNDOS_EN_UN_MINUTO;
  segundos += s;
  return segundos;
}

#separate
int32 segundosDesdeAgno1(int yr, mo, dy, hr, mi, se) {
  int32 segundos;
  segundos = diasDesdeAgno1(yr, mo, dy) * SEGUNDOS_EN_UN_DIA;
  segundos += segundosDesdeHora0(hr, mi, se);
  return segundos;
}

// Calcula el numero de segundos entre dos fechas y horas

// Adaptado para años entre 2001 y 2135 (limitado por el tamaño de los int32)


#separate
int32 segundosEntre(int yr1, mo1, dy1, hr1, mi1, se1, yr2, mo2, dy2, hr2, mi2, se2) {
  int32 inicio;
  int32 final;
  inicio = segundosDesdeAgno1(yr1, mo1, dy1, hr1, mi1, se1);
  final  = segundosDesdeAgno1(yr2, mo2, dy2, hr2, mi2, se2);
  if (inicio > final)
    return inicio-final;
  else
    return final-inicio;
}

// Calculo del dia de la semana. Adaptado SOLO para años del 2000 al 2099

#separate
int ISODiaDeLaSemana(int YY, int MM, int DD) {
  signed long diaDeLaSemana;
  int cent = 20;  // YYYY / 100

  // Algoritmo de congruencia de Zeller

  if (MM < 3) {
    MM = MM + 12;
    if (YY > 0)
      YY--;
    else {
      YY = 99;
      cent--;
    }
  }

  diaDeLaSemana = DD;
  diaDeLaSemana += (((signed long)MM + 1) * 26) / 10;
  diaDeLaSemana += YY;
  diaDeLaSemana += YY / 4;
  diaDeLaSemana += cent / 4;
  diaDeLaSemana -= cent * 2;

  while (diaDeLaSemana < 0)
    diaDeLaSemana += 7;

  diaDeLaSemana %= 7;

  return Orden_Dias_Semana[(int)diaDeLaSemana]; // Ahora tenemos el número ISO del dia de la semana
}

// Calculo de número ISO de la semana. Adaptado SOLO para años del 2001 al 2098

#separate
void ISONumeroDeLaSemana(int YY, int MM, int DD, int& weekOfYear, int& actualYear)
{
  signed long diaDelAgno;
  int DiaDeLaSemanaInicial;
  int DiaDeLaSemanaFinal;
  short bisiesto;
  signed int i;

  do {
    bisiesto = esAgnoBisiesto(YY);
    diaDelAgno = 0;

    for (i=1; i<=MM; i++) {
      if (i < MM)
        diaDelAgno += Dias_de_cada_Mes[bisiesto][ i ];
      else
        diaDelAgno += DD;
    }
    actualYear = YY;
    DiaDeLaSemanaInicial = ISODiaDeLaSemana(actualYear, 1, 1);

    if (DiaDeLaSemanaInicial > JUEVES)
      diaDelAgno -= 8 - DiaDeLaSemanaInicial;
    else
      diaDelAgno += DiaDeLaSemanaInicial - 1;

    if (diaDelAgno <= 0)
      weekOfYear = 0xFF;
    else {
      weekOfYear = diaDelAgno / 7;
      if (diaDelAgno % 7 != 0)
        weekOfYear++;
      if (weekOfYear > 52) {
        DiaDeLaSemanaFinal = DiaDeLaSemanaInicial;
        if (bisiesto) {
          if (DiaDeLaSemanaFinal == DOMINGO)
            DiaDeLaSemanaFinal = LUNES;
          else
            DiaDeLaSemanaFinal++;
        }
        if (DiaDeLaSemanaFinal < JUEVES) {
          actualYear++;
          weekOfYear = 1;
        }
      }
    }

    if (weekOfYear == 0xFF) {
      if ((--DD)==0) {
        if ((--MM)==0) {
          YY--;
          MM = 12;
        }
        DD = Dias_de_cada_Mes[esAgnoBisiesto(YY)][MM];
      }
    }

  } while (weekOfYear == 0xFF);
}





Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: antoniof en 24 de Febrero de 2006, 02:15:00
Hola RedPIC.

A ver si tienes a mano la de pasar enteros a ASCII con mas de una cifra claro Sonrisa Gigante

Es que la que tenia echa se me ha perdido Enfurruñado
Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 24 de Febrero de 2006, 13:17:00
Mi pacense amigo antoniof:

La función contraria es trivial ya que CCS nos la proporciona y se llama sprintf.
Te pongo un ejemplo de su uso:

Codigo:

   int y=128;             // Variable entera a convertir
   char sy[4];            // String de destino de la conversión (tres dígitos + de fin de string)

   sprintf(sy,"%u",y);   // sx vale ahora "128"



Sin embargo imaginemos que los amables señores de CCS no nos hubiesen proporcionado
tal función y tuviesemos que realizarla nosotros.

Entonces deberíamos proceder "descuartizando" nuestro número entero aplicandole
el principio de numeración indo-arábigo (decimal) en que se basa:

Codigo:

   int x=128;             // Variable entera a convertir
   char sx[4];            // String de destino de la conversión (tres dígitos + de fin    

   int c,d,u;             // Variables intermedias para centenas, decenas y unidades
   
   c = (int) x / 100;     // Calculamos cuantas centenas tiene nuestro número ...
   x = x - (c * 100);     // y se lo restamos
   d = (int) x / 10;      // Calculamos cuantas decenas tiene nuestro número ...
   x = x - (d *  10);     // y se lo restamos
   u = (int) x / 1;       // Y por último calculamos cuantas unidades tiene nuestro número.
                          // De esta forma nuestro string se compone de ...  
   sx[0]="0"+c;           // La Centena que será el ASCII del "0" mas nuestras centenas
   sx[1]="0"+d;           // La Decena que será el ASCII del "0" mas nuestras decenas y
   sx[2]="0"+u;           // La Unidad que será el ASCII del "0" mas nuestras unidades
   sx[3]="";            // Y finalizamos el string con su correspondiente caracter
                          // sx vale ahora "128"


Fácil y sencillo como juego de chiquillo Vacilando

hummm ... y esto me dá ideas ... si, me dá ideas ...


Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 24 de Febrero de 2006, 16:18:00
Esta respuesta que he dado al tema que planteó el amigo antoniof me ha
sugerido una solución más elegante que la que anteriormente tenía para la
conversión de Entero a BCD, ya que esta conversión no deja de ser una
simplificación del tema de "descuartizar" un numero en sus potencias de 10.

El asunto estriba en que el código BCD consiste simplemente en representar
los números como lo hacemos habitualmente pero solo con cuatro dígitos binarios
convirtiendo por tanto cualquier entero en sus correspondientes componentes,
uno a uno, a su representación binaria:

57dec = 0101 0111bcd

O sea que el numero anterior debemos trocearlo en centenas, decenas y
unidades y obtener así cada dígito por separado, que es lo que realmente
.

Para ello he escrito la función int2bcd que podeis ver en el post original de
este hilo.



Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: garlic_74 en 27 de Febrero de 2006, 08:37:00
aver si alguien se curra ejemplos de la libreria string.h que ha mi siempre me dan problemas Muchas risas
strcpy()
stcmp()
strcat()

Un saludo!!! Muchas risas
Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 27 de Febrero de 2006, 15:35:00
Bueno amigo Garlic, voy a ver si me busco una aplicación bonita donde haga uso del tratamiento "completo" de las funciones de string.h ...

De hecho acabo de concluir algo que hace uso de varias funciones de este "include" ... strcpy, strcmp, strncpy, strncmp ... y algo más. Voy a ver si le doy forma y lo publico ... aunque sea en la sección de Ejemplitos 16F678A

¡Te acepto el reto! Muchas risas

Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: Nocturno en 27 de Febrero de 2006, 15:41:00
Si es que te ponen un capote y entras a saco. Asi da gusto.
Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 27 de Febrero de 2006, 16:03:00
Jua, jua, jua Muchas risasMuchas risasMuchas risas  ... manolo, me llamas Toro, y yo tan ancho y tan pancho ... jua, jua, jua Muchas risasMuchas risasMuchas risas ...

Pero la verdad es que tienes razón ... a mi se me puede aplicar lo de los ingenieros:

Para hacer que un ingeniero se lance de cabeza a la resolución de un problema no hay mas que insinuarle que no es posible solucionarlo, entonces se lanza a él como un chihuahua a una rodaja de mortadela, y ni come ni duerme, ni se lava, y ni casi respira hasta encontrar la solución mas elegante, rápida y barata que en cabeza cabe.

Pero eso es otra historia ....



Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: pachopic en 27 de Febrero de 2006, 20:52:00
HOLA:

aqui  otra manera de convertir un numero cualquiera a bcd mediante el operador modulo (%) , y arreglos: Sonrisa GiganteSonrisa GiganteSonrisa GiganteSonrisa GiganteSonrisa Gigante

Codigo:

////////// FUNCION QUE CONVIERTE A 5 DIGITOS DE BINARIO long int A BCD //

void bin16_bcd5(long int n)// el numero a convertir es un entero largo
{
int i;          // indice del arreglo unidades=bcd_dato
  • ,d=[1],...m=[5]
    for(i=0;i<5;i++)// llena el arreglo con los valores uni,dec,cen,mil,diezm
    {                      // (cambio i dependiendo que tantos digitos sea el # a convertir)
    bcd_dato[ i ]=n%10;// mediante la operacion modulo se obtiene el, i digito decimal
    n=n/10;            // n dividido 10 para cada i y tomamos su valor entero:
    }                  // por ejemplo  para i=0,  4358 mod 10 =8, luego 4358/10 =435
    }                  // para i=2, 435 mod 10=5, 435/10=43 luego 43 mod 10=3

    LUEGO:

    bcd_dato[0]=8
    bcd_dato[1]=5
    bcd_dato[2]=3
    bcd_dato[3]=4
          .               .
          .               .
          .               .






salu2
Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 28 de Febrero de 2006, 05:35:00
Muy elegante tu función Pachopic. Te felicito.

Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 28 de Febrero de 2006, 05:52:00
El Reto Garlic-Strings se compone, en principio y según las páginas
138 y 139 del C Compiler Reference Manual Build-In Functions, de:

Codigo:

STANDARD STRING FUNCTIONS
STRCAT()
STRCHR()
STRRCHR()
STRCMP()
STRNCMP()
STRSPN()
STRICMP()
STRNCPY()
STRCSPN()
STRLEN()
STRLWR()
STRPBRK()
STRSTR()


Syntax: ptr=strcat (s1, s2) Concatenate s2 onto s1
        ptr=strchr (s1, c) Find c in s1 and return &s1[ i ]
        ptr=strrchr (s1, c) Same but search in reverse
        cresult=strcmp (s1, s2) Compare s1 to s2
        iresult=strncmp (s1, s2, n) Compare s1 to s2 (n bytes)
        iresult=stricmp (s1, s2) Compare and ignore case
        ptr=strncpy (s1, s2, n) Copy up to n characters s2->s1
        iresult=strcspn (s1, s2) Count of initial chars in s1 not in s2
        iresult=strspn (s1, s2) Count of initial chars in s1 also in s2
        iresult=strlen (s1) Number of characters in s1
        ptr=strlwr (s1) Convert string to lower case
        ptr=strpbrk (s1, s2) Search s1 for first char also in s2
        ptr=strstr (s1, s2) Search for s2 in s1

Parameters: s1 and s2 are pointers to an array of characters (or the name of an array).
            Note that s1 and s2 MAY NOT BE A CONSTANT (like "hi" ).
            n is a count of the maximum number of character to operate on.
            c is a 8 bit character

Returns: ptr is a copy of the s1 pointer
         iresult is an 8 bit int
         result is -1 (less than), 0 (equal) or 1 (greater than)

Function: Functions are identified above.

Availability: All devices

Requires: #include <string.h>



Va a ser dificil montar un ejemplo donde se usen todas estas funciones,
asi que intentaré usar el mayor número posible de ellas, y de las que
resten pondré algunos ejemplos que aclaren su uso y/o aplicación.

Vamos a ver qué resulta de todo esto.  Giño

Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 28 de Febrero de 2006, 12:43:00

(http://picmania.garcia-cuervo.net/images/picc_strings_dump.jpg")

Con mi insufrible manía de hacer la cosas lo mas dificil posible he montado
una demo de este asunto de los strings mediante un "monitor rs232".

Quiero decir que he hecho un programa que se comunica con el PC mediante
la rs232 y que acepta comandos y argumentos de estos comandos para los
ejemplos de algunas funciones ...

Pero para poder hacer esto de los comandos, que en el fondo no es mas que
procesar strings, he necesitado hacer uso de la mayoria de las funciones que
estamos tratando de ejemplificar.

El resultado ha sido plenamente satisfactorio ya que funciona perfectamente
y a la vez ha salido, perdonen la inmodestia, muy pedagógico. Aparecen la
mayoría de las funciones de tratamiento de strings y las que no lo hacen se
manejan de forma absolutamente análogas a las que sí.

Mas abajo os posteo el código  completo del <a href="http://picmania.garcia-cuervo.com/recursos/_strings_demo.c" target="_blank">Strings_Demo.c[/url]

<span class="texto_mini">Codigo:</span>[hr /
]

/////////////////////////////////////////////////////////////////////////////////////////
//
// Strings_Demo v.1.0
//
// © 28.02.2006 By RedRaven (RedPic)
//
// Para Foro Todo Pic
//
// Idioma: CCS PICC v.3.242
//
/////////////////////////////////////////////////////////////////////////////////////////

#include <16f876a.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#include <stdlib.h>

// Constantes y definiciones ////////////////////////////////////////////////////////////

int const MAXLENBUFF=42;                         // Maxima longitud del buffer de recepción RS232
int const MAXLENCOMMAND=10;                      // Maxima longitud de un comando (sin argumentos)
int const MAXLENARG=8;                           // Maxima longitud de cada uno de los argumentos s1 y s2

// Variables Globales ///////////////////////////////////////////////////////////////////

char buffrec[MAXLENBUFF];                        // Buffer de Recepcion
int  xbuffrec=0x00;                              // índice del Buffer de Recepcion

int1 new_command=0;                              // Flag para indicar comando disponible
int1 pdte_send_prompt=0;                         // Flags para enviar echos fuera de la int_rda
int1 pdte_send_tmp_prompt=0;

char s1[MAXLENARG];                              // Argumento 1
char s2[MAXLENARG];                              // Argumento 2
char sr[MAXLENBUFF];                             // Resultado de nuestras manipulaciones de Strings

// Declaracion de Funciones /////////////////////////////////////////////////////////////

void On_reset(void);                             // Tras RESET del Micro
void Send_listen(void);                          // Monitoriza RS232 : Comienzo
void Send_opts(void);                            // Monitoriza RS232 : Presenta opciones
void Send_prompt(void);                          // Monitoriza RS232 : Presenta el Cursor
void Send_tmp_prompt(void);                      // Monitoriza RS232 : Presenta el Cursor y el comando actual
void Ini_buffrec(void);                          // Borra el buffer de recepción
void Add_buffrec(char c);                        // Añade un caracter al buffer de recepción
void Procesa_comando(void);                      // Procesado de comandos


// INTERRUPCIONES ///////////////////////////////////////////////////////////////////////

// INTERRUPCION RDA - Recepción USART -

#int_rda
void serial_isr() {
   if(kbhit()){                                  // Si hay algo pendiente de recibir ...
      Add_buffrec(getc());                       // lo recibo y lo añado al Buffer de Recepcion
   }
}

// Control del Buffer de recepcion ---------------------------------------

void Ini_buff_rec(void){                         // Inicia a "�" el Buffer de Recepcion

   int i;
   for(i=0;i<MAXLENBUFF;i++){                    // Bucle que pone a 0 todos los
      buffrec[ i ]=0x00;                           // caracteres en el Buffer de Recepcion
   }
   xbuffrec=0x00;                                // Inicializo el indice de siguiente caracter recibido
}

void Add_buffrec(char c){                         // Añade caracter al Buffer de Recepcion

      switch(c){
         case 0x0D:                              // [Enter] -> Habilita Flag para procesar comando en Main
            buffrec[xbuffrec++]=" ";             // Añade un espacio en blanco al final y ...
            new_command=1;                       // Habilita Flag para procesar comando en Main
            break;
         case 0x08:                              // [Del]   -> Borra último caracter del Buffer
            if(xbuffrec>0){                      //            Si hay algo en el buffer
               buffrec[--xbuffrec]=0x00;         //            decremento el índice, escribo un cero y ...
               pdte_send_tmp_prompt=1;           //            habilito flag para refrescar el prompt
            }
            break;
         case 0x01B:                             // [Esc]   -> Borra el Buffer completamente y ...
            Ini_buff_rec();                      //            habilito flag para refrescar el prompt
            pdte_send_prompt=1;
            break;
         case 0x009:                             // [Tab]   -> Refresca el prompt y el comando tal como esté
            pdte_send_tmp_prompt=1;
            break;
         default:
            buffrec[xbuffrec++]=c;               // Añade caracter recibido al Buffer
            putc(c);                             // y lo monitorizo
      }
}

// Rutinas y Funciones de RROS ///////////////////////////////////////////

void On_reset(void){                             // Inicializacion del Micro tras RESET

   disable_interrupts(GLOBAL);                   // todas las interrupciones desactivadas

   delay_ms(100);

   Ini_buff_rec();                               // Inicializo Buffer de recepcion
   new_command=0;                                // Desactivo flag de comando pendiente.
   pdte_send_prompt=0;                           // Desactivo Flags para enviar echo fuera de la int_rda
   pdte_send_tmp_prompt=0;

   enable_interrupts(int_rda);                   // interrupcion RDA habilitada
   enable_interrupts(global);                      // todas las interrupciones activadas

   Send_listen();                                // Presenta Comienzo
   Send_prompt();                                // Presenta el Cursor

}

void Send_listen(void){                          // Presenta Comienzo

   printf("
Strings Demo v1.0" );
   Send_opts();
}

void Send_opts(void){                            // Relación de comandos válidos

   printf("

" );
   printf("[?] ver comandos válidos
" );
   printf("[strcat ABC abc] añade s2=abc a s1=ABC
" );
   printf("[strlwr ABC] convierte ABC a minúsculas
" );
   printf("[strstr ABC abc] busca s2=abc dentro de s1=ABC
" );

}

void Send_prompt(void){                          // Presenta el cursor

   printf("
>" );
}

void Send_tmp_prompt(void){                      // Presenta el cursor con el comando actual

   printf("
>%s",buffrec);
}

// MAIN Programa Principal ///////////////////////////////////////////////

void main(void)
{
   On_reset();

   do {

      // Deteccion de la necesidad de procesar comandos pendientes ///////
      if(new_command==1){                        // Si hay un nuevo comando ...
         new_command=0;                          // deshabilito el aviso y ...
         Procesa_comando();                      // Procesado de comandos
         Ini_buff_rec();                         // inicializo todo para nuevo comando y ...
         pdte_send_prompt=1;                     // mando prompt.
      }

      // Deteccion de la necesidad de enviar echos ///////////////////////
      if(pdte_send_prompt==1){                   // Si esta pendiente de enviar prompt ...
         pdte_send_prompt=0;                     // marco que ya no lo está y ...
         Send_prompt();                          // lo envío.
      }
      if(pdte_send_tmp_prompt==1){               // Si esta pendiente de enviar prompt temporal ...
         pdte_send_tmp_prompt=0;                 // marco que ya no lo está y ...
         Send_tmp_prompt();                      // lo envío.
      }

     } while(TRUE);
}

// Funciones necesarias ... //////////////////////////////////////////////

int extrae_argumentos(int cuantos){

   int i,c;
   int error=0;                                  // Para devolver código de error si se da el caso
   char *ptri;
   char *ptrf;
   
   for(i=0;i<MAXLENARG;i++){                     // Bucle que pone a 0 todos los
      s1[ i ]="�";                                // caracteres en s1 y s2 antes de extraer
      s2[ i ]="�";
   }

   c=1;
   for(i=0;i<MAXLENBUFF;i++){                    // Bucle que marca los separadores " " (espacios)
      if(buffrec[ i ]==" "){                       // en el buffer de recepción
         buffrec[ i ]=c++;                         // escribiendo 0x01 en el primero, 0x02 en el segundo ... etc.
      }                                          // con lo que s1 estará entre 0x01 y 0x02 y ...
   }                                             // s2 estará entre 0x02 y 0x03.

   if(cuantos==1){                               // Si necesito dos argumentos y ...
      if(c!=3){                                  // Error: tengo menos o mas de un argumento
         error=1;                                // ya que hemos puesto un numero distinto a 2 de marcas
         goto retorno;                           // observa que para 2 marcas c vale 3
      }
   }
   if(cuantos==2){                               // Si necesito dos argumentos y ...
      if(c!=4){                                  // Error: tengo menos o mas de dos argumentos
         error=1;                                // ya que hemos puesto un numero distinto a 3 de marcas
         goto retorno;                           // observa que para 3 marcas c vale 4
      }
   }

   ptri=strchr(buffrec,0x01);                    // obtengo el puntero donde aparece 0x01
   ptrf=strchr(buffrec,0x02);                    // obtengo el puntero donde aparece 0x02
   if(ptri!=0 && ptrf!=0){                       // Si he encontrado 0x01 y 0x02
      ptri+=1;                                   // avanzo 1 ptri para saltarme 0x01
      strncpy(s1,ptri,ptrf-ptri);                // Luego s1 lo extraigo entre ptri y ptrf
   }

   if(cuantos==1){                               // Si solo necesito un argumento he terminado
      goto retorno;
   }

   ptri=strchr(buffrec,0x02);                    // obtengo el puntero donde aparece 0x02
   ptrf=strchr(buffrec,0x03);                    // obtengo el puntero donde aparece 0x03
   if(ptri!=0 && ptrf!=0){                       // Si he encontrado 0x01 y 0x02
      ptri+=1;                                   // avanzo 1 ptri para saltarme 0x02
      strncpy(s2,ptri,ptrf-ptri);                // Luego s2 lo extraigo entre ptri y ptrf
   }

retorno:

   return(error);
}

// Procesa_comando: Hace cosas o manda hacerlas ... //////////////////////

void Procesa_comando(void){

   int1 procesado_ok=0;                          // Flag para comprobar si he procesado algo válido
   char xcommand[MAXLENCOMMAND];                 // Comprobador de comando recibido
   int  error;
   char *ptrx;

   // COMANDO = "" intro en blanco ---------------------------------------
   strcpy(xcommand,"" );
   if(!strcmp(buffrec,xcommand)){
      procesado_ok=1;
      goto fin_procesa;
   }
   // COMANDO = "?" ------------------------------------------------------
   strcpy(xcommand,"?" );
   if(!strncmp(buffrec,xcommand,strlen(xcommand))){
      Send_opts();
      procesado_ok=1;
      goto fin_procesa;
   }
   // COMANDO = "strcat" -------------------------------------------------
   strcpy(xcommand,"strcat" );
   if(!strncmp(buffrec,xcommand,strlen(xcommand))){
      error=extrae_argumentos(2);
      if(error!=0){
         printf("
Error: numero erróneo de argumentos" );
      }
      else{
         strcpy(sr,s1);
         strcat(sr,s2);
         printf("

%s + %s = %s
",s1,s2,sr);
      }
      procesado_ok=1;
      goto fin_procesa;
   }
   // COMANDO = "strlwr" -------------------------------------------------
   strcpy(xcommand,"strlwr" );
   if(!strncmp(buffrec,xcommand,strlen(xcommand))){
      error=extrae_argumentos(1);
      if(error!=0){
         printf("
Error: numero erróneo de argumentos" );
      }
      else{
         strcpy(sr,s1);
         strlwr(sr);
         printf("

%s -> %s
",s1,sr);
      }
      procesado_ok=1;
      goto fin_procesa;
   }
   // COMANDO = "strstr" -------------------------------------------------
   strcpy(xcommand,"strstr" );
   if(!strncmp(buffrec,xcommand,strlen(xcommand))){
      error=extrae_argumentos(2);
      if(error!=0){
         printf("
Error: numero erróneo de argumentos" );
      }
      else{
         strcpy(sr,s1);
         ptrx=strstr(sr,s2);
         if(ptrx==0){
            printf("

%s no está en %s
",s2,s1);
         }
         else{
            printf("

%s empieza en el caracter %uº de %s
",s2,(ptrx-&sr[0])+1,s1);
         }
      }
      procesado_ok=1;
      goto fin_procesa;
   }
fin_procesa:

   // COMANDO ERRÓNEO - ¿ezo qué é lo que é ?-----------------------------
   if(procesado_ok==0){
      printf("
?%s",buffrec);
   }
}









Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 28 de Febrero de 2006, 12:54:00
Recomiendo encarecidamente, para los interesados en el manejo de strings,
el estudio detallado de la funcion int extrae_argumentos(int cuantos)
ya que implementa las esencias fundamentales de su tratamiento.

Tened en cuenta al recibir vía RS232 el caracter 0x0D (Enter) disparo el
procesado de lo recibido hasta entonces en buffrec[]

Así el comando strcat asdfg qwerty[0x0D] hace  

buffrec[] = "strcat asdfg qwerty "

por lo que entonces debo:

detectar que se trata del comando strcat cosa que hago con :

   strcpy(xcommand,"strcat" );
   if(!strncmp(buffrec,xcommand,strlen(xcommand))){

dentro de procesa_comando()

extraer sobre s1[] y/o s2[] los argumentos asdfg y qwerty que
es lo que realiza :

   error=extrae_argumentos(2);

y ...
realizar la función real strcat para presentar el resultado en :

   strcpy(sr,s1);
   strcat(sr,s2);
   printf("%s + %s = %s",s1,s2,sr);

Lo demás solo sirve para que todo esto funcione.

Si llegais a comprender su funcionamiento todo lo demas es obvio y sencillo.

¡Que tengais suerte! y no dudad en consultar aspectos oscuros o dudas que
tengáis.



Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: antoniof en 01 de Marzo de 2006, 02:29:00
Diox RedPIC me tienes locolocolocoloco

Sin duda cuando te propones algo lo consigues.

Vamos a tener que llamar a la universidad de Sevilla o recoger unas cuantas firmas para que te den el titulo de Ingeniero YA!!!

Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 01 de Marzo de 2006, 02:44:00
Ja, ja, ja ... a lo mejor ese es el único metodo posible para que me den el titulo.

Cuando estuve a finales de los 70 estudiando pa ingeniero me echaron a la calle ...
era demasiado aficionado al vidrio y las faldas Muchas risas Muchas risas Muchas risas
Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: pocher en 01 de Marzo de 2006, 12:07:00
No tengo más remedio que entrar para felicitarte.

Eres uno más del FORO que hace grandes cosas y no le dá importancia. ¡Bien, bien!

RebotadoRebotadolocolocoRebotadoRebotado
Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 01 de Marzo de 2006, 12:26:00
Gracias Pocher, la verdad es que me divierto como un Cosaco en una Taberna
durante la Hora Feliz en que todo es grátis ja ja ja Muchas risas Muchas risas Muchas risas

Y ahora que nadie nos lee ... te confieso que lo hago porque me da mucho
coraje de ver a otros foreros que lo contestan ABSOLUTAMENTE TODO pero
nunca abren un hilo nuevo, nunca se imaginan un proyecto aunque sea
tonto, nunca comparten lo que han hecho ... sino que solo dan lecciones
a diestro y siniestro pero de los que nunca hemos visto algo que ellos mismos
hayan hecho

 .... en fin ... que me da pena ... y pa contrarrestar ... po eso Muchas risas

Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: Sispic en 01 de Marzo de 2006, 13:57:00
Impresionante Diego ademas muy limpio .

Solo me quedo con la intriga -> que será eso del VIDRIO ? que te hizo perder el escrivir desquiciado
Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 01 de Marzo de 2006, 14:07:00
Ja, ja, ja Me pasé los tres años que duré en la facultad de ingenieros de ...
juerga en juerga, empalmando las borracheras una con otra y ...
al final me dijeron amablemente que preferían prescindir de mi y
de mis servicios. ja, ja, ja

Muchas risas  Muchas risas  Muchas risas  Muchas risas  Muchas risas

Hoy lo lamento pero ya es tarde. (25 años tarde)

Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: vszener en 02 de Marzo de 2006, 09:59:00
Unirme a mis compañeros en las felicitaciones!y para mi vuesamerced RedPic, amigo, forero y maestro solo me queda decir que el titulo de ingeniero se te queda pequeño!!!

Cada dia me gusta mas este foro!tanto por la informacion que contiene como la gente que lo habita!


Suerte!!!Giño
Título: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 05 de Marzo de 2006, 14:19:00
Titulo : Funciones Date y Time
=====================

Y ahora en otro orden de cosas vamos a tratar una serie de funciones
bajo el denominador común de Date y Time.

Estas funciones no son mías, son una traducción de lo originalmente publicado
en el Foro CCS Library y su autor es Aurelian Nichita
Yo me he limitado a traducirlas al español y probar que funcionan.

Incluye las funciones:

esAgnoBisiesto(int y)
diasDesdeAgno1(int y, int m, int d)
segundosDesdeHora0(int h, int m, int s)
segundosDesdeAgno1(int yr, mo, dy, hr, mi, se)
segundosEntre(int yr1, mo1, dy1, hr1, mi1, se1, yr2, mo2, dy2, hr2, mi2, se2)
ISODiaDeLaSemana(int YY, int MM, int DD)
ISONumeroDeLaSemana(int YY, int MM, int DD, int& weekOfYear, int& actualYear)

Codigo:


// Definiciones y Funciones de Date Time ////////////////////////////////////////////////

// Números ISO de los dias de la semana
 
#define LUNES     1
#define MARTES    2
#define MIERCOLES 3
#define JUEVES    4
#define VIERNES   5
#define SABADO    6
#define DOMINGO   7

const int Dias_de_cada_Mes[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
                                      {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} };

const int Orden_Dias_Semana[7] = {6, 7, 1, 2, 3, 4, 5};

#define SEGUNDOS_EN_UN_DIA 86400

#define SEGUNDOS_EN_UNA_HORA 3600
#define SEGUNDOS_EN_UN_MINUTO 60
#define MINUTOS_EN_UN_DIA 1440
#define MINUTOS_EN_UNA_HORA 60
#define HORAS_EN_UN_DIA 24


// Algunas funciones que seran usadas mas adelante

#inline
short esAgnoBisiesto(int y) {
  return (y % 4 == 0);
}

#separate
int32 diasDesdeAgno1(int y, int m, int d) {
  int32 dias = 0;
  int i;
  short es_bisiesto;

  es_bisiesto = esAgnoBisiesto(y);
  for (i=1; i<y; i++) {
    if (esAgnoBisiesto(i))
      dias += 366;
    else
      dias += 365;
  }
  for (i=1; i<m; i++)
    dias += Dias_de_cada_Mes[es_bisiesto][ i ];
  dias += d;

  return dias;
}

#separate
int32 segundosDesdeHora0(int h, int m, int s) {
  int32 segundos;
  segundos = (int32)h * SEGUNDOS_EN_UNA_HORA;
  segundos += (int32)m * SEGUNDOS_EN_UN_MINUTO;
  segundos += s;
  return segundos;
}

#separate
int32 segundosDesdeAgno1(int yr, mo, dy, hr, mi, se) {
  int32 segundos;
  segundos = diasDesdeAgno1(yr, mo, dy) * SEGUNDOS_EN_UN_DIA;
  segundos += segundosDesdeHora0(hr, mi, se);
  return segundos;
}

// Calcula el numero de segundos entre dos fechas y horas

// Adaptado para años entre 2001 y 2135 (limitado por el tamaño de los int32)


#separate
int32 segundosEntre(int yr1, mo1, dy1, hr1, mi1, se1, yr2, mo2, dy2, hr2, mi2, se2) {
  int32 inicio;
  int32 final;
  inicio = segundosDesdeAgno1(yr1, mo1, dy1, hr1, mi1, se1);
  final  = segundosDesdeAgno1(yr2, mo2, dy2, hr2, mi2, se2);
  if (inicio > final)
    return inicio-final;
  else
    return final-inicio;
}

// Calculo del dia de la semana. Adaptado SOLO para años del 2000 al 2099

#separate
int ISODiaDeLaSemana(int YY, int MM, int DD) {
  signed long diaDeLaSemana;
  int cent = 20;  // YYYY / 100

  // Algoritmo de congruencia de Zeller

  if (MM < 3) {
    MM = MM + 12;
    if (YY > 0)
      YY--;
    else {
      YY = 99;
      cent--;
    }
  }

  diaDeLaSemana = DD;
  diaDeLaSemana += (((signed long)MM + 1) * 26) / 10;
  diaDeLaSemana += YY;
  diaDeLaSemana += YY / 4;
  diaDeLaSemana += cent / 4;
  diaDeLaSemana -= cent * 2;

  while (diaDeLaSemana < 0)
    diaDeLaSemana += 7;

  diaDeLaSemana %= 7;

  return Orden_Dias_Semana[(int)diaDeLaSemana]; // Ahora tenemos el número ISO del dia de la semana
}

// Calculo de número ISO de la semana. Adaptado SOLO para años del 2001 al 2098

#separate
void ISONumeroDeLaSemana(int YY, int MM, int DD, int& weekOfYear, int& actualYear)
{
  signed long diaDelAgno;
  int DiaDeLaSemanaInicial;
  int DiaDeLaSemanaFinal;
  short bisiesto;
  signed int i;

  do {
    bisiesto = esAgnoBisiesto(YY);
    diaDelAgno = 0;

    for (i=1; i<=MM; i++) {
      if (i < MM)
        diaDelAgno += Dias_de_cada_Mes[bisiesto][ i ];
      else
        diaDelAgno += DD;
    }
    actualYear = YY;
    DiaDeLaSemanaInicial = ISODiaDeLaSemana(actualYear, 1, 1);

    if (DiaDeLaSemanaInicial > JUEVES)
      diaDelAgno -= 8 - DiaDeLaSemanaInicial;
    else
      diaDelAgno += DiaDeLaSemanaInicial - 1;

    if (diaDelAgno <= 0)
      weekOfYear = 0xFF;
    else {
      weekOfYear = diaDelAgno / 7;
      if (diaDelAgno % 7 != 0)
        weekOfYear++;
      if (weekOfYear > 52) {
        DiaDeLaSemanaFinal = DiaDeLaSemanaInicial;
        if (bisiesto) {
          if (DiaDeLaSemanaFinal == DOMINGO)
            DiaDeLaSemanaFinal = LUNES;
          else
            DiaDeLaSemanaFinal++;
        }
        if (DiaDeLaSemanaFinal < JUEVES) {
          actualYear++;
          weekOfYear = 1;
        }
      }
    }

    if (weekOfYear == 0xFF) {
      if ((--DD)==0) {
        if ((--MM)==0) {
          YY--;
          MM = 12;
        }
        DD = Dias_de_cada_Mes[esAgnoBisiesto(YY)][MM];
      }
    }

  } while (weekOfYear == 0xFF);
}




Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 16 de Abril de 2006, 18:12:35
El concepto de flotabilidad es inaprensible ... o sí  :lol:
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: Modulay en 16 de Abril de 2006, 18:16:43
No cojo el concepto :shock:
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 16 de Abril de 2006, 18:20:15
Es que me he tirado un buen rato buscando este post (parece que al buscador se le había atragantado y he tenido que buscarla página a página  :P )

Asi que me he dicho: Ponerle chincheta no, ya que no me gusta autochinchetearme, asi que le he posteado una disquisición filósofica sobre la flotabilidad ... para que flote ...  :lol:  :lol:  :lol:

y flota.

(perdonad la disgresión)

Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: Nocturno en 17 de Abril de 2006, 01:53:41
Ya tienes tu chincheta, amigo Diego, y descansa algo más hombre, que se te llena la boca de palabros extraños y no hay quien te entienda  :D .
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: jfh900 en 02 de Mayo de 2006, 14:47:32
Esta es una función para convertir una cadena Hexadecimal en un long. No he utilizado la función de RedPic para convertir un caracter hexadecimal en número por que me da un error el compilador, por lo que la he sustituido por otra.

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

long ChHexToInt( char * cString )
{
int  nIdx;  // Índice para recorrer la cadena
long nRes;  // Resultado acumulado
int  nChar; // Carácter en número
int  nLong; // Longitud de la cadena

nLong = strlen(cString);

for(nIdx=0;nIdx<nLong;nIdx++)
   {
   nChar = AscHex2Int(cString[nIdx]);
   nRes = 16*nRes+nChar;
   }

return(nRes);
}


signed int AscHex2Int(char ch) // Convierte un caracter ascii hex a int
{             
switch(ch)
   {
   case '0': return 0;
   case '1': return 1;
   case '2': return 2;
   case '3': return 3;
   case '4': return 4;
   case '5': return 5;
   case '6': return 6;
   case '7': return 7;
   case '8': return 8;
   case '9': return 9;
   case 'a':
   case 'A': return 10;
   case 'b':
   case 'B': return 11;
   case 'c':
   case 'C': return 12;
   case 'd':
   case 'D': return 13;
   case 'e':
   case 'E': return 14;
   case 'f':
   case 'F': return 15;
   default: return -1;
   }
}   
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: Cryn en 23 de Mayo de 2006, 13:21:09
Hola, saludos a todos espero se pueda, necesito una funcion que reciba de parámetros, un PIN y número en ms, y haga un parpadeo de la cantidad de ms en el pin especificado. Como puedo hacerlo??

void parp(PIN,#ms)
{
    parpadeo en PIN, con retardo en #ms    // bueno algo parecido
}

puede adicionarse otro parametro para determinar la cantidad de veces del parpadeo, seguramente habra un for dentro la función
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: jfh900 en 23 de Mayo de 2006, 20:43:36
No esta claro lo que quieres hacer,cuando indicas ms que quiere decir que si vale 10 tiene que parpadear 10 veces o parpadear con un retardo de 10 ms y en este último caso que tendria que hacer un solo parpadeo (encender y apagar) o lo tendria que hacer mas veces

Saludos.
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: Cryn en 24 de Mayo de 2006, 11:58:48
aclaro un poco; todos parametros:

PIN = Pin en el cual se realizara el parpadeo (RA1, RA5, RB7,etc.) cualquier pin de puerto.
#ms = el tiempo que duradá encendido en ms, ya que se usará seguramente un delay_ms(); por ej si quiero que parpadee cada segundo en viare 1000
otro parametro = indicar las veces que realizará el parpadeo, ej paraentro = 1 parpadeará solo una vez; =10 parpadeará 10 veces, y asi sucesivamente, segun el dato de parametro que sea enviado.

espero me hayan entendio, pues muchas gracias por la respuesta.
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: LabPIC en 26 de Mayo de 2006, 12:55:36
Hola a todos soy principiante  :z) en la programacion en C para PIC´s especificamente, y necesito saber si hay alguna librería en CCS para el puerto USB. De antemano gracias  :mrgreen:

Saludos LabPIC
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: Arbolito en 26 de Mayo de 2006, 13:31:46
si en la carpeta drivers se llama pic18_usb y pic_usb
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: LabPIC en 26 de Mayo de 2006, 20:26:04
Ups creo que se pq no tengo :z) estos drivers para la usb , lo que pasa es que es la version demo la que tengo  :D, de cualquier manera gracias juan ya lo conseguire por aca.

Saludos LabPIC  :mrgreen:
Título: Re: Ejemplitos en C -- Error en AgnoBisiesto
Publicado por: oedipus en 01 de Junio de 2006, 05:16:25
...
#inline
short esAgnoBisiesto(int y)
{
return (y % 4 == 0);
}
...

Un año es bisiesto si es divisible por 4, excepto aquellos divisibles por 100 pero no por 400. Luego la función es erronea. Algo correcto sería lo siguiente:


#define TRUE 1
#define FALSE 0

int GLeapYearQ(int y)
{
   if( (y % 4) != 0 ) return FALSE;
   if( ( y % 100 ) != 0 ) return TRUE;
   if( ( y % 400) != 0 ) return FALSE;
   return TRUE;
}
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 01 de Junio de 2006, 15:38:37
ja, ja, ja  :D  :D  :D

Tienes toda la razón.  :P

Ya tuvimos tuvimos el mismo intercambio de mensajes con este tema el maestro nocturno y yo ... pero no logro encontrar donde están esos mensajes asi que ... copio aquí lo esencial de los mismos:

Primitivamente el calendario romano constaba de 10 meses; se atribuye a la influencia de los sabinos la introducción del calendario de 12 meses con tres fechas mensuales fijas: Calendas, Nonas e Idus.

Julio César estableció el calendario de 365 días con años bisiestos y Gregorio XIII lo reformó tal y como es hoy.

Las Calendas eran el "día 1" de cada mes. Los días anteriores al día 1 hacian referencia a las Calendas de ese mes. v.g. en un año normal de 365 días: el 1 de marzo, era las Calendas de Marzo; el 28 de febrero era el día anterior de Calendas de Marzo; el 27 de febrero eran 3 días antes de Calendas de Marzo; el 26 de febrero eran 4 días antes de Calendas de Marzo; el 25 de febrero eran 5 días antes de Calendas de Marzo; el 24 de febrero eran 6 días antes de Calendas de Marzo; el 23 de febrero eran 7 días antes de Calendas de Marzo.

Desde el año 45 AC, Febrero cada 4 años tuvo dos días llamados "el sexto antes de Calendas de Marzo". El día extra era originalmente el segundo de ellos, pero desde el siglo III fue el primero. De ahí el término bisexto (luego "bisiesto") para el 24 de febrero en un año bisiesto.

Este día se añade para corregir el desfase que existe entre la duración real de los años: 365 días y 6 horas aproximadamente. Esto hace que se corrija cada cuatro años (los años múltiplos de cuatro) que se acumulan 24 horas.

El calendario juliano consideraba bisiesto los años divisibles por cuatro. Así el año juliano dura 365 días +1/4=365,25 días (más que el año trópico que dura 365,2422 días).

La regla completa para los años bisiestos según el calendario Gregoriano es:

Un año es bisiesto si es divisible por 4, excepto aquellos divisibles por 100 pero no por 400.
Es decir los años que sean divisibles por 4 serán bisiestos; aunque no serán bisiestos si son divisibles entre 100 (como los años 1500, 1700, 1800, 1900 y 2100) a no ser que sean divisibles por 400 (como los años 1600, 2000 ó 2400). En 400 años debe haber 97 años bisiestos, de esa manera el año del calendario gregoriano se mantiene muy parecido al año solar. Así el año gregoriano dura 365 días +1/4-3/400=365,2425 días (más que el año trópico que dura 365,2422 días).

Como el error es de 0,0003 días por año, podría parecer que al cabo de tres mil años se habrá acumulado un día de error. Pero en realidad no sabemos exactamente cuándo llegará el error a un día. La cifra de 365,2422 dias por año trópico no es del todo exacta, porque tanto la duración del año trópico, como la velocidad de rotación de la tierra, van cambiando con los siglos, y de una manera que no es completamente predecible


Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: jfh900 en 01 de Junio de 2006, 15:55:24
Si pero la función sigue estando mal:

Citar
#define TRUE 1
#define FALSE 0

int GLeapYearQ(int y)
{
   if( (y % 4) != 0 ) return FALSE;
   if( ( y % 100 ) != 0 ) return TRUE;
   if( ( y % 400) != 0 ) return FALSE;
   return TRUE;
}

Yo pondria esta versión:

#define TRUE 1
#define FALSE 0

int GLeapYearQ(int y)
{
   if ( (y % 4) = 0 ) &       // Sea Divisible por 4 "Y"
        ((y % 100) != 0) |   // ( No divisible por 100 "O"
         (y % 400) = 0)))    //   Divisible por 400 )
      return TRUE;
   else
      return FALSE;
}
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: oedipus en 02 de Junio de 2006, 06:48:11
Si pero la función sigue estando mal.

Yo pondria esta versión:

#define TRUE 1
#define FALSE 0

int GLeapYearQ(int y)
{
   if ( (y % 4) = 0 ) &       // Sea Divisible por 4 "Y"
        ((y % 100) != 0) |   // ( No divisible por 100 "O"
         (y % 400) = 0)))    //   Divisible por 400 )
      return TRUE;
   else
      return FALSE;
}

No, a ver, la función que he puesto, puede ser más o menos elegante, pero es correcta. En cambio cuidado que con las prisas, creo que has puesto el AND && y el OR mal :).

Copiando (y modificando) del maravilloso "The C Programming Language" De Kernighan y Ritchie:

#define TRUE 1
#define FALSE 0

int is_year_leap (int year) {
    if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)
         return TRUE;
   else
        return FALSE;
}
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: jfh900 en 03 de Junio de 2006, 13:26:12
Efectivamente tienes razón.

Un saludo.
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 29 de Junio de 2006, 17:55:45
Una introducción al uso de printf fprintf y sprintf

Hay tres funciones parecidas en cuyo nombre aparece el printf, y que son la printf propiamente dicha, fprintf y sprintf.

La mas usual es printf("Hola mundo"); que escribe un string en el puerto serie del PIC. A esta misma funcion se le pueden "empotrar" el contenido de una o varias variables dentro del string a enviar. Para ello disponemos de la posibilidad de colocarle dentro unos carácteres especiales que van a indicar que allí deseamos mostrar el contenido de cierta variable.

Por ejemplo si deseamos mostrar este mismo texto de "Hola mundo" pero desde una variable y no desde dentro del printf podemos hacerlo así:

char mistring[]="Hola mundo";
printf("Mi frase favorita es %s",mistring);


Esto dará como resultado que se envíe por el puerto serie la cadena "Mi frase favorita es Hola mundo".

Para cada tipo de variable, entera, flotante, con o sin signo, etc. tenemos su propia forma de indicarle la representación en printf anteponiéndole el consabido %:

C Character
S String or character
U Unsigned int
x Hex int (lower case output)
X Hex int (upper case output)
D Signed int
e Float in exp format
f Float
Lx Hex long int (lower case)
LX Hex long int (upper case)
Iu unsigned decimal long
Id signed decimal long
% Just a %

printf asume que la salida del string es la STDOUT o sea el puerto serie.

Pero fprintf es igual salvo que podemos indicarle cuál va a ser la salida donde deseamos que nos vuelque el resultado. Al declarar #use_rs232 podemos indicarle un "canal" o nombre de esa salida serie, fprintf puede decirle qué canal en concreto es el que vamos a utilizar.

#use rs232(baud=9600, xmit=PIN_B1,rcv=PIN_B2, stream=CANAL1)
#use rs232(baud=9600, xmit=PIN_A2,rcv=PIN_A3, stream=CANAL2)
#use rs232(baud=9600, xmit=PIN_C6,rcv=PIN_C7, stream=CANAL3)

fprintf(CANAL2,"Hola mundo");


enviaría nuestro texto al canal CANAL2 definido en la segunda de nuestras declaraciones.

Y por último:

Vemos que con el uso de los "%" podemos "representar las mismas variables de distinta forma.

char mivar='K';    

es una variable de tipo char de un solo byte cuyo contenido lo hemos inicializado con el caracter ASCII K, si ahora jugamos con él dentro de printf podemos obtener resultados muy curiosos:

printf("%c %U %H %h",mivar,mivar,mivar,mivar);

enviará al puerto serie el string "K 75 4B 4b"

Como podeís ver printf muestra distintas representaciones de un mismo contenido "formateado".

Esto nos lleva a la última de las funciones que es sprintf.

sprintf es identica a printf salvo que el resultado en vez de lanzarlo por el puerto serie lo guarda en una variable de tipo string que le indiquemos.

char miascii = 'K';
char mistring[3];
mistring = sprintf("%H",miascii);


¿Cuanto vale mistring? Pues "4B\0" (Un asccii '4', un ascii 'B' y un ascii 0) o sea que hemos hecho una conversión de ASCII a integer y de éste a un string hexadecimal de un solo salto.  :mrgreen:  :mrgreen:  :mrgreen:

(Como siempre. Me ha salido otra novela  :D  :D  :D)
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: pictolero en 30 de Junio de 2006, 21:18:05
yo soy nuevo en este foro y solo hace muy poco supe que los pic se podian programar en c
con esto doy a entender que no tengo idea como hacerlo si alguien tubiera un tutorial de c para pic que lo pudiera compartir gracias
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: Nocturno en 01 de Julio de 2006, 02:46:22
Un tutorial como tal no sé si encontrarás, pero te recomiendo que examines estos hilos del foro, en orden cronológico y haciendo los ejemplos que hay en ellos.
Te puedo garantizar que aprederás C, y no serás el primero en comprobarlo.

Microcursillo en C (http://www.todopic.com.ar/foros/index.php?topic=4533.0)
Ejemplitos en C para 16F648A (http://www.todopic.com.ar/foros/index.php?topic=4530.0)
Ejemplitos en C para 16F876A (http://www.todopic.com.ar/foros/index.php?topic=4531.0)

Y siempre teniendo como referencia para dudas este mismo hilo, el de las funciones favoritas del amigo Diego.
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: piriots en 12 de Julio de 2006, 18:59:00
Hola!! estan muy buenas y elegantes estas funciones. Ahora estaba por probar la de ascii hex a int pero el ccs me da error en  el  r=d-"0";  Yo no veo ningun problema en la funcion pero el compilador me dice bad expression syntax. Estoy usando la version 3.236 del CCS. Alguien sabe que puede estar pasando??

Salu2
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: djpalas en 12 de Julio de 2006, 19:14:02
Buenas a tod@s

Piriots el problema es que estas utilizando comillas dobles "0". Puesto que tenemos un variable r del tipo int (8Bits) y d es del tipo char (también 8Bits), el problema es que al tipo char le estas quitanto una caneda de caracteres.
Al poner "0" estas declarando un array del tipo char de 2 elementos, el primero es el caracter 0, y el 2º es el caracter NULL para finalizar la cadena.

Por lo que creo que te irá si pones:
r=d-'0';

Utilizando solo comillas simples ;)

Espero que te sirva de ayuda.
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: piriots en 12 de Julio de 2006, 19:47:56
Muchas gracias Djpalas, se me habia pasado por alto, con esto arreglado funciona muy bien. Redpic podrias corregir este pequeño detalle para que no suceda otra vez?

Salu2 y muchas gracias!!
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 12 de Julio de 2006, 21:31:07
Corregido  :oops:
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 13 de Julio de 2006, 09:42:10
Leer y Escribir en la EEPROM interna del PIC variables int 16 bits (2 bytes)

Empezemos por el principio: read_eeprom(address) y write_eeprom(address, byte) trabajan con int8, un byte de 8 bits. Para leer y escribir int16, dos bytes de 8 bits cada uno, hay que fabricarse unas funciones "puente" de este estilo:

Código: C
  1. void write_eeprom_16bits(int address, long* val){
  2.    int pLow, pHigh;
  3.    pLow  = val;
  4.    pHigh = val>>8;
  5.    write_eeprom(address,pHigh);
  6.    delay_ms(12);
  7.    ++address;
  8.    write_eeprom(address,plow);
  9.    delay_ms(12);
  10. }
  11.  
  12. long read_eeprom_16bits(int address){
  13.    int  pLow, pHigh;
  14.    long result;
  15.    pHigh  = read_eeprom(address);
  16.    ++address;
  17.    pLow  = read_eeprom(address);
  18.    result=(pHigh<<8);
  19.    result+=pLow;
  20.    return result;  
  21. }

Con ellas he escrito un programa de Test que en el reset guarda un valor de 16 bits en la variable x, llama a la función write_eeprom_16bits y se queda a la espera "escuchando" la RS232 ...

al recibír la tecla 'r' realiza la funciona inversa, lee sobre la variable y, también de 16 bits, desde la misma dirección en la que antes escribimos con read_eeprom_16bits y monitoriza el resultado.

Todo este recorrido esta salpicado de printf's para poder ver todo el proceso paso a paso:

(http://picmania.garcia-cuervo.com/images/PICC_EEPROM_16Bits_Dump.JPG)

El programa completo tal como quedó para poder monitorizar todos los pasos es:

Código: C
  1. // eeprom_16bits plus rs232
  2. #include <18f4550.h>
  3. #fuses HS,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT,NOPBADEN, NOLVP
  4. #use delay(clock=20000000)
  5. #use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
  6.  
  7. char Keypress = 0x00;
  8. char Command  = 0x00;
  9.  
  10. long x,y;
  11.  
  12. #int_rda
  13. void serial_isr() {
  14.  
  15.    Keypress=0x00;
  16.    if(kbhit()){
  17.       Keypress=getc();
  18.       if(Keypress!=0x00){
  19.          if(Keypress=='r'){
  20.             Command=Keypress;            
  21.          }    
  22.          putchar(keypress);
  23.          keypress=0x00;
  24.       }
  25.    }
  26. }
  27.  
  28. void write_eeprom_16bits(int address, long* val){
  29.  
  30.    int pLow, pHigh;
  31.    printf("write_eeprom_16bits( address=%u, val=%lx)\r\n",address,val);
  32.    pLow  = val;
  33.    pHigh = val>>8;
  34.    printf("write_eeprom( address=%u, val=%x)\r\n",address,pHigh);
  35.    write_eeprom(address,pHigh);
  36.    delay_ms(12);
  37.    ++address;
  38.    printf("write_eeprom( address=%u, val=%x)\r\n",address,pLow);
  39.    write_eeprom(address,plow);
  40.    delay_ms(12);
  41. }
  42.  
  43. long read_eeprom_16bits(int address){
  44.  
  45.    int  pLow, pHigh;
  46.    long result;
  47.    printf("read_eeprom_16bits( address=%u)\r\n",address);
  48.    pHigh  = read_eeprom(address);
  49.    printf("read_eeprom( address=%u) = %x\r\n",address,pHigh);
  50.    ++address;
  51.    pLow  = read_eeprom(address);
  52.    printf("read_eeprom( address=%u) = %x\r\n",address,pLow);
  53.    result=(pHigh<<8);
  54.    result+=pLow;
  55.    return result;  
  56. }
  57.  
  58.  
  59. void main(){
  60.  
  61.    disable_interrupts(global);
  62.  
  63.    setup_adc_ports(NO_ANALOGS);
  64.    setup_adc(ADC_OFF);
  65.    setup_spi(FALSE);
  66.    setup_psp(PSP_DISABLED);
  67.    setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
  68.    setup_timer_0(RTCC_OFF);
  69.    setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
  70.    setup_timer_2(T2_DISABLED,0,1);
  71.    setup_timer_3(T3_DISABLED);
  72.    setup_comparator(NC_NC_NC_NC);
  73.    setup_vref(FALSE);
  74.    port_b_pullups(FALSE);
  75.    set_tris_e(0b00010000);
  76.    set_tris_c(0b10000000);
  77.    
  78.    delay_ms(1000);
  79.  
  80.    output_High(PIN_E0);
  81.    output_High(PIN_E1);
  82.    output_High(PIN_E2);
  83.    printf("\r\n");
  84.    printf("18F4550 in RRBOARAD2\r\n");
  85.    printf("Test EEPROM with 18 bits\r\n\n");
  86.    delay_ms(500);
  87.    output_Low(PIN_E0);
  88.    output_Low(PIN_E1);
  89.    output_Low(PIN_E2);
  90.  
  91.    Command=0x00;
  92.    enable_interrupts(int_rda);
  93.    enable_interrupts(global);
  94.  
  95.    x=0x1f2f;
  96.    y=0;
  97.    
  98.    printf("initial 16 bits x = %lx (%lu), y = %lx (%lu)\r\n",x,x,y,y);
  99.    write_eeprom_16bits(0,x);
  100.    printf("\r\n");
  101.  
  102.    while(TRUE) {
  103.       if(Command=='r'){
  104.          Command=0x00;
  105.          printf("\r\n\n");
  106.          y=read_eeprom_16bits(0);
  107.          printf("final 16 bits x = %lx (%lu), y = %lx (%lu)\r\n",x,x,y,y);
  108.       }
  109.    }
  110. }

Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: MGLSOFT en 13 de Julio de 2006, 10:42:36
Yo me hice una libreria para la lectura y escritura de la EEPROM aprovechandome de los ejemplos que da el CCS.
Lo mejorcito es que comprueba si el valor a escribir es igual al que esta escrito, evitando consumir las operaciones de escritura sin sentido de hacerlo.
La adjunto por si les sirve a alguno. :mrgreen: :mrgreen:
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: MGLSOFT en 15 de Enero de 2007, 12:08:26
En que tipo de display piensas mostrar este valor?
Si es en LCD no necesitas hacer la conversion extraña que haces, ya que CCS permite mostrar un valor float o entero doble con los decimales que necesites... :-) :-) :-)
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: LABmouse en 15 de Enero de 2007, 14:31:49
Hola Amigos.

Doctor , le comento mi caso.  :D

Estoy intentando convertir un numero float a BCD para poderlo mostrar en display.

A mi parecer la mejor manera de hacerlo es con la funcion sprintf

Sigo los pasos de nuestro amigo RedPic


char miascii = 'K';
char mistring[3];
mistring = sprintf("%H",miascii);


aproposito me saca un error elcompilador y mirando la ayuda de CCS, el tiene otra forma de usar el sprintf.

char mystring[20];

long mylong;

 

mylong=1234;

sprintf(mystring,"<%lu>",mylong);

// mystring now has:

//      < 1 2 3 4 > \0


Maestro RedPic,sera que tienes un error de escritura?, ¿o es que yo no la se utilizar?

Mi programa tiene lo siguiente:

float    lectura_ADC;
float    TEMPERATURA;
float    RESISTENCIA;



lectura_ADC=read_adc();
lectura_ADC=lectura_ADC*5;
lectura_ADC=lectura_ADC/1023;

for(i=0;i<=9;i++) temperatura_BCD=0;

sprintf(temperatura_BCD,"%f",lectura_ADC);
umil=temperatura_BCD[0];
centena=temperatura_BCD[1];
decena=temperatura_BCD[2];



Compila bien y todo, pero no funciona! :cry:

Mi pregunta es la siguiente:

En el vector en donde se guarda el resultado del sprintf, quedan numeros ascii o quedan ya en decimal?. Porque probe para ambos casos y no funciona.

Ustedes me recomiendan otra forma? Esta del sprintf si la puedo usar para esta tarea?.

Muchas Gracias.


Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: LABmouse en 15 de Enero de 2007, 15:15:29
Bueno, ya esta funcionando.

De esta forma fue en la que trabajo.

      lectura_ADC=read_adc();
      lectura_ADC=lectura_ADC*5;
      lectura_ADC=lectura_ADC/1023;
      sprintf(temperatura_BCD,"%2.2f",lectura_ADC);

      umil=ascci_dec(temperatura_BCD[0]);
      centena=ascci_dec(temperatura_BCD[1]);
      decena=ascci_dec(temperatura_BCD[3]);
      unidad=ascci_dec(temperatura_BCD[4]);


Bueno la conclucion es que en la variable temperatura_BCD quedan guardados los BCD pero en ascii.
Lo otro que me ayudo fue el truco de condicionar la funcion sprintf , indicandole que necesito 2 enteros y 2 decimales. es por ello que aparece %2.2f.

me explico con un ejemplo.
sea:
lectura_ADC un variable tipo float, con el valor de 12.1203

temperatura_BCD[5] un vector tipo char.

cuandose se ejecuta

sprintf(temperatura_BCD,"%2.2f",lectura_ADC);

Se obtiene :

temperatura_BCD[5]  = {'1','2','.','1','2'}




Lo que tengo ahora es el siguiente problema. Uso el PIC18F452. Tiene un cristal de32768hz.  Por hacer los procedimientos anteriores, el display Parapadea demasiado, tanto que se dificulta leerlo. ¿Hay alguna forma de elevar la velocidad de trabajo sin cambiar el cristal?

 
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: MGLSOFT en 15 de Enero de 2007, 15:28:47
Bueno, ya esta funcionando.

De esta forma fue en la que trabajo.

      lectura_ADC=read_adc();
      lectura_ADC=lectura_ADC*5;
      lectura_ADC=lectura_ADC/1023;
      sprintf(temperatura_BCD,"%2.2f",lectura_ADC);

      umil=ascci_dec(temperatura_BCD[0]);
      centena=ascci_dec(temperatura_BCD[1]);
      decena=ascci_dec(temperatura_BCD[3]);
      unidad=ascci_dec(temperatura_BCD[4]);


Bueno laconclucion es que en la variable temperatura_BCD quedan guardados los BCD pero en ascii.

Lo que tengo ahora es el siguiente problema. Uso el PIC18F452. Tiene un cristal de32768hz.  Por hacer los procedimientos anteriores, el display Parapadea demasiado, tanto que se dificulta leerlo. ¿Hay alguna forma de elevar la velocidad de trabajo sin cambiar el cristal?

 

Bueno, por lo que veo utilizas displays de 7 segmentos, cosa que no habias aclarado.

Algunos consejos utiles

Donde pones:
Código: [Seleccionar]
lectura_ADC=read_adc();
      lectura_ADC=lectura_ADC*5;
      lectura_ADC=lectura_ADC/1023;

Ahorras algo de ROM, conviertes a float en un solo paso y ademas es mas legible esto:
Código: [Seleccionar]
float const resoluc=5.0/1023.0;

i=read_adc();
lectura_ADC=i*resoluc;

Para el parpadeo del display lo que creo que debes hacer es poner ese cristal en Tock1 (seguramente quieres temporizar bien o hacer funciones de reloj) y en su lugar poner un cristal de al menos 4 MHz, asi podras manejar bien los tiempos de muestreo de cada numero en los displays antes de rotarlos... :mrgreen: :mrgreen: :mrgreen:
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: LABmouse en 15 de Enero de 2007, 16:15:58
MGLSOFT  tienes razon, solo habia dicho que eran display, pero no 7 segmentos, son 4.Para la operacion matematica, tienes toda la razon, no tiene sentido que el Pic realice las operaciones matematicas que ya se sabe de antemano el resultado.

Bueno, respecto a cambiar el timer,pues lo que pasa es que ya el circuito imrpeso esta fabricado y no es posible cambiar ya nada. La solucion que encontre es cambiar de PIC por el 18F4520 que si tiene oscilador interno creo que de 4Mhz y escompatible pin a pin.

Gracias, y comentare resultados.

Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: PalitroqueZ en 17 de Enero de 2007, 16:56:57
Hola Amigos. Aquí tengo una función que permite llevar un long a string pero en binario, tal vez pueda serles útil

Código: [Seleccionar]
void   long_to_strBIN(long   value){
int   i;
  for(i=0;i<16;i++){   // limpia el array
     cadena[i]='0';
   }
   for(i=0;i<16;i++){
      if(bit_test(value,i)){  // prueba cada bit del long
         cadena[15-i]='1';    // asigna el caracter "1" al array si el bit es uno
      }
      else{
         cadena[15-i]='0'; // asigna el caracter "0" al array si el bit es cero
      }
   }
}

un código ejemplo para usarlo:

Código: [Seleccionar]
#include <16f877.h> //archivo de cabecera

#fuses XT,NOWDT,NOPROTECT // el fuse que configuramos anteriormente (CORREGIDO)
#use delay(clock=4000000) // el clock que tendremos a la entrada del CPU

#define use_portb_lcd TRUE
#include <LCD.c>
char  cadena[16];  // usada dentro de long_a_binario.c
#include <long_a_binario.c>

void main(){
long  value;
set_tris_c(0x1);  //RC0<- entrada
lcd_init();       // inicia la LCD
 value = 0xffff;  // carga value con un long de 65535
   while(1){   //bucle eterno
      while(!input(PIN_C0)){ // pregunta por RC0
         long_to_strBIN(value); //convierte un LONG en un arrays de 16 caracteres
         delay_ms(10);
         printf(lcd_putc,"\f%s\n",cadena); //muestra en binario
         printf(lcd_putc,"%lu",value);    // muestra en decimal
         value--;                         //decrementa el long
         delay_ms(100);                   //retardo
      }
   }
}




la simulación en proteus:

(http://img440.imageshack.us/img440/8255/enproteuske8.th.jpg) (http://img440.imageshack.us/my.php?image=enproteuske8.jpg)


Salu2
Pedro

y el adjunto:
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: walvarez en 20 de Enero de 2007, 13:52:26
no conozco nada sobre programacion en c y quiero aprender desde cero.
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: RedPic en 20 de Enero de 2007, 15:00:43
Pues lo mejor lo tienes en Indice de Hilos Destacados en el sub-Foro de C para Microcontroladores.  (http://www.todopic.com.ar/foros/index.php?topic=14634.0)


y otros ...


Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: AcoranTf en 26 de Junio de 2011, 14:13:49
Hola, a raiz de pedir ayuda para un proyecto con el PIC18F4523, el cual no llego a buen puerto porque era para la empresa en que trabajo y a la hora de compensar el trabajo a quien lo iba a realizar, se echaron atras y todo quedo en nada. Como decia a raiz de eso y ademas que hacia tiempo que tenia ganas de ponerme a estudiar las distintas formas de programar los PIC's, me he decidido a dar un paso adelante. Con la ayuda de un colega del foro, que desde el principio me estuvo ayudando con el susodicho proyecto y que sigue ayudandome en este otro reto y la de todos ustedes, seguro que avanzare en el tema.
De momento ya estoy leyendo y preparandome para hacer algunas cosillas segun vaya entendiendo lo que estudio.
Por otro lado quiero aportar lo que si controlo, que es la electronica, si alguien necesita mi ayuda en ese campo y esta a mi alcance, no dudeis en os ayudare.

Saludos.
Título: Re: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: jukaceledon en 17 de Julio de 2014, 22:16:21
Unirme a mis compañeros en las felicitaciones!y para mi vuesamerced RedPic, amigo, forero y maestro solo me queda decir que el titulo de ingeniero se te queda pequeño!!!

Cada dia me gusta mas este foro!tanto por la informacion que contiene como la gente que lo habita!


Suerte!!!<img   src="http://pics.miarroba.com/caretos/wink.gif" alt="Giño" title="Giño" />

hola estimado mi nombre Juan Carlos, en mis estudios debo ahcer un programa con pic c compiler, tiene los siguientes condiciones

1.- Debe trabajar con un dato decimal y otro entero
2.- se deben ver en un lcd
3.- Via un pulsador se debe aumentar o disminuir el decimal en fraccion de uno y en entero en 1 y verse en el lcd
4.- Se debe guardar en memoria ( el entero en entero y float en float)
5.- al reiniciar el pic los valores guardados en memoria se deben leer y ver en la lcd
6,. y asi sucesivamente

Espero me pueda ayudar

Juka 
Título: Re: RE: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: jukaceledon en 17 de Julio de 2014, 22:19:40
Unirme a mis compañeros en las felicitaciones!y para mi vuesamerced RedPic, amigo, forero y maestro solo me queda decir que el titulo de ingeniero se te queda pequeño!!!

Cada dia me gusta mas este foro!tanto por la informacion que contiene como la gente que lo habita!


Suerte!!!<img   src="http://pics.miarroba.com/caretos/wink.gif" alt="Giño" title="Giño" />

hola estimado mi nombre Juan Carlos, en mis estudios debo ahcer un programa con pic c compiler, tiene los siguientes condiciones

1.- Debe trabajar con un dato decimal y otro entero
2.- se deben ver en un lcd
3.- Via un pulsador se debe aumentar o disminuir el decimal en fraccion de uno y en entero en 1 y verse en el lcd
4.- Se debe guardar en memoria ( el entero en entero y float en float)
5.- al reiniciar el pic los valores guardados en memoria se deben leer y ver en la lcd
6,. y asi sucesivamente

Espero me pueda ayudar

Juka 


Se me olvido agragar lo que llevo, el entero esta bien lo hace pero en el float no me resulta


#include <16f877a.h>
#device  adc = 8 // ADC a 8 bits
#use     delay(crystal = 4MHz)
#include <lcd420.c>
#include <internal_eeprom.c>
#define pulsador pin_c0
#define reset pin_c1
void main (void)
{
int8 entero;
float decimal;
//leo las memorias
   entero = read_eeprom(0);
read_float_eeprom(02);
lcd_init();                   // Inicializar la pantalla.
    while (true)
   {
     
     if(input(pulsador))
     {
   
   entero=entero + 1.9;             // varia el valor.
   decimal=decimal + 1.1;           // Varia el valor.
          }
           
     if(input(reset))
     {
 
   lcd_init();
   entero=00;             //`pone a cero la cuenta.
   decimal=0;             // pone a cero la cuenta.
          }
     
lcd_gotoxy(1,1);
printf(lcd_putc,"ent=");// impr
lcd_gotoxy(8,1);
printf(lcd_putc,"dec=");//imprime tem actual
lcd_gotoxy(5,1);
printf(lcd_putc,"%d",entero);//
delay_ms(100);
lcd_gotoxy(13,1);
printf(lcd_putc,"%f",decimal);
delay_ms(100);
     
//aqui debo escribir en memoria

write_eeprom(0,entero);
delay_ms(10);         
write_float_eeprom(02,decimal);
delay_ms(10);
   }
}
Título: Re: Ejemplitos en C: Mis Funciones favoritas en CCS C
Publicado por: BrunoF en 18 de Julio de 2014, 01:09:19
int8 entero;
float decimal;
//leo las memorias
   entero = read_eeprom(0);


pero no veo que decimal tenga asignado valor inicial. Eso hace que decimal arranque con un valor aleatorio que depende del valor de las posiciones de memoria asociadas a la variable.

Hacé

float decimal = 0.0;

Ninguna variable debería quedar con valor inicial desconocido.

Saludos.