Ayuda para programar pic en lenguaje "C"

Un saludo a todos los amigo del foro. Tengo tiempo por aca en el foro casi que digo que me criee en este foro, pero es mi primera vez que les ago un comunicado de auxilio.

Bueno el tema es que ahora me encuentro aprendiendo de programacion de PIC en CCs con el programita Pic C compiler ya que estoy cansado de los IC4013, 4017, 4063 y el que nunca falta el 555 y 556 y ahora me quiero ir con el PIC para ya trabajar todo digital.

Bueno me dejo de bla bla bla y les cuento lo que quiero


Nececito realizar en un PIC un programa en "c" que me lea unos pulso de la siguiente manera.

cuando lea un pulso en el puerto rb0; me encienda un led en ra0
cuando lea dos pulsos en puerto rb0; me encienda un led en ra1

de manera que si hay un pulso me encienda un puerto pero si lee 2 pulso me encienda otro puerto.

Ya realice este programa pero solo me cirve para un puerto.

#include <12f675.h>
#FUSES NOWDT, INTRC_IO, NOCPD, NOPROTECT, NOMCLR, NOPUT, NOBROWNOUT, BANDGAP_HIGH
#use delay(clock=4000000)
void init()
{
#define GP0 PIN_A0
#define GP1 PIN_A1
#define GP2 PIN_A2
#define GP3 PIN_A3
#define GP4 PIN_A4
#define GP5 PIN_A5
#byte OSCCAL = 0x80
setup_comparator( NC_NC_NC_NC );
setup_adc_ports( NO_ANALOGS );
setup_adc( ADC_OFF );
}
void main()
{
DO{
IF (INPUT(GP0)){ // Si se presiona GP0
output_toggle(GP2); // cambia el estado del pin GP2
WHILE (INPUT(GP0));
}
}
while(true);
}


Quiero que encienda de un toque al pulsador un led y de dos toques en menos de un segundo otro led pero que la entrada sea por el mismo puerto.

Graciasss... Espero su ayuda
 
lo que yo haria seria usar dos if y usar un delay para verificar si se a pulsdo dos veces el pulsador, animo no es tan complicado
 
Bueno hay algunas maneras de lograrlo facilmente, una de ellas la que menciona sammaael, al retardo que hace referencia es conocido como bouncefree delay o retardo antirebote, es usado cuando quieres senser el cierre de algun contacto mecanico o como en tu caso el toque de algun sensor con el dedo, porque ??
bien, para que te quede claro por que falla tu programa te explico de manera sencilla, aunque para una persona cerrar un switch o tocar el sensor dos veces en menos de un segundo puede parecernos rapidisimo al micro (pic en tu caso) le somos tan lentos como una tortuga recién parida.. solo recuerda que las instrucciones las ejecuta a la velocidad de 1us (un micro segundo) con algunas excepciones como los if, los goto en fin y eso si estas usando un cristal o reloj interno de 4MHz evidentemente si usas uno de mayor velocidad ese tiempo es aun mas corto.
De manera que cuando tu pegas o despegas tu dedo de el sensor, tu programa ya fue ejecutado miles y miles de veces, lo que en muchas ocasiones genera a nuestros ojos un comportamiento erratico.
Por ultimo, para efectos practicos el retardo generalmente es de 15 a 20 ms y con ello debieras tener una mejora substancial de tu programa, claro que puedes mejorarlo incluyendo algun par de instrucciones mas pero te lo dejo de tarea..
Saludos
 
Buenas amigo disculpen mi ignorancia pero es que estoy aprendiendo y bueno como dice el dicho "el que no sabe es como el que no ve".

La cuestion es que no se si les entendi vien, ice de la siguiente manera como parece que les entendi con un delay y otro IF y esta vien me lee solo el segundo pulso y me pone en 1logico el puerto GP2 pero la cuestion es que en el primer pulso tiene que encender el puerto GP1 por ejemplo:


Si recive un pulso en GP0 y no recive el segundo me de 1 en GP2
Y si recive un pulso y luego el otro que es en menos de un segundo por GP0 me de 1 en GP1 mas no me active el GP2

Esta es de la manera que acabo de probar.

