Un alumno me envía un problema que tiene al intentar activar una salida. Parece que la tarjeta de inicializa bien, pero al hacer clic en el botón "Activar calefactor" se muestra el siguiente error:
La solución es sencilla, debes ir a la función que genera el error (en este caso "proceso_escribir_calefactor()" y comentar la línea correspondiente a la llamada de la función "proceso_error" (resaltada en color rojo en la imagen de abajo):
Una vez hecho, al activar la salida, podrás ver en el simulador como cambian los niveles y así comprobar que lo estás haciendo bien (que se activa sólo una salida y no todo el puerto por ejemplo):
Con el simulador abierto puedes ir haciendo clic en los botones activar/desactivar calefactor/válvula de tu programa y comprobar si cambian los niveles en las salidas (H/L). Es una manera magnífica de ver si lo estás haciendo bien.
Recuerda que estamos en un entorno de simulación que nos permite trabajar sin tener el "HW". En situaciones reales, deberás tener muy presente el tratamiento de errores para poder determinar, en caso de error, donde puede estar el fallo.
..
..
Apuntes teoría sensores y material de prácticas para la asignatura del curso Informática Industrial
Mostrando entradas con la etiqueta primer bloque. Mostrar todas las entradas
Mostrando entradas con la etiqueta primer bloque. Mostrar todas las entradas
11 de febrero de 2011
Al iniciar el programa..los temporizadores deberían estar apagados
En los proyectos se debe incluir uno o varios temporizadores para controlar la frecuencia de refresco de las entradas/salidas. Un alumno me envía un correo comentando los errores que se muestran al iniciar el programa:
Son dos mensajes, uno en el fondo con el título "SimSenyII" y otro delante "ssDAQmxReadAnalogScalarF64()..". Esta claro que el primero es del simulador, que intenta arrancar (cuando se llama a alguna función de la tarjeta) y el segundo corresponde a una función de la tarjeta de adquisición..Estos errores aparecen sin intervención del usuario, nada más arrancar, ésto sugiere que es debido a un temporizador que debería estar parado.
Lo que sucede aquí es bastante frecuente, arrancar la aplicación con los temporizadores ENCENDIDOS. Como el timer se dispara antes de poder inicializar el simulador y la tarjeta, todo salta por los aires, no se puede empezar a usar una función de la tarjeta si antes no se ha inicializado..
Solución: Busca el temporizador en el formulario y desactívalo cambiando su propiedad "Enabled=false", de este modo, al arrancar el programa, el timer estará apagado:
De esta manera el sistema estará inicializado pero detenido hasta que el usuario determine los valores deseados y el modo (manual o automático) .
Si se usa el modo automático, habrá que activar el temporizador:
"Form1->Timer1->Enabled=1" (el timer es el "encargado" de controlar el sistema)
Si se usa el modo manual, habrá que detener el temporizador:
"Form1->Timer1->Enabled=0" (el usuario controla las salidas, el timer no hace falta)
Por último, yo añadiría un botón nuevo con el que puedas inicializar la tarjeta, añade uno al formulario, cámbiale el nombre y haz doble clic en para escribir el código que deberá ejecutarse al pulsarlo:
"proceso_inicializar_proceso();" (inicia la tarjeta y el simulador)
De este modo, cuando arranques la aplicación, pulsa primero en el botón y tendrás las tarjeta lista para usar. A partir de este momento ya puedes llamar a las funciones que quieras.
Esto es una parte de la solución.
Ahora el programa permite inicializar la tarjeta y elegir el modo de funcionamiento, sin errores.
..
Son dos mensajes, uno en el fondo con el título "SimSenyII" y otro delante "ssDAQmxReadAnalogScalarF64()..". Esta claro que el primero es del simulador, que intenta arrancar (cuando se llama a alguna función de la tarjeta) y el segundo corresponde a una función de la tarjeta de adquisición..Estos errores aparecen sin intervención del usuario, nada más arrancar, ésto sugiere que es debido a un temporizador que debería estar parado.
Lo que sucede aquí es bastante frecuente, arrancar la aplicación con los temporizadores ENCENDIDOS. Como el timer se dispara antes de poder inicializar el simulador y la tarjeta, todo salta por los aires, no se puede empezar a usar una función de la tarjeta si antes no se ha inicializado..
Solución: Busca el temporizador en el formulario y desactívalo cambiando su propiedad "Enabled=false", de este modo, al arrancar el programa, el timer estará apagado:
De esta manera el sistema estará inicializado pero detenido hasta que el usuario determine los valores deseados y el modo (manual o automático) .
Si se usa el modo automático, habrá que activar el temporizador:
"Form1->Timer1->Enabled=1" (el timer es el "encargado" de controlar el sistema)
Si se usa el modo manual, habrá que detener el temporizador:
"Form1->Timer1->Enabled=0" (el usuario controla las salidas, el timer no hace falta)
Por último, yo añadiría un botón nuevo con el que puedas inicializar la tarjeta, añade uno al formulario, cámbiale el nombre y haz doble clic en para escribir el código que deberá ejecutarse al pulsarlo:
"proceso_inicializar_proceso();" (inicia la tarjeta y el simulador)
De este modo, cuando arranques la aplicación, pulsa primero en el botón y tendrás las tarjeta lista para usar. A partir de este momento ya puedes llamar a las funciones que quieras.
Esto es una parte de la solución.
Ahora el programa permite inicializar la tarjeta y elegir el modo de funcionamiento, sin errores.
..
10 de febrero de 2011
Cannot convert 'int (*)() to 'int'
Cuando accedemos a las variables del módulo de datos, por ejemplo durante la inicialización del sistema, usamos funciones creadas por el usario. Recuerda que para cada variable asociada a un sensor o actuador, has creado funciones de lectura y escritura. Nos encontramos este error:
En la figura anterior, aparece un error de conversión. Esto puede suceder cuando al llamar a una función, ésta no entiende muy bien los datos que se le pasan o se le devuelve un dato que no coincide con lo esperado. Por ejemplo podría darse el caso de esperar un entero (int) y le ha venido de golpe un doble (double) u otro tipo.
En la instrucción marcada en rojo de la figura, lo que se trata de hacer es actúar sobre la válvula, abriéndola o cerrándola físicamente. El valor que se le pasará será aquel que el usuario haya decidido, haciendo clic en un botón o de cualquier otro modo en el interfaz gráfico. Cuando lo haga, este valor se guardará en el módulo de datos para mantener la imagen del proceso.
Aquí es donde está el problema, en la llamada a la función, se le pasa como parámetro "VerVálvula" pero debería ser "VerVálvula()" ya que es la función del módulo de datos que consulta la variable.
Al olvidar los paréntesis, el compilador busca una variable llamada "VerVálvula" y genera el error porque lo que encuentra es una función.
Recuerda: aunque la función no tenga argumentos - void VerVálvula(void) - al llamarla siempre hay que incluirlos.
En la figura anterior, aparece un error de conversión. Esto puede suceder cuando al llamar a una función, ésta no entiende muy bien los datos que se le pasan o se le devuelve un dato que no coincide con lo esperado. Por ejemplo podría darse el caso de esperar un entero (int) y le ha venido de golpe un doble (double) u otro tipo.
En la instrucción marcada en rojo de la figura, lo que se trata de hacer es actúar sobre la válvula, abriéndola o cerrándola físicamente. El valor que se le pasará será aquel que el usuario haya decidido, haciendo clic en un botón o de cualquier otro modo en el interfaz gráfico. Cuando lo haga, este valor se guardará en el módulo de datos para mantener la imagen del proceso.
Aquí es donde está el problema, en la llamada a la función, se le pasa como parámetro "VerVálvula" pero debería ser "VerVálvula()" ya que es la función del módulo de datos que consulta la variable.
Al olvidar los paréntesis, el compilador busca una variable llamada "VerVálvula" y genera el error porque lo que encuentra es una función.
Recuerda: aunque la función no tenga argumentos - void VerVálvula(void) - al llamarla siempre hay que incluirlos.
No encuentra las funciones de la tarjeta DAQ
Cuando se compila un programa, pueden aparecer muchos errores relacionado con las funciones de la tarjeta de adquisición. Los errores que aparecen pueden parecerse a los siguientes:
Los errores tipo: "[C++ Warnings]", son advertencias pero no detienen la ejecución. La compilación se va a parar en seco cuando encuentre errores de tipo: "[Link Error]". En una de las líneas con este error, dice que no puede encontrar una función externa "DAQmxReadAnalogScalar64..".
Aunque hayamos copiado la librería (fichero.lib) de la tarjeta DAQ en la carpeta del proyecto, quizá no le hayamos indicado al compilador que está allí. El compilador es un poco perezoso y no va a mirar a menos que se lo indiques.
Para resolverlo, activa la opción "View/Project manager", verás la estructura del proyecto:
Lo que ves en la figura anterior es una lista de los ficheros que "mirará" el compilador. Si algo no está en esta "lista", es como si no existiera (aunque físicamente esté copiado en la carpeta del proyecto). Puedes ver todas las unidades del proyecto (ficheros.cpp) y la cabecera de la librería (NIDAQmx.h), pero NO la librería (NIDAQmx.lib). Búscala y añadela.
Selecciona la opción "Project/Add to project", localiza la librería y selecciónala:
Ahora comprueba de nuevo desde "View/Project manager" que la librería ya está en la lista. De este modo, el compilador ya sabe donde se encuentran todas las funciones que necesita para compilar tu programa.
Cuando compiles de nuevo, los errores generados por las funciones de la tarjeta habrán desaparecido, pero nos quedarán otros asociados con las funciones que ha creado el usuario (eso en otro artículo).
Los errores tipo: "[C++ Warnings]", son advertencias pero no detienen la ejecución. La compilación se va a parar en seco cuando encuentre errores de tipo: "[Link Error]". En una de las líneas con este error, dice que no puede encontrar una función externa "DAQmxReadAnalogScalar64..".
Aunque hayamos copiado la librería (fichero.lib) de la tarjeta DAQ en la carpeta del proyecto, quizá no le hayamos indicado al compilador que está allí. El compilador es un poco perezoso y no va a mirar a menos que se lo indiques.
Para resolverlo, activa la opción "View/Project manager", verás la estructura del proyecto:
Lo que ves en la figura anterior es una lista de los ficheros que "mirará" el compilador. Si algo no está en esta "lista", es como si no existiera (aunque físicamente esté copiado en la carpeta del proyecto). Puedes ver todas las unidades del proyecto (ficheros.cpp) y la cabecera de la librería (NIDAQmx.h), pero NO la librería (NIDAQmx.lib). Búscala y añadela.
Selecciona la opción "Project/Add to project", localiza la librería y selecciónala:
Ahora comprueba de nuevo desde "View/Project manager" que la librería ya está en la lista. De este modo, el compilador ya sabe donde se encuentran todas las funciones que necesita para compilar tu programa.
Cuando compiles de nuevo, los errores generados por las funciones de la tarjeta habrán desaparecido, pero nos quedarán otros asociados con las funciones que ha creado el usuario (eso en otro artículo).
29 de enero de 2011
Pregunta de examen
Pregunta de examen (Test Enero 2010):
7. Observa detenidamente el siguiente código en C y determina el valor de la variable “z” una vez ejecutadas todas las sentencias.
int x,y,z;
x=8;
y=4;
if(x=y){z=x*y;}
else{z=x+y;}
a) 0x12
b) 0x0C
c) 0x10
Respuesta:
En la sentencia de comparación "if(x=y) {z=x*y}" es donde está la clave.
Como sabes, una sentencia "if" compara un valor con otro y si se cumple la condición, ejecuta la sentencia que le sigue. Pero la sentencia "if" puede funcionar de manera diferente...si nos olvidamos algo..
En este problema, hay un fallo, la sentencia correcta sería "if(x==y)".
Recuerda que en una comparación siempre deben incluirse dos signos "=".
Por lo tanto al incluir sólo un signo "=", la sentencia NO COMPARA, ASIGNA:
if (x=y) >> ASIGNA EL VALOR DE "y" A "x" (ambas valen ahora 4).
A continuación, se ejecuta la sentencia "{z=x*y}" z=4*4=16=0x10.
Si tienes curiosidad y quieres comprobarlo, puedes abrir un proyecto en Builder y probarlo.
Añade un objeto tipo "Label" y asígnale el valor de z. Comprobarás que al poner sólo un signo "=" el la etiqueta aparece 16, pero si lo haces correctamente con "==" en la etiqueta aparecerá 12.
..
7. Observa detenidamente el siguiente código en C y determina el valor de la variable “z” una vez ejecutadas todas las sentencias.
int x,y,z;
x=8;
y=4;
if(x=y){z=x*y;}
else{z=x+y;}
a) 0x12
b) 0x0C
c) 0x10
Respuesta:
En la sentencia de comparación "if(x=y) {z=x*y}" es donde está la clave.
Como sabes, una sentencia "if" compara un valor con otro y si se cumple la condición, ejecuta la sentencia que le sigue. Pero la sentencia "if" puede funcionar de manera diferente...si nos olvidamos algo..
En este problema, hay un fallo, la sentencia correcta sería "if(x==y)".
Recuerda que en una comparación siempre deben incluirse dos signos "=".
Por lo tanto al incluir sólo un signo "=", la sentencia NO COMPARA, ASIGNA:
if (x=y) >> ASIGNA EL VALOR DE "y" A "x" (ambas valen ahora 4).
A continuación, se ejecuta la sentencia "{z=x*y}" z=4*4=16=0x10.
Si tienes curiosidad y quieres comprobarlo, puedes abrir un proyecto en Builder y probarlo.
Añade un objeto tipo "Label" y asígnale el valor de z. Comprobarás que al poner sólo un signo "=" el la etiqueta aparece 16, pero si lo haces correctamente con "==" en la etiqueta aparecerá 12.
..
8 de diciembre de 2010
Eliminar un formulario de una unidad
A veces por error hemos creado una unidad con un formulario que no necesitamos y cuando vamos a eliminarlo, Borland no lo permite, para eliminarlo y mantener la unidad, puedes hacer lo siguiente:
- Quita la unidad del proyecto.
- Edita a mano el módulo para eliminar todo lo que tenga que ver con el formulario.
- Vuelve a añadirlo al proyecto.
- Quita la unidad del proyecto.
- Edita a mano el módulo para eliminar todo lo que tenga que ver con el formulario.
- Vuelve a añadirlo al proyecto.
Duda con una función del módulo de proceso
Un alumno envía una función del módulo de proceso:
int Proceso_leer_rebose(void) {
int32 errdaq;
uInt32 data;
errdaq = DAQmxStartTask(en_dig); //
errdaq = DAQmxReadDigitalScalarU32(en_dig,0.0,&data,NULL);
errdaq = DAQmxStopTask(entradas_digitales);
if ((data & 0x00000001) == 0){
return(REBOSE_HAY);}
else{
return(REBOSE_NO_HAY);
}
Esta función "Proceso_leer_rebose" lee físicamente los pines de la tarjeta para detectar niveles de tensión, usa para ello tres funciones de la tarjeta NI USB-6008 (aparecen resaltadas). Este valor es almacenado en la variable "data".
Como esta variable tiene el valor del puerto completo y queremos mirar sólo un bit, aplicamos una máscara (línea resaltada en verde) para quedarnos con el bit de interés.
De este modo podemos detectar el estado del bit y almacenarlo en el módulo de datos, para que esté a disposición de otras funciones, por lo tanto yo modificaría esta última parte de la función:
if ((data & 0x00000001) == 0){
Datos_escribir_rebose(0);
else
{
Datos_escribir_rebose(1);
}
Por lo tanto la función no devuelve nada, sólo almacena el valor que lee del sensor en el módulo de datos. Esta función "Proceso_leer_rebose" está haciendo uso de la función "Datos_escrbir_rebose" del módulo de datos para guardar esta información. El último cambio que habría que hacer sería redefinir la cabecera de la función para que devuelva "void":
void Proceso_leer_rebose(void) {
Se indica "void" porque la función no devuelve ningún valor. Lo hace a través de las funciones del módulo de datos.
int Proceso_leer_rebose(void) {
int32 errdaq;
uInt32 data;
errdaq = DAQmxStartTask(en_dig); //
errdaq = DAQmxReadDigitalScalarU32(en_dig,0.0,&data,NULL);
errdaq = DAQmxStopTask(entradas_digitales);
if ((data & 0x00000001) == 0){
return(REBOSE_HAY);}
else{
return(REBOSE_NO_HAY);
}
Esta función "Proceso_leer_rebose" lee físicamente los pines de la tarjeta para detectar niveles de tensión, usa para ello tres funciones de la tarjeta NI USB-6008 (aparecen resaltadas). Este valor es almacenado en la variable "data".
Como esta variable tiene el valor del puerto completo y queremos mirar sólo un bit, aplicamos una máscara (línea resaltada en verde) para quedarnos con el bit de interés.
De este modo podemos detectar el estado del bit y almacenarlo en el módulo de datos, para que esté a disposición de otras funciones, por lo tanto yo modificaría esta última parte de la función:
if ((data & 0x00000001) == 0){
Datos_escribir_rebose(0);
else
{
Datos_escribir_rebose(1);
}
Por lo tanto la función no devuelve nada, sólo almacena el valor que lee del sensor en el módulo de datos. Esta función "Proceso_leer_rebose" está haciendo uso de la función "Datos_escrbir_rebose" del módulo de datos para guardar esta información. El último cambio que habría que hacer sería redefinir la cabecera de la función para que devuelva "void":
void Proceso_leer_rebose(void) {
Se indica "void" porque la función no devuelve ningún valor. Lo hace a través de las funciones del módulo de datos.
4 de diciembre de 2010
Control - Cuestión 3 Tipo A, B, C, D
Tipo A
Completar el código siguiente pare gestionar la lectura de un sensor digital marca Acme conectado a una tarjeta NI USB-6008 en P0.5. Se pide sustituir los tres interrogantes remarcados en color rojo por el código en lenguaje C correspondiente:
¿? lectura_sensor_acme(¿?) {
int32 daq_error;
uInt32 dato;
daq_error=DAQmxReadDigitalScalarU32(digital_sensor_task,0.0,&dato,NULL);
if (daq_error !=0) process_error(daq_error,"Lectura sensor ACME()");
if ((dato & ¿?)===0) return(0);
else return(1);
}
Solución:
int..............................(void)
máscara = 0x00000020
Tipo B
Completar el código siguiente pare gestionar la lectura de un sensor digital marca Acme conectado a una tarjeta NI USB-6008 en P0.7. Se pide sustituir los tres interrogantes remarcados en color rojo por el código en lenguaje C correspondiente:
¿? lectura_sensor_acme(¿?) {
int32 daq_error;
uInt32 dato;
daq_error=DAQmxReadDigitalScalarU32(digital_sensor_task,0.0,&dato,NULL);
if (daq_error !=0) process_error(daq_error,"Lectura sensor ACME()");
if ((dato & ¿?)===0) return(0);
else return(1);
}
Solución:
int............................(void)
máscara=0x00000080
Tipo C
Completar el código siguiente pare gestionar la lectura de un sensor digital marca Acme conectado a una tarjeta NI USB-6008 en P0.3. Se pide sustituir los tres interrogantes remarcados en color rojo por el código en lenguaje C correspondiente:
¿? lectura_sensor_acme(¿?) {
int32 daq_error;
uInt32 dato;
daq_error=DAQmxReadDigitalScalarU32(digital_sensor_task,0.0,&dato,NULL);
if (daq_error !=0) process_error(daq_error,"Lectura sensor ACME()");
if ((dato & ¿?)===0) return(0);
else return(1);
}
Solución:
int.............................(void)
máscara= 0x00000008
Tipo D
Completar el código siguiente pare gestionar la lectura de un sensor digital marca Acme conectado a una tarjeta NI USB-6008 en P0.6. Se pide sustituir los tres interrogantes remarcados en color rojo por el código en lenguaje C correspondiente:
¿? lectura_sensor_acme(¿?) {
int32 daq_error;
uInt32 dato;
daq_error=DAQmxReadDigitalScalarU32(digital_sensor_task,0.0,&dato,NULL);
if (daq_error !=0) process_error(daq_error,"Lectura sensor ACME()");
if ((dato & ¿?)===0) return(0);
else return(1);
}
Solución:
int............................(void)
máscara= 0x00000040
Completar el código siguiente pare gestionar la lectura de un sensor digital marca Acme conectado a una tarjeta NI USB-6008 en P0.5. Se pide sustituir los tres interrogantes remarcados en color rojo por el código en lenguaje C correspondiente:
¿? lectura_sensor_acme(¿?) {
int32 daq_error;
uInt32 dato;
daq_error=DAQmxReadDigitalScalarU32(digital_sensor_task,0.0,&dato,NULL);
if (daq_error !=0) process_error(daq_error,"Lectura sensor ACME()");
if ((dato & ¿?)===0) return(0);
else return(1);
}
Solución:
int..............................(void)
máscara = 0x00000020
Tipo B
Completar el código siguiente pare gestionar la lectura de un sensor digital marca Acme conectado a una tarjeta NI USB-6008 en P0.7. Se pide sustituir los tres interrogantes remarcados en color rojo por el código en lenguaje C correspondiente:
¿? lectura_sensor_acme(¿?) {
int32 daq_error;
uInt32 dato;
daq_error=DAQmxReadDigitalScalarU32(digital_sensor_task,0.0,&dato,NULL);
if (daq_error !=0) process_error(daq_error,"Lectura sensor ACME()");
if ((dato & ¿?)===0) return(0);
else return(1);
}
Solución:
int............................(void)
máscara=0x00000080
Tipo C
Completar el código siguiente pare gestionar la lectura de un sensor digital marca Acme conectado a una tarjeta NI USB-6008 en P0.3. Se pide sustituir los tres interrogantes remarcados en color rojo por el código en lenguaje C correspondiente:
¿? lectura_sensor_acme(¿?) {
int32 daq_error;
uInt32 dato;
daq_error=DAQmxReadDigitalScalarU32(digital_sensor_task,0.0,&dato,NULL);
if (daq_error !=0) process_error(daq_error,"Lectura sensor ACME()");
if ((dato & ¿?)===0) return(0);
else return(1);
}
Solución:
int.............................(void)
máscara= 0x00000008
Tipo D
Completar el código siguiente pare gestionar la lectura de un sensor digital marca Acme conectado a una tarjeta NI USB-6008 en P0.6. Se pide sustituir los tres interrogantes remarcados en color rojo por el código en lenguaje C correspondiente:
¿? lectura_sensor_acme(¿?) {
int32 daq_error;
uInt32 dato;
daq_error=DAQmxReadDigitalScalarU32(digital_sensor_task,0.0,&dato,NULL);
if (daq_error !=0) process_error(daq_error,"Lectura sensor ACME()");
if ((dato & ¿?)===0) return(0);
else return(1);
}
Solución:
int............................(void)
máscara= 0x00000040
Control - Cuestión 2 Tipo A, B, C, D
Tipo A
Disponemos de un convertidor analógico/digital de 12 bits, con Vgnd=0V y Vref=8V, al que conectamos un sensor analógico para medir el nivel en litros de una solución líquida que hay en un depósito. El sensor proporciona 8 voltios cuando el nivel es de 4200 litros y 0 voltios cuando el nivel es de 0 litros.
Se pide:
a) Obtener la expresión matemática que relaciona los voltios con los litros.
b) Obtener la expresión matemática que relaciona los voltios con el dato digital.
c) Obtener la expresión matemática que relaciona el dato digital con los litros.
Solución:
a) Hay que sacar la ecuación de la recta que pasa por los dos puntos (0,0) y (4200,0). Para ello aplicamos la fórmula siguiente:
Y-Y1 / X-X1 = Y2-Y1 / X2-X1
V-0 / L-0 = 8-0 / 4200-0
V = L/525
b) V = (8-0 / 2^12) * Dato_digital = (8/4096) * Dato_digital = Dato_digital / 512
c) L / 525 = Dato_digital / 512
L = 1,0253 * Dato_digital
Tipo B
Disponemos de un convertidor analógico/digital de 12 bits, con Vgnd=0V y Vref=6V, al que conectamos un sensor analógico para medir el nivel en litros de una solución líquida que hay en un depósito. El sensor proporciona 6 voltios cuando el nivel es de 3600 litros y 0 voltios cuando el nivel es de 0 litros.
Se pide:
a) Obtener la expresión matemática que relaciona los voltios con los litros.
b) Obtener la expresión matemática que relaciona los voltios con el dato digital.
c) Obtener la expresión matemática que relaciona el dato digital con los litros.
Solución:
Los dos puntos de la recta son: (0,0) (3600, 6).
a) V-0/L-0 = 6-0/3600-0 => V=L/600.
b) V=(6-0/2^12) * Dato_digital = (6/4096)*Dato_digital => V=Dato_digital/682,66
c) Dato_digital/682,66 = L/600 => L = (600*Dato_digital)/682.66 =>
L = 1,1377 * Dato_digital
Tipo C
Disponemos de un convertidor analógico/digital de 12 bits, con Vgnd=0V y Vref=12V, al que conectamos un sensor analógico para medir el nivel en litros de una solución líquida que hay en un depósito. El sensor proporciona 6 voltios cuando el nivel es de 5400 litros y 0 voltios cuando el nivel es de 0 litros.
Se pide:
a) Obtener la expresión matemática que relaciona los voltios con los litros.
b) Obtener la expresión matemática que relaciona los voltios con el dato digital.
c) Obtener la expresión matemática que relaciona el dato digital con los litros.
Solución:
a) V-0/L-0=12-0/5400-0 => V/L=1/450 => V=L/450
b) V=(12-0/2^12)*Dato_digital => V=Dato_digital/341,333
c) L/450=Dato_digital/341,333 => L=450*Dato_digital/341,333
L=1,31837*Dato_digital
Tipo D
Disponemos de un convertidor analógico/digital de 12 bits, con Vgnd=0V y Vref=14V, al que conectamos un sensor analógico para medir el nivel en litros de una solución líquida que hay en un depósito. El sensor proporciona 6 voltios cuando el nivel es de 3500 litros y 0 voltios cuando el nivel es de 0 litros.
Se pide:
a) Obtener la expresión matemática que relaciona los voltios con los litros.
b) Obtener la expresión matemática que relaciona los voltios con el dato digital.
c) Obtener la expresión matemática que relaciona el dato digital con los litros.
Solución:
Contamos con los dos puntos de la recta (0,0) y (3500,14).
a) V-0/L-0=14-0/3500-0 => V/L=1/250 => V=L/250
b) V=(14-0/2^12)*Dato_digital => V=Dato_digital/292,5714
c) L/250=Dato_digital/292,5714 => L=250*Dato_digital/292,5714
L=0,8544*Dato_digital
Disponemos de un convertidor analógico/digital de 12 bits, con Vgnd=0V y Vref=8V, al que conectamos un sensor analógico para medir el nivel en litros de una solución líquida que hay en un depósito. El sensor proporciona 8 voltios cuando el nivel es de 4200 litros y 0 voltios cuando el nivel es de 0 litros.
Se pide:
a) Obtener la expresión matemática que relaciona los voltios con los litros.
b) Obtener la expresión matemática que relaciona los voltios con el dato digital.
c) Obtener la expresión matemática que relaciona el dato digital con los litros.
Solución:
a) Hay que sacar la ecuación de la recta que pasa por los dos puntos (0,0) y (4200,0). Para ello aplicamos la fórmula siguiente:
Y-Y1 / X-X1 = Y2-Y1 / X2-X1
V-0 / L-0 = 8-0 / 4200-0
V = L/525
b) V = (8-0 / 2^12) * Dato_digital = (8/4096) * Dato_digital = Dato_digital / 512
c) L / 525 = Dato_digital / 512
L = 1,0253 * Dato_digital
Tipo B
Disponemos de un convertidor analógico/digital de 12 bits, con Vgnd=0V y Vref=6V, al que conectamos un sensor analógico para medir el nivel en litros de una solución líquida que hay en un depósito. El sensor proporciona 6 voltios cuando el nivel es de 3600 litros y 0 voltios cuando el nivel es de 0 litros.
Se pide:
a) Obtener la expresión matemática que relaciona los voltios con los litros.
b) Obtener la expresión matemática que relaciona los voltios con el dato digital.
c) Obtener la expresión matemática que relaciona el dato digital con los litros.
Solución:
Los dos puntos de la recta son: (0,0) (3600, 6).
a) V-0/L-0 = 6-0/3600-0 => V=L/600.
b) V=(6-0/2^12) * Dato_digital = (6/4096)*Dato_digital => V=Dato_digital/682,66
c) Dato_digital/682,66 = L/600 => L = (600*Dato_digital)/682.66 =>
L = 1,1377 * Dato_digital
Tipo C
Disponemos de un convertidor analógico/digital de 12 bits, con Vgnd=0V y Vref=12V, al que conectamos un sensor analógico para medir el nivel en litros de una solución líquida que hay en un depósito. El sensor proporciona 6 voltios cuando el nivel es de 5400 litros y 0 voltios cuando el nivel es de 0 litros.
Se pide:
a) Obtener la expresión matemática que relaciona los voltios con los litros.
b) Obtener la expresión matemática que relaciona los voltios con el dato digital.
c) Obtener la expresión matemática que relaciona el dato digital con los litros.
Solución:
a) V-0/L-0=12-0/5400-0 => V/L=1/450 => V=L/450
b) V=(12-0/2^12)*Dato_digital => V=Dato_digital/341,333
c) L/450=Dato_digital/341,333 => L=450*Dato_digital/341,333
L=1,31837*Dato_digital
Tipo D
Disponemos de un convertidor analógico/digital de 12 bits, con Vgnd=0V y Vref=14V, al que conectamos un sensor analógico para medir el nivel en litros de una solución líquida que hay en un depósito. El sensor proporciona 6 voltios cuando el nivel es de 3500 litros y 0 voltios cuando el nivel es de 0 litros.
Se pide:
a) Obtener la expresión matemática que relaciona los voltios con los litros.
b) Obtener la expresión matemática que relaciona los voltios con el dato digital.
c) Obtener la expresión matemática que relaciona el dato digital con los litros.
Solución:
Contamos con los dos puntos de la recta (0,0) y (3500,14).
a) V-0/L-0=14-0/3500-0 => V/L=1/250 => V=L/250
b) V=(14-0/2^12)*Dato_digital => V=Dato_digital/292,5714
c) L/250=Dato_digital/292,5714 => L=250*Dato_digital/292,5714
L=0,8544*Dato_digital
Control - Cuestión 1 Tipo D
En un sistema informático industrial se tiene un proceso del que se quiere medir la humedad en el interior de un recinto. Para ello se utiliza un sensor analógico.
Se pide escribir el código en lenguaje C del módulo de datos para gestionar la imagen digital del citado sensor (variable para almacenar la información, función para almacenar y para leer la información). No hace falta indicar el código del archivo .h, únicamente el .cpp
Solución:
Para diseñar el módulo de datos, debemos empezar preguntándonos cuantos sensores hay en dicho sistema. Sólo tenemos uno (medirá la humedad), definimos por tanto una variable que lo represente.
double humedad;
Para cada variable definida en el módulo de datos, debe haber como mínimo dos funciones, una para leer el valor de la misma (leer_humedad) y otra para escribir un valor en ella (escribir_humedad). El módulo de datos propuesto tendrá este aspecto:
double humedad;
void almacenar_humedad(double valor)
{
humedad = valor;
}
double leer_humedad(void)
{
return (humedad);
}
Se pide escribir el código en lenguaje C del módulo de datos para gestionar la imagen digital del citado sensor (variable para almacenar la información, función para almacenar y para leer la información). No hace falta indicar el código del archivo .h, únicamente el .cpp
Solución:
Para diseñar el módulo de datos, debemos empezar preguntándonos cuantos sensores hay en dicho sistema. Sólo tenemos uno (medirá la humedad), definimos por tanto una variable que lo represente.
double humedad;
Para cada variable definida en el módulo de datos, debe haber como mínimo dos funciones, una para leer el valor de la misma (leer_humedad) y otra para escribir un valor en ella (escribir_humedad). El módulo de datos propuesto tendrá este aspecto:
double humedad;
void almacenar_humedad(double valor)
{
humedad = valor;
}
double leer_humedad(void)
{
return (humedad);
}
Control - Cuestión 1 Tipo C
En un sistema informático industrial se tiene un proceso del que se quiere medir la presión de un tanque. Para ello se utiliza un sensor analógico.
Se pide escribir el código en lenguaje C del módulo de datos para gestionar la imagen digital del citado sensor (variable para almacenar la información, función para almacenar y para leer la información). No hace falta indicar el código del archivo .h, únicamente el .cpp
Solución:
Para diseñar el módulo de datos, debemos empezar preguntándonos cuantos sensores hay en dicho sistema. Sólo tenemos uno (medirá la presión), definimos por tanto una variable que lo represente.
Para cada variable definida en el módulo de datos, habrá como mínimo dos funciones, una para leer el valor de la misma (leer_presión) y otra para escribir un valor en ella (escribir_presión). El módulo de datos propuesto tendrá este aspecto:
double presion; // variable que almacena el valor del sensor
void almacenar_presion(double valor) // escribe en la variable
{
presion = valor;
}
double leer_presion(void) // lee el valor de la variable
{
return (presion);
}
Se pide escribir el código en lenguaje C del módulo de datos para gestionar la imagen digital del citado sensor (variable para almacenar la información, función para almacenar y para leer la información). No hace falta indicar el código del archivo .h, únicamente el .cpp
Solución:
Para diseñar el módulo de datos, debemos empezar preguntándonos cuantos sensores hay en dicho sistema. Sólo tenemos uno (medirá la presión), definimos por tanto una variable que lo represente.
Para cada variable definida en el módulo de datos, habrá como mínimo dos funciones, una para leer el valor de la misma (leer_presión) y otra para escribir un valor en ella (escribir_presión). El módulo de datos propuesto tendrá este aspecto:
double presion; // variable que almacena el valor del sensor
void almacenar_presion(double valor) // escribe en la variable
{
presion = valor;
}
double leer_presion(void) // lee el valor de la variable
{
return (presion);
}
Control - Cuestión 1 Tipo B
En un sistema informático industrial se tiene un proceso del que se quiere medir la temperatura de una habitación. Para ello se utiliza un sensor analógico.
Se pide escribir el código en lenguaje C del módulo de datos para gestionar la imagen digital del citado sensor (variable para almacenar la información, función para almacenar y para leer la información). No hace falta indicar el código del archivo .h, únicamente el .cpp
Solución:
Para diseñar el módulo de datos, debemos empezar preguntándonos cuantos sensores hay en dicho sistema. Sólo tenemos uno (medirá la temperatura), definimos por tanto una variable que lo represente.
Para cada variable definida en el módulo de datos, debe haber como mínimo dos funciones, una para leer el valor de la misma (leer_temperatura) y otra para escribir un valor en ella (escribir_temperatura). El módulo de datos propuesto tendrá este aspecto:
double temperatura; // almacena la temperatura del sensor..
void almacenar_temperatura(double valor)
{
temperatura = valor;
}
double leer_temperatura(void)
{
return (temperatura);
}
Importante:
La función "lee_temperatura" lee el valor de la variable "temperatura" ¡no la temperatura real!
La función "escribe_temperatura" almacena un dato en la variable, ese dato se habrá obtenido anteriormente con otra función que lee físicamente el sensor.
Se pide escribir el código en lenguaje C del módulo de datos para gestionar la imagen digital del citado sensor (variable para almacenar la información, función para almacenar y para leer la información). No hace falta indicar el código del archivo .h, únicamente el .cpp
Solución:
Para diseñar el módulo de datos, debemos empezar preguntándonos cuantos sensores hay en dicho sistema. Sólo tenemos uno (medirá la temperatura), definimos por tanto una variable que lo represente.
Para cada variable definida en el módulo de datos, debe haber como mínimo dos funciones, una para leer el valor de la misma (leer_temperatura) y otra para escribir un valor en ella (escribir_temperatura). El módulo de datos propuesto tendrá este aspecto:
double temperatura; // almacena la temperatura del sensor..
void almacenar_temperatura(double valor)
{
temperatura = valor;
}
double leer_temperatura(void)
{
return (temperatura);
}
Importante:
La función "lee_temperatura" lee el valor de la variable "temperatura" ¡no la temperatura real!
La función "escribe_temperatura" almacena un dato en la variable, ese dato se habrá obtenido anteriormente con otra función que lee físicamente el sensor.
Control - Cuestión 1 Tipo A
En un sistema informático industrial se tiene un proceso del que se quiere medir el nivel existente en un tanque de líquido. Para ello se utiliza un sensor analógico...

