# Programas hechos en MPLAB



## george.manson.69 (May 26, 2009)

Este es un simple parpadeo de un led...

Nota: Los programas fueron hechos por mi no es un copy/paste de otros sitios)


```
/////////////////////////////////////////////////////////////////////////////

#include<16f628a.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)
#byte TRISB=0x86
#byte PORTB=0x06


void main(void){
	TRISB=0x00;
	PORTB=0x00;
	do{
		output_high(PIN_B0);
		delay_ms(1000);
		output_low(PIN_B0);
		delay_ms(1000);
	}while(TRUE);	

}
```

puse abajo un practica hecha en proteus 7.4 apra que puedas bajarlo y compilador en mplab.


----------



## Vegetal Digital (May 26, 2009)

> #fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT


que hace el INTRC_IO?

segui posteando!


----------



## george.manson.69 (May 26, 2009)

este es un simple contador de 0 a 9;
donde solo se utiliza un display de catodo comun en el puerto b del pic


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;CONTADOR 0 A 9
//DATE:23/ABRIL/2009
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16f628a.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)


//INICIO DEL PROGRAMA///////////////
void main(void){

//VARIBALES///////////////////////////
	int mostrar[]={0b11000000,0b11111001,0b10100100,0b10110000,
				   0b10011001,0b10010010,0b10000011,0b11111000,
				   0b10000000,0b00011000};
	int contador;
//CONFIGURACION E/S///////////////

	set_tris_b(0x00);
	do{
		for(contador=0;contador<=9;++contador){
			output_b(mostrar[contador]);
			delay_ms(1000);
		}
	}while(TRUE);
}
```


----------



## george.manson.69 (May 26, 2009)

#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT 


que hace el INTRC_IO?

segui posteando! 

___________________________________________________________________________________

vegetal digital

INTRC_IO es una instruccion que te permite usar el oscilador interno del pic16f628a
y se usan como entrada o salida los pines donde debe de ir el oscilador externo...


----------



## george.manson.69 (May 26, 2009)

este programa hace un scroll de un led ...en el puerto b del pic...de un solo lado va estar corriendo el led...mientras no sea pulsado el push botton que esta en el pin0 del pic..del puerto a. y si es pulsado 
el led el scroll se dirijira al lado contrario al que estaba


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;FUNCIONES DEL CCS C COMPLIER
//DATE:27/ABRIL/2009
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16f628a.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)

retorna(int c);

void main(void){
		int a;
		set_tris_b(0x00);
		set_tris_a(0x21);
		a=1;

		do{
			output_b(a);
			if(a==128)
				a=1;
			else
				a=a<<1;
			delay_ms(100);
			if(input(PIN_A0))
				a=retorna(a);
			
		}while(TRUE);
}

retorna(int c){

		do{
			if(c==1)
				c=128;
			else 
				c=c>>1;
			output_b(c);
			delay_ms(100);
		}while(input(PIN_A0));
		return(c);
}
```


----------



## george.manson.69 (May 26, 2009)

este programa es un simple deodificador de  0 a 7, donde se usa tres pulsadores en el puerto a...se le introduce un numero binario de 000 a 111 para que en el display de anodo comun aparesca el 0 a 7,...


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;DECODIFICADOR
//DATE:23/ABRIL/2009
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16f628a.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)


//INICIO DEL PROGRAMA////////////////////
void main(void){
	
		int mostrar[]={0b11000000,0b11111001,0b10100100,0b10110000,
				       0b10011001,0b10010010,0b10000011,0b11111000};
		int numero;
		set_tris_b(0x00);
		set_tris_a(0xff);
		setup_comparator(NC_NC_NC_NC);
		
		do{
			numero=input_a();
			output_b(mostrar[numero]);
		}while(TRUE);
		
}
```


----------



## george.manson.69 (May 27, 2009)

Simple programa que controla un lcd....


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;CONTADOR 0 A 9
//DATE:23/ABRIL/2009
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16f628a.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)
#define use_portb_lcd TRUE
#include<LCD.C>

int x[]={"hola"};
int y[]={"JORGE"};
int i;

void main(){
	lcd_init();

	for(i=0;i<=3;i++){
		lcd_putc(x[i]);
		delay_ms(1000);
	}
	lcd_putc("\n");
	lcd_putc("# es; ");
	for(i=0;i<=4;i++){
		lcd_putc(y[i]);
		delay_ms(1000);
	}
	lcd_putc("\f otra vez?");

}
```


----------



## george.manson.69 (May 27, 2009)

Este prgrama hace una comunicacion serial con la compu y el pic...

si quieres verlo que funcione entra a youtube...y busquen "godness006"
ahi etsan algunos proyectos que he hecho


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;TERMINAL VIRTUAL
//DATE:24/ABRIL/2009
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16F628A.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=2400,xmit=PIN_B6,rcv=PIN_B7)

void main(void){
		int VALOR;
		set_tris_b(0x80);
		
		do{
			for(VALOR=0;VALOR<=10;VALOR++){
				printf("EL VALOR ES: %u\r",VALOR);
				delay_ms(1000);
			}
		}while(TRUE);

}
```


----------



## george.manson.69 (Jun 8, 2009)

Este programa lo que hace...por medio de la computadora vas a ingresar a un numero del teclado de la compu, al display.


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;DECODIFICADOR_RS232
//DATE:03/MAYO/2009
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16F628A.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=2400,xmit=PIN_B6,rcv=PIN_B7)

void config(void){
		set_tris_a(0x20);
		set_tris_b(0x80);
		setup_comparator(NC_NC_NC_NC);
}

void main(void){
		int mostrar[]={0b10000000,0b11011001,0b01000100,0b01010000,0b00011001,
					   0b00010010,0b00000011,0b11011000,0b00000000,0b00011000};
		int x;	
		config();
		
		output_a(0b10000000);
		do{
			x=getc();
			switch(x){
					case 48: output_a(mostrar[0]); break;
					case 49: output_a(mostrar[1]); break;
					case 50: output_a(mostrar[2]); break;
					case 51: output_a(mostrar[3]); break;
					case 52: output_a(mostrar[4]); break;
					case 53: output_a(mostrar[5]); break;
					case 54: output_a(mostrar[6]); break;
					case 55: output_a(mostrar[7]); break;
					case 56: output_a(mostrar[8]); break;
					case 57: output_a(mostrar[9]); break;
 			}
		}while(TRUE);
}
```


----------



## george.manson.69 (Jun 15, 2009)

```
//------------------------------------
//TITULO: SENSOR DE TEMPERATURA Y ENVIADO A LA PC
//AUTOR: JORGE ARTURO RODRIGUEZ HERNANDEZ
//FECHA: 12\JUNIO\'09
//------------------------------------

#include <12f675.h>
#fuses XT,NOWDT,NOCPD,NOPROTECT,MCLR,NOPUT
#use delay(clock=4000000)
#use rs232(baud=2400,xmit=PIN_A2,rcv=PIN_A1)

void config(void){
		set_tris_a(0x3b);
		setup_comparator(NC_NC_NC_NC);
		setup_adc(ADC_CLOCK_INTERNAL);
		setup_adc_ports(sAN0);
}

void main(void){
		int x,y;
		config();
		
		do{
			x=read_adc();
			delay_ms(500);
			y=2*x;
			printf("LA TEMP= %u",y);
			printf("°C\r\n");
		}while(TRUE);
}
```


----------



## george.manson.69 (Jun 18, 2009)

\\ simple circuito con un pic16f887, que se trata de un teclado analogo, escribimos la contrasena o la podemos cambiar.


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;CONTRASENA
//DATE:18/JUNIO/'09
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16f887.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT,NOPUT
#use delay(clock=8000000)
#include<LCD.C>

int LEER_TECLADO;
int TECLADO[]={"0123456789#*"};
int UNO,DOS,TRES,CUATRO;
int UNO_P,DOS_P,TRES_P,CUATRO_P;
int GOA,i;

void config(void){	
		write_eeprom(0x04,1);
		write_eeprom(0x05,2);
		write_eeprom(0x06,3);
		write_eeprom(0x07,4);
		set_tris_a(0x01);
		set_tris_c(0x00);	
		setup_comparator(NC_NC_NC_NC);
		setup_adc(ADC_CLOCK_INTERNAL);
		setup_adc_ports(sAN0);
		output_low(PIN_C0);
		lcd_putc("\fCOMPILED ON\n");
		lcd_putc(__DATE__);
		delay_ms(2000);
}

ADC(int VALOR_ADC){
NO_PULSADO:
			delay_ms(10);
			VALOR_ADC=read_adc();
			if(VALOR_ADC>140){
				goto NO_PULSADO;
			}
			else if(VALOR_ADC<24){
				VALOR_ADC=1;
			}
			else if(VALOR_ADC<43){
				VALOR_ADC=2;
			}
			else if(VALOR_ADC<60){
				VALOR_ADC=3;
			}
			else if(VALOR_ADC<74){
				VALOR_ADC=4;
			}
			else if(VALOR_ADC<88){
				VALOR_ADC=5;
			}
			else if(VALOR_ADC<98){
				VALOR_ADC=6;
			}
			else if(VALOR_ADC<108){
				VALOR_ADC=7;
			}
			else if(VALOR_ADC<114){
				VALOR_ADC=8;
			}
			else if(VALOR_ADC<122){
				VALOR_ADC=9;
			}
			else if(VALOR_ADC<128){
				VALOR_ADC=0;
			}
			else if(VALOR_ADC<137){
				VALOR_ADC=10;
			}
			else if(VALOR_ADC<140){
				VALOR_ADC=11;
			}	

		return(VALOR_ADC);
}

void ESCRIBIR_PASSWORD(void){
			
		for(i=0;i<=3;i++){
			delay_ms(500);			
			LEER_TECLADO=ADC(LEER_TECLADO);
			write_eeprom(i,LEER_TECLADO);
			lcd_putc(TECLADO[LEER_TECLADO]);
		}
			delay_ms(500);
}

void CAMBIAR(void){
			lcd_putc("\fESCRIBE AHORA\n");
			ESCRIBIR_PASSWORD();

			UNO=read_eeprom(0x00);
			DOS=read_eeprom(0x01);
			TRES=read_eeprom(0x02);
			CUATRO=read_eeprom(0x03);
			
			write_eeprom(0x04,UNO);
			write_eeprom(0x05,DOS);
			write_eeprom(0x06,TRES);
			write_eeprom(0x07,CUATRO);
			lcd_putc("\fCAMBIADO");
			delay_ms(1000);
}

void CHEKAR(void){
			UNO=read_eeprom(0x00);
			DOS=read_eeprom(0x01);
			TRES=read_eeprom(0x02);
			CUATRO=read_eeprom(0x03);

			UNO_P=read_eeprom(0x04);
			DOS_P=read_eeprom(0x05);
			TRES_P=read_eeprom(0x06);
			CUATRO_P=read_eeprom(0x07);
}

void main(void){
		lcd_init();
		config();
AGAIN:
	do{
		lcd_putc("\fCHANGE->(*)\n");
		lcd_putc("ENTER-->(#)");
		
		GOA=ADC(GOA);
		switch (GOA){
			case 10:
					lcd_putc("\fPASSWORD:\n");
					ESCRIBIR_PASSWORD(); 
					goto CHEK;	
			case 11: 
					lcd_putc("\fESCRIBE EL\n");
					lcd_putc("PASSWORD 1ERO");
					delay_ms(800);
					lcd_putc("\fTYPE NOW\n");
					ESCRIBIR_PASSWORD();
					CHEKAR();
					if(UNO==UNO_P && DOS==DOS_P && TRES==TRES_P && CUATRO==CUATRO_P){
						lcd_putc("\fCORRECTO");
						delay_ms(1000);
						CAMBIAR();
					} 
					else
						lcd_putc("\fINCORRECTO");
						delay_ms(1000);
					break;
		}
	}while(TRUE);

CHEK:		CHEKAR();

			if(UNO==UNO_P && DOS==DOS_P && TRES==TRES_P && CUATRO==CUATRO_P){
					lcd_putc("\fCORRECTO");
					output_high(PIN_C0);
			}
			else
					lcd_putc("\fINCORRECTO");
			delay_ms(3000);
			output_low(PIN_C0);
			goto  AGAIN;
				
}
```


----------



## george.manson.69 (Jun 19, 2009)

este circuito lo que haces es por medio de la computadora tenemos un programa llamado hercules que hace la comunicacion serial con el pic, bueno por medio de este programa introducimos un password en este caso es "hola", si es asi prendera un led indicando que se activo algo, y si ponemos otra palabra que no sea "hola" prendera otro led indicando que esta mal el password.


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;PASSWORD
//DATE:25/ABRIL/2009
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16F628A.h>
#include <STRING.H>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=2400,xmit=PIN_B6,rcv=PIN_B7)

void main(void){
		char password[6];
		char numero[]="hola";
		set_tris_b(0x80);
		setup_comparator(NC_NC_NC_NC);

		printf("ESCRIBA EL PASSWORD PORFAVOR: \r");
		while(TRUE){
			printf("PASSWORD: %S\n ",gets(password));
			if (!strcmp(password,numero)){
				printf("BIEN \r");
				output_high(PIN_B0);
				output_low(PIN_B1);
			}
			else{
				printf("MAL \r");
				output_low(PIN_B0);
				output_high(PIN_B1);
			}
		}
}
```

bueno tengo un programa llamado *configure virtual serial port* es bueno para simular puertos seriales y ya podras conectadorlo con proteus con el compim que se encuentra en las librerias.


----------



## foso (Jun 19, 2009)

Hola george manson , una pregunta : ese programa CCS, se puede bajar ? yo tengo el MPlab pero no se como programar en C. ¿ Con el Mplab me alcanza para programar PICs en lenguaje C ?


----------



## george.manson.69 (Jun 19, 2009)

la respuesta es si...yo tengo mplab y pss le agrege el picbasic pro y el ccs c solo necesitas unos plugings para adierirlo a mplab..busca en google "ccs c compiler rapidshare" algo asi era....y bajo...y me dices despues te lo pasaria pero no tengo el instalador...


----------



## foso (Jun 20, 2009)

no se que son esos plugins y te comento que busque en rapidshare y me aparecen varios CCS, no se cual bajar


----------



## george.manson.69 (Jun 20, 2009)

pss deja empezar a buscar, a lo mejor un amigo tenga aun el instalador, se lo habia pasado anteriormente pero como quiera  intenta bajar todos los que encuetres en rapidshare, solo los que digan version 4.xxx, y no los de 3.xxx son mas viejos y no e conviene...deja lo consigo y te lo envio...pero como quiera busca...
los ploguins no se como se escriba...sirven para aderir el ccs c a mplap...debolada se encuentra esos en google....y debolada se instalan .-..espero conseguir el progarma la otra semana y te lo envio...


----------



## foso (Jun 20, 2009)

gracias geroge ya encontre uno en rapidshare, una version 4. algo. Te agradesco igual, ya lo instale y anda joya. Ahora falta solo aprender un poco de programacion.
Saludos


----------



## george.manson.69 (Jun 22, 2009)

estos dos programas uno es el transmisor y el otro el reseptor, lo puse a 1200 baudios porque me funciono correctaente le aumentaba los baudios y no lo captaba muy bien el receptor. el transmisor es TWS434 y el recepyor es el RWS434 los dos trabajn a 434 Mhz.
Cuando el switch que se encuentra en el PIN_A0 sea presionado eviara por el PIN_B4 una 'S' 10 veces con un retardo cada uno de 10 ms.
mientras el receptor esperara hasta que capte la 'S' y prendera un led en el PIN_B1



```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;TX_RF
//DATE:21/JUNIO/'09
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16F628A.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=1200,xmit=PIN_B4)

void main(void){
		int i;
		set_tris_b(0x00);
		setup_comparator(NC_NC_NC_NC);

		do{
			if(input(PIN_A0)){
				for(i=0;i<=10;i++){
					printf("S");
					delay_ms(10);
				}
				delay_ms(500);
			}
		}while(TRUE);
}
```




```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;RX_RF
//DATE:21/JUNIO/'09
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16F628A.h>
#include <STRING.H>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=1200,rcv=PIN_B0)


void main(void){
		char x;
		set_tris_b(0x01);
		setup_comparator(NC_NC_NC_NC);

	do{
		output_low(PIN_B1);
		do{
			x=getch();
		}while(x!='S');
			output_high(PIN_B1);
			delay_ms(2000);
	}while(TRUE);
}
```


----------



## Juvenal (Jun 22, 2009)

Hola, si quisiera usar estos programas con el 18f4550 que tendria que cambiar de estos programas, gracias por el post y su respuesta


----------



## PasivoSPC (Jun 22, 2009)

Hola amigos tengo un problema con el pic16f628a mi caso al utilizar el RB4 como forma de parpadeo no da ningun resultado el los otros RBX si,no utilizo comunicacion, y los simulo en proteus 7.4 y codego CCS c

 bueno les dejo 2 codigos y ningunos me an funcionado.. espero sus ayudas.... 


```
#include<16f628a.h> 
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT 
#use delay(clock=4000000) 
#byte TRISB=0x86 
#byte PORTB=0x06 


void main(void){ 
   TRISB=0x00; 
   PORTB=0x00; 
   do{ 
      output_high(PIN_B4); 
      delay_ms(1000); 
      output_low(PIN_B4); 
      delay_ms(1000); 
   }while(TRUE);    

}
```


```
#include<16f628a.h> 
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT 
#use delay(clock=4000000) 
#byte port_b=6
void main() {
   int contador;
   set_tris_b(0);           //// declaramos el puerto B como salidas
   port_b=0;
   while (true) {           //// bucle infinito
      contador=200;         //// retraso, 200 ciclos de 1000 microsegundos, o sea, 2 milisengundos
      while(--contador!=0)
         delay_us(1000);
      port_b=0xff;          //// activa todos los pins del puerto B
      contador=200;
      while(--contador!=0)  //// retraso, 200 ciclos de 1000 microsegundos, o sea, 2 milisengundos
         delay_us(1000);
      port_b=0x00;};        //// apaga todos los pins del puerto B
   }
```


----------



## george.manson.69 (Jun 22, 2009)

hola..que version de proteus tienes...acabo de simular el programa y a mi si me funciona...
a lo mejor es la version del proteus...yo tengo el proteus 7.4 sp3


----------



## george.manson.69 (Jun 23, 2009)

control de un servo y comunicacion con la pc, este circuito lo que hace es esperar una senal de la cumputadora, para poder girar 45 grados, 90 grados, 135 grados o 180 grados, al girar a cualquier grados elegidoesperara un cierto tiempo en esa posiscion al termino de 3 segundos! regresara a su posicion original osea a 0 grados.


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;SERVO SIMPLE
//DATE:23/ABRIL/2009
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16f628a.h>
#include <STRING.H>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=20000000)
#use rs232(baud=2400,xmit=PIN_A1,rcv=PIN_A0)

void config(void);

void main(void){
		long i,a;
		char POSICION;
		config();
INICIO:
		output_b(0x00);
		printf("POSICIONANDO EL MOTOR\r\n");
		for(i=a;i>=500;i=i-10){
			output_high(PIN_B0);
			delay_us(i);
			output_low(PIN_B0);
			delay_ms(10);
		}
		printf("\f");
		printf("POSICION --> 0 GRADOS\r\n");

		printf("ESCRIBA LA POSICION QUE QUIERE:\r\n");
		printf("45 GRADOS -->(Q)\r\n");
		printf("90 GRADOS -->(W)\r\n");
		printf("135 GRADOS -->(E)\r\n");
		printf("180 GRADOS -->(R)\r\n");

		do{
			POSICION=getch();
		}while(POSICION!='Q' && POSICION!='W' && POSICION!='E' && POSICION!='R');
		
		if (POSICION=='Q'){
			a=1000;
		}
		else if (POSICION=='W'){
			a=1500;
		}
		else if (POSICION=='E'){
			a=2000;
		}
		else if (POSICION=='R'){
			a=2500;
		}

		output_high(PIN_B0);
		delay_us(a);
		output_low(PIN_B0);
		delay_ms(5000);
		goto INICIO;

}

void config(void){
		set_tris_a(0x21);
		set_tris_b(0x00);
		setup_comparator(NC_NC_NC_NC);
}
```


----------



## PasivoSPC (Jun 23, 2009)

Hola  de nuevo estuve revisando mis codigos mi probrema fue k dentro de los recursos de archivo *h habia 
#FUSES LVP                      //Low Voltage Programming on B3(PIC16) or B5(PIC18)
fue la confucion y no por el programa y bueno otra duda fue para k sirve..? este codigo FUSES LVP en k forma me sirve .....


----------



## george.manson.69 (Jun 23, 2009)

lo que yo sepa...por ahi entra la información para programar el pic.....pero pss yo tengo un programador de pic's en usb y pss no necesito usar eso de LVP.


----------



## george.manson.69 (Jun 25, 2009)

este programa es muy simple lo hice en c#, es un control de 8 led's, en pocas palabras manipulas 1 byte(8bit) y lo mandas al pic...


----------



## Vegetal Digital (Jun 29, 2009)

Juvenal dijo:
			
		

> Hola, si quisiera usar estos programas con el 18f4550 que tendria que cambiar de estos programas, gracias por el post y su respuesta



Hola, para usar los programas con ese micro tenes que cambiar el include:
#include<18f4550.h> //importante: yo nunca trabaje con este micro, nose si el ccs tiene las librerias correspondientes

y cambiar los fuses y alguna otra cosa mas que ahora no me acuerdo
saludos


----------



## Vegetal Digital (Jun 29, 2009)

PasivoSPC dijo:
			
		

> Hola  de nuevo estuve revisando mis codigos mi probrema fue k dentro de los recursos de archivo *h habia
> #FUSES LVP                      //Low Voltage Programming on B3(PIC16) or B5(PIC18)
> fue la confucion y no por el programa y bueno otra duda fue para k sirve..? este codigo FUSES LVP en k forma me sirve .....


LVP: Low Voltage Programming
sirve para programar el micro con bajo voltaje

[Me edito]
Para poner el pic en modo de programación en bajo voltaje se usa PGM, normalmente RB3, CREO que se ponen 5 voltios
Por eso no es tan utilizado(si mientras corre el programa este pin se pone en el estado correcto, entrara en modo programación) 

Fuente: "Programming method used by ICD, comparied to Low Voltage Programming, use of RB3"
Saludos


----------



## ingdenis1 (Jun 30, 2009)

tengo una duda no puedo hacer funcionar un teclado matricial 4x3 ya cree un tema sobre esto hize el circuito en proteus y no funciona deberia aparecer en la lcd la tecla presionada, el programa es uno de los ejemplos que trae por default el ccs, gracias por cualquier ayuda.


----------



## george.manson.69 (Jul 1, 2009)

hola ingdenis1 encontre esta liberia de un teclado 4x4 en google...a ver si te sirve!


```
///////////////////////////////////////////////////////////////////////////
////                     KBD_LIB.C by Redraven                         ////
////                                                                   ////
////                     Derived from KBDD.C                           ////
////                  Generic keypad scan driver                       ////
////                                                                   ////
////  kbd_init()   Must be called before any other function.           ////
////                                                                   ////
////  c = kbd_getc(c)  Will return a key value if pressed or /0 if not ////
////                   This function should be called frequently so as ////
////                   not to miss a key press.                        ////
////                                                                   ////
///////////////////////////////////////////////////////////////////////////
////        (C) Copyright 1996,1997 Custom Computer Services            ////
//// This source code may only be used by licensed users of the CCS C   ////
//// compiler.  This source code may only be distributed to other       ////
//// licensed users of the CCS C compiler.  No other use, reproduction  ////
//// or distribution is permitted without written permission.           ////
//// Derivative programs created using this software in object code     ////
//// form are not restricted in any way.                                ////
////////////////////////////////////////////////////////////////////////////

////////////////// The following defines the keypad layout on port D

// Un-comment the following define to use port B
#define use_portb_kbd TRUE

// Make sure the port used has pull-up resistors (or the LCD) on
// the column pins


#if defined(__PCH__)
#if defined use_portb_kbd
   #byte kbd = 0xF81              // This puts the entire structure
#else
   #byte kbd = 0xF83              // This puts the entire structure
#endif
#else
#if defined use_portb_kbd
   #byte kbd = 6                  // on to port B (at address 6)
#else
   #byte kbd = 8                  // on to port D (at address 8)
#endif
#endif

#if defined use_portb_kbd
   #define set_tris_kbd(x) set_tris_b(x)
#else
   #define set_tris_kbd(x) set_tris_d(x)
#endif

//Keypad connection:   (for example column 0 is B0)

#define COL0 (1 << 0) // PIN_B0
#define COL1 (1 << 1) // PIN_B1
#define COL2 (1 << 2) // PIN_B2
#define COL3 (1 << 3) // PIN_B3

#define ROW0 (1 << 4) // PIN_B4
#define ROW1 (1 << 5) // PIN_B5
#define ROW2 (1 << 6) // PIN_B6
#define ROW3 (1 << 7) // PIN_B7


#define ALL_ROWS (ROW0|ROW1|ROW2|ROW3)


#define ALL_PINS (ALL_ROWS|COL0|COL1|COL2|COL3)


// Keypad layout:

char const KEYS[4][4] = {{'1','2','3','A'},
                         {'4','5','6','B'},
                         {'7','8','9','C'},
                         {'*','0','#','D'}};


#define KBD_DEBOUNCE_FACTOR 33    // Set this number to apx n/333 where
                                  // n is the number of times you expect
                                  // to call kbd_getc each second

void kbd_init() {
}

char kbd_getc( ) {
   static byte kbd_call_count;
   static short int kbd_down;
   static char last_key;
   static byte col;

   byte kchar;
   byte row;

   kchar='\0';
   if(++kbd_call_count>KBD_DEBOUNCE_FACTOR) {
       switch (col) {
         case 0   : set_tris_kbd(ALL_PINS&~COL0);
                    kbd=~COL0&ALL_PINS;
                    break;
         case 1   : set_tris_kbd(ALL_PINS&~COL1);
                    kbd=~COL1&ALL_PINS;
                    break;
         case 2   : set_tris_kbd(ALL_PINS&~COL2);
                    kbd=~COL2&ALL_PINS;
                    break;
         case 3   : set_tris_kbd(ALL_PINS&~COL3);
                    kbd=~COL3&ALL_PINS;
                    break;
       }

       if(kbd_down) {
         if((kbd & (ALL_ROWS))==(ALL_ROWS)) {
           kbd_down=false;
           kchar=last_key;
           last_key='\0';
         }
       } else {
          if((kbd & (ALL_ROWS))!=(ALL_ROWS)) {
             if((kbd & ROW0)==0)
               row=0;
             else if((kbd & ROW1)==0)
               row=1;
             else if((kbd & ROW2)==0)
               row=2;
             else if((kbd & ROW3)==0)
               row=3;
             last_key =KEYS[row][col];
             kbd_down = true;
          } else {
             ++col;
             if(col==4)
               col=0;
          }
       }
      kbd_call_count=0;
   }
  set_tris_kbd(ALL_PINS);
  return(kchar);
}
```

y este es un ejemplo donde al aplanar una tecla del teclado 4x4 te lo envia  a la compu!
(yo no lo hice, por ahi me lo encontre jeje)



```
#include <16f876a.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)
#use fast_io(b)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#include "kbd_lib.c"

void main(){
   char mitecla=0;

   kbd_init();
   printf("\rKeyboard 4x4 monitor\r\r";
   do {
      mitecla=kbd_getc();
      if(mitecla!=0){
         putc(mitecla);
      }
   } while (TRUE);
}
```


----------



## ingdenis1 (Jul 1, 2009)

gracias ahora solo me gustaría saber como va conectado el teclado al pic que pin a que pin si lleva resistencias pull up externas  si va a 5v etc.gracias de todos modos.


----------



## george.manson.69 (Jul 2, 2009)

Este programa es hecho en C#y controla un servo, aqui les dejo el programa hecho en mplab para poder resivir los datos del programa y asi mismo controlar el servo.


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;CONTROL DE SERVO
//DATE:26/JUNIO/'09
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16F628A.h>
#include<math.h>
#fuses HS,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=20000000)
#use rs232(baud=2400,xmit=PIN_A0,rcv=PIN_A1)

void config(void){
		set_tris_a(0x22);
		set_tris_b(0x00);
		setup_comparator(NC_NC_NC_NC);
}

void main(void){
		int x;
		float y;
		long z;
		config();
		output_b(0x00);
	do{

		x=getch();
		y=(x*6.666e-6)+0.9e-3;
		z=y*1000000;
		output_high(PIN_B0);
		delay_us(z);
		output_low(PIN_B0);
		delay_us(20000-z);
	}while(TRUE);
}
```


----------



## george.manson.69 (Jul 2, 2009)

en un par de semanas subire la contruccion de un robto controlado por la compu, y controlado via RF...paso a paso para los que les interese puedan hacer uno...COMING SOON


----------



## george.manson.69 (Jul 8, 2009)

bueno como habia dicho antes vamos a empezar con el proyecto prometido, el robot controlado por la lap, y via RF, bueno para empezar ahi les dejo la imagen como deber de ir el proyecto. primero el transmisor.
como vemos usamos un USB/SERIAL para hacer la comunicacion, pero otros pueden usar otro pic, que tenga para manejo de USB. pero bueno yo no he he familiarizado aun con esos, por ahora con el adaptador, sigue el max 232, y luego el pic16f628a, y el transmisor rws434.

el programa aun no lo voy a subir porque hay que explicar por detalle la contruccion del circuito, y luego de los software.


----------



## george.manson.69 (Jul 8, 2009)

Bueno ya vimos el transmisor ahora sigue el receptor, el receptor costa de un rws434 y un pic16f628a,un LCD Y un driver H 1 amp y luego los motores.
lo que trato de hacer es que al resivir una señal de la computadora, el LCD visualice lo que esta haciendo el robot, por ejemplo mando una señal que de una vuelta a la derecha, y el LCD me diga que esta dando vuelta  ala derecha asi sucesivamente.
bueno para ponerlo mucho mejor el circuito, pongamole un password que al resivir la contraseña pueda activarse el robot y a si puedas controlarlo.
por ahora aqui esta el diagrama como va hacer el circuito.
(nota; este robot solo podra resivir señal hasta lso 60 mts y de ahi ya no hara nada)


----------



## Vegetal Digital (Jul 8, 2009)

En el mensaje de mas arriba el transmisor es tws, no rws.
Capaz que este un poco ansioso pero...con que vas a hacer los programas de la compuatora, con visual basic?
linda "pinta" nueva
Saludos


----------



## george.manson.69 (Jul 8, 2009)

si lo voy hacer en visual basic.... ya lo tengo pero le estoy agregando mas cosas como, mas COM porque las laptop empiezan desde COM4 y de ahi para delante..y pss puede pasar que alguien quiera usar una computadora de escritorio y tenga COM1 y 2 y pss tengo que adaptar el programa que use esos puertos...y otras cosas le estoy agregando...pero por ahora voy a explicar la circuiteria...ya tengo todo hecho pinta bien todo el robot y se mueve donde yo lo digo.


----------



## Meta (Jul 8, 2009)

Si ya saben usar el C18 de MPLAB. ¿Por qué no prueban el C32 así prueban el PIC32 sin miedo?

www.mypic32.com


----------



## Palmas (Jul 8, 2009)

Hola george, te felicito por estos programas. Yo también quiero aprender el ccs y voy a comenzar, tengo un buen libro que se llama compilador ccs y proteus. Saludos desde Lima-Perú.
Palmas.


----------



## Meta (Jul 8, 2009)

Aquí hay un manual en PDF muy bueno sobre C18 para escapar.

http://electronica-pic.blogspot.com/2009/07/manual-en-pdf-sobre-la-configuracion-y.html

Saludo.


----------



## george.manson.69 (Jul 9, 2009)

hola...vamos a empezar por partes a explicar cada parte del robot, lo que hemos visto en el transmisor usamos un cable de usb/serial ya que las laptop ya no usan este tipo de comunicacion puro usb, habra unas laptops que tengan este tipo de seriales, pero son antiguas. pero bueno el que yo compre fue en steren es una tienda de electronica, lo conecte primero y luego instale el driver que venia con el paquete, y listo...hay que ver que siempre hay que usar el mismo puerto usb donde fue instaldo porque si lo ponemos en otro puerto usb deberiamos otra vez instalar el driver para que ese puerto este listo para colocarse el adaptador.

estos adaptadores funcionan cambiando el voltaje y elevandolo, por ejemplo el puerto usb sale 5 volts y ponemos el daptador cambiaria de 5 a solo 9 volt ya que no tiene suficiente capacidad para elevarlo a 13, y con esas circunstancias no podemos usar estos tipo de adaptadores para programar pic's porque es muy poco voltaje entregado. pero para poder comunicarnos es suficiente.


----------



## george.manson.69 (Jul 9, 2009)

el mas conocido entre los electronicos el max232 para poder cambiar señales rs232 a ttl. este tipo de circuito es muy economico y utiliza solo 4 capacitores y listo para usar.

este circuito se conecte a cualquier computadora que tenga un puerto serial, los puertos serial como hemos visto varias explicaciones entregan +,-13volts y por su puesto lo queremos conectar a un pic no jalara, y tenemos un riesgo a que pueda descomponerse. y por esta causa usamos el max232 para cambair esos 13 volts a 5 volts.


----------



## george.manson.69 (Jul 9, 2009)

este pequeño dispositivo tiene un alcanze de hasta 100mts a 9 volts, por lo que yo he probado, existen decodificadores que te permiten enviar bits, por dar una ejemplo tenemos 1011 y eso te lo envia a una cierta velocidad que cuenta el decodificador(ht12e), pero podemos usar pic directamente en este caso, ya que el pic es multiuso, los baudios requeridos para que funcione correctamente, en mi caso seria baud=1200, asi tenemos la seguridad que se enviara los datos correctamente ya que estoy usando una pila de 9 volts.

(menos voltaje seria menos baudios y mas voltaje mas baudios.)

aqui dejo como debe de ir conecatdo el transmisor al pic..."IN" es donde debe de ir el TX del pic.


----------



## george.manson.69 (Jul 9, 2009)

bueno aqui esta todo lo que habia dicho anteriormente, es el circuito de transmisor, muy sencillo, podemos usar un pic12f675 pero me surgio unos problemitas, al querer cambiar los baudios y los pines transmision, entonces tuve que usar un pic mas grande en este caso el pic16f628a, en el puerto b podemos usar unos led para indicar el lado donde nuestro robot esta dando vuelta para que sea mas chido el circuito jeje.
ustedes diran porque no conecte directamente el transmisor al max, sin usar el pic, bueno pues hbaia dicho antes para que el robot se activara tendremos que usar un password, y el porgrama que va contener el pic, es lo que va hacer es compara el password con lo que hemos escrito, y enviar la información 10 veces por el transmisor(twr434), asi cada cosa que queramos que haga el robot se enviara 10 veces por el transmisor. mas adelante explicare con detalle lo que quiero decir.


----------



## george.manson.69 (Jul 9, 2009)

bueno ya por ultimo para terminar con el transmisor nos guiaremos con la estrategia seguir para el programa que va a contener el pic.


----------



## Palmas (Jul 9, 2009)

Vamos a revisar detenidamente este enlace, Gracias.
Palmas.


----------



## george.manson.69 (Jul 10, 2009)

bueno ya terminamos el transmisor solo faltaria publicar los programas que son los mero mero, pero eso sera al ultimo..por ahora ya explicamos las partes de trasmisor se ve sencillo y lo es , ahora como vimos como va ser el receptor que contenia un rws434, pic, driver H, motores, y un lcd....vamos a explicar la conexion de rws434 primero que nada.

este receptor es de 434Mhz tiene un alcanze al interperie 120 metros o indoor a 60 metros aprox. se puede conectar directamente al pic. se alimenta de solo 5 volts y sus conexion es muy simple. los baudios requeridos son 4800 pero en este proyectos lo pondre a 1200 bps.


----------



## george.manson.69 (Jul 10, 2009)

bueno este puede usarse un L293 ya que es muy popular para invertir los giros de los motores DC, pero yo usare un que consegui por internet es identico al L293 pero solo cambiaria el nombre el que yo use fue el SN754410NE.

la conexion es simple como vemos en el esquema  de abajo.


----------



## george.manson.69 (Jul 10, 2009)

bueno use los motoreductores son muy buenos porque tienen un gran torque, use en este proyecto dos motoreductores de 4kg*cm. me salieron muy bueno pero ustedes pueden comprar otro tipo de motores para esto no hay problema.


----------



## Vegetal Digital (Jul 10, 2009)

Hola tu proyecto esta cada vez más interesante, te felicito. Sobre los motores, donde los conseguiste? 
Averigue en todos los lugares de mi ciudad pero nadie tiene motores de esos, en cika me venden pero sin reducción. Vos los comprastes o se los sacaste a algún aparato?
Gracias
Saludos


----------



## Meta (Jul 10, 2009)

Muy bueno lo que estás haciendo.


----------



## george.manson.69 (Jul 10, 2009)

bueno todo lo anterior se resume a esto. este circuito es el receptor, donde va ser colocado donde va el chasis de carrito, la antena puede medir 30 cm o 15 cm, no importa.


----------



## george.manson.69 (Jul 10, 2009)

Vegetal Digital dijo:
			
		

> Hola tu proyecto esta cada vez más interesante, te felicito. Sobre los motores, donde los conseguiste?
> Averigue en todos los lugares de mi ciudad pero nadie tiene motores de esos, en cika me venden pero sin reducción. Vos los comprastes o se los sacaste a algún aparato?
> Gracias
> Saludos




www.robodacta.com
ahi los compre...ahi es donde compre todo el materia que use...no se si envian fuera del pais materiales...si es asi va ser un poco caro en envio...pero si quieres entra  ala pag y aberigua


----------



## Vegetal Digital (Jul 10, 2009)

Muchas gracias voy a averiguar


----------



## george.manson.69 (Jul 11, 2009)

bueno sigue de mostrar el algoritmo que va contener el programa del pic del receptor.
pronto subire lo que resta...los programas en C para los pic, y Control del robots hecho en C#..solo paciencia les pido jeje


----------



## Meta (Jul 11, 2009)

Va tomando forma...


----------



## ingdenis1 (Jul 13, 2009)

el organigrama lo hiciste en ofice visio?


----------



## ByronAC (Jul 16, 2009)

Hola, soy nuevo en este foro y estoy impresionado con tanta información y tantos proyectos posteados por ustedes, me parece buenísimo el proyecto que estás montando .

Por mi lado, soy novato en micros, solo sé manejar el 16f84a y ahora quiero comenzar a trabajar el 18f2550 para interconectar el pc con unos actuadores ( el micro es el enlace entre el pc y los actuadores). Ccs parece que es un programa para programar en C, y al parecer se puede interconectar con MPLAB. Por ahí vi que preguntaron antes.. tienen los links para descargar Css y el plugin para MPLAB?

Felicitaciones de nuevo por tanto conocimiento jeje


----------



## HUGO3010 (Jul 16, 2009)

george:
hola lei algo de la transmision y me parecio muy interesante gracias por compartir. te consulto si lo has probado realmente y si hay que tener cuidado con las adaptaciones de impedancias de las antenas o no .
en la realidad tienen tan buen alcance y funcionamiento como lo promocionan seguin tus experiencias 
gracias y te saludo muy atentamente. hugo


----------



## george.manson.69 (Jul 16, 2009)

HUGO3010 dijo:
			
		

> george:
> hola lei algo de la transmision y me parecio muy interesante gracias por compartir. te consulto si lo has probado realmente y si hay que tener cuidado con las adaptaciones de impedancias de las antenas o no .
> en la realidad tienen tan buen alcance y funcionamiento como lo promocionan seguin tus experiencias
> gracias y te saludo muy atentamente. hugo



hola hugo..mira no tuve problemas para nada, al hacer los dos circuitos (transmisor y receptor) ando ahorita de vacaciones y deje mis trabajos en la casa, y por eso no he subido los programas que falta para terminar el proyecto..solo tengo intenet aqui, pero funciona muy bien, voy a subir imagenes y un video de su funcionamiento..."ver para creer".
saludos!


----------



## Vegetal Digital (Jul 17, 2009)

ByronAC dijo:
			
		

> Hola, soy nuevo en este foro y estoy impresionado con tanta información y tantos proyectos posteados por ustedes, me parece buenísimo el proyecto que estás montando .
> 
> Por mi lado, soy novato en micros, solo sé manejar el 16f84a y ahora quiero comenzar a trabajar el 18f2550 para interconectar el pc con unos actuadores ( el micro es el enlace entre el pc y los actuadores). Ccs parece que es un programa para programar en C, y al parecer se puede interconectar con MPLAB. Por ahí vi que preguntaron antes.. tienen los links para descargar Css y el plugin para MPLAB?
> 
> Felicitaciones de nuevo por tanto conocimiento jeje


Lo lamento pero no podemos darte esos programas en el foro...
Busca en google el ccs y si ya tenes el mplab no son necesarios los plugin, al menos yo no los necesite.
Saludos


----------



## ByronAC (Jul 17, 2009)

ok gracias por hacerme saber, ya lo estoy buscando en otro lugar.  jeje


----------



## george.manson.69 (Jul 18, 2009)

bueno aqui esta lo prometido...jeje...este pequeño programa esta en forma de control.
se dara un archivo para word, donde viene explicado el programa.
y se dara el programa.


----------



## george.manson.69 (Jul 18, 2009)

aqui le dejo como debe ser el programa para cada pic, tanto como el transmisor y receptor. Puede que me salir del tema que tenia que era programas hecho en ccs c. pero si se fijan bien los programas anteriores fuera referencia apra hacer estos. y para saber tambien que podemos hacer con estos...y pues logramas hacer un robot simple. 


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;TRANSMISOR
//DATE:28/JUNIO/'09
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16F628A.h>
#include <STRING.H>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=2400,xmit=PIN_A0,rcv=PIN_A1)


void config(void){
		set_tris_a(0x22);
		set_tris_b(0x00);
		setup_comparator(NC_NC_NC_NC);
}

void accion(void){
			int x,y;
			do{
				x=getch();
				#use rs232(baud=1200,xmit=PIN_A2)
				switch(x){
					case'U':
						for(y=0;y<=15;y++){ 
							printf("U");
							delay_ms(5);
						}
						output_b(0x01); 
						break;
					case'L':
						for(y=0;y<=15;y++){ 
							printf("L");
							delay_ms(5);
						}
						output_b(0x02); 
						break;
					case'R': 
						for(y=0;y<=15;y++){ 
							printf("R");
							delay_ms(5);
						}
						output_b(0x04); 
						break;
					case'D': 
						for(y=0;y<=15;y++){ 
							printf("D");
							delay_ms(5);
						}
						output_b(0x08);
						 break;
					case'O':
						for(y=0;y<=15;y++){ 
							printf("O");
							delay_ms(5);
						}
						output_b(0x00); 
						break;
				}
				#use rs232(baud=2400,xmit=PIN_A0,rcv=PIN_A1)
					
			}while(x!='O');
}



void main(void){
		char password[]="YES";
		char word[];
		int z;
		config();
		output_b(0x00);

		do{
			#use rs232(baud=2400,xmit=PIN_A0,rcv=PIN_A1)
			gets(word);
			if(strcmp(word,password)){
				output_b(0x0f);
				#use rs232(baud=1200,xmit=PIN_A2)
				for(z=0;z<=30;z++){
					printf("A");
					delay_ms(5);
				}
				#use rs232(baud=2400,xmit=PIN_A0,rcv=PIN_A1)
				accion();
			}
			else{
				output_b(0x00);
			}
		}while(TRUE);

}
```


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;RECEPTOR
//DATE:28/JUNIO/'09
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16F628A.h>
#include <STRING.H>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)
#define use_portb_lcd TRUE
#include<LCD.C>
#use rs232(baud=1200,rcv=PIN_A4)
#define EN1_2 PIN_A6
#define EN3_4 PIN_A7
#define A_1	  PIN_A0
#define A_2	  PIN_A1
#define A_3   PIN_A2
#define A_4   PIN_A3

int SALIR,c;

void config(void){
		set_tris_a(0x30);
		setup_comparator(NC_NC_NC_NC);
		output_low(EN1_2);
		output_low(EN3_4);
		output_low(A_1);
		output_low(A_2);
		output_low(A_3);
		output_low(A_4);
}
void main(void){
		config();
		lcd_init();

MAIN:
		lcd_putc("\fPASSWORD");
		output_low(EN1_2);
		output_low(EN3_4);
		do{
			c=getch();
			switch (c){
				case 'A':
					lcd_putc("\fCORRECTO");
					delay_ms(1000);
					SALIR=1;
					break;
			}
		}while(SALIR!=1);
		SALIR=0;
		lcd_putc("\fESPERANDO\n");
		lcd_putc("A SER CONTROLADO");
		output_high(EN1_2);
		output_high(EN3_4);
		output_low(A_1);
		output_low(A_3);
		do{
			c=getch();
			switch (c){
				case 'O':
					goto MAIN;
					break;
				case 'U':
					lcd_putc("\fADELANTE");
					output_high(A_1);
					output_low(A_2);
					output_high(A_4);
					output_low(A_3);
					break;
				case 'D':
					lcd_putc("\fRETROCEDER");
					output_low(A_1);
					output_high(A_2);
					output_low(A_4);
					output_high(A_3);
					break;
				case 'L':
					lcd_putc("\fIZQUIERDA");
					output_low(A_1);
					output_high(A_2);
					output_high(A_4);
					output_low(A_3);
					break;
				case 'R':
					output_high(A_1);
					output_low(A_2);
					output_low(A_4);
					output_high(A_3);
					lcd_putc("\fDERECHA");
					break;
			}
		}while(TRUE);
}
```


----------



## george.manson.69 (Jul 18, 2009)

aqui les dejo las imagenes del proyecto.


----------



## george.manson.69 (Jul 19, 2009)

YouTube - VÃ­deo0007

YouTube - VÃ­deo0006

YouTube - VÃ­deo0008

YouTube - VÃ­deo0010


----------



## Moyano Jonathan (Jul 20, 2009)

Exelente proyecto ! felicitaciones por los avances


----------



## george.manson.69 (Jul 21, 2009)

bueno para otra vez empezar con los programas aqui les dejo una matriz de led 8x8 simple.


```
//-------------------------------------
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;MATRIX
//DATE:20/JULIO/'09
//-------------------------------------

//CONFIGURACION///////////////////
#include<16f628a.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)
#define DATA  PIN_A0
#define CLK   PIN_A1
#define RESET PIN_A2

void config(void){
		set_tris_b(0x00);
		set_tris_a(0x20);
		setup_comparator(NC_NC_NC_NC);
}

void SEND_DATA0(void){
		output_low(DATA);
		delay_us(2);
		output_low(CLK);
		delay_us(2);
		output_high(CLK);
}

void SEND_DATA1(void){
		output_high(DATA);
		delay_us(2);
		output_low(CLK);
		delay_us(2);
		output_high(CLK);
}


void main(void){
		int H[]={0b01000010,0b01000010,0b01000010,0b01111110,0b01000010,0b01000010,0b01000010,0b01000010};//"H" 
		int O[]={0b00111100,0b01000010,0b01000010,0b01000010,0b01000010,0b01000010,0b01000010,0b00111100};//"O"
		int L[]={0b01111110,0b01000000,0b01000000,0b01000000,0b01000000,0b01000000,0b01000000,0b01000000};//"L"
		int A[]={0b01000010,0b01000010,0b01000010,0b01111110,0b01000010,0b01000010,0b00100100,0b00011000};//"A"
		int i;
		long j;
		config();
		output_bit(RESET,1);  // "ON"
		output_bit(CLK,0);
		output_bit(DATA,0);

		while(TRUE){
			for(j=0;j<=25;j++){
				for(i=0;i<=7;i++){
					output_b(H[i]);			//H
					delay_ms(5);
					SEND_DATA1();
				}
				SEND_DATA0();
			}

			for(j=0;j<=25;j++){
				for(i=0;i<=7;i++){
					output_b(O[i]);			//O
					delay_ms(5);
					SEND_DATA1();
				}
				SEND_DATA0();
			}

			for(j=0;j<=25;j++){
				for(i=0;i<=7;i++){
					output_b(L[i]);			//L
					delay_ms(5);
					SEND_DATA1();
				}
				SEND_DATA0();
			}	

			for(j=0;j<=25;j++){
				for(i=0;i<=7;i++){
					output_b(A[i]);			//A
					delay_ms(5);
					SEND_DATA1();
				}
				SEND_DATA0();
			}

			for(j=0;j<=25;j++){
				for(i=0;i<=7;i++){
					output_b(0X00);			//" "
					delay_ms(5);
					SEND_DATA1();
				}
				SEND_DATA0();
			}
		}
}
```


----------



## george.manson.69 (Jul 22, 2009)

bueno aqui les dejo un programa ue te pide el valor a cada display,para empezar un conteo desde el numero elegido.
aqui se pone en pruebla las interrupciones en este caso el timer0.
por ejemplo si queremos un conteo de 60 segundos hay que poner en los display un 6 y un 0 y presionar S y listo.


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;CONTADOR_RS232
//DATE:06/MAYO/2009
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16F628A.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)
#use rs232(baud=2400,xmit=PIN_A2,rcv=PIN_A3)

#define ENABLE_1 PIN_A1
#define ENABLE_2 PIN_A0

int mostrar[]={0b11000000,0b11111001,0b10100100,0b10110000,
			   0b10011001,0b10010010,0b10000011,0b11111000,0b00000000,0b00011000};

int x,i,KEY;
int N1;
int N2;

//CONFIGURACION/////////////
void config(void){
			set_tris_a(0x28);
			set_tris_b(0x00);
			setup_comparator(NC_NC_NC_NC);
			setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1|RTCC_8_BIT);
			set_timer0(0);
}	



//INTERRUPCION POR TIMER0
#INT_TIMER0
void MUESTRA(){
		
		output_low(ENABLE_1);
		output_high(ENABLE_2);
		output_b(mostrar[N2]);
		delay_ms(5);

		output_low(ENABLE_2);
		output_b(mostrar[N1]);
		output_high(ENABLE_1);
}

//ELECCION DEL NUMERO

NUMERO(){
	loop:	x=getch();
				switch(x){
					case 48: KEY=0; break;
					case 49: KEY=1; break;
					case 50: KEY=2; break;
					case 51: KEY=3; break;
					case 52: KEY=4; break;
					case 53: KEY=5; break;
					case 54: KEY=6; break;
					case 55: KEY=7; break;
					case 56: KEY=8; break;
					case 57: KEY=9; break;
					default: printf("NO ES UN NUMERO, INTENTE OTRA VEZ \r\n"); goto loop;
				}
		return(KEY);
}

//INICIO DEL PROGRAMA PRINCIPAL/////////////////////

void main(void){
			disable_interrupts(INT_TIMER0);
			disable_interrupts(GLOBAL);
			config();

			
		do{
			printf(">>ESCRIBA EL 1er VALOR; \r\n");
	
			N1=NUMERO();
				
			output_b(mostrar[N1]);
			output_high(ENABLE_1);
			output_low(ENABLE_2);
			delay_ms(1000);
			output_low(ENABLE_1);

			printf(">>ESCRIBA EL 2do VALOR; \r\n");
		
			N2=NUMERO();

			output_b(mostrar[N2]);
			output_low(ENABLE_1);
			output_high(ENABLE_2);
			delay_ms(1000);
			output_low(ENABLE_2);
		
			printf("PARA EMPEZAR PRESIONE (S) \r\n");
			do{
				x=getch();
			}while(x!='S');
			printf("START...\r\n");
			do{
				enable_interrupts(INT_TIMER0);
				enable_interrupts(GLOBAL);
				for(i=1;i<=45;i++){
						delay_ms(10);
				}

				if(N1==0){
					N2--;
					N1=9;
				}else{
					N1--;
				}
			}while(N1!=0 || N2!=0);
			disable_interrupts(INT_TIMER0);
			disable_interrupts(GLOBAL);
			output_low(ENABLE_1);
			output_low(ENABLE_2);
			printf("HA TERMINADO EL CONTEO; \r\n");
			delay_ms(1000);
		}while(TRUE);
}
```


----------



## george.manson.69 (Jul 23, 2009)

bueno aqui les dejo dos practicas, un programa es para poner el reloj en el lcd, y otro programa es para probar el teclado 4x4.


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;LCD TIEMPO
//DATE:22/JULIO/'09
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16F887.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)
#include<LCD.C>

//DEFINICIONES
#define HORA	PIN_A0
#define MINUTO	PIN_A1

//VARIABLES
int OVERFLOW,MINUTE,HOUR,SECOND;

//CONFIGURACION
void config(void){
		set_tris_a(0x03);
		set_tris_d(0x00);
		setup_adc(ADC_OFF);
		setup_comparator(NC_NC_NC_NC);
		setup_timer_0(RTCC_INTERNAL|RTCC_DIV_64|RTCC_8_BIT); //overflow cada 16.384mS
		set_timer0(0);
}

//INTERRUPCION 
#INT_TIMER0
void TIMER0(void){
		OVERFLOW++;
		if(OVERFLOW>61){
			OVERFLOW=0;
			SECOND++;
			if(SECOND==60){
				SECOND=0;
				MINUTE++;
				if(MINUTE==60){
					MINUTE=0;
					HOUR++;
					if(HOUR==24){
						HOUR=0;
					}
				}
			}
		}
}

void TIEMPO(void){
		int i;
		
		for(i=0;i<=200;i++){
			delay_ms(1);
		}
}

//INICIO DEL PROGRAMA
void main(void){
		config();
		lcd_init();
		
		SECOND=0;
		MINUTE=0;
		HOUR=0;
		lcd_putc("    R E L O J");
		enable_interrupts(INT_TIMER0);
		enable_interrupts(GLOBAL);
		while(TRUE){
			if(input(MINUTO)){
				MINUTE++;
				if(MINUTE==60){
					MINUTE=0;
				}
				TIEMPO();
			}
		
			if(input(HORA)){
				HOUR++;
				if(HOUR==24){
					HOUR=0;
				}
				TIEMPO();
			}
			lcd_gotoxy(6,2);
			printf(lcd_putc,"%u:%u:%u  ",HOUR,MINUTE,SECOND);
		}
}
```


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;KEYBOARD Y LCD
//DATE:23/JULIO/'09
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16F887.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=8000000)
#use fast_io(b)
#include<kbd_lib.c>
#include<LCD.C>

void config(void){
		set_tris_b(0xF0);
		port_b_pullups(0xF0);
		setup_adc(NO_ANALOGS);
		setup_comparator(NC_NC_NC_NC);
		disable_interrupts(GLOBAL);
}

void main(void){
		char KEY=0;
		int N=1;
		config();
		kbd_init();
		lcd_init();

		while(TRUE){
			lcd_putc("NUMERO");
			do{
				KEY=kbd_getc();
				if(KEY!=0){
					lcd_gotoxy(N,2);
					lcd_putc(KEY);	
					N++;
				}
			}while(N<=17);
			lcd_putc("\f");
			N=1;
		}
}
```


----------



## dragondgold (Jul 28, 2009)

hola soy nuevo en esto de programar Cy aun no entiendo la distincion entre #DEFINE y #BIT los dos hacen lo mismo? como hago por ejemplo si quiero una parte de la ram para guardar algun dato yo en asm ponia por ejemplo

ejemplo_1         equ         0x24                         de este modo ejemplo_1 esta en la 0x24 de la ram

y que hace exactamente la instruccion int?


----------



## Vegetal Digital (Jul 28, 2009)

int es una declaracion de una variable puede ser asi:
unsigned int8 d; //esta es una variable del tipo sin signo y de una extension de 8 bits, va desde 0 hasta 255

unsigned int 16 d; // la variable d tiene una extension de 2 bytes y como es sin signo va desde 0 hasta 65536

signed int8 v;// la variable v es de 1 byte y como tiene signo va desde -127 a 128 (puede ser desde -128 a 127 pero ahora no me acuerdo)

#bit sirve para darle nombre a un determinado puerto por ejemplo

#BIT LED = PORTB.0
#BIT SENSOR = PORTC.3

con define se puede hacer esto pero tambien se puede darle un "nombre" a un conjunto de instrucciones:

#define M_D_AVANZA OUTPUT_HIGH(PIN_B6); OUTPUT_LOW(PIN_B7); //parte de un programa mio para  mi primer robot microcontrolado que todavia esta en construcción, lo que hace pone en alto b6 y en bajo b7 para que el motor gire (M_D_AVANZA = motor derecho avanza)

Para guardar un dato es lo de mas arriba con las variables
Espero te sirva
saludos


----------



## dragondgold (Jul 28, 2009)

Vegetal_Digital que hace exactamente tu robot porque yo tengo uno hecho con un 16f84 y ahora lo voy a mejorar con un 16f877 pero el mio tiene bumpers nomas ya que no encuentro en ninguna casa de electronica nadie que venda esos sensores SHARP o los IS471F y no se como esquive por infrarrojo vos pudiste solucionar esto? (esta argentina no vende nada )


----------



## Vegetal Digital (Jul 28, 2009)

Mi robot es igual al tuyo, le puse dos contactos en el frente, pero se me quemo la parte de potencia de los motores que la hice con un l293, tengo que esperar hasta el viernes que llegue, y el lunes empiezan de nuevo las clases así que voy a estar con poco tiempo. Los sensores que decis no se que son, si queres experimentar con infrarrojos he leido que el CNY70 anda bien. Para mi ese es un paso que dare mas adelante.
que le queres mejorar que tenes que usar un 16f877?
Yo estoy usando el 16f84 por una cuestión de espacio.


----------



## george.manson.69 (Jul 31, 2009)

Este simple programa lo que hace al introducir el tiempo(MM:SS) empezara a decrementar hasta llegar a cero.

esto pone a prueba el timer0,y timer1. 


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;CONTROL DE 4 DISPLAY
//DATE:31/JULIO/2009
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16F628A.h>
#fuses HS,NOWDT,NOLVP,NOMCLR,NOPROTECT
#use delay(clock=20000000)

//definiciones del cada display 1 al 4

#define EN1  PIN_A0
#define EN2  PIN_A1
#define EN3  PIN_A2
#define EN4	 PIN_A3
#define PUSH PIN_A4
#define PUSH2 PIN_A5

//variable que contiene la decodificacion para mostrar cada numero en el display
//de 7 segmentos

int mostrar[]={0b01000000,0b01111001,0b00100100,0b00110000,0b00011001,
			   0b00010010,0b00000011,0b01111000,0b00000000,0b00011000};

//definicion de variables a usar

signed int MEN1=0,MEN2=0,SEN3=0,SEN4=0;
int i;
long j;
int OVERFLOW;

//funcion: que establece los puertos como I/O establece el timer0 con 6.5536mS 
void config(void){
		set_tris_a(0x30);
		set_tris_b(0x80);
		setup_comparator(NC_NC_NC_NC);
		setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128|RTCC_8_BIT);//overflow 6.5536mS
		setup_timer_1(T1_INTERNAL|T1_DIV_BY_1);//overflow 13.1072mS
		set_timer0(0);
}

#INT_TIMER0
void TIMER0(void){
	OVERFLOW++;
	if(OVERFLOW>152){
		OVERFLOW=0;
		SEN4--;
		if(SEN4<0){
			SEN4=9;
			SEN3--;
			if(SEN3<0){
				SEN3=5;
				MEN2--;
				if(MEN2<0){
					MEN2=9;
					MEN1--;
					if(MEN1<0){
						MEN1=0;
					}
				}
			}
		}
	}
		
}

#INT_TIMER1
void TIMER1(void){
		output_bit(EN1,0);
		output_bit(EN2,0);
		output_bit(EN3,0);
		output_b(mostrar[SEN4]);
		output_bit(EN4,1);
		delay_ms(6);
		output_bit(EN1,0);
		output_bit(EN2,0);
		output_bit(EN4,0);
		output_b(mostrar[SEN3]);
		output_bit(EN3,1);
		delay_ms(6);
		output_bit(EN1,0);
		output_bit(EN3,0);
		output_bit(EN4,0);
		output_b(mostrar[MEN2]);
		output_bit(EN2,1);
		delay_ms(6);
		output_bit(EN3,0);
		output_bit(EN2,0);
		output_bit(EN4,0);
		output_b(mostrar[MEN1]);
		output_bit(EN1,1);
}

//RUTINA DE TEMPORIZACION ANTIREBOTE
void TIEMPO(void){
	for(i=1;i<=100;i++){
		delay_ms(1);
	}
}

//rutina de temporizacion de vizualizacion
void TIEMPO1(void){
	for(j=1;j<=1000;j++){
		delay_us(1);
	}
}

void main(void){
		config();

MAIN:
		disable_interrupts(INT_TIMER0);
		enable_interrupts(INT_TIMER1);
		enable_interrupts(GLOBAL);

		//EN ESTA RUTINA INTRODUCES EL TIMEPO

		do{
			if(~input(PUSH)){
				TIEMPO();
				SEN4++;
				if(SEN4>=10){
					SEN4=0;
					SEN3++;
					if(SEN3>=6){
						SEN3=0;
						MEN2++;
						if(MEN2>=10){
							MEN2=0;
							MEN1++;
							if(MEN1>=6){
								MEN1=0;
							}
						}
					}
				}
			}
		}while(input(PUSH2));
		disable_interrupts(INT_TIMER1);
		enable_interrupts(INT_TIMER0);
		
		//EN ESAT RUTINA EMPIEZA A DECREMENTAR EL TIEMPO PUESTO ANTERIORMENTE

		do{
			output_bit(EN1,0);
			output_bit(EN2,0);
			output_bit(EN3,0);
			output_b(mostrar[SEN4]);
			output_bit(EN4,1);
			TIEMPO1();
			output_bit(EN1,0);
			output_bit(EN2,0);
			output_bit(EN4,0);
			output_b(mostrar[SEN3]);
			output_bit(EN3,1);
			TIEMPO1();
			output_bit(EN1,0);
			output_bit(EN3,0);
			output_bit(EN4,0);
			output_b(mostrar[MEN2]);
			output_bit(EN2,1);
			TIEMPO1();
			output_bit(EN3,0);
			output_bit(EN2,0);
			output_bit(EN4,0);
			output_b(mostrar[MEN1]);
			output_bit(EN1,1);
			TIEMPO1();
		}while(MEN1!=0 || MEN2!=0 || SEN3!=0 || SEN4!=0);
		disable_interrupts(GLOBAL);
		delay_ms(1000);
		goto MAIN;
}
```


----------



## george.manson.69 (Ago 6, 2009)

Este programa simplemnte hace una inicializacion de la targeta y escribe "hola mundo" y lo lee y lo muestra en el LCD.


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;SPI
//DATE:18/JUNIO/'09
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16f887.h>
#fuses HS,NOWDT,NOLVP,MCLR,NOPROTECT,NOPUT
#use delay(clock=20000000)
#define use_portb_lcd TRUE
#include<LCD.C>

long i;
long data_in;
char LETRA[11];
char GRABAR[64];

#include<comandos.h>

void config(void){
		setup_adc(ADC_OFF);
		setup_comparator(NC_NC_NC_NC);
		set_tris_c(0x10);
		set_tris_d(0x00);
		output_d(0x00);
		setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_64);
}

void main(void){
		config();
		lcd_init();
		output_bit(PIN_C0,1); /*desactivamos de la SD*/
		
		for(i=0;i<10;i++)
		{
			spi_write(0xFF);		//se manda almenos 80 blocks para resetear el SD
		}

		output_bit(PIN_C0, 0); /* Activacion de la SD */


		/* Envia a la SD el comando 0 */
		//modo spi

		comando0();

		output_bit(PIN_C0,1); /* Desactivacion de la SD */
		spi_write(0xFF);
		output_d(0x01);
		delay_ms(1000);

		output_bit(PIN_C0, 0); /* Activacion de la SD */

		/* Envia a la SD el comando 1 */
		//incilizar la targeta spi
		comando1();

		output_bit(PIN_C0,1); /* Desactivacion de la SD */
		spi_write(0xFF);
		output_d(0x02);
		delay_ms(1000);

		output_bit(PIN_C0, 0); /* Activacion de la SD */
		//escribimos "HOLA MUNDO" en la tarjeta(vea el archivo comandos.h)
		comando24();

		output_bit(PIN_C0,1); /* Desactivacion de la SD */
		spi_write(0xFF);

		output_bit(PIN_C0, 0); /* Activacion de la SD */
		//leemos lo que escribimos
		comando17();

		output_bit(PIN_C0,1); /* Desactivacion de la SD */
		spi_write(0xFF);
		//lo proyectamos al lcd
		for(i=0;i<=11;i++){
			lcd_putc(LETRA[i]);
		}

}
```

las funciones se encuetran en el archivo de comandos.h

que es este.


```
//COMANDO QUE TE PERMITE HCAER UN RESET U PONER EN MODO SPI.
void comando0(void){
		while(data_in!=1)
		{
			spi_write(0x40) ;
			spi_write(0x00) ;
			spi_write(0x00) ;
			spi_write(0x00) ;
			spi_write(0x00) ;
			spi_write(0x95) ;

			for(i=0;i<64;i++)
			{
				spi_write(0xFF);
				data_in = spi_read();

				if(data_in==0x01)
				{
					break;
				}
			}
		}
}

//COMANDO QUE TE SIRVE PARA PONER LA TARGETA EN MODO SPI
void comando1(void){
	while(data_in!=0)
		{
			spi_write(0x41) ;
			spi_write(0x00) ;
			spi_write(0x00) ;
			spi_write(0x00) ;
			spi_write(0x00) ;
			spi_write(0xFF) ;

			for(i=0;i<64;i++)
			{
				spi_write(0xFF);
				data_in = spi_read();

				if(data_in==0x00)
				{
					break;
				}
			}
		}
}

//COMANDO QUE TE PERMITE ESTABLECER CUANTOS BYTES PODEMOS USAR PARA
//ESCRIBIR O LEER.

void comando16(void){

	while(data_in!=0){
		spi_write(0x50) ;
		spi_write(0x00) ;
		spi_write(0x00) ;
		spi_write(0x00) ;
		spi_write(0x00) ;
		spi_write(0xFF) ;
		
	for(i=0;i<64;i++){
			spi_write(0xFF);
			data_in = spi_read();

			if(data_in==0x00){
				break;
			}
		}
	}
}

//COMANDO QUE TE PERMITE ESCRIBIR EN UN SECTOR DE LA MEMORIA
//EN ESTE CASO SU ESCRIBIMOS ALGO, QUE NO CONTEGA LOS 512 BYTES NECESARIOS,
//SOLO LO RELLENAMOS CON OXFF.
void comando24(void){

	while(data_in!=0x00){
		spi_write(0x58) ;
		spi_write(0x00) ;
		spi_write(0x00) ;
		spi_write(0x00) ;
		spi_write(0x00) ;
		spi_write(0xFF) ;

		for(i=0;i<64;i++){
			spi_write(0xFF);
			data_in = spi_read();
			if(data_in==0x00){
				break;
			}
		} 
	}

	spi_write(0xFF) ;
	spi_write(0xFF) ;
	spi_write(0xFE) ;

	//MENSAJE GRABADO

	spi_write('H');
	spi_write('O');
	spi_write('L');
	spi_write('A');
	spi_write(' ');
	spi_write('M');
	spi_write('U');
	spi_write('N');
	spi_write('D');
	spi_write('O');

	for(i=0;i<501;i++){
		spi_write(0xFF);
	}

	spi_write(0xFF) ;
	spi_write(0xFF) ;

	data_in = spi_read(0xFF);

	data_in &=0b00011111;

	if(data_in!=0b00000101){
		output_d(0x0A);		//ESCRITURA MAL
	}
	else{
		output_d(0x02);		//ESCRITURA BIEN
	}

	while(spi_read(0xFF)!=0xFF);
}

//ESTE COMANDO ES DE LECTURA,YA QUE EL PIC16F887
//NO TIENE TANTA MEMORIA SOLO USAREMOS 64 BYTES DEL PIC.
//EL RESTO SOLO LO USAREMOS COMO BASURA.

void comando17(void){

	while(data_in!=0x00){
		spi_write(0x51) ;
		spi_write(0x00) ;
		spi_write(0x00) ;
		spi_write(0x00) ;
		spi_write(0x00) ;
		spi_write(0xFF) ;

		for(i=0;i<64;i++){
			spi_write(0xFF);
			data_in = spi_read();
			if(data_in==0x00){
				break;
			}
		} 
	}

	output_bit(PIN_D2,1);
	while(spi_read(0xFF)!=0xFE);

	for(i=0;i<=11;i++){
		LETRA[i]=spi_read(0xFF);
	}

	for(i=0;i<=53;i++){
		GRABAR[i]=spi_read(0xFF);
	}

	for(i=0;i<=64;i++){
		GRABAR[i]=spi_read(0xFF);
	}
	for(i=0;i<=64;i++){
		GRABAR[i]=spi_read(0xFF);
	}

	for(i=0;i<=64;i++){
		GRABAR[i]=spi_read(0xFF);
	}
	for(i=0;i<=64;i++){
		GRABAR[i]=spi_read(0xFF);
	}

	for(i=0;i<=64;i++){
		GRABAR[i]=spi_read(0xFF);
	}
	for(i=0;i<=64;i++){
		GRABAR[i]=spi_read(0xFF);
	}

	for(i=0;i<=64;i++){
		GRABAR[i]=spi_read(0xFF);
	}
	
	SPI_write(0xFF);		
	SPI_write(0xFF);
	output_bit(PIN_D2,0);
}
```


----------



## george.manson.69 (Ago 10, 2009)

este pequeño circuito te permite guardar o leer en la memoria eeprom. en este caso se creo un archivo .bin para simular la memoria de la eeprom.

en el archivo .bin se puede abrir con el notepad de window, para checar que mensaje tiene guardado en la eeprom.



```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;FUNCIONES DEL CCS C COMPLIER
//DATE:27/ABRIL/2009
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16f628a.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)
#define use_portb_lcd TRUE
#include"LCD.C"

#define EEPROM_SDA  PIN_A0
#define EEPROM_SCL  PIN_A1
#include"24256.C"
void config(void){
		set_tris_a(0x20);
		set_tris_b(0x00);
		setup_comparator(NC_NC_NC_NC);
}

void main(void){
		
		int i;
		int LETRA;

		config();
		init_ext_eeprom();
		lcd_init();

		for(i=0;i<=9;i++){
			LETRA=read_ext_eeprom(i);
			lcd_putc(LETRA);
		}
}
```


----------



## george.manson.69 (Ago 10, 2009)

este programa fue hecho en matlab para adquirir la temperatura de un sensor usando un pic12f675.

primero que nada mostramos el programa que contiene el pic12f675


```
//------------------------------------
//TITULO: SENSOR DE TEMPERATURA Y ENVIADO A A MATLAB
//AUTOR: JORGE ARTURO RODRIGUEZ HERNANDEZ
//FECHA: 09\AGOSTO\'09
//------------------------------------

#include <12f675.h>
#fuses XT,NOWDT,NOCPD,NOPROTECT,MCLR,NOPUT
#use delay(clock=4000000)
#use rs232(baud=2400,xmit=PIN_A2,rcv=PIN_A1)

unsigned int READ,TEMP;
int ENTER;
void config(void){
		set_tris_a(0x3B);
		setup_comparator(NC_NC_NC_NC);
		setup_adc(ADC_CLOCK_INTERNAL);
		setup_adc_ports(sAN0);
}

void main(void){
		config();

		do{
			ENTER=getc();
			if(ENTER=='E'){
				READ=read_adc();
				TEMP=2*READ;
				printf("%d",TEMP);
			}
		}while(TRUE);
}
```


ahora vemos que usamos* virtual serial port*


----------



## Moyano Jonathan (Ago 11, 2009)

Exelentes tus ejemplos estaría bueno que compilaras en un rar todos los ejemplos y los postearas para más facilidad para quien los quiera descargar.


----------



## Chico3001 (Ago 11, 2009)

Mejor que el rar seria el ZIP por que es universal y gratuito..


----------



## Moyano Jonathan (Ago 11, 2009)

Si podría ser también , lo que pasa es que siempre he usado Winrar

1 saludo !


----------



## ja_ro (Ago 11, 2009)

Hola Jorge:
Necesito de tu ayuda para un PIC 16F84 que contenga un temporizador regresivo.
¿Puedo contar con tu experiencia?
Un Saludo


----------



## george.manson.69 (Ago 12, 2009)

ja_ro dijo:
			
		

> Hola Jorge:
> Necesito de tu ayuda para un PIC 16F84 que contenga un temporizador regresivo.
> ¿Puedo contar con tu experiencia?
> Un Saludo



a ver dime tu duda...que es lo que quires hacer! para haber si pueod ayudarte! como temporizador necesitas!?


----------



## ja_ro (Ago 12, 2009)

Gracias Jorge.
Necesito programar en un PIC 16F84 un temporizador de cuenta atrás con lo siguiente:
- Alimentación 12 Voltios
- Tiempo de programación de 0 a 99 minutos, mediante pulsadores
- Un pulsador de Star y otro de Stop o Reset
- Dos displays de 7 segmentos que indiquen los minutos programados y la cuenta atrás
- Al pulsar Star se activa un Relé y al llegar a cero se desactiva
- Que conserve la ultima programación
Y creo que de momento es todo. ¿Es difícil realizar el programa en Hex para grabar directamente?
¿Conoces algún circuito con estas prestaciones?
Gracias Jorge


----------



## george.manson.69 (Ago 12, 2009)

ja_ro dijo:
			
		

> Gracias Jorge.
> Necesito programar en un PIC 16F84 un temporizador de cuenta atrás con lo siguiente:
> - Alimentación 12 Voltios
> - Tiempo de programación de 0 a 99 minutos, mediante pulsadores
> ...




si te fijas bien en las paginas atras de este tema tengo muchos de ese tipo...
y tienen el archivo .hex lo que necesitas para programar el pic, solo lo que faltaria es cambiar de pic en este caso, para el pic16f84.
la alimentacion no se te olvideo usar un regulador para 5 volts, (7805 )para regular el voltaje de 12 a 5 para alimentar el microcontrolador.


----------



## ja_ro (Ago 12, 2009)

george.manson.69 dijo:
			
		

> ja_ro dijo:
> 
> 
> 
> ...



Tengo que pedirte perdón, pero pensé que había leido todos tus post. Creo que te refieres al CONTROL 4 DISPLAY.rar, en el cual veo 4 displays y dos pulsadores uno para empezar el conteo y otro para el reset, pero (corrigeme sime equivoco)
¿Como programo el tiempo, que quiero que sea variable mediante pulsadores y donde tengo la salida a relé que te comento?
Y otra cosa para mi importante, ¿el PIC aguanta el consumo de los displais normales de 7 segmentos?
Gracias de nuevo y perdona mi torpeza.


----------



## george.manson.69 (Ago 13, 2009)

ja_ro dijo:
			
		

> george.manson.69 dijo:
> 
> 
> 
> ...



ese circuito que mencionas puedes programar el tiempo, lo malo es que solo tienes 2 pulsadores, un pulsador para cambiar el tiempo tienes que dejar preionado el push botton para que coloques el tiempo que quiereas  puede ser hasta 59:59 lo maximo que puedes introducir. y el otro push botton, es para empeza la cuenta regresiva desde el tiempo que pusiste.
pero se puede modificar rapidamente, como tu quieres para dos display's, se dejara dos pines del pic libres, y de ahi puedes poder el reset y el relevador. solo faltaria mejorar ese circuito y listo.

que idioma programas? ASM, BASIC, C?

ahh...el pic si soporta los display, en este caso mis display que tengo son de anodo comun, y solo le puse un transistor al ando y listo para que toda la tension caiga en el transistor no en el pic, y aparte los dos displays no prenden al mismos tiempo, se estan turnando para prender cada uno a una velocidad muy rapida que parece que estan prendidos al mismo tiempo.


----------



## ja_ro (Ago 13, 2009)

Hola Jorge:
Me preguntas que en que idioma programo y la verdad es que a mis 50 años apenas programo el DVD para que me grabe alguna peli.Nací un poco tarde y no veo factible aprender ahora ningún lenguaje de programación aunque me gustaría.
He bajado el proteus 7 para simular el circuito tuyo y me he dado cuenta de que en los tiempos que quiero usar, que  estarían comprendidos entre 5 y 60 minutos, es un poco lento poner el tiempo, ya que empieza por los segundos.
En resumen y abusando de tu paciencia y comprensión me gustaría saber si estarías dispuesto a diseñarme el circuito y hacer el programa tú.
Algo como lo tu tuyo pero un poco rediseñado como tu bien dices.
Me da vergüenza a mis años, pero no alcanzo más.
Sin ningún compromiso Jorge, si me dices que no lo entenderé
Un Saludo


----------



## george.manson.69 (Ago 13, 2009)

A OK...esta bien te voy a ayudar..pero pues espero quye te sirva este circuito...lo hice rapido..pero hay un pequeño problema este circuito trabaja hasta 99 segundos..jeje 

este es una imagen del circuito..es tal como pediste 

--el relevador puede ser de cualquiera...de 5,6,12,24 volts no pasa nada ya que se esta usando un transistor para separar el pic y el relevador.
--reset(MCLR del pic)
--ajustar
--start.

pero solo son segundos..


espero que te sirva.


----------



## Moyano Jonathan (Ago 13, 2009)

No importa la edad que tengas para programar yo recien tengo 19 y sin embargo con ayuda de internet y los foros he aprendido casi todo lo que se de electronica.


----------



## dragondgold (Ago 13, 2009)

hola estoy aprendiendo a programar en C y veo que ustedes saben mucho yo queria programa el PWM del pic 16f877 a una frecuencia de 38Khz pero no lo logro yo hice este programa hay algun error?


```
#include<16f877a.h>
#fuses NOWDT,NOPROTECT
#use delay(clock=4000000)
#byte TRISB=0x86
#byte PORTB=0x06
#byte TRISC=0x87
#byte PORTC=0x07


void main(void){
TRISB=0x00;
PORTB=0x00;
TRISC=0x00;
T2CON=0b00000111; //TMR2 habilitado y predivisor de 16
while(TRUE){
SETUP_CCP1(CCP_PWM);
SET_PWM1_DUTY(594);
}
}
```
yo use esta formula para calcular la frecuencia esta bien?

valor/(1/clock)*predivisor tmr2

0.000594/(1/4000000)*16 

eso me dio como resultado 8016 Hz o sea 38Khz pero cuando simulo en proteus me da una frecuencia de 250Hz ayudenme por fas!


----------



## Vegetal Digital (Ago 13, 2009)

Moyano Jonathan dijo:
			
		

> No importa la edad que tengas para programar yo recien tengo 19 y sin embargo con ayuda de internet y los foros he aprendido casi todo lo que se de electronica.


Yo tengo 14 y programo en C para pics


----------



## ja_ro (Ago 13, 2009)

george.manson.69 dijo:
			
		

> A OK...esta bien te voy a ayudar..pero pues espero quye te sirva este circuito...lo hice rapido..pero hay un pequeño problema este circuito trabaja hasta 99 segundos..jeje
> 
> este es una imagen del circuito..es tal como pediste
> 
> ...



Jorge
No esperaba menos de ti
Muchisimas Gracias
Lo que necesitaba es esto, solo que en vez de segundos serían minutos, pero no te preocupes intentaré investigar como cambiar el programa para que sean minutos.
Muy Agradecido por tu paciencia
Un Saludo


----------



## george.manson.69 (Ago 14, 2009)

Vegetal Digital dijo:
			
		

> Moyano Jonathan dijo:
> 
> 
> 
> ...



io tengo 21 y apenas el año pasado aprendi programar pic's jeje. aprendi devolada programar en ASM, y luego en BASIC, y por ultimo C que considero que es la herramienta mas poderosa, a cuanto se diga de hacer programas complejos.


----------



## Vegetal Digital (Ago 14, 2009)

george.manson.69 dijo:
			
		

> io tengo 21 y apenas el año pasado aprendi programar pic's jeje. aprendi devolada programar en ASM, y luego en BASIC, y por ultimo C que considero que es la herramienta mas poderosa, a cuanto se diga de hacer programas complejos.



Ahora conozco a alguien que diga que c es muy poderoso y que conozoca variedad de lenguajes...
Saludos


----------



## dragondgold (Ago 15, 2009)

alguno me podria explicar como programo el modo PWM del pic16f877 en C porque no encuentro información en ningun lado


----------



## mecatrodatos (Ago 16, 2009)

Que tal interesante foro he pasado del asm, el pascal ,el basic y creo que es tiempo de programar en C, muy buenos ejemplos.


----------



## machine_softronics (Ago 18, 2009)

aqui te estoy enviando el diseño de la matriz.espero slaga bien


----------



## EINNER C (Ago 20, 2009)

hola a todos

muy buenos los ejemplos que han dado, yo me inicie en esto de programacion en pic con c ccs hace poco y espero pronto poder postear algunos ejemplos

george.manson.69 quisiera saber si es posible que posteara mas ejemplos realizados con matlab, pues en este tema si me siento muy novato y se ve que dominas muy bien el tema 

hasta luego y exitos a todos


----------



## EINNER C (Ago 20, 2009)

hola dragondgold

aqui te mando un ejemplo del pwm en c, 


```
#include <16f877.h>
#fuses XT, NOPUT, NOWDT, NOBROWNOUT, NOLVP, NOCPD
#use delay(clock=4000000)

void main(void){

   long dutyPWM;
   // Para cristal de 4 mhz, frecuencia de 20 khz ,
   // T2DIV set to 1
   // Para calcular la frecuencia:
   // (4/frecuencia cristal)*T2_DIV*(periodo+1)


   // (4/4000000)*1*(49+1)=0.00005seg
   setup_timer_2(T2_DIV_BY_1, 49, 1);

   // seleccionamos PWM para los dos módulos CCP
   setup_ccp1 (CCP_PWM);
  
      // Para calcular el tiempo en nivel alto, dado que usamos un LONG, sería:
   // Valor*T2_DIV*(1/frecuencia del cristal). Si se usa un valor tipo INT en lugar
   // de LONG se calcularía multiplicando la fórmula por 4: Valor*T2_DIV*(1/frecuencia del cristal)*4
   dutyPWM = 100; // 0.000025seg/(1*(1/4000000))=100, que es el valor a cargar. Duty 50%
  
   set_pwm1_duty(duty_PWM1);
  

   while(1){   //bucle infinito.
   }
}
```

espero te sirva


----------



## ralego2003 (Ago 20, 2009)

Hola que tal george.manson.69 tengo una duda, con respecto a la conexión de RF entre PC y PIC quisiera saber si se puede establecer la comunicación sin utilizar el PIC del transmisor, es decir poder mandar los datos directamente del MAX232 ya que no requiero de la contraseña.

Muchas gracias y espero tu respuesta   !


----------



## george.manson.69 (Ago 21, 2009)

ralego2003 dijo:
			
		

> Hola que tal george.manson.69 tengo una duda, con respecto a la conexión de RF entre PC y PIC quisiera saber si se puede establecer la comunicación sin utilizar el PIC del transmisor, es decir poder mandar los datos directamente del MAX232 ya que no requiero de la contraseña.
> 
> Muchas gracias y espero tu respuesta   !



no se puede ya que el programa de "Control of a robot" te manda una contraseña, y el programa que contiene el pic resive esa contraseña y activa el robot...tendrias que hacer otro programa parecido al control of a robot pero sin contrseña...


----------



## ralego2003 (Ago 23, 2009)

ok george.manson.69 ya realice el programa solo que hay un problema, al parecer el circuito receptor toma mucha basura. ¿Es por eso que lo mandas 10 veces o como se puede solucionar ese problema? ya que con los decodificadores que mencionas anteriormente no sucede eso!!!


----------



## ja_ro (Ago 27, 2009)

Hola george.manson.69, espero que no te hayas olvidado de mi. No se por qué, pero tanto tú como yo tenemos desabilitada la opción de recibir privados, bueno yo espero que ya no.
Saludos


----------



## foso (Ago 28, 2009)

Cuando quiero compilar en PCW me dice ***Error 18 "Informacion.rtf.c" Line 0(0,1): File can not be opened

¿Que puede ser eso ?


----------



## george.manson.69 (Ago 28, 2009)

Ja ro no me he olvidado...es que ya entre a la escuela y pues no tengo mucho tiempo para conectarme y revisar dudas, estoy todo el dia en le escuela



foso dijo:


> cuando quiero compilar en pcw me dice ***error 18 "información.rtf.c" line 0(0,1): File can not be opened
> 
> ¿que puede ser eso ?


 

mmm...pcw esta incorporado a mplab verdad? A lo mejor esta mal instalado, puede ser eso o puede ser que se alla borrado por accidente un archivo del programa de pcw


----------



## george.manson.69 (Ago 30, 2009)

este es un simple circuito que capta 4 sensores de humedad y los valores seran proyectos a un lcd de 20x4.



```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;SENSORES
//DATE:28/AGOSTO/'09
///////////////////////////////////////
//CONFIGURACION///////////////////
#include<16F886.h>
#device ADC=8
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=8000000)
#include<LCD420_PORTC.C>
#include<kbd_lib.C>
int PLANTA1,PLANTA2,PLANTA3,PLANTA4;
short DONE;
int KEY;
void config(void){
  set_tris_a(0x0F);
  set_tris_b(0xF0);
  port_b_pullups(0xF0);
  setup_adc(ADC_CLOCK_INTERNAL|VSS_VDD);
  setup_adc_ports(sAN0|sAN1|sAN2|sAN3);
  setup_comparator(NC_NC_NC_NC);
  disable_interrupts(GLOBAL);
}
void ADC_HECHO(void){
  while(DONE!=1){
   DONE=adc_done();
  }
}
void main(void){
  config();
  lcd_init();
  kbd_init();
START:
  lcd_gotoxy(1,1);
  lcd_putc("\f------SENSORES------");
  lcd_gotoxy(1,2);
  lcd_putc("ENTRAR A MEDIR LOS");
  lcd_gotoxy(1,3);
  lcd_putc("SENSORES:");
  lcd_gotoxy(9,4);
  lcd_putc("YES(A)");
  do{
   KEY=kbd_getc();
   if(KEY!=0){
    if(KEY=='A')
     break;
   }
  }while(TRUE);
  lcd_gotoxy(1,1);
  lcd_putc("\f------SENSORES------");
  do{
   set_adc_channel(0);
   delay_us(50);
   ADC_HECHO();
   PLANTA1=read_adc();
   set_adc_channel(1);
   delay_us(50);
   ADC_HECHO();
   PLANTA2=read_adc();
   set_adc_channel(2);
   delay_us(50);
   ADC_HECHO();
   PLANTA3=read_adc();
   set_adc_channel(3);
   delay_us(50);
   ADC_HECHO();
   PLANTA4=read_adc();
 
   PLANTA1=2*PLANTA1;
   PLANTA2=2*PLANTA2;
   PLANTA3=2*PLANTA3;
   PLANTA4=2*PLANTA4;
   lcd_gotoxy(1,2);
   printf(lcd_putc,"1.- %u C 2.- %u C ",PLANTA1,PLANTA2);  
   lcd_gotoxy(1,3);
   printf(lcd_putc,"3.- %u C 4.- %u C ",PLANTA3,PLANTA4);
   KEY=kbd_getc();
   if(KEY!=0)
    goto START;
  }while(TRUE);
}
```


----------



## george.manson.69 (Ago 31, 2009)

Bueno ya me he envolucrado con un chip en especial que es el pic18f2550 que es muy bueno para ya hacer cosas mas interesantes. Gracias a lo que he investigado en este foro 

A especial a unos chavos que han aportado mucho, como es Meta, Moyano jonathan en un tema que habla de interfaz de USB. Gracias a esto he logrado comunicar por medio de este bicho a la computadora por USB.

Bueno primero que nada mostrare el programa hecho en CCS C.

Que hace una inicializacion por decirlo asi entre el pic y la compu por medio de USB.

A este se le conose como CDC (Comunication device class) que simula un puerto serial a una entrada USB de la computadora, poder asi hacer practicas sin necesidad de comprar un USB a SERIAL, este seria directamente al pic.

Bueno como ya exite un tema que proporciona Moyano jonathan que explica todo detelladamente sobre esta comunicación me basare simplemente hacer proyectos con este interfaz.


```
//=================================
//autor:jorge arturo rdz hdz
//titulo:CONEXION ENTRE USB y LAP
//fecha: 30/AGOSTO/2009
//=================================
#include <18F2550.h> // Definición de registros internos.
#fuses HSPLL,NOMCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOPBADEN
#use delay(clock=48000000) // Frecuencia máxima de trabajo.
#include "usb_cdc.h" // Descripción de funciones del USB.
#include "usb_desc_cdc.h" // Descriptores del dispositivo USB.
void main() {
 set_tris_b(0x00);
 output_b(0x00);
   usb_cdc_init(); // Configuramos al puerto virtual.
   usb_init(); // Inicializamos el stack USB.
 output_high(PIN_B0); //LED ROJO ENCENDIDO
 output_low(PIN_B1);  //LED VERDE APAGADO
   while(!usb_cdc_connected()) {} 
   // espera a detectar una transmisión de la PC (Set_Line_Coding).
   do{
      usb_task();
      if (usb_enumerated()){    // Espera a que el dispositivo sea enumerado por el host.
  output_low(PIN_B0);   //LED ROJO APAGADO
  output_high(PIN_B1);  //LED VERDE ENCENDIDO
         if(usb_cdc_kbhit()){   // En espera de nuevos caracteres en el buffer de recepción.
            if(usb_cdc_getc()=='x'){ //llego x?
               printf(usb_cdc_putc, "llego x.\n\r"); 
             }
            if(usb_cdc_getc()=='a'){ //llego a?
               printf(usb_cdc_putc, "llego a.\n\r");
 
             }
         }
       }
   }while (TRUE);
}
```

Bueno no explique como funciona el anterior, cuando se conecta aparecera y debe de aparecer para la simulación, un mensaje en la parte inferior derecha de la pantalla, una conexión (cuando conectamos un memoria aparce un dispositivo encontrado algo parecido) bueno le damos click ahí y debera aparecer la pantalla para poder intalar un driver entonces vamos hacer click en next, entonces buscaremos donde este instaldo el CCS C y buscamos la carpeta de drivers entonces la elegimos y entonces se encontrara tres driver entonces le daremos click al del medio para instalarlo. Y todo listo para simular, en este caso ya no usaremos el VIRTUAL SERIAL PORT ya que sera directo la comunicación. Entonces cualquier programa como hyperterminal u otro programa que hace comunicación serial lo abriremos siempre y cuando este conectado(en la simulación) el usb. Automáticamente detectara el COM donde esta el usb del pic. Y listo!!

Ahora esta practica consta de un teclado 4x4 y USB, que al presionar una tecla del teclado 4x4 aarecera en la pantalla donde este conectado el usb.


```
//=================================
//autor:jorge arturo rdz hdz
//titulo:CONEXION ENTRE USB y LAP
//fecha: 30/AGOSTO/2009
//=================================
#include <18F2550.h> // Definición de registros internos.
#fuses HSPLL,NOMCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOPBADEN
#use delay(clock=48000000)  // Frecuencia máxima de trabajo.
#include<kbd_lib.c>
#include "usb_cdc.h"   // Descripción de funciones del USB.
#include "usb_desc_cdc.h"  // Descriptores del dispositivo USB.
int KEY;
void config(void){
  set_tris_b(0xF0);
  port_b_pullups(0xF0);
  setup_comparator(NC_NC_NC_NC);
  setup_adc(ADC_OFF);
}
 
void main() {
 config();
 kbd_init();  //Configuramos el teclado
 usb_cdc_init(); // Configuramos al puerto virtual.
 usb_init();  // Inicializamos el stack USB.
 output_high(PIN_C0); //LED ROJO ENCENDIDO
 output_low(PIN_C1);  //LED VERDE APAGADO
   while(!usb_cdc_connected()) {} 
   // espera a detectar una transmisión de la PC (Set_Line_Coding).
   do{
      usb_task();
      if (usb_enumerated()){    // Espera a que el dispositivo sea enumerado por el host.
   output_low(PIN_C0);   //LED ROJO APAGADO
   output_high(PIN_C1);  //LED VERDE ENCENDIDO
   do{
    KEY=kbd_getc();
    if(KEY!=0){
     usb_cdc_putc(KEY);
    }
   }while(TRUE);
  }
   }while (TRUE); // bucle infinito.
}
```

Bueno para hacer la cosa mas interesante hice un programa en visual c# donde escribimos en una linea lo que se nos ocurra y lo enviamos a visualizar al lcd, el comando de borrado seria ”*”, por ejemplos queremos que borre la pantalla y escriba “*HOLA MUNDO” al hacer esto primero enviara el “*” para borrar la pantalla y luego escribira HOLA MUNDO en la primera linea del lcd.

Este es una imagen del programa Y el codigo que contiene el PIC.


```
//===============================
//AUTOR:JORGE ARTURO RDZ HDZ
//TITULO: USB + LCD
//FECHA: 30/AGOSTO/2009
//===============================
#include <18F2550.h> // Definición de registros internos.
#fuses HSPLL,MCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOPBADEN
// Fuses utilizados:
/*
HSPLL: utilizamos un cristal HS de alta velocidad, en conjunto con el PLL para generar los 48Mhz.
NOMCLR: Utilizamos reset por software, y dejamos el pin 1 del micro como entrada/salida digital.
NOWDT: No utilizamos el perro guardían.
NOPROTECT: Desactivamos la protección de código.
NOLVP: Desactivamos la programación a bajo voltaje.
NODEBUG: No entramos al modo debug.
USBDIV: signfica que el clock del usb se tomará del PLL/2 = 96Mhz/2 = 48Mhz.
PLL5: significa que el PLL prescaler dividirá en 5 la frecuencia del cristal. para HS = 20Mhz/5 = 4Mhz.
CPUDIV1: El PLL postscaler decide la división en 2 de la frecuencia de salida del PLL de 96MHZ, si queremos 48MHZ, lo dejamos como está.
VREGEN: habilita el regulador de 3.3 volts que usa el módulo USB
*/
#use delay(clock=48000000)  // Frecuencia máxima de trabajo.
#define use_portb_lcd TRUE
#include<LCD.C>
#include "usb_cdc.h"   // Descripción de funciones del USB.
#include "usb_desc_cdc.h"  // Descriptores del dispositivo USB.
char LETRA[];
void config(void){
  setup_comparator(NC_NC_NC_NC);
  setup_adc(ADC_OFF);
}
  
void main() {
 config();
 lcd_init();  //Configuramos el LCD
 usb_cdc_init(); // Configuramos al puerto virtual.
 usb_init();  // Inicializamos el stack USB.
 output_high(PIN_C0); //LED ROJO ENCENDIDO
 output_low(PIN_C1);  //LED VERDE APAGADO
   while(!usb_cdc_connected()) {} 
   // espera a detectar una transmisión de la PC (Set_Line_Coding).
   do{
      usb_task();
      if (usb_enumerated()){    // Espera a que el dispositivo sea enumerado por el host.
   output_low(PIN_C0);   //LED ROJO APAGADO
   output_high(PIN_C1);  //LED VERDE ENCENDIDO
   if(usb_cdc_kbhit()){
    LETRA=usb_cdc_getc();
    if(LETRA=='*'){
     lcd_putc("\f");
    }else{
     lcd_putc(LETRA);
    }
   }  
  }
   }while (TRUE); // bucle infinito.
}
```


----------



## Moyano Jonathan (Sep 1, 2009)

Exelentes tus ejemplos


----------



## george.manson.69 (Sep 1, 2009)

hola de nuevo...vamos hacer otro circuito con USB, bueno este trata de algo my simple, es controlar 8 led por medio de USB, ya habia hecho algo parecido pero se trataba por puerto serial, y pues ahora lo cambie por el tal PIC18F2550 que tiene un USB 2.0 incluido .

este es el programa que contiene el PIC18F2550 hecho con el CCS C.

```
//=================================
//autor:jorge arturo rdz hdz
//titulo:CONTROL DE 8 LED
//fecha: 30/AGOSTO/2009
//=================================

#include <18F2550.h> // Definición de registros internos.

#fuses HSPLL,NOMCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOPBADEN

#use delay(clock=48000000) // Frecuencia máxima de trabajo.

#include "usb_cdc.h" // Descripción de funciones del USB.
#include "usb_desc_cdc.h" // Descriptores del dispositivo USB.

void main() {

    int KEY;
    set_tris_b(0x00);
    output_b(0x00);
   usb_cdc_init(); // Configuramos al puerto virtual.
   usb_init(); // Inicializamos el stack USB.

    output_high(PIN_C0);    //LED ROJO ENCENDIDO
    output_low(PIN_C1);        //LED VERDE APAGADO
   while(!usb_cdc_connected()) {} 
   // espera a ser conectado
   do{
      usb_task();
      if (usb_enumerated()){          // Espera a que el dispositivo sea enumerado por el host.
        output_low(PIN_C0);            //LED ROJO APAGADO
        output_high(PIN_C1);        //LED VERDE ENCENDIDO
        if(usb_cdc_kbhit()){
            KEY=usb_cdc_getc();
            switch(KEY){
                case '1': output_toggle(PIN_B0); break;
                case '2': output_toggle(PIN_B1); break;
                case '3': output_toggle(PIN_B2); break;
                case '4': output_toggle(PIN_B3); break;
                case '5': output_toggle(PIN_B4); break;
                case '6': output_toggle(PIN_B5); break;
                case '7': output_toggle(PIN_B6); break;
                case '8': output_toggle(PIN_B7); break;
            }
        }
    }
   }while (TRUE); // bucle infinito.
}
```


----------



## foso (Sep 2, 2009)

Hola ! . Una pregunta. Una vez que tenemos escrito el programa en el CCS ¿ se puede compilar directamente desde CCS y usar el .hex que nos da el programa para grabar el PIC?

Digo esto porque había escuchado que al programa CCS lo integran con Mplab y no se para que hacen esto.


----------



## Chico3001 (Sep 2, 2009)

Efectivamente.... el PIC solo entiende codigo maquina, y nosotros solo entendemos codigo de alto nivel, asi que la funcion del compilador (en este caso CSS) es traducir de codigo de alto nivel a codigo maquina, y el resultado es el archivo hex que es el que tienes que grabar en el PIC


----------



## george.manson.69 (Sep 4, 2009)

Hola por fin he podido adquirir datos continuos desde el usb, bueno hize un pequeño programa que te registra la temperatura, cada 1 segundo, y lo guarda en una lista a la derecha, eset programa fue hecho en visual c#.

programa que contiene el pic.

```
//=================================
//autor:jorge arturo rdz hdz
//titulo:MEDIDOR DE TEMPERATURA
//fecha: 30/AGOSTO/2009
//=================================
#include <18F2550.h> // Definición de registros internos.
#device ADC=8
#fuses HSPLL,NOMCLR,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOPBADEN
#use delay(clock=48000000) // Frecuencia máxima de trabajo.
#include "usb_cdc.h" // Descripción de funciones del USB.
#include "usb_desc_cdc.h" // Descriptores del dispositivo USB.
int TEMP;
char VALOR;
void main() {
 set_tris_b(0x00);
 set_tris_a(0x01);
 setup_adc(ADC_CLOCK_INTERNAL);
 setup_adc_ports(AN0);
 read_adc(ADC_READ_ONLY);
 output_b(0x00);
 usb_cdc_init(); // Configuramos al puerto virtual.
 usb_init(); // Inicializamos el stack USB.
 output_high(PIN_C0); //LED ROJO ENCENDIDO
 output_low(PIN_C1);  //LED VERDE APAGADO
   while(!usb_cdc_connected()) {};
   // espera a ser conectado
   do{
  usb_task();
  if (usb_enumerated()){    // Espera a que el dispositivo sea enumerado por el host.
   output_low(PIN_C0);   //LED ROJO APAGADO
   output_high(PIN_C1);  //LED VERDE ENCENDIDO
   delay_us(10);
   TEMP=read_adc();
   TEMP=2*TEMP;
         if(usb_cdc_kbhit()){   // En espera de nuevos caracteres en el buffer de recepción.
           VALOR=usb_cdc_getc();
    if(VALOR=='A'){
     usb_cdc_putc(TEMP);
    }
            }
         }
   }while (TRUE); // bucle infinito.
}
```
 
IMAGEN DEL PROYECTO.


----------



## foso (Sep 4, 2009)

No se que pasa pero los archivos .hex que me genera el C Compiler no me funcionan cuando los grabo en el PIC. Debe ser que hay que configurar algo en el programa ¿no?


----------



## george.manson.69 (Sep 4, 2009)

foso dijo:


> No se que pasa pero los archivos .hex que me genera el C Compiler no me funcionan cuando los grabo en el PIC. Debe ser que hay que configurar algo en el programa ¿no?




si debe ser algo del programa, e so mas seguro, asegurate que que al copilarlo este todo bien, que no tenga errores

mandame si quieres un programa hecho en C, y yo lo compilo


----------



## foso (Sep 7, 2009)

ya solucioné el problema. Gracias igual george.mason.69 . Era un problema del programa PICkit2, me estaba olvidando de ajustar la palabra de configuracion.

 ¡Que bueno que es programa en C ! te facilita un montón, aunque no sabes que tanto te va a ocupar el programa en la memoria. 

Saludos.


----------



## flowers (Sep 17, 2009)

Hola compañero, creo que podrás ayudarme...
...yo también estoy haciendo un control de temperatura. Con un PIC16F877 hago la conversion A/D de una PT100, y convierto los valores de 0-5V a 0-255 sin inconvenientes. Pero mi problema radica en que tengo que diseñar un software que levante la curva de temperatura. No tengo inconvenientes en la transmision de datos a la PC, pero no puedo graficar la curva en tiempo real (este es el gran problema). Estoy usando C# 2008 express. POR FAVOR SI ALGUIEN PUEDE DARME UNA MANO POR AMOR AL ARTE....JA!

PD: no importa que programa usar, lo que si importa es que necesito que se haga un archivo ejecutable para levantar la curva de datos (desde el port serie) en tiempo real.

Desde ya un gran abrazo!


----------



## george.manson.69 (Sep 18, 2009)

hola ....es lo ue yo tambien queria hacer...pero pues no le se muy bien al C# y le pregunte a un amigo sobre graficar la temperatura en tiempo real, ebntonces me dijo, que deberia de usar JAVA cosa que no me involucrado...por el simple hecho de que es muy complejo...


----------



## hernanfire (Sep 25, 2009)

Hola a todos, Felicitaciones George, este hilo es EXCELENTE,  he realizado un 75% de los ejemplos que adjuntaste para ganar experiencia en el manejo de proteus, Mplab y CCS,;-) te hago una consulta, me podras indicar el lenguaje de programacion que usas, me parece que lo mencionas C# y habra alguna posibilidad de que adjuntes el codigo fuente en este lenguaje, de cualquier ejemplo que hayas realizado en comunicacion en USB?¿?¿ 
Desde ya te agradezco. Seguire el hilo. Gracias


----------



## Hernan83 (Sep 28, 2009)

Hola George 69 ,mira excelente el foro y los temas,esto me viene bien para empezar con USB,ya mismo tengo los componentes y me lo pongo a hacer,queria hacer el que maneja los 8 leds,pero una pregunta,ejecutando el .exe del proyecto,con ese programita visual ya deberia funcionarme o debo cargar algun otro archivo o algo en la pc,aclaro que uso el XP,en la pc me aparece algun otro puerto COM virtual? Gracias por la rta


----------



## eddy4011 (Sep 28, 2009)

Que palabras mas alentadoras y gentiles yo te felicito,pues yo tengo 54 y recien empece con el CCS C, yo solo vi algo de fortran 4 cuando me gradue en 1980 y con toda la ayuda de la red es mucho lo que estoy aprendiendo, Saudo  desde la playas de West Palm...
 Eddy.


----------



## Hernan83 (Sep 29, 2009)

Hice el circuito USB que maneja los 8 leds,grabo el .hex al micro,el programita en visual me detecta bien como port3 en la pc,bajo xp,cuando conecto la placa me hace el ruidito clasico "turu" del USB y aparece el globito con el nombre,me prende solo el led rojo en la placa,pero me pone el asistente para que busque el archivo que falta!!! que hago! como se llama el archivo que pide que busque y de donde lo saco!!!  Gracias desde ya!


----------



## george.manson.69 (Sep 29, 2009)

hernan83 dijo:


> Hice el circuito USB que maneja los 8 leds,grabo el .hex al micro,el programita en visual me detecta bien como port3 en la pc,bajo xp,cuando conecto la placa me hace el ruidito clasico "turu" del USB y aparece el globito con el nombre,me prende solo el led rojo en la placa,pero me pone el asistente para que busque el archivo que falta!!! que hago! como se llama el archivo que pide que busque y de donde lo saco!!!  Gracias desde ya!


 
Tienes el CCS C vdd? si lo tienes busca la carpaeta en archivos de programas PIC Cy luego entra y busca la carpeta de drivers y ahi habra tres archivos que son los drivers que hacen el interfaz de USB.

y saludos.


----------



## Hernan83 (Sep 29, 2009)

Disculpame las molestias,se me instalaron los driver,todo bien,en administrador de disp. me aparece como com4,el programita visual conecta el led verde,hace el ruidito "turun" al conectar pero no me aparece el globito con el nombre y sigue prendido el led rojo de la placa,o sea no hay comunicacion,que puede ser? disculpame la insistencia,pero es mi primer proyecto USB,es hasta que le agarre la mano,gracias!!!


----------



## ALEXANDERBUCHON (Sep 30, 2009)

A todos los amigos que usan el 18f4550.
Necesito ayuda... Estaba tentado en poner "urgente" pero se (jajaja) que todo es urgente en nuestra actividad... Asi es que... Aqui va: "urgente" necesito información de lo siguiente: Estoy haciendo un proyecto donde el pic18f4550 es la base de adquisicion de datos: Por una parte 1 puerto analogico que me lee por comparacion un sensor de presion mpx7500, y al mismo tiempo un sensor sht11 de sensirion, y ademas (para no quedarme corto) necesito leer un sensor de campo hall, y un encoder (estoy usando un encoder paso a paso si... Un motor pap como encoder (jajajaja)) por ello necesito si alguien puede darme una pauta a seguir... Porque usé varios ejemplos (llevo varios meses en esto) de mplab, de css de c18 en fin ya me perdí en la cantidad de información que bajé de internet.... Resumiendo... Que me conviene usar... Hid, bulk, cdc o que tucuimas ! Si es uno de estos si alguien podria ponerme un esqueleto de programa en c, en assambler o lo que sea... Para darle fin a este tema que me hace caer el pelo... Por otro lado si existe del lado del pc... Alguna libreria ocx para leer con vbasic... En fin... Me olvidaba... Estoy usando el usb para esto está claro no ?? Jajajaj la placa la tengo fabricada... No es la que está en internet porque la que bajé como modelo tenia fallas terribles, no es tan simple como lo pintan, tuve que ponerle condensadores en todas partes asi como resistencias para que no se tilde al !pasar la mano encima!!!! Jajajajajaj cosa de locos... Bueno... Lo hice extenso pero ni modo... Tendria que poner un blog de las desventuras de desarrollar un data aad. Por medio de usb... 
Un saludo muy cordial a la gente que se dedica a esto... Son fenómenos y es durisimo encontrar información digerible... Es un reto de por sí.

Abrazos.


----------



## JanO_o (Oct 5, 2009)

buenas gente...
hago el cuento corto...
quiero grabar en la eeprom interna del pic 16f84a usando el compilador C de CCS

y según manual y miles de paginas...

READ_CALIBRATION
READ_EEPROM(address)
WRITE_EEPROM(address, value)

esas son los comando que hay que usar...
la cosa es que me compila todo si no le coloco el read_calibration... pero no funciona

cuando lepongo el read_calibration, me sale un error diciendo que no esta definido el READ_CALIBRATION... 
y lo defini asi...

#define read_calibration 10
Fin = read_calibration (10);

el problema,,, (nose si se definirá asi)... es que me sale un error

error en la linea X blabla "expect ;"

que lo necesita aki..

#define read_calibration (aki) 10

y no puedo hechar a andar el programa con la dichosa funcion...
la cosa es que segun manual es necesario calibrar la memoria para poder usarla (ya que es la memoria interna).

ojalá alguien me pueda ayudar, ya que esto me tiene un poco complicado...
he buscado ya hasta el aburrimiento en internet y nada, no he pillado una explicacion para esto.

bueno, saludos gente y gracias...


----------



## JanO_o (Oct 5, 2009)

buenas, una consulta, ya que veo que has hecho programas grabando en la eeprom del pic...

lo que pasa es que he tratado de grabar en la eeprom y no he podido... creo que me falta configurar algo que no veo en el manual ni en internet...

ojala me puedan ayudar, aki el codigo:



```
#include <16f84a.h> //libreria del pic
#use delay (clock=4000000) //frecuencia del cristal k se va a ocupar.
#fuses HS,NOWDT,NOPUT,NOPROTECT

#byte port_b=0x06
#byte port_a=0x05
#byte k=0x0c
float D,I,L;




void main()
{



   set_tris_b(0); //declaramos el puerto b como salida
   port_b=0;//el valor inicial es 0
   set_tris_a(1);//declaramos el puerto a como entrada
   port_a=0;




      while(1)
      {
      output_low(pin_b1);
      output_low(pin_b0);
      if(input(pin_a0)==1)
         {
         I=0;
         While(input(pin_a0)==1)
            {
            output_high(pin_b0);
            #use delay(clock=4000000)
            delay_us(50);
            I=I+1;
            }
         }

//grabar eepromm

#define LAST_VOLUME 10

write_eeprom(0x04,I);

#use delay (clock=4000000)
delay_ms(50);


//#define LAST_VOLUME 10
L=read_EEPROM(0x04);










      while(input(pin_a1)==1)
         {
         D=0;
         //output_high(pin_b1);
         while(D<=L)
            {
            output_high(pin_b1);
            #use delay(clock=4000000)
            delay_us(50);
            D=D+1;
            }

         }
      }
}
```
basicamente en un temporizador, en el que el tiempo que temporiza esta configurado por un pulsador en la entrada A0... y la partida del temporizador se la da A1.

bueno, eso es... ojalá me puedan ayudar gracias


----------



## Hernan83 (Oct 6, 2009)

Quisiera saber si el CCS tiene libreias para escribir y leer en una EEPROM  24LC256,y si puedo usarlas en conjunto con el PIC18F2550,gracias!


----------



## Moyano Jonathan (Oct 6, 2009)

Si si las tiene tendrías que buscar en la carpeta driver's del CCS


----------



## black (Oct 7, 2009)

gracias checare la información


----------



## bobby valentino (Oct 22, 2009)

hola quisiera saber si alguien puede ayudarme tengo q hacer un proyecto para la escuela se trata de que con un pic controle un servo motor que cada 3 minutos gire a 180° y despues regrese a 0° otros 3 minutos y asi lo siga haciendo quien me puede ayudar???


----------



## george.manson.69 (Nov 5, 2009)

Aqui he juntado algunos proyectos que he hecho en este espacio


----------



## nexus148 (Nov 19, 2009)

Hola george.manson.69

Estoy probando el codigo USB escrito por ti, para comunicar USB del micro con el PC (CDC). 
Programo el Pic con tu codigo, conecto el USB al PC, me reconoce el hardware, busco en la carpeta .../PICC/Drivers/ encuantra 3 ficheros, pero ninguno funciona, creo que es por el win7.

¿Puedes ayudarme?

Un saludo y felicidades por los proyectos, son muy utiles.


----------



## george.manson.69 (Nov 19, 2009)

yO LO PROBE CON WINXP Y FUNCIONA...A LO MEJOR PODRIA SER ESO!!! EN LA CARPETA DONDE ESTAN LOS DRIVER HAY UN ARCHIVO QUE MODIFICAS...MRA ABRE EL ARCHIVO, "usb_desc_cdc.h" ve hasta abajo y encuentra "start device descriptors" 

y busca en la linea

0x61,0x04, //vendor id (0x04D8 is Microchip, or is it 0x0461 ??)  ==8,9
0x33,0x00, //product id   ==10,11

esos numeros hexadecimales cambialos por estos

08,0x04, //vendor id (0x04D8 is Microchip, or is it 0x0461 ??)  ==8,9
0x0A,0x00, //product id   ==10,11

a ver si funciona!!!

pero no se te olvide hacer una copia de seguridad!!!!


----------



## nexus148 (Nov 20, 2009)

Gracias george.manson.69. Ya funciona.


----------



## george.manson.69 (Nov 20, 2009)

Que bien que alla funcionado!!!
despues de todo que tenia el circuito? nexus148

si era lo que te habia mencionado en el mensaje pasado? o que era?


----------



## nexus148 (Nov 21, 2009)

Si te refieres al primer problema, era simplemente el cristal de 20Mhz. Nunca me habia pasado que fallara 2 cristales recien comprados.
Quité uno de un circuito viejo y a funcionar a la primera.

Luego tube problemas con el debug, y lo solucioné poniendo 2 resistencia pulldown en el PGC y PGD del programador, ahora funciona perfecto.

Un saludo.


----------



## george.manson.69 (Nov 21, 2009)

Este proyecto lo subo porque se me hace que es muy interesante, ya que puedes controla 4 servomotores via RS232.

Aqui se encuetra el programa el microcontrolador en CCS C


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;CONTROL DE 4 SERVOS
//DATE:20/NOVIEMBRE/'09
///////////////////////////////////////
//CONFIGURACION///////////////////
#include<16F628A.h>
#include<math.h>
#fuses HS,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=20000000)
#use rs232(uart1,baud=2400)
//VARIABLES QUE SE USAN EN EL PROGRAMA
int x,A=0,B=0,C=0,D=0;
float y;
long zA=0,zB=0,zC=0,zD=0;
//CONFIGURACION DEL MICROCONTROLADOR
void config(void){
  set_tris_a(0x20);
  set_tris_b(0x02);
  setup_comparator(NC_NC_NC_NC);
  enable_interrupts(INT_RDA);
  enable_interrupts(GLOBAL);
}
//INTERRUPCION POR RESEPCION
#INT_RDA
void RS232_receive(void){
  if(kbhit()){
   x=getc();
   switch (x){
    case 'A':
     A=getc();
     break;
    case 'B':
     B=getc();
     break;
    case 'C':
     C=getc();
     break;
    case 'D':
     D=getc();
     break;
   }
  }
  y=(A*6.6666666e-6)+0.9e-3;
  zA=y*1000000;
  y=(B*6.6666666e-6)+0.9e-3;
  zB=y*1000000;
  y=(C*6.6666666e-6)+0.9e-3;
  zC=y*1000000;
  y=(D*6.6666666e-6)+0.9e-3;
  zD=y*1000000;
}
//INICIO DEL PROGRAMA PRINCIPAL
void main(void){
  config();
 do{
  output_high(PIN_A0);
  delay_us(zA);
  output_low(PIN_A0);
  output_high(PIN_A1);
  delay_us(zB);
  output_low(PIN_A1);
  output_high(PIN_A2);
  delay_us(zC);
  output_low(PIN_A2);
  output_high(PIN_A3);
  delay_us(zD);
  output_low(PIN_A3);
  delay_us(80000-zA-zB-zC-zD);
 }while(TRUE);
}
```
 
nota: se usa el virtual serial port para poder simular puertos seriales


----------



## george.manson.69 (Dic 7, 2009)

Hola de nuevo he puesto otros proyectos que hecho en este hilo...
los programas sepueden bajar buscandolos en este tema.


----------



## Vegetal Digital (Dic 7, 2009)

Excelente, muy buenos los proyectos con comunicación usb.
Saludos


----------



## george.manson.69 (Dic 8, 2009)

Hola aqui esta un proyecto simple donde manejas 6 display de 7 segmentos.

Aqui etsa el codigo que contiene el PIC.


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;LETRERO CON DISPLAY DE 7 SEGMENTOS
//DATE:18/JUNIO/'09
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16f887.h>
#fuses HS,NOWDT,NOLVP,MCLR,NOPROTECT,NOPUT
#use delay(clock=20000000)
#use rs232(uart1,baud=2400)

//DEFINIMOS PINES

//#define    EN1    PIN_C0 
//#define    EN2    PIN_C1
//#define    EN3    PIN_C2    NO SE PORQUE LO PUSE
//#define    EN4    PIN_C3  PORQUE NO SE USAN
//#define    EN5    PIN_C4
//#define    EN6    PIN_C5

//AGREGAMOS VARIABLE FIJAS
const int LETRA[]={    0b00001001,    //H
                    0b01000000,    //O
                    0b01000111,    //L
                    0b00001000, //A
                    0b11111111, //SPACE
                    0b11111111, //SPACE 
                     0b11111111, //SPACE
                    0b11111111, //SPACE
                    0b11111111, //SPACE
                    0b11111111, //SPACE
                    0b11111111};//SPACE

//AGREGAMOS VARIABLES

unsigned int x=0;
signed int y=6,z=6,n=1,VALOR=100;
unsigned long i;


//CONFIGURACION DEL PIC

void config(void){

        set_tris_c(0x80);                //RC0-RC6 SALIDAS, RC7 ENTRADAS
        set_tris_d(0x00);                //RD0-RD7 SALIDAS
        setup_comparator(NC_NC_NC_NC);    //OPAM APAGADOS
        setup_adc(ADC_OFF);                //DAC APAGADO
}

void main(void){
        
        config();    //HABLAMOS A LA CONFIGURACION DE CONFIGURACION
        output_c(0x00);
        while(TRUE){
            for(i=0;i<=VALOR;i++){                //ciclo de temporizacion
                    for(y=z;y<=6;y++){            //ciclo donde activa cada display
                            bit_set(*7,y);        //con su correspondiente letra
                            output_d(LETRA[x]);
                            delay_ms(1);        //Tiempo de vizualizacion
                            bit_clear(*7,y);    //Apaga el display antes Prendido
                            x++;                //Incrementa para saber donde debe
                            if(x>=n) x=0;        //primero empezar el principo de la palabra
                    }
            }
            VALOR=VALOR-10;                        //Cuando valla mas letras mostradas se va a tardar
            if(VALOR<=9) VALOR=100;                //mas, entonces el tiempo debe de disminuir para
            z--;                                //una vizualizacion correcta
            if(z<=-4) z=6;                        //Decrementa para vizualizar mas letras al paso del tiempo
            n++;                                //transcurrido.
            if(n>=11) n=1;                        //Incrementa el limite a donde debe de llegar                                                //cada letra con corde al tiempo transcurrio
        }
}
```


----------



## george.manson.69 (Dic 13, 2009)

Bueno amigos!!! He estado trabajando en un buen proyecto que a todos les va a interesar, es un controlador para 8 servos. Que contiene un software para controlarlos via serial. Batalle para porde hacer esto mas simple para proigrama del PIC.
El software esta hecho en C#. Gracias a esto ustedes contruiran su propio controlador y asi ya no estaran gastando para comprar uno. Ustedes mismos podran hacer un controlador. 

Este es el programa que contiene el microcontrolador PIC.


```
////////////////////////////////////////////////////////////////////
//TITULO: CONTROL DE 8 SERVOMOTORES PARA HITEC                  //////
//AUTOR: JORGE ARTURO RODRIGUEZ HERNANDEZ                      //////
//FECHA: 11-12-09                                              //////
//DESCRIPCION: POR MEDIO DEL PROGRAMA CONTROL DE 8 SERVOS.EXE //////
//               CONTROLARAS POR MEDIO DE BARRAS QUE TE INDICARA//////
//               EL GRADO Y EL SERVO A CONTROLAR.               //////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////

#include<16F628A.H>
#fuses HS,NOWDT,NOLVP,MCLR,NOPROTECT

//HS: CRISTAL DE HIGH SPEED 20MHZ
//NOWDT: NO SE UTILIZA EL PERRO GUARDIAN
//NOLVP: SE DESACTIVA ESTA OPCION DE PROGRAMACION
//MCLR:ACTIVAMOS EL MASTER CLEAN
//NOPROTECT: NO SE PROTEGE EL CODIGO()

#use delay(clock=20000000)            //CRISTAL DE 20MHZ
#use rs232(uart1,baud=2400)            //PIN_B1->RX,PIN_B2->TX
#use fast_io(A)                     //RAPIDA INTERVENCION DEL PUERTO A
#use fast_io(B)                        // ''          ''         PUERTO B
#priority timer1,rda                //Es mas primordial que se atienda la interrupcion
                                    //en el timer1
//CONSTANTES DE ENCENDIDO

int ON='A';

//VARIABLES A CONTROLAR

unsigned long tick;            //E
unsigned int SERVO=0;        //ES EL NUMERO DEL SERVO A CONTRLAR MAXIMO CONTAR DE 0 A 7
unsigned int PUERTO=5;        //SOLO AQUI PASA DEL 5 A 6
short LAHL=1;                // SOLO AQUI HACES EL SWITCHEO CUANDO ESTA ALTO O BAJO
short FLAG=0;                //ACTUALIZADOR
unsigned long AUX,AUXH,AUXL;//AUXILIARES PARA OPERACIONES
unsigned int NSERVO=0;        //NUMERO DE SERVO SELECCIONADO
unsigned long POSICION=180;        //0 - 180 grados maximo
unsigned int i;

//VARIABLE DE CONTROL DE PULSO DE ALTO Y BAJO PARA LOS 8 SERVOS 
//COLOCADO COMO UN ARREGLO

unsigned long HIGH[]={0,0,0,0,0,0,0,0};
unsigned long LOW[] ={0,0,0,0,0,0,0,0};

void config(void){

        output_a(0x00);
        output_b(0x00);
        set_tris_a(0xA0);
        set_tris_b(0x02);
        output_bit(PIN_B3,1);
        setup_comparator(NC_NC_NC_NC);            //Comparadores APAGADO
        setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); //Tick de 0.0002ms
        set_timer1(tick);
        disable_interrupts(INT_TIMER1);
        disable_interrupts(INT_RDA);
        disable_interrupts(GLOBAL);
}

#INT_TIMER1
void Interrupcion_timer1(void){

        if(LAHL==1){                    //SI ES PARA EL TIEMPO ALTO? ENTRA
            bit_set(*PUERTO,SERVO);        //ESTABLECE EL PIN A PRENDER
            tick=HIGH[SERVO];            //TOMA LOS TICK NECESARIOS PARA TIEMPO EN ALTO
            LAHL=0;                        //LO CAMBIA PARA EL TIEMPO BAJO
        }else if(LAHL==0){                //SI ES PARA EL TIEMPO BAJO? ENTRA
            bit_clear(*PUERTO,SERVO);    //PONE A BAJO EL PIN QUE CORRESPONDE
            SERVO++;                    //INCREMENTA PARA SIGUIENTE SERVO
            if(SERVO>=4){                //HA TERMINADO EN EL PUERTO A?
                if(SERVO>=4 && PUERTO==5){ //CAMBIA AL PUERTO B, Y ENCIENDE EL PIN 4
                    PUERTO=6;
                    SERVO=4;
                }else if(SERVO>=8 && PUERTO==6){ //HA LLEGADO EL LIMITE DEL PUERTO B
                    PUERTO=5;            //CAMBIA EL PUERTO A
                    SERVO=0;            //Y EMPIEZA EL CICLO DESDE EL PIN CERO 
                }
        }
            tick=LOW[SERVO];            //TOMA EL TICK PARA EL TIEMPO BAJO
            LAHL=1;                        //LO CAMBIA PARA EL TIEMPO ALTO
        }    
        set_timer1(tick);                //ESTABLECE EL TIMER PARA MANTENER EL PUSLO ALTO
                                        //O BAJO PARA EL PIN QUE CORRESPONDA
}


#INT_RDA
void Interrupcion_X_recepcion(void){

        disable_interrupts(INT_TIMER1);//DESACTIVA EL TIMER 1
        if(kbhit()){                    //HAY INFORMACION A CAPTAR
            NSERVO=getc();                //1ER BYTE PARA EL NUMERO DEL SERVO
            POSICION=getc();            //2DO BYTE PARA LA POSICION
        }
        FLAG=1;    //ESTE PARAMETRO TE INDICA QUE SE A EFECTUADO UN CAMBIO EN UN DE LOS
                //SERVOMOTORES
        set_timer1(get_timer1());        //CUANDO SE SALIO DE LA RUTINASE QUEDO CON UN
        enable_interrupts(INT_TIMER1);    //CIERTO VALOR EL TIMER 1, ENTONCES LO TOMAMOS 
}                                        //PARA QUE SIGA DONDE SE QUEDO...

void main(void){

        config();
        ON=getc();
        if(ON=='E'){
            printf("----Control de Servomotores----\r\n");
            printf("Version 1.0\r\n");
            printf("Contacto: george.manson.69@gmail.com\r\n");
            printf("Window XP SP3\r\n");
            printf("\r\n");
            printf("Inicializar Servos:\r\n");
            for(i=0;i<=7;i++){
                printf("SERVO %u: ",i);
                POSICION=getc();
                printf("%Lu Grados \r\n",POSICION);
                AUX=(POSICION*34)+4400; //AQUI OBTIENES LOS TICK'S                    
                AUXH=65536-AUX;             //AQUI OBTIENES EL TIEMPO EN ALTO        
                HIGH[i]=AUXH;        //ACTUALIZA EL SERVO SELECCIONADO
                AUX=12500-AUX;            //2.5ms - (TIEMPO TRANSCURRIDO EN ALTO)
                AUXL=65536-AUX;            //AQUI OBTIENES EL TIEMPO BAJO
                LOW[i]=AUXL;        //ACTUALIZAS SERVO SELECCIONADO
            }
            output_bit(PIN_B0,1);
            output_bit(PIN_B3,0);
            enable_interrupts(GLOBAL);
            enable_interrupts(INT_TIMER1);
            enable_interrupts(INT_RDA);
        }

        while(TRUE){
            if(FLAG==1){
                Printf("SERVO %u: %Lu Grados...\r\n",NSERVO,POSICION);
                disable_interrupts(INT_RDA);
                AUX=(POSICION*34)+4400; //AQUI OBTIENES LOS TICK'S                    
                AUXH=65536-AUX;             //AQUI OBTIENES EL TIEMPO EN ALTO        
                HIGH[NSERVO]=AUXH;        //ACTUALIZA EL SERVO SELECCIONADO
                AUX=12500-AUX;            //2.5ms - (TIEMPO TRANSCURRIDO EN ALTO)
                AUXL=65536-AUX;            //AQUI OBTIENES EL TIEMPO BAJO
                LOW[NSERVO]=AUXL;        //ACTUALIZAS SERVO SELECCIONADO
                FLAG=0;
                enable_interrupts(INT_RDA);
            }
        };
}
```


La explicacion es muy simple, conectamos el cirucito al serial por medio del Max232,
abrimos el archivo de CONTROL DE 8 SERVOS.exe entonces buscamos el COM en donde esta conectado y presionamos CONECTAR, aparacera un menu y luego nos pedira inicializar donde dice el INICIALIZADOR ahi movemos la barra para cada servo que, cuando completemos los 8 servos, los servos se posicionara en lo que se puso en el inicializador, y luego ya podremos controlarlos uno por uno con las barras respectivas.

Yo lo probe fisicamente y funciono correctamanete.

Espero que les guste...y Esperen mas proyectos mas complejos!!!


----------



## mecatrodatos (Dic 13, 2009)

Esta interesante tu post pero tengo una duda a ver si me puedes colaborar as oido del compilador FED C es que necesito realizar control de dipositivos de temperatura y me recomendaron este compilador.


----------



## george.manson.69 (Dic 13, 2009)

mecatrodatos dijo:


> Esta interesante tu post pero tengo una duda a ver si me puedes colaborar as oido del compilador FED C es que necesito realizar control de dipositivos de temperatura y me recomendaron este compilador.




Lo estare viendo...pero acabo de ver esta pagina que hbala sobre un WIZ C es ese que quieres utilizar?


----------



## mecatrodatos (Dic 13, 2009)

si ese es un amigo que lo maneja dice que tiene excelentes prestacion como si estuvieran unidos el proteus , niple el asm y el compilador porque se puede ver todo y simularlo a la vez


----------



## george.manson.69 (Dic 13, 2009)

mecatrodatos dijo:


> si ese es un amigo que lo maneja dice que tiene excelentes prestacion como si estuvieran unidos el proteus , niple el asm y el compilador porque se puede ver todo y simularlo a la vez




Ok estare usandolo..para aprenderle...estoy viendo que esta facil prormarlo...solo le falta las librerias...bueno algunas...pero Que es mejor WIZ-C o CCS C? Cual e la primarodial diferencia?


----------



## mecatrodatos (Dic 13, 2009)

Mira he utilizado el mkro c y el ccs compiler pero cuando vi como se realizaban proyectos con el FED C me asombre por el programa cuando un amigo utilizo una pantalla grafica y hay estaba la libreria y el elemento propiamente dicho y en cuestion de minutos la hizo funcionar pero toda la informacion que me sumistro esta en ingles con eso te dijo que es un lenguaje dealto nivel mas aplicado al usuario., pero el entorno de la programacion es en C.

te agregare com amigo para tratar este tema y no darle otro camino a tu hilo


----------



## COSMICO (Dic 15, 2009)

soy nuevo en esto,,
me he bajado el compilador pic c compiler con muchos ejemplos..
pero de c solo se que nada se..
me gustaria aprender paso por paso,,si alguien tiene un tuto, que detalle instrucciones y su uso con ejemplos 
por favor hagamelo llegar..
Gracias desde ya a todos los amigos del foro..


----------



## dynamco (Dic 15, 2009)

que raro che deberia funcionar,cualquier cosita muchachos si necesitan mas codigos yo tengo mas secuenciadores


----------



## george.manson.69 (Dic 17, 2009)

Aqui les traigo un manual para conocer ¿Como funciona un servo?
Desde como manejarlo, hasta la simulacion y creacion de programa en Visual C#
Espero que les guste!!!


----------



## mecatrodatos (Dic 17, 2009)

Esta bien explicado gracias


----------



## COSMICO (Dic 18, 2009)

Esta muy bueno esto!! gracias,,


----------



## george.manson.69 (Dic 18, 2009)

Bueno antes de que termine el año!!!, aqui les traigo un control de 5 servomotores que puden grabar maximo de 2 a 9 posiciones para cada servo.


Como funciona:
1.-Abrimos el programa de CONTROL DE SERVOS V1,1 BETA
2.-Creamos dos puertos virtuales con "virual serial port" y despues conectamos nuestro programita antes de simular en proteus.
3.-Al estar conectado, ya podemos ponerle play en proteus
4.-Nos pedira la inicializacion de los servos, es hara que los servos se establesza en un lugar al iniciar.
5.-Nos pedira despues si queremos controlarlos manualmente, o queremos grabar las posiciones de los servos. Hay dos boton que dicen "REC" O "MANUAL" ahi responderemos. Si queremos manual los servos ESPERARAN la senal para que gire a los grados que queremos.
Si queremos grabar servos:
Al presionar "REC" los servos se posicionaran en el lugar indicado(donde se inicializaron los servos),
Empezamos a mover los servos siempre y cuando no sea la misma posicion, ya que no se grabara, tambien se debe de acalarar que es preferible empezar a grabar de 0 a 4 y luego otra vez de 0 a 4 y asi las veces que allas puesto que grabara en el codigo.
Porque al inciar los servos empezara por decirlo asi por rondas, por ejemplo en la primera ronda de 0 a 4, se graba algo inicia, ahi lo grabado y luego la segunda ronda empieza de 0 a 4 y asi.
Si tiene alguna duda como mucho gusto aqui andamos...!!!

```
////////////////////////////////////////////////////////////////////
//TITULO: CONTROL DE 5 SERVOMOTORES CON GRABAMIENTO DE-       //////
//    POSICION PARA HITEC O PARECIDO       //////
//AUTOR: JORGE ARTURO RODRIGUEZ HERNANDEZ       //////
//FECHA: 11-12-09             //////
//DESCRIPCION: POR MEDIO DEL PROGRAMA CONTROL DE 5 SERVOS.EXE //////
//      CONTROLARAS POR MEDIO DE BARRAS QUE TE INDICARA//////
//      EL GRADO Y EL SERVO A CONTROLAR.               //////
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
#include<16F886.H>
#fuses HS,NOWDT,NOLVP,MCLR,NOPROTECT
//HS: CRISTAL DE HIGH SPEED 20MHZ
//NOWDT: NO SE UTILIZA EL PERRO GUARDIAN
//NOLVP: SE DESACTIVA ESTA OPCION DE PROGRAMACION
//MCLR:ACTIVAMOS EL MASTER CLEAN
//NOPROTECT: NO SE PROTEGE EL CODIGO()
#use delay(clock=20000000)   //CRISTAL DE 20MHZ
#use rs232(uart1,baud=2400)   //PIN_C7->RX,PIN_C6->TX
#use fast_io(C)      //RAPIDA INTERVENCION DEL PUERTO C
#priority timer1,rda    //Es mas primordial que se atienda la interrupcion
         //en el timer1
//VARIABLES A CONTROLAR
unsigned long tick;   //E
unsigned int SERVO=0;  //ES EL NUMERO DEL SERVO A CONTRLAR MAXIMO CONTAR DE 0 A 4
unsigned int PUERTO=7;  //SOLO PARA EL PUERTO C
unsigned long AUX,AUXH,AUXL;//AUXILIARES PARA OPERACIONES
unsigned int NSERVO=0;  //NUMERO DE SERVO SELECCIONADO
unsigned long POSICION=180; //0 - 180 grados maximo
unsigned int Respuesta;  //RESPUESTA DE LO QUE SE QUIERE HACER G o M
unsigned int x=0;   //INDICA COLUMNAS
unsigned int PULSO;   //TE INDICA EL TIEMPO QUE TIENE QUE ESPERAR PARA CAMBIAR DE POSICION
short SW=0;     //ACTIVA LA REPRODUCCION DE LO QUE SE GRABO
short LAHL=1;    // SOLO AQUI HACES EL SWITCHEO CUANDO ESTA ALTO O BAJO
short FLAG=0;    //ACTUALIZADOR
//VARIABLE DE CONTROL DE PULSO DE ALTO Y BAJO PARA LOS 5 SERVOS 
//COLOCADO COMO UN ARREGLO
unsigned long HIGH[]={0,0,0,0,0};  //ARREGLO PARA GUARDAR LA POSICION EN TIEMPO ALTO
unsigned long LOW[] ={0,0,0,0,0}; //ARREGLO PARA GUARDAR LA POSICION EN TIEMPO BAJO
//MAXIMO DE MEMORIA PARA GRABAR PARA CADA SERVO
unsigned int s[]={0,0,0,0,0};  //ARREGLO PARA GRABAR LAS POSICIONES DE LOS SERVOS
//VARIABLE QUE GUARDA LAS POSICIONES DE LOS SERVOS
unsigned long INH[4]={};   //ARREGLO DE VARIABLES DE INICIALIZADOR
unsigned long INL[4] ={};   //------------------------------------
unsigned long TEMPH[4]={};   //ARREGLO TEMPORAL PARA ALTO
unsigned long TEMPL[4]={};   //--------------------- BAJO
//SI SE DESEA CAMBIAR EL 9 PARA QUE SEA MENOS PASOS A GRABAR 
unsigned long SERVOH[5][4];   //MATRIZ DONDE SE PIENSA GUARDAR TODAS LAS POSICONES DE CADA SERVO ALTO
unsigned long SERVOL[5][4];   //---------------------------------------------------------------- BAJO
//FUNCION DE CONFIGURACION DEL MICROCONTROLADOR
void config(void){
  set_tris_a(0x01);
  set_tris_c(0x80);      //1000 0000
  setup_adc(ADC_OFF);      //CONVERTIDOR ANALOGO-DIGITAL APAGADO
  setup_comparator(NC_NC_NC_NC);   //Comparadores APAGADO
  setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); //Tick de 0.0002ms
  set_timer1(tick);
  disable_interrupts(GLOBAL);
  enable_interrupts(INT_TIMER1);
  enable_interrupts(INT_RDA);
}
//INTERRUPCION EN EL TIMER 1, DEPENDE DE LO QUE SE ALLA CARGADO EN EL TIMER1
#INT_TIMER1
void Interrupcion_timer1(void){
  if(LAHL==1){     //SI ES PARA EL TIEMPO ALTO? ENTRA
   bit_set(*PUERTO,SERVO);  //ESTABLECE EL PIN A PRENDER
   tick=HIGH[SERVO];   //TOMA LOS TICK NECESARIOS PARA TIEMPO EN ALTO
   LAHL=0;      //LO CAMBIA PARA EL TIEMPO BAJO
  }else if(LAHL==0){    //SI ES PARA EL TIEMPO BAJO? ENTRA
   bit_clear(*PUERTO,SERVO); //PONE A BAJO EL PIN QUE CORRESPONDE
   SERVO++;     //INCREMENTA PARA SIGUIENTE SERVO
   if(SERVO>=5){    //HA TERMINADO EN EL PUERTO A?
    SERVO=0;    //EMPIEZA OTRA VEZ
    if(SW==1){    //EMPEZAR EL MOVIMIENTO GUARDADO
     PULSO++;   //INCREMENTA VARIABLE
     if(PULSO==75){  //HA LLEGADO A 75 PULSOS?
      disable_interrupts(GLOBAL);//APAGAMOS TEMPORALEMNTE LAS INTERRUPTIONES
     }
    }
   }
   tick=LOW[SERVO];   //TOMA EL TICK PARA EL TIEMPO BAJO
   LAHL=1;      //LO CAMBIA PARA EL TIEMPO ALTO     
  }
  set_timer1(tick);    //ESTABLECE EL TIMER PARA MANTENER EL PUSLO ALTO
          //O BAJO PARA EL PIN QUE CORRESPONDA
}
//INTERRUPCION DE RECEPCION
#INT_RDA
void Interrupcion_X_recepcion(void){
  disable_interrupts(INT_TIMER1);//DESACTIVA EL TIMER 1
  if(kbhit()){     //HAY INFORMACION A CAPTAR
   NSERVO=getc();    //1ER BYTE PARA EL NUMERO DEL SERVO
   POSICION=getc();   //2DO BYTE PARA LA POSICION
  }
  FLAG=1; //ESTE PARAMETRO TE INDICA QUE SE A EFECTUADO UN CAMBIO EN UN DE LOS
    //SERVOMOTORES
  set_timer1(get_timer1());  //CUANDO SE SALIO DE LA RUTINASE QUEDO CON UN
  enable_interrupts(INT_TIMER1); //CIERTO VALOR EL TIMER 1, ENTONCES LO TOMAMOS 
}          //PARA QUE SIGA DONDE SE QUEDO...
//PONE EN LA POSICION DEL INICIALIZADOR
void PUNTO_DE_INICIO(void){
  for(NSERVO=0;NSERVO<=4;NSERVO++){
   HIGH[NSERVO]=INH[NSERVO]; //AGARRA LOS VALORES ALTOS DE CADA SERVO
   LOW[NSERVO]=INL[NSERVO];  //AGARRA LOS VALORES BAJOS DE CADA SERVO
  }
}
//ACEPTO LO DE MANEJAR SERVOS MANUALMENTE
void MANUAL(void){
  enable_interrupts(GLOBAL);
  while(TRUE){
   if(FLAG==1){
    Printf("SERVO %u: %Lu Grados...\r\n",NSERVO,POSICION);
    disable_interrupts(INT_RDA);
    AUX=(POSICION*34)+4400; //AQUI OBTIENES LOS TICK'S     
    AUXH=65536-AUX;    //AQUI OBTIENES EL TIEMPO EN ALTO  
    HIGH[NSERVO]=AUXH;  //ACTUALIZA EL SERVO SELECCIONADO
    AUX=20000-AUX;   //2.5ms - (TIEMPO TRANSCURRIDO EN ALTO)
    AUXL=65536-AUX;   //AQUI OBTIENES EL TIEMPO BAJO
    LOW[NSERVO]=AUXL;  //ACTUALIZAS SERVO SELECCIONADO
    FLAG=0;
    enable_interrupts(INT_RDA);
   }
  }
}
//ACEPTO GRABAR SERVOS
void GRABAR(void){
  enable_interrupts(GLOBAL);
  while(TRUE){
    if(FLAG==1){
    Printf("SERVO %u: %Lu Grados...\r\n",NSERVO,POSICION);
    disable_interrupts(INT_RDA);
    AUX=(POSICION*34)+4400; //AQUI OBTIENES LOS TICK'S     
    AUXH=65536-AUX;    //AQUI OBTIENES EL TIEMPO EN ALTO  
    HIGH[NSERVO]=AUXH;  //ACTUALIZA EL SERVO SELECCIONADO
 
    AUX=20000-AUX;   //4ms - (TIEMPO TRANSCURRIDO EN ALTO)
    AUXL=65536-AUX;   //AQUI OBTIENES EL TIEMPO BAJO
    LOW[NSERVO]=AUXL;  //ACTUALIZAS SERVO SELECCIONADO
    if(s[NSERVO]==5){  //MAXIMO A GRABAR 9 POSICIONES DE CADA SERVO 
          //(Depende si se cambio en la matriz de SERVOH,SERVOL)
     printf("SERVO [%u]; Maximo de grabado\r\n",NSERVO);
    }
    else if(HIGH[NSERVO]!=TEMPH[NSERVO] && LOW[NSERVO]!=TEMPL[NSERVO]){//A CAMBIADO LA POSICION?
     SERVOH[s[NSERVO]][NSERVO]=HIGH[NSERVO];         //SE GUARDA EL TIEMPO ALTO
     SERVOL[s[NSERVO]][NSERVO]=LOW[NSERVO];         //------------------- BAJO
     printf("SERVO[%u]; %u grabado(s)\r\n",NSERVO,s[NSERVO]+1);
     s[NSERVO]++;  //INCREMENTA EL LIMITE DE CADA SERVO
    }
    FLAG=0;     //ESPERA OTRA VEZ SI SE HA RESIVIDO UN CAMBIO EN LOS SERVOS
    TEMPH[NSERVO]=HIGH[NSERVO]; //SE GUARDA TEMPORALMENTE EL TIEMPO ALTO DEL SERVO CORRESPONDIENTE
    TEMPL[NSERVO]=LOW[NSERVO]; //----------------------------------------------------------------
    if(s[0]==5 && s[1]==5 && s[2]==5 && s[3]==5 && s[4]==5){//MAXIMO DE GRABAR 5 SERVOS (TAMBIEN,
                  //SE CAMBIA LOS PARAMETROS DEPENDE
                  //SI CAMBIO SERVOH Y SERVOL
     printf("SE GRABO TODOS LOS PASOS\r\n");
     printf("DESEA EMPEZAR LO GRABADO? \r\n");
     while(!input(PIN_A0)); //NECESITAMOS PRESIONAR EL PUSH PARA EMPEZAR
     SW=1;
PUNTO_INICIO:
     printf("SE REINICIO LA POSICION DE LOS SERVOS\r\n");
     PULSO=0;
     x=0;
     while(TRUE){
      if(PULSO>=75){
       for(NSERVO=0;NSERVO<=4;NSERVO++){ //ACTUALIZA PARA EL PRIMER MOVIMIENTO
        HIGH[NSERVO]=SERVOH[x][NSERVO]; //ALTO
        LOW[NSERVO]=SERVOL[x][NSERVO];  //BAJO
       }
       set_timer1(get_timer1());
       enable_interrupts(GLOBAL);
       PULSO=1;
       x++;
       if(x>=5){  //HA LLEGADO AL LIMITE DONDE SE GRABO LOS SERVOS//TMB CAMBIA ESTE
           //PARAMETRO SI SE CAMBIO SERVOH Y SERVOL
        goto PUNTO_INICIO;    //OTRA VEZ
       }
      }
 
     }
    }
    enable_interrupts(INT_RDA);
   }
  } 
}
//MENU PRINCIPAL
void main(void){
  config();
  printf("INILIZAR SERVOS\r\n");
  for(NSERVO=0;NSERVO<=4;NSERVO++){
   printf("SERVO[%u]; ",NSERVO); 
   POSICION=getc(); 
   printf("%Lu grados...\r\n",POSICION);
   AUX=(POSICION*34)+4400; //AQUI OBTIENES LOS TICK'S     
   AUXH=65536-AUX;    //AQUI OBTIENES EL TIEMPO EN ALTO  
   INH[NSERVO]=AUXH;  //ACTUALIZA EL SERVO SELECCIONADO
   AUX=20000-AUX;   //2.5ms - (TIEMPO TRANSCURRIDO EN ALTO)
   AUXL=65536-AUX;   //AQUI OBTIENES EL TIEMPO BAJO
   INL[NSERVO]=AUXL;  //ACTUALIZAS SERVO SELECCIONADO
  }
  PUNTO_DE_INICIO();
  printf("Desea Grabar Servos? (REC)\r\n");
  printf("Desea Manipular Servos Manualmente? (MANUAL)\r\n");
RESPUESTA:
  printf("R= ");
  Respuesta=getc();
  switch (Respuesta){
   case 'G': printf("REC\r\n"); GRABAR();break;
   case 'M': printf("MANUAL\r\n");MANUAL(); break;
   default: printf("Intente otra vez\r\n"); goto RESPUESTA;
  }
}
```
 

El archivo de abajo tiene una imagen y la simulacion en proteus el programa necesario para controlarlo.
**Nota: Si no se abre, podria ser su version ya que estoy usando proteus 7.5 Sp3*
*si tienen uno mas abajo no creo que se abra...!*


----------



## Vegetal Digital (Dic 19, 2009)

> este programa es muy simple lo hice en c#, es un control de 8 led's, en pocas palabras manipulas 1 byte(8bit) y lo mandas al pic...



Hola, me podrías dar los programas que creaste en C# en ese ejemplo? Lo posteaste en la página 2.


----------



## george.manson.69 (Dic 20, 2009)

Claro..aqui estan...ahi viene todo. No se podian abrir? O que paso?


----------



## Vegetal Digital (Dic 21, 2009)

Yo me refería al programa que va en la computadora, el software que esta hecho en C#. 
gracias por tu tiempo.


----------



## gothikmarko (Dic 22, 2009)

que tal george muy buenos ejemplos me han ayudado mucho a comprender este lenguaje para pics

ahora tengo una pequeña duda que espero me puedas resolver, quiero hacer una matriz de leds pero con la informacion de las letras guardada en una 24lc256, lo que necesito es saber si la libreria que utilizas en un ejemplo anterior (24256.c) funciona en pics que no manejan i2c por hardware como el 16f84a y si es asi me la puedes pasar ya que no la encuentro entre los archivos del ccs que tengo instalado.

gracias y espero tu respuesta


----------



## COSMICO (Dic 22, 2009)

Nos estas tomando del pelo?
Esos codigos funcionan bien!!!!!!!!!!!
Saludos


----------



## edusolano (Dic 28, 2009)

Hola, estoy intentando compilar codigo desde mplab 8.4 en CCS, pero cuando le doy al boton de "build all" o "make project" se me abre el compilador PCWHD. Esto es normal o se puede compilar en mplab?
En qualquier caso, me dijeron que tenia que usar mplab porque al programar el micro seria mas facil hacerlo con el mplab. Una vez creado el *.hex se puede usar el mplab para programar el mico?. A ver si pueden ayudarme gracias.


----------



## COSMICO (Dic 28, 2009)

Desde el entorno CCs puedes compilar tu programa,perfectamente,
Aunque;si con mplab usando un plugins...deberias poder utilizarlo sin problem..
Pero es igual de facil con el CCs directo..
Despues si tienes picstar o pickit, solo debes importar el .HEx desde mplab..y listo
El CC s compila y te genera .HEX y el cof..
Suerte..


----------



## PantroPKL (Dic 29, 2009)

george.manson.69 dijo:


> bueno aqui esta lo prometido...jeje...este pequeño programa esta en forma de control.
> se dara un archivo para word, donde viene explicado el programa.
> y se dara el programa.



hola, revise tu proyecto y esta muy interesanre, pero como me falta un poco de experiencia en programacion quisiera a ver si me puedes mandar el codigo fuente del este progama, y que compilador usaste? te lo agradeceria mucho, mi mail 
NoLeíLasPolíticasDelForoYPorEsoMeEditaronElMensaje@ForosDeElectrónica.Com


----------



## george.manson.69 (Dic 29, 2009)

PantroPKL dijo:


> hola, revise tu proyecto y esta muy interesanre, pero como me falta un poco de experiencia en programacion quisiera a ver si me puedes mandar el codigo fuente del este progama, y que compilador usaste? te lo agradeceria mucho, mi mail
> NoLeíLasPolíticasDelForoYPorEsoMeEditaronElMensaje@ForosDeElectrónica.Com



Use el compilador CCS C compiler....para mayor infrmacion pedes acceder a su paginas..
www.ccsinfo.com 
o busca informacion en google...hay un monton de info en google...
a que te refieres con el codigo fuente....el archivo .hex?


----------



## PantroPKL (Dic 31, 2009)

primero programamaste en ccs, ese archivo esta en .c , despues compilaste y te resulto un archivo .hex, el codigo al que me refiero es el programa antes de compilar pero en visual, con el cual mandas los comandos para el transmisor, ese es el codigo que me gustaria revisar....
^_^


----------



## george.manson.69 (Ene 2, 2010)

PantroPKL dijo:


> primero programamaste en ccs, ese archivo esta en .c , despues compilaste y te resulto un archivo .hex, el codigo al que me refiero es el programa antes de compilar pero en visual, con el cual mandas los comandos para el transmisor, ese es el codigo que me gustaria revisar....
> ^_^


 
ok ok!!! bueno deja cheko en mis documentos si es que un tengo la hoja de proyecto donde esta escrito el codigo.
mañana sin falta te lo envio...ok!



PantroPKL dijo:


> primero programamaste en ccs, ese archivo esta en .c , despues compilaste y te resulto un archivo .hex, el codigo al que me refiero es el programa antes de compilar pero en visual, con el cual mandas los comandos para el transmisor, ese es el codigo que me gustaria revisar....
> ^_^



Te mando el codigo fuente del control!!!

Espero que te ayude

Bueno Subo un buen manual para quienes ya entraron al mundo de programacion en C. Contiene en otro archivo .zip las simulaciones.

Y tambien subo un programa que recien he hecho que es un OSCILOSCOPIO via232, con una entrada analoga mides el voltaje y te lo proyecta a una grafica.

Al bajar el archivo contiene un texto para saber como funciona y con su respectivo codigo del Micro. Espero que les funciones ya que yo lo probe fisicamente y funciona al 99.99% ya que nada es perfecto en la vida.


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;Enviar datos
//DATE:28/AGOSTO/'09
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16F886.h>
#device ADC=10
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=8000000)
#use rs232(uart1,baud=2400)

float VALOR;
float VOLTAJE;

void config(void){
    set_tris_a(0x01);
    set_tris_c(0x80);
    setup_adc(ADC_CLOCK_INTERNAL|VSS_VDD);
    setup_adc_ports(sAN0);
    setup_comparator(NC_NC_NC_NC);
}

void main(void){
    config();

    do{
        delay_ms(10);
        VALOR=read_adc();
        VOLTAJE=(VALOR*5)/1023; //Transformamos a volatge
        printf("%.3f\n",VOLTAJE);
    }while(TRUE);
}
```


----------



## george.manson.69 (Ene 10, 2010)

Este es un manual para aquellos que quieren hacer aplicaciones por USB modo BULK transfer te menciona paso por paso para la contruccion de software en C# 2008.

Ademas un extra agrego. uin CALCULADOR DE TIMERS.

este programa te ayuda a calcular los timer0,1,2 para pic10/12/16/18
aveces necesitamos calcular el timer para cada cuando quiere que se produsca una interrupcion y todo lo demas...

espero que les ayude...

<------------------------------Espero sus comentarios-------------------------->


----------



## Pablet (Ene 25, 2010)

hola!! yo programo en c18 pics 18 pero ahora quiero programar pic12 y 16 en c, y queria saber si con el ccs puedo programar tambien por registros, es decir, configurar los registros adcon adcon1 etc, es que todos los programas que he visto lo hacen con instrucciones que no conozco y que realmente no se lo que se ejecuta por detras. . .  y tambien me podria evitar los fuses haciendolo como en c18, con los #pragma config que es al fin y al cabo como esta en el datasheet!! gracias!!


----------



## george.manson.69 (Ene 25, 2010)

Pablet dijo:


> hola!! yo programo en c18 pics 18 pero ahora quiero programar pic12 y 16 en c, y queria saber si con el ccs puedo programar tambien por registros, es decir, configurar los registros adcon adcon1 etc, es que todos los programas que he visto lo hacen con instrucciones que no conozco y que realmente no se lo que se ejecuta por detras. . .  y tambien me podria evitar los fuses haciendolo como en c18, con los #pragma config que es al fin y al cabo como esta en el datasheet!! gracias!!



debes de usar esto:

#byte TRISB=0x86 
#byte PORTB=0x06

entonces despues del main:

void main(void){
TRISB=0x00; //TODAS SALIDAS
PORTB=0x00;
}
y asi...solo hay definirlos  con #byte al principio del programa


----------



## Pablet (Ene 25, 2010)

tengo que definir la direccion de cada registro¿?¿?¿? eso no lo hace la libreria que declaro?


----------



## george.manson.69 (Ene 26, 2010)

el archivo 
#include¨16F628A.H¨  // POR EJEMPLO

esa no viene los registros como tu te lo sabes, sino viene por ejemplo
en lugar de TRISB.

viene SET_TRIS_B(0x00); que es igual a TRISB=0x00;

pero debes de definir el TRISB ve como te explique arriba


----------



## COSMICO (Ene 26, 2010)

george.manson.69.
FELICITACIONES POR TU TRABAJA Y APORTES.
Quisiera preguntarte, estoy trabajando usb en modo HID, con algunos ejemplos de C CCS.
Pero solo logro que al oprimir determinada letra me envie algun mensaje al terminal virtual..
Quiero hacerlo trabajar en modo eco, que reciba los caracteres y los 
imprima directamente al terminal.Como te digo soy nuevo en esto, si pudieras ayudarme 
te lo agradeceria...

Amigo george.manson.69.
Exelente labor..
Este foro me agrada mucho..
Felicitaciones de nuevo, este es el lugar para aprender..

george.manson.69.
estoy tratando de simular tus ejemplos de usb,,pero no funcionan en mi pc..
abren los ejecutables arranca la simulacion, pero no logro integrar, por ejemplo
el terminal virtual del sensor de temperatura para que muestre los valores 
leidos desde la simulacion..
AYUUUUDAA POR FAVOR.


----------



## caponero (Ene 27, 2010)

Muy bueno el post amigo me sirve de mucho es excelente


----------



## george.manson.69 (Ene 28, 2010)

COSMICO dijo:


> george.manson.69.
> FELICITACIONES POR TU TRABAJA Y APORTES.
> Quisiera preguntarte, estoy trabajando usb en modo HID, con algunos ejemplos de C CCS.
> Pero solo logro que al oprimir determinada letra me envie algun mensaje al terminal virtual..
> ...


 
Acual es el programa exactamente es el que estas usando(osea el que bajaste de aqui). Esque tengo varios de USB de temperatura y no se cual sera...si puedes decirme cual es!! para poder ayudarte...

Nota los programas pueden funciar pefectamente de Window Xp.
Mientras el programa que contiene el Micro...los he calado y me han funcionado de maravilla...asegurate que funcione bien al conectar el USB a la compu que te lo detecte.



caponero dijo:


> Muy bueno el post amigo me sirve de mucho es excelente


 

Gracias caponero!!! y espera mas proyectos, en este caso se termino la comunicacion serial va hacer proyectos con USB en modo BULK TRANSFER...
y otra vez gracias..y saludos!!!


----------



## COSMICO (Ene 28, 2010)

george.manson.69 dijo:


> Acual es el programa exactamente es el que estas usando(osea el que bajaste de aqui). Esque tengo varios de USB de temperatura y no se cual sera...si puedes decirme cual es!! para poder ayudarte...
> 
> Nota los programas pueden funciar pefectamente de Window Xp.
> Mientras el programa que contiene el Micro...los he calado y me han funcionado de maravilla...asegurate que funcione bien al conectar el USB a la compu que te lo detecte.
> ...



El programa es aquel, en el cual se digita la tecla "a" o "x" y sale el mensaje respectivo
lo que yo quiero es que al oprimir cualquier tecla se vea reflejada en la terminal virtual.
como trabajar el rs232 en modo eco,pero con el usb.., gracias por tu ayuda.


----------



## COSMICO (Feb 2, 2010)

Ya pude resolver lo de la simulacion de los circuitos en proteus.
Casi me saco un ojo con eso..
solo fue reinstalar las librerias usb de proteus, algo por ahy me estaba fallando.


----------



## COSMICO (Feb 8, 2010)

Amigo george..
A proposito de tu CURSO DE MCU Y PROTEUS,,
Trate como propones de hacer desplazar  la palabra HOLA del pequeño publik que pones como ejemplo de derecha a izquierda, y despues de tanto matarme la cabeza y no lograrlo
decidi cambiar la conexion de las matrices, para que las columnas fueran barridas de derecha a izquierda, segun la perspectiva de vista del monitor de mi pc; y encontre que la letra "L" salia invertida, lo cual me obligo a invertir la posicion de esos bytes en la tabla.
A mi manera de pensar, esa no es la forma; me podrias colaborar con eso y regalandome una explicacion detallada de como funciona el codigo para estas matrices..Te agradesco 
y perdon la molestia..


----------



## george.manson.69 (Feb 10, 2010)

Este pequeña guia solo te menciona como hacer un enlaze en labview para que te detecte la conexion del usb con el VID&PID asignado al micro.
Y como no salirme del tema tambien se encuetra el programa que debe de ir al micro, que es hecho en CCS. cosa que igual al manual de USB  modo bulk transfer.(arriba)



COSMICO dijo:


> Amigo george..
> A proposito de tu CURSO DE MCU Y PROTEUS,,
> Trate como propones de hacer desplazar  la palabra HOLA del pequeño publik que pones como ejemplo de derecha a izquierda, y despues de tanto matarme la cabeza y no lograrlo
> decidi cambiar la conexion de las matrices, para que las columnas fueran barridas de derecha a izquierda, segun la perspectiva de vista del monitor de mi pc; y encontre que la letra "L" salia invertida, lo cual me obligo a invertir la posicion de esos bytes en la tabla.
> ...



Intentaste poner las palabras al reves por ejemplo:

en el arreglo donde estan las variables que se usan para vizualizar las letras

0x00,0xx00,0x00,0x00//H
0x00,0x00,0x00,0x00//O
0x00,0xx00,0x00,0x00//L
0x00,0x00,0x00,0x00//A

por ejemplo cambia las letras en lugar de que empieze el arreglo de arriba a bajo,
que empieze de abajo a arriba.

0x00,0x00,0x00,0x00//A
0x00,0xx00,0x00,0x00//L
0x00,0x00,0x00,0x00//O
0x00,0xx00,0x00,0x00//H

y cambia el "for" que empieze desde 7 a 0. lo subo despues ya que no traigo nada ahorita sobre el curso de mcu.


----------



## COSMICO (Feb 10, 2010)

george.
Te agradesco y estamos charlando sobre el tema..


----------



## giovamolina (Feb 10, 2010)

Hola george, tengo una inquietud, me gustaría hacer este mismo tipo de comunicacion pero entre un PIC12F629 como transmisor y un PIC16F628A como receptor, ya lo he intentado y no me ha dado resultados... adjunto te mando los codigos que desarrolle con el compilador c ccs y con la ayuda del libro COMPILADOR C CCS Y SIMULADOR PROTEUS PARA MICROCONTROLADORES... Cualquier tipo de ayuda sería de gran aporte, ya que llevo varios días intentándolo...Gracias. La lógica que quiero desarrollar es muy parecida a la que haces en tus ejemplos...


----------



## magdalena (Feb 11, 2010)

Hola a todos disculpen estoy programando una lcd de 4bits en un pic 18f8720 a 20 Mhz en la simulacion me sale correctamente pero en la practica no me sale... quiera ver quien me puede ayudar porque la verdad no encuentro el error... por cierto la patita rw esta a tierra....


----------



## george.manson.69 (Feb 13, 2010)

magdalena dijo:


> Hola a todos disculpen estoy programando una lcd de 4bits en un pic 18f8720 a 20 Mhz en la simulacion me sale correctamente pero en la practica no me sale... quiera ver quien me puede ayudar porque la verdad no encuentro el error... por cierto la patita rw esta a tierra....




sube el diagrama y el programa..para entender mejor la falla.


----------



## magdalena (Feb 13, 2010)

ok pero me dijeron que podia ser por los tiempos ustedes saben algo de eso... como es a 20Mhz o tambien porque no he desactivado alguna funcion que este haciendo ese puerto... agradeceria mucho su ayuda...

aqui esta el .h


```
#include <18F8720.h>
#device adc=8

#FUSES NOWDT                 	//No Watch Dog Timer
#FUSES WDT128                	//Watch Dog Timer uses 1:128 Postscale
#FUSES EC                    	//External clock with CLKOUT
#FUSES NOPROTECT             	//Code not protected from reading
#FUSES NOOSCSEN              	//Oscillator switching is disabled, main oscillator is source
#FUSES BROWNOUT              	//Reset when brownout detected
#FUSES BORV25                	//Brownout reset at 2.5V
#FUSES NOPUT                 	//No Power Up Timer
#FUSES NOCPD                 	//No EE protection
#FUSES STVREN                	//Stack full/underflow will cause reset
#FUSES NODEBUG               	//No Debug mode for ICD
#FUSES LVP                   	//Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT                 	//Program memory not write protected
#FUSES NOWRTD                	//Data EEPROM not write protected
#FUSES NOWAIT                	//Wait selections unavailable for Table Reads or Table Writes
#FUSES MCU                   	//Microcontroller Mode
#FUSES NOWRTC                	//configuration not registers write protected
#FUSES NOWRTB                	//Boot block not write protected
#FUSES NOEBTR                	//Memory not protected from table reads
#FUSES NOEBTRB               	//Boot block not protected from table reads
#FUSES NOCPB                 	//No Boot Block code protection

#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
#use i2c(Master,Fast,sda=PIN_C4,scl=PIN_C3)

aqui esta el .c

#include "D:\Pruebas1\Nueva carpeta\PRUEBALCD.h"
#include "D:\Pruebas1\Nueva carpeta\lcdnuevo.c"


void main()
{
   #byte PORTE=0xF84
   #byte lcd = 0xF84  // Direccion de la estructura "lcd".
//#byte lcd = 9      // Direccion del puerto d

  setup_adc_ports(NO_ANALOGS|VSS_VDD);
   setup_adc(ADC_OFF);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_wdt(WDT_OFF);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_timer_3(T3_DISABLED|T3_DIV_BY_1);
   setup_timer_4(T4_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   
   lcd_init();
      lcd_putc("hola mundo");
   delay_ms(10000);
//Setup_Oscillator parameter not selected from Intr Oscillator Config tab

   // TODO: USER CODE!!

}

aqui esta la libreria lcd

///////////////////////////////////////////////////////////////////////////
// LCD                                   
///////////////////////////////////////////////////////////////////////////
//     E0  RS
//     E1  ENABLE
//     E4  D4
//     E5  D5
//     E6  D6
//     E7  D7
//   (Sin 'RW')
//
// Funciones soportadas:
//                         lcd_init()
//                         lcd_gotoxy( BYTE col, BYTE fila)
//                         lcd_putc( char c)
//                              \f  Clear display                             
//                              \n  Go to start of second line                
//                              \b  Move back one position
//
///////////////////////////////////////////////////////////////////////////
#define use_porte_lcd TRUE  //LCD conectado al puerto b.
//
struct lcd_pin_map {
   BOOLEAN rs;       // RE0
   BOOLEAN enable;   // RE1
   BOOLEAN unused1;  // RE2
   BOOLEAN unused2;  // RE3
   int data : 4;     // RE4-RE7
} lcd;
//
#byte lcd = 0xF84  // Direccion de la estructura "lcd".

#define set_tris_lcd(x) set_tris_e(x)
#define lcd_type 2           // Tipo de LCD: 0=5x7, 1=5x10, 2=2 lineas
#define lcd_line_two 0x40    // Dirección de la LCD RAM para la 2da. linea
//
//Defino la cadena de inicializacion del LCD.
BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
//
//Configuro el estado de cada pin para lectura y escritura:
struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // Escribir.
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // Leer.
//
//Funciones:
BYTE lcd_read_byte() {
      BYTE low,high;
      set_tris_lcd(LCD_READ);
      delay_cycles(1);
      lcd.enable = 1;
      delay_cycles(1);
      high = lcd.data;
      lcd.enable = 0;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(1);
      low = lcd.data;
      lcd.enable = 0;
      set_tris_lcd(LCD_WRITE);
      return( (high<<4) | low);
}
//
void lcd_send_nibble( BYTE n ) {
      lcd.data = n;
      delay_cycles(1);
      lcd.enable = 1;
      delay_us(2);
      lcd.enable = 0;
}
//
void lcd_send_byte( BYTE address, BYTE n ) {
      lcd.rs = 0;
      while ( bit_test(lcd_read_byte(),7) ) ;
      lcd.rs = address;
      delay_cycles(1);
      delay_cycles(1);
      lcd.enable = 0;
      lcd_send_nibble(n >> 4);
      lcd_send_nibble(n & 0xf);
}
//
void lcd_init() {
    BYTE i;
    set_tris_lcd(LCD_WRITE);
    lcd.rs = 0;
    lcd.enable = 0;
    delay_us(180);
    for(i=1;i<=3;++i) {
       lcd_send_nibble(3);
       delay_us(60);
    }
    lcd_send_nibble(2);
    for(i=0;i<=3;++i)
       lcd_send_byte(0,LCD_INIT_STRING[i]);
}
//
void lcd_gotoxy( BYTE x, BYTE y) {
   BYTE address;
   if(y!=1)
     address=lcd_line_two;
   else
     address=0;
     address+=x-1;
     lcd_send_byte(0,0x80|address);
}
//
void lcd_putc( char c) {
   switch (c) {
     case '\f'   : lcd_send_byte(0,1);
                   delay_ms(2);
                                           break;
     case '\n'   : lcd_gotoxy(1,2);        break;
     case '\b'   : lcd_send_byte(0,0x10);  break;
     default     : lcd_send_byte(1,c);     break;
   }
}
```

y aqui esta el esquema... noc como ingresarlo... me sale error... bueno si me pueden ayudar con esto seria chevere... igual esta conectado al puerto e


----------



## Vegetal Digital (Feb 13, 2010)

Proba con un cristal de 4MHz, a mí nunca me andan los lcd con mayor velocidad que esa.
Saludos


----------



## Moyano Jonathan (Feb 13, 2010)

Vegetal Digital que raro lo que vos decis...yo los he puesto a andar a 48Mhz sin ningún drama usando un PIC182550


----------



## magdalena (Feb 14, 2010)

entonces que puedo hacer... ya estoy arta... no encuentro el error... plis que alguien me ayude...


----------



## george.manson.69 (Feb 14, 2010)

magdalena dijo:


> entonces que puedo hacer... ya estoy arta... no encuentro el error... plis que alguien me ayude...



MM yo no veo que en los #fuses halas puesto el HS para que trabaje con un cristal de 20Mhz, y tambien veo que en los fueses esta el WDT activado, aunque lo desactives en main() mejor desactivalo desde los fuses.

He aqui 3 practicas con labview con pic18f2550 con el protocolo USB modo Bulk Transfer. Espero que sea de utilidad. Y por supuesto el Diagramas y programas para el microcontrolador hecho en C.


----------



## magdalena (Feb 14, 2010)

ok gracias.... estoy revisando lo que me has enviado... yo te aviso despues si me ha servido... si por ahi tienen un codigo de una lcd con rw a tierra y funcionando a 20Mhz y me lo proporcionan se los agradeciria mucho... gracias...

ah y no le he puesto HS porque el clock es externo tiene un cristal de 20Mhz... y esta conectado entre la pata OSC1 Y OSC2


----------



## COSMICO (Feb 19, 2010)

george.manson.69.
Recuerdas el favor que te pedi al respecto del pequeño publik .
del curso de mcu..
Me podrias colaborar..???
Gracias amigo..


----------



## george.manson.69 (Feb 22, 2010)

COSMICO dijo:


> george.manson.69.
> Recuerdas el favor que te pedi al respecto del pequeño publik .
> del curso de mcu..
> Me podrias colaborar..???
> Gracias amigo..



Disculpa por la tardansa aqui esta lo que me pedists sobre el publik


----------



## COSMICO (Feb 22, 2010)

Gracias amigo..
Y disculpa el acoso.Estamos en contacto


----------



## myesid (Feb 23, 2010)

george.manson.69 dijo:


> hola ingdenis1 encontre esta liberia de un teclado 4x4 en google...a ver si te sirve!
> 
> 
> ```
> ...


hola george.manson quisiera saber como agregar esa libreria de keypath 4x4 a mi software ccs para asi trabajar mas facilmente podrias explicar el codigo de ejemplo que encontraste


----------



## george.manson.69 (Feb 23, 2010)

myesid dijo:


> hola george.manson quisiera saber como agregar esa libreria de keypath 4x4 a mi software ccs para asi trabajar mas facilmente podrias explicar el codigo de ejemplo que encontraste


 
es facil copia el codigo y pegalo en bloc de notas conla extencion '.c' y grabalo en la carpeta de drivers donde esta ubicado donde esta instado el programa PICC.

y hacer tu programita solo incluye la libreria y listo


----------



## magdalena (Feb 25, 2010)

Hola que tal yo solucione mi problema si alguien necesita el codigo aqui se los dejo... gracias igual por su ayuda... 


```
#define use_porte_lcd TRUE  //LCD conectado al puerto e

struct lcd_pin_map {                 // This structure is overlayed
   BOOLEAN enable;       //MODIFICADA PARA EASYPIC--------------------
   BOOLEAN rs;      //MODIFICADA PARA EASYPIC--------------------
   BOOLEAN unused;  // on to an I/O port to gain
   BOOLEAN unused1;  // access to the LCD pins.
                    // The bits are allocated from
                    // low order up.  ENABLE will
   int   data : 4;  // be pin B3-------------------------
} lcd;

#byte lcd = 0xF84
#define set_tris_lcd(x) set_tris_e(x)

#define lcd_type 2        // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the 2nd line  

byte const LCD_INIT_STRING[4] =
{
 0x28 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots
 0xf,                    // Display on
 1,                      // Clear display
 6                       // Increment cursor
 }; 
//-------------------------------------

struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out

void lcd_send_nibble(byte nibble)
{
   lcd.data = nibble;
   delay_cycles(1);
   lcd.enable = 1;
   delay_us(2);
   lcd.enable = 0;
}
//-----------------------------------

//----------------------------------------

// Send a byte to the LCD.
void lcd_send_byte(byte address, byte n)
{
      lcd.rs = 0;
      delay_us(3000);
      lcd.rs = address;
      delay_cycles(1);
      lcd.enable = 0;
      lcd_send_nibble(n >> 4);
      lcd_send_nibble(n & 0xf);
}
//---------------------------------------

void lcd_init(void)
{
   BYTE i;
   set_tris_lcd(LCD_WRITE);
   lcd.rs = 0;
   lcd.enable = 0;
   delay_ms(50);
   lcd_send_nibble(2);
   delay_ms(5);
   for(i=0;i<=3;++i)
   {
      lcd_send_byte(0,LCD_INIT_STRING[i]);
      delay_ms(5); 
   }
}
//----------------------------
 
void lcd_gotoxy(byte x, byte y)
{
   byte address;
   if(y != 1)
      address = lcd_line_two;
   else
      address=0;
   address += x-1;
   lcd_send_byte(0, 0x80 | address);
}
//-----------------------------

void lcd_putc(char c)
{
   switch(c)
   {
      case '\f':                //limpia pantalla
         lcd_send_byte(0,1);
         delay_ms(2);
         break;
      case '\n':                //cambio de linea
         lcd_gotoxy(1,2);
         break;
      case '\b':                //retrocede 1 caracter
         lcd_send_byte(0,0x10);
         break;
      default:
         lcd_send_byte(1,c);
         break;
   }
}
//------------------------------

void lcd_setcursor_vb(short visible, short blink) 
{
  lcd_send_byte(0, 0xC|(visible<<1)|blink); 
}
```


----------



## Vegetal Digital (Feb 26, 2010)

magdalena dijo:


> Hola que tal yo solucione mi problema si alguien necesita el codigo aqui se los dejo... gracias igual por su ayuda...



¿Cuál era el problema?


----------



## Destripador (Feb 26, 2010)

Hola a todos

estoy programando en Ccs  un 16f877a y la cosa es que necesito leer los bits del puerto E individualmente, tengo conectadas ahi resistencias y botones y de ahi a la fuente, tengo algo como esto


port_e_pullups(TRUE);
set_tris_E=(0b00000111);
if(bit_test(9,1)) 
{
// aqui irian las instrucciones en caso de que se este presionando el boton conectado al pin RE0
}
while(true){}
}

se que estoy haciendo algo mal porque no me sale o no se que me falte o que onda

mucho agradecere su ayuda


----------



## george.manson.69 (Feb 26, 2010)

Destripador dijo:


> Hola a todos
> 
> estoy programando en Ccs  un 16f877a y la cosa es que necesito leer los bits del puerto E individualmente, tengo conectadas ahi resistencias y botones y de ahi a la fuente, tengo algo como esto
> 
> ...



usa la logica de switch case:

por ejemplo 


```
x=input_a() & 0b00000111; //Tomo solo los tres switches

switch(x){
case 0: //sentencia
case 1: //sentecnia
case ....
case 7: //ya que los tres interruptores toman un valor decimal de 7 cuando estan conectados los tres interruptores

}
```


----------



## Vegetal Digital (Feb 26, 2010)

hay varias formas yo nunca use la instrucción bit_test pero te muestro estas otras alternativas:


```
if(INPUT(PIN_E0))
{
//insertar aqui código

}
```

o definis una variable:


```
while(TRUE)
{
pulsador=INPUT(PIN_E0);
if(pulsador==1)
{
//inserte aqui codigo
}
}
```


o le das un nombre al pin

```
#bit BOTON = PORTE.0

if(BOTON)
{
//inserte aquí su codigo
}
```

La última es la mas cómoda, espero te sirva


----------



## COSMICO (Feb 26, 2010)

Estaba por sugerirte lo mismo que el amigo
Vegetal Digital, pero creo que ya tienes suficientes ejemplos..
La verdad tampoco uso esta sentencia para leer puertos 
Mas bien a nivel de bits, con if, o con la sentencia switch case, como sugiere otro amigo en el foro..


----------



## Destripador (Feb 26, 2010)

gracias a todos

lo voy a intentar y les aviso como salio


----------



## Destripador (Mar 1, 2010)

eeeee

si me salio

muchas gracias a todos!!!!!!!!!!!!!!!!!!


----------



## COSMICO (Mar 1, 2010)

Me alegra que te saliera todo bien..


----------



## Hernan83 (Mar 8, 2010)

Estoy usando un pic 16F877 con un LCD 4X20 en CCS,lo conecto al puerto B en la configuracion de 4 bits,cristal de 4 Mhz con el siguiente codigo:


```
#include <16F877.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=4000000)
#include <LCD420.c>
#define use_portb_lcd TRUE

void main() {
 
 
 lcd_init();
 
 lcd_putc("\f Hernan Alberto A. \n");
 lcd_putc("Ejemplo LCD en CCS C");
 
}
```

Ya me estoy volviendo loco!!!:enfadado: y no me funciona,puse este codigo,por lo simple,estoy haciendo las cosas muy simples pero nada! Habre puesto bien los fuses? Solo se me iluminan las lineas 1 y 3. Alguien puede decirme que podra ser?


----------



## renech (Mar 11, 2010)

que tal amigos del foro tengo una duda inmensa sobre como programar en ccs c ya que mi programador funciona perfectamente en lenguaje ensamblador pero creo que estoy direccionando mal en c alguien puede decirme como se graba un pic desde ccs y con que programador


----------



## magdalena (Mar 12, 2010)

tu puedes grabar el pic con mplab... solo necesitas el .hex de ccs... nada mas...

HERNAN ponle algo de retardos a lo mejor sea por eso y revisa bien si estas las patitas que estas utilizando en el pic son las mismas que tienes en el programa...

mi problema con el codigo de la lcd se debia a los retardos....


----------



## Ferchorobot (Mar 14, 2010)

Estoy loco con este programa para mostrar por el LCD esto tan sencillo en proteus me funciona bien pero al momento de probarlo realmente no hace nada, el programa trata de mostrar un mensaje en el lcd para decir q esta listo luego cuando el led prenda y apague el lcd indica el estado del led, el lcd no inicia ni tampoco pasa a la funcion de prender y apagar el led del pin_a2. Espero me puedas ayudar con esto. el lcd que uso al momento de probarlo es el LM071L de la hitachi. te adjunto la conexion en proteus para ver si me puedes indicar que esta malo.


```
#include <16F628.h>

#FUSES NOWDT                     //No Watch Dog Timer
#FUSES HS                        //High speed Osc (> 4mhz)
#FUSES NOPUT                     //No Power Up Timer
#FUSES NOPROTECT                 //Code not protected from reading
#FUSES NOBROWNOUT                //No brownout reset
#FUSES MCLR                      //Master Clear pin enabled
#FUSES NOLVP                     //No low voltage prgming, B3(PIC16) or B5(PIC18)  used for I/O
#FUSES NOCPD                     //No EE protection

#use delay(clock=20000000)
#define LCD_ENABLE_PIN PIN_B0
#define LCD_RS_PIN PIN_B1
#define LCD_RW_PIN PIN_B2
#define LCD_DATA_PORT 6
#define LCD_TYPE 2
#define LCD_TRIS_LOCATION set_tris_b(x)
#include <lcd.c>

#use fast_io (a)
#use fast_io (b)

void main()
{
   port_b_pullups(False);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   lcd_init();
   lcd_putc("\fReady...");
   delay_ms(500);
   output_a(0x00);
   set_tris_a(0x00);
   while(1)
   {
      output_high(PIN_A2);
      lcd_putc("\fOff");
      delay_ms(500);
      output_low(PIN_A2);
      lcd_putc("\fOn");
      delay_ms(500);
   }
}
```


----------



## george.manson.69 (Mar 15, 2010)

Ferchorobot dijo:


> Estoy loco con este programa para mostrar por el LCD esto tan sencillo en proteus me funciona bien pero al momento de probarlo realmente no hace nada, el programa trata de mostrar un mensaje en el lcd para decir q esta listo luego cuando el led prenda y apague el lcd indica el estado del led, el lcd no inicia ni tampoco pasa a la funcion de prender y apagar el led del pin_a2. Espero me puedas ayudar con esto. el lcd que uso al momento de probarlo es el LM071L de la hitachi. te adjunto la conexion en proteus para ver si me puedes indicar que esta malo.
> 
> 
> ```
> ...



El pin VEE debe de ir a tierra, en proteus el pin VEE va al positivo pero, fisicamente yo lo he conectado al negativo y funciona al 100. otra podria ser la configuracion del lcd. checa en algunos circuitos que he hecho antras y veras que he configurado el lcd diferente.


----------



## serbio (Mar 19, 2010)

Hola!! Quiero agradecer a George Mason por estos excelentes proyectos y a los demas foristas por sus aportes.
Saludos


----------



## COSMICO (Mar 19, 2010)

Opino lo mismo..
No he visto un foro como0 este en la web..


----------



## george.manson.69 (Mar 28, 2010)

Este oprobador simplemente te checa el VID & PID, y te dice si esta conectado o no,
y aun estoy en base de experimentacion de cambiar el buffer general, en este caso solo puedes cam,biar el buffer de envio y resepcion. el general es los datos que envias.

En el .zip se encuentra todo lo necesario...para entenderlo mejor...el porgrama esta hecho en C# 2008, he creado tambien una libreria para usar el mpusbapi mas sencillo especialemnte para C#, el archivo es USB.dll.

Las funciones son simples:

VID_PID(); busca el vid&pid asignado y te manda un valor mayor que cero si es cierto.

cambiar_VIDPID(); pùedes cambair el VID & PID facilmente

entre varias funciones de escritura y lectura...

Y por supuesto esta el prgrama para el PIC18 y la simulacion en proteus


----------



## Lithiumrd (Mar 29, 2010)

Seria bueno para los que estamos empezando en el mundo del ccs que comentaran el codigo para tener idea de que hace cada funcion

GRacias


----------



## M.a.R.c.K (Mar 29, 2010)

Hola oye me interesa tu tema y ps no se mucho de PICS y ps talves esto se oiga tonto pero como lo conecto el control de servos y la programacion que hisiste para controlar el servo dandole coordenadas...


----------



## harrypotter (Mar 29, 2010)

Gracias George.Manson por todo el apoyo que das a la comunidad


----------



## M.a.R.c.K (Mar 29, 2010)

Perdon amigo por lo anterior mi duda es como crear los puertos seriales?

hola oye otra pregunta el pic que yo tengo es el PIC16F883 crees que actue igual?


----------



## george.manson.69 (Mar 30, 2010)

M.a.R.c.K dijo:


> Perdon amigo por lo anterior mi duda es como crear los puertos seriales?
> 
> hola oye otra pregunta el pic que yo tengo es el PIC16F883 crees que actue igual?


 
debe de funcionar igual, solo mira si tiene la misma RAM los dos pics el que yo use y el tuyo...los circuitos los probe fisicamente, y funcionan...yo creo que debe de funcionar con ese PICmicro 883...saludos


----------



## COSMICO (Mar 31, 2010)

M.a.R.c.K.
Amigo. Por internet bajate un programita con el nombre 
virtual serial port driver; es gratis y trabaja muy bien;  facil de usar
Como dice crea puertos com virtuales, puedes trabajar tus aplicaciones en c# o vb
y simularlas junto con proteus..


----------



## dragondgold (Abr 17, 2010)

Hola amigos tengo un problema compilando un programa con el CCS que ya no se que pueda ser porque la verdad no se que intenta decirme el CCS.


```
#include <16F628.h>
#use delay(clock=4000000)
#fuses XT,WDT,NOMCLR,NOPROTECT
/*PUERTOS*/
#byte PORTA = 0x05
#byte TRISA = 0x85
#byte PORTB = 0x06
#byte TRISB = 0x86
#byte PR2   = 0x92
/*VARIABLES*/
INT estado= 0

//********************INTERRUPCIONES*********************
#int_TIMER0                                              //INTERRUPCION DEL TIMER0
VOID TIMER0(VOID){
IF(estado==0){
PR2= 1;                                                  //VALOR PARA PERÍODO
setup_ccp1(CCP_PWM);                                     //MODULO CCP EN MODO PWM
set_timer0 (242);                                        //CUENTA DEL TIMER0
estado= 1;
}
ELSE{
setup_ccp1(CCP_OFF);
estado= 0;
PORTB= 0;
}
}

/*************************PROGRAMA PRINCIPAL*********************************/

VOID main(){

/*PUERTOS*/
TRISB= 0;
TRISA= 0;
PORTA, PORTB= 0;
/*PWM*/
setup_timer_2(T2_DIV_BY_1,1,1);                          //CONFIGURACIÓN DEL TIMER2 PARA EL PERIODO DE 2uS --- Valor 1 --- Divisor 1
set_pwm1_duty(4);                                        //PARA UN DUTY CICLE DEL 50% --- 4/4*(1+1))
setup_ccp1(CCP_OFF);

/*CONFIGURACION DEL TIMER0*/
setup_timer_0(RTCC_INTERNAL | RTCC_DIV_1);               //GENERO UNA INTERRUPCIÓN CADA 14uS
set_timer0 (242);
enable_interrupts(int_timer0);
enable_interrupts(global);

WHILE(1){}
}
                                                

/*SI ESTADO ES 1 ESTA DANDO LOS PULSOS
SI ESTADO ES 0 ESTA EN LA SEGUNDA PARTE EN DONDE ES 0*/
```

El programa genera por 14uS un PWM y a los otros 14uS un nivel 0, me dice que falta un "," o un ";" en la línea 14 que vendría a ser donde esta la interrupción del TIMER0 donde dice #int_TIMER0. No se porque me dice eso es lo único que me impide compilar.


----------



## Eduardo (Abr 17, 2010)

> me dice que falta un "," o un ";" en la línea 14 que vendría a ser donde esta la interrupción del TIMER0 donde dice #int_TIMER0. No se porque me dice eso es lo único que me impide compilar.


El error está antes --> Te faltó el *;* para terminar la linea " INT estado= 0  "


----------



## dragondgold (Abr 17, 2010)

Haaaa! Muchas gracias! Lo había revisado un montón de veces y no lo vi parece 

Gracias!


----------



## COSMICO (Abr 19, 2010)

Hola Amigos
Ustedes que lo saben y lo pueden todo, necesito tomar una cantidad n de muestras del 
conversor adc del pic 873; sumarlas y luego dividir este resultado para sacar un promedio
de las muestras. como puedo hacer esto en ccs.Un ejemplo me vendria bien
Gracias por su ayuda


----------



## george.manson.69 (Abr 21, 2010)

Este es un robot que hice has poco...espero que le guste...Explica yo creo casi todo de como contruirlo..

http://www.easy-share.com/1909992253/SANDWOROT.pdf


----------



## COSMICO (Abr 21, 2010)

COSMICO dijo:


> Hola Amigos
> Ustedes que lo saben y lo pueden todo, necesito tomar una cantidad n de muestras del
> conversor adc del pic 873; sumarlas y luego dividir este resultado para sacar un promedio
> de las muestras. como puedo hacer esto en ccs.Un ejemplo me vendria bien
> Gracias por su ayuda



Perdon que insista 
Alguien me puede dar una manito


----------



## george.manson.69 (Abr 23, 2010)

COSMICO dijo:


> Hola Amigos
> Ustedes que lo saben y lo pueden todo, necesito tomar una cantidad n de muestras del
> conversor adc del pic 873; sumarlas y luego dividir este resultado para sacar un promedio
> de las muestras. como puedo hacer esto en ccs.Un ejemplo me vendria bien
> Gracias por su ayuda


 
es sencillo

es:


```
for(sensores=0;sensores<=numero_sensores a manajer;sensores++){
            set_adc_channel(sensores);
            delay_us(50);
            channels(sensores)=read_adc();
}
 
for(sensores=0;sensores<=numero_sensores a manajer;sensores++){
            resultado+=channels(sensores);
}
```
 
yo digo que asi puede ser a la respuesta de tu pregunta....espero que te sirva


----------



## COSMICO (Abr 23, 2010)

Amigo gracias. Lo pruebo y te comento como me fue


----------



## Vegetal Digital (Abr 24, 2010)

No te faltaria dividirlo? algo así:

```
resultado=resultado/numero_sensores_a_manejar;
```


----------



## COSMICO (Abr 24, 2010)

ok gracias a ti tambien
Vegetal Digital.


----------



## george.manson.69 (Abr 25, 2010)

Ok me habia faltado eso lo mero bueno jaja....


```
for(sensores=0;sensores<=numero_sensores a manajer;sensores++){
            set_adc_channel(sensores);
            delay_us(50);
            channels(sensores)=read_adc();
}
 
for(sensores=0;sensores<=numero_sensores a manajer;sensores++){
            resultado+=channels(sensores);
}

resultado=resultado/numero_sensores_a_manejar;
```

recuerda que si pones las entradas analogas de 10 bit debes de poner una variable
de "resultado " de tipo int32, o si es 8 bit tambien pon una variable de mismo tipo.


----------



## COSMICO (Abr 25, 2010)

De nuevo gacias amigo,george.manson.69
  tan pronto pueda lo pongo en practica


----------



## george.manson.69 (Abr 29, 2010)

Les quiero compartir un espacio sobre manuales que he hecho durante este tema recopilados...y seguira aumentando...ya que ultimamente pesa mas de 2 MB y no puedo subirlos en este tema...espero que les guste...

http://mcuproyects.blogspot.com/


----------



## dragondgold (May 2, 2010)

Hola resulta que escribí un programa de una simple lectura del puerto analógico del PIC pero el compilador me rechaza los comandos referidos al uso del ADC y no estan mal escritos que puede ser? Les dejo el código. Uso CCS.


```
#include <16F628A.h>
#device adc=10
#use delay(clock=4000000)
#fuses XT,NOWDT,NOMCLR,NOPROTECT
/*PUERTOS*/
#byte PORTA = 0x05
#byte TRISA = 0x85
#byte PORTB = 0x06
#byte TRISB = 0x86
/*VARIABLES*/
INT16 adc;                                               //VALOR DEL ADC (BINARIO)
FLOAT tension = 0.000;                                   //TENSION DEL ADC (VOLTS)

VOID main(VOID){
TRISB = 0;
setup_adc_ports(AN0);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
delay_us(20);
                        WHILE(1){
adc = read_adc();                               //LECTURA CANAL AN1
tension = 5.000 * adc / 1024.000;               //CONVERSION A VOLTAJE
IF((tension<2.5)&&(tension>1.00)){
            output_high(PIN_A2);
}
ELSE{
            output_low(PIN_A2);
}
delay_us(20);
                        }
}
```


----------



## COSMICO (May 2, 2010)

dragondgold.
El pic 628 no tiene entradas analogas, fijate en el datasheet
por eso te da Error; pasate a un pic 16f819, o a un pic 16f88
Ver el archivo adjunto PROBLEM.rar
miralo con pic 873


----------



## pepg (May 4, 2010)

hola,

estoy estudiando una asignatura de uC, y estoy buscando informacion sobre como implementar una comunicacion 1-wire entre pics y sensores. en concreto, habria un pic master (pic16fxxx), un pic esclavo (pic12fxx) y dos sensores.
estoy buscando una forma de implementar el programa en C la parte del pic esclavo, pero no se como hacerlo. todos los ejemplos son de dispositivos slaves de tipo sensores, que apenas mandan la medicion de temperatura, por ejemplo.

gracias de antemano.


----------



## kaymar (May 12, 2010)

george.manson.69 dijo:


> ```
> //------------------------------------
> //TITULO: SENSOR DE TEMPERATURA Y ENVIADO A LA PC
> //AUTOR: JORGE ARTURO RODRIGUEZ HERNANDEZ
> ...




Hola que tal, estoy muy interasado. Pero no lo tienes com para el 16f877a???

Y cómo es, paralelo, seria,?? Baudio, etc...???


Saludos y gracias!!!


----------



## COSMICO (May 12, 2010)

Mira. kaimar
Son muy pocos los cambios
Ver el archivo adjunto TERMO.rar


----------



## FRYCK (May 13, 2010)

hola  *Kaymar*   te dejo el código con las modificaciones que pedías saludos

```
#include <16F877A.h>
#device adc=8
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES XT                       //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPUT                    //No Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection
#FUSES NOWRT                    //Program memory not write protected
#use delay(clock=4000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
void config(){
   setup_adc_ports(ALL_ANALOG);
   setup_adc(ADC_CLOCK_INTERNAL);
   setup_psp(PSP_DISABLED);
   setup_spi(FALSE);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
}
void main(){
      int x,y;
      config();
      do{
         x=read_adc();
         delay_ms(500);
         y=2*x;
         printf("LA TEMP= %u",y);
         printf("°C\r\n");
      }while(TRUE);
}
```


----------



## inovaspirit (May 16, 2010)

Muchas Gracias, no saben cuanto me han ayudado tus ejemplos george.manson.69, soy nuevo esto de los pics y  CCS, estoy intentando controlar la posicion de un servo y posteriormente un motor a pasos, pero cuando movia el motor a pasos, se volvia loco el servo, pero con los ejemplos me di cuenta que no establecia prioridades en la interrupciones. 

le muestro mi codigo 


```
//    Ancho pulso medio  1.5 ms ->  90 ticks de TMR0
//    Ancho pulso maximo 2.5 ms -> 155 ticks de TMR0

#include <16f877a.h>
#fuses XT,NOWDT,NOPROTECT,NOLVP,PUT,BROWNOUT
#use delay(clock=4000000)
#use standard_io(b)
#define PIN_SERVO1 PIN_B0
#priority int_RTCC,rda

const int AJUSTE_FINO_DE_RTCC =  30;
const int ticks_PULSO_MINIMO  =  75;
const int ticks_PULSO_MEDIO   =  96;
const int ticks_PULSO_MAXIMO  = 119;
int1 flagRTCC     = 0;
int   contRTCC    = 0;
int1 flagSERVO1 = 0;
int   tSERVO1     = ticks_PULSO_MEDIO;

#int_RTCC

void RTCC_isr(){
   ++contRTCC;
   if(contRTCC==4){
      set_TIMER0(AJUSTE_FINO_DE_RTCC);
   }

   if(contRTCC==5){
      flagRTCC=1;
      contRTCC=0x00;
   }
}
void main() {
   int ValTIMER0;
   setup_counters(RTCC_INTERNAL,RTCC_DIV_16);
   enable_interrupts(int_rda);
   enable_interrupts(global);
      set_TIMER0(0);
   enable_interrupts(INT_RTCC);

    do {
      // DISPARO DEL PULSO PWM
      if(flagRTCC==1){
         flagRTCC=0;
         output_high(PIN_SERVO1);
         flagSERVO1=1;    
      }
      // CONTROL DE ANCHO DEL PULSO PWM

      if(flagSERVO1==1){
         valTIMER0 = get_TIMER0();
         if(valTIMER0>tSERVO1){
            flagSERVO1=0;
            output_low(PIN_SERVO1);
         }   
      } 
      // CONTROL DEL SERVOMOTOR MEDIANTE PUSH

      if(input(pin_b1)==0 && input(pin_b4)==1 && input(pin_b5)==1){
      //delay_ms(200);
      tSERVO1=ticks_PULSO_MINIMO;}
      else if (input(pin_b2)==0 && input(pin_b4)==1 && input(pin_b5)==1){
      //delay_ms(200);
      tSERVO1=ticks_PULSO_MAXIMO;}
      else if (input(pin_b3)==0 && input(pin_b4)==1 && input(pin_b5)==1){
      //delay_ms(200);
      tSERVO1=ticks_PULSO_MEDIO;}
          
     // CONTROL DEL MOTOR A PASOS MEDIANTE PUSH
      if (input(pin_b4)==0){
      delay_ms(300);
   
      output_low(pin_b6);
      delay_ms(100);
      output_low(pin_b7);
     delay_ms(100);
      output_high(pin_b7);
    delay_ms(100);
      output_low(pin_b7);
  delay_ms(100);
      output_high(pin_b7);
      delay_ms(100);
      output_low(pin_b7);
      delay_ms(100);
      output_high(pin_b7);
      delay_ms(100);
      output_low(pin_b7);}
             
     else if (input(pin_b5)==0){
     delay_ms(300);
     
     output_high(pin_b6);
   delay_ms(100);
     output_low(pin_b7);
    delay_ms(100);
     output_high(pin_b7);
     delay_ms(100);
     output_low(pin_b7);
    delay_ms(100);
     output_high(pin_b7);
     delay_ms(100);
     output_low(pin_b7);
    delay_ms(100);
     output_high(pin_b7);
     delay_ms(100);
     output_low(pin_b7);}
   
   } while (TRUE);
  
}
```
si me presentaran mejoras a mi codigo se los agradecería, les adjunto la simulacion en proteus.

Nota: Para el control del motor a pasos empleo un driver que es el l297 y un puente h que es el l298, asi que al pic unicamente lo que le solicito es un tren de 2 pulsos, por lo que se me ocurrio hacerlos con delays...


----------



## kaymar (May 16, 2010)

Muchas gracias a ambos por su ayuda!!!!

Saludos y nos vemos pronto !!!


----------



## misterlee (May 17, 2010)

Te felicito por poner estos programas,  yo no se programar en C ( he hecho algunos en asembler y me han quedado bien)  los voy a leer para tener una idea como hiciste tus programas sin embrago me ubiera gustado que hubieras puesto algunos comentarios despues de cada sentencia para tener una idea mas clara ya que soy de muy lento aprendizaje y en serio tengo que leer algo varias veces para poder comprenderlo a cabalidad de todas maneras bien por lo que has puesto para todos los interesados, felicidades.


----------



## tillbarton (May 25, 2010)

george un favor me puedes e*X*plicar como funciona el scroll q*UE* pusistes de ejemplo lo pruebo y si trabaja de maravilla pero aun no comprendo la sintaxis de como trabaja por favor si fueras tan amable de explicarlo te dejo mi mail 



gracias


----------



## george.manson.69 (Jun 7, 2010)

aqui les tengo un exemplo de uso de un GLCD programado en pic c compiler

Para simularlo se debe de tener proteus 7.6 sp4


----------



## magdalena (Jun 8, 2010)

Hola que tal como están???
Disculpe molestarlos pero tengo un pequeño y gran problema...
estoy recibiendo datos con la interrupción RDA, Funciona perfecto... pero al momento de que ya he recibido 40 datos el programa no corre más... tengo que apagar y prender el pic para q vuelva a trabajar... noc como pueda solucionar el problema... si alguien podria ayudarme se lo agradeceria mucho...


----------



## FRYCK (Jun 8, 2010)

hola *magdalena*  coloca mas datos de tu problema  como  que tipo de micro controlador utilizas, el circuito es simulado, el código si es posible  postealo para poderte ayudar 
saludos


----------



## george.manson.69 (Jun 9, 2010)

magdalena sube el progrograma para ver que puede ser...o la simulacion si puedes para buscar una falla...


----------



## magdalena (Jun 10, 2010)

hola FRYCK gracias por la ayuda pero ya lo solucione... lo que me pasaba era que estaba utilizando un punteros en vez de cadenas de caracteres.
Saludos.

y tambien gracias george.manson.69... ahora tengo otro problemita... ustedes saben como puedo utlizar dos o más interrupciones RDA al mismo tiempo...??? tienen algún ejemplo, es que noc cuando activar uno y cuando activar otro...


----------



## Moyano Jonathan (Jun 10, 2010)

Para lo que querés tenés que tener un micro con 2 usart......o en su defecto usar usart por software y interrupcion por el pin RB0.


----------



## magdalena (Jun 10, 2010)

Moyano Jonatha el micro que tengo es si tiene dos Usart... es el pic 18f8720... ya tengo las dos interrupciones hechas pero no funca... noc como es que tengo q poner para activar una y desactivar otra... en que momento... noc... podrian explicarme esto por favor...


----------



## Moyano Jonathan (Jun 10, 2010)

los PIC18Fxx manejan vectores de interrupciones que se dividen en 2 : Alta y baja prioridad ahora lo que no se es como manejar las prioridades en CCS..para eso tendrías que leer el manual de usuario de CCS. Ahora lo mejor sería que pusieras el código del programa que estás haciendo para ver que puede estar saliendo mal ...Y otra cosa no probés nada en el proteus por que generalmente hay problemas que vos vés en la simulación pero que en realidad no existen...por eso arma todo en proto y probalo fisicamente.
El error que estás teniendo me parece es que cuando se está cumpliendo la interrupción por ejemplo de la usart 1 el micro deja todas las tareas a un lado a no ser que una interrupción de más prioridad aparezca....el tema es que hay que saber manejar dichas prioridades para que no ocurran problemas de colisiones de datos...

Por eso es mejor que nos digas que proyecto tenés el código fuente, el circuito todo para poder ayudarte por que sino es medio dificil que te podamos ayudar.


----------



## magdalena (Jun 10, 2010)

noc y el otro problema que tengo es que cuando lo programo en el pic y saco el cable de programacion el programa funciona perfecto pero cuando apago el pic y lo vuelvo a prender no funca... no entiendo porq???
si alguien me ayuda se lo agradeceria mucho...

aqui les envio el codigo...
este es el .c


> #include "D:\BIOMETRICO\main.h"
> #include "D:\BIOMETRICO\24512_B.c"
> #include "D:\BIOMETRICO\KEY_B.c"
> #include "D:\BIOMETRICO\LCD_B.c"
> ...


_
este es el .h



			#include <18F8720.h>
#device adc=8

#FUSES NOWDT                    //No Watch Dog Timer
//#FUSES WDT1                   //Watch Dog Timer uses 1:128 Postscale
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOOSCSEN                 //Oscillator switching is disabled, main oscillator is source
#FUSES NOBROWNOUT                 //Reset when brownout detected
#FUSES BORV25                   //Brownout reset at 2.5V
#FUSES PUT                      //Power Up Timer
#FUSES NOCPD                    //No EE protection
#FUSES NOSTVREN                   //Stack full/underflow will cause reset
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                      //Low Voltage Programming on B3(PIC16) or B5(PIC18)
#FUSES NOWRT                    //Program memory not write protected
#FUSES NOWRTD                   //Data EEPROM not write protected
#FUSES NOWAIT                   //Wait selections unavailable for Table Reads or Table Writes
#FUSES MCU                      //Microcontroller Mode
#FUSES NOWRTC                   //configuration not registers write protected
#FUSES NOWRTB                   //Boot block not write protected
#FUSES NOEBTR                   //Memory not protected from table reads
#FUSES NOEBTRB                  //Boot block not protected from table reads
#FUSES NOCPB                    //No Boot Block code protection

/*#byte PORTA=0XF80
#byte PORTB=0XF81
#byte PORTC=0XF82
#byte PORTD=0XF83
#byte PORTE=0XF84
#byte PORTF=0XF85
#byte PORTG=0XF86
#byte PORTH=0XF87
#byte PORTJ=0XF88*/

#byte RESET = 0X00

#use delay(clock=20000000)
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,restart_wdt)
//#use rs232(baud=9600,parity=N,xmit=PIN_A2,rcv=PIN_A3,bits=8,restart_wdt,stream=GPS)
#use rs232(baud=9600,parity=N,xmit=PIN_G1,rcv=PIN_G2,bits=8,restart_wdt,stream=GPRS)
#use rs232(baud=9600,parity=N,xmit=PIN_A4,rcv=PIN_A5,bits=8,restart_wdt,stream=PC)


void InitBuffer(void);
byte convertir_decimal(char num);
byte convertir_byte(char num1,char num2);
char *InitBuffer1(int16 length, char *array);
void InitBuffer2(void);
void Alarma(void);
void InitBufferRX(void);
void InitBufferRX2(void);
		
Hacer clic para expandir...

_


----------



## Moyano Jonathan (Jun 10, 2010)

Bueno más o menos ahi entendí tu programa ahora te lo correjí...como me percaté ...el compilador si hace la distinción de vectores de interrupción de alta y baja prioridad pero el usuario es el encargado de configurarlas. El problema que vos tenés es que las has configurado mal y hay porciones de código que te están haciendo funcionar mal el programa:

En cuanto te tenga las correciones te las paso ...pero si queres verlo vos te digo que el problema radica en la habilitacion / deshabilitacion de interrupciones ...


----------



## magdalena (Jun 10, 2010)

ok... gracias... en serio te lo agradezco mucho... esperare tu correccion... y no se me puedas explicar algo de como se cuando debo o no habilitar las interrrupciones???
Saludos


----------



## H3RO (Jun 11, 2010)

Hola soy algo nuevo en esto..quisiera saber si la sintacsis es la misma para todos los pic?
yo tengo pensado utilizar el pic 16f84a!
alguien plz que me responda


----------



## magdalena (Jun 11, 2010)

hola q tal H3RO si es lo mismo para todos... pero tienes q leer el su hoja de datos por si acaso...


----------



## H3RO (Jun 11, 2010)

se agradece magdalena!
muchas gracias por tu respuesta


----------



## magdalena (Jun 12, 2010)

no te preocupes H3RO... por si a caso tu sabes algo de interrupciones...??? sabes utilizarlas bien???


----------



## george.manson.69 (Jun 13, 2010)

Uso de tarjetas microSD proyecto a nivel hardware, SPI.
Este circuito es muy simple solo trata de uso de una tarjeta microSD modo SPI, este caso he usado un microcontroldor PIC16F887, usando solo 64 bytes en cada bloque de la tarjeta y el resto como basura ya que este microcontrolador no posee mas de 368 bytes.

Codigo hecho en CCS C.

```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;USO DE TARJETA SD
//DATE:22/JULIO/'05
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16F887.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT,NODEBUG
#use delay(clock=8M)
//#include<kbd_lib.c>
#include<LCD420_PORTD.C>
#define SIZE_BLOCK 64
#include<SPI_uSD.c>

const char letra[]={"PRIMERA PRUEBA DE MICROSD YEAH"};

void config(void){
    //set_tris_c(0x10);
    setup_adc(ADC_OFF);
    setup_comparator(NC_NC_NC_NC);
    setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_64);
}

void main(void){
    int info;
    config();
    //kbd_init();
    lcd_init();

    lcd_putc("\fExample SD card!!!\n");
    delay_ms(1000);
    if(!SD_Init()){
        lcd_putc("Tarjeta SD fail");
        lcd_gotoxy(1,3);
        lcd_putc("try again      ");
        while(TRUE);
    }else{
        lcd_putc("Tarjeta Accedida    ");
    }
    delay_ms(1000);
    lcd_gotoxy(1,2);
    for(info=0;info<SIZE_BLOCK;info++){            //Guardamos temporalemente en la variable "data"
        if(info<30) data[info]=letra[info];        //la frase y resto basura
        else data[info]=info;
    }
    if(write_SD(100)){                            //Grabamos a la tarjeta la frase que contiene la 
        lcd_putc("DATA fail!!!            ");        //variable "data"
    }else{
        lcd_putc("DATA saved!!!         ");
    }
    for(info=0;info<SIZE_BLOCK;info++){        //BORRAMOS TODA LA VARIABLE "data" para
        data[info]=0xAA;                    //saber que no hay nada en la variable
    }
    delay_ms(1000);

    lcd_gotoxy(1,2);

    if(!read_SD(100)){                        //cargamos la variable data con los valores
        lcd_putc("DATA read!!!     ");        //guardados en la tarjeta SD
    }else{
        lcd_putc("DATA fail!!!     ");
    }
    delay_ms(1000);
    for(info=0;info<30;info++){                //Si se guardo correctamente este
        if(info<14){                        //debe de proyectar la frase que guardamos en la memoria
            lcd_gotoxy(info+1,3);
            lcd_putc(data[info]);
        }else{
            lcd_gotoxy(info-14,4);
            lcd_putc(data[info]);
        }
    }
}
```
Otra prueba con la tarjeta, guarda 64 lecturas analogas.


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;USO DE TARJETA SD
//DATE:22/JULIO/'09
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16F887.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=8000000)
#use fast_io(b)
#include<kbd_lib.c>
#include<LCD420_PORTD.C>
#define SIZE_BLOCK 64
#include<SPI_uSD.c>

int c=0,ca,x,aux=0,count=3,ac;
float volts;

void config(void){
    set_tris_b(0xF0);
    port_b_pullups(0xF0);
    setup_comparator(NC_NC_NC_NC);
    setup_spi(SPI_MASTER|SPI_L_TO_H|SPI_CLK_DIV_64);
    setup_adc(ADC_CLOCK_INTERNAL|VSS_VDD);
    setup_adc_ports(sAN0);
}

char tecla(){
    while(TRUE){
        c=kbd_getc();
        if(c!=0)break;
    }
    return c;
}


void main(void){
    config();
    lcd_init();
    kbd_init();


    while(TRUE){
        lcd_putc("\f----Invernadero-----\n");
        lcd_putc("Intertar SD:     <A>");
        ca=tecla();
        switch(ca){
            case 'A': 
                    if(!SD_init()){
                        lcd_gotoxy(1,2);
                        lcd_putc("Inicialiacion fallo   ");
                        break;
                    }else{

                        lcd_gotoxy(1,2);
                        lcd_putc("Inicialiacion SD    ");
                        delay_ms(2000);
                        lcd_gotoxy(1,2);
                        lcd_putc("Rec Temperatura: <B>");
                        lcd_gotoxy(1,3);
                        lcd_putc("Read Temperatura:<C>");
                        ac=tecla();
                        if(ac!='B' && ac!='C'){
                            break;
                        }else if(ac=='B'){
                            lcd_gotoxy(1,2);
                            lcd_putc("NO RETIRE SD...!!!! ");
                            lcd_gotoxy(1,3);
                            lcd_putc("                    ");
                            for(x=0;x<64;x++){
                                if(x==count){
                                    count+=3;
                                    aux++;
                                    lcd_gotoxy(aux,3);
                                    lcd_putc(0xFF);
                                }
                                delay_ms(100);
                                DATA[x]=read_adc();
                            }
                            if(write_SD(50)){
                                lcd_gotoxy(1,2);
                                lcd_putc("No se pudo grabar!!! ");
                                lcd_gotoxy(1,3);
                                lcd_putc("                     ");
                            }else{
                                lcd_gotoxy(1,2);
                                lcd_putc("Grabado!!!           ");
                                lcd_gotoxy(1,3);
                                lcd_putc("                     ");
                            }
                            aux=0;
                            count=3;
                            delay_ms(2000);
                            break;
                        }else if(ac=='C'){
                            
                            lcd_gotoxy(1,2);
                            lcd_putc("Checando temp. saved     ");
                            lcd_gotoxy(1,3);
                            lcd_putc("                         ");
                            if(!read_SD(50)){
                                while(ca!='D'){
                                        ca=tecla();
                                        if(ca=='1'){
                                            if(aux<=64){
                                                aux++;
                                            }else{aux=1;}
                                        }
                                        if(ca=='8'){        
                                            if(aux==0){
                                                aux=1;
                                            }else{
                                                aux--;
                                            }
                                        }
                                        volts=((float)DATA[aux]*5)/255;
                                        lcd_gotoxy(1,3);
                                        printf(lcd_putc,"%u.- %0.2f C                 ",aux,volts);
                                    }
                            }else {aux=0;break;}
                            aux=0;
                            break;
                        }
                                            
                                        
                    }
        }
    }
}
```

Se necesita tener proteus 7.7 para la simulacion


----------



## EINNER C (Jun 14, 2010)

hola george.manson.69

estan excelentes tus aportes,,, hacia un tiempo no volvia al foro, espero estar contribuyendo con algo dentro de poco....


----------



## george.manson.69 (Jun 14, 2010)

Siguiendo con estas tarjetas le traigo como usar en modo fat16 googleando encontre los drivers para el manejo de estas.

```
///////////////////////////////////////////////////////
//Autor del exemplo: george.manson.69            ///////
//Contacto: george.manson.69@gmail.com            ///////
//Sobre: Tarjeta MMC modo Fat16                    ///////
//Este programa lo que hace es crear una carpeta nombrada     ////
//"DATO" y despues crea un archivo de texto (.txt)             ////
//donde se empezara adherir datos de ADC maximo de 10          ////
//Al terminar podemos checar la memoria MMC en la computadora////
//Tanto la carpeta y archivo con los datos ADC                 ////
//                                                             ////
//Los drivers para la utilizacion del FAT16 fue creado         ////
//por Suky. en la pagina web www.infopic.comlu.com             ////
//Donde podras bajar los drivers actualizados.                 ////
///////////////////////////////////////////////////////                                

#include<18F2550.H> //Agregamos todos los registros del uC18
#fuses INTRC_IO,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOPBADEN
/*
MCLR: vamos ha usar el PIN MCLR, el reset se hará por Hardware
HSPLL: Vamos a usar un cristal de 20.00Mhz.
NOWDT: No vamos a usar el perro guardian.
NOPROTECT: Memoria no protejida contra lecturas.
NODEBUG: No utilizamos código para debugear.
NOLVP: No utilizamos el modo de programación con bajo voltaje.
USBDIV: signfica que el clock del usb se tomará del PLL/2 = 96Mhz/2 = 48Mhz.
PLL1: significa que el PLL prescaler  dividirá la frecuencia del cristal. 20Mhz/5=4Mhz
CPUDIV1: El PLL postscaler decide la división en 2 de la frecuencia de salida del PLL de 96MHZ, si queremos 48MHZ, lo dejamos como está.
VREGEN: habilita el regulador de 3.3 volts que usa el módulo USB.
NOPBADEN: Deshabilitamos el módulo conversor ADC del puerto B.
*/

//------------------------------------------------------------
//Configuraciones                                            //
//------------------------------------------------------------

#use delay(clock=8M)
#use rs232(baud=9600,xmit=PIN_B7,rcv=PIN_B6)

#include <SDCard_hard.c>
#include <FAT16_SDCard.c>

char Texto1[512]="Medidor de voltaje\r\n";
char texto2[512];

/*******************************************************************************/
void main(void){
    char car[6]="DATOS";
    char dir[7]="/DATOS";
    char NombreArchivo[20]="Datos1.txt";
    long UbicacionFolder;
    long tx;
    unsigned int value_adc;

    set_tris_a(0b00000001);
    set_tris_b(0b01000001);
      setup_adc_ports(AN0);
    setup_adc(ADC_CLOCK_INTERNAL|VSS_VDD);
    setup_comparator(NC_NC_NC_NC);
    output_high(PIN_C0);
    output_high(PIN_C1);
    output_high(PIN_C2);
   
    delay_ms(2000);

    printf("Iniciando SD Card\r\n");

    if(SDCard_init()==0){
      printf("Error al iniciar\r\n");
       }else{
      printf("Se ha iniciado correctamente la memoria!!!\r\n\r\n");
      FAT_init();
        printf("Creando carpeta de datos\r\n");
      if(FAT_CreateDirectory(car,car,DirectorioRaiz)==0){
            printf("error de creacion de carpeta\r\n");
      }
        printf("Buscando la direccion de la carpeta deseada\r\n");
      if(FAT_FindDirectory(dir,DirectorioRaiz,UbicacionFolder)==0){
            printf("error en leer la carpeta\r\n");
      }
        printf("Creando archivo de datos\r\n");
      if(FAT_CreateFile(NombreArchivo,NombreArchivo,UbicacionFolder,Texto1)==0){
        printf("error de creacion de archivo\r\n");
      }else{
        for(tx=0;tx<10;tx++){
            delay_ms(1);
            value_adc=read_adc();
            sprintf(texto2,"voltaje=\t%u\r\n",value_adc);
            if(FAT_OpenAddFile(NombreArchivo,UbicacionFolder,Texto2)==0){
                printf("error de sobreescritura Dato[%lu]\r\n",tx);
            }else{
                printf("DAtO[%lu] grabado\r\n",tx);
            }
        }
       }
   }

   while(TRUE);
}
```

Lamentablemente parece que no he encontrado la forma para que funcione simulado, pero lo he armado fisicamente y trabajo perfectamente


----------



## Clematida (Jun 16, 2010)

Hola, tengo una duda acerca de como hacer realmente funcionar este programa, para enviar y recibir datos elegimos un pin transmisor y receptor, pero en mi caso yo la única comunicación que tengo entre el pic y el portatil es por USB, el hercules establece la conexión entre el pic y el pc pero no se reciben datos porque no tengo ningún pic transmisor conectado al portatil, como puedo hacer funcionar el programa? quiero ver en la pantalla del hercules los mensajes que envíe desde el pic.



george.manson.69 dijo:


> Este prgrama hace una comunicacion serial con la compu y el pic...
> 
> si quieres verlo que funcione entra a youtube...y busquen "godness006"
> ahi etsan algunos proyectos que he hecho
> ...


----------



## george.manson.69 (Jun 16, 2010)

Clematida dijo:


> Hola, tengo una duda acerca de como hacer realmente funcionar este programa, para enviar y recibir datos elegimos un pin transmisor y receptor, pero en mi caso yo la única comunicación que tengo entre el pic y el portatil es por USB, el hercules establece la conexión entre el pic y el pc pero no se reciben datos porque no tengo ningún pic transmisor conectado al portatil, como puedo hacer funcionar el programa? quiero ver en la pantalla del hercules los mensajes que envíe desde el pic.


 

mm..tendrias que comprar un cable usb-serial. y despues comprar un max232 y conectarlo al pic...

PC=USB-SERIAL=MAX232=PIC

mas o menos asi...

hay algunas practicas de comunicacion serial aqui:

mcuproyects.blogspot.com


----------



## muessli (Jun 19, 2010)

Hola, alguien tiene idea porque sale esto en proteus? en el log de simulacion de proteus se repite como 10.000 veces y se pone todo lento. El aviso es *"[PIC16 CORE]PC=0x0095. TRISB instruction is deprecated for PIC16628"*, mayormente aparece la direccion 0x0095, algunas pocas veces tambien salen las 0x004C y 0x0094.
El codigo es este:

```
#include <16f628a.h>
#fuses xt,nowdt,nomclr
#use delay (clock = 4000000)
#define use_portb_kbd TRUE
#include <kbd.c>
#use standard_io (a)

void main (){

char k,kant='0';
char pwmh=0,pwml=0;
kbd_init();
PORT_b_PULLUPS(TRUE);

while(1){
         k=kbd_getc();
         if (k=='\0') k=kant;
         
         if ((k=='*') || (k=='#')) k='0'; 
         
         kant=k;
         k=k-48;
         pwmh=k*28;
         pwml=255-pwmh;
         for (pwmh;pwmh>0;pwmh--){
         output_high(pin_A0);}
         
         for (pwml;pwml>0;pwml--){
         output_low(pin_A0);}
       }
}
```
 
MUCHAS GRACIAS


----------



## Eduardo (Jun 19, 2010)

muessli dijo:


> Hola, alguien tiene idea porque sale esto en proteus? en el log de simulacion de proteus se repite como 10.000 veces y se pone todo lento. El aviso es *"[PIC16 CORE]PC=0x0095. TRISB instruction is deprecated for PIC16628"*....


Pos te lo está diciendo "La instrucción TRISB es desaprobada para el 16F628".

Desde hace un par de siglos  Microchip viene desaconsejando la instrucción TRIS, pero por misterios de la industria, se la sigue incluyendo en el código .

Durante cada lectura del teclado se cambia la configuración del puerto, como en esto usa la instrucción TRIS por eso te saltan los trillones de warnings.

*Solución:*
- Desde el CCS, ir a Tools->Device Editor->PIC16F628A->Other Features y poner TRIS=False
==> El código generado ya no incluirá TRIS y funcará como los dioses.

- Enviar un email a CCS preguntando por qué mie*** tiene esa configuración por defecto


----------



## muessli (Jun 21, 2010)

Eduardo, funciono perfecto como dijiste, muchas gracias por tu solucion.
Saludos...
Pd: mail a CCS enviado.:enfadado:


----------



## Clematida (Jun 22, 2010)

george.manson.69 dijo:


> mm..tendrias que comprar un cable usb-serial. y despues comprar un max232 y conectarlo al pic...
> 
> PC=USB-SERIAL=MAX232=PIC
> 
> ...



Me pregunto si habrá una solución más fácil y a mi alcance, quizá si pueda conectar el pin transmisor al pc usando simplemente la placa, hay unos pines en la entrenadora que tienen que ver con el USB pero no entiendo para qué sirven mirando el esquemático.


----------



## robotec (Jun 23, 2010)

que tal, apenas estoy adentrandome al mundo de la programacion en ccs, y me esta gustando y da gusto saber de foros como estos, estaba probando el programa de interrupciones, pero la verdad si es mucha informacion para mi caburarla, les cuento mi problema tengo que hacer un programa con el cual cuente los pulsos de entrada, algo muy sencillo pero que por mas que le leo y leo no logro entenderlo bien espero me puedan asesorar muchas gracias


----------



## EINNER C (Jun 23, 2010)

hola robotec

puedes utilizar la interrupcion por pin, en el caso de un16fxxx la  mayoria, el rb0, y cada vez q ingrese a la interrupcion pues q  incremente una variable,,,, la funcion de interrupcion es como otra  funcion, lo unico es que se ejecuta cuando haya un cambio en dicho pin,,

mas o menos seria asi, pues no estoy en casa para colaborarte con el  program en el momento..

incluir las archivos de cabecera

long var=0;

#INT_EXT
void nombre_funcion()
      {var++;}

void main()
    {
     enable_interrupts(GLOBAL);
     enable_interrupts(INT_EXT);

WHILE(TRUE)
{//bucle infinito}

}

bueno lo demas q necesites hacer, ...

saludos,,,


----------



## robotec (Jun 24, 2010)

muchas gracias einnerc voy a trabajar con lo que me pusiste y ya te dire de mis avances



			
				robotec dijo:
			
		

> muchas gracias einnerc voy a trabajar con lo que me pusiste y ya te dire de mis avances


 agrego el codigo con el cual me estoy basando, lo simulo y nada
#include <16F876a.h>
#use delay (clock=4000000)
#fuses XT,NOWDT,NOPROTECT,PUT,NOBROWNOUT,NOLVP //ordenes para el programador
#include<lcd.c> //libreria manejo lcd

#use fast_io(a)

int count=0;

void main()
{

set_tris_a(0xFF);

lcd_init();
lcd_putc("\f");

setup_timer_0 ( RTCC_EXT_L_TO_H|RTCC_DIV_1); //los impulsos por RA4/T0CKI
set_timer0(56); //si optoacoplador impulsos 100Hz, cada 2sg ++count
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);


while(TRUE){
delay_ms(500);
printf(lcd_putc, "\f%u impulsos", count);
}
}


#INT_TIMER0
void wave_timer() {

set_timer0(56);
++count;

}


----------



## samaelsys (Jun 24, 2010)

Hola amigos me parece interesante todo de lo que han planteado hasta el momento, me gustaria que me ayuden en hacer un programa para controlar un motor paso a paso. Gracias!!!

ahhh se me olvidaba con el PIC16F877 y el puerto serie(RS232) con una interfaz en VB.NET


----------



## EINNER C (Jun 24, 2010)

hola @samaelsys

aqui te pueden ayudar bastante con lo de visual.net

https://www.forosdeelectronica.com/f26/interfaz-puerto-serie-picrs232-v2-00-beta-28156/index3.html

saludos


----------



## samaelsys (Jun 24, 2010)

Gracias amigo, pero sabes ese no es tanto el problema(VB.NET) por el momento, lo que quierop antes es crear el programa que manipule el firmware del PIC16F877 para controlar motores usando el programa PIC C de CCS, gracias, se te agradece.Feliz Día


----------



## pollo rangel (Jun 26, 2010)

HOYA 
COMO LE PUEDO HACER PARA CAMBIAR EL GIRO DE UN MOTOR CD ESTOY USANDO EL PWM  DEL PIC ESTE ES MI PROGRAMA 

#include <16F887.h>
#fuses INTRC,NOPROTECT,NOLVP,NOWDT 
#use delay(clock=8000000)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7)


int duty1=40;
int duty2=40;

void main()

{
char caracter;
output_low(PIN_C1);   
output_low(PIN_C2); 

setup_ccp1(CCP_PWM);  
setup_ccp2(CCP_PWM); 

setup_timer_2(T2_DIV_BY_16, 124, 1);  // 500 Hz     


while(1)  
{
caracter=getc();
	set_pwm1_duty(duty1);                   
	set_pwm2_duty(duty2);                  

  if  (caracter=='a')
		{
			delay_ms(32);
			duty1 += 1;
		}

   if   (caracter=='b')
		{
			delay_ms(32);
			duty1 -= 1;
		} 



 }
}


----------



## muessli (Jun 26, 2010)

Hola, de los que allan probado los ejemplos usb de las anteriores paginas, es normal que al ejecutar cada aplicacion se pidan unos drivers que no estan por ningun lado? donde se consiguen?
Gracias.


----------



## george.manson.69 (Jun 26, 2010)

muessli dijo:


> Hola, de los que allan probado los ejemplos usb de las anteriores paginas, es normal que al ejecutar cada aplicacion se pidan unos drivers que no estan por ningun lado? donde se consiguen?
> Gracias.


 
que raro....cual ejemplo estas probando de las paginas anteriores, ya que procuro subir todo...todos los archivos necesarios para probar el ejemplo...si me puedes decir cual para ayudarte...a lo mejor se me paso en ese ejemplo...



pollo rangel dijo:


> HOYA
> COMO LE PUEDO HACER PARA CAMBIAR EL GIRO DE UN MOTOR CD ESTOY USANDO EL PWM  DEL PIC ESTE ES MI PROGRAMA
> 
> #include <16F887.h>
> ...



Tendras que usar un multiplexor y un solo canal PWM....el multiplexor puedes usar el 74LS138 y el driver para motores el clasico l293...

Simula en proteus el circuito 74LS138 para que veas el funcionamiento y captaras rapidamente la idea ...


----------



## EINNER C (Jun 27, 2010)

hola pollo  rangel

si es necesario dejar un modulo pwm libre, quizas para otra funcion, es buena la idea de george, pero si definitivamente lo necesitas solo para controlar dicho motor, seria mejor q utilizaras ambos para no tener circuiteria extra, hay q aprovechar al maximo la potencia de estos dispositivos, y el l293 q te recominenda es el perfecto para estos casos, basicamente es un puente h.
saludos


----------



## robotec (Jun 28, 2010)

que tal george.manson.69 estaba siguiendo el ejemplo que subiste del reloj con interupciones y la verdad no puedo simularlo al momento de correrlo sencillamente no hace nada, y con ese me estoy basando para lo de las interrupciones ya que tengo que hacer un programa el cual pueda escoger la hora y de ahi se valla para atras como un cronometro saludos


----------



## COSMICO (Jun 28, 2010)

george.manson.69 amigo..
Necesito usar el puerto c del 16f877
detectando un pulsador en cada pin on_off
la sentencia switch, case, puede ser usada para leer cada pin del portc?
Es para no usar tantos if_ else..


----------



## muessli (Jun 28, 2010)

george.manson.69 dijo:


> que raro....cual ejemplo estas probando de las paginas anteriores, ya que procuro subir todo...todos los archivos necesarios para probar el ejemplo...si me puedes decir cual para ayudarte...a lo mejor se me paso en ese ejemplo...



Hola george.manson.69, gracias por responder, la verdad no me funciona ninguno, excepto el USB_BULK_TRANSFER que trae su driver, reinstale los drivers del proteus (7.7 SP2) pero nada, tambien cambie el usb_desc_cdc.h a 08,0x04 y 0x0A,0x00 y nada, tambien probe con el driver de microchip mchpcdc.inf y tampoco..es un lio de drivers parece o ...no se cual es.
Ademas tampoco me funcionaron los proyectos con el puerto serie..asi que no se si sera el proteus... 
Te agredeceria si podes me cuentes como es el lio este..o que tengo mal. Gracias y saludos.


----------



## george.manson.69 (Jun 28, 2010)

muessli dijo:


> Hola george.manson.69, gracias por responder, la verdad no me funciona ninguno, excepto el USB_BULK_TRANSFER que trae su driver, reinstale los drivers del proteus (7.7 SP2) pero nada, tambien cambie el usb_desc_cdc.h a 08,0x04 y 0x0A,0x00 y nada, tambien probe con el driver de microchip mchpcdc.inf y tampoco..es un lio de drivers parece o ...no se cual es.
> Ademas tampoco me funcionaron los proyectos con el puerto serie..asi que no se si sera el proteus...
> Te agredeceria si podes me cuentes como es el lio este..o que tengo mal. Gracias y saludos.



Mmm no puede ser, ni idea de que podria ser , ya que los exemplos que he subido los pruebo y funcionan, lo que podria ser es que, seria muy remotamente que a la simulacion le pongas que este corriendo a 20Mhz el micro...podria ser eso, si es que lo tienes asi...sera otra cosa...al simular no hace nada de nada,, ni aparece un error ni nada?...tienes windows tienes,, ya que mpusbapi.dll no funciona en window VISTA ni 7, solo funciona si esta actualizado el DLL, pero otra cosa lo de puerto serie usando el USB ese debe de funcionar corrrectamente...

Pasos para usar el usb...

1.-Arma el circuito tal como esta el exemplo...o si quiere simplemente abrir el circuito de algun ejemplo que use USB modo CDC (puerto serie)
2.-Despues te pedira unos drivers de los cuales en el exemplo que hallas abierto en la misma carpeta debe de contenerlo o cuando bajaste el archivo por ahi debe de andar, despues de que te pida los driver buscalos en la carpeta correpondiente, he instalalos...y automaticamente estara listo, despues si el exemplo que que bajaste contiene el programa para hacer la accion como manipular 8 led o el que controlas el LCD o no se...(solo para puerto serie), busca el COMx que fue creado despues que hallas intalado los drivers, sino sabes donde ve a buscar los drivers instalados en tu computadora y debde de anda ahi el USB-SERIE y el COMx disponible, ahora conociendo que COMx esta disponible buscalo en el programita y ponle conectar, y el led prendera verde cuando se conecte al programita...


Ahora si es con el BULK es practicamente lo mismo, buscar drivers mmm...instalarlos y executar el porgrama que correponde a la simulacion, y ya!!!...yy Sin NADA de Nada...me avisas....

nota...simulalo sin cambiar el programa, solo bajalo, descomprimelo, y simula.



COSMICO dijo:


> george.manson.69 amigo..
> Necesito usar el puerto c del 16f877
> detectando un pulsador en cada pin on_off
> la sentencia switch, case, puede ser usada para leer cada pin del portc?
> Es para no usar tantos if_ else..




Mi idea seria ser

variable=PORTC; //lee puerto


```
switch(varieble){
    case 0x01: acccion; break;
    case 0x02:
    case 0x03:
    ......
}
```

dependiendo si las resistencias van al ground

espero que te sriva la idea


----------



## EINNER C (Jun 28, 2010)

hola robotec

yo por ahi hace un tiempo hice  un cronometro up/down, con  start,reset,stop y u/d, ademas pues si era descendente el conteo se  podia indicar donde iniciaba, con hh:mm:ss, esto con un teclado 4x4,  pero lo realize en asembler, un poco mas complejo, si de algo te sirve.

claro q no le veria problema pasarlo a c, estoy algo ocupado pero en  cuanto pueda lo realizo y lo subo

ssaludos...


----------



## COSMICO (Jun 28, 2010)

Gracias amigo..
Probare.


----------



## robotec (Jun 29, 2010)

gracias einner se te agradece


----------



## muessli (Jun 29, 2010)

> Mmm no puede ser, ni idea de que podria ser , ya que los exemplos que he subido los pruebo y funcionan, lo que podria ser es que, seria muy remotamente que a la simulacion le pongas que este corriendo a 20Mhz el micro...podria ser eso, si es que lo tienes asi...sera otra cosa...al simular no hace nada de nada,, ni aparece un error ni nada?...tienes windows tienes,, ya que mpusbapi.dll no funciona en window VISTA ni 7, solo funciona si esta actualizado el DLL, pero otra cosa lo de puerto serie usando el USB ese debe de funcionar corrrectamente...



Gracias george.manson.69, urgando y reinstalando y con lo que me dijiste al final funciono, de vuelta gracias y saludos.


----------



## elzytacogelona (Jun 29, 2010)

No seas malo ayudame a aprender a programar en c los microcontroladores...

mplab....ya lo descarge

se que no tiene compilador en c, tambien ya lo descarge.

ahora ya los instale en mi compu...pero...eso es suficiente...?

como escribo? como programo??

he hecho pruebas con programas cortos, como el tuyo por ejemplo, pero y despues que hago??

gracias por tu ayuda!!


----------



## Moyano Jonathan (Jun 30, 2010)

@elzytacogelona: No es que nadie te quiera enseñar a programar , lo que pasa es que nadie te puede dedicar todo su tiempo solo para enseñarte a vos a programar todos tenemos cosas que hacer y no siempre se trata de electrónica, sino de la vida de cada uno ...
Lo que te recomiendo es que primero antes de querer programar cualquier cosa es leer...
C es un lenguaje estructurado ...por lo tanto antes de empezar a programar hay que aprender bien las estructuras.
Luego hay que aprender las funciones básicas como while....for....do while .....etc.
Y recien luego podrías estar empezando a aprender a programar con los ejemplos que a puesto el amigo george.manson.69
Y por último te vuelvo a reiterar....tenes que leer mucho y aprender sobre el lenguaje que vallas a usar antes de ponerte a programar ...de lo contrario te resultará muy complejo...

Una recomendación: Leer algún libro de programación de C para PC y luego ponerte con el C para los PIC ...ya que basicamente son lo mismo ...con las diferencias propias de cada plataforma (PC o PIC)


----------



## george.manson.69 (Jun 30, 2010)

elzytacogelona dijo:


> No seas malo ayudame a aprender a programar en c los microcontroladores...
> 
> mplab....ya lo descarge
> 
> ...




La pregunta no es que hago despues? la pregunta es que quiero hacer?...primero has como dice moyano, empieza sobre lo mas basico, instrucciones como funcionan, las bases , si nunca has porgramado un microcontrolador en algun lenguaje se te va hacer tan complejo, que te aburriras de intentar entener lo que estas haciendo, te recomiendo empezar a programar micros desde cero, usando MPLAB con el lenguaje de bajo nivel que es el ensamblador que tiene por defauilt MPLAB...te recomiendo a que programes primero por hay, para que empiecez a entender mucho mejor las cosas...te lo recomiendo al 100%. pero deplano si quieres aprender directamente C te recomiendo a que busque info en google sobre intrucciones en C, como funcionan? configuraciones de modulos internos del micro, como funcionan? y asi...Los porgramas que subo en este espacio son directos, en pocas palabras es bajar, probar, hacer y entender...Solo es lo que pretendo en este tema programas hechos en CCS C no es nada un curso completo de como porgramar un micro....

Saludos...y Suerte...aqui andaremos....


----------



## robotec (Jun 30, 2010)

que tal amigos, por fin logre entender como hacer el programa que queria, aunque no use interrupciones se los pongo para que lo vean y espero les ayude a entender como a mi me ayudo a conocer mas del lenguaje c

este programa es un contador de pulsos cada vez que oprimas el push tendras un numero y sera impreso en un lcd


#include <16f876a.h>//se determina con el pic a trabajar          
#fuses HS,NOWDT,NOPROTECT,PUT,NOLVP//se configura el pic 
#use delay (clock=20000000)//se configura la velocidad de frecuencia
#define use_portb_lcd TRUE //definimos el portb paa usar el lcd
#include <lcd.c> //se manda a traer la libreria del lcd

void main() //comienza el programa
{
   int i=0,j=0,h=0,g=0,z=0;//e definen las variables para hacer el conteo
   lcd_init();//se inicializa el lcd   
   printf(lcd_putc,"  contador de\n   pulsos");  //ponemos una introduccion 

   do//se eliminan los rebotes mientras es pulsado el boton
   {

   }while(input(PIN_A0)==1);
   printf(lcd_putc,"\f");//borra lo que tenga el lcd         
   lcd_gotoxy(7,1); //nos dirigimos al centro del lcd         
   for(;//ciclo infinito
   {                     
      if(!input(PIN_A0))//checamos si el boton a sido pulsado
      {                  
         do
         { 

         }while(!input(PIN_A0));//se eliminan rebotes
         if(i>9)//si i es mayor a nueve
         {  //entonces ponemos a i a cero de nuevo
            i=0; 
            j++; //incrementamos j                
            if(j>9)//si j es mayor a 9
            {
               J=0;//mandamos a j a cero 
               h++;//incrementamos h
            }
            if(h>9)//si h es mayor a 9 
            {
               h=0;//mandamos a cero
               g++;//incrementamos g
            }
            if(g>9)//si g mayor a 9
            {
               g=0;//igualamos g a cero
               z++;//incrementamos z
            }
            if(z>9)//si z mayor a 9
            {
               z=0;//igualamos a cero a z
               delay_ms(100);
            }

         }
         printf(lcd_putc,"%u%u%u%u%u",z,g,h,j,i); //mandamos a imprimir los datos al lcd
         printf(lcd_putc,"\b\b\b\b\b"); //retrasa el cursor una posicion(escribe encima)
         i++;                        //incremento contador indice tabNum
      }         
   }                     //...infinito
}

espero con ansias puedas subir el codigo del reloj einner saludos y seguire subiendo lo que vallla realizando


----------



## robotec (Jul 1, 2010)

me gustaria saber cual sentencia es mejor para eiminar los rebotes 
 for(;
   {                  //bucle...
      if(!input(PIN_A0))         //¿se ha pulsado el boton?
         {
            delay_ms(151);      //SI -> retardo para evitar los rebotes
            i++;            //incremento contador indice tabBCD
            if(i>9)            //¿se ha mostrado digito 9?
               i=0;         //SI -> restaura valor indice(para mostrar digito 0)
            output_b(tabBCD_); //muestra por portb digito 7 segmentos
         } 
         while(!input(PIN_A0));
         delay_ms(151);         
      }                     //...infinito


o esta
do//se eliminan los rebotes mientras es pulsado el boton
{

}while(input(PIN_A0)==1);
printf(lcd_putc,"\f");//borra lo que tenga el lcd
lcd_gotoxy(7,1); //nos dirigimos al centro del lcd
for(;//ciclo infinito
{
if(!input(PIN_A0))//checamos si el boton a sido pulsado
{
do
{

}while(!input(PIN_A0));//se eliminan rebotes_


----------



## samaelsys (Jul 1, 2010)

Hola Amigos, he querido comenzar por hacer encender un led, al parecer el programa esta bien, pero cuando hago la simulación en proteus me dan errores. Les dejo los archivos por si me regalan su ayuda, GRACIAS

Saludos!!!!!!!


----------



## robotec (Jul 2, 2010)

que tal samaelsys, si solo quieres encender un led no es necesario tantas lineas en tu codigo, para mi solo seria esto
#include <16f877.h>
#fuses HS,NOWDT,NOLVP,NOPROTECT
#use delay(clock=20000000)
#byte TRISB=0x86
#byte PORTB=0x06


void main(void){
   TRISB=0x00;
   PORTB=0x00;
   do{
      output_high(PIN_B0);
      delay_ms(1000);
      }while(TRUE);   

}

o a la mejor quieres hacer otra cosa, si es asi dimeloo y me gustaria poder ayudarte


----------



## samaelsys (Jul 2, 2010)

Gracias robotec, te agradesco tu aporte, probe el programa así y me dio error, no se si le hechaste un viztaso al diseño del circuito, ya q tampoco se mucho acerca de diseños de circuito, a lo mejor algo esta mal conectado.

contestando a tu pregunta y gracias nuevamente por tu ayuda ofrecida, por ahora solo quiero poder encender leds y comenzar a progresar poco a poco, hasta poder controlar un motor paso a paso. espero me ayudes amigo, se te agradece muchiiisimo

Saludos!!!


----------



## EINNER C (Jul 4, 2010)

hola robotec

habia abandonado un poco el foro pues estaba algo ocupado, pero a mas tardar manana subo el cronometro e c, por el momento lo dejo en asembler

cualquier duda aqui estoy.......

saludos

nota: para establecer una hora cuando esta en 000000 se da up/down. 00 00 00 d y sttart, hay se borra el display y va digitando la hora y cuando termines le da start..


----------



## COSMICO (Jul 4, 2010)

samaelsys.
El problema que tienes, es que el proteus no esta cargando el codigo en el pic 
si pinchas sobre [pic16] program property not especified, que esta diciendo 
propiedad del programa no especificada para el pic 16. encontraras que en el menu desplegable
 aparece la forma de cargar el hex cof etc en el pic; esto es por que no lo reconoce..
Debe ser algun tipo de problema en la instalacion de tu proteus, o si es un demo puede ser por ahy..
Te regreso un archivo en mi proteus exactamente igual al tuyo; debe funcionar;en el mio lo hace
pero no el que tu subiste..
Ojo. Estas configurando oscilador Rc en el programa, y estas usando cristal en la simulacion
En la simulacion no importa, pero si lo armas puede causar problemas..
Suerte
Ver el archivo adjunto ENCIENDE_LED.rar


----------



## robotec (Jul 4, 2010)

samaelsys.

la verdad no pude abrir tu dns, pero arme uno, para hacer lo que pides y no me marca error; lo mas seguro como comenta cosmico sea error de instalcion del proteus, te recomiendo lo vuelvas a instalar, y si el problema sigue comentalo para ver la manera de solucionarlo.

einner gracias por tu ayuda, yo sigo en la lucha de poder lograrlo, una ayudadita no me caeria mal saludos


----------



## yeaaa (Jul 8, 2010)

Saludos, la verdad es que este foro esta muy completo y quiero felicitar a todas las personas que contribuyen al conocimiento de las demas personas por medio de ejemplos didacticos

Bueno quisiera ver si me pueden ayudar a mi problema, estoy tratando de usar el puerto serial de la PC conectado a un pic, bueno el programa del pic ya lo tengo, pero el problema es la interfaz de la computadora, e visto los ejemplos expuestos por *george.manson.69 * y quisiera pedirles aver si me pueden facilitar un tutorial sencillo de c#, no quiero algo muy complejo, simplemente con que viniera como crear un codigo sencillo y controlar el puerto serial se los agradeceria mucho


----------



## george.manson.69 (Jul 10, 2010)

yeaaa dijo:


> Saludos, la verdad es que este foro esta muy completo y quiero felicitar a todas las personas que contribuyen al conocimiento de las demas personas por medio de ejemplos didacticos
> 
> Bueno quisiera ver si me pueden ayudar a mi problema, estoy tratando de usar el puerto serial de la PC conectado a un pic, bueno el programa del pic ya lo tengo, pero el problema es la interfaz de la computadora, e visto los ejemplos expuestos por *george.manson.69 * y quisiera pedirles aver si me pueden facilitar un tutorial sencillo de c#, no quiero algo muy complejo, simplemente con que viniera como crear un codigo sencillo y controlar el puerto serial se los agradeceria mucho



He subido un pequeño ejemplo en este tema
de programas hechos en C18
y utiliza un software hecho en c#express 2010, para que te des una idea como se hace un enlace serial. Espero que sea de ayuda...Saludos


----------



## EINNER C (Jul 11, 2010)

hola yeaaa

creo q esto te puede servir bastante

https://www.forosdeelectronica.com/f26/interfaz-puerto-serie-picrs232-v2-00-beta-28156/

y en el blog del amigo meta hay unos buenos tutoriales
saludos


----------



## WolfAlvein (Jul 13, 2010)

hola a todos mis amigos les escribo el dia de hoy por q necesito hacer que el 16F84A o el 16F628, sean capaces de recibir un voltaje analogico dado por un termopar que se encuentra conectado a los PIN_A0 y PIN_A1. verdaderamente soy un novato con respecto a la programacion de este estilo y estoy usando el lenguaje C atravez del programa llamado CCS C pero no conosco el set de instrucciones que pueden recivir los PIC.

ahora la cuestion es q e leido q los 16f84A y el 16f628 no son capaces de hacer la convercion A/D que necesito q realicen ya q una ves obtenido el valor del termopar en voltaje se supone que voy a dar 8 salidas digitales que van 4 a un 7 segmento y los otros 4 a otro 7 segmento con sus display apropiado.

pero igual me interesa conocer como realizar el codigo si porfavor me pueden ayudar se lo agradeceria muchisimo saludos a todos.


----------



## samaelsys (Jul 13, 2010)

cosmico y robotec mil gracias por su ayuda...

cosmico con el diseño q me eniviaste funciona a la perfección, quite lo del oscilador RC y sigue funcionando bien, ahora le he instalado un motor paso a paso, pero todavia no me gira por completo, estoy investigando para eso!! por ahora lo conecto directamente al pic, pero en el futuro kiero hacerlo con el ULN2803.

gracias amigos, espero me puedan ayudar siempre!!

saludos!!!!


----------



## Alvaroke1 (Jul 17, 2010)

hola!..como veran soy nuevo en el foro y la verdad este tema esta muy interesante con muchisimos ejemplos didacticos...me interesa mucho introducirme en el mundo de la programacion de pics con C, pero tengo uan duda....estuve viendo el ccs pero vi que es solamente de pago, o existe para bajarselo gratis?? de antemano gracias por la respuesta.


----------



## Moyano Jonathan (Jul 17, 2010)

No , es de pago su licencia vale creo que U$S 100. Para programar gratis en C podés optar por el C18 lite que lo ofrece microchip pero solo sirve para PIC's 18F ahora también creo que está el HI - TEC lite para PIC16 pero no lo he probado.


----------



## Alvaroke1 (Jul 17, 2010)

Moyano Jonathan dijo:


> No , es de pago su licencia vale creo que U$S 100. Para programar gratis en C podés optar por el C18 lite que lo ofrece microchip pero solo sirve para PIC's 18F ahora también creo que está el HI - TEC lite para PIC16 pero no lo he probado.




um... =/ q mala suerte...haber leere acerca del HI -TEC gracias! ^^


----------



## juankruiz (Jul 17, 2010)

hola como estan todos les pido su ayuda para q me ayuden en un codigo aqui les adjunto un archivo q tengo donde solo es un contador de dos digitos multiplexado.
pero ahora me piden que en vez de usar los display use leds para que se vea como codigo binario ademas de mostrar segundos minutos y horas y que me de 10 tonos audibles cada 10 segundos si uds tienen una idea para terminar este codigo y modificarle les agradezco 

adjunto va el documento en word del multiplexado el otro doc es el dsn en proteus del resultado final como debe quedar solo habria q cargarle el coigo que les pido q me ayuden
 gracias

;*********************************************************************
;     CONTADOR DE DOS DIGITOS MULTIPLEXADO CON DISPLAY DE 
;     SIETE SEGMENTOS USANDO EL TMR0 COMO BASE DE TIEMPO 
;         DE 10ms  (10x100) PARA INCREMENTAR SU VALOR CADA 
;                                          SEGUNDO DE 00-99
;*********************************************************************
; 		NOMBRE:			p5c_2dm.asm
;		FECHA:				21/06/2010
;		VERSION:			1.00
;		PROGRAMADOR:		Juan Ruiz
;*********************************************************************
;			DESCRIPCION: 
;Se trata de incrementar un contador cada segundo y mostrar 
;su valor en dos displays colocados en el puerto B usando la
;técnica de multiplexación. Uno para unidades y otro para
;decenas. Los displays se refrescan cada 20ms. El tmr0 se 
;programa para que genere una interrupción cada 0.01 seg.
; (10 mS) que se repetirá 100 veces con el objeto de activar 
;el conteo cada 1000 mS. Use un reloj de 4MHz.
;*********************************************************************
;DIRECTIVAS

	LIST		p=16F887		;Tipo de microcontrolador
	INCLUDE 	P16F887.INC		;Define los SFRs y bits del 
						;P16F887

	__CONFIG _CONFIG1, _CP_OFF&_WDT_OFF&_XT_OSC	
						;Setea parámetros de 
						configuración

	errorlevel	 -302			;Deshabilita mensajes de 
						;advertencia por cambio 
						;bancos			
	UDATA	
	contador	RES 	1		;Cuenta 100 interrupciones
	unidades	RES 	1
	uni_cod		RES 	1
	decenas	RES 	1
	dec_cod	RES 	1
	sel		RES 	1
;*********************************************************************
;PROGRAMA
	ORG	0x00		;Vector de RESET
	GOTO	MAIN
	ORG	0x04		;Vector de interrupción
	GOTO	Interrupcion	;Va a rutina de interrupción

;DURANTE LA INTERRUPCION SE CUENTAN 100 INTERRUPCIONES
;PARA COMPLETAR 10x100=1000ms. 			
Interrupcion  
	movf	sel,w		;Se mueve a si mismo para afectar bandera
	btfss	STATUS,2	;sel=0 refresca dig1; sel=1 refresca dig2
	goto	dig2
dig1	 	
	movf	unidades,w  
	call	tabla
	movwf	uni_cod
	movf 	uni_cod,w
	bsf	PORTA,0
	bsf	PORTA,1
	movwf	PORTB
	bcf	PORTA,0
	comf	sel,f
	goto 	dec
dig2	
	movf	decenas,w  
	call		tabla
	movwf	dec_cod
	movf 	dec_cod,w
	bsf	PORTA,0
	bsf	PORTA,1
	movwf	PORTB
	bcf	PORTA,1
	comf	sel,f	
dec

	decfsz 	contador,f		;cuenta espacios de 10ms
	goto	Seguir			;Aún, no son 100 interrupciones
	INCF 	unidades,f		;Ahora sí 10x100=1000ms=1seg
	movlw	.10
	subwf	unidades,w
	btfss	STATUS,2
	goto	cont
	clrf	unidades
	incf	decenas
	movlw	.10
	subwf	decenas,w
	btfss	STATUS,2
	goto	cont
	clrf	decenas

cont
 	movlw 	.100		
       	movwf 	contador   		;Carga contador con 100

Seguir   
	bcf	INTCON,T0IF		;Repone flag del TMR0 
	movlw 	~.39
       	movwf 	TMR0      		;Repone el TMR0 con ~.39
       	retfie				;Retorno de interrupción

MAIN
;SETEO DE PUERTOS 
	BANKSEL	ANSEL		;Selecciona el Bank3
	CLRF		ANSEL
	CLRF		ANSELH
	BANKSEL 	TRISA		;Selecciona el Bank1
	CLRF		TRISA		;PORTA configurado como salida
	CLRF		TRISB		;PORTB configurado como salida

;INICIALIZACION	      
	BANKSEL 	PORTA		;Selecciona el Bank0		
	CLRF		PORTA		;Borra latch de salida de PORTB
	CLRF		PORTB		;Borra latch de salida de PORTC
	clrf		unidades
	clrf		decenas
	clrf		sel			                                                                         

;PROGRAMACION DEL TMR0
	banksel		OPTION_REG  	;Selecciona el Bank1
	movlw		b'00000111'	;TMR0 como temporizador
	movwf		OPTION_REG  	;con preescaler de 256 
	BANKSEL	TMR0		;Selecciona el Bank0
	movlw		.217		;Valor decimal 217	
	movwf		TMR0		;Carga el TMR0 con 217

;PROGRAMACION DE INTERRUPCION
	movlw	b'10100000'
	movwf	INTCON			;Activa la interrupción del TMR0
	movlw	.100			;Cantidad de interrupciones a contar
	movwf	contador		;Nº de veces a repetir la interrupción

Loop			
	nop
	goto 	Loop

; TABLA DE CONVERSION---------------------------------------------------------

tabla
        	ADDWF   PCL,F       	; PCL + W -> W
					; El PCL se incrementa con el 
					; valor de W proporcionando un 
					; salto
       	RETLW   0x3F     	; Retorna con el código del 0
	RETLW	0x06		; Retorna con el código del 1
	RETLW	0x5B		; Retorna con el código del 2
	RETLW	0x4F		; Retorna con el código del 3
	RETLW	0x66		; Retorna con el código del 4
	RETLW	0x6D		; Retorna con el código del 5
	RETLW	0x7D		; Retorna con el código del 6
	RETLW	0x07		; Retorna con el código del 7
	RETLW	0x7F		; Retorna con el código del 8
	RETLW	0x67		; Retorna con el código del 9
	END			; Fin del programa fuente

;CALCULO DEL VALOR A CARGAR EN TMR0 A 4MHz
;PARA OBTENER TEMPORIZACION DE 10 MILISEGUNDOS
;CON PREESCALADOR DE 1:256
;Temporización=(4Tosc)(256-ValorTMR0)(preescalador)
;0.010=(4Tosc)(256-ValorTMR0)(256)
;ValorTMR0=217


----------



## JvLIO (Jul 17, 2010)

Vna pregvnta aca tv en el lengvaje C NO VSAS subrutina como en el assembler por favor respondan ya que yo vso el assembler GRACIAS ANTE MANO


----------



## samaelsys (Jul 18, 2010)

alvaroke 1, el ccs si es pagado pero podes encontrarlo en internet rebuscandote....
yo tengo el instalador...
saludos....


----------



## samaelsys (Jul 19, 2010)

Hola Amigos, les cuento que he avanzado mucho en el manejo de los motores paso a paso tanto en sentido horario como antihorario, ahora les pido sus tan valiosa ayuda en la recepción de datos del puerto serie por medio del pic, yo uso esto:

char parametros;

parametros = getchar();

pero la verdad no se si es la forma correcta, además de eso no se como sincronizar mi aplicación en VB.NET con el circuito simulado en Proteus.

Espero me puedan ayudar

Saludossss......


----------



## george.manson.69 (Jul 20, 2010)

samaelsys dijo:


> Hola Amigos, les cuento que he avanzado mucho en el manejo de los motores paso a paso tanto en sentido horario como antihorario, ahora les pido sus tan valiosa ayuda en la recepción de datos del puerto serie por medio del pic, yo uso esto:
> 
> char parametros;
> 
> ...


 
Usa el software _*Virtual Serial Port*_ es un porgrama para crear puertos virtuales o COM virtuales...googlea para encontrarlo
saludos


----------



## muessli (Jul 22, 2010)

hola, alguien sabe que ventaja o desventaja tiene usar un ciclo infinito como while(true) comparado con un label - goto label?
Gracias y saludos


----------



## Eduardo (Jul 22, 2010)

muessli dijo:


> hola, alguien sabe que ventaja o desventaja tiene usar un ciclo infinito como while(true) comparado con un label - goto label?
> Gracias y saludos


En un caso *como ese* la única diferencia es estética.  La legibilidad no cambia gran cosa y el código generado es el mismo.

En general, un código sin goto es más legible que con goto. Pero la _elegancia_ y _limpieza_ de un código pasa lejos más por la habilidad del programador que por si usa goto.

La verdadera razón por la que *no conviene el goto*, es porque al no poder determinar el compilador el orden en que se ejecutan las instrucciones (porque se salta de cualquier lado a cualquier lado), le fracasan los criterios de optimización.


----------



## muessli (Jul 22, 2010)

Gracias Eduardo, ta clarito.
Saludos


----------



## muessli (Jul 24, 2010)

Hola, estoy intentado realizar un menu con lcd, pero evidentemente tengo un error en la estructura de seleccion, simulandolo en proteus se ve bien el primer menu y entra a la funcion op1, pero cuando presiono "abajo" (el siguiente menu) nunca pasa y se queda trabado. Alguien puede aclararme en donde metí la pata?
Soy nuevo en el ccs, antes programaba en picbasic y este menu lo habia hecho en 15 minutos con basic...y funcionaba perfecto, sin embargo la estructura de c se la ve mas ordenada, espero no haberme equivocado en el cambio.
Gracias


```
#include <16f628a.h>
#use delay(clock=4000000)
#fuses nowdt,nomclr,intrc
#define use_portb_lcd TRUE
#include <lcd.c>

void op1(VOID);
void op2(void);
void op3(void);

void main(){

  lcd_init();
  int1 b1;
  b1=1;

  set_tris_a(0b0000111);
  set_tris_b(0x00);
  
 
 do{
                        
    switch (b1){
                  case 1: 
                         printf(lcd_putc,"\f* Opcion 1\n  Opcion 2");
                         delay_ms(100);
                         if (input(pin_a0)==0) b1=b1+2;
                         if (input(pin_a1)==0) op1();
                         if (input(pin_a2)==0) b1=b1+1;
                       
                         break;
                  case 2: 
                         printf(lcd_putc,"\f  Opcion 1\n* Opcion 2");
                         delay_ms(100);
                         if (input(pin_a0)==0) b1=b1-1;
                         if (input(pin_a1)==0) op2();
                         if (input(pin_a2)==0) b1=b1+1;
                         
                        break; 
                  case 3: 
                        printf(lcd_putc,"\f  Opcion 2\n* Opcion 3");
                        delay_ms(100);
                         if (input(pin_a0)==0) b1=b1-1;
                         if (input(pin_a1)==0) op3();
                         if (input(pin_a2)==0) b1=1;
                         
                       break;
}
 }while(1);
 
}

void op1(){
           
           printf(lcd_putc,"\fEsta es la Op 1");
        delay_ms(2000);
   }


void op2(){
           printf(lcd_putc,"\fEsta es la Op 2");
        delay_ms(2000);
   }

void op3(){
           printf(lcd_putc,"\fEsta es la Op 3");
        delay_ms(2000);
   }
```


----------



## Eduardo (Jul 24, 2010)

A la variable b1 la tenés declarada como bit (int1) ==> Jamás podrá tomar valores como 2 y 3. Cuando hacés el primer b1=b1+1 el resultado es 0.

Además revisá lo que hacés en el switch caso 1, porque si pin_a0 y pin_a2 están en 1 ==> si b1 estuviera bien declarada pasaría a valer 4.



PD. 
Esos b1=b1+1,b1=b1-1 y b1=b1+2  son muy de Basic. Por favor, en C usá b1++ , b1-- y b1+=2


----------



## g.corallo (Jul 24, 2010)

muy buen aporte me sirvio mucho

saludos.


----------



## muessli (Jul 26, 2010)

> A la variable b1 la tenés declarada como bit (int1) ==> Jamás podrá tomar valores como 2 y 3. Cuando hacés el primer b1=b1+1 el resultado es 0.
> 
> Además revisá lo que hacés en el switch caso 1, porque si pin_a0 y pin_a2 están en 1 ==> si b1 estuviera bien declarada pasaría a valer 4.



Uy que abriboca, tenes toda la razon Eduardo, lo que paso fue que al comienzo pense hacerlo con banderas, despues cambie de idea y esa variable quedo mal definida, Gracias ademas por recordarme lo de los incrementos, es que no estaba bien seguro se era b++ o ++b, asi que lo puse del modo mas basio para ver funcionameinto, sin embargo en lugar de incrementar ahora puse directamente los valores de los case, es decir if (input(pin_a2)==0) b1=2; y asi. Solo le faltaria agragarle unos antirrebote a los pulsadores y quedaria aceptable.
Ey Eduardo mil gracias por notarme mi error y los consejos. 
Gran saludo.


----------



## samaelsys (Jul 27, 2010)

Buen día amigos, les cuento que he avanzado en el manejo  del pi16f877 y controlar motores
pero ahora tengo un problem con el envio y recepción de datos del puerto serie, el problema se me presenta en el archivo input.c

no se que es lo que pasa!!!

si me pueden ayudar, les agradeceré infinitamente....

Saludos.........


----------



## samaelsys (Jul 28, 2010)

Bueno amigos, no he podido solucionar el problema, acá dejo el proyecto completo así como el circuito en Proteus, espero me puedan ayudar, ya que me interesa recibir y enviar datos por el puerto rs232, espero su ayuda...

saludos.....


----------



## dragondgold (Jul 29, 2010)

Hola, a ver si pueden ayudarme con este programa que ya me tiene loco. No logro que compile, me da un error en la libreria de lcd.c diciendo que no sabe lo que es la instruccion delay_ms() lo cual es muy raro. Espero puedan ayudarme.

Saludos


```
#include <16F628.h>
#include <lcd.c>
#use delay (clock=4000000)
#fuses NOMCLR, NOWDT, NOPROTECT
#byte PORTB = 0x06
#byte TRISB = 0x86

//lcd_gotoxy(1,1);
//            printf(lcd_putc, "HOLA");

int SENSOR;
int32 TAPADO;
int32 LIBRE;

VOID main(VOID){
TRISB = 0b00000001;
PORTB = 0;
SENSOR, LIBRE, TAPADO = 0;
init_lcd();

         WHILE (1){

         IF(input(PIN_B0)==0){
            
            IF(SENSOR==0){
               ++TAPADO;
               SENSOR = 0;
            }
         
            IF(SENSOR==1){
               TAPADO, LIBRE = 0;
               SENSOR = 0;
            }
         }
/////////////////////////////////////////////////////////////////////////// E(input(PIN_B1)
         IF(input(PIN_B0)==1){
         
            IF(SENSOR==0){
               LIBRE,TAPADO = 0;
               SENSOR = 1;
            }
            
            IF(SENSOR==1){
               ++LIBRE;
               SENSOR = 1;
            }
         }
///////////////////////////////////////////////////////////////////////////         
         IF(LIBRE>=50000){
            output_high(PIN_B1);
             
         }
         IF(LIBRE<50000){
            output_low(PIN_B1);
         }
         
         
         IF(TAPADO>=100000){
            output_high(PIN_B2);
         }
         IF(TAPADO<100000){
            output_low(PIN_B2);
         }
         }
}
```


----------



## Eduardo (Jul 29, 2010)

Estás declarando el clock para calcular los retardos (#use delay (clock=4000000)) *después* de #include <lcd.c> 

Otro error es cuando llamás a init_lcd() ==> la rutina se llama *lcd_init()*


----------



## dragondgold (Jul 29, 2010)

Ooooo muchisimas gracias ya lose para la proxima!!

Saludos!!


----------



## samaelsys (Jul 30, 2010)

Hola amigos!!, como les habia planteado con anterioridad el problema que tengo es similar al de  dragondgold solo que mi problema es con el método getc() que me da error al compilarlo y abre el archivo input.c cuando lo hago y señala el metodo, no se que hacer

espero sus ayuda

saludos...


----------



## Eduardo (Jul 30, 2010)

samaelsys dijo:


> Hola amigos!!, como les habia planteado con anterioridad el problema que tengo es similar al de  dragondgold solo que mi problema es con el método getc() que me da error al compilarlo y abre el archivo input.c cuando lo hago y señala el metodo, no se que hacer
> * espero sus ayuda*
> saludos...


Empezá ayudando vos ==> Al código lo dejaste lleno de líneas anuladas (con // ) y parece que esperás que la gente se tome el trabajo de descifrar cuáles líneas son de prueba y cuales no.
Tampoco está claro como es el comando que hay que escribir en el Terminal.

Lo único que salta a la vista es que tenés invertida RX-TX entre COMPIM y el MAX232 y estás cortocircuitando la salida R1OUT con el TX del Terminal.


----------



## dragondgold (Jul 30, 2010)

Hola, bueno gracias a Eduardo pude avanzar muchísimo en mi proyecto. Les vengo con un planteo que no pude solucionar. Les comento un poco para que entiendan. El programa es un sensor para una cosechadora que debe detectar cuando no hay mas semillas y cuando se tapo la salida. Utilizo un emisor infrarrojo a 38KHz y su respectivo receptor para que de acuerdo a si el rayo se corta del todo o nunca es cortado sepa si no hay semillas o si se tapo la salida. el problema es que uso 8 sensores y para ello creo 8 registros en la RAM llamados sensores, TAPADO y LIBRE. Incremento una variable que me provoca un incremento en los registros ya que uso matrices. El problema es que necesito incrementar también el pin que testea la señal PIN_B0 incrementarlo a PIN_B1 por ejemplo, para ello utilice una matriz que incrementando el valor me va colocando los diferentes pines, pero no funciona cuando lo simulo y no se por que pueda ser. Les dejo el programa y la simulación a ver si me pueden dar una mano.

Saludos y gracias!!


```
//0 = OBJETO            1 = NADA 
#include <16F877A.h>
#use delay (clock=4000000)
#include <lcd.c>
#fuses XT, NOWDT, NOPROTECT
#byte PORTB = 0x06
#byte TRISB = 0x86
/////////////////////////////////////////////////////////////
int SENSOR[];
int32 TAPADO[];
int32 LIBRE[];
int DY[];
int PIN[] = (PIN_B0, PIN_B1, PIN_B2, PIN_B3, PIN_B4, PIN_B5, PIN_B6, PIN_B7); 
int s = 1;
/////////////////////////////////////////////////////////////
VOID main(VOID){
TRISB = 1;
PORTB = 0;
SENSOR, LIBRE, TAPADO = 0;
lcd_init();
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
         WHILE (1){

         IF(input(PIN[s])==0){
            
            IF(SENSOR[s]==0){
               ++TAPADO[s];
               SENSOR[s] = 0;
            }
         
            IF(SENSOR[s]==1){
               TAPADO[s], LIBRE[s] = 0;
               SENSOR[s] = 0;
            }
         }
/////////////////////////////////////////////////////////////////////////// 
         IF(input(PIN[s])==1){
         
            IF(SENSOR[s]==0){
               LIBRE[s],TAPADO[s] = 0;
               SENSOR[s] = 1;
            }
            
            IF(SENSOR[s]==1){
               ++LIBRE[s];
               SENSOR[s] = 1;
            }
         }
///////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
         IF(LIBRE[s]>=5000){
            
            lcd_gotoxy(1,1);
            printf(lcd_putc, "SIN SEMILLAS");
            lcd_putc('\n');
            printf(lcd_putc, "BOCA:%u",s);
            DY[0]=0;
                               }
         IF(LIBRE[s]<5000){
            
            IF(DY[0]==0){
            lcd_putc('\f');
            lcd_gotoxy(1,1);           
            printf(lcd_putc, "OK");
            DY[0]=1;
            }
         }
        
//////////////////////////////////////////////////////////////////////////      
         IF(TAPADO[s]>=5000){
            
            lcd_gotoxy(1,1);
            printf(lcd_putc, "TAPADO");
            lcd_putc('\n');
            printf(lcd_putc, "BOCA:%u",s);
            DY[1]=0;
                     }
         IF(TAPADO[s]<5000){
            
             IF(DY[1]==0){
            lcd_putc('\f');
            lcd_gotoxy(1,1);           
            printf(lcd_putc, "OK");
            DY[1]=1;
             }
                     }
         }

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

           
}
```


----------



## magdalena (Jul 30, 2010)

hola q tal como estan!!! los aportes q estan dando al foro estan increibles... me he alejado un poco del foro por algunos motivos de ocupacion... 
Les cuento q todavia sigo con el problema de las interrupciones... q noc como utilizarlas... en que momento activalarlas y desactivarlas... noc si me puedan ayudar... explicarme como mismo funcionan... pero plis paso a paso para poder entender bien...
Gracias...


----------



## Eduardo (Jul 31, 2010)

Esto está mal declarado:

```
/////////////////////////////////////////////////////////////
int SENSOR[];
int32 TAPADO[];
int32 LIBRE[];
int DY[];
int PIN[] = (PIN_B0, PIN_B1, PIN_B2, PIN_B3, PIN_B4, PIN_B5, PIN_B6, PIN_B7); 
int s = 1;
/////////////////////////////////////////////////////////////
```
No estás declarando el tamaño de los vectores ==> Como suponés que va a saber acomodarlos? Solamente en PIN[] se puede saber el tamaño. Un compilador no es una madre...
Debería saltar error durante la compilación, pero no lo hace (bug). Te termina asignando 1 byte a todos, y cuando escribís DY[1] le escribe encima a PIN[]

También está mal la sintaxis, es:
  int PIN[8] = *{*PIN_B0, PIN_B1, PIN_B2, PIN_B3, PIN_B4, PIN_B5, PIN_B6, PIN_B7*}*;

Los índices de los vectores empiezan en 0, y vos empezás con s=1.

Tampoco incrementás "s" en ningún lado.


----------



## dragondgold (Jul 31, 2010)

Bueno, el incremento de s lo elimine por ahora porque era una etapa de prueba lo de los {} en ves de () en la variable PIN me di cuenta después, error mio. De acuerdo con lo que mencionas de no colocar ningún numero para asignar la cantidad de variables dentro de PIN, según mi libro de C si no coloco nada el compilador me toma la cantidad de variables de acuerdo a la cantidad de valores que yo le asigne entre los {}. Anoche lo analice un poco mas y fui descubriendo errores, gracias nuevamente por la ayuda prestada en cuanto lo tenga armado y funcionando lo posteo.

Saludos y muchísimas  gracias!!


----------



## Eduardo (Jul 31, 2010)

dragondgold dijo:


> ...según mi libro de C si no coloco nada el compilador me toma la cantidad de variables de acuerdo a la cantidad de valores que yo le asigne entre los {}.


Por eso puse que sólo en PIN[] se podía saber el tamaño.

Pero ojo, CCS es una colección de bugs.  
Con arrays bidimensionales en C basta declarar el número de columnas y las filas las saca de lo declarado entre {} .  
Pero al menos en la versión que yo tengo (4.104), si el array es de constantes (const int X[n][]) te lo llena con cualquier cosa. Sólo declarando explícitamente las filas lo arma bien.


----------



## dragondgold (Jul 31, 2010)

Muy interesante lo que comentas Eduardo. Convendría pasarse a programar C con MPLAB o HITECH? Tengo la misma versión de CCS que vos y creo que es la ultima.

Saludos


----------



## ivan_mzr (Ago 4, 2010)

Que compilador es recomendado?, yo tambien estoy por empesar con C y no por cual irme


----------



## josb86 (Ago 4, 2010)

george.manson.69 dijo:


> hola voy a poner todos los programas que he hecho en ccs c compilado en mplab...soy uevo en este foro y como todos estube investgando como funciona nada funcion.
> 
> este es un simple parpadeo de un led...
> (los programs fueron hechos por mi no por copy paste de otros citios)
> ...



hola como están, estoy comenzando con ccs generalmente uso basic pero manejo bastante bien c++ y quiero aprender a programar pic pero tengo algunas preguntas.

en este primer ejemplo tu colocas :
#include<16f628a.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)
#byte TRISB=0x86
#byte PORTB=0x06 

y si uno entra a 16f876a que es el que estoy utilizando yo
me muestra:
#define PIN_A0  40
#define PIN_A1  41
#define PIN_A2  42
#define PIN_A3  43
#define PIN_A4  44
#define PIN_A5  45

#define PIN_B0  48
#define PIN_B1  49
#define PIN_B2  50
#define PIN_B3  51
#define PIN_B4  52
#define PIN_B5  53
#define PIN_B6  54
#define PIN_B7  55

#define PIN_C0  56
#define PIN_C1  57
#define PIN_C2  58
#define PIN_C3  59
#define PIN_C4  60
#define PIN_C5  61
#define PIN_C6  62
#define PIN_C7  63

por que entonces colocas "#byte PORTB=0x06" ya en el "#include<16f628a.h>" no esta definido todo esto?


----------



## Eduardo (Ago 4, 2010)

josb86 dijo:


> ...por que entonces colocas "#byte PORTB=0x06" ya en el "#include<16f628a.h>" no esta definido todo esto?


No. Además el significado de #byte es diferente al de #define.

Si te quedan dudas, o bien mirá el contenido del 16F628A.h o bien tratá de compilarlo sin esa línea.


----------



## josb86 (Ago 4, 2010)

Eduardo dijo:


> No. Además el significado de #byte es diferente al de #define.
> 
> Si te quedan dudas, o bien mirá el contenido del 16F628A.h o bien tratá de compilarlo sin esa línea.



, es para darle un nombre completo al puerto b?
corrí este programa

#include <16C84.H> /* tipo de PIC */
#use delay( clock = 4000000 ) /* reloj de 4 MHz */
#byte puerto_b = 06 /* dirección del puerto B */
void main( void )
{
set_tris_b( 0x00 ); /* puerto B como salida */
puerto_b = 0; /* apaga todos los led */
do{
delay_us( 1000 ); /* retardo de 1000 (seg. */
bit_set( puerto_b, 7 ); /* enciende el led RB7 */
delay_us( 1000 ); /* espera 1 ms*/
bit_clear( puerto_b, 7); /* apaga el led */
} while( TRUE ); /* Repetir siempre */
}


----------



## Eduardo (Ago 4, 2010)

#byte  nombre = 0xnn  ubica la variable nombre en la dirección 0xnn.
Como 0x06 es la dirección del puerto B, lo que escribas en nombre es lo que vas a tener en los pines.  
Cuando el puerto no se usa como byte, sino como una mezcla de entradas y salidas de 1 o varios bits, se declara una estructura y se la asigna a esa dirección.

#define nombre xxxx yyy zzzz....   en cambio, reemplaza cada aparición de nombre por xxxx yyy zzzz.... (durante la compilación)


----------



## josb86 (Ago 5, 2010)

tengo otra pregunta en basic pro hay una instrucción que es pulsin:

PULSIN PORTB.4,1,W3 ' Measure high pulse on Pin4 stored in W3

la cual sirve para saber el tiempo entre las partes positivas o negativas de una señal a la entrada de algun pin y guardarlo en una variable w3, mi pregunta es ¿existe algun comando asi en ccs c?


----------



## gollazo (Ago 6, 2010)

Ola a todos baje el proyecto de george de la matriz de 8x8 en c y la verdad esta muy bueno le entiendo mas al c que al asmpero lo intento practicar mi duda es que como le puedo hacer para que la letra se deslize de derecha a izquiersa como los letreros electronicos espero puedan decirme que intruccion usar o como quedaria el codigo de antemano gracias 

posdata. este post esta genial sigan asi todos


----------



## COSMICO (Ago 6, 2010)

Busca en este mismo tema mas atras,esa pregunta ya fue resuelta..
Un saludo.


----------



## magdalena (Ago 7, 2010)

sigo con mi duda sobre interrupciones!!! plis si alguien puede ayudarme un poquito se lo agradeceria mucho!!!


----------



## gollazo (Ago 7, 2010)

ya encontre el programa de la matriz aora surguio otro problema ya tengo el material fisicamente pero cuando conecto todo la matriz se enciende pero no hace ninguna letra no se si mi matriz de 8x8 tenga pines ya designados ejemplo pin 1 el 2 etc o pueda poner lo pines como quiera


----------



## EINNER C (Ago 8, 2010)

hola gollazo

a mi me surgio ese poblema cuando la utilize por primera vez, y lo que pasa es q los pines de la matriz no estan en orden, tienes q, con ayuda de un multimetro puede ser, identificar las columnas y las filas y luego de ello conectar como es debido, asi saldra el mensaje q quieres, 
me explico un poco mejor,,,  hay matrices donde los leds se activan con las filas en anodo y las columnas en catodo, y otras de forma inversa, asi que hay que ubicar puede ser tierra en un pin y vcc en los demas, te encendera bn toda una fila o toda una columna, si no pasa nada, pon vcc en ese pin y tierra en los demas, y veras una fila o una columna encendida, asi identificaras que pines corresponden a las columnas y cuales a la filas

espero le sirva.... saludos.......

no olvides que el pograma tiene q estar adecuado para activar las filas y las columnas segun la matriz q tienes.......



magdalena dijo:


> sigo con mi duda sobre interrupciones!!! plis si alguien puede ayudarme un poquito se lo agradeceria mucho!!!



que duda tienes mas especificamente, como realizar cualquier tipo de interrupcion? ademas q compilador trabajas pic ccs, mikroc,..., asembler,,,, ya las he manejo y espero poder colaborarte

saludos...........


----------



## gollazo (Ago 8, 2010)

Hola EINNER C me sirvio de mucho tu ayuda gracias ya lo conecte y quedo de lujo aora el siguiente reto es que de deslize mi letrero .COSMICO me dijo que ojas mas atras estaba la respuesta pero no lo encuentro XD voy a buscarlo bien espero y lo encuentre


Otra duda que tengo es porque la matriz de led 8x8 me parpadea mucho y quiero que se vea mejor pero no se si es el crystal o el tiempo que le doy para que pase a la siguiente leta el tiempo de de 5ms


----------



## EINNER C (Ago 9, 2010)

gollazo dijo:


> Otra duda que tengo es porque la matriz de led 8x8 me parpadea mucho y  quiero que se vea mejor pero no se si es el crystal o el tiempo que le  doy para que pase a la siguiente leta el tiempo de de 5ms



pues no estoy muy seguro pero lo q creo, y si no estoy mal, lo mas  normal y para q se vea fluido es q se muestren 30 fps, y creo q tu  tiempo es muy grande ya q son 8 columnas, deberias dejarlo en 2ms, asi  aseguras q se vea bn, y el micro vaa responder sin dudda.....


----------



## banistelrroy (Ago 9, 2010)

hola soy nuevo en el foro y mi pregunta es alguien encontrado el programa para enviar y recibir datos por el puerto usb en mplab o vasic gracias de ante mano soy nuevo y estoy preocupado por un trabajo que tengo que hcer en un curso....gracias se que me podran ayudar


----------



## samaelsys (Ago 24, 2010)

Buenas tardes amigos, sigo con el control de motores paso a paso, todo ha marchado bien hasta que implemente la funcion kbhit(), ya que no entra al ciclo el código es algo así:
// ESTO ES DENTRO DEL MAIN
while(1){
      int a=0;
      delay_ms(1000);
      puts("running......");
      if (kbhit()){
         char parametros[20];
         int g;
         gets(parametros);
         m0= (parametros[0]);
         m1= (parametros[1]);
         m2= (parametros[2])-48;

bueno esto funcionaba mas que bien antes de aplicarle el "if (kbhit()){", pero ahora no ejecuta nada ya que necesito capturar una cadena completa que se envia desde una interfaz en VB.NET, he investigado y todo me conduce a el uso de "getc()", pero veo que solo sirve para capturar un carácter; pero ya aplicandolo descubri que captura hasta 2 carácteres, por eso les pido su ayuda.

Espero noticias pronto de uds.

Saludos


----------



## george.manson.69 (Ago 25, 2010)

samaelsys dijo:


> Buenas tardes amigos, sigo con el control de motores paso a paso, todo ha marchado bien hasta que implemente la funcion kbhit(), ya que no entra al ciclo el código es algo así:
> // ESTO ES DENTRO DEL MAIN
> while(1){
> int a=0;
> ...



define las variables antes de la funcion principal que es main, no es recomendable declarar variables antes del proceso...
despues de eso parece estar todo bien....cuando pones la funcion gets tambien captura el terminator algo asi,, que el null y tambien podria contar entonces si envias una cadena de caracteres por ejemplo 3 caracteres en realizad resiviras 4 ya que el caracter null.

SALUDOS!!!


----------



## samaelsys (Ago 25, 2010)

gracias george.manson.69 por responder tan pronto, te agradezco, fijate que ya he hecho eso de la declaracion de las variables antes del main pero igual, da los mismos inconvenientes, y como decía la funcion gets() si me captura toda la cadena, pero solo si le quito la funcion kbhit(), vale la pena decir q la cadena podra ser hasta de 10 caracteres, he estado experimentando con fgetc(), getc(), pero no me captura mas de 2 caracteres, espero me puedan hechar la mano en eso...

saludos amigos..... Suerte.........


----------



## samaelsys (Sep 4, 2010)

Buen día amigos, he logrado resolver los problemas que les habia planteado antes de captura de carácteres, pero ahora necesito su ayuda para conectar el MAX232 al circuito q controla los motores, espero me puedan ayudar, adjunto dejo el archivo de proteus, espero su ayuda...
Saludosss....

Perdon, pero no había djuntado el archivo, hoy si hay esta...
Suerte amigos....
Saludos....

aki esta jejejeje.....


----------



## muessli (Sep 17, 2010)

Hola a todos, estoy intentando realizar una comunicacion serie bidireccional (duplex por ahora,aunque full duplex seria excelente) entre 2 pics pero solo logro una unidireccional. no se que estara fallando si alguien ve algo en el codigo agradezco la ayuda.
Gracias y saludos.


```
//primer pic

#include <16f628a.h>
#fuses XT,NOWDT,NOMCLR   
#use delay(clock=4000000)       
#use rs232(baud=9600, xmit=PIN_B0, rcv=PIN_B1)    
//#use rs232(baud=9600, UART1)       // USART POR HARDWARE  RB2/TX Y RB1/RX 

#include <stdlib.h>

#define LED_0 PIN_B4
char r;
void main() {
   while (TRUE) { 
       if (kbhit()) {
         r = getc();
       }
      if (input(PIN_A0)==0){
         output_high(LED_0);
         printf("a"); //ENVIAR CARACTER a
         
       }
       else{
       
         output_low(LED_0);
         printf("b"); //ENVIAR CARACTER b
         if (r=="c"){
         output_high(LED_0);
         delay_ms(500);
         output_low(LED_0);
         delay_ms(500);
         output_high(LED_0);
         delay_ms(500);
         output_low(LED_0);
       }
       }
       }
   }
```


```
//segundo pic

#include <16f628a.h>
#fuses XT,NOWDT,NOMCLR      
#use delay(clock=4000000)       
#use rs232(baud=9600, xmit=PIN_B0, rcv=PIN_B1)    
//#use rs232(baud=9600, UART1)       // USART POR HARDWARE  RB2/TX Y RB1/RX 

#define LED_0 PIN_B4
#include <stdlib.h>

char x;

void main() {
   while (TRUE) { 
       if (kbhit()) {
         x = getc();
       }
       if (x=='a'){
         delay_ms(1000);
         output_high(LED_0);
         printf("c");
         delay_ms(3000);
       }
       else{
         output_low(LED_0);
         
       }
   }
}
```


----------



## COSMICO (Sep 24, 2010)

Hola amigos.
Tengo un dolor de cabeza con la programación de pull up internas
del pic 12f629 en ccs.
Me pueden mostrar el para de instrucciones para habilitarla individualmente 
y en conjunto..
Les agradesco..


----------



## jairosaw (Oct 6, 2010)

olep colegas,,, necesito ayuda,,

Me encuentro realizando un proyecto con un pic18F2550 y un lcd de 4 filas en CCS, el proyecto toma la señal de dos sensores que estan por el Puerto B (BO , y B1) Estoy utilizando dos de las tres interrrupciones que tiene este PIC, estas señales las coloco dentro de un contador y realiza una resta Nota: Siempre hay una señal mayor que otra, simultaneamente entra la señal y esta realziando la resta, hasta ahi todo marcha bien ,el conteo o las entradas llegan de 0 hasta 200000, por lo que utilice Long long en tipo de datos, utilice interrupciones para garantizar de que no se me perdiera ninguna pulso, En proteus me funciona de maravillas pero en lo fisico el conteo de ambas entradas solo me llega hasta un valor ejemplo 5000, y se me detiene el conteo como si el PIC se Bloquera, lo reseteo y vuelve inicia pero se me detiene el conteo, dedusco de que algo pasa con las interrupciones no se si las estoy configurando bien las dos, cada señal entra con una frecuencia de 10HZ mas o menos adjunto el codigo por favor a ver si tengo algun problema,,,

#include <18f2550.h>
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT
#use delay (clock=12000000)

#use standard_io(b) //puerto usado para el LCD es necesario declararlo como #use standard_io(b)
#use fast_io(a)
#use standard_io(C) //puerto usado para el LCD es necesario declararlo como #use standard_io(b)

#BYTE porta = 0x05
#BYTE portb = 0x06
#BYTE portc = 0x07

#define use_portb_lcd TRUE
#include "lcd flex.c"
#include   "internal_eeprom.c"


long long contador2=0;
long long contador1=0;
long long cont_resta=0;

#INT_EXT
void ext_isr()
{
  contador2++;

}

#INT_EXT1
void ext1_isr()
{
  contador1++;

}


//////////////////////////////  ciclo principal /////////////////////////
void main()
{

    lcd_init();//llama a lcd
    delay_ms(500);
    lcd_gotoxy(1,1);
    printf(lcd_putc," Contador Restador ");
    Lcd_putc( "\b");                //Limpio pantalla
    disable_interrupts(global);
//configura puertos
  set_tris_a(0b11111111);
  set_tris_b(0b00000011);
  set_tris_c(0b00000001);
//fin configura puertos
   ext_int_edge (L_TO_H);
 // setup_timer_1 (T1_EXTERNAL);
   enable_interrupts(int_ext);
   enable_interrupts(int_ext1);
   enable_interrupts(global);

   delay_ms(20);

   ext_int_edge (L_TO_H);
  //setup_timer_1 (T1_EXTERNAL);
   enable_interrupts(int_ext1);
   enable_interrupts(global);

   delay_ms(20);

////////////////////////////////////////////         bucle principal         /////////////////////////////
for(;{

   while(!input(PIN_c0))   //reset

     {
     Lcd_putc( "\f");                //Limpio pantalla

     lcd_gotoxy(1,2);
     printf(lcd_putc,"CONTADOR EN CEROS  ");

      delay_ms(1000);
      Lcd_putc( "\b");                //Limpio pantalla
       lcd_gotoxy(1,1);
     printf(lcd_putc," Contador Restador  ");
          Lcd_putc( "\b");
   {set_timer1 (0);contador2=0;contador1=0;cont_resta=0;

     lcd_gotoxy(1,2);   //tercera linea
     printf(lcd_putc,"UNI ENT= %7lu ",contador1);   //muestra la ENTRADA
     lcd_gotoxy(21,1);   //tercera linea
     printf(lcd_putc,"UNI SAL= %7lu ",contador2);   //muestra la SALIDA
     lcd_gotoxy(85,1);   //cuarta linea
     printf(lcd_putc,"DESPERDICIO= %7lu ",cont_resta);    // muestra la diferencia
          Lcd_putc( "\b");                //Limpio pantalla
    }
    }

    if(contador1>contador2)
   {cont_resta=contador1-contador2;}   //ENTRADA-SALIDA
     lcd_gotoxy(1,2);   //tercera linea
     printf(lcd_putc,"UNI ENT= %7lu ",contador1);   //muestra la ENTRADA
     lcd_gotoxy(21,1);   //tercera linea
     printf(lcd_putc,"UNI SAL= %7lu ",contador2);   //muestra la SALIDA
    lcd_gotoxy(85,1);   //cuarta linea
     printf(lcd_putc,"DESPERDICIO=%7lu ",cont_resta);    // muestra la diferencia


    Lcd_putc( "\b");                //Limpio pantalla
//***********************************************************
}
}


----------



## george.manson.69 (Oct 7, 2010)

Usa la definicio de 
alta prioridad, a lo mejor las dos interrupciones surgen al mismo tiempo y el PIC no sabe que hacer, 
la instruccion es:

#priotity interrupcion de alta prioridad,interrupcion de baja prioridad

checa en el Manual de CCS
o si no activa las interrupciones cuando sea necesario, cuando cuente lo que debe de contar desactivalos y muestra el resultado, al mostrar el resultado en el LCD activa las interrupciones para leer los pulsos nuevamente.
Estas usando un oscilador Externo de 12Mhz en fisico?


----------



## jairosaw (Oct 7, 2010)

Gracias George.manson por tu respuesta,,

Bueno lo primero que me dices no lo he hecho en ccs voy a chequear te agredeceria si tienes algo de informacion,

Con respecto a lo segundo seria algo asi, habilitar y deshabilitar cuando se requiera:

*#INT_EXT*
void ext_isr()
{
_disable_interrupts(INT_EXT1);
  contador2++;
enable_interrupts(INT_EXT1);_
}

*#INT_EXT1*
void ext1_isr()
{
_disable_interrupts(INT_EXT);
  contador1++;
enable_interrupts(INT_EXT);_
}

Voy a realizar lo anterior si es lo que me dices, y en cuanto a lo tercero si, efectivamente estoy  utilizando un cristal de 12MHZ para el PIC18F2550 que utilizo.

Gracias
Saludos Jairo


----------



## jairosaw (Oct 7, 2010)

Olap utilice la segunda opcion de habilitar y deshabilitar la interrupcion cuando se esta en un conteo,,, pero igual,, el micro se detiene cuando esta trbajando,,, sigo con el interrogante de las interrupciones como vos decis george el micro se esta bloqueando cuando se encuentran las dos y no sabe q hacer ayuda


#INT_EXT
void ext_isr()
{
disable_interrupts(INT_EXT1);
contador2++;
enable_interrupts(INT_EXT1);
}

#INT_EXT1
void ext1_isr()
{
disable_interrupts(INT_EXT);
contador1++;
enable_interrupts(INT_EXT);
}


----------



## jairosaw (Oct 8, 2010)

De nuevo George.manson, voy a realizar segun lo que he encontrado sobre las prioridades a una algo no me queda claro segun lei para el caso de los:
*PIC16F se escribe en el codigo algo asi *#priority INT_EXT,INT_EXT1*, 
*Para los de la familia PIC18ff se escribe asi: #INT_EXT HIGH y  #INT_EXT1 LOW.
* Por ultimo tambien encontre algo asi: ejemplo #INT_EXT FAST
Es cierto lo anterior?? cual de los TRES usar?? Para que mi micro no se quede colgado en pleno programa debido al uso de dos interrupciones..

Gracias por la respuesta


----------



## ByAxel (Oct 8, 2010)

Que tal!.
Los PIC16F no tienen prioridad, al ocurrir una interrupción el CPU salta siempre al mismo vector donde debe estar la rutina de interrupción.
El uso de *#priority* solo se aplica a los 18F o mayores.
Se te olvida usar *#device HIGH_INTS=true*, de otro modo no le hará caso a interrupciones con prioridad en los P18. Luego usas *#INT_EXT HIGH* para indicarle que esta interrupción tiene mayor prioridad.

*#INT_EXT HIGH*, es de mayor prioridad.
*#INT_EXT FAST*, de mayor prioridad pero no guarda el contexto, la respuesta es más rápida pero se pueden perder datos.
*#INT_EXT1 LOW*, o sin LOW se considera de baja prioridad cuando se usa *#device HIGH_INTS=true*.

saludos.


----------



## george.manson.69 (Oct 8, 2010)

no tedras la simulacion del circuito para qu lo subas y lo chequemos...por cierto en que puerto esta el LCD? veo que ocupas los tres puertos y aparte el LCD dodne esta conectado?...!!


----------



## fafy (Oct 9, 2010)

hola me  podrian echar un cable con este programa necesito variar la  velocidad entre 0 y 50 ya que este solo actua entre 0 y 9.

#include <16f628a.h>
#fuses xt,nowdt,nomclr
#use delay (clock = 4000000)
#define use_portb_kbd TRUE
#include <kbd.c>
#use standard_io (a)

void main (){

char k,kant='0';
char pwmh=0,pwml=0;
kbd_init();
PORT_b_PULLUPS(TRUE);

while(1){
         k=kbd_getc();
         if (k=='\0') k=kant;

         if ((k=='*') || (k=='#')) k='0'; 

         kant=k;
         k=k-48;
         pwmh=k*28;
         pwml=255-pwmh;
         for (pwmh;pwmh>0;pwmh--){
         output_high(pin_A0);}

         for (pwml;pwml>0;pwml--){
         output_low(pin_A0);}
       }
}


----------



## jairosaw (Oct 12, 2010)

Colegas otra ves yo,, de nuevo con el proyecto...

BYAXEL gracias por la repuesta acerca de las prioridades, cargue el programa con las modificaciones pero de nuevo con  el problema de que el micro se me detiene, es decir el conteo se detiene, no se si es que no le esta haciendo caso a las prioridades yo realice lo siguiente: 

#include <18f2550.h>
*#device HIGH_INTS=true* Esta declaración la coloque justo debajo del include

más  abajo coloque 

#priority INT_EXT, INT_EXT1,


y despues coloque 

#INT_EXT HIGH   : high ala ext 0 cmo prioridad alta
void ext_isr()
{
  disable_interrupts(INT_EXT1);
  contador2++;
  enable_interrupts(INT_EXT1);
}

Creo que lo he hecho bien, lo único fue que cuando intente colocar LOW al EXT 1 me salió un error de directiva invalidad, lo que hice fue más bien no colocarla ya q considero q está declarada también en la # prioridad ext1, como segunda prioridad. Bueno la verdad ya no se que mas realizarle a esto, adjunto aunque no sea necesario la simulación puesto que en ella funciona para que le den una chequea de como es el programa. Aclaro el circuito lo diseñe en Eagle y en baquelita y como es sencillo la parte del hardware esta mas que descartada lo único extraordinario es los datos al lcd que está a 4 bits van por un cable utp que utilice más o menos de 3 metros, el cual con anterioridad probé continuidad y todo eso , e igualmente la iluminación y el contraste se ven muy bien puesto que el voltaje llega bien,
Lo anterior lo descarto ya que el micro se me queda pegado pero sospecho por interrupciones ya q cuando ocurre esto reseteo el pic y arranca nuevamente, a veces dura funcionando un buen rato hasta que se para.


----------



## jairosaw (Oct 14, 2010)

Colegas , byaxel, les cuento que revizando el progrma en la declaracion de los flancos me falta declarar el flanco de la EXT1: de hecho me cuaso curiosida como le hacias caso en el contador,

 ext_int_edge (L_TO_H);
    ext_int_edge (1,L_TO_H);
   enable_interrupts(int_ext);
   enable_interrupts(int_ext1);
   enable_interrupts(global);

lo anterior lo realice pero sin buenos resultados, todavia no entien por que se me pega el pic utilizando las dos interrupciones, aun declarando las prioridades, los flancos, y qu ya comprobe de ingun pulso se esta perdiendo,
Ayuda por favor debido a que buscado varia informacion acerca de las int. y creo q como la tengo esta bien..
Por que se queda pegado un microcontrolador ?? Aun cuando sus interrupciones tienen prioridad


----------



## ByAxel (Oct 14, 2010)

Has intentado no usar el pin RW del LCD? hay algo que no me está gustando (bueno, nunca e usado ese pin)... pero cuando el PIC espera al LCD (unos 10ms creo) ocurre la interrupción de cualquiera de las dos entradas, puede ser que al volver a la parte del LCD se pierda... 
Por ahora no se me ocurre otra cosa...

saludos.


----------



## JuanCarlosabigor (Oct 18, 2010)

hola he comenzado a usar el mplab de la version 8.56, y al seguir los esquemas de programacion en c que ponen de ejmplos me salen los siguientes errores:
Error 111 "C:\ejemplosPIC\NUEVA\prueba.c" Line 3(7,43): Unknown keyword in #FUSES
*** Error 128 "C:\ejemplosPIC\NUEVA\prueba.c" Line 5(2,6): A #DEVICE required before this line
me podrian ayudar a comprender este error ya que no se porque me dice que no reconoce FUSES
de antemano gracias y son muy buenos su proyectos que esponen


----------



## ByAxel (Oct 18, 2010)

JuanCarlosabigor dijo:


> hola he comenzado a usar el mplab de la version 8.56, y al seguir los esquemas de programacion en c que ponen de ejmplos me salen los siguientes errores:
> Error 111 "C:\ejemplosPIC\NUEVA\prueba.c" Line 3(7,43): Unknown keyword in #FUSES
> *** Error 128 "C:\ejemplosPIC\NUEVA\prueba.c" Line 5(2,6): A #DEVICE required before this line
> me podrian ayudar a comprender este error ya que no se porque me dice que no reconoce FUSES
> de antemano gracias y son muy buenos su proyectos que esponen



CCS en MPLAB, bueno asegúrate de usarlo ya que el MPLAB instala el C de Hi-tech que sigue el estándar ANSI C cosa que no es compatible con el CCS, no lo confundas... lo digo puesto que ahí no reconoce las directivas.


----------



## JuanCarlosabigor (Oct 18, 2010)

ok gracias, y suerte con sus proyectos


----------



## pato1982 (Oct 28, 2010)

george.manson.69 dijo:


> Uso de tarjetas microSD proyecto a nivel hardware, SPI.
> Este circuito es muy simple solo trata de uso de una tarjeta microSD modo SPI, este caso he usado un microcontroldor PIC16F887, usando solo 64 bytes en cada bloque de la tarjeta y el resto como basura ya que este microcontrolador no posee mas de 368 bytes.
> 
> Codigo hecho en CCS C.
> ...




George, como estas? Estoy comenzando con la programación para la lectura y escritura de memorias SD, y pase por el foro y encontré estos ejemplos subidos por vos, que están realmente buenísimos. Utilizo el compilador PCWHD de CCS.
Mi pregunta es, la librería SPI_uSD.c, la programaste vos?
Gracias!
Un abrazo!


----------



## vicente fhc (Oct 30, 2010)

Ferchorobot dijo:


> Estoy loco con este programa para mostrar por el LCD esto tan sencillo en proteus me funciona bien pero al momento de probarlo realmente no hace nada, el programa trata de mostrar un mensaje en el lcd para decir q esta listo luego cuando el led prenda y apague el lcd indica el estado del led, el lcd no inicia ni tampoco pasa a la funcion de prender y apagar el led del pin_a2. Espero me puedas ayudar con esto. el lcd que uso al momento de probarlo es el LM071L de la hitachi. te adjunto la conexion en proteus para ver si me puedes indicar que esta malo.
> 
> 
> ```
> ...



Hola, como Tu, yo soy nuevo en esto, probe este programa en PROTEUS y luego en PROTOBOARD y funciona correctamente. Creo que tienes un problema de conexion, recuerda que el LCD rquiere de un potenciometro para el contraste.


----------



## COSMICO (Nov 1, 2010)

Correcto, si no colocas un divisor de tension adecuado o un potenciometro "reostato"
en el pin 3 del lcd, puede que solo percibas el encendido de los segmentos sin dejar ver los caracteres enviados por 
tu pic.El proteus no los necesita pues asume estos valores por default,pero en protoboard se debe 
colocar.Un valor tipico es de 5k para este reostato..


----------



## Etazla (Nov 2, 2010)

este es un programa en mplab, para poner un pulsador que detecta los numeros del 0 al 8 y los muestra en una pantalla lcd(aunque tiene unos errores). bueno mi pregunta es como puedo hacer una foto celda que cada vez que detecte oscuridad me muestre en el lcd el nivel de luz y en unos leds en los otros puertos vayan subiendo(llevo dias mirando y no se por donde empezar) jejejeje pal que le sirva la programacion con gusto aunque el error es que se me coloca automatico no espera la siguiente secuencia de pulsos y se queda oscilando el lcd entre 1 y mas de 8. hay algunas cosas que estan con ; por que las coloque de comentario para luego agregarlas o mirar si las suprimo.


```
;**********************************************************************
;   This file is a basic code template for assembly code generation   *
;   on the PIC16F887. This file contains the basic code               *
;   building blocks to build upon.                                    *
;                                                                     *
;   Refer to the MPASM User's Guide for additional information on     *
;   features of the assembler (Document DS33014).                     *
;                                                                     *
;   Refer to the respective PIC data sheet for additional             *
;   information on the instruction set.                               *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Filename:	    xxx.asm                                           *
;    Date:                                                            *
;    File Version:                                                    *
;                                                                     *
;    Author:                                                          *
;    Company:                                                         *
;                                                                     *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Files Required: P16F887.INC                                      *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Notes:                                                           *
;                                                                     *
;**********************************************************************


	list		p=16f887	; list directive to define processor
	#include	<p16f887.inc>	; processor specific variable definitions


; '__CONFIG' directive is used to embed configuration data within .asm file.
; The labels following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.

	__CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_ON & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT
	__CONFIG    _CONFIG2, _WRT_OFF & _BOR21V



;***** VARIABLE DEFINITIONS
CONT		EQU	0X20
CONT2		EQU	0X21
LCDATA		EQU	0X22
VAR1		EQU	0X23
TEMPORAL	EQU	0X24

w_temp		EQU	0x7D		; variable used for context saving
status_temp	EQU	0x7E		; variable used for context saving
pclath_temp	EQU	0x7F		; variable used for context saving


;********* DEFINICIONES DE BANDERAS *************
EN		EQU		0X00
RS		EQU		0X01



;**********************************************************************
		ORG     0x000             ; processor reset vector
		clrf    PCLATH            ; ensure page bits are cleared
  		goto    main              ; go to beginning of program


	movwf   w_temp            ; save off current W register contents
	movf	STATUS,w          ; move status register into W register
	movwf	status_temp       ; save off contents of STATUS register
	movf	PCLATH,w	  ; move pclath register into w register
	movwf	pclath_temp	  ; save off contents of PCLATH register

; isr code can go here or be located as a call subroutine elsewhere


	movf	pclath_temp,w	  ; retrieve copy of PCLATH register
	movwf	PCLATH		  ; restore pre-isr PCLATH register contents
	movf    status_temp,w     ; retrieve copy of STATUS register
	movwf	STATUS            ; restore pre-isr STATUS register contents
	swapf   w_temp,f
	swapf   w_temp,w          ; restore pre-isr W register contents
	retfie                    ; return from interrupt



main
		BANKSEL	ANSELH
		CLRF	ANSELH

		BANKSEL	ANSEL
		CLRF	ANSEL

		BANKSEL	TRISB
		CLRF	TRISB			;PONGO TODOS LOS TRIS DE SALIDA EN EL PUERTO B

		BANKSEL	PORTB

		BANKSEL	ANSELH			;SELECCIONO EL BANCO DE RAM DEL REGISTRO ANSELH (ANALOG SELECTOR HIGH SE USA PARA CONFIGURAR EL PORTB)
		MOVLW	0X00
		MOVWF	ANSELH			;AL CARGAR 0X00 EN ESE REGISTRO LE DIGO AL PIC QUE LOS PINES DEL PUERTO B SON DIGITALES (CON 1 ES ANALOGO)
	
		BANKSEL	ANSEL			;SELECCIONO EL BANCO DE RAM DEL REGISTRO ANSEL (ANALOG SELECTOR HIGH SE USA PARA CONFIGURAR EL PORTA)
		MOVLW	0X00
		MOVWF	ANSEL			;AL CARGAR 0X00 EN ESE REGISTRO LE DIGO AL PIC QUE LOS PINES DEL PUERTO A SON DIGITALES (CON 1 ES ANALOGO)
	
		BANKSEL	TRISC			;SELECCIONO EL BANCO DE RAM DEL REGISTRO DE CONFIGURACION DE ENTRADA/SALIDA DEL PUERTO C
		MOVLW	B'00001111'
		MOVWF	TRISC			;EN EL PORTC LOS PINES BAJOS SON DE ENTRADA Y LOS ALTOS SON DE SALIDA 
	
		BANKSEL	TRISA			;ESTO ES LO MISMO PERO PARA EL PUERTO A
		MOVLW	B'00000011'			
		MOVWF	TRISA			;CAMBIO EL VALOR EN EL REGUISTRO TRIS PARA QUE EN EL PIN 0 DEL PORTA SEA DE ENTRADA 
	
		BANKSEL	PORTC			;ANTES DE PASAR A LA RUTINA QUE NECESITO, DEBO SELECCIONAR EL BANCO DEL PUERTO B (QUE ES EL QUE VOY A USAR)
		CLRF	VAR1
		CLRF	PORTC
		CLRF	PORTA
		BCF		STATUS,Z

	LED_ON_OFF
			BSF		PORTA,3			;PONGO EN 1 EL PIN 3 DEL PUERTO A 
			CALL 	RUTINA
			BCF		PORTA,3			;PONGO EN 0 EL PIN 0 DEL PUERTO B
			CALL	RETARDOTI		;LLAMO AL RETARDO
			BSF		PORTA,3			;PONGO EN 1 EL PIN 3 DEL PUERTO A 
			CALL 	RUTINA
			BCF		PORTA,3			;PONGO EN 0 EL PIN 0 DEL PUERTO B
			CALL	RETARDOTI		;LLAMO AL RETARDO
			GOTO	LED_ON_OFF		;VUELVO A INICIAR TODO DE NUEVO PERO SIN RECONFIGURAR LA MAQUINA 
		
		RETARDI
			MOVLW	0XFF
			MOVWF	CONT
		LOOP_RETARDI
			DECFSZ	CONT,F
			GOTO	LOOP_RETARDI
			RETURN
		
		RETARDOTI
			MOVLW	0XFF
			MOVWF	CONT2
		LOOP_RETARDOTI
			CALL	RETARDI
			DECFSZ	CONT2,F
			GOTO	LOOP_RETARDOTI
			RETURN
		
		
		RUTINA
			BTFSS	PORTA,0
			GOTO	CHEQUEO1
			BTFSS	PORTA,1
			GOTO	CHEQUEO5
			GOTO	RUTINA
		
		CHEQUEO1
			BTFSC	PORTA,1
			GOTO	CHEQUEO2
			GOTO	CHEQUEO1
		
		CHEQUEO2
			BTFSS	PORTA,1
			GOTO	CHEQUEO3
			GOTO	CHEQUEO2
		
		CHEQUEO3
			BTFSC	PORTA,0
			GOTO	CHEQUEO4
			GOTO	CHEQUEO3
		
		CHEQUEO4
			BTFSS	PORTA,1
			GOTO	CHEQUEO4
			INCF	VAR1
			GOTO	MIRAR1
		
		CHEQUEO5
			BTFSC	PORTA,0
			GOTO	CHEQUEO6
			GOTO	CHEQUEO5
		
		CHEQUEO6
			BTFSS	PORTA,0
			GOTO	CHEQUEO7
			GOTO	CHEQUEO6
		
		CHEQUEO7
			BTFSC	PORTA,1
			GOTO	CHEQUEO8
			GOTO	CHEQUEO7
		
		CHEQUEO8
			BTFSS	PORTA,0
			GOTO	CHEQUEO8
			DECF	VAR1
			GOTO	MIRAR2
		
		MIRAR1
			MOVF	VAR1,W
			SUBLW	0X10
			BTFSC	STATUS,Z	
			DECF	VAR1
			GOTO	ACTUALIZAR	
		
		MIRAR2
			MOVF	VAR1,W
			SUBLW	0XFF
			BTFSC	STATUS,Z
			INCF	VAR1
			GOTO	ACTUALIZAR			;3520634    2685240
		
		ACTUALIZAR
			MOVF	VAR1,W
			MOVWF	TEMPORAL		;Y LO ALAMCENO EN UNA VARIABLE "TEMPORAL" PARA PODER OPERARLA
			SWAPF	TEMPORAL,W		;HAGO UN SWAPDE LOS BITS QUE ACABO DE LEER DEL PUERTO B
		
		SALIDA
			MOVWF 	PORTC 			;UNA VEZ REALIZADA LA OPERACION RECARGO EL RESULTADOEN EL PUERTO B
			GOTO	CHEQUEO_NUMERICO


CHEQUEO_NUMERICO

		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE

		CALL	INIT_LCD
		GOTO	CHEQUEO_PIN_CUATRO

CHEQUEO_PIN_CUATRO

		BTFSC	PORTC,7
		GOTO	CHEQUEO_POSIBLE_OCHO
		GOTO	CHEQUEO_NO_ES_OCHO

CHEQUEO_NO_ES_OCHO

		BTFSC	PORTC,6
		GOTO	CHEQUEO_POSIBLE_CUATRO
		GOTO	CHEQUEO_NO_ES_CUATRO

CHEQUEO_POSIBLE_OCHO

		BTFSC	PORTC,6
		GOTO	MAS_D_OCHO
		GOTO	CHEQUEO_POSIBLE_OCHO2

CHEQUEO_NO_ES_CUATRO

		BTFSC	PORTC,6
		GOTO	CHEQUEO_POSIBLE_TRES
		GOTO	CHEQUEO_POSIBLE_UNO


CHEQUEO_POSIBLE_OCHO2

		BTFSC	PORTC,5
		GOTO	MAS_D_OCHO 
		GOTO	CHEQUEO_POSIBLE_OCHO3

CHEQUEO_POSIBLE_CUATRO

		BTFSC	PORTC,5
		GOTO	CHEQUEO_POSIBLE_SIETE
		GOTO	CHEQUEO_POSIBLE_CUATRO2

CHEQUEO_POSIBLE_OCHO3

		BTFSC	PORTC,4
		GOTO	MAS_D_OCHO 
		GOTO	ES_8

CHEQUEO_POSIBLE_CUATRO2

		BTFSC	PORTC,4
		GOTO	ES_CINCO
		GOTO	ES_CUATRO

CHEQUEO_POSIBLE_UNO
		BTFSC	PORTC,4
		GOTO	ES_UNO
		GOTO	ES_CERO

CHEQUEO_POSIBLE_TRES

		BTFSC	PORTC,4
		GOTO	ES_TRES
		GOTO	ES_DOS


CHEQUEO_POSIBLE_SIETE

		BTFSC	PORTC,4
		GOTO	ES_SIETE
		GOTO	ES_SEIS

ES_CERO

		CALL	MENSAJE_ES_0
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE

		CALL	BORRAR
		GOTO	LED_ON_OFF

ES_UNO

		CALL	MENSAJE_ES_1
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE

		CALL	BORRAR
		GOTO	LED_ON_OFF

ES_DOS

		CALL	MENSAJE_ES_2
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE

		CALL	BORRAR
		GOTO	LED_ON_OFF

ES_TRES

		CALL	MENSAJE_ES_3
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE

		CALL	BORRAR
		GOTO	LED_ON_OFF

ES_CUATRO
		
		CALL	MENSAJE_ES_4
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE

		CALL	BORRAR
		GOTO	LED_ON_OFF
ES_CINCO
		
		CALL	MENSAJE_ES_5
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE

		CALL	BORRAR
		GOTO	LED_ON_OFF

ES_SEIS

		CALL	MENSAJE_ES_6
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE

		CALL	BORRAR
		GOTO	LED_ON_OFF

ES_SIETE

		CALL	MENSAJE_ES_7
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE

		CALL	BORRAR
		GOTO	LED_ON_OFF

ES_8
		
		CALL	MENSAJE_ES_8
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE

		CALL	BORRAR
		GOTO	LED_ON_OFF

MAS_D_OCHO

		CALL	MENSAJE_MAS_DE_8
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE
		MOVLW	.255
		CALL	RETARDOTE

		CALL	BORRAR
		GOTO	LED_ON_OFF

INICIO

	;	CALL	BORRAR
;
;		CALL	ACTIVAR_CURSOR_
;		MOVLW	.255
;		CALL	RETARDOTE

		CALL	COMANDO_CURSOR_DER
		CALL	COMANDO_CURSOR_DER
		CALL	COMANDO_CURSOR_DER
		CALL	COMANDO_CURSOR_DER
		CALL	COMANDO_CURSOR_DER

		CALL	MENSAJE_HOLA_MUNDO


		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ

		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER

		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ

		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER

		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ
		CALL	COMANDO_SCROLL_IZQ

		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER
		CALL	COMANDO_SCROLL_DER

		;MOVLW	.128					;CARGO EL VALOR BASE DE RAM PARA MOSTRAR CARACTERES
		;ADDLW	.64						;LE SUMO EL VALOR QUE NECESITO PARA LA LINEA 2 (LA LINEA 1 ES 0, LA LINEA 2 ES 64)
		;CALL	LCDI					;ENVIO LA INSTRUCCION

	;	CALL	MENSAJE_LINEA2

	;	MOVLW	.255
	;	CALL	RETARDOTE
	;	CALL	COMANDO_SCROLL_IZQ
	;	MOVLW	.255
	;	CALL	RETARDOTE
	;	CALL	COMANDO_SCROLL_IZQ
	;	MOVLW	.255
	;	CALL	RETARDOTE
	;	CALL	COMANDO_SCROLL_IZQ

	;	MOVLW	.255
	;	CALL	RETARDOTE
	;	MOVLW	.255
	;	CALL	RETARDOTE
	;	MOVLW	.255
	;	CALL	RETARDOTE
	;	MOVLW	.255
	;	CALL	RETARDOTE
	;	MOVLW	.255
	;	CALL	RETARDOTE
;
;		CALL	BORRAR
;
;		CALL	MENSAJE_A_TRABAJAR

LOOP	GOTO	LOOP


RETARDOTE
LOOP_RETARDOTE
		CALL	RETARDO
		DECFSZ	CONT2,F
		GOTO	LOOP_RETARDOTE
		RETURN

RETARDO
		MOVLW	.255
		MOVWF	CONT
LOOP_RETARDO
		DECFSZ	CONT,F
		GOTO	LOOP_RETARDO
		RETURN

INIT_LCD
		MOVLW   0X30		;MANDA LA INSTRUCCION 3 VECES, PRIMERA
		MOVWF	PORTB
        CALL    OUTLCD
        MOVLW   0X30		;SEGUNDA
		MOVWF	PORTB
        CALL    OUTLCD
        MOVLW   0X30		;TERCERA
		MOVWF	PORTB
        CALL    OUTLCD
        MOVLW   0X20		;Operacion en 4 bits
		MOVWF	PORTB
        CALL    OUTLCD		;MANDA LA INSTRUCCION
        MOVLW   0X2C		;
        CALL    LCDI
        MOVLW   0X08		;
        CALL    LCDI
        MOVLW   0X0F		;
        CALL    LCDI
        MOVLW   0X01		;
        CALL    LCDI
        MOVLW   0X06		;
        CALL    LCDI
        MOVLW   0X0C
        CALL    LCDI
		RETURN

OUTLCD
		BSF     PORTB,EN         ; PONE EN 1 el enable del lcd  "HABILITA" EL LCD
		MOVLW   0X05			;0X05
		MOVWF   CONT2
		CALL    RETARDOTE
		BCF     PORTB,EN         ; PONE EN 0 ENABLE DEL LCD
		RETURN

LCDD
		MOVWF	LCDATA		;
		SUBLW	0X00		;COMPARO CON 0X00 PARA SABER SI TERMINO DE ESCRIBIR EN LCD
		BTFSC	STATUS,Z	;SALTO SI NO ES IGUAL A 0X00
		GOTO	FIN_LCDD	;SI ES IGUAL TERMINO LA RUTINA SIN SACAR NADA POR LCD

		MOVLW	0XF0            ;MASCARA DEL NIBBLE ALTO
		ANDWF	LCDATA,W        ;
		MOVWF   PORTB           ;SACA POR EL PUERTO EL DATO
		BSF		PORTB,RS        ;PONE RS EN CARACTER

		CALL	OUTLCD

		MOVLW	0X0F            ;MASCARA DEL NIBBLE BAJO
		ANDWF	LCDATA,f        ;
		SWAPF	LCDATA,W        ;PONE LOS 4 BITS DE MENOR PESO EN EL DE MAYOR PESO EN LCDATA
		MOVWF   PORTB           ;SACA POR EL PUERTO EL DATO
		BSF		PORTB,RS        ;PONE RS EN CARACTER

		CALL	OUTLCD
FIN_LCDD
		RETURN


LCDI
		MOVWF	LCDATA		;
		MOVLW	0XF0            ; MASCARA DEL NIBBLE ALTO
		ANDWF	LCDATA,W        ;
		MOVWF   PORTB           ;SACA POR EL PUERTO EL DATO
		BCF		PORTB,RS        ; PONE RS EN INSTRUCCION O COMANDO

		CALL	OUTLCD          ; DA SALIDA POR EL LCD

		MOVLW	0X0F            ; MASCARA DEL NIBBLE BAJO
		ANDWF	LCDATA,f        ;
		SWAPF	LCDATA,W        ; PONE LOS 4 BITS DE MENOR PESO EN EL DE MAYOR PESO EN IODATA
		MOVWF   PORTB           ;SACA POR EL PUERTO EL DATO
		BCF		PORTB,RS        ; PONE RS EN INSTRUCCION

		CALL	OUTLCD          ; DA SALIDA POR EL LCD

		RETURN


MENSAJE_ES_0

		MOVLW	'M'
		CALL	LCDD
		MOVLW	'A'
		CALL	LCDD
		MOVLW	'S'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'D'
		CALL	LCDD
		MOVLW	'E'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'O'
		CALL	LCDD
		MOVLW	'C'
		CALL	LCDD
		MOVLW	'H'
		CALL	LCDD
		MOVLW	'O'
		CALL	LCDD
		RETURN

MENSAJE_ES_1

		MOVLW	'P'
		CALL	LCDD
		MOVLW	'U'
		CALL	LCDD
		MOVLW	'E'
		CALL	LCDD
		MOVLW	'S'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'C'
		CALL	LCDD
		MOVLW	'O'
		CALL	LCDD
		MOVLW	'M'
		CALL	LCDD
		MOVLW	'O'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'Q'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'E'
		CALL	LCDD
		MOVLW	'S'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'1'
		CALL	LCDD

		RETURN

MENSAJE_ES_2

		MOVLW	'A'
		CALL	LCDD
		MOVLW	'H'
		CALL	LCDD
		MOVLW	'O'
		CALL	LCDD
		MOVLW	'R'
		CALL	LCDD
		MOVLW	'A'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'S'
		CALL	LCDD
		MOVLW	'O'
		CALL	LCDD
		MOVLW	'N'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'2'
		CALL	LCDD
		RETURN

MENSAJE_ES_3

		MOVLW	'P'
		CALL	LCDD
		MOVLW	'E'
		CALL	LCDD
		MOVLW	'R'
		CALL	LCDD
		MOVLW	'O'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'Y'
		CALL	LCDD
		MOVLW	'A'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'S'
		CALL	LCDD
		MOVLW	'O'
		CALL	LCDD
		MOVLW	'N'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'3'
		CALL	LCDD

		RETURN

MENSAJE_ES_4

		MOVLW	'3'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'M'
		CALL	LCDD
		MOVLW	'A'
		CALL	LCDD
		MOVLW	'S'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'1'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'S'
		CALL	LCDD
		MOVLW	'O'
		CALL	LCDD
		MOVLW	'N'
		CALL	LCDD
		MOVLW	'.'
		CALL	LCDD
		MOVLW	'.'
		CALL	LCDD
		MOVLW	'.'
		CALL	LCDD
		MOVLW	'.'
		CALL	LCDD
		CALL 	RETARDOTE
		CALL 	BORRAR
		GOTO 	SEGUNDO_CUATRO
	
SEGUNDO_CUATRO
		MOVLW	'M'
		CALL	LCDD
		MOVLW	'U'
		CALL	LCDD
		MOVLW	'Y'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'B'
		CALL	LCDD
		MOVLW	'I'
		CALL	LCDD
		MOVLW	'E'
		CALL	LCDD
		MOVLW	'N'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'4'
		CALL	LCDD
				
		RETURN
MENSAJE_ES_5

		MOVLW	'C'
		CALL	LCDD
		MOVLW	'U'
		CALL	LCDD
		MOVLW	'A'
		CALL	LCDD
		MOVLW	'N'
		CALL	LCDD
		MOVLW	'T'
		CALL	LCDD
		MOVLW	'O'
		CALL	LCDD
		MOVLW	'S'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'D'
		CALL	LCDD
		MOVLW	'E'
		CALL	LCDD
		MOVLW	'D'
		CALL	LCDD
		MOVLW	'O'
		CALL	LCDD
		MOVLW	'S'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'V'
		CALL	LCDD
		MOVLW	'E'
		CALL	LCDD
		RETURN

MENSAJE_ES_6

		MOVLW	'E'
		CALL	LCDD
		MOVLW	'L'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'N'
		CALL	LCDD
		MOVLW	'U'
		CALL	LCDD
		MOVLW	'M'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'D'
		CALL	LCDD
		MOVLW	'E'
		CALL	LCDD
		MOVLW	'L'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'D'
		CALL	LCDD
		MOVLW	'A'
		CALL	LCDD
		MOVLW	'D'
		CALL	LCDD
		MOVLW	'O'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		RETURN


MENSAJE_ES_7

		MOVLW	'E'
		CALL	LCDD
		MOVLW	'S'
		CALL	LCDD
		MOVLW	'T'
		CALL	LCDD
		MOVLW	'E'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'E'
		CALL	LCDD
		MOVLW	'S'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'7'
		CALL	LCDD
		MOVLW	'M'
		CALL	LCDD
		MOVLW	'E'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'C'
		CALL	LCDD
		MOVLW	'A'
		CALL	LCDD
		MOVLW	'N'
		CALL	LCDD
		MOVLW	'C'
		CALL	LCDD
		RETURN


MENSAJE_MAS_DE_8

		MOVLW	'M'
		CALL	LCDD
		MOVLW	'A'
		CALL	LCDD
		MOVLW	'S'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'D'
		CALL	LCDD
		MOVLW	'E'
		CALL	LCDD
		MOVLW	' '
		CALL	LCDD
		MOVLW	'O'
		CALL	LCDD
		MOVLW	'C'
		CALL	LCDD
		MOVLW	'H'
		CALL	LCDD
		MOVLW	'O'
		CALL	LCDD
		RETURN

MENSAJE_ES_8

		MOVLW	'C'
		CALL	LCDD
;		MOVLW	.255
;		CALL	RETARDOTE

		MOVLW	'O'
		CALL	LCDD
;		MOVLW	.255
;		CALL	RETARDOTE

		MOVLW	'M'
		CALL	LCDD
;		MOVLW	.255
;		CALL	RETARDOTE

		MOVLW	'O'
		CALL	LCDD
;		MOVLW	.255
;		CALL	RETARDOTE

		MOVLW	' '
		CALL	LCDD
;		MOVLW	.255
;		CALL	RETARDOTE

		MOVLW	'Q'
		CALL	LCDD
;		MOVLW	.255
;		CALL	RETARDOTE

		MOVLW	' '
		CALL	LCDD
;		MOVLW	.255
;		CALL	RETARDOTE

		MOVLW	'E'
		CALL	LCDD
;		MOVLW	.255
;		CALL	RETARDOTE

		MOVLW	'S'
		CALL	LCDD
;		MOVLW	.255
;		CALL	RETARDOTE

		MOVLW	' '
		CALL	LCDD
;		MOVLW	.255
;		CALL	RETARDOTE

		MOVLW	'8'
		CALL	LCDD
;		MOVLW	.255
;		CALL	RETARDOTE

		RETURN


COMANDO_CURSOR_IZQ
;		MOVLW	.16			;A QUE BINARIO CORRESPONDE? SI ESTA BIEN EL COMANDO?
;		CALL	LCDI
;		RETURN

COMANDO_CURSOR_DER
;		MOVLW	.20			;A QUE BINARIO CORRESPONDE? SI ESTA BIEN EL COMANDO?
;		CALL	LCDI
;		RETURN

COMANDO_SCROLL_DER
		MOVLW	.28
		CALL	LCDI

		MOVLW	.255
		CALL	RETARDOTE
		RETURN

COMANDO_SCROLL_IZQ
		MOVLW	.24
		CALL	LCDI

		MOVLW	.255
		CALL	RETARDOTE
		RETURN

BORRAR
		MOVLW	.1
		CALL	LCDI
		RETURN

ACTIVAR_CURSOR
;		MOVLW	.13
;		CALL	LCDI
;		RETURN

ACTIVAR_CURSOR_
;		MOVLW	.14
;		CALL	LCDI
;		RETURN

MENSAJE_HOLA_MUNDO
;		MOVLW	'H'
;		CALL	LCDD
;		MOVLW	'O'
;		CALL	LCDD
;		MOVLW	'L'
;		CALL	LCDD
;		MOVLW	'A'
;		CALL	LCDD
;		MOVLW	' '
;		CALL	LCDD
;		MOVLW	'M'
;		CALL	LCDD
;		MOVLW	'U'
;		CALL	LCDD
;		MOVLW	'N'
;		CALL	LCDD
;		MOVLW	'D'
;		CALL	LCDD
;		MOVLW	'O'
;		CALL	LCDD
;		RETURN

MENSAJE_LINEA2
;		MOVLW	'E'
;		CALL	LCDD
;		MOVLW	'S'
;		CALL	LCDD
;		MOVLW	'T'
;		CALL	LCDD
;		MOVLW	'A'
;		CALL	LCDD
;		MOVLW	' '
;		CALL	LCDD
;		MOVLW	'E'
;		CALL	LCDD
;		MOVLW	'S'
;		CALL	LCDD
;		MOVLW	' '
;		CALL	LCDD
;		MOVLW	'L'
;		CALL	LCDD
;		MOVLW	'A'
;		CALL	LCDD
;		MOVLW	' '
;		CALL	LCDD
;		MOVLW	'2'
;		CALL	LCDD
;		MOVLW	' '
;		CALL	LCDD
;		MOVLW	'L'
;		CALL	LCDD
;		MOVLW	'I'
;		CALL	LCDD
;		MOVLW	'N'
;		CALL	LCDD
;		MOVLW	'E'
;		CALL	LCDD
;		MOVLW	'A'
;		CALL	LCDD
;		RETURN


MENSAJE_A_TRABAJAR
;		MOVLW	'A'
;		CALL	LCDD
;		MOVLW	' '
;		CALL	LCDD
;		MOVLW	'T'
;		CALL	LCDD
;		MOVLW	'R'
;		CALL	LCDD
;		MOVLW	'A'
;		CALL	LCDD
;		MOVLW	'B'
;		CALL	LCDD
;		MOVLW	'A'
;		CALL	LCDD
;		MOVLW	'J'
;		CALL	LCDD
;		MOVLW	'A'
;		CALL	LCDD
;		MOVLW	'R'
;		CALL	LCDD
;		MOVLW	'.'
;		CALL	LCDD
;		MOVLW	'.'
;		CALL	LCDD
;		MOVLW	'.'
;		CALL	LCDD
;		RETURN


		END                       ; directive 'end of program
```


----------



## perru (Nov 3, 2010)

Hola a tod@s! Lo primero: george manson un 100 sobre 10, menudo peazo tema te has currao, enhorabuena, y gracias tb al resto de integrantes, es todo informacion util para los novatos como yo, ggg. Escribo para ver si me podeis resolver unas dudas. 

1-Estoy aprendiendo a programar en CCS y he observado que al establecer los puerto como entradas o salidas, en la simulacion de proteus el puerto en cuestion no hace lo que yo le ordeno, es decir, seteo port b como entrada mediante set_tris_b(1), voy a proteus y me encuentro que hay pines rojos y azules, incluso uno apagado (gris).  ¿A que puede ser debido esto? ¿que es lo ke estoy haciendo mal? he probado poniendo en hex, en binario... y no hay manera.

2-Esta parte es mas de proteus, tal vez y no se si es este el lugar indicado, ya podeis perdonar. Pongo un pulsador pero al actuarlo no observo cambio de estado alguno con la watch window en ese puerto, a ke puede ser debido? he visto circuitos en los ke simplemente conectan un estremo al pin y el otro a tierra o a +5v segun el estado ke se kiera konseguir, pero no hay manera, ¿sera ke en lo ke he visto estan activadas las resistencias internas del pic? digo esto x ke si intercalo una resistencia la simulacion si anda aunke sigo sin observar cambi de estado en el puerto.

Muchas gracias de antemano y seguir asi. Enhorabuena!!!


----------



## ByAxel (Nov 3, 2010)

Que PIC usas?
Sube el programa que estás probando...


----------



## perru (Nov 3, 2010)

Hola ByAxel, un placer volver a verte, este es el codigo, aparentemente sencillo pero ke no hace lo ke yo kiero 

//Incluimos las librerias necesarias

#include <16F874A.h>

#use delay(clock=40000000)

#include <lcd_mod.c>

#fuses HS,NOWDT,NOPROTECT,NOLVP





void MenuReloj()

{

   lcd_putc("\f");

   lcd_gotoxy(1,1);

   lcd_putc("MENU HORA");



   while(true)

   {

      lcd_putc("\f");

      lcd_gotoxy(1,1);

      lcd_putc("10h20m");



      if(!input(pin_c3))//pulsador de salida

      {

         return;

      }

      else

      {

         delay_ms(20);

      }

   }

}



void main()

{

   int columna=1;

   int fila=1;



   //Establecemos los puertos

   SET_TRIS_A(0);

   SET_TRIS_B(1);



   //Inicializar LCD

   lcd_init();





   while(true)

   {

      //Menu Reloj

      if(!input(pin_b0))//pulsador de menu

      {

         MenuReloj();

      }



      if(!input(pin_b0))

      {

      }



      //Corre la cadena por todo el LCD

      lcd_putc("\f");

      lcd_gotoxy(columna,fila);

      lcd_putc("HOLA");



      delay_ms(20);



      columna++;



      if(columna==17)


----------



## ByAxel (Nov 3, 2010)

Es parte del programa?
- Wow 40Mhz? #use delay(clock=40000000) no exageres que los PIC16F no pueden correr a mas de 20Mhz.
- En la cabecera prueba esto *#use fast_io(b)*; esto evita a que se esté configurando una y otra vez el puerto.


----------



## perru (Nov 3, 2010)

Lo del reloj ha sido un fallo, lo otro lo he probado pero nada, en proteus hace lo ke kiere, he seteado el port c para probar y pone todos los pines menos uno, en portb cuatro y cuatro, cuando pulso cambia el color del pin pero en el registro de la watch window no y aparte no hace lo ke esta en el programa. Adjunto la simulacion con el boton sin pulsar y pulsado para este codigo

//Incluimos las librerias necesarias
#include <16F874A.h>
#use delay(clock=4000000)
#include <lcd_mod.c>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use fast_io(b)
#use fast_io(c)

//#DEVICE

void MenuReloj()
{
   lcd_putc("\f");
   lcd_gotoxy(1,1);
   lcd_putc("MENU HORA");

   while(true)
   {
      lcd_putc("\f");
      lcd_gotoxy(1,1);
      lcd_putc("10h20m");

      if(!input(pin_c3))
      {
         return;
      }
      else
      {
         delay_ms(1000);
      }
   }
}

void main()
{
   int columna=1;
   int fila=1;

   //Establecemos los puertos
   SET_TRIS_A(0);
   set_tris_b(1);
   set_tris_c(1);   
   //Inicializar LCD
   lcd_init();


   while(true)
   {
      //Menu Reloj
      if(!input(pin_b0))
      {
         MenuReloj();
      }

      if(!input(pin_b0))
      {
      }

      //Corre la cadena por todo el LCD
      lcd_putc("\f");
      lcd_gotoxy(columna,fila);
      lcd_putc("HOLA");

         delay_ms(40);

      columna++;

      if(columna==17)
      {
         fila++;
         columna=1;
      }

      if(fila>2)
      {
         fila=1;
      }
   }
}


----------



## ByAxel (Nov 3, 2010)

Simule tu código sin las rutinas del LCD quedando algo así:


```
#include <16F874A.h>
#FUSES XT
#use delay(clock=4M)
#use fast_io(b)
#use fast_io(c)
long cnt = 0;

//---
void Menu(void)
{
   while(TRUE){
      if(!input(PIN_C0)){
         break;   
      } 
      delay_ms(100);
      output_toggle(PIN_C3);  // Parpadeo mientras RC0 = 1
      --cnt;                         // Decremento un contador
   }
}

void main()
{
   // Al usar el PORTA como I/O digital se tiene que desactivar las entradas análogas.

   set_tris_a(0);
   set_tris_b(1);
   set_tris_c(1);
   
   output_b(0);
   output_c(0);
      
   while(TRUE){   
      if(!input(PIN_B0)){
         Menu();   // RB0 = 0 => Va a sub-proceso
      }
      delay_ms(100);
      output_toggle(PIN_B3);  // Parpadeo mientras RB0 = 1
      ++cnt;                        // Incremento un contador
   }
}
```

Si le hace caso a los pulsadores. Me pregunto si tu librería del LCD es la causante. Y no se te olvide de colocar las resistencias a pull-up para darle un valor lógico '1' a pin como entrada mientras no se presione el pulsador.

saludos


----------



## Etazla (Nov 3, 2010)

ByAxel dijo:


> Simule tu código sin las rutinas del LCD quedando algo así:
> 
> 
> ```
> ...



pero fue simulado en que?, la rutina solo del pulsador en mplab es....


```
;**********************************************************************
;   This file is a basic code template for assembly code generation   *
;   on the PIC16F887. This file contains the basic code               *
;   building blocks to build upon.                                    *
;                                                                     *
;   Refer to the MPASM User's Guide for additional information on     *
;   features of the assembler (Document DS33014).                     *
;                                                                     *
;   Refer to the respective PIC data sheet for additional             *
;   information on the instruction set.                               *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Filename:        xxx.asm                                           *
;    Date:                                                            *
;    File Version:                                                    *
;                                                                     *
;    Author:                                                          *
;    Company:                                                         *
;                                                                     *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Files Required: P16F887.INC                                      *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Notes:                                                           *
;                                                                     *
;**********************************************************************


    list        p=16f887    ; list directive to define processor
    #include    <p16f887.inc>    ; processor specific variable definitions


; '__CONFIG' directive is used to embed configuration data within .asm file.
; The labels following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.

    __CONFIG    _CONFIG1, _LVP_OFF & _FCMEN_ON & _IESO_OFF & _BOR_OFF & _CPD_OFF & _CP_OFF & _MCLRE_ON & _PWRTE_ON & _WDT_OFF & _XT_OSC
    __CONFIG    _CONFIG2, _WRT_OFF & _BOR21V



;***** VARIABLE DEFINITIONS
CONT        EQU    0X20
CONT2        EQU    0X21
VAR1        EQU    0X22
TEMPORAL    EQU    0X23


w_temp        EQU    0x7D        ; variable used for context saving
status_temp    EQU    0x7E        ; variable used for context saving
pclath_temp    EQU    0x7F        ; variable used for context saving


;**********************************************************************
    ORG     0x000             ; processor reset vector

    nop
      goto    main              ; go to beginning of program


    ORG     0x004             ; interrupt vector location

    movwf   w_temp            ; save off current W register contents
    movf    STATUS,w          ; move status register into W register
    movwf    status_temp       ; save off contents of STATUS register
    movf    PCLATH,w      ; move pclath register into w register
    movwf    pclath_temp      ; save off contents of PCLATH register

; isr code can go here or be located as a call subroutine elsewhere

    movf    pclath_temp,w      ; retrieve copy of PCLATH register
    movwf    PCLATH          ; restore pre-isr PCLATH register contents
    movf    status_temp,w     ; retrieve copy of STATUS register
    movwf    STATUS            ; restore pre-isr STATUS register contents
    swapf   w_temp,f
    swapf   w_temp,w          ; restore pre-isr W register contents
    retfie                    ; return from interrupt



main
    BANKSEL    ANSELH            ;SELECCIONO EL BANCO DE RAM DEL REGISTRO ANSELH (ANALOG SELECTOR HIGH SE USA PARA CONFIGURAR EL PORTB)
    MOVLW    0X00
    MOVWF    ANSELH            ;AL CARGAR 0X00 EN ESE REGISTRO LE DIGO AL PIC QUE LOS PINES DEL PUERTO B SON DIGITALES (CON 1 ES ANALOGO)

    BANKSEL    ANSEL            ;SELECCIONO EL BANCO DE RAM DEL REGISTRO ANSEL (ANALOG SELECTOR HIGH SE USA PARA CONFIGURAR EL PORTA)
    MOVLW    0X00
    MOVWF    ANSEL            ;AL CARGAR 0X00 EN ESE REGISTRO LE DIGO AL PIC QUE LOS PINES DEL PUERTO A SON DIGITALES (CON 1 ES ANALOGO)

    BANKSEL    TRISB            ;SELECCIONO EL BANCO DE RAM DEL REGISTRO DE CONFIGURACION DE ENTRADA/SALIDA DEL PUERTO B
    MOVLW    B'00001111'
    MOVWF    TRISB            ;EN EL PORTB LOS PINES BAJOS SON DE ENTRADA Y LOS ALTOS SON DE SALIDA 

    BANKSEL    TRISA            ;ESTO ES LO MISMO PERO PARA EL PUERTO A
    MOVLW    B'00000011'            
    MOVWF    TRISA            ;CAMBIO EL VALOR EN EL REGUISTRO TRIS PARA QUE EN EL PIN 0 DEL PORTA SEA DE ENTRADA 

    BANKSEL    PORTB            ;ANTES DE PASAR A LA RUTINA QUE NECESITO, DEBO SELECCIONAR EL BANCO DEL PUERTO B (QUE ES EL QUE VOY A USAR)
    CLRF    VAR1
    CLRF    PORTB
    CLRF    PORTA
    BCF        STATUS,Z

LED_ON_OFF
    BSF        PORTA,3            ;PONGO EN 1 EL PIN 3 DEL PUERTO A 
    CALL     RUTINA
    BCF        PORTA,3            ;PONGO EN 0 EL PIN 0 DEL PUERTO B
    CALL    RETARDOTE        ;LLAMO AL RETARDO
    BSF        PORTA,3            ;PONGO EN 1 EL PIN 3 DEL PUERTO A 
    CALL     RUTINA
    BCF        PORTA,3            ;PONGO EN 0 EL PIN 0 DEL PUERTO B
    CALL    RETARDOTE        ;LLAMO AL RETARDO
    GOTO    LED_ON_OFF        ;VUELVO A INICIAR TODO DE NUEVO PERO SIN RECONFIGURAR LA MAQUINA 

RETARDO
    MOVLW    0XFF
    MOVWF    CONT
LOOP_RETARDO
    DECFSZ    CONT,F
    GOTO    LOOP_RETARDO
    RETURN

RETARDOTE
    MOVLW    0XFF
    MOVWF    CONT2
LOOP_RETARDOTE
    CALL    RETARDO
    DECFSZ    CONT2,F
    GOTO    LOOP_RETARDOTE
    RETURN


RUTINA
    BTFSS    PORTA,0
    GOTO    CHEQUEO1
    BTFSS    PORTA,1
    GOTO    CHEQUEO5
    GOTO    RUTINA

CHEQUEO1
    BTFSC    PORTA,1
    GOTO    CHEQUEO2
    GOTO    CHEQUEO1

CHEQUEO2
    BTFSS    PORTA,1
    GOTO    CHEQUEO3
    GOTO    CHEQUEO2

CHEQUEO3
    BTFSC    PORTA,0
    GOTO    CHEQUEO4
    GOTO    CHEQUEO3

CHEQUEO4
    BTFSS    PORTA,1
    GOTO    CHEQUEO4
    INCF    VAR1
    GOTO    MIRAR1

CHEQUEO5
    BTFSC    PORTA,0
    GOTO    CHEQUEO6
    GOTO    CHEQUEO5

CHEQUEO6
    BTFSS    PORTA,0
    GOTO    CHEQUEO7
    GOTO    CHEQUEO6

CHEQUEO7
    BTFSC    PORTA,1
    GOTO    CHEQUEO8
    GOTO    CHEQUEO7

CHEQUEO8
    BTFSS    PORTA,0
    GOTO    CHEQUEO8
    DECF    VAR1
    GOTO    MIRAR2

MIRAR1
    MOVF    VAR1,W
    SUBLW    0X10
    BTFSC    STATUS,Z    
    DECF    VAR1
    GOTO    ACTUALIZAR    

MIRAR2
    MOVF    VAR1,W
    SUBLW    0XFF
    BTFSC    STATUS,Z
    INCF    VAR1
    GOTO    ACTUALIZAR            ;3520634    2685240

ACTUALIZAR
    MOVF    VAR1,W
    MOVWF    TEMPORAL        ;Y LO ALAMCENO EN UNA VARIABLE "TEMPORAL" PARA PODER OPERARLA
    SWAPF    TEMPORAL,W        ;HAGO UN SWAPDE LOS BITS QUE ACABO DE LEER DEL PUERTO B

SALIDA
    MOVWF     PORTB             ;UNA VEZ REALIZADA LA OPERACION RECARGO EL RESULTADOEN EL PUERTO B
    RETURN
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             



; example of preloading EEPROM locations

    ORG    0x2100
    DE    5, 4, 3, 2, 1

    END                       ; directive 'end of program'
```

y aprovecho para decir como hago para un cto con una fotocelda o un fototransistor para poder medirlo en el lcd (un conversor analogo digital) pero no se como montarlo por que este si me tiene en bloqueo mental total. solo tengo este......pero este muestra es el paso de voltaje atravez de un potenciometro....


> Notes:                                                           *
> ;                                                                     *
> ;**********************************************************************
> 
> ...


----------



## ByAxel (Nov 4, 2010)

Etazla dijo:


> pero fue simulado en que?, la rutina solo del pulsador en mplab es....


Es lógico, en el proteus que es el mismo que usa más arriba... lee y mira todo antes de decir algo.

Con respecto a tu pregunta aunque fue el primer lenguaje que aprendí me da flojera leer todo el asm  peeero... intenta evitar mandar los datos al LCD una y otra vez, algo usual es enviarlo cuando el valor del ADC de una canal haya cambiado, eso involucra tener un registro/s donde se compare el valor actual con el anterior y al ser diferente, recién lo muestre en el LCD y actualice el registro de comparación. Otra es usando lo anterior pero con un rango más amplio, es decir por ejemplo si el valor actual es mayor + 10 unidades o menor - 10 unidades al valor anterior, recién lo muestra en el LCD y actualiza el registro... en fin  o 

saludos


----------



## dragondgold (Nov 5, 2010)

Hola, estoy en el tema de la comunicación infrarroja y tengo un sensor como los de TV en donde un 1 se interpreta por 800us de pulsos a 38KHz. Hice una rutina a la cual le envío el dato y esta me la saca por un pin que yo defino. Entonces si es 1 generar pulsos de 38KHz por 800us aproximadamente y si es un 0 saca simplemente un 0 por el pin antes mencionado. Para esto genero una interrupcion cada 13us en donde cambio el pin de 1 a 0 entonces en el cambio me daria un periodo de 26us = 38KHz. El programa durante la interrupción es bastante rapido pero para salir de la rutina al programa le toma 53uS en salir y si necesito generar un periodo de 26us repetidas veces esto me demora todo. Por que demora tanto si supuestamente se sale inmediatamente de la interrupcion en ASM con la instrucción RETFIE, por que demora tanto en CCS? Me esta volviendo loco. Olvide de decir que el programa calcula el valor que le va al timer de acuerdo a la frecuencia de reloj, esto nos permite tener comunicaciones de infrarrojo a cualquier velocidad de reloj, yo estoy probando en el peor de los casos que es 4MHz, espero puedan ayudarme.

El programa:

```
#include <16F84A.H>
#use delay(clock=4M)
#include <XMIT_IR.c>
#define io_port B

INT16 IR;

VOID MAIN (VOID){

set_tris_b(0b00000000);
output_b(0b00000000);
IR = 0b1010101010101010;
ir_init(4);
delay_ms(1000);

   WHILE(1){
ir_write(IR);
delay_ms(3000);
   }
    
}
```


La rutina:

```
#ifndef XMIT_IR
#define XMIT_IR
#define RMIT_PIN PIN_B0
#define XMIT_PIN PIN_B1
#use fast_io(B)


//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                        VARIABLES GLOBALES                                                    //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

INT FFF = 0;                                                                     //numero a cargar en el timer segun la freq del cristal
INT nt = 0;                                                                      //veces a repetir el periodo para llegar a 800us = 1 bit
INT1 XDF = 0;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                        INTERRUPCION TIMER0                                                   //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#INT_TIMER0                                                                   
VOID TIMER0 (VOID){                                                              //interrupción del timer0
      set_timer0(FFF);
      output_toggle(XMIT_PIN);
      ++nt;
      IF(nt==60){
      disable_interrupts(INT_TIMER0);
      XDF = 1;
      }
      return;
}



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                               PROTOTIPOS DE FUNCIONES                                                        //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

VOID ir_write (int16 dato);                                                      //envío de datos                                                    
VOID ir_init (VOID);                                                             //inicialización, debe llamarse antes que otra rutina
INT16 ir_read (VOID);                                                            //leo el dato recibido             

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Esta función envía por un PIN que se define pulsos de 38KHz para un "1" y nada para un "0" para ser enviados  //
//vía infrarrojo, acepta hasta INT16, el pin por donde salen los pulsos es seleccionable. La funcion envía los  //
//bits comenzando por el más significativo el inicio de la transmición esta marcada por un flanco de subida.    //
//Se utiliza el timer0 para la generacion de los pulsos                                                         //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

VOID ir_write(int16 dato){

XDF = 0;
INT n;                                                                           //cantidad de bits
output_low(XMIT_PIN);                                                            //inicializo pin de transmición
setup_timer_0(RTCC_DIV_1 | RTCC_INTERNAL);                                       //timer 0 para temporizacion del periodo en modo software
enable_interrupts(GLOBAL);
enable_interrupts(INT_TIMER0);
set_timer0(FFF);
WHILE(XDF!=1){}                                                                  //flanco de bajada en el receptor para inicio de TR
nt = 0;
XDF = 0;

   FOR(n=16;n>0;--n){                                                            //voy contando los 16 bits
      IF(bit_test(dato,n)==1){                                                   //si el bit de mayor peso es 1
       set_timer0(FFF);
       enable_interrupts(INT_TIMER0);
         WHILE(XDF!=1){}                                                         //repito 61 veces el periodo con el timer para completar 800uS
       nt = 0;
       XDF = 0;
      }
      
      ELSE{
         disable_interrupts(INT_TIMER0);
         output_low(XMIT_PIN);                                                   //envío un "0"
         delay_us(800);
      }
   }
output_low(XMIT_PIN);                                                            //apago el pin de transmicion
disable_interrupts(INT_TIMER0);                                                  //desabilito las interrupciones                                                                     //dejo al timer0 para ser usado, esta rutina ya no lo usa mas
}  

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Configuro la interrupción para la recepción de datos y configura los tiempos segun la frecuencia de reloj.    //
//INT QQ es la frecuencia de cristal usada (sin dividir por 4) en MHz                                           //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

VOID ir_init(FLOAT QQ){

      QQ = QQ / 4;                                                               //frecuencia del reloj /4 para sacar Freq de tarabajo
      QQ = 1 / QQ;                                                               //periodo de la freq de trabajo
      QQ = 13 / QQ;                                                              //saco el valor del timer para generar los 13us
      FFF = 256 - QQ;                                                            //le resto el valor y 256 (8 bits) y obtengo el valor timer
      ext_int_edge(H_TO_L);                                                      //interrupcion por flanco de bajada para la recepcion
      enable_interrupts(INT_EXT);                                                //de datos
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Recibo datos dentro de la interrupción de hasta INT16, la rutina se sincroniza con la interrupción que se     //
// produce en RB0 por flanco de bajada, debido a esto la funcion debe usarse inmediatamente despues de          //  
// producirse la interrupcion en RB0                                                                            //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

INT16 ir_read(VOID){
   
INT16 dato = 0;                                                                  //variable donde se guarda el dato recibido
INT n;                                                                           //cantidad de bits a recibir

      delay_us(900);                                                             //el flanco de bajada indica inicio de transmición, espero
                                                                                 //al siguiente bit y un poco mas para asegurarme estar dentro
                                                                                 //del mismo y no caer sobre el flanco
   FOR(n=16;n>0;--n){                                                            //voy contando los 16 bits
      IF(input(RMIT_PIN)==0){                                                    //si el dato recibido es 0
      bit_set(dato,n);                                                           //pongo a 1 el bit correspondiente del registro ya que
      dato = dato<<1;                                                            //el sensor recibe los datos invertidos, roto una vez a la
      delay_us(900);                                                             //izquierda para ir formando el dato y espero al siguiente
      }                                                                          //bit
      
      ELSE{                                                                      //si el dato recibido es 1 pongo el bit correspondiente
      bit_clear(dato,n);                                                         //a 0 porque el receptor manda los datos invertidos
      dato = dato<<1;                     
      delay_us(900);    
      }
   }
  
   return dato;                                                                  //devuelvo el dato recibido en formato INT16
}
   
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                            FIN LIBRERIA                                                      //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#endif
```

Saludos y gracias!!


----------



## ByAxel (Nov 5, 2010)

En realidad para entrar y salir de una interrupción en los PIC16 se demora porque guarda/restaura el contexto del registro STATUS, PCL, PCLATCH y otras cosas pero a que se demora tanto como dices tendrías que revisar el archivo *.lst que genera al compilar, ahí está todo en ASM y para que se entienda mejor ve a "Options > Project Options > Output Files" y en "List file" escoge "Symbolic".

PD: Para casos precisos es mejor mezclar ambos lenguajes C + ASM.

saludos.


----------



## dragondgold (Nov 5, 2010)

Bueno intente borrar el flag de interrupción en asm y hasta ahi todo bien pero me da un error extraño y no me deja compilar... No hay otra manera? No recuerdo que en ASM se tardara tanto en salir de una interrupcion, yo no hacia todos esos pasos y funcionaba... Ya no se que hacer agote todas las posbilidades la interrupcion era lo que me quedaba y todo iba bien excepto que cuando sale demora demasiado... Alguna idea??

Se los agradezco saludos


----------



## ByAxel (Nov 5, 2010)

Si lo vez bien, genera todo esto para la rutina de interrupción solo al declarar:

```
0000:  MOVLW  00
0001:  MOVWF  PCLATH
0002:  GOTO   MAIN
0003:  NOP
0004:  MOVWF  07F
0005:  SWAPF  STATUS,W
0006:  CLRF   STATUS
0007:  MOVWF  21
0008:  MOVF   PCLATH,W
0009:  MOVWF  20
000A:  CLRF   PCLATH
000B:  MOVF   FSR,W
000C:  MOVWF  22
000D:  MOVF   @77,W
000E:  MOVWF  23
000F:  MOVF   @78,W
0010:  MOVWF  24
0011:  MOVF   @79,W
0012:  MOVWF  25
0013:  MOVF   @7A,W
0014:  MOVWF  26
0015:  BCF    STATUS.IRP
0016:  BCF    STATUS.RP0
0017:  BTFSS  INTCON.TMR0IE
0018:  GOTO   01B
0019:  BTFSC  INTCON.TMR0IF
001A:  GOTO   02C
001B:  MOVF   22,W
001C:  MOVWF  FSR
001D:  MOVF   23,W
001E:  MOVWF  @77
001F:  MOVF   24,W
0020:  MOVWF  @78
0021:  MOVF   25,W
0022:  MOVWF  @79
0023:  MOVF   26,W
0024:  MOVWF  @7A
0025:  MOVF   20,W
0026:  MOVWF  PCLATH
0027:  SWAPF  21,W
0028:  MOVWF  STATUS
0029:  SWAPF  07F,F
002A:  SWAPF  07F,W
002B:  [B]RETFIE[/B]
002C:  BCF    PCLATH.PCLATH3
002D:  BCF    PCLATH.PCLATH4
002E:  GOTO   02F
```

Si continuas con el C, creo que debes de hacer la rutina de interrupción manualmente y en ASM, usando directivas como #ORG para ubicar el código en el lugar correcto...


----------



## dragondgold (Nov 12, 2010)

Hola, tengo un array bidimensional que es un imagen para mostrar en un GLCD creada por el programa Bitmap2lcd basic v1.8 el cual crea una imagen en hexadecimal a partir de una imagen JPG o GIF. Tengo la funcion que toma el array bidimensional y me lo va escribiendo en el GLCD para formar la imagen pero si tengo mas de una imagen debo crear muchas de estas funciones con diferentes nombres. Entonces pense en crear el array tridimensional en donde esta tercera indicaria el numero de imagen a mostrar, pero por mas que intento opciones no logra compilar el codigo por que? La idea en sintesis es hacer un array tridimensional a partir de este que tengo para poder seguir agregando mas imagenes. Espero puedan ayudarme:


```
VOID IMG_TMAX (VOID){
 char i,j;
 signed char k;
    for( i = 0 ; i < 64 ; i ++ )
   {  
      for( j = 0 ; j < 16 ; j ++)
      {    
         for(k=7;k>-1;k--)
         {      
            if( bit_test(IMAGEN_TMAX[i][j],7-k )) 
               glcd_pixel( j*8+k,i, ON );
               
         }  
      }
   }
}
```

Como ven para cada imagen deberia cambiar en donde dice IMAGEN_TMAX por el nombre de la otra imagen pero esto se solucionaria con un array tridimensional y simplemente cambiando un numero en una variable.

Este es el array de la imagen:


```
CONST INT8 IMAGEN_TMAX [128][16] = {                                             //imagen numero 1 Tmax

 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00                           //128 filas para la imagen
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00                           //16 columnas para la imagen
 0x7F , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF
 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFE
 0x7F , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF
 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFE
 0x7F , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF
 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFE
 0x7F , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF
 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFE
 0x7F , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF
 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFE
 0x7F , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF
 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFF , 0xFE
 0x00 , 0x00 , 0x00 , 0x03 , 0xFC , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x03 , 0xF8 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x07 , 0xF8 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x07 , 0xF0 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x3E , 0x00
 0x00 , 0x00 , 0x00 , 0x0F , 0xE0 , 0x0F , 0xF8 , 0x1F
 0xF0 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x41 , 0x00
 0x00 , 0x00 , 0x00 , 0x0F , 0xE0 , 0x1F , 0xF8 , 0x3F
 0xF0 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x9C , 0x80
 0x00 , 0x00 , 0x00 , 0x1F , 0xC0 , 0x1F , 0xF8 , 0x3F
 0xE0 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xA2 , 0x80
 0x00 , 0x00 , 0x00 , 0x3F , 0xC0 , 0x1F , 0xF8 , 0x7F
 0xE0 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xBC , 0x80
 0x00 , 0x00 , 0x00 , 0x3F , 0x80 , 0x1F , 0xF8 , 0xFF
 0xE0 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xA4 , 0x80
 0x00 , 0x00 , 0x00 , 0x7F , 0x00 , 0x3F , 0xF8 , 0xFF
 0xE0 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0xA2 , 0x80
 0x00 , 0x00 , 0x00 , 0x7F , 0x00 , 0x3F , 0xF9 , 0xFF
 0xC0 , 0x3F , 0xE0 , 0x3F , 0xCF , 0xE0 , 0x41 , 0x00
 0x00 , 0x00 , 0x00 , 0xFE , 0x00 , 0x7F , 0xFB , 0xFF
 0xC0 , 0xFF , 0xF0 , 0x3F , 0xDF , 0xE0 , 0x3E , 0x00
 0x00 , 0x00 , 0x01 , 0xFE , 0x00 , 0x7F , 0xFF , 0xFF
 0x81 , 0xFF , 0xF8 , 0x3F , 0x9F , 0xE0 , 0x00 , 0x00
 0x00 , 0x00 , 0x01 , 0xFC , 0x00 , 0x7F , 0xFF , 0xFF
 0x83 , 0xFF , 0xF8 , 0x7F , 0xBF , 0xC0 , 0x00 , 0x00
 0x00 , 0x00 , 0x03 , 0xFC , 0x00 , 0xFF , 0xFF , 0xFF
 0x87 , 0xFF , 0xF8 , 0x7F , 0x3F , 0xC0 , 0x00 , 0x00
 0x00 , 0x00 , 0x03 , 0xF8 , 0x00 , 0xFF , 0xFF , 0xFF
 0x0F , 0xFF , 0xF8 , 0x7F , 0x3F , 0x80 , 0x00 , 0x00
 0x00 , 0x00 , 0x07 , 0xF0 , 0x01 , 0xFF , 0xFF , 0xFF
 0x0F , 0xFF , 0xF8 , 0xFF , 0x3F , 0x80 , 0x00 , 0x00
 0x00 , 0x00 , 0x07 , 0xF0 , 0x01 , 0xFF , 0xFF , 0xFF
 0x0F , 0xF3 , 0xF8 , 0xFE , 0x7F , 0x80 , 0x00 , 0x00
 0x00 , 0x00 , 0x0F , 0xE0 , 0x01 , 0xFF , 0xFF , 0xFE
 0x1F , 0xE7 , 0xF0 , 0xFE , 0x7F , 0x80 , 0x00 , 0x00
 0x00 , 0x00 , 0x1F , 0xC0 , 0x03 , 0xFF , 0xFF , 0xFE
 0x1F , 0xC7 , 0xF0 , 0xFF , 0xFF , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x1F , 0xC0 , 0x03 , 0xFF , 0xFF , 0xFE
 0x1F , 0xCF , 0xE0 , 0xFF , 0xFE , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x3F , 0x80 , 0x03 , 0xFF , 0xFF , 0xFC
 0x1F , 0xFF , 0xE0 , 0xFF , 0xFC , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x7F , 0x80 , 0x07 , 0xFF , 0xFF , 0xFC
 0x3F , 0xFF , 0xE0 , 0xFF , 0xF0 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x7F , 0x00 , 0x07 , 0xFD , 0xEF , 0xF8
 0x3F , 0xFF , 0xE1 , 0xFF , 0xF8 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0xFF , 0x00 , 0x07 , 0xFD , 0xCF , 0xF8
 0x7F , 0xFF , 0xC3 , 0xFF , 0xF8 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0xFE , 0x00 , 0x0F , 0xF9 , 0x9F , 0xF8
 0x7F , 0xFF , 0xC7 , 0xFF , 0xF8 , 0x00 , 0x00 , 0x00
 0x00 , 0x01 , 0xFE , 0x00 , 0x0F , 0xF8 , 0x1F , 0xF0
 0x7F , 0x3F , 0x87 , 0xF3 , 0xF8 , 0x00 , 0x00 , 0x00
 0x00 , 0x01 , 0xFC , 0x00 , 0x0F , 0xF0 , 0x3F , 0xF0
 0xFE , 0x3F , 0x8F , 0xE7 , 0xF8 , 0x00 , 0x00 , 0x00
 0x00 , 0x03 , 0xF8 , 0x00 , 0x1F , 0xF0 , 0x3F , 0xF0
 0xFE , 0x3F , 0x8F , 0xE7 , 0xF8 , 0x00 , 0x00 , 0x00
 0x00 , 0x03 , 0xF8 , 0x00 , 0x1F , 0xE0 , 0x3F , 0xE1
 0xFC , 0x7F , 0x1F , 0xCF , 0xF0 , 0x00 , 0x00 , 0x00
 0x00 , 0x07 , 0xF0 , 0x00 , 0x3F , 0xE0 , 0x7F , 0xE1
 0xFC , 0x7F , 0x1F , 0xCF , 0xF0 , 0x00 , 0x00 , 0x00
 0x00 , 0x0F , 0xE0 , 0x00 , 0x3F , 0xE0 , 0x7F , 0xE1
 0xFC , 0xFE , 0x1F , 0xCF , 0xF0 , 0x00 , 0x00 , 0x00
 0x00 , 0x07 , 0xE0 , 0x00 , 0x3F , 0xE0 , 0xFF , 0xC3
 0xF8 , 0xFE , 0x1F , 0x9F , 0xF0 , 0x00 , 0x00 , 0x00
 0x00 , 0x01 , 0xE0 , 0x00 , 0x7F , 0xC0 , 0xFF , 0xC3
 0xF8 , 0xFE , 0x3F , 0x9F , 0xE0 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x40 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00 , 0x00
};
```


----------



## george.manson.69 (Nov 13, 2010)

dragondgold dijo:


> Hola, tengo un array bidimensional que es un imagen para mostrar en un GLCD creada por el programa Bitmap2lcd basic v1.8 el cual crea una imagen en hexadecimal a partir de una imagen JPG o GIF. Tengo la funcion que toma el array bidimensional y me lo va escribiendo en el GLCD para formar la imagen pero si tengo mas de una imagen debo crear muchas de estas funciones con diferentes nombres. Entonces pense en crear el array tridimensional en donde esta tercera indicaria el numero de imagen a mostrar, pero por mas que intento opciones no logra compilar el codigo por que? La idea en sintesis es hacer un array tridimensional a partir de este que tengo para poder seguir agregando mas imagenes. Espero puedan ayudarme:
> 
> 
> ```
> ...




Mira una manera eficaz es realizar una funcion usando punteros, te propongo que empieces a busacar como funcionan los punteros, eso seria una solucion muy optima.


```
void Glcd_image(const unsigned char *ptr){

 char i,j;
  signed char k;
       for( j = 0 ; j < 16 ; j ++)
       {    
          for(k=7;k>-1;k--)
          {      
             if( bit_test(&ptr,7-k )) 
                glcd_pixel( j*8+k,i, ON );
                
          }  
       }

}
```

y asi si tienes dos imagenes del mismo tamañano. solo tendrias que llmar una sola funcion pero diferentes imagenes, las imagenes etaran guardadas en la memoria de programa . por eso se pone un puntero que apunte a la memoria de programa

por ejemplo.

Glcd_image(imagen1);
Glcd_image(imagen2);

y asi...seria una solucion muy optima, checa a lo mejor esa seria una solucion.

Saludos


----------



## dragondgold (Nov 13, 2010)

Huuuuy gracias ya habia intentado con punteros pero me decia que estaba intentando crear un puntero para una variable CONST y no me dejaba, ahora lo pruebo, y ya encontre como hacer el array tridimencional!!

Edito: no debería ser if( bit_test(*ptr,7-k )) ? en ves de if( bit_test(&ptr,7-k )) ? porque usas & en ves *? Si supuestamente se comprueba el bit de la variable que guarde el puntero...

Saludos


----------



## george.manson.69 (Nov 14, 2010)

dragondgold dijo:


> Huuuuy gracias ya habia intentado con punteros pero me decia que estaba intentando crear un puntero para una variable CONST y no me dejaba, ahora lo pruebo, y ya encontre como hacer el array tridimencional!!
> 
> Edito: no debería ser if( bit_test(*ptr,7-k )) ? en ves de if( bit_test(&ptr,7-k )) ? porque usas & en ves *? Si supuestamente se comprueba el bit de la variable que guarde el puntero...
> 
> Saludos


VOID IMG_TMAX (const unsigned char *ptr, unsigned char ON){
 char i,j;
 signed char k;
    for( i = 0 ; i < 64 ; i ++ )
   {  
      for( j = 0 ; j < 16 ; j ++)
      {    
         for(k=7;k>-1;k--)
         {      
            if( bit_test(*ptr,7-k )) 
               glcd_pixel( j*8+k,i, ON );

         } 
         *ptr++; //faltaba poner esto
      }
   }
}
Asi lo tengo en mi programita, ya lo probe y funciona, y si estaba bien como tu decias me habia equivocado error de dedo jeje.

saludos


----------



## dragondgold (Nov 15, 2010)

George me dice "Expecting an identifier" señalando en donde declaro al puntero en la funcion, me hacia exactamente lo mismo por eso no utilize punteros. No se por que me da ese error no se que me falta declara, me gusta la idea de los punteros porque con la matriz tridimensional es bastante lento en buscar y dibujar la imagen...

Saludos


----------



## dragondgold (Nov 16, 2010)

george.manson no se como funcionó tu codigo, estuve leyendo y el CCS no admite punteros a constantes, que mal otro punto en contra al CCS =(

Saludos!!


----------



## george.manson.69 (Nov 17, 2010)

dragondgold dijo:


> george.manson no se como funcionó tu codigo, estuve leyendo y el CCS no admite punteros a constantes, que mal otro punto en contra al CCS =(
> 
> Saludos!!


  Ok! bueno yo esty usando el compilador Hi tech, y me funciono de 100, pero no lo probe con el CCS C. 
Pero debe de funcionar en CCS C.

En el arreglo de la imagen tienes por ejemplo

const int image[64][16];? bueno en el que yo tengo en HI tech le puse const unsigned char image[1024].

cambie la definicion del arreglo de la imgen por este:

const int image[1024] por si no lo tienes de esta manera, en el tema de Programas hecho en C18 he subido a lo similar si gustas pasar por el tema.

Saludos


----------



## dragondgold (Nov 17, 2010)

Podrias pasarme el programa que hiciste asi lo reviso por favor? Funciona la rutina de crear la imagen poniendo solo [1024] en ves de [128][16]? Mande un mail a CCS y me respondieron que se podia crear punteros a constates cambiando el CONST por ROM y que tambien pueden crearse punteros a funciones 

Muchas gracias!!


----------



## george.manson.69 (Nov 17, 2010)

dragondgold dijo:


> Podrias pasarme el programa que hiciste asi lo reviso por favor? Funciona la rutina de crear la imagen poniendo solo [1024] en ves de [128][16]? Mande un mail a CCS y me respondieron que se podia crear punteros a constates cambiando el CONST por ROM y que tambien pueden crearse punteros a funciones
> 
> Muchas gracias!!



https://www.forosdeelectronica.com/f24/programas-hechos-c18-compiler-38812/

en la ultima parte..esta el protyecto


----------



## COSMICO (Nov 23, 2010)

Pase este tema aqui pues me lo sugirieron.
Espero no violar las normas, pido el favor al moderador; borre este tema 
del hilo programas hechos en c18

Hola amigo george.manson.69
mira,tengo este programa para contar pulsos por el tmr0, cada vez que interrumpe el tmr1
a 100ms.La cosa es que cuando tomo el valor del registro que uso para leer el tmro
haciendo la conversion siempre pierdo las unidades, el valor lo represento en 4 display 7segmentos
Te agradesco la ayuda.Un saludo.
Mira la rutina para tomar y pasar los datos.


m=((val)/1000);
c=((val-m*1000)/100);
d=((val-c*100-m*1000)/10);
u=val-d*10-c*100-m*1000;

output_high(PIN_A3);//millares
output_b(disp[m]);
delay_ms(3);//(15);
output_low(PIN_A3);
delay_us(3);


output_high(PIN_A2);//centena
output_b(disp[c]);
delay_ms(3);//(15);
output_low(PIN_A2);
delay_us(3);

output_high(PIN_A1);//decena
output_b(disp[d]);
delay_ms(3);//(15);
output_low(PIN_A1);
delay_us(3);

output_high(PIN_A0);//unidad
output_b(disp);
delay_ms(3);//(15);
output_low(PIN_A0);
delay_us(3);

} while (TRUE);
}


----------



## Daoíz (Nov 24, 2010)

Buenas tardes, me parece muy interesante este hilo que se ha formado.
Uso el dsPIC30F4012, y necesito leer la frecuencia de una onda cuadrada, desde 0 a 30KHz

Puedo conectar la entrada a la pata del dsPIC que yo quiera, concretamente le tengo conectado al RE0.

Me podeis pasar un ejemplo para hacer esto, no encuentro nada claro, solo versiones muy antiguas y me imagino que los dsPICs tengas alguna aplicación mejor que los PIC antiguos.


Me he decantado por usar un pin denominado IC1 (input capture 1) y con un timer, a ver si me sale

Un saludo y gracias


----------



## mabrojo (Dic 17, 2010)

Hola soy nuevo en el foro y con esto de los PIC, pero me interesa mucho. Queria felicitarlos a todos por la cantidad de info que se encuentra en el foro. Y pedirle a "george.manson.69" si podria subir de vuelta el SANDWOROT ya que el link http://www.easy-share.com/1909992253/SANDWOROT.pdf esta muerto.

bueno desde ya muchas gracias, saludos.
Martin


----------



## george.manson.69 (Dic 18, 2010)

mabrojo dijo:


> Hola soy nuevo en el foro y con esto de los PIC, pero me interesa mucho. Queria felicitarlos a todos por la cantidad de info que se encuentra en el foro. Y pedirle a "george.manson.69" si podria subir de vuelta el SANDWOROT ya que el link http://www.easy-share.com/1909992253/SANDWOROT.pdf esta muerto.
> 
> bueno desde ya muchas gracias, saludos.
> Martin



Hola mabrojo, claro que subire de nuevo el Robot SANDWOROT. Apartr de mañana lo subire!
Saludos!


----------



## mabrojo (Dic 19, 2010)

Esperamos.. jaja muchas gracias
Saludos


----------



## dann (Dic 23, 2010)

para hacer un pwm con pic16f877A de 200hz pero sin usar el modulo ccp1 con los puros timers q comience en %40 y amentarlo y disminuirlo con 2 botones en el puerto B solamente

[/QUOTE]

QUOTE=george.manson.69;176611]Este programa es hecho en C#y controla un servo, aqui les dejo el programa hecho en mplab para poder resivir los datos del programa y asi mismo controlar el servo.


```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;CONTROL DE SERVO
//DATE:26/JUNIO/'09
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16F628A.h>
#include<math.h>
#fuses HS,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=20000000)
#use rs232(baud=2400,xmit=PIN_A0,rcv=PIN_A1)

void config(void){
		set_tris_a(0x22);
		set_tris_b(0x00);
		setup_comparator(NC_NC_NC_NC);
}

void main(void){
		int x;
		float y;
		long z;
		config();
		output_b(0x00);
	do{

		x=getch();
		y=(x*6.666e-6)+0.9e-3;
		z=y*1000000;
		output_high(PIN_B0);
		delay_us(z);
		output_low(PIN_B0);
		delay_us(20000-z);
	}while(TRUE);
}
```
[/QUOTE]


----------



## Lvcios (Ene 11, 2011)

Eduardo dijo:


> Pos te lo está diciendo "La instrucción TRISB es desaprobada para el 16F628".
> 
> Desde hace un par de siglos  Microchip viene desaconsejando la instrucción TRIS, pero por misterios de la industria, se la sigue incluyendo en el código .
> 
> ...



Yo hice eso de editar el dispositvo pero me sigue marcando esa advertencia en proteus. No se que sea. Seguire intentando y vere los resultados.


----------



## Lvcios (Ene 11, 2011)

Bueno, obvio no me quede de brazos cruzados. He creado otra libreria para manejar el teclado matricial. Cuando le ajuste los ultimos detalles la subo para que entre todos le hagamos modificaciones. Es para trabajar con el puerto a de un pic16f628a por ahora...


----------



## Vegetal Digital (Ene 17, 2011)

Lvcios dijo:


> El código generado ya no incluirá TRIS y funcará como los dioses.



Y como configuras los puertos? Con *fast_io* ...?


----------



## theshark27 (Feb 11, 2011)

george.manson.69 dijo:


> este circuito lo que haces es por medio de la computadora tenemos un programa llamado hercules que hace la comunicacion serial con el pic, bueno por medio de este programa introducimos un password en este caso es "hola", si es asi prendera un led indicando que se activo algo, y si ponemos otra palabra que no sea "hola" prendera otro led indicando que esta mal el password.
> 
> 
> ```
> ...





HOLA MANSON interesante el programa pero como recien estoy empezando esto de programar PIC sólo se programar el 16f628a pero en assembler eso con sus 30 y pico instrucciones osea  como paso este programa a lenguaje ensamblador, gracias


----------



## dukex (Feb 15, 2011)

theshark27 dijo:


> HOLA MANSON interesante el programa pero como recien estoy empezando esto de programar PIC sólo se programar el 16f628a pero en assembler eso con sus 30 y pico instrucciones osea  como paso este programa a lenguaje ensamblador, gracias



Mejor empieza busando informaión sobre lenguaje C para que vayas  aprendiendo es muy fáil y  te será de gran ayuda aprender a programar en este lenguaje...

saludos


----------



## theshark27 (Feb 15, 2011)

ok brother, gracias por la sugerencia


----------



## norman sanchez (Feb 22, 2011)

Hola a todos 
soy un poco nuevo en esto les agradeceria a todos por su ayuda necesito realizar un contador de 0-9 con un pulsador que cuando lo cierre me haga decremento no es mucho pero no he podido realizarlo agrdezo por la ayuda gracias...


----------



## checharrin (Mar 3, 2011)

Hola! Bueno creo q todos tienen excelentes proyectos pero quisiera saber si tiene alguien el codigo para controlar el pic 18f4550 desde el usb y me lo reconosca el software de jvm servo es q por q no tenia para comprar la placa yo hice mi propio circuito y placa pero necesito el archivo hex para q me la reconosca la compu y poder controlar los servos en tiempo real o si alguien me puede ayudar =(  bueno es para un brazo robotico


----------



## COSMICO (Mar 3, 2011)

Hola amigo george.
Intento incluir este codigo en el ccs pero me da muchos errores
quiero usar el tmr0 pero en asm, ¿que me sugieres?
Un saludo


----------



## george.manson.69 (May 3, 2011)

Tarjeta para labview muy economica, 8 Entradas Analogas, 8 entradas Digitales, 8 Salidas Digitals.

Salu2!!!


----------



## PAKAR (May 4, 2011)

Hola
no se si puedan ayudarme con un progarama en mplab
q nege 
CON UN PIC 16F84
ejemplo:
Pongo 1 me lo cambie a cero

se los agradeceria mucho
grax de antemano


----------



## COSMICO (May 4, 2011)

Si a lo que te refieres, que al poner un alto en algun pin del port
otro pin de cualquier port cambie a cero, seria algo asi, para RB0>>>RB1

  bsf  status,rp0; paso al banco 1
  MOVLW 0X01
  MOVWF PORTB; RB0 es entrada, el resto salidas; (La instruccion tris,es ambigua)
  bsf status,rp0; Paso al banco 0
  CLRF PORTB; limpio el port
loop
  BTFSS PORTB,0 ; Pregunto si rb0 es 1
  GOTO ESCERO ; no es 1, salto a ESCERO
  BSF PORTB,1; si es 1 rb0, pogo en  1 rb1
  goto loop; regreso a loop
ESCERO
  BCF PORTB,1; pongo a 0 rb1
  goto loop; regreso a loop

Solo tienes que implementar la rutina anti rebote para el pulsador , o hacerlo por hardware


----------



## PAKAR (May 8, 2011)

Grax
x la respuesta
pero la verdad no entendi nada d nada
esq no e usado el programa


----------



## COSMICO (May 9, 2011)

Amigo.
Te sugiero, que estudies el asembler, pues de otra manera va a ser muy dificil ayudarte.


----------



## electrocebados (May 9, 2011)

*Hola!!! como va??*
Soy algo nuevo en el mundo de la programacion de pics... y todavia no se muy bien el codigo en assambler! podrian ayudarme a modificar un programa echo en .asm para poder programar el pic?? 
es un programa muy bueno!! *Se trata de un decodificador DTMF y es controlado por el pic 16f84* , pero quisiera tener varias versiones del programa.
*tengo el programa original en .asm y quisiera modificarlo*, despues de hacer tantas pruebas no pude lograr lo que buscaba!! *podrian ayudarme?? lo necesito lo antes posible!!*

gracias saludos!!!!


----------



## panchillo (May 29, 2011)

tengo un programa "MPLAB" y quisiera saber como utilizarlo, por ejemplo: quiero hacer un programita sencillo que empieze de 30 y decremente de 1 en 1 hasta 20 y de ahì empiece a decrementar de 2 en 2 hasta cero y volver a 30 y vuelva a hacer lo mismo, que quede ciclado!!!, sabes como hacer este programa, se me hace que ha de estar sencillo, pero es que no conosco la funciones de este programa que tengo y quiero utilizarlo.....

me despido de usted enviandole un cordial saludo.


----------



## COSMICO (May 29, 2011)

tienes idea de lenguaje asembler?


----------



## panchillo (May 30, 2011)

si tengo una idea, pero no se como utilizarlo por que yo no soy programador, me gusta la electronica y estoy incursando en esta heramienta de mplab, me gustaria que me ayudaran, para ser mas claro, saber como utilizar este lenguaje.....


----------



## Moyano Jonathan (May 30, 2011)

> si tengo una idea, pero no se como utilizarlo por que yo no soy programador, me gusta la electronica y estoy incursando en esta heramienta de mplab, me gustaria que me ayudaran, para ser mas claro, saber como utilizar este lenguaje.....



Si tenés las herramientas software y hardware , es cuetión de que te bajes cualquier libro de programación (hay cientos de ellos) y te pongas a programar...no es dificil...solo es cuestión de sentarse y ponerse a trabajar.

Un saludo !


----------



## panchillo (May 30, 2011)

ok, muchas gracias, cual me recomendarian, que este muy bien explicado...


----------



## COSMICO (May 30, 2011)

El mas bueno y completo en mi opinion, para programar asembler es.
Microrontrolador pic 16f84.
Desarollo de proyectos
2ª edicion
Con este libro aprendes a programar, muy facil y su contenido es muy bueno
Ya despues te pasas a una gama mas alta de pic.
Buen viento y buena mar.


----------



## panchillo (May 31, 2011)

muchas gracias cosmico  ...... seguire por aqui dandoles guerra por que me quiero preparar con esta herramienta y saber programar. 

Saludos y que pases buen dia.


----------



## inspector gadget (Jun 1, 2011)

El mejor tutor c que he visto en mucho tiempo. Amigo George gracias por tu paciencia y generosidad para los que iniciamos el campo de los micros. Mi pregunta es ¿puedes indicarme la manera como puedo comenzar a programar la matriz de leds (cambiar el texto) con hyperterminal para evitar tener que programar el micro con el texto que elija? muchas gracias


----------



## arsfigo07 (Jun 2, 2011)

Hola panchillo, la verdad no es complicado tu programa pero eso si hay que leer mucho, porque uno te puede decir mas o menos pero lo importante es que lo entiendas. Para tu programa esto mas o menos haria.

cargar a w con en numero a decrementar, luego guardar ese numero en otro registro (ya que el registro w no es muy seguro para guardar la informacion), luego empezar a decrementar de 1 en 1 y al mismo tiempo ir incrementando otro registro; ejemplo voy decrementando al registro de nombre "abajo" pero voy incrementando a registro "arriba" y para comparar podrias hacer una vil resta y cuando el resultado de esta resta sea 0 bueno pues de ahi me paso a otra rutina.... Esa seria mas o menos la idea y para hacerlo ciclico:

LOOP

(y en esta parte todo tu codigo y de esta manera solito se va a resetear)

GOTO LOOP  

Como ves si cuando ya tengas un programa "piloto" lo subes y lo checamos!!!!. Echale gana!!!


----------



## guerra1488 (Jun 11, 2011)

Hola.
Estoy intentando hacer el programa para un 16F84. Tiene que visualizarse el contenido de un registro denominado contador.
Se inicializará a 0 y se va incrementando en una unidad por la acción de un pulsador A.
Otro pulsador B provocará una interrupción haciendo parpadear un led durante 5 s.


He conseguido hacer que mediante 8 leds en el puerto B se visualice el contenido del registro contador y aumenta cada vez que pulsas el A.
Lo de la interrupción no lo he consegudo. Gracias por vuestra ayuda.



> LIST	P=16F84A
> PA		EQU		0x05
> PB		EQU		0x06
> CONTA	EQU		0x0C
> ...


----------



## JuanCarlosabigor (Jun 12, 2011)

que onda guerra:
bueno para el manejo de interrupciones, debes de hacer mas o menos lo siguiente

declarar el vector de interrupcion que es algo    como esto:
              org    0x04
              goto    [etiqueta de subrrutina de interrupcion]

en al gunlugar de tu programa debes poner esta etiqueta donde va a estar la rutina de interrupcion,


[etiqueta de subrrutina de interrupcion]

     en esta subrrutina debes de habilitar la interrupcio externa  en el registro INTCON ya que para lo que deceas hacer es conveniente la interrupcion externa es el bit INTE=1, y las interrupciones globale GIE=1 etc.. 

           RETFIE     //con esta instruccion regresas de subrutinas de interrupcion

es conveniente almacenar el estado del registro W y el contenido del registro status cuando hay una llamada de interrupcion pero bueno eso te lo digo despues.

dale un vistaso al DATA del pic y lee sobre esto registro, ya que es mejor aprender a leer las datas de estos pics ya que hay biene toda esta informacion espero no haberte confundido mas hasta luego y suerte


----------



## guerra1488 (Jun 12, 2011)

Ok estoy mirando todo el DATA y los registros, a ver si lo consigo hacer. Es para un examen, el problema que escribi es el examen de la semana pasada, pero mañana nos lo vuelve a repetir y nose como sera, pero si algo parecido. Intentare sacarlo y a ver que tal se da la cosa.

Muchisimas gracias!!


----------



## gustavo333 (Jun 15, 2011)

Reciba usted un cordial saludo, permítanme presentarme mi nombre es Gustavo Mtz, soy estudiante en México, la razón del presente mensaje es el de solicitar de la manera mas atenta su ayuda, ya que se presenta la situación de que necesito hacer un proyecto para detectar los caracteres de un modulo Parallax GPS Receiver Module 28146, en que este transmite ya la trama completa NMEC atreves de un solo pin, y se desea enviarlas a la computadora utilizando un PIC 16F876, via el protocolo rs232, la captura de la cadena de datos del GPS es por el pin C1, este es un código que estando probando pero no obtengo algún dato significativo, este es el código que estamos usando en la Escuela.


```
#include <16f876.h>
#device ADC=10
#fuses HS,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP,NOCPD,NOWRT

//SE DEFINE EL FORMATO PARA LA Tx a 9600 BAUDS VIA RS-232 STANDAR, DADO QUE SON LAS
//PROPIAS LIBRERIAS DEL COMPILADOR CCS, (VER EL LIBRO DE GARDER "PIC C")
//CON UN OSC. 4MHZ Vtx=1200 BAUDS , PARA UN OSC. 10MHZ  Vtx=9600

#use delay (CLOCK=20000000)
#use rs232 (BAUD=4800, XMIT=PIN_C6, RCV=PIN_C7)

// SE DEFINE LA DIRECCION DEL PUERTO B COMO ELEMENTO DE ENTRADA SALIDA.
// ASI COMO LA DIRECCION DE MEMORIA DE CADA UNO DE LOS DEMAS PUERTOS A,B,C.
// DICHA INFORMACION SE ENCUENTRA ESPECIFICADA EN EL REGISTRO DE MEMORIA DEL PIC.
// (MAYOR INFORMACIÓN DATA SHEET DE MICROCHIP [url]WWW.MICROCHIP.COM[/url]

#use fast_io (b)
#byte porta = 5
#byte portb = 6
#byte portc = 7

// SE INCLUYE EL ENCABEZADO DE LA LIBRERIA PARA LA OPERACION DEL LCD
// POR EL PUERTO B,OBSERVAR PROGRAMA lcd_b.c

#include <lcd_b.c>
#use standard_io(C)
#use standard_io(A)

int j=0; 
char cadena[71];
char *buffer=cadena; // UNION entre el puntero y el vector

#int_rda 

void recepcion_serie() // Rutina de interrupción por recepción serie 
  {   
   buffer[j] = getc(); 
   j++; 
 
  
  } 

void main() 
{
lcd_init(); 
lcd_putc("\fPreparando...\n");  
enable_interrupts(INT_RDA); 
enable_interrupts(GLOBAL); 

while(true)
   {if(cadena[17]=='V')
    { printf(lcd_putc,"\f ERROR DE\n\t RECEPCION");
     delay_ms(10);
    }
   else
      {If(input(pin_a1)==1)
         {printf(lcd_putc,"\fTiempo=%c%c:%c%c",cadena[7],cadena[8],cadena[9],cadena[10]);//imprime el tiempo
         printf(lcd_putc,"\nFecha=%c%c/%c%c/%c%c",cadena[55],cadena[56],cadena[57],cadena[58],cadena[59],cadena[60]);//imprime la fecha
         delay_ms(10);
         }
      else
         {printf(lcd_putc,"\fLat=%c%c%c%c.%c%c%c%c%c%c",cadena[20],cadena[21],cadena[22],cadena[23],cadena[25],cadena[26],cadena[27],cadena[28],cadena[29],cadena[30]); // imprime la latitud
          printf(lcd_putc,"\nLon=%c%c%c%c%c.%c%c%c%c%c%c",cadena[32],cadena[33],cadena[34],cadena[35],cadena[36],cadena[38],cadena[39],cadena[40],cadena[41],cadena[42],cadena[43]);//imprime la longitud
          printf(lcd_putc,"\n%d",j);
          delay_ms(10);
         }
      }
   if(j>=71)
      {buffer[71]=(0);
      j=0;
      }
   }
}
```


Como podrá ver son escasos mis conocimientos en Lenguaje C, pero mi preocupación es que no completo algún programa de prueba para leer los datos y  enviarlos tanto al LCD   


Por lo anterior quisiera pedirle su ayuda, si me podría ayudar a completar o efectuar dicha función, en algún programa con código en C atreves del código CCS 4.0 con que cuento, para cumplir dicha tarea de capturar los datos del gps via el puerto serie, o bien agrdeceria que me pudieran proporcionar alhun ejemplo para desplegar losdatos en un lcd de 2x16


----------



## pilisimo (Oct 9, 2011)

Hola a todos.

Excelente foro, todo lo que cualquier principiante en microcontroladores PICS  necesita esta aquì. Felicitaciones a los creadores y colaboradores a este foro.

Me gustaria saber si alguien me puede ayudar con el siguiente proyecto.

Se necesita hacer un calendario con pic 16f628a y que tenga las siguientes caracteristicas.

Que muestre la fecha en un display lcd 2 x 16.(mes/dia/año)
Que muestre la Hora en el mismo display.(hh:mm:ss)
Que se pueda programar una alarma On/Off a una hora predeterminada (Cuatro eventos en el dia).


Ejemplo : que se prenda todos los dias a las 5:00 a.m. y se apague a las 06:00 am. Que se vuelva a Prender a las 14:00 y se apague a las 16:00 etc. Todo esto programable no fijo.

Por ultimo que trabaje con un reloj de tiempo real I2C.

Tengo ya algun codigo en desarrollo pero esta sin terminar. 

Me ha dado mucho dolor de cabeza este proyecto ya que soy nuevo en esto de los PICS.

Agradeceria su ayuda. Gracias.


----------



## Elizabethcm (Oct 31, 2011)

Me encata este foro me ha guiado en muchas ocasiones para practicar en ciertos temas.... ahora el problemita que tengo es con el puerto A del pic 16f877a he leido que tiene entradas y salidas digitales, y que hay que configurar el ADCON1 y modificar el registro TRISA, pero al poner los 3 primeros pines como entrada no me lo reconoce asi como no reconoce los que pongo como salida.... lo que quiero es encender un led del puerto A del pin A5 presionando un boton que se encuentra en el pin A0. Realmente no se que estoy haciendo mal. Agradeceria su ayuda. Gracias. Estoy usando MPLAB y Proteus.


----------



## D@rkbytes (Oct 31, 2011)

Elizabethcm dijo:


> Me encata este foro me ha guiado en muchas ocasiones para practicar en ciertos temas.... ahora el problemita que tengo es con el puerto A del pic 16f877a he leido que tiene entradas y salidas digitales, y que hay que configurar el ADCON1 y modificar el registro TRISA, pero al poner los 3 primeros pines como entrada no me lo reconoce asi como no reconoce los que pongo como salida.... lo que quiero es encender un led del puerto A del pin A5 presionando un boton que se encuentra en el pin A0. Realmente no se que estoy haciendo mal. Agradeceria su ayuda. Gracias. Estoy usando MPLAB y Proteus.


Pues para ayudarte siempre debes primero subir aqui el código que estas haciendo
para ver en donde esta el error, ya que así sin saber que estas haciendo es imposible.
Ni siquiera mencionaste en que lenguaje lo estas haciendo, solo que usas MPLAB y Proteus.
MPLAB trabaja varios lenguajes aunque su primordial sea el assembler.


----------



## Elizabethcm (Nov 2, 2011)

asi es es mplab assembler


```
LIST p=16F877A
INCLUDE<P16F877A.INC>

STATUS    equ   0x3
PORTA     equ   0x5
TRISA     equ   0x5
org 0x00
movlw B'00000110'
movwf ADCON1 
bsf STATUS,RP0
movlw B'00001111' ;bit 0-3 ENTRADAS y 4-7 SALIDAS
movwf TRISA
bcf STATUS,RP0 

INICIO
    btfss    PORTA,0        
    goto    ENCIENDE        
    bcf        PORTA,0       
    goto    ENCIENDE
ENCIENDE                    
    bsf        PORTA,0        
    goto    INICIO        
    END
```

es esto lo que ando haciendo no se si ando poniendo
mal lo de la entradas y salidas...


----------



## COSMICO (Nov 2, 2011)

Elizabethcm.
Estas usando el pin del porta, como entrada, y despues lo forzas como salida.
asi no te trabaja para nada.O es entrada o es salida, pero no ambas
ademas asi tu codigo, mantendra encendido el led siempre
Que quieres hacer exactamente.
¿Si el pin ra0 es cero, encender un led, y si es uno apagarlo?


----------



## Elizabethcm (Nov 2, 2011)

La idea es encender un led que lo ubico en el pin 4 (RA4) del puerto A, al presionar un botón ubicado en el pin0 (RA0) del mismo puerto. He leido que configurando el ADCON1 pongo los pines ya sea en entrada o salida digital. y modificando el registro TRISA especifico que pines con entrada y cuales salida. Esto es lo que hago en la primera parte. 
No entiendo que esta mal? porque igual tengo entendido que si es posible poner los pines tanto en entrada como en salida. Eso es lo que se me complica.


----------



## D@rkbytes (Nov 3, 2011)

Elizabethcm dijo:


> La idea es encender un led que lo ubico en el pin 4 (RA4) del puerto A, al presionar un botón ubicado en el pin0 (RA0) del mismo puerto. He leido que configurando el ADCON1 pongo los pines ya sea en entrada o salida digital. y modificando el registro TRISA especifico que pines con entrada y cuales salida. Esto es lo que hago en la primera parte.
> No entiendo que esta mal? porque igual tengo entendido que si es posible poner los pines tanto en entrada como en salida. Eso es lo que se me complica.


Saludos. No soy *cosmico* pero el tiene razón en cuanto a lo que estas haciendo mal
con el código que estas implementando, y como te comente en tu post que subieras
el código para entonces poder ayudarte pues ok.
En tu primer post dijiste que querias encender un LED en RA5
por medio de un Pushbutton en RA0 hasta ahí todo OK la cosa es facil.
Pero en tu código jamas usaste RA4 ni RA5, querias prender un LED sobre un botón presionado.
El problema radica en que si tratas de encender un LED por RA4 directamente
no se podra, ya que RA4 es Open Drain (Drenador Abierto)
resulta tendrias que hacer uso de un transistor que lo controle y usando una R Pull Up en RA4
Para mantener los dos estados "Eso pasa por no leer los datasheets"
Hay varios problemas relacionados con este detalle de los PIC y mas con la configuración del ADC
Bien, aqui dejo el código para encender un LED normalmente y otro usando Pull Up y un TR NPN
Nota: El LED dara un destello inicial cuando se usa Pull Up
Eso es debido a la configuración del transistor y a la inicialización del PIC.


----------



## Elizabethcm (Nov 3, 2011)

GRACIAS POR LAS OBSERVACIONES


----------



## gcgiron (Dic 10, 2011)

george.manson.69 dijo:


> control de un servo y comunicacion con la pc, este circuito lo que hace es esperar una senal de la cumputadora, para poder girar 45 grados, 90 grados, 135 grados o 180 grados, al girar a cualquier grados elegidoesperara un cierto tiempo en esa posiscion al termino de 3 segundos! regresara a su posicion original osea a 0 grados.
> 
> 
> ```
> ...


 
Una Pregunta:

#fuses *INTRC_IO*,NOWDT,NOLVP,MCLR,NOPROTECT

He resaltado el oscilador interno en la palabra de configuración, pues luego el reloj interno no trabaja maximo a 4MHz?

#fuses *HS*,NOWDT,NOLVP,MCLR,NOPROTECT

No quedaria mejor asi Para que el PIC corra a 20MHz con cristal externo? Si estoy mal corrijame.

Será que también se puede programar el cristal interno a 20 MHz?

Gracias.

Lo compile en CCS y lo simule en ISIS Proteus de esta forma y me salio.

Gracias.


----------



## D@rkbytes (Dic 10, 2011)

gcgiron dijo:


> Una Pregunta:
> 
> #fuses *INTRC_IO*,NOWDT,NOLVP,MCLR,NOPROTECT
> 
> ...


Cuando se usa la configuración de Oscilador interno siempre correra a 4Mhz.
Esa es la maxima velocidad del 16F628 para oscilador interno.


----------



## JuanCarlosabigor (Dic 11, 2011)

hola gcgiron como muchos compañeros lo han dicho es muy importante que revises la hoja de datos del pic que utilizas, en este pic al configurar el oscilador interno, el pic correra a 4 MHz, el cual es suficiente creo yo para manejar 2400 bauts, de igual  ten mucho cuidado cuando simules en proteus ya que pasa muchas cosas por alto vale saludos,


----------



## kuropatula (Abr 4, 2012)

Hola, eso mismo que necestiás está en la primer página de este post.
Saludos!


----------



## DEPREDADORX1 (Abr 17, 2012)

Hola a todos,

Estoy interesado en empezar con C y este foro es ideal para el objetivo, solo que tengo algunas dudas respecto al mplab ide...  estuve probando algunos ejemplos básicos que, supongo están probados ya, pero no logré que funcionara ninguno de ellos, siempre me presenta el error de que no existe el archivo referido al pic, sea el 16f628 o 16f877, probé con la version 8.84 y obtengo el mismo resultado, acaso existen limitaciones en las mismas o hay que instalar más librerías... no sé, espero que alguien pueda orientarme al respecto pues si no logro hacer funcionar lo más básico, cómo avanzo?

Como siempre, gracias a mil y felicitaciones por los programas.


----------



## JuanCarlosabigor (Abr 18, 2012)

que onda DEPREDADORX1

para poderte ayudar necesito saber si utilizas CCS o que "C" utilizas, ahora para mas fácil copia los archivos 16f628.h en tu proyecto; si puedes dar mas información tal vez podríamos apoyarte mas
suerte


----------



## DEPREDADORX1 (Abr 19, 2012)

Gracias por contestar,

Acabo de instalar Mplab ide 8.30, la idea es trabajar en c pues quiero guiarme también por los tutos de Cesar Cansino que parecen muy buenos. Quisiera comentar que revisando la carpeta include me he dado cuenta que no existe referencia al pic 16f628 ni tampoco al 16f877, supongo que debe haber restricciones de algun tipo pero no lo tengo claro, gracias por responder.

Ah, por cierto, para una muestra del problema:
Error   [141] E:\PROGRAMACION DE MICROCONTROLADORES EN C++\PROYECTOS 1\parpadeo led.c; 1.19 can't open include file "16f628a.h": No such file or directory


----------



## JuanCarlosabigor (Abr 19, 2012)

hola!
El error que pones no me dice nada lo siento, si podrías poner que compilador de C utilizas, ya que recuerda que Microchip no tiene un compilador de C para los pic16fxxxx, sin embargo existe CCS el cual es un compilador compatible con MPLAB.

Otra sugerencia es que pongas el código de tu programa para tener una mejor idea de lo que pasa,

tambien porque no intentas con Micro C  de mikroelectronika es muy buena la versión gratuita y sirve bien para los pic16fxxxx
suerte


----------



## DEPREDADORX1 (Abr 20, 2012)

Hola y gracias nuevamente,

Pues uso el Hitec c pro, supongo que es una versión con limitaciones, pero me parece raro para un código tan básico como los planteados aquí en la primera página.  Respecto al micro C, pues todo dependería que tantas variaciones tenga con respecto a lo que se trata aquí y en los tutos del señor Cancino, de cualquier forma, googlearé a ver que tal me va.


----------



## Ernaldo (Abr 24, 2012)

Buenas, buenas!
Soy nuevo en el foro, y sé que ustedes me podrán ayudar con esto

Es respecto al uso de algunos tipos de terminos a la hora de programar
Necesito que me expliquen como se llaman, para que sirven, cuando y porqque los utilizamos los siguientes comandos:


TMRO
PCL
Status
FSR
TRIS (a....e)
Port (a.....e)

y que se refiere cuando hablan de BCS y BCF

PD: en mi materia a cursar, usaremos el PIC16f887 y para compilar el programa Assembler
gracias por su atención y sigan ayudandonos y motivandonos en esta materia =]


----------



## RobinsonTaborda (Abr 24, 2012)

hola a todos  necesito ayuda con mi proyecto de grado

necesito  dllar  un programa para un pic 16f876a con el cual debo controlar dos servo motores hobby yo lo hice uno en mikcroC el cual me simula muy bien a la hora de montarlo en proteus pero lo necesito en MPLAB Y mejor si es MPLABX lo he intentando y no me da a continuación dejo el codigo les agradesco mucho en lo que me pudieses colaboraras ya que esto es para mi proyecto de grado de antemano muchas grasias


----------



## sshoice esparza (Abr 30, 2012)

diculpa me que signidicado tiene:
#byte TRISB=0x86
#byte PORTB=0x06

se que tiene que ver con la ram y con los bancos pero no me queda muy bien entendido me podias ayudar por favor gracias


----------



## COSMICO (Abr 30, 2012)

#byte TRISB=0x86
#byte PORTB=0x06

La primera, declara la posición del reg trisb en el banco de memoria uno
la segunda hace los mismo con el reg portb pero en el banco de memoria  cero

El trisb, sirve para configurar en que modo trabajara el port, entradas o salidas o combinadas, unas entradas otras salidas
Puedes ver esto en el mapa de memoria en el datasheet.

El portb se refiere al puerto físico o los pines del PIC, con este nombre. Es por donde saldrá o entrara la 
información que manejes en el PIC, según configuración del trisb.

Se declaran, para que el compilador los reconozca, cuando sean nombrados en alguna parte del programa, y no cause error de compilación


----------



## sshoice esparza (Abr 30, 2012)

por decir vi este ejemplo:



////////////////////////////////////////////////////////////////////////////////////
//   VsZeNeR"05      
//             6/Agosto/05
//
//Programa:   Parpadeo de un led cada 0.5s 
//Version:   0.0
//
//Dispositivo: PIC 16F648A      Compilador:    CCS vs3.227
//Entorno IDE: MPLAB IDE v7.20   Simulador:    Proteus 6.7sp3
//
//Notas: Parpadeo de un led cada 0.5s por el pin RB0 del puerto B
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h>         //pic a utilizar          
#fuses XT,NOWDT,NOPROTECT,PUT      //ordenes para el programador 
#use delay (clock=4000000)         //Fosc=4Mhz
#use fast_io(b)

///PROGRAMA
void main(void)
{
   set_tris_b(0xFE);   //portb como salida(RB0,las demas desactivadas)
   disable_interrupts(GLOBAL);   //todas las interrupciones desactivadas

   do{   
      output_low(PIN_B0);          //led off
      delay_ms(500);            
      output_high(PIN_B0);        //led on
      delay_ms(500);
   }while(TRUE);                //bucle infinito
}



por que no se declara el puerto b como entrada y salidas y simplemente se pone:

set_tris_b(0xFE);

y no:

#byte TRISB=0x86
#byte PORTB=0x06

lo que no entiendo es cuando utilizar estos comandos o son equivalentes?


----------



## COSMICO (Abr 30, 2012)

no no no.
set_tris_b(0xFE); esta confuigurando el registro como RB0=salida
RB1...RB7, como entradas, esta usando notacion hexadecimal, 0xFE
el binario es asi,B'11111110' es donde se ve claro como queda configurado este registro de 8 bits
#BYTE, es una directiva.
set_tris, es una instrucción
Para mayor claridad ve al principio del este tema, alli podras aclarar tus dudas
Todo esta muy bien explicado.


----------



## sshoice esparza (Abr 30, 2012)

eso si lo entiendo es que lo que pasa es de que me tope con un tutorial y de ahí fui haciendo un programa
que es este:


```
#include <16f76.h>
#use delay (clock=4000000)
#fuses XT,NOWDT,NOPUT,NOPROTECT

#byte PORTB=0x06       
#byte PORTC=0x07

int dato;

void main(void)
  
  
    {
    
      set_tris_b(0x00);
      set_tris_c(0xff);
      portb=0x00;
      
         while (true)
            {
              dato= portc;
              switch(dato)
                     {
              case 1: PORTB =0xff;
              break;
              
              case 2: portb=0b00001111;
              break;
              
              
              case 3: portb=0b00111100;
              break;
              
              default: portb=0x00;
              break;
              
                          
                     }
              
            }
    
    }
```

es que no se que función tiene :

#byte PORTB=0x06       
#byte PORTC=0x07

por lo que me dices se que es un variable de tipo byte
pero a la hora de modificar la direccion de donde quero que se guarde el dato me marca error :S


----------



## COSMICO (Abr 30, 2012)

compila el programa y sube un pantallazo tal cual, sin cerrar ninguna pestaña


----------



## sshoice esparza (Abr 30, 2012)

Y pues es esto los errores que me salen

ESTOS ERRORES APARECEN CUNADO QUITO:

#byte PORTB=0x06 
#byte PORTC=0x07


----------



## COSMICO (Abr 30, 2012)

Mira eso es lógico.
Lo que el compilador te dice, es que no estas declarando las variables.
el compilador necesita de estas, y otras referidas al puerto que quieras usar.
Si quieres usar el puertoA te tacaria agregar


#byte PORTA=0x05

#byte PORTB=0x06
#byte PORTC=0x07
Son abligatorias, se deben declarar, no las borres


----------



## sshoice esparza (Abr 30, 2012)

ok son variables esta bien no necesariamente tiene que llamarse PORTC, PORTB, PORTA, 
ok pueden tener un nombre "x"
lo que no entiendo es por que esa variables no les puedo poner otra direcion por que a fuerza tiene que llevar esas direcciones ?


----------



## JuanCarlosabigor (Abr 30, 2012)

hola sshoice esparza

si miras la data del pic encontraras que el puerto A se encuentra en el banco 0 del mapa de memoria y su dirección es 0x05, es por eso que forzosamente debes de ponerle esta dirección, ya que en la RAM del pic esta reservado esta posición para el puerto A, de  igual forma para el puerto B y  C que tienen la direccion 0x06 y 0x07 respectivamente.

por lo tanto los valores 0x05, 0x06 y 0x07, hacen referencia a una posición fisica en la RAM del pic y si le pones otro valor, estarías escribiendo en otro registro especial del pic lo que podria darte problemas ya que varios de estos registros configuran al pic para que funcione de cierta manera,

bueno espero no te halla confundido mas si no me dices y espero podertelo explicar de otra manera

saludos!


----------



## sshoice esparza (Abr 30, 2012)

hola JuanCarlosabigor


si lo pene a la hora de ver el   datasheet del pic


entonces esas direciones por decir #byte PORTA=0x05 es donde puedo guardar mis variables por decir 
algo?


y cual es la diferencia entre #byte PORTA=0x05 y #BYTE TRISA = 0X85  ?

o para cuales casos los puedo utilizar ?

gracias JuanCarlosabigor


----------



## JuanCarlosabigor (Abr 30, 2012)

bueno aquí hay cosas que aclarar

1. el porta es donde guardaras la información que leeas en el puerto A y asi con los otros puertos 

2. los registro tris, como trisa,   trisb o trisc etc, sirven para configurar los puertos ya sea de entrada o salida,
por ejemplo

si tu quieres que los 4 bits mas significativos del puerto A sean entradas y los 4 bits menos significativos sean salidas, pondrias trisa=0xf0; donde un "1" configura al pin como entrada y un "0" lo configura como salida


----------



## sshoice esparza (Abr 30, 2012)

bueno se pone :

set_tris_a(0b11110000);
lo que llo tengo entendido lo que no eniendo e cuando se le pone el #byte ....
como :
TRISA = 0X85
se que tanben es algo sobre los bancos pero se me ase muy confuso por wue todabia no lo logro entender


----------



## JuanCarlosabigor (Abr 30, 2012)

set_tris_a(0b11110000); es una funcion del compilador CCS, esta instruccion es equivalente a las siguientes declaraciones

#BYTE TRISA = 0X85  // posicion en la ram del pic
TRISA = 0XF0            // asignacion en el programa principal

con set_tris_a te ahorras el declarar #BYTE TRISA =0x85


----------



## sshoice esparza (Abr 30, 2012)

y cual es lo equivalente de :

#byte PORTB=0x06
#byte PORTC=0x07



osea a declarar estos datos le estoy dicendo al pic que voi a utilizar el puerto b y el puerto c?

y asi a la hora de mencionar el puero b y c no marque error
por decir  portb=0b11110000;


----------



## JuanCarlosabigor (Abr 30, 2012)

#byte PORTB=0x06
#byte PORTC=0x07

exactamente si pones esto, le indicas al compilador que utilizaras el puerto b y c, pero recuerda que si utilizas mayúsculas debes de utilizar mayúsculas, PORTB es diferente a portb, esto es un error comun que nos llega a pasar.


----------



## ByAxel (May 1, 2012)

sshoice esparza dijo:


> osea a declarar estos datos le estoy dicendo al pic que voi a utilizar el puerto b y el puerto c?
> 
> y asi a la hora de mencionar el puero b y c no marque error
> por decir  portb=0b11110000;



Si y no . No te enrriedes que en la mayoria de casos ni se usa esas declaraciones...
Con setear los TRISx con Set_tris_x() ya puedes usar los puertos para leer o escribir. Para eso ya se utiliza las otras funciones que dispone el CCS como output_b(0x0F);

Es decir que el equivalente de


```
#byte PORTB = 0x06
...
PORTB = 0b11110000
```
es simplemente

```
output_b(0b11110000);
```
- Ahora, creo que te pone en dudas el valor que se le asigna a #byte PORTB por ejemplo. Segùn la hoja de datos del PIC (que es importante leer) dice que el registro PORTB se encuentra en la direcciòn (posiciòn de memoria) 0x06 de la RAM (registro especial). Si cambias ese valor entonces solo se està apuntando a otro sitio dentro de la memoria RAM.
- El nombre que se pone luego de #byte es solo referencial. Lo mismo sucede si se pone

```
#byte SALIDAS = 0x06
...
SALIDAS = 0b11110000
```

Un saludo

PD: Revisa el archivo de ayuda del CCS que està todo (sintaxis, funciones, etc...)


----------



## sshoice esparza (May 1, 2012)

ByAxel mi problema empeso cuando me tope con este programa no e terminado de comprenderlo en la cuestion de que es lo que hace :
#byte PORTB=0x06
#byte PORTC=0x07

no se si nadamas estoy declarando los puertos como entradas/salidas es donde estoi confunido
yo pense que era para eso para declarar entradas/salidas pero a cambiar la direccion como
#byte PORTB=0x00 (todos los pines salidas) me marca error en el compilador
 de que portb no esta declarado o algo asi :S

#include <16f76.h>
#use delay (clock=4000000)
#fuses XT,NOWDT,NOPUT,NOPROTECT

#byte PORTB=0x06
#byte PORTC=0x07

int dato;

void main(void)


    {

      set_tris_b(0x00);
      set_tris_c(0xff);
      portb=0x00;

         while (true)
            {
              dato= portc;
              switch(dato)
                     {
              case 1: PORTB =0xff;
              break;

              case 2: portb=0b00001111;
              break;


              case 3: portb=0b00111100;
              break;

              default: portb=0x00;
              break;


                     }

            }

    }


----------



## ByAxel (May 1, 2012)

creo que te pone en dudas el valor que se le asigna a #byte PORTB por ejemplo. Segùn la hoja de datos del PIC (que es importante leer) dice que el registro PORTB se encuentra en la direcciòn (posiciòn de memoria) 0x06 de la RAM (registro especial). Si cambias ese valor entonces solo se està apuntando a otro sitio dentro de la memoria RAM.
- El nombre que se pone luego de #byte es solo referencial. Lo mismo sucede si se pone


```
#byte SALIDAS = 0x06
...
SALIDAS = 0b11110000;
```


----------



## sshoice esparza (May 1, 2012)

bueno eso si lo entiendo ya me cheque en los bancos 
pero para que sirbe declarala o no 
(#byte PORTB=0x06  #byte PORTC=0x07) en el programa?
osea nadamas estoi declarando una variable?
i la estoy almacenando en esa direeccion por : 0x06


----------



## ByAxel (May 1, 2012)

#byte PORTB no es para declarar entras o salidas, con eso solo le estas indicando al compilador que una posicion de memoria de la RAM va ser usado con el nombre PORTB, por eso lo indico mas arriba que el nombre PORTB solo es para simbolizar la direccion 0x06 que obviamente es del PORTB. Igual se puede poner otro nombre con la misma direccion y ser usado dentro del programa sin inconvenientes.



sshoice esparza dijo:


> osea nadamas estoi declarando una variable?
> i la estoy almacenando en esa direeccion por : 0x06



Sip. Cada vez que leas o escribas en la dicha variable la va estar haciendo en el PORTB para el caso del ejemplo.



El compilador dispone de las siguientes funciones para los puertos de I/O

```
[B]DISCRETE I/O[/B]

 
[LIST]
[*]get_tris_x( )
[*]input( )
[*]input_change_x( )
[*]input_state( )
[*]input_x( )
[*]output_X( )*
[*]output_bit( )
[*]output_drive( )
[*]output_float( )
[*]output_high( )
[*]output_low( )
[/LIST]

[LIST]
[*]output_toggle( )
[*]output_x( )+
[*]port_x_pullups( )*
[*]set_pullup( )+
[*]set_tris_x( )
[/LIST]
```

En tu ejemplo puedes reemplazar con:

```
portb=0x00; con output_b(0x00);
dato= portc; con dato = input_c();
...
```

Puedes usar uno u otro mètodo, es igual.


----------



## sshoice esparza (May 1, 2012)

entonces cuando se declara una variable al mencionarla se debe escribir tal y como es ejemplo
portb = PORTB por que esto en el programa no afecta?
por que me la toma como la misma variable?


----------



## ByAxel (May 1, 2012)

sshoice esparza dijo:


> entonces cuando se declara una variable al mencionarla se debe escribir tal y como es ejemplo
> portb = PORTB por que esto en el programa no afecta?
> por que me la toma como la misma variable?



ok, creo que te confundes con la misma palabra byte, recuerda que escribir
*#byte* que se usa para acceder a los *registros especiales* es distinto de declarar una variable como *byte dato; *(tambien se escribe como *int8 dato;*) la cual es una variable que ocupa una posicion de memoria en la parte de la RAM denominada "registros para el usuario".

En *portb = PORTB;* y si no està activada una opcion para que el compilador sea sensible a mayusculas y minusculas entonces solo esta pasando el contenido de la misma a la misma variable.


----------



## sshoice esparza (May 1, 2012)

eso ya me quedo entendido pero entonces en el programa para que hacedemos a los registros especiales?
y en que forma me afecta al borrarlo del programa?
#byte PORTB=0x06
#byte PORTC=0x07


----------



## ByAxel (May 1, 2012)

sshoice esparza dijo:


> eso ya me quedo entendido pero entonces en el programa para que hacedemos a los registros especiales?
> y en que forma me afecta al borrarlo del programa?
> #byte PORTB=0x06
> #byte PORTC=0x07



Para el ejemplo que pones es mero gusto del quien hizo el programa. Puesto que dentro del programa utiliza lo que ha declarado.

Lo pongo de esta manera:


```
#include <16f76.h>
#use delay (clock=4000000)
#fuses XT,NOWDT,NOPUT,NOPROTECT
 
int8 dato;
 
void main(void)
    {
 
      set_tris_b(0x00);
      set_tris_c(0xff);
      output_b(0x00);
 
         while (true)
            {
              dato =  input_c();
              switch(dato)
                     {
              case 1: output_b(0xff);
              break;
 
              case 2: output_b(0b00001111);
              break;
 
 
              case 3: output_b(0b00111100);
              break;
 
              default: output_b(0x00);
              break;
                     }
            }
    }
```

He reemplazado las lineas de codigo que es para PORTB y PORTC haciendo lo mismo con la diferencia que he usado funciones del mismo compilador.  

Parece que el CASE no està activado, por eso el compilador no distingue entre mayusculas y minusculas.


----------



## sshoice esparza (May 1, 2012)

exelente men


nadamas estas declarando la variable dato con : int8 dato;

pero para declarar una variable de tipo byte?


----------



## ByAxel (May 1, 2012)

sshoice esparza dijo:


> exelente men
> nadamas estas declarando la variable dato con : int8 dato;
> pero para declarar una variable de tipo byte?



El int8 es lo mismo que byte, por defecto toma valores de 0 a 255. El resto ya depende del programa si se desea usa signed o unsigned delante de byte o int8. En el tiempo que he usado el CCS me he dado cuenta que no es un compilador muy estricto.

Tambien hay int1, int8 , int16 que es lo mismo para byte, word, int, etc... todo esta en el archivo de ayuda.

Un saludo


----------



## DEPREDADORX1 (May 10, 2012)

Saludos,

Estoy tratando de mostrar la lectura del adc (AN0) del pic16f877A en una pantalla gráfica en proteus, francamente no sé cómo proceder pues no he acertado con la solución, estaré muy agradecido si me orientan o, si tienen,  un ejemplo básico para mostrar un float o entero en estas glcd.


----------



## DEPREDADORX1 (May 14, 2012)

Bueno, ya lo resolví con un ejemplo de la ayuda del pcw, aunque tengo algunas dudas al respecto y, formulo nuevamente, si alguien puede orientarme, muchas gracias de antemano. Mi dudas son respecto a lo que hacen algunas lineas del ejemplo como estas:

adc=(adc>249)?249:adc;

if (adc>200 && !warn)


----------



## ByAxel (May 14, 2012)

DEPREDADORX1 dijo:


> Bueno, ya lo resolví con un ejemplo de la ayuda del pcw, aunque tengo algunas dudas al respecto y, formulo nuevamente, si alguien puede orientarme, muchas gracias de antemano. Mi dudas son respecto a lo que hacen algunas lineas del ejemplo como estas:
> 
> adc=(adc>249)?249:adc;
> 
> if (adc>200 && !warn)



Hola:
En  adc=(adc>249)?249:adc;
es como un resumen de los comandos IF-ELSE que seria así:


```
if(adc>249){
   adc = 249;
}else{
      adc = adc;
}
```
y en  if (adc>200 && !warn)
hace una doble comparación y ambas tienen que ser verdaderas.

*Si*(If) ¿adc>200 *y*(&&) warm=0? *entonces*.... {}

Un saludo


----------



## DEPREDADORX1 (May 14, 2012)

Ah.... ya veo, mi sincero agradecimiento por tu respuesta, seguiré practicando ahora que me es un poco más claro esto a ver a donde llego y quizás mas adelante enbarcarme en un buen proyecto.

De nuevo gracias y mucha Suerte!


----------



## DEPREDADORX1 (May 17, 2012)

Saludos nuevamente,

Estaba interesado en hacer un velocímetro en ccs pero veo que resulta complejo pues tiene que implementarse con timer y, segun he leido, resulta dificil alcanzar la precisión necesaria para tal fin pues habría que hacer lectura cada segundo, me gustaría tener la opinión del algun forero que sepa, pues entonces no me complico y lo dejo en basic (proton) pues tiene la orden Count para tal fin.


----------



## alejandrozambrano90 (May 24, 2012)

buenas tardes amigos.. estoy impresionado por las cosas que se pueden hacer con los microcontroladores, los felicito por tan excelente página. estoy iniciandome pocoa poco en el mundo de la programación y hace poco realice un llamado propeller displays con un 16F877A en el cual tengo conectado el puerto B a los leds (desde RB1 a RB7) para asi formar las palabras en una matriz de 7x5 (los 5 me los da el desplazamiento de la barra de leds), ademas de esto le tengo 2 leds conectados 1 a RA0 y el otro a RA1 los cuales los tengo en los extremos de la barra para asi tener un marco en la imagen, en inconveniente que tengo es la sincronización que debe tener el sistema para que al pasar por los 360° de la circunferencia se haga una interrupción y me comience de nuevo el mensaje(cosa que no sucede y cuando termina de escribir el mensaje se repite de inmediato), lo que se me ha ocurrido es un sensor óptico de barrera conectado al RC0 que con el registro de control del timer 1 se pueda obtener esta señal y enviarlo de nuevo al inicio de la escritura en el display, lo que no se es como leer este registro para así cada vez que se termine de leer la palabra el micro tenga que esperar a que se culminen los 360° para volver a empezar.

De antemano les agradezco su colaboración


----------



## rencor (Jun 26, 2012)

tu si broer ah para aquel *qu*e empieza tus ejemplos son muy utiles sigues asi muchacho.


----------



## lopezulises4 (Jul 6, 2012)

hola a todos 
tengo un problema y no se como resolverlo, es referente al pic12f508 donde tengo las instrucciones para encender dos led.
en la primera intruccion se enciendn las salidas 3 y 4 (uno y despues el otro) en la segunda intruccion es parecida solo que quiero que se repita por lo menos 5 veces antes de que regrese a la primera instruccion.
despues quiero que al mismo tiempo se encienda los 2 led pero no me lo respeta solo enciende uno a la vez (este codigo no lo inclui debido a que no me encienden asi).
ojala alguien pueda hecharme la mano 

incluyo el programa


```
LIST P=12F508, r=hex   ;originalmente es PIC12C508 yo lo cambie porque uso el 12F508
   INCLUDE "P12F508.INC"   ;Incluimos la libreria que originalmente era PIC12C508

   __CONFIG _MCLRE_OFF & _CP_OFF & _WDT_OFF & _IntRC_OSC ;Aquí se configuran los fusibles

; Variables
W   EQU 0
F   EQU 1

OUT1   EQU   0   ;GP0
OUT2   EQU   1   ;GP1
OUT3   EQU   2   ;GP2   ; no se usa GP3 por ser exclusivamente entrada
OUT4   EQU   4   ;GP4
OUT5   EQU   5   ;GP5
AUX1   EQU   0x0C   ;variable auxiliar
AUX2   EQU   0x0D   ;variable auxiliar
N    EQU 0x00

   ORG 0x000

   clrwdt


   movlw b'11000000'
   option

   movlw b'00001000'   ; Configura GP0-GP2 y GP4-GP5 como salida. GP3 solo es entrada
   tris GPIO

   bcf GPIO,OUT1   ;Borra todas las salidas
   bcf GPIO,OUT2
   bcf GPIO,OUT3
   bcf GPIO,OUT4
   bcf GPIO,OUT5


flasher 
bsf  GPIO,OUT3   ;Enciende el tercer LED
   call retardo   ;Espera un tiempo
   bcf  GPIO,OUT3   ;Apaga el tercer LED
   call retardo   ;Espera un tiempo 

 bsf  GPIO,OUT4   ;Enciende el cuarto LED
   call retardo   ;Espera un tiempo
   bcf  GPIO,OUT4   ;Apaga el cuarto LED
   call retardo   ;Espera un tiempo
goto repetir


repetir
incf N,F
bsf  GPIO,OUT2   ;Enciende el tercer LED
   call retardo   ;Espera un tiempo
   bcf  GPIO,OUT2   ;Apaga el tercer LED
   call retardo   ;Espera un tiempo 
 bsf  GPIO,OUT5   ;Enciende el cuarto LED
   call retardo  ;Espera un tiempo
   bcf  GPIO,OUT5   ;Apaga el cuarto LED
   call retardo   ;Espera un tiempo

goto flasher


retardo
   movlw   0x80      
   movwf   AUX1
   movwf   AUX2
Dec_1
   decfsz   AUX1, F
   goto   Dec_1
   decfsz   AUX2, F
   goto   Dec_1
   retlw   0
```


----------



## tronik (Jul 8, 2012)

Hola como están gente !

tengo una duda con respecto a los fuses de este pic 
tengo varios microcontroladores como este que me encontré 
y quiero programarlos, pero ala hora de empesar con el programa 
me copie los fuses de un pic16f84a y los pege en el programa de pic16f767 pero me da  
 me da error el programa MPLAB

alguien se sabe los fuses para este pic 
o como buscarlos si por medio de datasheet o otra parte 
otra cosa estoy programando en assambler 


gracias!!


----------



## carferper (Jul 8, 2012)

lo mas facil es buscar el archivo  "P16F767" y ver al final del documento los bits de configuracion. En windows por ejemplo esta dentro del directorio "..microchip\\mplabx\mpasmx" en caso de que estes usando MPLABX.


----------



## D@rkbytes (Jul 9, 2012)

lopezulises4 dijo:


> hola a todos
> tengo un problema y no se como resolverlo, es referente al pic12f508 donde tengo las instrucciones para encender dos led.
> en la primera intruccion se enciendn las salidas 3 y 4 (uno y despues el  otro) en la segunda intruccion es parecida solo que quiero que se  repita por lo menos 5 veces antes de que regrese a la primera  instruccion.
> despues quiero que al mismo tiempo se encienda los 2 led pero no me lo  respeta solo enciende uno a la vez (este codigo no lo inclui debido a  que no me encienden asi).
> ojala alguien pueda hecharme la mano


Saludos.
Haz algo como esto.

```
clrf GPIO   ; Puerto en 0

flasher
;   Código...
;...............
;...............
    movlw 0x05        ; ¿Cuantas veces repetir?
    movwf contador  ; Cargar el contador en este caso con 5
    
repetir
;   Código...
;...............
;...............
; Aquí empiezas el bucle (loop)
    decfsz    contador,F    ; Decrementar contador
    goto    repetir    ; contador no llego a 0
;   Código...          ; contador llego a 0
;...............
;...............
    goto flasher
;***********************************************
; Y para encender dos o más LED puedes hacer esto.
    movlw    0x30
    movwf    GPIO    ; Pongo en 1 GPIO,5 y GPIO,4
    call    retardo
    clrf    GPIO    ; Los apago
    call    retardo
```
Suerte.


----------



## ivan1983 (Jul 9, 2012)

hola amigos mi problema este programa alguien me ayuda por favor:

                      list p=16f877, f=inhx32
                      #include<p16f877.inc>
     CBLOCK   0x20
     ENDC
                      ORG    0x00
                      GOTO COMIENZO
                      ORG    0x05
     COMIENZO  BSF STATUS,RP0
                      CLRF TRISB
                      BCF STATUS,RP0
                      CLRF PORTB
     SEGUIR       BSF PORTB,0 
                      CALL SEGUNDO
                      BCF PORTB,0
                      CALL SEGUNDO
                      GOTO SEGUIR
                      INCLUDE<RETAR_1s.INC>
                      END

LOS ERRORES DE ESTE PROGRAMA:
3 found directive in column 1. (CBLOCK)
4 "     "      "       "      "         (ENDC)
11 register in operand not in bank 0. ensure that bank bits are correct.
16 symbol not previously defined (SEGUNDO)
18     "       "        "           "             "
20 Cannot open file (include file <RETAR_1S.INC> not found)

por favor necesito ayuda ayudenme GRACIAS.


----------



## Daniel Meza (Jul 9, 2012)

Vayamos  por partes:



> register in operand not in bank 0. ensure that bank bits are correct



Cada que utilices algún registro más allá del banco 0 debes de especificar sobre que rango de memoria está, por ejemplo:

movwf TRISA^0x80

El registro TRISA se encuentra en el banco 1, por eso se debe especificar que está más allá del banco 0 por medio de la sintáxis "^0x80"



> symbol not previously defined (SEGUNDO)



Debes de declarar las variables a utilizar antes de usarlas.
Esto se logra por medio de:

Segundo EQU 0x20, donde en lugar de 0x20 puedes definir la posición de memoria que desees



> Cannot open file (include file <RETAR_1S.INC> not found)



La librería Retar_1s.INC debe de estar en la carpeta de librerías del ensamblador

Saludos


----------



## ivan1983 (Jul 9, 2012)

gracias amigo sobre las libreria como hago eso si no se me podes dar un dato ? y si no tengo de donde lo saco recien soy nuevo en los pic.....gracias


----------



## Daniel Meza (Jul 9, 2012)

Tienes que conseguirla. Si no, los retardos los puedes generar tu mismo con subrutinas de retardo.
Si apenas empiezas con esto te recomiendo este libro para que vayas aclarando dudas


----------



## ivan1983 (Jul 9, 2012)

daniel te agregue a mi msn y face para asi me ayudes un poco por favor me aceptas....gracias


----------



## Daniel Meza (Jul 9, 2012)

bien. Como ayuda te dejo este enlace , allí se habla sobre el tema de los retardos para PIC's


----------



## Luno (Jul 12, 2012)

Mis saludos cordiales.

La programación trata de una matriz de leds 8x8 utilizando el pic16f88

Tengo problemas que aún no las puedo resolver, quisiera pedir su ayuda, o alguna señal de cual podria ser la solucion..

A continuación pego el codigo que es en C. e indico los 5 errores que me aparecen al compilar en software MPLAB IDE v8.86



```
#include <16f88.h>      // Tipo de microcontrolador
#fuses INTRC_IO,MCLR    // Oscilador interno, MCLR activo
#fuses NOPUT,NOBROWNOUT // Sin Brownout reset ni Power up timer 
#use fast_io(B)       // La configuración de los puertos solo se hace al principio.
#use delay(clock=8M)    // Velocidad del oscilador interno 8 MHz

#define Load PIN_B0   // Load (STCP ambos integrados) B0
#define Clk PIN_B1   // Clock (SHCP ambos integrados) B1
#define dClm PIN_B2   // Data para las columnas (DS integrado 1) BC2
#define dLin PIN_B3   // Data para las lineas (DS integrado 2) B3


char  Memoria[96];      // 96 Bytes para la memoria (0 - 95)
char  Visor[8];         // 8 para el visor (8 columnas)

int1  flag;             // Flags de control
int1 flag2;
int   indx;             // Indice donde almacenará las nuevas columnas.
int   line;             // Linea que a mostrar.
int   time;             // Variables para el control de
int   ptime;            // la velocidad de desplazamiento.
int   t;                // Variable auxiliar.

void CargaMem(char Ascii);
void GuardaClm(char c);

#int_rtcc
void isr(){
   int Mul=128;         // Cada vez que ocurre la interrupcion
   if(++line>7)Line=0;  // selecciona la siguiente linea, si se pasa de 7 vuelve a 0.
   
   if(++ptime>5){      // Suma 1 a ptime. Si se pasa de 20
      ptime=0;          // lo pone en 0 y suma 1 a time.
      if(++time>200){   // Si se pasa de 200
         time=0;        // lo pone en 0
         Flag=true;     // y activa el flag.
      }
   }
   
   
   for(t=0;t<8;t++){    // Bucle 0 - 7 (Lineas)
      
    Aqui-> output_bit(dLin,!!(Visor[Line]&Mul)); //el error: Undefined identifier   PIN_B3

                                              
      if (Line==t)output_high(dClm);         // Si Line es igual a t
                                             // activa el bit correspondiente
      else  output_low(dClm);                // a la columna, sino lo desactiva.
      
    Aquí ->  output_low(Clk);  // el error: Undefined identifier   PIN_B1

    Aquí ->  output_high(Clk); // el error: Undefined identifier   PIN_B1
      
      Mul>>=1;          // Divide la mascara que compara con Visor[] (128,64,32...)
   }
   Aquí ->   output_low(Load);  //el error: Undefined identifier   PIN_B0
   Aquí ->   output_high(Load); // El error: Undefined identifier   PIN_B0

   
}
void main(){
   int k;   
   set_tris_a(0x00);
   set_tris_b(0x00);
   for (k=0;k<8;k++){
      Visor[k]=0;
   }
   for (k=0;k<96;k++){
      Memoria[k]=0;
   }                    // Limpia la memoria y el visor
   
   flag=true;           // Activo el flag para que cargue la memoria
   
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);  // Configuración del Timer0
   enable_interrupts(int_rtcc);              // Interrupcion por Timer0
   enable_interrupts(global);                // Interrupciones globales
   
   do{
      if (Flag){                 // Si el flag está activado
         flag2=true;             // Activa el flag2
         
         for (k=0;k<8;k++){      // Pasa el contenido de las primeras 8
            visor[k]=Memoria[k]; // columnas en memoria al visor
         }
         
         for (k=0;k<95;k++){        // Rota el contenido de toda la memoria
            Memoria[k]=Memoria[k+1];// a la izquierda 1=1+1, 2=2+1, n=n+1...
            
            if (Memoria[k]!=0){Flag2=false;} // Si hay alguna columna que no
                                             // esté vacía desactiva el flag2
         }         
         Memoria[95]=0;             // Limpia la ultima columna de la memoria
        
        if (Flag2){                 // Si flag2 está activo            
            indx=7;                 // a partir de la columna 7 
            CargaMem("PICROBOT");   // escribe PICROBOT            
         }
         Flag=false;                // Desactiva el flag
         
      }
   }while (true);    // Bucle infinito


}

void GuardaClm(char c){
   if (indx<94){
      Memoria[indx]=c;     // Guarda la columna en la ubicación actual de memoria
      indx++;              // y aumenta el indice
   }
}


void CargaMem(char ascii){    // Carga la memoria con el caracter deseado
   switch (ascii){    
      
      case('B'):
      GuardaClm(0b01111111);
      GuardaClm(0b01111111);
      GuardaClm(0b01001001);
      GuardaClm(0b01001001);
      GuardaClm(0b01111111);
      GuardaClm(0b00110110);      
      break;
      
      case('C'):
      GuardaClm(0b00111110);
      GuardaClm(0b01111111);
      GuardaClm(0b01000001);
      GuardaClm(0b01000001);
      GuardaClm(0b01100011);
      GuardaClm(0b00100010);     
      break;

      case('I'):
      GuardaClm(0b01000001);
      GuardaClm(0b01000001);
      GuardaClm(0b01111111);
      GuardaClm(0b01111111);
      GuardaClm(0b01000001);
      GuardaClm(0b01000001);      
      break;  

      case('O'):
      GuardaClm(0b00111110);
      GuardaClm(0b01111111);
      GuardaClm(0b01000001);
      GuardaClm(0b01000001);
      GuardaClm(0b01111111);
      GuardaClm(0b00111110);      
      break;      
      
      case('P'):      
      GuardaClm(0b01111111);
      GuardaClm(0b01111111);
      GuardaClm(0b00001001);
      GuardaClm(0b00001001);
      GuardaClm(0b00001111);
      GuardaClm(0b00000110);      
      break;
      
      case('R'):
      GuardaClm(0b01111111);
      GuardaClm(0b01111111);
      GuardaClm(0b00001001);
      GuardaClm(0b00011001);
      GuardaClm(0b01111111);
      GuardaClm(0b01100110);
      break;
      
      case('T'):
      GuardaClm(0b00000011);
      GuardaClm(0b00000001);
      GuardaClm(0b01111111);
      GuardaClm(0b01111111);
      GuardaClm(0b00000001);
      GuardaClm(0b00000011);
      break;      
   }
      GuardaClm(0b00000000);
}
```

*//Gracias*


----------



## D@rkbytes (Jul 12, 2012)

Luno dijo:


> Mis saludos cordiales.
> 
> La programación trata de una matriz de leds 8x8 utilizando el pic16f88
> 
> ...


Saludos Luno.
Cargue tu código en MPLAB v8.83 y usando como compilador PCWHD Compiler v4.114
Y no se presento ningún tipo de error al compilar el código.

*      Memory usage:   ROM=17%      RAM=35% - 36%
      0 Errors,  0 Warnings.*

El problema puede estar con el compilador que estas utilizando,
que no reconoce esas instrucciones y por eso te produce errores.

Aquí adjunto el proyecto generado por MPLAB.

PD. Movi tu tema a este otro por tratarse de un programa hecho en MPLAB

Suerte.


----------



## Luno (Jul 12, 2012)

Tenias razón.
Descargue el mismo plugin tuyo. y lo complile con eso. y si me funcó.

Gracias.


----------



## D@rkbytes (Jul 12, 2012)

Luno dijo:


> Tenias razón.
> Descargue el mismo plugin tuyo. y lo complile con eso. y si me funcó.
> 
> Gracias.


OK. Que bien.
Como el entorno de desarrollo MPLAB es multi lenguaje,
hay que instalar el plugin adecuado para cada tipo de lenguaje de programación.

En lo personal prefiero usar MPLAB solo para programas en ensamblador.
Y para otros lenguajes con su propio IDE, que por default ya tienen su propio compilador.

Así se evitan muchos problemas.

Suerte.


----------



## ilcapo (Jul 22, 2012)

algun programa en CCS usando: 

goto 

no puedo hacer arrancar el GOTO! me tira errores , saludos !


----------



## COSMICO (Ago 25, 2012)

Sube tu programa para ver cual es el error.


----------



## ByAxel (Ago 27, 2012)

ilcapo dijo:


> algun programa en CCS usando:
> 
> goto
> 
> no puedo hacer arrancar el GOTO! me tira errores , saludos !



Para el CCS utiliza la conbinacion del
goto_address() y label_adress()

El help del CCS explica como se utiliza.

Caso aparte aunque funcione para varios PIC no sugiero utilizar el GOTO para el lenguaje C... no es que no se pueda, es más una mala practica.

Saludos


----------



## Luno (Ago 27, 2012)

Buenas noches a todos. Tengo una duda.

Cómo poder utilizar el pwm y encender un led al mismo tiempo ?

Me explico: el pwm será controlado por 2 pulsadores, con uno aumenta y con el otro disminuye.

Y por otro lado utilizo un pulso que activa un led siempre y cuando el pulso este en 1 logico, si esta en 0 se apaga el led. 

Bueno, quiero aumentar el pwm y al mismo tiempo prender el led. Pero en mi programa al simular en el proteus cuando mantengo prendido el led se bloquea totalmente el pwm. Y cuando dejo el led apagado se desbloquea el pwm y es ahi cuando únicamente puedo controlar el pwm a mi manera... 

Esa es mi duda. 

Gracias.    Les dejo el programa. 



```
#include <16f877a.h>
#fuses NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP 
#use delay(clock=4000000)

void main()
{
   int i = 0;
   setup_adc_ports(NO_ANALOGS);
   set_tris_c(0x00);         		
   set_tris_b(0xFF);           		
   disable_interrupts(GLOBAL); 	
  
   output_b(0x00); //CCP1
   setup_ccp1(CCP_PWM);
 
   setup_timer_2(T2_DIV_BY_16, 255, 1);
 
 
   while(1)
   {
      if (input(PIN_B0)&&(i<255))
      i++;
      {set_pwm1_duty(i);
         delay_ms(8);}

      if (input(PIN_B1)&&(i>0))
	  i--;
      {set_pwm1_duty(i);
         delay_ms(5);} 

    	if (input(PIN_B2)){
		output_high(PIN_C4); 
	    while (input(pin_B2));
        }    
		output_low(PIN_C4);
   }
}
```


----------



## COSMICO (Ago 28, 2012)

Luno.
Ahí te envio corregido, el programa compila y prueba tal cual esta.
Me cuentas..


```
//*****************************
#include <16f877a.h>
#fuses NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP 
#use delay(clock=4000000)

void main()
{
   int i = 0;
   setup_adc_ports(NO_ANALOGS);
   set_tris_c(0x00);               
   set_tris_b(0xFF);                 
   disable_interrupts(GLOBAL);    
  
   output_b(0x00); //CCP1
   setup_ccp1(CCP_PWM);
 
   setup_timer_2(T2_DIV_BY_16, 255, 1);
 
 
   while(1)
   {
      if (input(PIN_B0)&&(i<255))
      i++;
      {set_pwm1_duty(i);
         delay_ms(8);}

      if (input(PIN_B1)&&(i>0))
     i--;
      {set_pwm1_duty(i);
         delay_ms(5);} 

       if (input(PIN_B2))//{
      output_high(PIN_C4); 
       //while (input(pin_B2));
       // }    
       else
      output_low(PIN_C4);
   }
}
```


----------



## Luno (Ago 30, 2012)

Gracias COSMICO me ah valido la compilación y es como lo queria, muchas gracias.

Bueno en esta oportunidad, mi pc se ah malogrado y ahora estoy en una laptop, eh vuelto a instalar el proteus y el MPLab IDE v8.87 Pero tengo problemas en instalar el compilador C, ya que manejo ese lenguaje.

Anteriormente en este mismo post lo habia preguntado y me resulto bien en mi Pc. Ahora que estoy en una lap nueva eh intentado instalar el compilador 4 veces pero al final no resulto del todo bueno.

Y queria que me ayudaran como poder instalar el PCWHD Compiler .... uso un Windows Seven Started


----------



## Luno (Ago 30, 2012)

Hola aquí nuevamente. y con buena cara  

Finalmente se me hizo , luego de aún seguir con el intento al fin.



Ohhh cuando creia que todo andaba bien.... al compilar en el MPLAB todo Ok .... me mostró "BUILD SUCCEEDED" , sin embargo, al ir al proteus y cargar en archivo hex. Oh sorpresa no está, pero están estos 2 archivos (cheken en la foto encerrada en rojo). y bueno cargué el que pesa de 14KB ... y el programa Sí funciona lo cargó bien y cumple con todas las funciones.

Pero, necesitaba el archivo .hex para utilizarlo en un grabador de Pics Pickit2 

Cómo hago ahora para generarlo ? ..... Gracias 

Me olvidaba aqui esta la foto:


----------



## cmontoya (Sep 20, 2012)

Hola amigos
Ya que estoy aprendiendo a programar  pic con hi-tech , tengo planeado hacer un publik (8x32) con ayuda de un código de george.manson que me a servido mucho . El único problema  que tengo  es que esta diseñado para una matriz 8x8 y  para extenderla toca  hacer lo que dice el código 



> (si lo contrario se desea usar mas matrices esto
> reducirá la velocidad y causara parpadeos o letras erróneas, para solucionar esto cuando mas matrices
> se use la interrupción por timer0 se debe de acortar)


Pues la verdad no se donde modificar el timer para arreglar eso 
Gracias por sus consejos


----------



## lilia (Oct 22, 2012)

hola duena tarde

soy muy nueva en esto perdon!!!!

pero quisiera saber como hacer el programa para un display rotativo que me muestre a pacman comiendo  o algo  asi para el pic 16f84  em mplab  o que haga lo que sea 


porfis!!!!!!!!!!!!!!!!!11

era carita triste jajajaja


----------



## cmontoya (Oct 22, 2012)

lilia dijo:


> hola duena tarde
> 
> soy muy nueva en esto perdon!!!!
> 
> ...



Sabes programar??? cual lenguaje ASM , Basic, C??


----------



## dragon33 (Oct 26, 2012)

Hola, les dejo un ejemplo de un programa y circuito en PROTEUS para aceder mediante pulsadores que tienen asignado un número cada uno a los numeros que están almacenados en tabla de memoria de programa, saludos.


----------



## krlitoz90 (Ene 30, 2013)

Hola amigos tengo el siguiente problema, visite el foro de george.manson.69 donde a puesto aplicaciones HID USB en proteus y descarge el archivo.
A la hora de la simulacion el puerto USB no funcionaba, entonces decidí investigar y me di con la sorpresa de que tenia que instalar los DRIVERS y eso hice. Pence que todo estaria correcto entoncs volvi a simular y mi Pc sonaba como cuando insertas una USB real y me salia el aviso de NUEVO DISPOSITIVO y luego me salia que mi dispositivo no funcionaria correctamente. La verdad noce que es lo que pasa si ya instale los drivers de Proteus que mas tengo que instalar para que funcione la simulacion. 
Necesito ayuda porfavor.
Adjunto la carpeta del ejemplo y las imagenes del problema


----------



## D@rkbytes (Ene 30, 2013)

Los drivers que necesitas para ese programa se encuentran dentro de una carpeta de la instalación de CCS
En esta --> C:\Archivos de programa\PICC\Drivers\NT,2000,XP,VISTA,7

Muevo tu post aquí, ya qué en el post _#109_ fue donde george.manson.69 adjunto el programa que mencionas.

Suerte.


----------



## krlitoz90 (Ene 31, 2013)

HOla amigo.. hice caso a lo que me dijiste C:\Archivos de programa\PICC\Drivers\NT,2000,XP,VISTA,7

Me salio 3 drivers ---> oem41, cdc_ntxpvista, cdc9xpt1.
Cuando instalo los dos primeros me dice que se instalo correctamente pero asi igual no funciona la simulacion en PROTEUS.. cuando instalo el ultimo me pide CCPORT y WDMMDMLD.VXD entoncs los descarge y los guarde en la misma carpeta DRIVERS  de PICC, luego de aceptar lo que me pide me dice que no se pudo instalar.. Haber si me das una mano con este tema porfavor.. te lo agradeceria muchoo
Te adjunto la imagen de la instalacion del ultimo archivo.


----------



## D@rkbytes (Ene 31, 2013)

Saludos.
Pues a mi tampoco me funciona el proyecto, habría que ver si alguien sabe que pasa. 
Pero esta es la secuencia para la instalación de los drivers.

Al ejecutar la simulación en Proteus, aparece el mensaje de nuevo hardware encontrado,
y como los drivers no están instalados saldrá la ventana del asistente de instalación.​ 
Seleccionar Instalar desde una lista o ubicación específica. Y presionar Siguiente.


Copiar y pegar la ruta de la carpeta en donde están los archivos (Drivers)
Ó presionar Examinar para buscar la carpeta manualmente.

Presionar siguiente, y comenzará la instalación.


Al terminar la instalación debe aparecer esto.

Instalación finalizada con éxito.

Y con eso quedarán instalados los drivers sin problemas.


El problema que tengo para hacer funcionar el programa, es que no sé en que puerto debe estar el programa.​ 
En la imagen que muestra george.manson.69, se ve en el puerto COM9, a mi no me funciona en ninguno.
Ver el archivo adjunto 22964
​De la forma como describo la instalación, a mi no me produce ningún error.
Sin embargo se requiere qué alguien que ya uso ese programa nos muestre como configurarlo.

Suerte y hasta pronto.​


----------



## COSMICO (Ago 21, 2013)

Hola amigo george.manson.69.
Espero estés bien. Queria preguntarte como te fue con tu proyecto de memoria sd, pues tengo la necesidad
de meter unas claves de cuatro y seis digitos e una Sd, tengo tu ejemplo, lo he intentado con otros pero no logro ni hacerla funcionar.
Pruebo con el tuyo de hola mundo y te comento.
Un saludo.


----------



## jamek (Sep 10, 2013)

george.manson.69 dijo:


> \\ simple circuito con un pic16f887, que se trata de un teclado analogo, escribimos la contrasena o la podemos cambiar.
> 
> 
> ```
> ...





tengo un par de dudillas, ví que puíste compilar con un pic 16f887, con mplab lo hicíste? porque intento instalar el ccs etc pero no me funciona, me sale una X roja al lado y no puedo empezar un proyecto sobre ése dispositivo, podrias ayudarme?
como podría empezar un nuevo proyecto en mplab con un pic 16f887?

Gracias!


----------



## D@rkbytes (Sep 10, 2013)

jamek dijo:


> me sale una X roja al lado y no puedo empezar un proyecto sobre ése dispositivo


Cuando te sale una *X* es porque no se ha encontrado el archivo correspondiente.
Asegúrate de que los programas tengan la ruta correcta en el paso 2 del Project Wizard.
En este caso selecciona el programa correcto Ccsc.exe en la carpeta de instalación de PICC.

Suerte.


----------



## callecuatro1976 (Ene 12, 2015)

Consulta: ¿Cómo visualizo el lcd en el pic16f883 y cómo declaro el adc?


----------



## D@rkbytes (Ene 12, 2015)

callecuatro1976 dijo:


> Consulta: ¿Cómo visualizo el lcd en el pic16f883 y cómo declaro el adc?


¿En qué lenguaje y con qué compilador?
MPLAB es un entorno de desarrollo integrado (IDE) que soporta varios compiladores.


----------



## callecuatro1976 (Ene 13, 2015)

en c con el ccs


----------



## D@rkbytes (Ene 13, 2015)

callecuatro1976 dijo:


> en c con el ccs


Pues entonces no entiendo cuál es el problema.
Declaras el PIC, la palabra de configuración y la frecuencia de trabajo.
Luego la librería que usarás para la pantalla LCD.

En el void main estableces la configuración para el ADC, creas tus variables y fórmulas y muestras el resultado.

La verdad es que no entiendo el motivo de la pregunta, pues es algo muy sencillo.

Con tan solo escribir: setup_adc_ports(parámetros); Ya te olvidas de configurar el registro ADCON0
Con escribir: setup_adc(parámetros); Te olvidas de configurar el registro ADCON1
Con escribir: set_adc_channel(canal); Te olvidas de configurar el registro ANSEL o el relacionado a la selección del canal.
Luego lees el canal seleccionado: Variable = read_adc(Parámetros opcionales);
Resultado = (Mi Fórmula usando el valor de "Variable");
Y con escribir: printf(lcd_putc,"Resultado: %XX",Resultado); Ya muestras el resultado en pantalla.

El compilador de CCS hace muchas configuraciones por ti, así que prácticamente no importa el PIC mientras sea un PIC16 con ADC.

Aparte, en el foro existen muchos ejemplos sobre eso para darte una idea.


----------



## callecuatro1976 (Ene 14, 2015)

¿Por qué no me funciona con este PIC?
Lo hago con otro y sale todo bien, pero con el 16F883 no me anda.


----------



## D@rkbytes (Ene 14, 2015)

callecuatro1976 dijo:


> ¿Por qué no me funciona con este PIC?
> Lo hago con otro y sale todo bien, pero con el 16F883 no me anda.


Porque estás declarando usar todos los pines con ADC como análogos y tienes conectada la pantalla en el puerto B.
Los pines del PORTB <5:0> tienen conversores y si están en modo análogo, la pantalla no va a funcionar.

Cambia: setup_adc_ports(*all_analog*); por: setup_adc_ports*(sAN0,sAN3*); que son son los canales que usarás.

Notas:
En el código estás declarando una frecuencia de 8MHz y en la simulación tienes 4MHz.
Para ese PIC el compilador establece el puerto B para los pines de la pantalla.
Por lo tanto, ésto no tiene caso ponerlo: *#define use_portb_lcd true*
Y el fuse* XT* también sale sobrando cuando usas ésto: #use delay (*internal*=8,000,000) 

Si vas a usar ese tipo de declaración, mejor usa la siguiente:
*#fuses NOFCMEN, NOIESO
#use delay (internal = 8MHz)

*Tampoco tienes conectado el pin 1 (RE3/MCLR/Vpp) y no tienes declarado no usarlo. (Únicamente entrada)
En la simulación puede funcionar si no es llevado a +5V. Pero físicamente al no tener conexión puedes tener problemas.


----------



## callecuatro1976 (Ene 15, 2015)

Cambia: setup_adc_ports(*all_analog*); por: setup_adc_ports*(sAN0,sAN3*); que son son los canales que usarás.


 me volvia loco aca setup_adc_ports*(sAN0,sAN3*);  va con una barra o raya en el medio no con coma (san0|san3)


----------



## D@rkbytes (Ene 15, 2015)

callecuatro1976 dijo:


> Me volvia loco acá: setup_adc_ports*(sAN0,sAN3*);  va con una barra o raya en el medio no con coma (san0|san3)


Cierto. Eso pasa al escribir código por aquí, se llegan a olvidar algunos formatos. 

Espero que si hayas podido hacer funcionar tu circuito.


----------



## callecuatro1976 (Ene 16, 2015)

si esta bien puede hacerlo funcionar y estoy aprendiendo bastante gracias al tiempo que dedican ustedes en el foro.


----------



## rockoztar (Sep 24, 2015)

¿Qué tal? ¿Cómo están?

He estado viendo algunos de los programas que se han puesto aquí, pero siempre encuentro que para declarar las condiciones de inicio o configuración del PIC, ponen #FUSES 

Como pueden ver en mi imagen, al poner #FUSES, creo que no se detecta por el MPLAB y también el Delay parece como si no lo detectara.

Soy nuevo en esto de los PIC's y también en el MPLAB, no he hecho algún programa, pero quiero probar los que ya están hechos para el PIC16F628A.     

En esa misma imagen había leído que puedo configurar las salidas, oscilador y diferentes funciones del PIC, en la parte de "configuration bits", por eso agrego eso.

Las preguntas son:
¿Funciona con #FUSES? ¿El Delay funcionará con esa programación? ¿Y cómo genero el .hex? 

Saludos. Espero me tengan un poco de paciencia. Soy nuevo con esto.

Gracias!

He visto que ayudan a todos, por eso recurrí aquí.

El programa que copié de aquí, es el siguiente:

```
///////////////////////////////////////
//AUTOR:JORGE ARTURO RODRIGUEZ HERNANDEZ
//TITLE;CONTADOR 0 A 9
//DATE:23/ABRIL/2009
///////////////////////////////////////

//CONFIGURACION///////////////////
#include<16f628a.h>
#fuses INTRC_IO,NOWDT,NOLVP,MCLR,NOPROTECT
#use delay(clock=4000000)


//INICIO DEL PROGRAMA///////////////
void main(void){

//VARIBALES///////////////////////////
    int mostrar[]={0b11000000,0b11111001,0b10100100,0b10110000,
                   0b10011001,0b10010010,0b10000011,0b11111000,
                   0b10000000,0b00011000};
    int contador;
//CONFIGURACION E/S///////////////

    set_tris_b(0x00);
    do{
        for(contador=0;contador<=9;++contador){
            output_b(mostrar[contador]);
            delay_ms(1000);
        }
    }while(TRUE);
}
```


----------



## D@rkbytes (Sep 25, 2015)

El programa se debe compilar tal cual está, pero todo parece indicar que no estás usando el compilador de CCS.
¿Tienes instalado mediante MPLAB X el plugin para PIC C Compiler? 

En ésta imagen no aparece porque ya lo tengo instalado. 

Sigue las instrucciones de instalación que se irán mostrando.
Nota: Si te aparece una advertencia de que el plugin no está certificado, acepta y continúa con la instalación.

En versiones anteriores a MPLAB X 3.05 con instalar el Plugin bastaba, ahora se tiene que instalar y seleccionar en el menú "Tools\Plugins" Sección "Available Plugins"

Para crear el archivo ejecutable .hex, lo debes hacer desde el menú "Run" Opción "Build Main Project" 

Y si la compilación marcha bien, se debe generar el archivo .hex. 
Éste se crea dentro una sub carpeta llamada "production" dentro de la carpeta "dist" de tu proyecto.
Pero me parece que el directorio de salida es configurable.

Finalmente, cuando la compilación sea exitosa, verás lo siguiente en la ventana inferior del entorno. (Output)

Nota: El programa compilado es el que mostraste.


----------



## rockoztar (Sep 25, 2015)

Que tal D@arkbytes, gracias por tu respuesta, hice lo que me dijiste paso a paso... pero despues de que se instalo el plugin y se abrio el MPLAB salio este mensaje...



Y quise crear un nuevo proyecto para ver si salia habilitado el nuevo plugin y aparece asi...

Aparece instalado... pero a la hora de seleccionarlo dice que no esta... 

Que puedo hacer con este problema?
Instalo el demo que me dice del CCS? 


Gracias por las respuestas!



Pude resolver el problema que tenia con el plugin... tuve que bajar el demo que me decia... Lo instale y volvi a abrir el MPLAB y ya quedo configurado... adjunto una imagen para que vean que funcionó.

Muchas gracias por la respuesta... seguire haciendo mas preguntas... porque necesito hacer un programa de un semaforo interactivo con varias funciones... Después les voy pidiendo ayuda en lo que no pueda.

De nuevo muchas gracias por todo!


----------



## flaker26 (Jun 10, 2016)

Hola amigos. Les cuento que estoy en los primeros pasos de programación de PIC y estoy con un problemita en mi programa.
Ya lo he hecho y copilado, luego lo cargo al PIC pero al momento de la prueba no funciona como deseo.

La idea es que con un PIC16F84A, yo le ingrese un pulso de 5 V al puerto B  en el pin 7 y me encienda un LED conectado al puerto B  en el pin 0, quede prendido por unos segundos y luego se apague esperando una nueva señal en el pin 7.

Lo que en realidad me sucede a mi cuando lo pruebo, es que el LED se enciende cuando aplico los 5 V en el pin 7 y cuando saco los 5  V en el pin 7, el led se apaga.

Les cuento que en el simulador del MPLAB me funciona perfecto.
Muchas gracias y dejo el código para que lo revisen.

Saludos.

```
;=================================================== 
list   P=PIC16F84A      Micro PIC16F84A
;=============================================================
w             equ   00
reg1          equ   0d
status        equ   03
ptob         equ   06
ptoa          equ   05
trisa         equ   90
trisb         equ   86
t1            equ   0e
grueso        equ   100000
;=============================================================
c             equ   0
z             equ   2
rp0           equ   5
rp1           equ   6
;==============================================================
reset         
              org   0
              bcf   status,rp0
              bcf   status,rp1
              movlw  0x80
              tris  ptob
              bcf   status,rp0
;===========================================================
inicio        btfsc   ptob,7
              goto    enciende
              goto inicio
;=============================================================
enciende
              bcf    status,rp1
              movlw   0x80
              tris   ptob
              bcf     status,rp0
              movlw  01
              movwf   reg1
              movf   reg1
              movwf   ptob
              call demora
demora        movlw   grueso
              movwf   t1
tt1           decfsz   t1
              goto    tt1
              movlw   00
              movwf   ptob
              goto    reset
         
              
              end
```


----------



## Daniel Meza (Jun 10, 2016)

Hola.

Enhorabuena por la iniciativa, pero veamos. Hay varios detalles en tu programa:

1- TRIS no es una instrucción en esta familia de micros, eso de entrada indica que quizá no tengas bien configurada la selección del dispositivo en el compilador.

2- En el bloque de la etiqueta reset veo que pretendes configurar las E/S, eso se hace por medio de los registros TRISA y TRISB (0-Salida, 1-Entrada). Estos registros se encuentran en el banco 1 de RAM y tu previamente estas seleccionando el banco 0 (ambas instrucciónes anteriores bcf STATUS,RP0).

3- La llamada a la rutina de demora está algo "exótica" pues la rutina es parte del programa principal.

Como ves son varios puntos a tratar, te recomiendo que leas la casi biblia de los PIC's 16F "PIC6F84 desarrollo práctico de aplicaciónes", ahí ahondarás en todos estos detalles que te comenté.

Saludos


----------



## D@rkbytes (Jun 10, 2016)

flaker26 dijo:


> La idea es que con un PIC16F84A, yo le ingrese un pulso de 5 V al puerto B  en el pin 7 y me encienda un LED conectado al puerto B  en el pin 0, quede prendido por unos segundos y luego se apague esperando una nueva señal en el pin 7.


Los detalles del programa ya te los mencionó Daniel, y el programa que quieres hacer es muy sencillo.
Pero sí te hace falta adentrarte más sobre el lenguaje ensamblador para PIC.

Esta es una forma sencilla de realizar ese proceso:

```
list    p = 16f84a
    include    p16f84a.inc
    __config _XT_OSC & _WDT_OFF & _PWRTE_ON
    
    errorlevel    -302

#define    pin_entrada    PORTB,7
#define    pin_salida    PORTB,0

    cblock    0x20
        cnt1,cnt2,cnt3
    endc

    org    0x00

inicio
    bsf        STATUS,RP0            ; Banco 1
    movlw    b'11111110'            ; RB0 como salida.
    movwf    TRISB
    bcf        STATUS,RP0            ; Banco 0
    bcf        pin_salida            ; "pin_salida" en 0 al iniciar.
    
programa
    btfsc    pin_entrada            ; Comprobar el estado de "pin_entrada" (Saltar si es cero)
    goto    enciende_led        ; Es alto, ir a "enciende_led"
    goto    salir                ; Es bajo, ir a "salir"
enciende_led
    bsf        pin_salida            ; Poner en 1 "pin_salida"
    call    retardo_2s            ; Llamar a la rutina "retardo_2s"
    bcf        pin_salida            ; Poner en 0 "pin_salida"
salir
    goto    programa

retardo_2s    ; @ 4 MHz.
; 1999996 ciclos
    movlw    0x11
    movwf    cnt1
    movlw    0x5D
    movwf    cnt2
    movlw    0x05
    movwf    cnt3
retardo_2s_0
    decfsz    cnt1,f
    goto    $+2
    decfsz    cnt2,f
    goto    $+2
    decfsz    cnt3,f
    goto    retardo_2s_0
; 4 ciclos (Incluyendo la llamada)
    return

    end
```



flaker26 dijo:


> Les cuento que en el simulador del MPLAB me funciona perfecto.


Aparte de los problemas en tu programa, eso puede ser debido a que no estás incluyendo la palabra de configuración.
Entonces el compilador usará la que tiene por defecto y será con _RC_OSC (Oscilador RC)
El simulador no toma en cuenta ese importante detalle, tan solo la frecuencia de operación.
Por eso muchos programas funcionan en el simulador, y no físicamente.


Daniel Meza dijo:


> 1- TRIS no es una instrucción en esta familia  de micros, eso de entrada indica que quizá no tengas bien configurada  la selección del dispositivo en el compilador.


TRIS, si es una instrucción de esta familia de PIC con referencia al registro que se especifique, pero desde hace varios años ya es obsoleta.
Se puede seguir utilizando, aunque el compilador mostrará una advertencia sobre su uso.


			
				MPASM dijo:
			
		

> *Warning[224] Use of this instruction is not recommended.*


Ahora se recomienda usar la librería del PIC a usar, en este caso; "P16F84A.INC"
Ya que ahí es donde se encuentra la definición y dirección de puertos y registros. P.E. TRISB


----------



## Daniel Meza (Jun 11, 2016)

D@rkbytes dijo:


> TRIS, si es una instrucción de esta familia de PIC con referencia al registro que se especifique, pero desde hace varios años ya es obsoleta.
> Se puede seguir utilizando, aunque el compilador mostrará una advertencia sobre su uso.



Bien, esto si lo he aprendido hoy, sabía que existía, incluso la he usado pero para la familia 12FXXX. Entonces como tal, algunos miembros de la familia 16F si la pueden ejecutar pero no es recomendable. 

Salu2


----------

