Error al compilar con PIC C de CCS

Dejo archivos sobre este proyecto por si sirve para aclararme algo más.
Gracias a cualquier curioso que se moleste en mirarlo buscando fallos.
Mira este sencillo código:
PHP:
#include <16f877.h>
#use     delay(crystal = 4MHz)


void main (void)
{
   int8 unidades,decenas,puerto;
   
   while (true)
   {

      puerto = input_b();
      
      if(puerto > 99){puerto = 99;}    // No permitir que "puerto" sea mayor a 99
      
      decenas = (puerto / 10);         // Obtener las decenas.
      puerto -= (decenas * 10);        // puerto = puerto - (Decenas * 10)
      unidades = puerto;               // para obtener las unidades.
      
      // Multiplexar los displays.
      output_c(unidades + 32);         // Mostrar unidades, activar display 2 y desactivar Display 1
      delay_ms(2);                     // Retardo para mostrar las unidades.
      output_c(decenas + 16);          // Mostrar decenas, activar display 1 y desactivar display 2
      delay_ms(2);                     // Retardo para mostrar las decenas.
   }
}
Hace lo mismo que quieres hacer, pero de una forma más sencilla.

Utiliza éste esquema por si lo quieres realizar físicamente. esquema leer puerto.jpg
 
Aclararme una cosa que diferencia hay en dejar un mensaje en RESPONDER y ponerlo EN RESPUESTA RAPIDA e enviado un mensaje en responder y no lo estoy viendo.



Me parece que a partir de ahora utilizare -respuesta rapida-, D@erbyte dame un toke si no as recibido mi mensaje porfa.
 
Última edición:
Sorry. Cada vez que sigo tus pasos acabo siempre aqui.
Lo que te queria decir es que tu codigo aunque solo muestre el numero es muy BUENO para mi D@rkbytes , he observado que 32 afecta al pin 6 y el 16 al PIN 4. ME GUSTA pero no entiendo como puede pasar de 15 utilizando solo 4 bits del PORTB te agradeceria mucho que me detallases esto D@rkbytes.
 
Última edición por un moderador:
He observado que 32 afecta al pin 6 y el 16 al PIN 4. ME GUSTA
Esa es una forma de realizar una máscara en un número.
Por ejemplo, quiero retener el número 7 y la vez mantener en 1 el bit 5:
Si el puerto es de 8 bits, entonces...

Obtenemos en binario el valor en 1 del bit 5.
0b00100000 = 32
Ahora sumamos 7 + 32 = 0b00100111

Al aplicar la máscara tenemos como resultado el número 7 (LSB) y también en 1 el bit 5
No entiendo como puede pasar de 15 utilizando solo 4 bits del PORTB.
Te agradecería mucho que me detallases ésto, D@rkbytes.
Porque no se están usando únicamente 4 bits del puerto B.
Pasa a binario el número 99 y ve cuantos bits tiene. :cool:
 
Última edición:
Si vale D@rk.
99 = 0110 0011 y esto no me aclara.
Yo crei q utilizabas la suma de 32 y 16 solo para activar distintos display
y con 37 = 0010 0101 este binario afecta a los "pin 4=false y 5=true" esto me desconcierta,deberian estar libres.
SI. Tu utilizas todos los pin de portb para leer
Pero para escribir en portc solo utilizas 4 sigo sin entender como puede pasar de 15 =1111.
Y no me mires asi.
 
No tiene gran ciencia.
Como el sistema es multiplex, se manda la cifra en números separados y se va activando el display correspondiente.
Para eso, se tiene que descomponer la cifra en decenas y unidades.
El decodificador 7447 trabaja 4 bits, por eso sólo se usan sólo 4 bits de salida.

Cuando ya se tienen los números de las decenas y las unidades separadas, se pueden mandar en cualquier orden.
Pero siempre activando el display del lugar al que corresponde cada número y enseguida se hace un retardo para mostrarse.
Como todo este proceso se lleva a cabo a una alta velocidad para nuestra vista, no notamos que mientras es mostrado un dígito, los demás permanecen apagados.

