Define pin con variable array en C de CCS

Hasta ahora ni siquiera e utilizado esto:

#bit activa1=porta.1

Siempre utilice output_high(PIN_A1); y output_low(PIN_A1);//No recomendable cuando //tienes un programa muy largo y necesitas cambiar el pin de salida A0 por otro (ponte a //buscar todas)

Y ahora me conviene mucho lo siguiente:

//#bit azti[0]=porta.1
//#bit azti[1]=porta.2
//#bit azti[2]=porta.3
//Compilacion erronea
//*** Error 86 "Ascen_3X8.c" Line 93(11,12): Expecting =
//*** Error 43 "Ascen_3X8.c" Line 93(13,14): Expecting a declaration



Pretendo que portA1 sea el valor de int1 azti[1] portA2=azti[2] ... sucesivo
¿Se puede hacer esto de alguna otra manera?



Luego me pasa que aunque me compile #bit activa1=porta.1
Me falta algo el valor de activa1 no esta afeztando al portA1
 
Última edición:
Asignar un byte de un arreglo a un registro SFR, no creo que pueda ser posible.
Pero asignar un nombre para un bit de un registro si es posible y debe ser de ésta forma:

#byte PORTA = getenv ("SFR:pORTA")

#bit ra1 = PORTA.1

Y para que funcione, debes establecer tus entradas y salidas con: set_tris_a (valor);
 
No creo que sea el set_tris E seguido la siguiente redundancia

#byte PORTA = getenv ("SFR:pORTA")
#BYTE PORTA=0x04
#BYTE TRISA=0X00
......
//delaracines datos fuciones
....
#byte PORTA = getenv ("SFR:pORTA")
#bit sal=PORTA.0
//int1 sal;

void main(){
....
set_tris_A(0b00000000);
.....
While(1){
......
sal=!sal;//no le afecta a A0
//if(sal){ output_high(PIN_A0); }//esto si responde declarando bajo int1 sal (sin redundancia)
// else{ output_low(PIN_A0); }
....
} }
 
mira un ejemplo que ami me funciona
cuando yo quiero renombrar un pin para no usar output_high o low

Código:
#if defined(__PCH__) // PIC18F
   
   #bit CLOCK     =GETENV("SFR:LATD").5
   #bit DATA      =GETENV("SFR:LATD").6
   #bit LATCH     =GETENV("SFR:LATD").7

#else            // PIC16F
   
   #bit CLOCK     =GETENV("SFR:PORTD").5
   #bit DATA      =GETENV("SFR:PORTD").6
   #bit LATCH     =GETENV("SFR:PORTD").7
  
#endif


#bit TRIS_CLOCK      =GETENV("SFR:TRISD").5
#bit TRIS_DATA       =GETENV("SFR:TRISD").6
#bit TRIS_LATCH      =GETENV("SFR:TRISD").7

es un ejemplo para casos en pic16 y pic18

ahora declarando las salidas:

TRIS_CLOCK=0; //CLOCK ES SALIDA
TRIS_DATA=0; //DATA ES SALIDA
TRIS_LATCH=0; //LATCH ES SALIDA


y un ejemplo de codigo:

if(dat==0)
{
DATA=0;
}
else
{
DATA=1;
}

CLOCK=0;
CLOCK=1;
 
Otra opción similar a la que ya te mensionaron es la siguiente:
Código:
// Se define etiquetas de pines //

#use fast_io(A) // Asignación rápida de los pines del puerto A

#locate Puerto_A = 0x05 // Defino el puerto A con una etiqueta
// Registro de PORTA ==> BITS: 7 6 5 4 3 2 1 0
//                             | | | | | | | |_ Giro_Motor : Pin usado para determinar el sentido de giro del motor
//                             | | | | | | |___ Salida_Motor : Pin utilizado para comandar el motor
//                             | | | | | |_____ Botonera : Pin utilizador por la botonera externa
//                             | | | | |_______ E_Fotocelula : Pin para detectar obtáculos
//                             | | | |_________ F_Carrera_C : Pin para determinar cuando está el portón cerrado
//                             | | |___________ F_Carrera_A : Pin para determinar cuando está el portón abierto
//                             | |_____________ HS : Pin usado para el cristal
//                             |_______________ HS : Pin usado para el cristal