Se pide escribir el código en lenguaje C del módulo de datos para gestionar la imagen digital del citado sensor (variable para almacenar la información, función para almacenar y para leer la información).
Nota: No hace falta indicar el código del archivo .h, únicamente el .cpp
Solución:
Para diseñar el módulo de datos, debemos empezar preguntándonos cuantos sensores hay en dicho sistema. Como en este problema sólo tenemos uno (medirá el nivel de líquido), definiremos una variable que lo represente.
Por cada variable definida en el módulo de datos, debe haber como mínimo dos funciones, una para leer el valor de la misma (leer_nivel) y otra para escribir un valor en ella (escribir_nivel). El módulo de datos propuesto tendrá este aspecto:
Cuando se lee físicamente el sensor, el nivel que se obtendrá será un valor del tipo "5,43 litros", por eso se define la variable real (double). Si quisiéramos representar valores entre 0 y 100, valores enteros, utilizaríamos una variable tipo entera "int".
Pasos para definir correctamente un módulo de datos...
1.- ¿Cuántos sensores tiene mi sistema? ..define una variable por cada sensor..
2.- ¿Qué tipo de dato devuelve el sensor?..real, entero, etc..define el tipo de variable..
3.- Por cada variable definida, crea dos funciones (lectura y escritura)..
(participa enviando tus comentarios)

