Autor Tema: Comienzo en C  (Leído 17347 veces)

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

Desconectado macedo

  • PIC18
  • ****
  • Mensajes: 270
Re: Comienzo en C
« Respuesta #45 en: 13 de Junio de 2012, 11:37:38 »
Hola como borro el WD en C, vi estos ejemplos:

Código: C
  1. _asm
  2.  CLRWDT
  3. _endasm
otro:
Código: C
  1. void CLRWDT(void) {
  2.          _asm clrwdt  _endasm
  3.         }

Código: C
  1. CLRWDT();

Esta funcion vi que es un macro, pero me da error el compilador, saben como puedo hacer.
Saludos

Desconectado jukinch

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 608
Re: Comienzo en C
« Respuesta #46 en: 13 de Junio de 2012, 20:33:28 »
Macedo. C es case sensitive. Es decir debés respetar mayúsculas y minúsculas.
así no va CLRWDT ni así clrwdt

Probá así. ClrWdt()

está definido como una macro. página 37 del manual mplab_c18_users_guide_51288j (DS51288J-page 37)

fuente: http://www.microchip.com/forums/m110249.aspx
          Saludos.
                   Jukinch
"Divide las dificultades que examinas en tantas partes como sea posible para su mejor solución." -René Descartes

Desconectado macedo

  • PIC18
  • ****
  • Mensajes: 270
Re: Comienzo en C
« Respuesta #47 en: 14 de Junio de 2012, 10:52:31 »
Si gracias, sabes lo que me paso esta pagina la habia visto pero la traduje con el google y me cambio el "ClrWdt" a todo mayúscula "CLRWDT" y lo tome así por eso no me funcionaba , puse la funcion como dicen ahi:
Código: C
  1. // prototype
  2.  void Clear_WDT(void);
  3.  
  4.  [...]
  5.  
  6.  // function definition
  7.  void Clear_WDT(void)
  8.  {
  9.         ClrWdt();
  10.  }

Gracias

y hasta ahora funciona correcto
Gracias.

Desconectado macedo

  • PIC18
  • ****
  • Mensajes: 270
Re: Comienzo en C
« Respuesta #48 en: 15 de Junio de 2012, 13:58:31 »
Hola, estoy en una duda con estas sentencia:
Código: C
  1. SSP1BUF = data;
  2.         while(!PIR1bits.SSP1IF);
  3.         PIR1bits.SSP1IF = 0;
  4.         LCD_E_HIGH;
  5. }
Es un equivalente a esto:
Código: ASM
  1. movFf   TEMP_CARACTER, SSP1BUF          ; Transmision por puerto SPI           
  2.  
  3. SPI_DELAY
  4.                 NOP
  5.                 NOP
  6.                 btfss   PIR1,SSP1IF                     ; Espera a que se envie el dato
  7.                 goto    SPI_DELAY
  8.                 bcf     PIR1,SSP1IF                     ; borra flag interrupcion
  9.                 bsf     LCD_SCE                         ; display OFF = LCD_E_HIGH;
  10.                 RETLW   0X00

El ASM es mi cod, lo que quiero saber es sobre el "while(!PIR1bits.SSP1IF);", este tiene la condición pero no hay bucle entre {}, mi pregunta es de esta manera espera siempre a que sea TRUE la condición y continua con la siguiente linea (PIR1bits.SSP1IF = 0; o salta fuera y retorna el control sin seguir con las demás lineas.
Saludos

Desconectado jukinch

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 608
Re: Comienzo en C
« Respuesta #49 en: 15 de Junio de 2012, 15:15:11 »
   while(!PIR1bits.SSP1IF);

Hace que mientras PIR1bits.SSP1IF sea falso se quede iterando dentro de ese while.
El ; que está después de los paréntesis sería lo que se ejecuta. Y como no hay nada, está vacío, no hace nada.
Muchas veces vas a ver esto también while(1); que hace que el código se quede iterando en esa línea
... hasta el infinito y más allá!


"Divide las dificultades que examinas en tantas partes como sea posible para su mejor solución." -René Descartes

Desconectado macedo

  • PIC18
  • ****
  • Mensajes: 270
Re: Comienzo en C
« Respuesta #50 en: 15 de Junio de 2012, 16:13:19 »
gracias

Desconectado jukinch

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 608
Re: Comienzo en C
« Respuesta #51 en: 15 de Junio de 2012, 19:07:42 »
Macedo:
        Tené presente como es la sintaxis del while para no poner signos ; de más.

mientras(condición) ejecutar sentencia; // acá si va el ;

pero podés también reemplazar la sentencia única por un bloque de sentencias mediante el uso de las llaves {   }

while (condición)
       { 
       // código a ejecutar mientras la condición sea verdadera
       } // acá no va el ;

Si pusieras:
while (condición)
       { 
       // código a ejecutar mientras la condición sea verdadera
       };

En realidad estarías ejecutando el bucle while y además una sentencia vacía generando código innecesario.  ;-)