#bit Giro_Motor    = Puerto_A.0 // A0 como salida para el manejo del sentido de giro del motor
#bit Salida_Motor  = Puerto_A.1 // A1 como salida para el manejo del motor
#bit Botonera      = Puerto_A.2 // A2 como entrada de la botonera externa para abrir o cerrar el portón.
#bit E_Fotocelula  = Puerto_A.3 // A3 como entrada de la fotocelula para deteccion de obtáculos
#bit F_Carrera_C   = Puerto_A.4 // A4 como entrada del final de carrera cerrado
#bit F_Carrera_A   = Puerto_A.5 // A5 como entrada del final de carrera abierto

void Inicializacion_dispositivo(void)  // Rutina de inicialicación del dispositivo
{
   output_a (0);                                // Borro las salidas del puerto A
   output_b (0b00100000);                       // Borro las salidas del puerto B
   set_tris_a (0b00111100);                     // Pines como entrada: A2,A3,A4,A5 - Pines como salida: A0,A1,A6,A7
   set_tris_b (0b01001001);                     // Pines como entrada: B0,B3,B6 - Pines como salida: B1,B2,B4,B5,B7
   setup_timer_2(T2_DIV_BY_16,250,10);          // Interrupción cada 10 mseg
   setup_timer_1 (T1_INTERNAL | T1_DIV_BY_4);   // Seteo el timer 1 para funcionar a 1 useg
   setup_timer_0 (T0_DIV_256);                  // Seteo el timer 0 para interrupciones cada 16,384 mseg
   enable_interrupts (GLOBAL);                  // Habilito las interrupciones globales
   Bandera_Reset = false;                       // Hago falsa la variable Bandera_Reset
}
 
Hola despues de probar todo el ejemplo de Trylo es lo que unico que e conseguido hacer funcionar Gracias

En mi caso esta prueba a valido para A1-A3 En un <18f64j90.h>

#bit sal =GETENV("SFR:LATA").1
#bit sal2 =GETENV("SFR:LATA").2
#bit sal3 =GETENV("SFR:LATA").3

#bit TRIS_sal =GETENV("SFR:TRISA").1
#bit TRIS_sal2 =GETENV("SFR:TRISA").2
#bit TRIS_sal3 =GETENV("SFR:TRISA").3

Me gusta Trylo responde bien
 
es que tube el mismo problema.

digamos que tenia un programa perfectamente funcional escrito en C18 y queria reciclar el programa pero en CCS para cargarlo en un pic16

y me di cuenta de algo terrible las directivas output_low, high y toggle no eran compatibles con mi codigo.

afortunadamente destripe unas librerias de LCD y otras para poder conseguir mi codigo y hacerlo compatible con el ya escrito.

y sobre las directivas

#if defined(__PCH__) // PIC18F

// codigo

#else // PIC16F


es para que el preprocesador sepa para que micro estamos compilando y llame partes del compilador que se requiera.

no es el mismo compilador para pic10, pic12, pic16 y pic18 son diferentes compiladores usando el mismo IDE
¿se puede preguntar un compilador diferente al CCS?
SI
por ejemplo puedes preguntar hasta por un compilador por ejemplo xc8 o c18



#if defined(__XC8)
 
Última edición:
Hola en mi caso CCS bajo PCHW 5.0? Compilo y funciono tanto con el #IF como sin el, luego solo vi que no lo necesitava, pero te aseguro que se puede guardar esta chuleta tuya como solucion. Puede que tambien funcionen los otros 2 metodos. Recuerdo que tuve que quitar //Funciones mias, porque interferian y falseavan el resultado, cosa que no hize antes pero ya ahora estoy con otro tema, del mismo programa.

3 Saludos
 
pero yo puse los #if no como adorno de navidad.

la idea es bueno no se que pic usas yo en este caso lo escribi para un pic18fXXX y cuando compilo el preprocesador se encarga de compilar solo la parte del pic18

pero si el mismo codigo fuente lo quiero para un pic16f el preprocesador solo compilara la parte pic16 y no la de pic18

¿funciona si dejo ambos?

NO por que si no le digo al preprocesador que compilar marcara error dependiendo que pic trabaje
 
alguien me puede ayudar con este codigo es para una tarea:

