Autor Tema: Ayuda para interpretar una cadena de comandos en C  (Leído 6447 veces)

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

Desconectado JCAK

  • PIC18
  • ****
  • Mensajes: 325
Ayuda para interpretar una cadena de comandos en C
« en: 14 de Junio de 2006, 18:13:46 »
HOLA ...

Soy novato en esto del lenguaje C he visto códigos donde la instrucción es como la siguiente:

TCCR0B = (1 << WGM02) | (0 << CS02) | (0 << CS01) | (1 << CS00);

Yo interpreto esto como lo siguiente:

TCCR0B.WGM02 = 1
TCCR0B.CS02 = 0
TCCR0B.CS01 = 0
TCCR0B.CS00 = 1

Pero no se si estoy interpretando bien, porque mi duda se presenta con "<<" que leí que significa un desplazamiento a la izquierda y "|" significa OR (no me refiero al OR logico)

Entonces me gustaría si alguien con más experiencia me puede aclarar un poquito, paso por paso, como interpretar esta linea.
Todo eso viene a raiz de tratar de traducir al BASIC un codigo que tengo, debido a que es lo que yo puedo entender mas facil.


gracias
Julio - Argentina

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Ayuda para interpretar una cadena de comandos en C
« Respuesta #1 en: 14 de Junio de 2006, 18:39:27 »
No acierto a interpretar correctamente la finalidad de esa línea. Quizas si pegas el programa entero, podriamos deducir su significado.

Desconectado JCAK

  • PIC18
  • ****
  • Mensajes: 325
Re: Ayuda para interpretar una cadena de comandos en C
« Respuesta #2 en: 14 de Junio de 2006, 19:16:02 »
Hola Nocturno

Quizas no la interpretes porque el registro ese es para ATMEL y no para PIC.
Concretamente tiene que ver con los timers. No obstante, entiendo que si se trata de C el lenguaje es el mismo y solo cambian los nombres de los registros, etc.
Por eso lo posteo acá, porque en el segmento del foro dedicado a ATEML no hay casi nada.

A continuación te paso como viene esa parte del código, el cual está hecho para el compilador IAR Workbench:




static void InitTimers(void)
{
  // Set up Timer/counter0 for PWM, output on OCR0B, OCR0A as TOP value, prescaler = 1.
  TCCR0A = (0 << COM0A1) | (0 << COM0A0) | (1 << COM0B1) | (0 << COM0B0) | (0 << WGM01) | (1 << WGM00);
  TCCR0B = (1 << WGM02) | (0 << CS02) | (0 << CS01) | (1 << CS00);
  OCR0A = PWM_TOP_VALUE;
  TIFR0 = TIFR0;
  TIMSK0 = (0 << TOIE0);

  // Set up Timer/counter1 for commutation timing, prescaler = 8.
  TCCR1B = (1 << CS11) | (0 << CS10);
}




Desde ya, muchas gracias.
« Última modificación: 14 de Junio de 2006, 19:19:45 por JCAK »
Julio - Argentina

Desconectado jfh900

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3595
Re: Ayuda para interpretar una cadena de comandos en C
« Respuesta #3 en: 14 de Junio de 2006, 19:50:01 »
Aparentemente parece que hace lo siguiente:

TCCR1B = (1 << CS11) | (0 << CS10); => TCCR1B = CS11*16+CS10

Llenamos un registro de 16 bits con dos de 8 bits mediante desplazamientos, habria que comprobarlo con el manual del compilador, ya que no domino ese compilador ni ese micro.

Un saludo


* Cuando hables, procura que tus palabras sean mejores que el silencio.
* 'Todos somos ignorantes, lo que ocurre es que no todos ignoramos las mismas cosas.' Albert Einstein.
* No hay nada peor que un experto para evitar el progreso en un campo
* "La vida es como una novela. No importa que sea larga, sino que esté bien narrada" Seneca
* La vida no se vive por las veces que respiras, sino por los momentos que dejan sin aliento.
* Dios dijo: ∇·E=ρ/ε0 ; ∇·B=0 ; ∇xE=-dB/dt ; ∇xB= μ0ε0dE/dt..y la luz se hizo..!!..

Desde España Jesús

Desconectado JCAK

  • PIC18
  • ****
  • Mensajes: 325
