Autor Tema: CURSO DE C  (Leído 7047 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado pacalaconcurso

  • PIC24F
  • *****
  • Mensajes: 718
CURSO DE C
« en: 14 de Febrero de 2004, 13:50:00 »
Son muchos los amigos que comienzan ahora con la programación en C y muchos más los que seguimos teniendo mas de un quebradero de cabeza...

que os parece si proponemos ejercicios que se puedan ir resolviendo entre todos los interesados y de esta forma seguro que cada uno de nosotros aprendemos algo nuevo

como cualquier programa tendra multiples soluciones podemos todos depurar nuestra tecnica....

quien se anima con la primera propuesta??? intentemos que no sea compleja para que todos puedan seguir el ritmo.

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: CURSO DE C
« Respuesta #1 en: 15 de Febrero de 2004, 04:32:00 »
La propuesta me viene de perlas.

1ª PROPUESTA:

Tengo un PIC emisor que tiene almacenadas las variables #byte a, #byte b y #byte c y se quiere enviarlas a un PIC receptor para que a su vez cuando las reciba las almacene en las variables #byte a, #byte b y #byte c .

¿Cuales serían las instrucciones de envio en el PIC emisor y cuales serían las instrucciones de recepción en el PIC receptor para que no haya pérdida de bits en la transmisión?

Desconectado angelmoi123

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 298
    • Construccion de Maquinas CNC
RE: CURSO DE C
« Respuesta #2 en: 16 de Febrero de 2004, 19:06:00 »
Saludos

Hey me anoto con este tema, tengo mucho que aprender, al igual que pacala con el fin de evityar tanto quebradero de cabezas.

angelmoi123

Desconectado pikman

  • Moderador Local
  • PIC24F
  • *****
  • Mensajes: 679
RE: CURSO DE C
« Respuesta #3 en: 16 de Febrero de 2004, 19:38:00 »
Bueno, qui voy con la 2º propuesta:

El reloj de tiempo real de dallas el DS1307, entrega los datos en BCD, por lo que si por ejemplo es la hora 22:32:57,  y si queremos utilizar los datos para que la hora y/o fecha sea una variable de control, metodo muy usado en sistemas de seguridad de todo tipo, si leemos el reloj obtenemos 0x22:0x32:0x57, bien he buscado por todos lados rutinas de conversion de binario a bcd y viceversa y no hay , una de las dos la he resuelto de esta manera:

bcd2bin(int bcd_value)
{
int temp,temp1;

temp = (bcd_value & 0x0F);
temp1= (swap(bcd_value) & 0x0F) *10;
temp = (temp + temp1);

return(temp);

}

Alguien me ayuda con la de binario  a bcd ?,


saludos cordiales

Ariel H. / PiKmAn

 
saludos
PikMan

Desconectado cucaracha

  • PIC24H
  • ******
  • Mensajes: 1409
    • CUCAWEB
RE: CURSO DE C
« Respuesta #4 en: 16 de Febrero de 2004, 19:48:00 »
Pues yo estoy usando estas para un DS1678. La de BCD a binario es de producción propia. La otra está sacada de la librería que hay en CCS. No fuistes tu el que me paso unos ejemplos donde venían estas librerías??
Bueno, ahí van:
Codigo:

/*******************************************************************/
/*************** RUTINA DE CONVERSIÓN BINARIO A BCD ****************/
/***** Convierte un valor BINARIO de 8bits a otro BCD de 8bits *****/
/************* El rango de entrada debe ser de 00 a 99 *************/
/*******************************************************************/

byte bin2bcd(byte valor_binario){
   byte temp;
   byte retval;
   temp = valor_binario;
   retval = 0;

   while(1){
      if(temp >= 10){
         temp -= 10;
         retval += 0x10;
      }
      else{
         retval += temp;
         break;
      }
  }
  return(retval);
}



/*******************************************************************/
/*************** RUTINA DE CONVERSIÓN BCD A BINARIO ****************/
/***** Convierte un valor BCD de 8bits a otro Binario de 8bits *****/
/************* El rango de entrada debe ser de 00 a 99 *************/
/*******************************************************************/

byte bcd2bin (byte valor_bcd){
   byte valor_bin;
   valor_bin=valor_bcd-(swap(valor_bcd&0xF0)*6);
   return(valor_bin);
}


Saludos desde Huelva (ESPAÑA)

Desconectado pikman

  • Moderador Local
  • PIC24F
  • *****
  • Mensajes: 679
RE: CURSO DE C
« Respuesta #5 en: 16 de Febrero de 2004, 20:10:00 »
HOla, CUCA, como estas, pues si yo te pase hace un tiempo pero la de bi2bcd que habia ahi no andaba y no la encontre en CCS y por lo que veo no es diferente a mi produccion como tu dices, bien de cualquier manera te agradezco, las mismas y bueno creo que queda cerrado el tema.

saludos

Ariel
saludos
PikMan

Desconectado MGLSOFT

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 7912
RE: CURSO DE C
« Respuesta #6 en: 17 de Febrero de 2004, 06:04:00 »
Real Time Clock Interfacing and BCD Numbers

Computers work most effectively with binary numbers and humans like to use decimal numbers. A compromise number system is popular with some devices called Binary Coded Decimal (BCD).
BCD uses 4 binary bits to encode each decimal digit. The numbers in memory are then saved, such that each decimal digit is exactly 4 bits.
Twenty three in decimal is 23 and in binary is 00010111. In BCD it would be 00100011. Notice in hex, the binary number is 23. In one byte, although a binary number can hold 0 to 255 and in BCD a
byte can hold only 0 to 99 (4 bits per decimal digit). To begin, create a file
BCD.C that can be used to input and output BCD numbers as follows:

libreria BCD.C


byte get_bcd()
{ char first,second;
do { first=getc();
} while ((first<"0") || (first>"9"));
 putc(first);
do {
second=getc();
} while (((second<"0") || (second>"9")) && (second!=""));
putc(second);
if(second=="") return(first-"0");
else return(((first-"0")<<4)|(second-"0"));
}
void display_bcd( byte n )
 { putc( (n/16)+"0" );
 putc( (n%16)+"0" );
}



‘Connect up the circuit to the right using the NJU6355 real time clock chip.
This chip can keep accurate date and time using the small crystal
attached to the part. The interface to the PIC16F877 is an SPI
interface. Internally the date/time is kept in the chip in BCD.

‘Enter and run the following program to demonstrate the real time clock:

Programa Reloj.C


#include <protoalone.h>
#include <nju6355.c>
#include <BCD.c>

void set_time()
{ int hour,min;
printf("
Hour: ";
hour=get_bcd();
 printf("
Min: ";
min=get_bcd();
 rtc_set_datetime(0,0,0,0,hour,min);
}
void main()
{
int hour,min,sec,last_sec;
rtc_init();
while (TRUE)
{ rtc_get_time( hour, min, sec );
if(sec!=last_sec) { printf(“
”);
display_bcd(hour);
putc(‘:’);
display_bcd(min);
 putc(‘:’);
 display_bcd(sec);
last_sec=sec;
}
 if(kbhit()&&(getc()==’S’) set_time();
}
}



L Notes:
! The kbhit() function returns true if a character comes in the RS232
port. The && operator evaluates right to left. This means if the
kbhit() returns false, then the getc() is never called. If it were alled,
the program would hang here (because there was no character).
This effect is referred to as a short circuit. Not all languages guarantee this, however, ANSI C does.




Esto esta sacado del manual de CCS para una de sus placas.
El tutorial lo baje del sitio de CCS y se llama Development KIT tutorial.Como quiero aprender C busco por cielo y tierra..
Todos los dias aprendo algo nuevo, el ultimo día de mi vida aprenderé a morir....
Mi Abuelo.

Desconectado cucaracha

  • PIC24H
  • ******
  • Mensajes: 1409
    • CUCAWEB
RE: CURSO DE C
« Respuesta #7 en: 17 de Febrero de 2004, 06:34:00 »
Marcos, he dejado en el almacén un tutorial de ANSI C. No se si lo tienes ya. Se llama "Aprenda ANSI C como si estuviera en primero". También "Aprenda Visual Basic 6.0 como si estuviera en primero".
ANSI C--> http://miarroba.com/foros/ver.php?foroid=256746&temaid=1442352
Visual Basic 6.0 --> http://miarroba.com/foros/ver.php?foroid=256746&temaid=1442374
Saludos desde Huelva (ESPAÑA)

Desconectado pacalaconcurso

  • PIC24F
  • *****
  • Mensajes: 718
RE: CURSO DE C
« Respuesta #8 en: 17 de Febrero de 2004, 13:18:00 »
esto tiene buena pintaaaaaaa

os dejo el codigo fuente completo del famoso esclavo modbus con un ejemplito que funciona.

www.pacalaconcurso.com/pic_modbus.zip

espero que les guste y que lo depuremos aun mas

saludos

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: CURSO DE C
« Respuesta #9 en: 19 de Febrero de 2004, 12:34:00 »
El problema es que yo en el tema de las comunicaciones voy en bicicleta y para "coger" al programita del esclavo modbus hay que ir como mínimo en ferrari.

Os expongo como estoy intentando enviar variables de un PIC a otro. En este programa al activar una entrada en PORTB del PIC emisor, se debe de activar la correspondiente salida del PORTB en el PIC receptor.

PIC EMISOR:

#include <16f876.h>
#fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, NOWRT

#use delay(clock=4000000)
#use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7)

#use fast_io(B)

#byte port_b = 6                   
#byte port_c = 7                   
   
main()

{
                static short E1,E2,E3,E4,E5,E6,S1,S2,S3,S4,S5,S6,S7;

     static char c[14];         
     set_tris_b(0xFF);             // E1,E2,E3,E4,E5,E6 entradas  
   
   while(1)
   {           
      E1 = input(PIN_B0);
      E2 = input(PIN_B1);
      E3 = input(PIN_B2);
      E4 = input(PIN_B3);
      E5 = input(PIN_B4);
      E6 = input(PIN_B5);
                 
                      S1 = E1;
                      S2 = E2;
                      S3 = E1 && E2;
                      S4 = E1||E2;
                      S5 = E5;
                      S6 = E6;
                      S7 = E5&&E6;

// Asignación de variables de E/S al array de caracteres

                   c[0] = E1 + "0";   
      c[1] = E2 + "0";
      c[2] = E3 + "0";
      c[3] = E4 + "0";
      c[4] = E5 + "0";
      c[5] = E6 + "0";

      c[6] = S1 + "0";
      c[7] = S2 + "0";
      c[8] = S3 + "0";
      c[9] = S4 + "0";
      c[10] = S5 + "0";
      c[11] = S6 + "0";
      c[12] = S7 + "0";   
                                        
      puts(c);
      delay_ms(1000);   //Se mandan datos cada segundo
   }
}


PIC RECEPTOR:


#include <16f876.h>
#fuses XT, NOPROTECT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD, NOWRT

#use delay(clock=4000000)
#use RS232(BAUD=9600,BITS=8,PARITY=N,XMIT=PIN_C6,RCV=PIN_C7)

#use fast_io(B)

#byte port_b=6

main()
{
  static short E1,E2,E3,E4,E5,E6,S1,S2,S3,S4,S5,S6,S7;
  static char c[14];
     
  set_tris_b(0b00000000);      
  set_tris_c(0b10000000);

  output_B(0x00);     

  while(1)
  {    
   gets(c);  // Lo que le llega lo almacena en la variable c
         
   if (c[0]=="0")    // Conversión para las entradas físicas
      E1 = 0;
   else
      E1=1;   
      
   if (c[1]=="0")
      E2 = 0;
   else
      E2=1;   

   if (c[2]=="0")
      E3 = 0;
   else
      E3=1;   
      
   if (c[3]=="0")
      E4 = 0;
   else
      E4=1;
         
   if (c[4]=="0")
      E5 = 0;
   else
      E5=1;   

   if (c[5]=="0")
      E6 = 0;
   else
      E6=1;   


   if (c[6]=="0")   // Conversión para las salidas físicas
      S1 = 0;
   else
      S1=1;   
      
   if (c[7]=="0")
      S2 = 0;
   else
      S2=1;   

   if (c[8]=="0")
      S3 = 0;
   else
      S3=1;   
      
   if (c[9]=="0")
      S4 = 0;
   else
      S4=1;
         
   if (c[10]=="0")
      S5 = 0;
   else
      S5=1;   

   if (c[11]=="0")
      S6 = 0;
   else
      S6=1;   
      
   if (c[12]=="0")
      S7 = 0;
   else
      S7=1;   

    output_bit(PIN_B0,E1);   // VISUALIZACION DE LAS ENTRADAS DEL PIC EMISOR    
    output_bit(PIN_B1,E2);          
    output_bit(PIN_B2,E3);    
    output_bit(PIN_B3,E4);            
    output_bit(PIN_B4,E5);            
    output_bit(PIN_B5,E6);
   

  }
}

No funciona bien, el problema que tiene es que sin activar ninguna entrada en el PIC emisor, se activa la primera salida en el PIC receptor.

Si activo la primera entrada en el PIC emisor se activa la segunda salida (en lugar de la primera) en el PIC receptor.

Si activo la segunda entrada en el PIC emisor se activa la tercera salida (en lugar de la segunda) en el PIC receptor.

Os dejo todos los archivos, junto con la simulación en PROTEUS por si quereis darle un vistazo: http://miarroba.com/foros/ver.php?foroid=256746&temaid=1450765

Un saludo



Desconectado pikman

  • Moderador Local
  • PIC24F
  • *****
  • Mensajes: 679
RE: CURSO DE C
« Respuesta #10 en: 19 de Febrero de 2004, 13:55:00 »
Pocher, he bajado el codigo para analizarlo pero.....estais usando 2 16f876?, si la respuesta es si, ly tu proyecto es con estos dos, puedes usar I2C con un maestro / esclavo estuve haciendo unas pruebas ( que no termine ) y va de maravilla, claro esta que el escladvo siempre debe tener MSSP osea I2C opr hardware.

saludos.

ARIEL
saludos
PikMan

Desconectado cucaracha

  • PIC24H
  • ******
  • Mensajes: 1409
    • CUCAWEB
RE: CURSO DE C
« Respuesta #11 en: 19 de Febrero de 2004, 15:29:00 »
Arrggh!! Bueno, tras una hora peleando con el código, tengo el problema por el que no funcionaba tu código.
Mira si te fijas, el puts lo que hace es un printf(c)+putc(13)+putc(10) y el gets lo que hace es recibe la cadena hasta que le llega un 13, entonces finaliza la cadena con un 0.
Osea, que del 10 nada de nada. Ahí esta el problema, más bien el fallo de los de CCS.
Prueba esto, pon un getc despues del gets, verás como lo que recibe es un 10.
Una cosa, para sincronizar ambos pic, pon un retardo en el transmisor para que al receptor le de tiempo a ponerse en espera. Pero recuerda que si el emisor empieza a transmitir antes de que el receptor esté listo, este recibirá basura y lo más probable es que se te quede bloqueado.
Mejor que esto es hacerlo igual que el protocolo RS232. Cuando quieras comunicarte pon a 1 un pin del emisor, que irá a la interrupción del receptor. Esto le indica al receptor que se quieren comunicar con él. Entoces una vez entre en la RSI pones a 1 un pin del receptor (para indicarle que estás listo) y recibes (gets). Esa salida irá a la interrupción del emisor, y una vez entre en la RSI del emisor indicará que el receptor está listo y por tanto envías la cadena. Que lío no... pero se entiende verdad??
Esto añade dos líneas más, pero así no tendrás ese fallo.

Bueno, ya sé porqué no me funcionó en su día cuando intenté enviar en un programa una cadena usando puts y gets. Leches!!

Saludos!!
Saludos desde Huelva (ESPAÑA)

Desconectado pacalaconcurso

  • PIC24F
  • *****
  • Mensajes: 718
RE: CURSO DE C
« Respuesta #12 en: 19 de Febrero de 2004, 15:29:00 »
no se si te entendi pocher, ya sabes que mi craneo se desborda mas de la cuenta....

no te es mas facil leer el puerto completo y transmitir el byte de un pic a otro....???

yo estoy usando una forma que va de maravilla con modbus y consite en crear en el emisor una estructura con los datos a transmitir, de esa forma puedes mezclar tipos (bool, float...) y luego la mandas mediante un puntero byte a byte.....en el receptor haces la operacion contraria, es decir, montas la estructura con un puntero a byte y te olvidas de los tipos....de esa forma transmites tipos de datos mezclados de forma rapida.

si tengo tiempo monto un ejemplo y lo cuelgo

Desconectado cucaracha

  • PIC24H
  • ******
  • Mensajes: 1409
    • CUCAWEB
RE: CURSO DE C
« Respuesta #13 en: 19 de Febrero de 2004, 15:33:00 »
Por cierto, en el envío no hace falta reservar un byte para el cero. Te basta con c[13], ya que lo añade el propio puts.
Para la recepción sí. C[14]. Y pon el getc sin nada delante, osea:
getc() y no c[13]=getc() por ejemplo que así funciona.
Saludos desde Huelva (ESPAÑA)

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: CURSO DE C
« Respuesta #14 en: 20 de Febrero de 2004, 00:13:00 »
Gracias a todos por vuestras respuestas.

- Ariel con I2C no lo he probado, lo quería para RS232 - RS485 para transmitir E/S de automatismos a largas distancias. Gracias por la prueba, cuando pueda yo también lo probaré.

- Cucaracha de nuevo has vuelto a dar en el clavo. Efectivamente con un getc() debajo del gets() funciona. Ahora bien no le encuentro sentido, teóricamente el gets() debiera de esperar hasta encontrar el retorno de carro que le envía el puts() y saltar a la siguiente línea de programa sin esperar la llegada del LF(10) con que finaliza el puts(). En otro programa más grande que este tan solo con el gets() me funciona bien... será cosa del compilador ? No sé.
Probaré lo que me dices acerca de realizar la comunicación con interrupciones y si pudieses pegar un ejemplo mejor que mejor. Gracias por tu tiempo.

- Hola Félix, lo que quería era mandar los 8 bits del PORTB pero además también otras variables, por eso no lo mande-recibí  directamente con un putc()-getc().
Si que te agradecería y creo que los demás también, expusieses un ejemplo sencillo, muy sencilo con una estructura y un puntero byte a byte, de esa forma tendríamos 3 maneras de enviar-recibir: a) Array de caracteres b) Interrupción c) Estructura

Un saludo



 

anything