y quiero simplificarlo, lo que quiero es que quede libre el pin RB0 para conteo de pulsos y utilizar los demas pines del mismo puerto para 2 displays 7 segmentos. el codigo que tengo actualmente funciona pero quiero simplificarlo, el arreglo que tengo declarado no lo uso porque no funciona por esa razon debo activar cada led del display manualmente pero el codigo me quedo muy gordo.

de antemano muchas gracias.


Código:
#include <16F628a.h>//PIC a utilizar
#USE DELAY( CLOCK=20Mhz ) //Oscilador
#FUSES HS,NOWDT,NOPROTECT,NOPUT//Ordenes para el programador
#USE STANDARD_IO(B)
#include <math.h>

INT ud=0;
INT dec=0;
int x =0;
int k =0;
int tiempo = 10;
//INT DISPLAY[10]={0b1000000,0b1111001,0b0100100,0b0110000,0b0011001,0b0010010,0b0000011,0b1111000,0b0000000,0b0011000};

void displaybits()
{
if (x==0)
{
output_bit(PIN_B1,0);// mostrar numero 0
output_bit(PIN_B2,0);
output_bit(PIN_B3,0);
output_bit(PIN_B4,0);
output_bit(PIN_B5,0);
output_bit(PIN_B6,0);
output_bit(PIN_B7,1);
}
if  (x==1)
{
output_bit(PIN_B1,1);// mostrar numero 1
output_bit(PIN_B2,0);
output_bit(PIN_B3,0);
output_bit(PIN_B4,1);
output_bit(PIN_B5,1);
output_bit(PIN_B6,1);
output_bit(PIN_B7,1);
}
if  (x==2)
{
output_bit(PIN_B1,0);// mostrar numero 2
output_bit(PIN_B2,0);
output_bit(PIN_B3,1);
output_bit(PIN_B4,0);
output_bit(PIN_B5,0);
output_bit(PIN_B6,1);
output_bit(PIN_B7,0);
}
if  (x==3)
{
output_bit(PIN_B1,0);// mostrar numero 3
output_bit(PIN_B2,0);
output_bit(PIN_B3,0);
output_bit(PIN_B4,0);
output_bit(PIN_B5,1);
output_bit(PIN_B6,1);
output_bit(PIN_B7,0);
}
if  (x==4)
{
output_bit(PIN_B1,1);// mostrar numero 4
output_bit(PIN_B2,0);
output_bit(PIN_B3,0);
output_bit(PIN_B4,1);
output_bit(PIN_B5,1);
output_bit(PIN_B6,0);
output_bit(PIN_B7,0);
}
if  (x==5)
{
output_bit(PIN_B1,0);// mostrar numero 5
output_bit(PIN_B2,1);
output_bit(PIN_B3,0);
output_bit(PIN_B4,0);
output_bit(PIN_B5,1);
output_bit(PIN_B6,0);
output_bit(PIN_B7,0);
}
if (x==6)
{
output_bit(PIN_B1,0);// mostrar numero 6
output_bit(PIN_B2,1);
output_bit(PIN_B3,0);
output_bit(PIN_B4,0);
output_bit(PIN_B5,0);
output_bit(PIN_B6,0);
output_bit(PIN_B7,0);
}
if (x==7)
{
output_bit(PIN_B1,0);// mostrar numero 7
output_bit(PIN_B2,0);
output_bit(PIN_B3,0);
output_bit(PIN_B4,1);
output_bit(PIN_B5,1);
output_bit(PIN_B6,1);
output_bit(PIN_B7,1);
}
if (x==8)
{
output_bit(PIN_B1,0);// mostrar numero 8
output_bit(PIN_B2,0);
output_bit(PIN_B3,0);
output_bit(PIN_B4,0);
output_bit(PIN_B5,0);
output_bit(PIN_B6,0);
output_bit(PIN_B7,0);
}
if  (x==9)
{
output_bit(PIN_B1,0);// mostrar numero 9
output_bit(PIN_B2,0);
output_bit(PIN_B3,0);
output_bit(PIN_B4,0);
output_bit(PIN_B5,1);
output_bit(PIN_B6,0);
output_bit(PIN_B7,0);
}
}
 
 
void DISPLAY_7SEG(void)  //separo decenas y unidades
{
dec = k/10; // 
ud  = k -(dec * 10);
output_a(0b01);//activo decenas
x = dec;
displaybits();
//***************
delay_ms(tiempo);
//***************
output_a(0b10); //activo unidades
x = ud;
displaybits();
delay_ms(tiempo); 
}