Se pide escribir el código en lenguaje C del módulo de datos para gestionar la imagen digital del citado sensor (variable para almacenar la información, función para almacenar y para leer la información).
Nota: No hace falta indicar el código del archivo .h, únicamente el .cpp
Solución:
Para diseñar el módulo de datos, debemos empezar preguntándonos cuantos sensores hay en dicho sistema. Como en este problema sólo tenemos uno (medirá el nivel de líquido), definiremos una variable que lo represente.
Por cada variable definida en el módulo de datos, debe haber como mínimo dos funciones, una para leer el valor de la misma (leer_nivel) y otra para escribir un valor en ella (escribir_nivel). El módulo de datos propuesto tendrá este aspecto:
Cuando se lee físicamente el sensor, el nivel que se obtendrá será un valor del tipo "5,43 litros", por eso se define la variable real (double). Si quisiéramos representar valores entre 0 y 100, valores enteros, utilizaríamos una variable tipo entera "int".
Pasos para definir correctamente un módulo de datos...
1.- ¿Cuántos sensores tiene mi sistema? ..define una variable por cada sensor..
2.- ¿Qué tipo de dato devuelve el sensor?..real, entero, etc..define el tipo de variable..
3.- Por cada variable definida, crea dos funciones (lectura y escritura)..
(participa enviando tus comentarios)
30 de noviembre de 2010
Unresolved external 'TForm1'...
Hoy nos hemos encontrado algunos errores de este tipo al compilar proyectos en clase, donde se apunta a un problema con un formulario..tiene esta pinta:
En el error se avisa de un problema en "PRACTICA6.OBJ", un objeto dependiente directamente de la unidad con el mismo nombre. En vuestro caso podría mostrarse el nombre de otra unidad..
Solución: Abre el gestor de proyectos con la opción "View/Manager"...