Re: Ayuda para interpretar una cadena de comandos en C
« Respuesta #4 en: 14 de Junio de 2006, 22:01:10 »
No creo que sea esa la función, porque el registro TCCR1B es de 8 bits.
Lo que hace esa linea es definir los bits que van en 1 o 0 para indicar el modo en que debe operar el timer.

Julio - Argentina

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Ayuda para interpretar una cadena de comandos en C
« Respuesta #5 en: 15 de Junio de 2006, 01:53:58 »
Lo único que se me ocurre es que las variables COM0A1, COM0A0, COM0B1, etc. estén cargadas con números enteros entre 0 y 7. Estos números indicarán la posición de esos bits en el byte TCCR0A y TCCR0B.

Por tanto, al indicar la línea:
TCCR0A = (0 << COM0A1) | (0 << COM0A0) | (1 << COM0B1) | (0 << COM0B0) | (0 << WGM01) | (1 << WGM00);

Lo que estás haciendo es colocar los valores 0 y 1 en el bit correspondiente. Es decir, cada uno de esos valores se "empuja" hacia la izquierda hasta ocupar su posición (indicada por el nº entero que comentaba antes) y luego se unen todos con el símbolo "|", o lo que es igual, se suman.

Pero sólo es una suposición, porque si realmente eso fuera así, la línea sería mucho más simple escribiéndola de esta manera:
TCCR0A = 0b001001;

aunque está claro que el lector no sabría qué bits se han seteado con qué valores sin mirar en el datasheet.

Desconectado JCAK

  • PIC18
  • ****
  • Mensajes: 325
Re: Ayuda para interpretar una cadena de comandos en C
« Respuesta #6 en: 19 de Junio de 2006, 20:21:09 »
Que tal a todos.

La verdad que yo no se de C, pero los que intentan ayudarme me parece que tampoco.
Los nombres que se ven en cada linea NO son variables, son nombres de registros, que por mas que no sen de PIC, es para darse cuenta y no confundirlo con una variable.
Esto es C y da lo mismo para lo que sea, yo pregunté como interpretar este comando y hasta puse un ejemplo, que a esta altura me doy cuenta que es bastante mas acertado que las ayudas que pasaron.

Alguien que quiera AYUDAR será bienvenido, los demas gracias pero no solo me confunden a mi, también al resto.

Tengo otra inquietud al respecto, por ejemplo, en que se diferencian estas dos lineas al usar una de ella |= y la otra solo el signo =

WDTCSR |= (1<<WDCE) | (1<<WDE);
WDTCSR = (1<<WDIF) | (1<<WDIE) | (1<<WDE) | (1<<WDP2);

El registro WDTCSR se compone como sigue:
WDIF - WDIE - WDP3 - WDCE - WDE - WDP2 - WDP1 - WDP0

Gracias y saludos
Julio - Argentina