void main()
{
 
output_a(0b00000011);//encender display 1 y 2
output_b(0b0000000);//enciende todos los segmentos GFEDCBA
delay_ms(1000);
output_a(0b00000000);//apago display 1 y 2
while (true)
  {
  delay_ms(500);
  k = k+1;
  if  (k == 100) 
   {
      k=0;
  }
  DISPLAY_7SEG();
  }
}
 
Última edición por un moderador:
Hola, para comenzar a simplificar, en lugar de encender cada puerto individualmente cómo dices. Más bien utiliza ésto:

int bcd=0b00000110; // Represento el valor "1" BCD
output_b(bcd);
Pues eso ya lo tiene implementado en su codigo, solo que no hace uso de ello, fíjate que al comienzo declara una variable display[10] al cual le asigna los valores del 0 al 9 en binario, pero luego nunca hace uso de ello y trabaja bit a bit, haciendo muy poco eficiente el código. Por otro lado veo que luego de mostrar un número espera un tiempo que lo realiza con delay, lo cual si la idea es hacer un timer pues esa no es la forma correcta, se debe usar el timer interno del micro y trabajar por interrupciones, y para ser mas estricto, se debería usar RTOS, pero eso ya es otro tema. Si no es para timer entonces puede funcionar.

 
yo lo que haria seria hacer un array para mostrar en el display algo parecido

unsigned char BCD[10]={0x01,0xAA,etc};

ya que tengo mis 10 digitos ahora hacer algo asi;


i=8; //el display mostrara el numero 8 si cambias el numero se mostrara en el display

output_b(BCD[ i ]); //el puerto B mostrara el codigo BCD y la i mostrara el numero a mostrar



aca hago un ejemplo de como podria verse:

primero que nada nececitamos llenar un array.

unsigned char BDC[10]={0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x67};

una vez lleno el array vamos a mostrar en el puerto en este caso el B.

output_b( BCD [ i ]);

como digimos anterior mente i sera el numero a mostrar en el puerto B y BCD[ ] sera el que dibuja en el puerto B el display.

ahora lo que vamos a hacer es mostrar del 0 al 9 por puerto B.

unsigned char i;

for(i=0 ; i<=10 ; i++ )
{

output_b(BCD);

delay_ms(1000);

}


NOTA:
yo puse delay para motivos didacticos lo mejor es no usar delay en los porgramas solo lo puse para mostrar el uso de puerto B y su respectivo algoritmo
 
Última edición:
gracias por sus respuestas, pero. lo del array ya lo usé pero me toma el puertob completo y yo quiero utilizar el puertob a partir del RB1 al RB7
INT DISPLAY[10]={0b1000000,0b1111001,0b0100100,0b0110000,0b0011001,0b0010010,0b0000011,0b1111000,0b0000000,0b0011000};

como alguien lo mencionó lo declaro pero no lo uso y la razón es que al mandar 7 bits. pues por default se toma desde RB0 - RB6.

si ya se ya se tambien probe mandar 8 bits igual ocuparía los 8 pines del puertob.

Pense era fácil, veo que no.
pero gracias a todos. si alguien me da alguna idea se lo agradecere eternamente.



juamma2468 tienes razón el código no es eficiente, si tambié sé que el delay de 500ms me estropea la sincronización entre los display, se queda parado un 1/2segundo uno de ellos y si puedo utilizar el timer0, pero mi problema es dejar el pin RB0 libre para interrupciones porque utilizaré el puerto RB1-RB7 para el display.

si alguien tiene alguna sugerencia se lo agradezco. y muchas gracias.
 
Última edición:
ahh mira eso es diferente.

tambien puedes hacer lo siguiente:

digamos que tienes 8 bits y quieres 4 displays de 8 segmentos y un pin del puerto B que es RB0

¿que hacemos en este caso?

facil del bit 4 al 7 los uso para mi display de 7 segmentos conectado a un decodificador BCD 74ls47 y los otros 3 bits para multiplexar mi display de 7 segmentos