..busca la unidad referida en el error "Practica6.cpp" y ábrela..
..bien ahora va algo de teoría (pero no mucha), observa que esta unidad principal, la que arranca el programa cuando hacemos doble clic en el .exe o compilamos en Borland, (es la que tiene el bloque "WinMain")..está claro..
..este bloque inicia nuestro programa y todos los elementos necesarios, como los formularios..
..en la cabecera apaece el siguiente código:
USEFORM("Uprincipal6.cpp", Vprincipal);
USEFORM("process.cpp", Form1);
..estas dos instrucciones preparan los formularios que utiliza vuestro proyecto, en este caso parece que hay dos..cuando sólo debería haber uno..
..el segundo sobra, el que está asociado a la unidad "process.cpp", no debería estar ahí...asi que se comenta la línea y dejamos sólo el formulario principal, queda así:
USEFORM("Uprincipal6.cpp", Vprincipal);
//USEFORM("process.cpp", Form1);
..seguimos, un poco más abajo..
Application->Initialize();
Application->CreateForm(__classid(TVprincipal), &Vprincipal);
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
..son las instrucciones que inician el sistema y crean los formularios, hay que eliminar la que arranca el formulario que no necesitamos, la tercera línea fuera..queda así:
Application->Initialize();
Application->CreateForm(__classid(TVprincipal), &Vprincipal);
//Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
..con estas modificaciones yo lo tenemos compilando sin errores, listo para poder seguir..
..podéis borrar las líneas comentadas..
..si tenéis algún otro error, me mandáis el proyecto en un zip y le echo un vistazo ;-)
En el error se avisa de un problema en "PRACTICA6.OBJ", un objeto dependiente directamente de la unidad con el mismo nombre. En vuestro caso podría mostrarse el nombre de otra unidad..
Solución: Abre el gestor de proyectos con la opción "View/Manager"...

