TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: aitopes en 29 de Agosto de 2007, 14:58:19
-
Hola!
Al fin me decidi, y estoy haciendo los primeros pinitos en CCS. Como no podia ser de otra manera, tengo un pequeño problema:
Tengo un programa que debe secuenciar las salidas del puerto B dependiendo del estado de A0 y A1 (que me permiten elegir el programa 1, 2, 3 o 4 y del estado de A2 y A3, que me permiten elegir cuatro velocidades distintas.
He programado todo con funciones, pero ponga como ponga los jumpers en A0, A1, A2 y A3, me toma el programa 0 con velocidad 0, por lo que deduzco que no me esta leyendo el PORTA, o bien las funciones que escribi para leer el puerto no funcionan como quiero.
El codigo es algo extenso, pero lo posteo completo por que puedo haber metido la pata en las directivas de principio, o dios sabe donde.
Por ultimo: el programa lo pruebo sobre el pic mismo, ya que como estoy aprendiendo, tome un proyecto que tenia terminado en BASIC, que funcionana ok, y lo estoy reprogramando en CCS.
Este es el codigo. Me gustaria me reten un poco, y vean si encuentran el error. Gracias! :mrgreen:
//------Directivas para el compilador--------
#include <16f627a.h> //PIC utilizado
#fuses INTRC,NOWDT,NOPROTECT,PUT //Configuramos los fuses
#use delay (clock=4000000) //Oscilador a 4Mhz
#use fast_io(a) //Optimizamos E/S del PORTA
#use fast_io(b) //Optimizamos E/S del PORTB
#byte portb = 0x6 //Direccion del PORTB
//#define CCP_OFF //Desabilito comparadores
//------Prototipos de funciones-----
int leo_prog(void);
int leo_demora(void);
void prog1(int demora);
void prog2(int demora);
void prog3(int demora);
void prog4(int demora);
void salidas_off( void);
//------------------------------------------------------------------------------
//------Programa principal----------
//------------------------------------------------------------------------------
void main(void)
{
int programa = 0, demora = 10, tiempo = 10;
set_tris_a(0xFF); //Todo el puerto como entrada.
set_tris_b(0x00); //Todo el puerto como salida.
disable_interrupts(GLOBAL); //todas las interrupciones desactivadas
//Comienzo el bucle infinito.
do{
programa = leo_prog(); //Guardo en programa el numero de prog. selecc.
demora = leo_demora(); //Guardo en demora el tiempo de demora elegido (en segundos)
//----ejecuto el programa elegido---
if (programa == 0) prog1(demora);
if (programa == 1) prog2(demora);
if (programa == 2) prog3(demora);
if (programa == 3) prog4(demora);
}while(TRUE); //Repito el bucle
}
//------------------------------------------------------------------------------
//Funcion leo_prog. Lee el estado de los switchs
// 1 y 2 (PIN_A0 y PIN_A1)
int leo_prog(void) {
int programa_aux=0;
if (PIN_A1==1) programa_aux = programa_aux++;
if (PIN_A0==1) programa_aux = programa_aux+2;
return programa_aux;
}
//Funcion leo_demora. Lee el estado de los switchs
// 3 y 4 (PIN_A2 y PIN_A3)
int leo_demora(void) {
int demora_aux=0;
int tiempo;
if (PIN_A3==1) demora_aux = demora_aux++;
if (PIN_A2==1) demora_aux = demora_aux+2;
switch (demora_aux) {
case 0: tiempo = 1;
break;
case 1: tiempo = 3;
break;
case 2: tiempo = 6;
break;
case 3: tiempo = 12;
break; }
return tiempo;
}
//Funcion Prog1. Ejecuta el programa numero 1 con la
//demora que recive como parametro.
void prog1(int demora) {
portb = 0x01;
delay_ms(demora);
portb = 0x02;
delay_ms(demora);
portb = 0x04;
delay_ms(demora);
portb = 0x08;
delay_ms(demora);
portb = 0x10;
delay_ms(demora);
portb = 0x20;
delay_ms(demora);
portb = 0x40;
delay_ms(demora);
portb = 0x80;
delay_ms(demora);
}
//Funcion Prog2. Ejecuta el programa numero 2 con la
//demora que recive como parametro.
void prog2(int demora) {
portb = 0x03;
delay_ms(demora);
portb = 0x0C;
delay_ms(demora);
portb = 0x30;
delay_ms(demora);
portb = 0xC0;
}
//Funcion Prog3. Ejecuta el programa numero 3 con la
//demora que recive como parametro.
void prog3(int demora) {
portb = 0x81;
delay_ms(demora);
portb = 0x03;
delay_ms(demora);
portb = 0x06;
delay_ms(demora);
portb = 0x0C;
delay_ms(demora);
portb = 0x18;
delay_ms(demora);
portb = 0x30;
delay_ms(demora);
portb = 0x60;
delay_ms(demora);
}
//Funcion Prog4. Ejecuta el programa numero 4 con la
//demora que recive como parametro.
void prog4(int demora) {
portb = 0x0F;
delay_ms(demora);
portb = 0xF0;
}
//Funcion salidas_off. Apaga todas las luces.
void salidas_off(void) {
portb = 0x00;
}
-
Hola Ariel. y bienvenido al bando de los que usamos el C :mrgreen:
me parece que hay un error cuando intentas poreguntar por RA[0,1]
if (PIN_A1==1) programa_aux = programa_aux++;
if (PIN_A0==1) programa_aux = programa_aux+2;
deberia ser:
if (input(PIN_A1)) programa_aux = programa_aux++;
if (input(PIN_A0)) programa_aux = programa_aux+2;
-
Hola Ariel.
No se mucho de CCS yo, pero para leer el estado de un PIN se usa bit_test(pin aquí) me parece...
O ahí pedro te lanzó otra posibilidad.
-
Esto no furula:
if (PIN_A1==1)
PIN_A1 es una constante,así que ese if siempre hará lo mismo.Lo mismo pasa con el siguiente:
if (PIN_A0==1)
La forma de hacerlo sería:
if input(PIN_A1)....
Voy a seguir mirando
-
Os adelantanteis pendejos!!!! jajaaj
-
jaja es que las preguntas facilongas tientan a muchoss...aznos! :D :D(entiendase el sarcásmo de la "z" en lugar de la "s")
-
Cuando haces (PIN_A1 == 1) siempre es true porque pin_XX son constantes que define CCS para utilizar en sus funciones.
Para leer un Pi debes usar INPUT(PIN) como indico en la imagen.
(http://img160.imageshack.us/img160/503/dibujo1yk4.th.png) (http://img160.imageshack.us/my.php?image=dibujo1yk4.png)
A ver si hay suerte!!
Un saludo
gONzAO
-
Anda Ariel,para que te quejes.Respuesta por triplicado,por si con una o con dos no tequeda claro jaaj
-
Que digo triplicado....cuadriplicado!!
-
Guauu, que velocidad, jaja, yo estaba dándole al arteYcreación con el paint y casi sale mi mensaje en la segunda hoja,
jajaj
Taluegoo
-
Hola Ariel.
No se mucho de CCS yo, pero para leer el estado de un PIN se usa bit_test(pin aquí) me parece...
O ahí pedro te lanzó otra posibilidad.
también es válido usar el bit_test(portx, pin_del_puerto)
-
Sisisi. Eso, eso, eso Pedrito! :D :D gracias por la correccion.!
-
[grenli mode]
:mrgreen:
[/grenli mode]
-
IMPRESIONANTE VELOCIDAD DE RESPUESTA!!!!!!! :shock: :shock:
Gracias a todos.
Cambie a
if (input(PIN_A1==1)) programa_aux = programa_aux++;
if (input(PIN_A0==1)) programa_aux = programa_aux+2;
Pero el resultadoes el mismo....
QUE TARADO! Acabo de ver los ==1, que me quedaron de gusto.
Y funciona de maravillas! ¿Quien dijo que el C era complicado?
Realmente...es maravilloso esto de las funciones. Lo escribi super rapido. En el BASIC que usaba no tenia funciones, asi que era bastante mas rebuscado todo.
Gracias por la ayuda y la bienvenida! :)
-
Otra mas, y no molesto mas!
Esto funcionara? Deberia hacer una pause de "demora" segundos:
//Funcion pausa_seg. Hace una pausa de un segundo.
//demora que recibe como parametro.
void pausa_seg(int demora) {
int i;
for (i=0; i<=demora; i++) {
delay_ms(1000); }
}
(es que el for-next escrito asi me da escalofrios todavia... :D)
-
Me autorespondo: Si, anda 10 puntos :-/ :-/
-
Otra mas, y no molesto mas!
Esto funcionara? Deberia hacer una pause de "demora" segundos:
//Funcion pausa_seg. Hace una pausa de un segundo.
//demora que recibe como parametro.
void pausa_seg(int demora) {
int i;
for (i=0; i<=demora; i++) {
delay_ms(1000); }
}
(es que el for-next escrito asi me da escalofrios todavia... :D)
Sacale el =.
Deberia funcionar.
Saludos.
-
Claro, el = hace que sea "demora+1", no? :?
-
Yes! :D O le sacas el igual, o inicializas i=1.
-
IMPRESIONANTE VELOCIDAD DE RESPUESTA!!!!!!! :shock: :shock:
Gracias a todos.
Cambie a
if (input(PIN_A1==1)) programa_aux = programa_aux++;
if (input(PIN_A0==1)) programa_aux = programa_aux+2;
Pero el resultadoes el mismo....
QUE TARADO! Acabo de ver los ==1, que me quedaron de gusto.
...
si se pueden poner los =1 y sería así:
if (input(PIN_A1)==1)...
aunque sería redundar, porque en C se asume true cuando preguntas por el resultado de una función booleana, el caso contrario
if (input(PIN_A1)==0) = if(!input(PIN_A1))
en ccs true=1 y false=0
PD: hay que poner un cronómetro para saber en cuanto tiempo respondemos cada uno :D
-
Espectacular. ¿Estare en condiciones para el 2/10? :mrgreen:
-
Gracias Pedro!
Sabia lo de que se asume true. E incluso puedo evitarme los "void" al declarar las funciones, pero los dejo por que el codigo queda igual de largo, y a mi me resulta mas claro si a esas cosas las "veo" escritas. :)
-
Te felicito Ariel, en tan corto tiempo y venido del Basic, la forma elegante y ordenada en que programas. :-/
Este es uno de los bastiones del C, la elegancia de la programacion.
El otro se aprende con el tiempo, y es aprender a realizar funciones y librerias reusables en muchos proyectos... :D
-
Gracias master!
Es que la prolijidad es imprescindible si prentendes entender el codigo años mas tarde.
Me gusta MUCHO el C. Ese que pase fue mi primer programita, y es obvio que se debe poder hacer mas corto o de otra manera, pero me gusto que salvo el problema con la lectura de pines que originó este hilo, funciono de una! :)
Saludos.
-
... y es obvio que se debe poder hacer mas corto o de otra manera...
Diste en el clavo Ariel. El primer paso es lograr hacer funcionar el programa. El segundo paso optimizarlo.
-
Pues a mí me gusta más hacerlo así:
#byte PORTB=0xF81
#bit TeclaTest = PORTB.2
if (TeclaTest)
... tecla pulsada
-
Hola Manolo!
Es una buena idea, queda mucho mas claro.
En Basic yo usaba algo asi (que se parece mucho a lo que propones):
Symbol teclatest = PORTB.2
if teclatest then
... tecla pulsada
Asi que no me va a costar adaptarme a esa manera de programar. :)
Saludos!
-
Hola!
Tengo otro problema con una funcion, asi que he "resucitado" este hilo.
La idea es la siguiente: Tengo un pulsador en A0, que se pone a +V al presionarlo. Cuando esto ocurre, el programa salta a una funcion que se encarga de contar de 1 a 6 repetidamente hasta que se suelte el pulsador. Cuando esto ocurre, se muestra un valor en el PORTB, y se regresa al programa principal.
Sin embargo, he colocado algunas"señales" en el codigo para seguirle el rasto a medida que se ejecuta, y si bien salto a la funcion al presionar el pulsador, nunca entra dentro del bucle "do....while" que hay dentro de ésta.
Por supuesto, se trata de un circuito que simula un dado.El codigo esta bien comentado, y es sencillo:
#include <16f627a.h> //PIC utilizado
#fuses XT,NOWDT,NOPROTECT,PUT //Configuramos los fuses
#use delay (clock=4000000) //Oscilador a 4Mhz
#use fast_io(b) //Optimizamos E/S del PORTB
#BYTE PORTB = 0x06 //El PORTB está en 0x06
//Variables globales--------------------------------------------------
//La tabla dado tiene el valor del PORTB para cada numero posible.
int dado [6]={0x01,0x08,0x09,0x0A,0x0B,0x07};
//Prototipo de funciones ---------------------------------------------
void lanzo_dado(void);
//------Programa principal--------------------------------------------
void main(void)
{
set_tris_a(0xFF); //configuro el PORTA completo como entrada.
set_tris_b(0x00); //configuro el PORTB completo como salida.
disable_interrupts(GLOBAL); //todas las interrupciones desactivadas
do{ //bucle principal
//Apago los leds
PORTB = 0x80;
if(input(PIN_A0)){ //Si elpulsador esta en alto...
lanzo_dado(); //...lanzo el dado y muestro el resultado
}
}while(TRUE); //Repito el bucle.
}
//--------------------------------------------------------------------
//Esta funcion lanza el dado y muestra el resultado
//--------------------------------------------------------------------
void lanzo_dado(void) {
char i=0; //i contendrá el valor del dado en cada momento.
do{ //bucle principal
i++; //Sumo 1 a i
PORTB = 0x40;
if (i == 7) { //Si pasa de 6...
i = 1; //...empiezo de 1 otra vez.
}
}while(PIN_A0); //Repito el bucle hasta que se suelte el pulsador.
PORTB = 0x20;
//Ahora, muestro el valor de "i" en los LEDs:
PORTB = dado [i];
delay_ms(5); //Espero 5 segundos, y vuelvo al programa ppal.
}
-
Hola Arielito!
¿Y el antirebote?
O bien, cambiando la condicion while(PIN_A0) a while(bit_test(porta,0))
Saludos!
-
En el Do--While estas testeando mal la condicion.
PIN A0 es una constante con un valor determinado, no sirve como condicion, porque no es una variable.
Deberias comprobar asi:
do{ //bucle principal
i++; //Sumo 1 a i
PORTB = 0x40;
if (i == 7) { //Si pasa de 6...
i = 1; //...empiezo de 1 otra vez.
}
}while(input(PIN_A0)); //Repito el bucle hasta que se suelte el pulsador.
-
Elemental, querido Marcos!!!!!!!!
Gracias! :mrgreen:
-
Haz también lo que te dice Bruno de lo contrario los rebotes daran al trasto con el do-while
-
Haz también lo que te dice Bruno de lo contrario los rebotes daran al trasto con el do-while
Eso he hecho. En el PIC SIMULATOR IDE va de fiesta ;)
Gracias a todos! :)