Desconectado jfh900

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3595
Re: Ayuda para interpretar una cadena de comandos en C
« Respuesta #7 en: 19 de Junio de 2006, 22:04:36 »
Vamos haber si nos aclaramos un poco, en primer lugar te comentare que estas preguntando por un micro que no es un PIC y como habras observado el foro se llama TODOPIC, esto no quiere decir que no haya gente que no conozca el ATMEL, si no que conocemos mucho mejor los pic. En segundo lugar te dire que el compilador que estas utilizando no sigue la convención del ANSI C que es el estandar de "C" y que es lo que realmente se estudia de "C", despues dentro del mundo de los compiladores para microcontroladores y microprocesadores, como estos son muy especiales (pilas rudimentarias, juegos de instrucciones mínimo, etc), cada fabricante a modificado su compilador de "C" para adaptarlo lo mejor posible a los requisitos de los microcontroladores y microprocesadores. Te paso una hoja del CCS (compilador para PIC's) donde aparecen los operadores. En dicha hoja veras que << es Left Shift operator y l es Bitwise inclusive or operator. Estos operadores uno es de ANSI C y el otro esta presente en la mayoria de los compiladores de "C" y por consiguiente cuando te encuentras con:

(1 << WGM02) | (0 << CS02) | (0 << CS01) | (1 << CS00);

Se puede observar según la mayoria de los compiladores que hay desplazamientos y sumas de valores.

En cuanto a que  CS02 es un registro y no una variable, resulta que la mayoria de los micros mapean los registros como variables, de echo ocupan el mismo espacio de memoria y son contiguos, en definitiva un registro es una posicicón de memoria donde se puede leer y escribir en muchos casos como si fuera una variable mas.

Es verdad que yo desconozco este compilador y este micro, pero decir que no tenemos ni idea de "C" es un poco arriesgado dado el`poco tiempo que llevas en el foro y el desconocimiento que tienes de nostros como personas. No voy a caer en la trampa facil de tirar de titulos ni de experiencia por que aqui estamos todos por un igual y mucha gente autodidacta a adquirido unos conocimientos muy solidos que dan la experiencia, sabiendo mas que muchos estudiantes de ingenieria que estan terminando sus estudios y pasan por este foro a preguntar. Por todo ello me parece pretencioso por tu parte el acudir al foro preguntando y cuando nosotros con nuestra buena voluntad te respondemos y perdemos nuestro tiempo (yo te aseguro que tengo muchas cosas que hacer mas importantes que la que estoy haciendo ahora) y tacharnos de  que no sabemos "C".

Por último te contesto a tu pregunta:

en que se diferencian estas dos lineas al usar una de ella |= y la otra solo el signo =

Lo primero |= es "distinto de" y es el operador contrario a == "igual a"

El operador = es un operador de asignacion, como nota curiosa te comentare que es muy corriente entre las personas poco duchas en programar en "C" hacer if(a=5) esto no esta haciendo una comparación y si una asignación (damos a la variable "a" el valor 5) la forma correcta es if(a==5). Bueno siempre y cuando el compilador lo entienda de esta forma. Esta cuestion se encuentra en cualquier manual de "C", asi que por favor leete algun manual antes de preguntar.

Por cierto este tipo de preguntas concretas del compilador ATMEL postealo en su foro.

Un saludo.
* Cuando hables, procura que tus palabras sean mejores que el silencio.
* 'Todos somos ignorantes, lo que ocurre es que no todos ignoramos las mismas cosas.' Albert Einstein.
* No hay nada peor que un experto para evitar el progreso en un campo
* "La vida es como una novela. No importa que sea larga, sino que esté bien narrada" Seneca
* La vida no se vive por las veces que respiras, sino por los momentos que dejan sin aliento.
* Dios dijo: ∇·E=ρ/ε0 ; ∇·B=0 ; ∇xE=-dB/dt ; ∇xB= μ0ε0dE/dt..y la luz se hizo..!!..

Desde España Jesús

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: Ayuda para interpretar una cadena de comandos en C
« Respuesta #8 en: 20 de Junio de 2006, 01:33:57 »
Déjalo, Jesús, no merece la pena que sigas intentando ayudarle, no somos bienvenidos.

Desconectado djpalas

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 595
    • Microtronic
Re: Ayuda para interpretar una cadena de comandos en C
« Respuesta #9 en: 20 de Junio de 2006, 07:36:09 »
Buenas!

1º En el primer post que pusiste, se activan o desactivan los bits del registro indicado.

Código: [Seleccionar]
sbi(port, bit)    <==>    (port) |= (1 << (bit))             set bit
cbi(port, bit)    <==>    (port) &= ~(1 << (bit))          clear bit

2º Tenias razón que no sabias C, porque nuestros maestros tan respondido como funciona esas instrucciones desde C y como funciona sobre el lenguaje C para microchip. Ya que estas posteando en una zona microchip, que es totalmente diferente a la programacion de los ATMEL.

3º No especificas que era un Atmel desde el primer post.

4º Este es para Jesús
Cita de: jfh900
........
Lo primero |= es "distinto de" y es el operador contrario a == "igual a"
........
Sin animos de ofender Jesús, se te paso algo por alto, un despiste lo tiene cualquiera :wink:
Código: [Seleccionar]
== "Igual a"
!=  "Distinto de"

La función del operador |= es la siguiente
Código: [Seleccionar]
a|=b   es lo mismo que  a=a|b

5º JCAK intenta postear en su sitio, aunque se tarde en responder un poco, al final alguien te ayudara mejor.

6º Manolo, Jesús, y todos los maestros de este foro. No cambieis sois unos maquinas  :D

PD: Ya aprovecho para darle las gracias a Manolo por darme de alta en el nuevo foro y guardarme mi nick. Con los examenes de ingeniería no dejan tiempo para mucho  :?

Saludos desde Cádiz, España
Web personal: http://www.microtronic.es

Desconectado jfh900

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3595
Re: Ayuda para interpretar una cadena de comandos en C
« Respuesta #10 en: 20 de Junio de 2006, 08:06:51 »
Hola djpalas antes de nada decirte que gracias por tu apoyo. En segundo lugar decirque que para nada me ofende tu post, toda critica constructiva es bien recivida en este foro y todo el mundo tiene derecho a opinar aun cuando este equivocado, para eso el resto se encargara (en buenas maneras) de discutir y llegar a una solución entre todos. Y en tercer lugar y último punto decirte que tienes toda la razón en cuanto a la rectificación (ultimamante el alzeimer y la suciedad de la pantalla me estan jugando malas pasadas, voy a tener que limpiarla :lol: ) me fue por != cuando en realidad era |= osease una OR con asignación.

Un saludo a todos.
* Cuando hables, procura que tus palabras sean mejores que el silencio.
* 'Todos somos ignorantes, lo que ocurre es que no todos ignoramos las mismas cosas.' Albert Einstein.
* No hay nada peor que un experto para evitar el progreso en un campo
* "La vida es como una novela. No importa que sea larga, sino que esté bien narrada" Seneca
* La vida no se vive por las veces que respiras, sino por los momentos que dejan sin aliento.
* Dios dijo: ∇·E=ρ/ε0 ; ∇·B=0 ; ∇xE=-dB/dt ; ∇xB= μ0ε0dE/dt..y la luz se hizo..!!..

Desde España Jesús

Desconectado JCAK

  • PIC18
  • ****
  • Mensajes: 325
Re: Ayuda para interpretar una cadena de comandos en C
« Respuesta #11 en: 20 de Junio de 2006, 13:58:14 »
Hola a todos una vez más

Antes de seguir, quiero pedir DISCULPAS a todos los que se sintieron tocados por mi forma de expresarme en mi mensaje anterior.
Se que me están brindando una mano y valoro eso por sobremanera, incluso por eso también participo en el foro y cuando puedo hago lo mismo por otros.
Pero lo que ocurre y para que entienda mi reacción, es que ya he leído en otros post y me pasó personalmente a mi con una consulta, que hay gente que por querer ayudar termina confundiendo o mal informando.
Me pasó concretamente a mi y no porque me lo contara nadie, que por querer ayudarme y yo por seguir las sugerencias, terminé quemando componentes, con errores grandes y no porque me faltara medir algo.
Eso es lo que ocasiona mi reacción y entiendo que cada uno se ataje luego, pero como dice el dicho, el que se quema con leche, ve una vaca y llora.

Bueno, ahora quiero agradecer a las ultimas respuestas y preguntar algo más que no me queda claro, si es que aún no han desanimado y aceptan mis disculpas.

Ahí voy:

Concretamente estoy tratando de interpretar un código C realizado con el compilador IAR, este compilador sirve tanto para programar PIC como ATMEL y mi intención es pasarlo a BASIC (mi mundo)

Yo leí algunas ayudas de C y también busqué en el compilador, pero por lo visto el compilador da por sobrentendido algunos comandos y esa explicación no está, y no doy con una ayuda que me aclare un par de cosas que me servirían para seguir.

Refiriéndome a lo ultimo que puse de ejemplo

WDTCSR |= (1<<WDCE) | (1<<WDE);
WDTCSR = (1<<WDIF) | (1<<WDIE) | (1<<WDE) | (1<<WDP2);

El registro WDTCSR se compone como sigue:
WDIF - WDIE - WDP3 - WDCE - WDE - WDP2 - WDP1 - WDP0


Sigue sin quedarme claro cómo interpretar las líneas por lo siguiente:

No confundir “|=” con “!=”, yo puse “|=”

No interpreto la primer linea, por más que que djplas explica el significado con a|=b   es lo mismo que  a=a|b ¿Podrías, por favor, explicarme con un ejemplo en bits y con los dos bits afectados WDCE WDE para ver si asi me doy cuenta?

Yo interpreto que la segunda linea es como enviar 11001100 al registro WDTCSR ¿es así?

Ahora me pregunto, acaso << no es para producir un desplazamiento a la izquierda? En ese caso la instrucción debería interpretarla como una asignación SET o en realidad pretende invertir el valor en que se encuentra el bit.

Saludos y gracias
Julio - Argentina

Desconectado djpalas

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 595
    • Microtronic
Re: Ayuda para interpretar una cadena de comandos en C
« Respuesta #12 en: 20 de Junio de 2006, 14:53:09 »
Buenas JCAK

Te explico rapidamente

la operacion OR, osea "|". No confundir con OR a nivel de BIT "||"

ejemplo
=====

a=1000 0010
b=0011 0100

si colocamos
a|=b; "Realiza (a OR b) y lo volvemos a guardar en a"
realiza la siguiente operacion
a=a|b;

    a=1000 0010
    b=0011 0100
OR___________
    a=1011 0110

con lo que a=1011 0110
/*********************************************************/

Código: [Seleccionar]
Ejemplo esta linea:
WDTCSR |= (1<<WDCE) | (1<<WDE);


WDTCSR tiene el valor xxxx xxxx (incondicional las X, pueden 0 o 1)
(1<<WDCE) es lo mismo que (0000 0001 << 4), puesto que WDCE esta en el bit4 del registro WDTCSR
(1<<WDE) es lo mismo que (0000 0001 << 3), puesto que WDE esta en el bit3 del registro WDTCSR

Como resultado tenemos:
WDTCSR = XXX1 1XXX

En la siguiente:

Código: [Seleccionar]
WDTCSR = (1<<WDIF) | (1<<WDIE) | (1<<WDE) | (1<<WDP2);

Como el operador de desplazamiento a la izquiera de bits "<<" introduce 0 por cada desplazamiento (1111 1111 <<2) se optiene el siguiente resultado 1111 1100

Tendriamos en este caso
WDTCSR=11001100


Espero que ahora lo comprendas mejor su funcionamiento ;)

Y sobre todo no heches las culpas a nadie del foro por que te sucediera aquello. La ultima palabra es tuya, y nose tú, pero yo si me la juego un poco en lo que hago, lo reviso como minimo unas pocas de veces. Los foreros no creo que lo hicieran queriendo, pero estamos para aprender de nuestros errores :-)

Saludos desde Cádiz, España
Web personal: http://www.microtronic.es

Desconectado jfh900

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3595
Re: Ayuda para interpretar una cadena de comandos en C
« Respuesta #13 en: 20 de Junio de 2006, 15:03:37 »
Por mi parte disculpas aceptadas.

Pasando a otra cosa, en esta pagina tienes la explicación de como se ponen bit a "cero" y a "uno"

http://www.users.on.net/~symes/CwithAVR/IntrotoCwithAVR.htm

aunque básicamente es lo mismo que te ha dicho djpalas con su estupenda explicación, solo una puntualización.

La diferencia entre:

WDTCSR = (1<<WDIF) | (1<<WDIE) | (1<<WDE) | (1<<WDP2);

es una asignación y por consiguiente los bits: WDIF WDIE WDE WDP2 se ponen a uno el resto se pone a cero

WDTCSR |= (1<<WDIF) | (1<<WDIE) | (1<<WDE) | (1<<WDP2);

es una OR con el propio registro con lo que: WDIF WDIE WDE WDP2 se ponen a uno el resto se deja como estaba (los que esten a 1 siguen a 1 y los que estan a 0 siguen a 0

Un saludo.
* Cuando hables, procura que tus palabras sean mejores que el silencio.
* 'Todos somos ignorantes, lo que ocurre es que no todos ignoramos las mismas cosas.' Albert Einstein.
* No hay nada peor que un experto para evitar el progreso en un campo
* "La vida es como una novela. No importa que sea larga, sino que esté bien narrada" Seneca
* La vida no se vive por las veces que respiras, sino por los momentos que dejan sin aliento.
* Dios dijo: ∇·E=ρ/ε0 ; ∇·B=0 ; ∇xE=-dB/dt ; ∇xB= μ0ε0dE/dt..y la luz se hizo..!!..

Desde España Jesús

Desconectado JCAK

  • PIC18
  • ****
  • Mensajes: 325
Re: Ayuda para interpretar una cadena de comandos en C
« Respuesta #14 en: 20 de Junio de 2006, 23:26:29 »
Mil gracias a todos por la ayuda, ahora si, me han logrado clarificar una parte del asunto.

Luego puede ser que pregunte algo más, pero ahora me voy a poner a analizar en profundida esta parte, porque todo el programa hace uso intensivo de esto y como conté anteriormente, voy a tratar de pasarlo a BASIC.

GRACIAS...  :)
« Última modificación: 21 de Junio de 2006, 12:22:56 por JCAK »
Julio - Argentina


 

anything