..busca la unidad referida en el error "Practica6.cpp" y ábrela..
..bien ahora va algo de teoría (pero no mucha), observa que esta unidad principal, la que arranca el programa cuando hacemos doble clic en el .exe o compilamos en Borland, (es la que tiene el bloque "WinMain")..está claro..
..este bloque inicia nuestro programa y todos los elementos necesarios, como los formularios..
..en la cabecera apaece el siguiente código:
USEFORM("Uprincipal6.cpp", Vprincipal);
USEFORM("process.cpp", Form1);
..estas dos instrucciones preparan los formularios que utiliza vuestro proyecto, en este caso parece que hay dos..cuando sólo debería haber uno..
..el segundo sobra, el que está asociado a la unidad "process.cpp", no debería estar ahí...asi que se comenta la línea y dejamos sólo el formulario principal, queda así:
USEFORM("Uprincipal6.cpp", Vprincipal);
//USEFORM("process.cpp", Form1);
..seguimos, un poco más abajo..
Application->Initialize();
Application->CreateForm(__classid(TVprincipal), &Vprincipal);
Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
..son las instrucciones que inician el sistema y crean los formularios, hay que eliminar la que arranca el formulario que no necesitamos, la tercera línea fuera..queda así:
Application->Initialize();
Application->CreateForm(__classid(TVprincipal), &Vprincipal);
//Application->CreateForm(__classid(TForm1), &Form1);
Application->Run();
..con estas modificaciones yo lo tenemos compilando sin errores, listo para poder seguir..
..podéis borrar las líneas comentadas..
..si tenéis algún otro error, me mandáis el proyecto en un zip y le echo un vistazo ;-)
The requested file doesn't exist / El fichero no existe...
Hola Luis, cuando intentamos compilar el proyecto, aparece el siguiente error, ¿puedes echarnos una mano? m.s.f. grupo 222.
Como puedes ver en la imagen (junto al texto "Fatal Error" al pie de la imagen), se avisa que hay un archivo (Planificador.cpp) que no existe, esto quiere decir que aunque has creado la unidad, Borland no puede encontrarla, es decir, la tiene en su "lista" de unidades del proyecto pero no está físicamente en la carpeta junto a las demás, porque ha sido movida, borrada o guardada en otro lugar..por eso aparece la ventana solicitando que tomes una decisión..
Si lo que sucedió es que moviste esta unidad fuera de la carpeta del proyecto, sólo tendrás que pegarla de nuevo a la carpeta de trabajo y recompilar. Si la borraste..
Solución: Cancela la ventana que aparece, haciendo clic en el botón "Cancelar" y regresa a Borland. Si has borrado la unidad, entonces crea una nueva utilizando el menú "File/New/Unit...
..verás que aparece en tu proyecto una nueva unidad..en este ejemplo aparece como "Unit1"...
...pero podría tener otro nombre, "Unit2", etc...ahora sin hacer nada antes, selecciona la opción "File/Save" para guardar esta nueva unidad...