El proceso se lleva a cabo de ésta manera.
Por ejemplo, para mostrar el número 10:

Se manda el número 1 (Decenas), se activa el pin del primer display (MSB) y se hace un retardo.
Se manda el número 0 (Unidades), se activa el pin del segundo display (LSB) y se hace un retardo.

Pero mientras se activa un display, los demás deben desactivarse.
En el programa que subí, ésto se hace con el método de máscara, pero también se puede usar otro puerto para el control de los displays, y por código se van activando y desactivando.
Lo último lleva más código aunque es más sencilla su comprensión.

99 = 0110 0011 y esto no me aclara.
Creo que con la explicación que te di, ya lo podrás comprender ahora.
No se manda el 99, se manda la decena (9) y después la unidad (9), cada una de 4 bits.
Pero como ya tenemos los números separados y el sistema es multiplexado, no importa el orden en que sean enviados los números, porque no lo vamos a notar aunque sean más de 2 displays.
Por lo tanto, se pueden enviar los datos de MSB a LSB o de LSB a MSB, e incluso revueltos.
Lo que si es importante, es que cada número debe colocarse en el lugar indicado.
Y esto se logra activando el display que a ese número le corresponde.
 
Última edición:
Decenas = (puerto / 10); // 9.8=98/10 Obtener las decenas=9. (esto me confundia la logica me eXigía multiplicar)
puerto -= (decenas * 10); // puerto = puerto - (Decenas * 10)
(¿¿¿¿PERO QUE HACE AHORA CON UN unidades=-98 ???)
Unidades = puerto; // para obtener las unidades.

Lo ultimo qUE dices qUE lleva mas compresion si creo entenderlo.

Otra cosa yo solo modifique el proyecto proteus para qUE funcionase Bajo tu codigo,

Quizas sea por eso pero mis displays se encendian por separado nunca al unisono, no utilice tu doble-display ni el BCR ese
(acabo de formatear y estoy instalando todo).

Gracias por todo D@rkibites
 
Última edición por un moderador:
Hola D@rkbytes. Se que tu programa tambien funciona, pero esto es mas simple de entender.

dec=valor/10; //Como dec es un entero, se va a guardar unicamente el entero
unidaz= valor%10; //El resto de la division de 10

El unico problema es que no se me ocurrio a mi.

Saludos.
 
Estimado
muy buen programa entiendo la Multiplexación, pero vuelvo a tener una duda con respecto a tus programas, son buenos pero quedo con la misma duda; este es uno de tus programas es similar al tema puntual......

///////////////////////////////////////////////////////////////////////////
#include <16f877a.h>
#use delay (crystal = 20MHz)
#use rs232(baud=9600,xmit=pin_c6,rcv=pin_c7,bits=8)

int8 valor=0;

#int_rda
void rda_isr(void){
valor = getc();
}

void main(void){
int8 unidades,decenas;
enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);

while (true){
unidades = (valor % 10); // Se extraen las unidades.
decenas = (valor % 100)/10; // Se extraen las decenas.

output_b(unidades+16); // Se convierte el número a BCD y se activa primer dígito.
delay_ms(2); // Retardo para mostrar las unidades.
output_b(decenas+32); // Se convierte el número a BCD y se activa segundo dígito.
delay_ms(2); // Retardo para mostrar las decenas.
}
}

///////////////////////////////////////////////////////////////////////////////

estimado, tengo las siguientes consultas ojala me ayudes a entender por favor:cry:

1: quiero pasar este mismo programa a un pic16f628a
2: el pic16f628a tienes los pines de comunicación en el puerto B, se podrá configurar para usarlo en el puerto a
3: en el programa que muestro, en que parte configuras la activación para que se encienda y se apague un display de 7 segmentos
4: en el foro hablas de que se puede hacer de otra formay que trae mas programa, cual seria ea forma:confused::confused:

por favor master , ayudeme con las dudas, creo que a todos los servira
:aplauso::aplauso:
 
Última edición:
OK. Saludos.