compras un display de 4 digitos de 7 segmentos conectas el selector a cada bit

ahora debes hacer un barrido para cada display puede ser del mismo puerto B o de otro puerto cualquiera.
 
tal vez lo que te estan pidiendo, es que aprendas a emplear las máscaras de bits, y las funciones que operan sobre bits como pueden ser OR AND XOR y desplazamiento de bits.

Si te olvidas de las funciones que usa el CCS, para los bits y lo haces Vos, habilitando ese manejo con #use fast_io(x) y luego accediendo a los puertos con
#byte MiVariable = getenv("SFR:pORTX")
podrás manejarlos con las operaciones que mencione, sin afectar tal o cual bit requerido.

En ocho líneas se escribe la funcion que hace el "barrido" y desentrama los segmentos a mostrar el esos display led 7 seg. si estan en el mismo puerto, creo que no has buscado lo suficiente por la web...
 
alguien me puede ayudar con este codigo es para una tarea:

y quiero simplificarlo, lo que quiero es que quede libre el pin RB0 para conteo de pulsos y utilizar los demas pines del mismo puerto para 2 displays 7 segmentos. el codigo que tengo actualmente funciona pero quiero simplificarlo, el arreglo que tengo declarado no lo uso porque no funciona por esa razon debo activar cada led del display manualmente pero el codigo me quedo muy gordo.

de antemano muchas gracias.
Si lo que quieres hacer es un contador de pulsos con display 7seg, también puedes usar la el timer0 como contador externo en modo interrupción por el pin Tocki/RA4 y utlizar todo el puerto b para tus display.
 
pero hay muchas formas de usar muchos displays de 7 segmentos sin abarcar todo el puerto B.

se podria usar hasta solo 3 pines del puerto B si uno esta dispuesto, no hay que decir oooooh se acabo el mundo debo conectar 1 display y ya se me acabo el puerto B por que use todos los segmentos.

no es asi se pueden usar 4 displays de 7 segmentos usando solo 3 pines y se acabo.
 
GRACIAS POR SUS RESPUESTAS
trilo-byte quiero ahorrarme un chorro de resistencias, por eso no utilizo el decodificador BCD, yo uso el 4511, Pero debo usar muchas resistencias. es fácil solucionarlo utilizando un codificador BCD, pero no quiero usarlos, quiero usar 7 bits del puerto b multiplexar 2 display 7 segmentos. y dejar libre el RB0 para interrupciones.

tambien sé como utilizar las interrupciones por timer0, los de los 3 pines del puerto b, seria de mandar los datos en serie a un 74ls164 para mostrarlo en paralelo.

por el amor de Dios solo quiero el Rb0 libre para interrupciones, y ocupar los demás para mostrar datos, mandar 7 bits sin afectar el RB0.

muchas gracias siguiré intentando igual si lo logro lo posteo. yajuuuuuuuuuu, nos vemos luego.
 
Quiero ahorrarme un chorro de resistencias, por eso no utilizo el decodificador BCD, yo uso el 4511, pero debo usar muchas resistencias.
Es fácil solucionarlo utilizando un codificador BCD, pero no quiero usarlos, quiero usar 7 bits del puerto B y multiplexar 2 display 7 segmentos y dejar libre el RB0 para interrupciones.
Uses lo que uses, siempre deberás colocar una resistencia por cada segmento del display.
Si lo haces multiplexando los displays, sí ahorrarás resistencias y eso también se puede hacer con decodificadores.

También sé cómo utilizar las interrupciones por Timer 0, los de los 3 pines del puerto B, sería de mandar los datos en serie a un 74ls164 para mostrarlo en paralelo.
En ese caso tendrás que usar un 74LS164 por cada display y cada uno con 7 resistencias.
Entonces ya no existirá ahorro en resistencias, únicamente en pines del microcontrolador.

Por el amor de Dios, sólo quiero el RB0 libre para interrupciones, y ocupar los demás para mostrar datos, mandar 7 bits sin afectar el RB0.
La única persona que se percató de ello fue AleSergi y ya te explicó en el post #16 cómo lograrlo usando una máscara de bits. :cool:
 
Atrás
Arriba