..observa que por defecto en el campo "Nombre" aparece "Unit1", cambia este nombe por el nombre de la unidad que está buscando tu proyecto "Planificador" y haz clic en el botón "Guardar" para continuar:
..no hace falta que añadas la extensión ".cpp" al nombre de la unidad, Borland lo hace automáticamente.
Una vez guardada la nueva unidad "Planificador" (o la que corresponda con tu proyecto), guarda todo el proyecto con la opción "File/Save all" y recompila.
Ahora puedes escribir el código en este unidad, pero asegúrate de guardar tu proyecto frecuentemente y haz copia de seguridad en algún medio portátil como un lápiz usb o enviándote un correo con todo el proyecto comprimido (más vale prevenir!).
Como puedes ver en la imagen (junto al texto "Fatal Error" al pie de la imagen), se avisa que hay un archivo (Planificador.cpp) que no existe, esto quiere decir que aunque has creado la unidad, Borland no puede encontrarla, es decir, la tiene en su "lista" de unidades del proyecto pero no está físicamente en la carpeta junto a las demás, porque ha sido movida, borrada o guardada en otro lugar..por eso aparece la ventana solicitando que tomes una decisión..
Si lo que sucedió es que moviste esta unidad fuera de la carpeta del proyecto, sólo tendrás que pegarla de nuevo a la carpeta de trabajo y recompilar. Si la borraste..
Solución: Cancela la ventana que aparece, haciendo clic en el botón "Cancelar" y regresa a Borland. Si has borrado la unidad, entonces crea una nueva utilizando el menú "File/New/Unit...
..verás que aparece en tu proyecto una nueva unidad..en este ejemplo aparece como "Unit1"...
...pero podría tener otro nombre, "Unit2", etc...ahora sin hacer nada antes, selecciona la opción "File/Save" para guardar esta nueva unidad...