El programa que muestras proviene de éste post: Interrupción RS232 en CCS

Si se puede usar ese programa en un PIC16F628A con el contador en los primeros 4 bits del puerto A, pero cambiando la máscara para obtener el control de los displays por los bits RA6 y RA7.
También se puede usar RA4 pero es Open Drain y se necesita una resistencia Pull-Up externa.
RA5 es sólo de entrada, así que queda descartado.

Y como se van a usar los pines RA6 y RA7 correspondientes al oscilador externo, se debe usar el oscilador interno y usar éstos pines como salidas.

3: en el programa que muestro, en que parte configuras la activación para que se encienda y se apague un display de 7 segmentos.
Eso está explicado en este mismo tema.
4: en el foro hablas de que se puede hacer de otra formay que trae mas programa, cual seria ea forma:confused:
De la forma clásica; usando un arreglo para obtener los bits de los segmentos y separar las decenas y unidades de la cifra a mostrar.
 
Última edición:
output_c(unidades + 32);
delay_ms(2);
output_c(decenas + 16);

output_c(unidades + 32); // voy descomponer para que se entienda

port c = ob00000000 = 8BITS

Si se quiere mostrar el numero 34, con multiplexacion el programa hara lo siguiente
1: mostrar decena = 3
2: mostrar unidad = 4

tabla de 4 BIT
0000 = 0
0001 = 1
0010 = 2
0011 = 3
0100 = 4

FORMAREMOS EL NUMERO 3

PORTC = 0B00000011 = 3 ; tenemos n°3 , los bit de color rojo indican el numero que formaremos
PORTC = 0B00010000 = 3 ; tenemos + 16 , los bits de color rojo sirven para activar los display
PORTC = 0B00010011= AHI JUNTAMOS TODO
CON EL +16 = Decimos que con RC4 ACTIVAREMOS EL DISPLAY

SALUDOS



D@rkbytes

en el programa ocupas los primeros 4 bit del puerto para formar el numero , como se podría hacer para ocupar los últimos 4 bits del puerto

RB0-RB1-RB2-RB3 REEMPLAZARLOS POR RB4-RB5-RB6-RB7, COMO SE PUEDE HACER

SALUDOS
 
Última edición:
Es sencillo.
Los primeros 4 bits es el número a mostrar y la máscara será el byte del bit de activación.

Por ejemplo: número = 5 y el bit del primer display = RA7
5 en binario = 101
Bit 7 en 1 (RA7) en binario = 10000000
5 + 128 en binario = 10000101

Ahí tienes que el bit 7 estará en 1 y el número 5 en los primeros 4 bits (LSB) :cool:
 
Última edición:
Buenas noches, estoy trabajando con arreglos y quiero definir la longitud del arreglo como una variable global de la siguiente manera:

CSS:
int n=7;

void main (){
while(TRUE)
   {
    int arreglo [n] ;
   }
}

El error dice: Expression must evaluate to a constant . Cómo puedo hacer que el arreglo acepte mi variable global?
 
En C no está permitido declarar una variable en mitad de una función, solo se puede hacer al principio:

Código:
//... librerías necesarias
int n=7;

void main (){
int arreglo [n];
while(TRUE)
   {
    //... Se hace algo...
   }
}

No es muy útil utilizar una variable para definir el tamaño de un array si este será de un tamaño fijo (lo que normalmente sucede en un entorno embebido). Te recomiendo usar un define:

Código:
//... librerías necesarias
#define TAMANIO_ARRAY (unsigned int)(7)

void main (){
int arreglo [TAMANIO_ARRAY];
while(TRUE)
   {
    //... Se hace algo...
   }
}
 
No es muy útil utilizar una variable para definir el tamaño de un array si este será de un tamaño fijo
Eso solo se puede hacer si el compilador soporta los VLA del ANSI C99 que no es el caso de los sistemas embebidos y de casi ningún compilador mas o menos estándard. EL GCC lo soporta de forma sui-generis y los compiladores que lo admiten generalmente arman un despelote con el stack.
 
Atrás
Arriba