"Divide las dificultades que examinas en tantas partes como sea posible para su mejor solución." -René Descartes

Desconectado macedo

  • PIC18
  • ****
  • Mensajes: 270
Re: Comienzo en C
« Respuesta #52 en: 16 de Junio de 2012, 11:54:01 »
Hola jukinch, dejame ver si es así, el "while" se ejecuta solo si tiene la condición "TRUE", si no es así se queda esperando hasta que la condición sea "TRUE" y entonces ejecuta su bloque, si no tiene nada se pasa a la siguiente linea.
Saludos

Desconectado jukinch

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 608
Re: Comienzo en C
« Respuesta #53 en: 16 de Junio de 2012, 11:58:48 »
No macedo:
              El while solo se ejecuta si la condición es true, sinó el programa sigue de largo.
ojo que en este while(!PIR1bits.SSP1IF); hay un operador que invierte la condición. Un signo !
"Divide las dificultades que examinas en tantas partes como sea posible para su mejor solución." -René Descartes

Desconectado macedo

  • PIC18
  • ****
  • Mensajes: 270
Re: Comienzo en C
« Respuesta #54 en: 16 de Junio de 2012, 14:57:49 »
Te pongo el cod. entero, es la transmicion por SPI:
Código: C
  1. void LCDSend(unsigned char data, unsigned char cd) {
  2.  
  3.         PIR1bits.SSP1IF = 0;   // borra flag interrupcion
  4.         LCD_E_LOW;             // Enable display!!!!!!!!!!!!!!!!!!!!!!
  5.  
  6.         if(cd == SEND_CHR) {
  7.         DC_HIGH;
  8.         }
  9.         else {
  10.         DC_LOW;
  11.         }
  12.                                                  //while((SSP1STAT & 0x01 == 0));
  13.         SSP1BUF = data;
  14.         while(!PIR1bits.SSP1IF);
  15.         PIR1bits.SSP1IF = 0;
  16.                                             //while((SSP1STAT & 0x01 == 0));
  17.         LCD_E_HIGH;
  18. }

Fijate como lo usa, según lo que me explicaste esta solo la condición y no hay sentencia para ejecución, el programa tendría que revisar "(!PIR1bits.SSP1IF);" si es FALSE volver al "while" y comprobar nuevamente asi haste que se vuelva TRUE  y continue en "PIR1bits.SSP1IF = 0;" y seguir, por eso creí que se quedaba ahí, no veo un bucle de espera hasta que termine la transmición como el ejemplo en ASM que puse.
Podes entender lo que quiero explicarte del porque mi confución en este programa.
Saludoss

Desconectado macedo

  • PIC18
  • ****
  • Mensajes: 270
Re: Comienzo en C
« Respuesta #55 en: 16 de Junio de 2012, 15:14:48 »
Hola creo que lo entendí:
Código: C
  1. SSP1BUF = data;                    // ENVIO EL DATO AL BUFFER DE LA SPI PARA ENVIARLO A LA LCD
  2.  
  3.         while(!PIR1bits.SSP1IF);           // ACA REVISO EL FLAG DE TRANSMICION, SI TERMINO SSP1IF= 1, PERO AL NO TERMINAR DE TRANSMITIR SSP1IF= 0,
  4.                                            // AL TENER !  QUEDA NEGADO Y ES SSP1IF= 1 ENTONCES EL WHILE ES "TRUE" Y SIEMPRE ESTA REVISANDO QUE LO SEA, UN BUCLE EN SI MISMO YA QUE NO TIENE SENTENCIAS DE EJECUCION,
  5.                                            // AL TERMINAR DE TRANSMITIR EL SSP1IF= 1, NEGADO ES SSP1IF= 1,  EL WHILE SE VUELVE "FALSE" Y CONTINUA CON LAS DEMAS LINEAS.
  6.         PIR1bits.SSP1IF = 0;               // CONTINUO CON MI PROGRAMA, BORRO EL FLAG Y CONTINUO
  7.                                            
  8.         LCD_E_HIGH;