void main()
{
DO{
IF (INPUT(GP0))
delay_ms(300);
IF (INPUT(GP0)){ // Si se presiona GP0
output_toggle(GP2); // cambia el estado del pin GP2
WHILE (INPUT(GP0));
}
}
while(true);
}
 
yo incluiria un output_toggle(GP1) despues de "cerrado" el segundo if, asi de no haber recivido otro pulso antes de un segundo se activara/desactivara GP1
y ese while(input(GP0)) para que lo pones?
saludos
 
Yo te sugiero que cuando generes cualquier programa antes de escribirlo directo en C o ensamblador o el lenguaje que prefieras, realices un diagrama de flujo, ello te facilitara llevar mejor la secuencia de tu programación y te dará visión de lo que requerirás, así sean bucles, toma de decisiones, tiempos de espera, modos de ejecución etc. ademas de lo que sugiere Meta
 
Gracias amigo. >Estoy leyendo el tuto que me recomendo nuestro amigo meta. Ya abia leido algunos cuantos pero ustedes mejor que yo deven saber que esto no se aprende de la noche a la mañana.
Por eso ya me le estoy metiendo a la practica para ir avanzando un poco mas.

Ayer flashee un PIC16f876 y lo arme en el protoboard que es un circuito de cerradura inteligente con un lcd 2x16 y teclado 4x4 y me gusto mucho pero hay un detalle que el programa me lo paso un amigo y es lo que no me gusta ya que quiero aprender hacer mis programas pero esto es como cuando estaba enpezando en el colegio que no sabia ni leer. Ustedes me deven entender jajaja.
Lo bueno es que ya tengo 12 años con la electronica y todo el resto lo se yo. E armado una cantidad de circuitos impresos de proyectos e echo un UPS para PC completo. Que incluso los ofresco para los que se quieran armar un buen UPS. Jajaja te podria dar asta unos 1000Watt el UPS.

Bueno ya no digo mas ya que me van a sacar del foro por decir tanto. Lo que pasa es que hay veces donde me vuelvo nostalgico. Jajaja

Seguire probando con el programa del tema de arriba ya que eso es algo que quiero adactarle a la alarma satelital.gsm del carro.
Ya estaba por hacerlo con un 4017 pero no me doy por vencido.
 
Gracias sammaael, ya prove con lo que me recomendaron pero tengo que revisar bien ya que hay algo que esta mal o quisas todo esta mal. El problema es que cundo lo pruebo en proteus al dar un pulso se me activa o al segundo pulso o alguna veces tengo que darle asta 3 veces para que encienda el led.

De verdad que Tengo un despelote con ese programa.
 
Buenas amigo acá estoy de nuevo, Les cuento que ya e aprendido a programar mucho mas en c. Hay voy poco a poco a paso de vencedores. Jajaja

Bueno el tema es que ahora me encuentro programando un control para un tablero de transferencia el cual ya esta casi listo excepto por unos detallitos que no e podido manejar bien.
El programa que les dejo es un control de tablero de transferencia de un banco de baterias que me elevan el voltaje a 110V en caso que falle el suministro electrico, el control que estoy haciendo consta con un voltimetro de salida, amperimetro de consumo, vatimetro y voltimetro para el voltaje de las bacterias. el cual tiene también un menú de 3 opciones para encender y apagar unos contactores.

el problema que tengo es que al ir y volver la luz los contactores se quedan apagado ya que se resetea el pic. Como podría usar las directiva de

read_eeprom (address):
write_eeprom (address, value):

Ninguno de los libros que tengo explica bien el funcionamiento de lo dicho.

#include <16f876.h>
#device adc=10

#FUSES XT,NOWDT
#FUSES
#use delay(clock=4000000)
#include <math.h>
#include <LCD.C>
#BYTE TRISA = 0x85
#BYTE PORTA = 0x05


enum funciones {panel,vol,amp,watts,bat,med,cal,ini};

void medir (void){
output_toggle(PIN_C5); }

void calibrar (void){
output_toggle(PIN_C6);}

void inicializar (void){
output_toggle(PIN_C7);}

void run_func(int numfunc){
switch(numfunc){
case 5:
medir();
break;
case 6:
calibrar();
break;
case 7:
inicializar();
break;
}
}