..observa que por defecto en el campo "Nombre" aparece "Unit1", cambia este nombe por el nombre de la unidad que está buscando tu proyecto "Planificador" y haz clic en el botón "Guardar" para continuar:
..no hace falta que añadas la extensión ".cpp" al nombre de la unidad, Borland lo hace automáticamente.
Una vez guardada la nueva unidad "Planificador" (o la que corresponda con tu proyecto), guarda todo el proyecto con la opción "File/Save all" y recompila.
Ahora puedes escribir el código en este unidad, pero asegúrate de guardar tu proyecto frecuentemente y haz copia de seguridad en algún medio portátil como un lápiz usb o enviándote un correo con todo el proyecto comprimido (más vale prevenir!).
14 de noviembre de 2010
Ejercicios con máscaras AND y OR (control)
Ejercicios de repaso:
Con estos ejercicios repasamos el uso de los operadores "AND" y "OR" para modificar el estado de algunos bits. Recuerda que la importancia de estos operaciones radica en poder cambiar el estado de un bit aislado "sin modificar" el estado de los demás.
Teniendo en cuenta que usamos la variable unsigned char mivar...
1. Poner los bits 2 y 5 a "0".
Una variable tipo char almacena un carácter (1 byte), cuando se usa junto al modificador 'unsigned' quiere decir que todos los bits son utilizados como dato. Cuando se usa junto al modificador 'signed', el bit 7 se utiliza como signo y por lo tanto sólo se dispone de 7 bits. En nuestro caso disponemos de 8 bits (b7....b0).
Si deseamos poner un bit a "0", usamos el operador "AND".
Escribe un "0" en los bits a cancelar y "1" en los demás. La máscara quedará:
valor = valor & 1101 1011; (observa que se ha puesto "0" en los bits a cancelar)
valor = valor & 0xDB;
2. Poner los bits 1, 3, 7 a "1".
Si deseamos poner a "1" un bit usamos el operador "OR".
Escribe un "1" en los bits que deseamos activar y "0" en los demás. La máscara quedará:
valor = valor | 1000 1010;
valor = valor | 0x8A;
3. Complementar el valor de los bits 4 y 6.
Para complementar usamos el operador XOR.
Escribe un "1" en el bit a complementar y los demás a "0". La máscara quedará por lo tanto:
valor = valor XOR 0101 0000;
valor = valor XOR 0x50;
4. Utilizando la variable valor char, poner a "1" la parte alta del registro y a "0" la parte baja,
La variable valor tipo char contiene 8 bits. La parte alta son los cuatro bits de la izquierda.
Para poner a "1" estos bits utilizamos el operador "OR" con una máscara:
valor = valor OR 1111 0000;
valor = valor OR 0xF0;
Si deseamos poner a "0" la parte baja, utilizamos el operador "AND":
valor = valor AND 11110000;
valor = valor AND 0xF0;
Nota: Un grupo de 4 bits se llama "nibble", leer más en Wikipedia
Importante: Cuando se hace referencia al bit 5, no hay que olvidar contar desde la derecha (cero incluido).
También puedes leer en el blog el artículo "Usar el operador AND"
Con estos ejercicios repasamos el uso de los operadores "AND" y "OR" para modificar el estado de algunos bits. Recuerda que la importancia de estos operaciones radica en poder cambiar el estado de un bit aislado "sin modificar" el estado de los demás.
Teniendo en cuenta que usamos la variable unsigned char mivar...
1. Poner los bits 2 y 5 a "0".
Una variable tipo char almacena un carácter (1 byte), cuando se usa junto al modificador 'unsigned' quiere decir que todos los bits son utilizados como dato. Cuando se usa junto al modificador 'signed', el bit 7 se utiliza como signo y por lo tanto sólo se dispone de 7 bits. En nuestro caso disponemos de 8 bits (b7....b0).
Si deseamos poner un bit a "0", usamos el operador "AND".
Escribe un "0" en los bits a cancelar y "1" en los demás. La máscara quedará:
valor = valor & 1101 1011; (observa que se ha puesto "0" en los bits a cancelar)
valor = valor & 0xDB;
2. Poner los bits 1, 3, 7 a "1".
Si deseamos poner a "1" un bit usamos el operador "OR".
Escribe un "1" en los bits que deseamos activar y "0" en los demás. La máscara quedará:
valor = valor | 1000 1010;
valor = valor | 0x8A;
3. Complementar el valor de los bits 4 y 6.
Para complementar usamos el operador XOR.
Escribe un "1" en el bit a complementar y los demás a "0". La máscara quedará por lo tanto:
valor = valor XOR 0101 0000;
valor = valor XOR 0x50;
4. Utilizando la variable valor char, poner a "1" la parte alta del registro y a "0" la parte baja,
La variable valor tipo char contiene 8 bits. La parte alta son los cuatro bits de la izquierda.
Para poner a "1" estos bits utilizamos el operador "OR" con una máscara:
valor = valor OR 1111 0000;
valor = valor OR 0xF0;
Si deseamos poner a "0" la parte baja, utilizamos el operador "AND":
valor = valor AND 11110000;
valor = valor AND 0xF0;
Nota: Un grupo de 4 bits se llama "nibble", leer más en Wikipedia
Importante: Cuando se hace referencia al bit 5, no hay que olvidar contar desde la derecha (cero incluido).
También puedes leer en el blog el artículo "Usar el operador AND"
Bus de direcciones y datos (control)
Ejercicios de repaso:
1. Una memoria dispone de 2 líneas de dirección y 8 líneas de datos.
¿Cuántos bits es capaz de almacenar? ¿Cuál es el valor hexadecimal de la última dirección?
Con 2 líneas de direcciones, podremos direccionar 2^2 = 4 direcciones.
00- posición 0
01 - posición 1
10 - posición 2
11 - posición 3
En total son 4 posiciones, pero al empezar a contar desde cero, hay que restar una unidad.
La última dirección será: 2^2-1= 3 (0x3).
En cada posición podemos almacenar 8 bits, por lo tanto la capacidad total es de 4x8 = 32 bits.
2. Una memoria dispone de 16 líneas de dirección y 8 líneas de datos.
¿Cuántos bits es capaz de almacenar? ¿Cuál es el valor hexadecimal de la última dirección?
Con 16 líneas, tenemos 2^16 = 65536 direcciones.
0000000000000000 - posición 0
0000000000000001 - posición 1
...............................
...............................
111111111111110
111111111111111 - última dirección.
Igual que antes, son 65536 posiciones, pero al empezar a contar desde cero, hay que restar una unidad.
La última dirección será 2^16-1 = 65536-1 = 65535 = 0xFF.
En cada una almacenamos 8 bits, la capacidad total será de 65536x8 = 524.288 bits.
Resumiendo: Podemos conocer la cantidad de direcciones de memoria como las combinaciones de 2 elevando a 'n', donde 'n' es el número de líneas de direcciones. Cuantas más bits (líneas) de direcciones, más posiciones de memoria podremos direccionar y por lo tanto más información podremos almacenar.
Sugerencias a tener en cuenta:
"Puede direccionar 2^16 x 8" - Ésto es la capacidad de la memoria en bits (16 líneas de direcciones y 8 de datos), no el número de posiciones de memoria que se calcula como 2^16.
"El valor hexadecimal será FFFF" - No es un error importante, pero incluid siempre la notación correctamente, si el valor está expresado en hexadecimal, precededlo con "0x". Lo correcto sería 0xFFFF.
"La capacidad de la memoria será 2^16 x 2^8" - Error grave, en cada posición se puede almacenar sólo 8 bits, no la combinación de todos ellos, por lo tanto si tenemos 65536 posiciones donde en cada una se almacena 8 bits, entonces la capacidad será 2^16 x 8 = 524288 bits.
Ejercicios propuestos:
1. Una memoria dispone de 4 líneas de dirección y 16 líneas de datos. ¿Cuántas posiciones de memoria pueden direccionarse? ¿Cuántos bits es capaz de almacenar?
¿Cuál es el valor hexadecimal de la última dirección?
2. Una memoria dispone de 32 líneas de dirección y 2 líneas de datos. ¿Cuántas posiciones de memoria pueden direccionarse? ¿Cuántos bits es capaz de almacenar?
¿Cuál es el valor hexadecimal de la última dirección?
3. Necesito disponer de 1543 direcciones de memoria ¿cuántas líneas de direcciones son necesarias? ¿Cuál es el valor hexadecimal de la última dirección?
4. Necesito disponer de 9 bits de datos en cada dirección de memoria, ¿cuántas líneas de datos necesito? Para el caso anterior, ¿cuál es la capacidad total en bits de la memoria?
Lee más sobre el bus de direcciones en Wikipedia:
http://es.wikipedia.org/wiki/Bus_de_direcciones
..
1. Una memoria dispone de 2 líneas de dirección y 8 líneas de datos.
¿Cuántos bits es capaz de almacenar? ¿Cuál es el valor hexadecimal de la última dirección?
Con 2 líneas de direcciones, podremos direccionar 2^2 = 4 direcciones.
00- posición 0
01 - posición 1
10 - posición 2
11 - posición 3
En total son 4 posiciones, pero al empezar a contar desde cero, hay que restar una unidad.
La última dirección será: 2^2-1= 3 (0x3).
En cada posición podemos almacenar 8 bits, por lo tanto la capacidad total es de 4x8 = 32 bits.
2. Una memoria dispone de 16 líneas de dirección y 8 líneas de datos.
¿Cuántos bits es capaz de almacenar? ¿Cuál es el valor hexadecimal de la última dirección?
Con 16 líneas, tenemos 2^16 = 65536 direcciones.
0000000000000000 - posición 0
0000000000000001 - posición 1
...............................
...............................
111111111111110
111111111111111 - última dirección.
Igual que antes, son 65536 posiciones, pero al empezar a contar desde cero, hay que restar una unidad.
La última dirección será 2^16-1 = 65536-1 = 65535 = 0xFF.
En cada una almacenamos 8 bits, la capacidad total será de 65536x8 = 524.288 bits.
Resumiendo: Podemos conocer la cantidad de direcciones de memoria como las combinaciones de 2 elevando a 'n', donde 'n' es el número de líneas de direcciones. Cuantas más bits (líneas) de direcciones, más posiciones de memoria podremos direccionar y por lo tanto más información podremos almacenar.
Sugerencias a tener en cuenta:
"Puede direccionar 2^16 x 8" - Ésto es la capacidad de la memoria en bits (16 líneas de direcciones y 8 de datos), no el número de posiciones de memoria que se calcula como 2^16.
"El valor hexadecimal será FFFF" - No es un error importante, pero incluid siempre la notación correctamente, si el valor está expresado en hexadecimal, precededlo con "0x". Lo correcto sería 0xFFFF.
"La capacidad de la memoria será 2^16 x 2^8" - Error grave, en cada posición se puede almacenar sólo 8 bits, no la combinación de todos ellos, por lo tanto si tenemos 65536 posiciones donde en cada una se almacena 8 bits, entonces la capacidad será 2^16 x 8 = 524288 bits.
Ejercicios propuestos:
1. Una memoria dispone de 4 líneas de dirección y 16 líneas de datos. ¿Cuántas posiciones de memoria pueden direccionarse? ¿Cuántos bits es capaz de almacenar?
¿Cuál es el valor hexadecimal de la última dirección?
2. Una memoria dispone de 32 líneas de dirección y 2 líneas de datos. ¿Cuántas posiciones de memoria pueden direccionarse? ¿Cuántos bits es capaz de almacenar?
¿Cuál es el valor hexadecimal de la última dirección?
3. Necesito disponer de 1543 direcciones de memoria ¿cuántas líneas de direcciones son necesarias? ¿Cuál es el valor hexadecimal de la última dirección?
4. Necesito disponer de 9 bits de datos en cada dirección de memoria, ¿cuántas líneas de datos necesito? Para el caso anterior, ¿cuál es la capacidad total en bits de la memoria?
Lee más sobre el bus de direcciones en Wikipedia:
http://es.wikipedia.org/wiki/Bus_de_direcciones
..
30 de octubre de 2010
Añadir un formulario al proyecto
Cuando trabajo en un proyecto Borland C++, puedo necesitar más formularios además del principal "Form1". Para añadirlo sólo hay que seleccionar la opción del menú "File/New/Form".
Lo que ocurre entonces es que Borland crea una unidad nueva asociada al formulario. Ambos objetos forman un conjunto. En el formulario se añaden los elementos gráficos y en la unidad el código de cada objeto, función, etc.
Para verlo en HD activa "Pantalla completa" después de iniciar la reproducción.
Lo que ocurre entonces es que Borland crea una unidad nueva asociada al formulario. Ambos objetos forman un conjunto. En el formulario se añaden los elementos gráficos y en la unidad el código de cada objeto, función, etc.
Para verlo en HD activa "Pantalla completa" después de iniciar la reproducción.
26 de octubre de 2010
Quiero cargar otro formulario en Borland C++
"He creado un proyecto en Borland C++, he guardado correctamente y al compilar, mi programa abre un formulario que no es el que deseaba. ¿Qué está ocurriendo? ¿Cómo puedo hacer que mi programa abra el formulario que deseo si tengo varios?" - Ana.
Se muestra la ventana de configuración de tu proyecto. Haz clic en la pestaña "Forms":
Primera Opción:
Cuando compilamos un programa, el primer formulario que se muestra en pantalla está determinado por las instrucciones del bloque principal "Project1.cpp". Selecciona la opción "View/Project manager" para abrir el gestor de proyectos y haz doble clic en "Project1.cpp":
Cuando compilamos un programa, el primer formulario que se muestra en pantalla está determinado por las instrucciones del bloque principal "Project1.cpp". Selecciona la opción "View/Project manager" para abrir el gestor de proyectos y haz doble clic en "Project1.cpp":
"Project1.cpp" podría tener otro nombre si lo has renombrado al crear tu proyecto. Una vez abierto, verás algunas instrucciones dentro. Puedes ver una muestra en la figura siguiente:
En la primera línea aparece: "Useform("Unit1.cpp",Form1)".
En esta instrucción se declara el formulario creado en la unidad "Unit1.cpp". Para cada formulario en el proyecto, aquí habrá una línea. Recuerda que un formulario está vinculado a las unidades.
Más adelante aparece: "Application..CreateForm".
Dicha instrucción crea los formularios. También habrá una instrucción para cada formulario. El formulario al que se haga referencia en la primera línea será el primero en cargarse (el que verá el usuario). Veamos un ejemplo:
En este proyecto tienes el bloque principal "Project1.cpp" y las dos unidades "Unit1.cpp" y "Unit3.cpp", con sus correspondientes formularios "Form1" y "Form3". Vamos a echar un vistazo al código del bloque principal "Project1.cpp" que es el encargado de cargar el formulario inicial:
En la figura anterior se puede ver que se han definido los dos formularios en las primeras líneas con la instrucción "Useform". Más adelante se crean con la instrucción "Application..CreateForm". Es importante fíjarse en el orden, primero se crea el formulario "Form1" y después "Form3", por lo tanto el que aparecerá al ejecutar la aplicación será el primero: "Form1".
Si se quisiera mostrar inicialmente el segundo, sólo se tendría que cambiar el orden de las instrucciones.
Segunda Opción:
Esta operación puedes realizarla también configurando las opciones del proyecto. Activa la opción del menú "Project/Options":
En la figura anterior puedes ver que en la zona de la izquierda aparecen los formularios usados por la aplicación (en este caso hay dos). Justo arriba en el apartado "Main form" puedes definir el formulario principal de tu aplicación. Aparece seleccionado "Form1", éste será el que se abrirá primero. Si quieres cambiarlo, sólo tienes que abrir la lista desplegable y seleccionar otro.
Esta operación lo que hace es cambiar el orden de las instrucciones que se acaban de explicar unos párrafos más arriba. Puedes comprobarlo cambiando el formulario por defecto aquí y abriendo el bloque principal de tu programa "Project1.cpp", busca las instrucciones "Application..CreateForm" y comprueba que se ha cambiado el orden de las instrucciones.
----
tiempo edición: 2'30h.
Elementos de un proyecto nuevo en Borland C++
"No tengo muy claro cual es la estructura de un proyecto, ¿por favor podrías explicármelo un poco? Gracias." - José.
Cuando empiezas un proyecto nuevo en Borland, se crean una serie de archivos. Para ver los elementos que componen dicho proyecto, puedes activar la opción del menú "View/Project manager":
"Project1.cpp" es el bloque de código que "arranca" tu programa (contiene el "main"). Normalmente no escribirás tu código aquí.
"Unit1.cpp" es un bloque o segmento de código donde escribirás tu programa. También se llama "unidad" y puedes tener las unidades que desees, pero cuando se crea un proyecto nuevo, sólo se crea una por defecto. Un buen programa tendrá varias unidades y cada una incluirá funciones diferentes, de modo que el código esté bien organizado.
"Form1" es el formulario. Cuando se crea una unidad, Borland crea también un formulario vinculado a ella. Puedes ver en la figura anterior que justo debajo de "Unit1.cpp" aparece "Form1". Un formulario te permitirá incluir elementos gráficos como botones, etiquetas y otros objetos que dotarán a tu aplicación de la necesaria interactividad.
En el siguiente diagrama puedes ver la estructura general de un proyecto. Del fichero "Project1.cpp" dependen las diferentes unidades "Unit1.cpp", "Unit2.cpp", etc. Observa que cada formulario está vinculado a una unidad.
Importante: Si eliminas de tu proyecto una unidad, también estarás borrando su formulario asociado.
Cuando empiezas un proyecto nuevo en Borland, se crean una serie de archivos. Para ver los elementos que componen dicho proyecto, puedes activar la opción del menú "View/Project manager":
"Project1.cpp" es el bloque de código que "arranca" tu programa (contiene el "main"). Normalmente no escribirás tu código aquí.
"Unit1.cpp" es un bloque o segmento de código donde escribirás tu programa. También se llama "unidad" y puedes tener las unidades que desees, pero cuando se crea un proyecto nuevo, sólo se crea una por defecto. Un buen programa tendrá varias unidades y cada una incluirá funciones diferentes, de modo que el código esté bien organizado.
"Form1" es el formulario. Cuando se crea una unidad, Borland crea también un formulario vinculado a ella. Puedes ver en la figura anterior que justo debajo de "Unit1.cpp" aparece "Form1". Un formulario te permitirá incluir elementos gráficos como botones, etiquetas y otros objetos que dotarán a tu aplicación de la necesaria interactividad.
En el siguiente diagrama puedes ver la estructura general de un proyecto. Del fichero "Project1.cpp" dependen las diferentes unidades "Unit1.cpp", "Unit2.cpp", etc. Observa que cada formulario está vinculado a una unidad.
Importante: Si eliminas de tu proyecto una unidad, también estarás borrando su formulario asociado.
Lo verás mejor si activas el modo "Pantalla completa".
(icono situado en la esquina inferior derecha del video)
----
t.edición del post 1'30h
grabación y publicación en HD
insertado en ventana, no enlace
Suscribirse a:
Entradas (Atom)