TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: JCAK en 14 de Junio de 2006, 18:13:46

Título: Ayuda para interpretar una cadena de comandos en C
Publicado por: JCAK 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
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: Nocturno 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.
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: JCAK 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.
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: jfh900 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


Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: JCAK 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.

Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: Nocturno 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.
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: JCAK 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
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: jfh900 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.
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: Nocturno en 20 de Junio de 2006, 01:33:57
Déjalo, Jesús, no merece la pena que sigas intentando ayudarle, no somos bienvenidos.
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: djpalas 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  :?
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: jfh900 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.
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: JCAK 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
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: djpalas 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 :-)
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: jfh900 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.
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: JCAK 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...  :)
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: JCAK en 22 de Junio de 2006, 15:33:24
HOLA AMIGOS....

Lo que me pasaron antes resultó todo perfecto, pero me surgíeron un par de dudas más y quiciera saber si pueden ayudarme. Ahí voy ....

ADCSRA es un registro de 8 bits compuesto de la siguiente manera:
ADEN - ADSC - ADATE - ADIF - ADIE - ADPS2 - ADPS1 - ADPS0

En el codigo C tengo una instrucción que dice asi:

while ( ! (ADCSRA & (1<<ADIF))
{
}


Tengo otroa que no usa el signo ! y dice asi:

while (ADCSRA & (1<<ADSC)
{
}


Y por utlimo otra que dice asi:

ADCSRA &= ~((1<<ADATE) | (1<<ADIE))

En esta creo que es algo asi como hacer ADCSRA = ADCSRA AND 11010111 pero la verdad que no estoy seguro ¿me confirmarían?

Yo entiendo que while es para que se quede en un loop, también entiendo que & es para hacer una operación AND, pero todo junto no entiendo como aplicarlo, en especial porque me da la sensación de estar trabajando con 8 bits y 1 bit y ya me perdí.


Algo estudié y uno de los link que me pasaron vino barbaro, pero Socoooorrroooo.....  :?
Con la ayuda en ejemplos binarios lo entiendo genial, por favor tirenme una manito más, no digo que sea la ultima ... gracias

Saludos
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: jfh900 en 22 de Junio de 2006, 15:51:54
Veamos:

while ( ! (ADCSRA & (1<<ADIF))

con esto lo que hacemos es poner un 1 en la posición del bit ADIF y todas las demas posiciones son cero seguidamente hacemos un AND, luego todas las posiciones son cero a excepción de la del bit ADIF que valdra "1" si el registro ADCSRA contien un 1 en esa posición. En definitiva comprobamos si el bit ADIF del registro ADCSRA vale uno o cero. El carácter ! lo que hace es invertir el valor osease si vale uno me devulve cero y si vale cero me devuelve uno. Como se lee entoces toda la instrucción:

ejecutar el bucle mientras el bit ADIF del registro ADCSRA valga cero

while (ADCSRA & (1<<ADSC)

Lo mismo perosin inversión:

ejecutar el bucle mientras el bit ADIF del registro ADCSRA valga uno

ADCSRA &= ~((1<<ADATE) | (1<<ADIE))

Teniendo encuenta:

ADEN - ADSC - ADATE - ADIF - ADIE - ADPS2 - ADPS1 - ADPS0

Esta es un poco mas complicada:

((1<<ADATE) | (1<<ADIE))

Esto devuelve:

ADEN - ADSC - ADATE - ADIF - ADIE - ADPS2 - ADPS1 - ADPS0
0         0           1           0         1        0           0            0

00101000

El carácter ~ hace el complemento (cambia ceros por uno y viceversa):

~00101000 = 11010111

Finalmente hace un and con el registro ADCSRA  y se lo asigna así mismo quedando:

ADCSRA &= ~((1<<ADATE) | (1<<ADIE)) =>

ADCSRA = ADCSRA & 11010111

Esto quiere decir que estamos poniendo a cero los bits 3 y 5 del registro ADCSRA que son:

ADEN - ADSC - ADATE - ADIF - ADIE - ADPS2 - ADPS1 - ADPS0
7         6          5            4        3         2           1            0

ADATE - ADIE

Con lo cual lo que habias deducido estaba bien.

Un saludo.


Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: djpalas en 22 de Junio de 2006, 16:05:06
Buenas!!

Estoy totalmente deacuerdo con jfh900, ha realizado una buen explicación. :D

Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: JCAK en 22 de Junio de 2006, 16:09:24
Hola JFH900

Por favor, solo confirmame si en la segunda linea que pusiste:

ejecutar el bucle mientras el bit ADIF del registro ADCSRA valga uno

Quiciste poner:

ejecutar el bucle mientras el bit ADSC del registro ADCSRA valga uno

Además y aprovechando la ocación, vos que sabes de C te pregunt lo siguiente, el que escribió este código en C para hacer el while, no tenia una manera más facil de lograr tal comparación.
Me refiero a que en BASIC yo pongo algo como While ADCSRA.ADIF = 0 y listo, o sea, no tengo que hacer un AND y luego comparar, ni invertir nada. ¿que opinas?

Gracias a todos nuevamente.
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: jfh900 en 22 de Junio de 2006, 16:29:19
Pues si tienes razón con las prisas crei que era el mismo bit, pero lo correcto es:

ejecutar el bucle mientras el bit ADSC del registro ADCSRA valga uno

En cuanto a lo segundo, comentarte que eso depende del compilador, si puede trabajar a nivel de bit's individuales o no. Creo por lo que vimos en el enlace que te puse y por lo que hemos estado viendo, que este compilador solo trabaja a nivel de byte y por consiguiente hay que aislar el bit que queramos testear dentro de un byte.

Un saludo.
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: JCAK en 23 de Junio de 2006, 20:06:00
Y se va la tercera.....

Me surgió una consulta, si bien leí en alguna ayuda de C, que #PRAGMA sirve para compatibilizar, no entiendo su aplicación práctica al momento de interpretar el código.

por ejemplo tengo una linea que dice asi:

#pragma vector=TIMER0_OVF_vect

Abajo de esto viene todo el resto del código
__interrupt void nombre()
etc.
etc.
etc.


Esto me fijé en la tabla del procesador y está definido en la dirección 0x20 y como descripción dice "Timer/Counter0 Overflow

Alguien me podría explicar de que manera interpreto esto y si alguien sabe de BASIC también, decirme cuál es su analogía.

Saludos, y gracias a todos los del foro que me dan una mano.

 :-)
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: jfh900 en 23 de Junio de 2006, 21:05:28
El significado de pragma es:

#pragma nombre-de-directiva

La directiva #pragma, permite a los compiladores "C" definir sus directivas particulares (que no corresponden a nada establecido en el estándar ANSI) sin interferir con otros compiladores que soporten este tipo de directivas. Si el compilador no reconoce la etiqueta nombre-de-directiva, la directiva es ignorada sin ningún tipo de mensaje o advertencia.

Hasta donde yo llego a entender de este compilador la directive:

#pragma vector=TIMER0_OVF_vect

Esta declarando un vector "vector" que apunta a la direccion de Overflow del Timer0, o lo que es lo mismo a la direccion de la interrupción del overflow del Timer0.

En cuanto a como implementarlo en basic, creo que tendrias que definir la interrupción para este caso.

Un saludo.
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: JCAK en 24 de Junio de 2006, 21:23:10
Hola jfh900

Si, eso que me pasaste es lo que leí por ahí, pero sinceramente sigue sin quedarme claro. Es decir, entiendo que la instrucción quedaría como sigue:

#pragma vector=0x20

o sea, setea un vector en la drirectiva #pragma, con un valor de 8 bits.

Pero de ahí en más, qué función cumple esta declaración al referise a la compatibilidad, no me queda claro, pese a que desde que escribí sigo buscando info que me lo aclare.

Saludos y gracias
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: jfh900 en 25 de Junio de 2006, 06:40:46
Puedes poner un poco mas de código, para ver el contexto en el cual se encuentra la directiva?. Hay que ver donde se utiliza "vector" y como. Tal vez si pones todo el código lo veamos mas coherente.

Un saludo.
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: JCAK en 25 de Junio de 2006, 18:04:21
Ahí voy a la carga... y desde ya mil gracias.

Recordar que los registros a los que hace referencia son de ATMEL. Espero no sea motivo de confución, o en todo caso me preguntan y amplío la info.

TIMER0_OVF_vect tiene un valor 0x20 mientras que TIMER1_COMPA_vect vale 0x16
Así tengo otras partes más que comienzan con la directiva #pragma


#pragma vector=TIMER0_OVF_vect
__interrupt void MotorPWMBottom()
{
  unsigned char temp;

  // Disable ADC auto-triggering. This must be done here to avoid wrong channel being sampled on manual samples later.
  ADCSRA &= ~((1 << ADATE) | (1 << ADIE));

  // Wait for auto-triggered ADC sample to complete.
  while (!(ADCSRA & (1 << ADIF)))
  {

  }
  temp = ADCH;
  if (((zcPolarity == EDGE_RISING) && (temp > ADC_ZC_THRESHOLD)) || ((zcPolarity == EDGE_FALLING) && (temp < ADC_ZC_THRESHOLD)))
  {
    unsigned int timeSinceCommutation;

    // Find time since last commutation
    timeSinceCommutation = TCNT1;
    TCNT1 = COMMUTATION_CORRECTION;

    // Filter the current ZC detection with earlier measurements through an IIR filter.
    filteredTimeSinceCommutation = (COMMUTATION_TIMING_IIR_COEFF_A * timeSinceCommutation
                                + COMMUTATION_TIMING_IIR_COEFF_B * filteredTimeSinceCommutation)
                                / (COMMUTATION_TIMING_IIR_COEFF_A + COMMUTATION_TIMING_IIR_COEFF_B);
    OCR1A = filteredTimeSinceCommutation;

    speedUpdated = TRUE;

    SET_TIMER1_INT_COMMUTATION;
    CLEAR_ALL_TIMER1_INT_FLAGS;

    // Disable Timer/Counter0 overflow ISR.
    DISABLE_ALL_TIMER0_INTS;

    // Read speed reference.

    // Make sure that a sample is not in progress.
    while (ADCSRA & (1 << ADSC))
    {

    }
    // Change channel
    ADMUX = ADMUX_SPEED_REF;

    // Start conversion manually.
    ADCSRA |= (1 << ADSC);

    // Wait for conversion to complete.
    while((ADCSRA & (1 << ADSC)))
    {

    }
    speedReferenceADC = ADCH;

    // Read voltage reference.
    // Change ADC channel.
    ADMUX = ADMUX_REF_VOLTAGE;
    // Start conversion manually.
    ADCSRA |= (1 << ADSC);
    // Wait for conversion to complete.
    while((ADCSRA & (1 << ADSC)))
    {

    }
    referenceVoltageADC = ADCH;

    // Enable current measurements in ADC ISR.
    ADMUX = ADMUX_CURRENT;
    ADCSRA |= (1 << ADATE) | (1 << ADIE) | ADC_PRESCALER;
  }
  else
  {
    unsigned char tempADMUX;

    tempADMUX = ADMUX;
    // Read current

    // Make sure that a sample is not in progress
    while (ADCSRA & (1 << ADSC))
    {

    }

    // Change channel
    ADMUX = ADMUX_CURRENT;

    // Start conversion manually.
    ADCSRA |= (1 << ADSC);
    // Wait for conversion to complete.
    while((ADCSRA & (1 << ADSC)))
    {

    }

    shuntVoltageADC = ADCH;
    currentUpdated = TRUE;

    // Restore ADC channel.
    ADMUX = tempADMUX;
    ADCSRA |= (1 << ADATE) | (1 << ADIE) | ADC_PRESCALER;
  }
}



Esta es otra parte del código:


#pragma vector=TIMER1_COMPA_vect
__interrupt void Commutate()
{
  // Commutate and clear commutation timer.
  DRIVE_PORT = nextDrivePattern;
  TCNT1 = 0;

  zcPolarity = nextCommutationStep & 0x01;

  // Set zero-cross detection holdoff time.
  CLEAR_ALL_TIMER1_INT_FLAGS;
  OCR1B = ZC_DETECTION_HOLDOFF_TIME_US;
  SET_TIMER1_INT_HOLDOFF;

  __watchdog_reset();
}



La verdad que no entiendo si esta directiva #pragma es indispensable para usar en el compilador BASIC al que intento pasarlo.


Gracias por la yuda que puedan acercar.

Saludos
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: jfh900 en 25 de Junio de 2006, 18:23:18
Desde el desconocimiento que poseo de este compilador, y siempre con elocubraciones, parece que esta directiva asigna la función siguiente al evento interrupcion que deseemos, por ejemplo:

#pragma vector=TIMER0_OVF_vect
__interrupt void MotorPWMBottom()

La subrutina de interrupcion MotorPWMBottom() es asignada al evento TIMER0_OVF_vect, o lo que es lo mismo cuando se produce un desbordamiento del Timer0 se llama a MotorPWMBottom.

Creo que ese será el funcionamiento de esta directiva.

Un saludo.
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: JCAK en 25 de Junio de 2006, 18:32:24
De ser asi sería barbaro porque ya entendería como aplicarlo en el BASIC

para un basic sería:

ON TIMER0_OVF_vect MotorPWMBottom

O sea que le dice que en caso de la interrupción valla a la rutina MotorPWMBottom

Alguien más que quiera confirma esto y ya estaríamos por la recta final..

Gracias jfh900
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: jfh900 en 25 de Junio de 2006, 19:46:59
Te dejo este manual para descargar, donde puedes verificar lo indicado:

http://rapidshare.de/files/24118197/cavr.pdf.html

Un saludo.
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: JCAK en 26 de Junio de 2006, 12:10:07
Gracias, gracias, gracias ... jfh900

Por ahora no mas preguntas.

Saludos
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: JCAK en 13 de Julio de 2006, 00:16:28
He regresado .....  :-)

El registro se llama TIFR0 y se me hizo un lio con una instrucción que es la siguiente:

TIFR0 = TIFR0;

Esto me parece haber leido que resetea el registro, pero es asi realmente ?

De antemano, gracias una vez mas....
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: vszener en 13 de Julio de 2006, 11:13:24
La instruccion
Código: C
  1. TIFR0 = TIFR0;
No resetea el dispositivo, simplemente le asigna a la variable TIFR0 el valor que ya tenia anteriormente...


Suerte!!! :wink:
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: JCAK en 13 de Julio de 2006, 11:34:46
Claro, en mi logica pienso lo mismo.... pero que sentido tiene entonces poner una linea asi?
Pregunto esto, porque estoy tomando el codigo de algo que está hecho por el propio fabricante del micro.
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: vszener en 13 de Julio de 2006, 12:35:34
Esta hecha asi
Código: C
  1. TIFR0 = TIFR0;

o asi:
Código: C
  1. TIFR0 = !TIFR0;


Suerte!!! :wink:
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: JCAK en 13 de Julio de 2006, 16:11:56
Ahi va completo y gracias por los que tiren un manito.... Aclaro que sigo con ATMEL

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);
}
Título: Re: Ayuda para interpretar una cadena de comandos en C
Publicado por: JCAK en 13 de Julio de 2006, 16:16:46
Encontré esto en un arichivo H
Creo que es así nomás, borra los flags


//! Macro that clears all Timer/counter0 interrupt flags.
#define CLEAR_ALL_TIMER0_INT_FLAGS    (TIFR0 = TIFR0)