Creo que así es, que me dicen.
Saludos

Desconectado macedo

  • PIC18
  • ****
  • Mensajes: 270
Re: Comienzo en C
« Respuesta #56 en: 18 de Junio de 2012, 11:02:59 »
Hola, necesito una mano, tengo en un proyecto que crear "menús" en un LCD Nokia 3310, y son varios, están los títulos de la pantalla, la descripción de los mismos, muestra y describe los errores producidos y muestra en el lcd resultados obtenidos con breves reseñas, todas estas frases deben estar escritas en el pic, la pregunta del millón es como, he visto ejemplos de esta forma:
Código: C
  1. unsigned char mnsj4[]  = {"Distribucion :\0"};
  2. unsigned char mnsj5[]  = {"00 38\0"};
  3. unsigned char mnsj6[]  = {"FR\0"};
  4. unsigned char mnsj7[]  = {"USA\0"};
  5. unsigned char mnsj8[]  = {"> Simulacion Juego <\0"};
  6. unsigned char mnsj9[]  = {"* En Juego... *\0"};
  7. unsigned char mnsj10[] = {"Numero Cantado:\0"};
  8. unsigned char mnsj11[] = {"Win :--\0"};
  9. unsigned char mnsj12[] = {"Games:\0"};
Pero me sale un error:
"Error - section '.idata_lcd.o' can not fit the section. Section '.idata_lcd.o' length=0x00000177"
El pic es el 18F67J50.
Por lo que pude interpretar de http://www.xargs.com/pic/c18-sections.html estoy cargando todo a la RAM y me sobrepase, lo que tengo que hacer es cargar los menus en la ROM.
Puede ser una forma asi:
Código: C
  1. unsigned char Menu[MENU_NUMB][16] = {
  2.  "Test EXT 1&2  \0",
  3.  "Test LEDS  \0",
  4.  "Test GUIA \0",
  5.  "Test MMA      \0",
  6.  "Test Joystick \0"
  7. };
Pero esta forma también me ocupa RAM no?
Puse el ejemplo:
Código: C
  1. rom rom char * array [] =
  2. {
  3.    "Cadena de 1",
  4.    "Cadena de 2",
  5. };
Pero no me funciona, mi cod:
Código: C
  1. LCDMsnj (0, 0, array[1]);

Los dos primeros ceros son las coordenadas y array el mensaje a mostrar.
Me pueden ayudar.
Gracias

Desconectado jukinch

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 608
Re: Comienzo en C
« Respuesta #57 en: 18 de Junio de 2012, 15:02:32 »
Macedo:

Con respecto a tu anterior post, no se si quedó claro el tema del operador not o ! dentro del while.

a este while(!PIR1bits.SSP1IF); debés analizarlo en dos tramos.

primero evaluar la expresión a la derecha del operador !, es decir, PIR1bits.SSP1IF. Luego a ese resultado lo negás con el !.
Pero el operador ! no altera el valor del  bit SSP1IF.

Mirá este ejemplo en pseudo código :


unsigned char x; // variable global

interrupción:
{
x=0;
}


void main(void)
{
x=1;
while(!(X==0));   // mientras x sea distinto a 0 se quedará iterando dentro del while.

                            // El programa primero evalúa el valor de x(que vale 1) con 0, lo que da false. Y al resultado lo niega.
                            // Eso es lo que toma como condición el while, siendo en definitiva la condición evaluada verdadera.
                            // pero x sigue teniendo su valor propio no siendo afectado por el operador !, ya que no se hace ninguna
                            // asignación a x.
                            // Cuando ocurra la interrupción se le cambiará el valor a la variable x pasando a valer 0, lo que
                            // hará que al salir de la interrupción x haga cambiar el resultado de la comparación con 0 y
                            // se resuelva como verdadera (equivalente a 1). Luego es negada por el operador not ! haciéndola falsa
                            // nuevamente. Entonces allí si saldrá del while.
                            //
}