void main() {


int16 q;
float v,a,w,b;

int cnt=0;
bit_set (TRISA,2); // Puerto a2 como entrada
setup_adc_ports(RA0_RA1_RA3_ANALOG); // Puertos RA0 RA1 Analogico y RA2 Digital

setup_adc(ADC_CLOCK_INTERNAL); //fuente de reloj RC

lcd_init(); //iniciamos lcd
lcd_putc("\fDrago109 P:2010");
lcd_putc("\nTablero Transfer");
delay_ms(3000);

for (;;) {
set_adc_channel(0); //Avilitacion canal 0 tambien se escoje otro canal
delay_us(20);
q = read_adc(); //lectura canal 0
v = 160.0 * q / 1024.0; //convercion a tension
//p = 160.0 * es el voltage que queremos medir y
//q /1024.0 es el valor adc por el cual multiplicamos el V.rf
set_adc_channel(1);
delay_us(20);
q = read_adc();
a =50.0 * q / 1024.0;

w = a * v; // se multiplica los voltios por Amperios
// para dar un resultado en wattios
set_adc_channel(3);
delay_us(20);
q = read_adc();
b = 18.0 * q/ 1024.0;

if(b >=13.85) { //Apaga PIN_C0 al llegar la carga a los 13.85V
output_low(PIN_C0); }
if(b <=13.80){ //Activa PIN_C0 al estar la bateria a menos de 13.80V
output_high(PIN_C0); }

if(b <=9.8) { //Activa PIN_C2 al estar la bateria descargada 9.8V
output_high(PIN_C2); }
if(b >=9.9) { //Apaga PIN_C2 al la bateria estar en carga
output_low(PIN_C2); }

if(v <=90.0) { //Activa PIN_C3 al caer el voltage menos de 90.0V
output_high(PIN_C3); }
if(v >=91.0) { //Apaga PIN_C3 al voltage superar los 91.0V
output_low(PIN_C3); }

if(v >=145.0){
output_high(PIN_C4);}
if(v <=140.0){
output_low(PIN_C4);}

if(w <=900.0){ //Apaga PIN_C1 al superar los 900.0 Watts
output_low(PIN_C1);}
if(w >=900.0){ //Activa PIN_C1 al bajar los 900.0 Watts
output_high(PIN_C1);}


if (BIT_TEST(PORTA,2)==0) cnt++; //Calcula los pulsos del voton
delay_ms(100);
if (cnt>=8) cnt=0;

Switch (cnt){ // Segun numeros de veces pulsado el boton se elige el menu

case 0:
lcd_gotoxy(1,1);
printf(lcd_putc, "\f%01.0fVol", v);
lcd_gotoxy(9,1);
printf(lcd_putc, " %01.1fAmp", a);
printf(lcd_putc, "\n%01.0fWat", w);
lcd_gotoxy(9,2);
printf(lcd_putc, " %01.1fBat", b);
Break;

case 1:
printf(lcd_putc, "\f Voltage Salida");
printf(lcd_putc, "\nEstable= %01.2fV", v);
break;

case 2:
printf(lcd_putc, "\fAmperaje Consumo");
printf(lcd_putc, "\nEstable=%01.2fAmp", a);
break;

case 3:
printf(lcd_putc, "\f Watts Salida");
printf(lcd_putc, "\nWatts= %01.2fW", w);
break;

case 4:
printf(lcd_putc, "\f Carga Bateria");
printf(lcd_putc, "\n Carga= %01.2fV", b);
break;

case 5:
printf(lcd_putc, "\f Contactor RED");
printf(lcd_putc, "\n ON/OFF");
break;

case 6:
printf(lcd_putc, "\f Contactor Resp");
printf(lcd_putc, "\n ON/OFF");
break;

case 7:
printf(lcd_putc, "\f Aux Porton");
printf(lcd_putc, "\n ON/OFF");
break;
}
if (input(PIN_A4)==0){
delay_ms(100);
run_func(cnt);}

delay_ms(100);
}
}



Quisiera guardar en la eeprom interna el programa para que al volver la alimentacion el pic siga con la misma configuracion.
 
Atrás
Arriba