Lo que quiero que quede claro en tu ejemplo es que el operador not no altera el valor del bit PIR1bits.SSP1IF .
Ese bit no se verá afectado por el while en si. Dicho valor solo será cambiado al ocurrir la interrupción pasando a valer 1.
No se en que pic estás trabajando.  En mi 18f4550 tengo que valdrá 1 cuando suceda una escritura o lectura en el SPP
y 0 mientras no haya ni lectura ni escritura.

SPPIF: Streaming Parallel Port Read/Write Interrupt Flag bit
1 = A read or a write operation has taken place (must be cleared in software)
0 = No read or write has occurred

while(!PIR1bits.SSP1IF); // se quedará iterando en  este while mientras no haya lectura ni escritura.
                                    // Cuando se produzca la interrupción sale del while.
PIR1bits.SSP1IF = 0; // luego borra el flag.




Con respecto al siguiente post debés cargar tu texto en rom para que no te ocupe memoria ram:


#pragma romdata
const rom char Palabra_Contador[]="CONTADOR"; // cadena de texto. se agregará el \0 al final
const rom char my_const_array [5] = {'a','b','c','d','e'}; array de caracteres. // no se agrega el \0 al final
#pragma romdata

mirá las páginas 24 y 25 del tutorial de suky. (las del texto no del pdf!) :)

modificado: (aclaré que las páginas son las del texto y no del pdf!)
« Última modificación: 18 de Junio de 2012, 15:06:40 por jukinch »
"Divide las dificultades que examinas en tantas partes como sea posible para su mejor solución." -René Descartes

Desconectado macedo

  • PIC18
  • ****
  • Mensajes: 270
Re: Comienzo en C
« Respuesta #58 en: 19 de Junio de 2012, 10:57:27 »
Hola jukinch, gracias por molestarte y tomarte el tiempo en responder, el post anterior lo comprendí, el operador ! solo niega, y PIR1bits.SSP1IF esta en "0" , al tener ! queda en 1 entonces se queda iterando en el while hasta que termine la transmición y PIR1bits.SSP1IF cambie a 1 pero con el ! queda en 0 entonces continua. Lo comprendí gracias, lo único que me desoriento es que no tenia llaves con sentencias para hacer algo, creí que no se podía hacer así que si o si debia de hacer algo.

Con respecto al otro post vi la conf. #pragma romdata  pero no me salia usarla así que iprobe con esto:
Código: C
  1. sprintf((char*)BusChar,(rom far char*)"> Simulacion Juego <");
  2.          LCDMsnj ( 0, 3, BusChar);

Es lo que me explicaste al principio, funciona, lo único es que tengo que cargar sprintf con cada frase y creo que llevara mucho código ya que son muchas. Otra pregunta es necesario colocar \0" al final de la frase "> Simulacion Juego <" en sprintf?
Voy a probar lo que me enseñaste y te comento.
Cual es el texto de suky ya que tengo dos pdf de el.
Saludos

Desconectado macedo

  • PIC18
  • ****
  • Mensajes: 270
Re: Comienzo en C
« Respuesta #59 en: 19 de Junio de 2012, 16:06:40 »
Hola, estuve probando pero necesito aprender mas sobre punteros. Coloque mi menu de esta forma:
Código: C
  1. #pragma romdata
  2. ....
  3. const rom char mnsj2[]="*Init. Cilindro*\0";
  4. ....
  5. ...
  6. #pragma romdata

Uso mi funcion asi:
Código: C
  1. LCDMsnj ( 0, 0, mnsj2);

Y la funcion es:
Código: C
  1. void LCDMsnj(unsigned char x,unsigned char y, const unsigned char *dataPtr) {
  2.  
  3.    rom unsigned char ** near_rom_ptr;
  4.    *near_rom_ptr=FontLookup[0];
  5.  
  6.    LCDSend(0x80|x, SEND_CMD );
  7.    LCDSend(0x40|y, SEND_CMD );
  8.  
  9.    while ( *dataPtr )                                   // loop to the end of string
  10.  {                    
  11.   for(k=0; k<6; k++)                                    // k<5
  12.       LCDSend(FontLookup[*dataPtr - 32][k], SEND_CHR);  //near_rom_ptr
  13.    
  14.       dataPtr++;
  15. //      LCDSend (0x00,SEND_CHR);                          // Espacio entre caracteres.
  16.   }
  17.  
  18. }

Bueno como sabran me tira este error: Warning [2054] suspicious pointer conversion, y no muestra nada en el LCD.
Help! :(
Saludos