Autor Tema: ayuda con mejora de programa  (Leído 5766 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado yair_xiox

  • PIC16
  • ***
  • Mensajes: 210
ayuda con mejora de programa
« en: 10 de Septiembre de 2015, 19:22:20 »
hola, voy a ponerl el codigo, estoy haciendo que unos leds se prendan cuando hay 0 y se apagen cuando hay uno pero eso no sirve sila entrada es una señal cuadrada que cambia constantemente de 1 0 o viceversa y necesito que me ayuden a cambiar la condicion del if por un while que pregunte por la entrada del pin 4 durante un tiempo si es cero o uno y dependiendo del valor que mas haya sido durante ese tiempo prenda los leds o los apague pero no se como hacerlo
Código: [Seleccionar]
#include <16f73.h>

#fuses XT,NOWDT,PUT, NOPROTECT


#use delay (clock =4000000)



#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use rs232(BAUD=9600, XMIT=PIN_C6, RCV=PIN_C7, BITS=8)

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>





unsigned char datos [16];
int j; 
void diagnostico (void)
{
datos [0]=0;
delay_us(0.4);
datos [1]=1;
delay_us(0.4);
datos [2]=0;
delay_us(0.4);
datos [3]=1;
delay_us(0.4);
datos [4]=0;
delay_us(0.4);
datos [5]=1;
delay_us(0.4);
datos [6]=0;
delay_us(0.4);
datos [7]=1;
delay_us(0.4);
datos [8]=0;
delay_us(0.4);
datos [9]=1;
delay_us(0.4);
datos [10]=1;
delay_us(0.4);
datos [11]=0;
delay_us(0.4);
datos [12]=1;
delay_us(0.4);
datos [13]=0;
delay_us(0.4);
datos [14]=1;
delay_us(0.4);
datos [15]=1;
delay_us(0.4);
for (j=0;j<15;j++ )
{
putc(datos[j]);
}
}

void main(){

set_tris_b(0x00);
set_tris_a(0x10);
set_tris_c(0x80);
setup_adc_ports(NO_ANALOGS);



 
output_high(PIN_A0);
 
while(true)
{
if(input(PIN_A4)==0)
{
output_high(PIN_B0);
output_high(PIN_B1);
output_high(PIN_B2);
output_high(PIN_B3);
}
else
{
output_low(PIN_B0);
output_low(PIN_B1);
output_low(PIN_B2);
output_low(PIN_B3);
}
diagnostico();

 
}
}


Desconectado RALF2

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2060
Re: ayuda con mejora de programa
« Respuesta #1 en: 10 de Septiembre de 2015, 20:11:55 »
Amigo yair_xiox, lo que preguntas ya lo habias hecho aqui:

http://www.todopic.com.ar/foros/index.php?topic=45102.0
Por politicas del foro no es conveniente que formules la misma pregunta varias veces, esa no es la mejor forma de pedir ayuda.
Tenias un problema con la version del compilador segun preguntabas y no haz dicho si lo resolvistes, por otro lado no entiendo bien que es lo que quieres hacer viendo tu programa. podrias ser mas especifico porque eso de poner un pin a cero o uno no me dice mucho.

Saludos

Desconectado yair_xiox

  • PIC16
  • ***
  • Mensajes: 210
Re: ayuda con mejora de programa
« Respuesta #2 en: 10 de Septiembre de 2015, 21:45:53 »
no estoy preguntando lo mismo, estoy pregntando como usar un while para preguntar por un pin si es uno o cero durante un tiempo y si es mas veces uno prenda los leds o si es cero mas veces los apague porque la entrada es una señal cuadrada

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: ayuda con mejora de programa
« Respuesta #3 en: 10 de Septiembre de 2015, 21:49:42 »
Podrias haber seguido seguido en el otro hilo, ya que es el mismo codigo.
Espero que no te enojes por lo que te digo y tus consultas seran siempre bien recibidas.

Como te dije estas teniendo serios problemas de programacion (en ASM y en C que son las cosas que vi), pero SERIOS, lei que estas intentando programar un robot con cinematica inversa, etc etc etc.

Pero por ahora lo que mas te vas a tener que enfocar es aprender C y como ejecutan las instrucciones de manera secuencial los microcontroladores, cosas como estas:

Código: [Seleccionar]
datos [0]=0;
delay_us(0.4);
datos [1]=1;
delay_us(0.4);
datos [2]=0;
delay_us(0.4);
datos [3]=1;
delay_us(0.4);
datos [4]=0;
delay_us(0.4);
datos [5]=1;
delay_us(0.4);
datos [6]=0;
delay_us(0.4);
datos [7]=1;
delay_us(0.4);
datos [8]=0;
delay_us(0.4);
datos [9]=1;
delay_us(0.4);
datos [10]=1;
delay_us(0.4);
datos [11]=0;
delay_us(0.4);
datos [12]=1;
delay_us(0.4);
datos [13]=0;
delay_us(0.4);
datos [14]=1;
delay_us(0.4);
datos [15]=1;
delay_us(0.4);

Son realmente absurdas, cuando la funcion delay_us admite nomas enteros y vos intentas pasarle un float.

Citar
Parameters: time - a variable 0-65535(int16) or a constant 0-65535

Ademas de que sirve asignarle un valor a una variable alojada en la RAM con delays entremedio ????, supongamos que acepta el delay ese valor. de que sirve asignarle una y otra ves el valor a ese array ???, se hubiera podido remplazar por:

unsigned char    datos   [16]={1,0,1,0,.....,1};
void diagnostico (void)
{
   int j;
   delay_us(6.4);
   for(j=0,j<16;j++)
...


Eso no va a hacer que se envie un 1 luego un 0 a cada 0.4us, solo estas haciendo que ponerle todos los valroes al array sea lento. (Ni es por que el delay es de 0).
Tampoco valdria la pena hacer eso por un 0 o un 1. utilizar 16 * 8 bits = 128 bits para solo tener la info de 16 bits.

Encima luego usas
for (j=0;j<15;j++ )
{
    putc(datos[j]);
}

Y tenes configurado el RS232. genial, esto es una funcion bloqueante que se queda esperando hasta que se envie todo.

Haciendo que tu if del main, tenga que esperar que se envie todo por la UART, para volver a preguntar sobre la entrada.

Otra cosa no estas enviando un 1 bit si esa fur tu idea. sino estas enviando:
1 bit de start + 8 bits de datos + 2 bits de stop, asincronamente asi que no es una onda cuadrada con un duty 50% si es lo que querias hacer.

Cada 1 o 0 ahi seria algo asi, como para darte un ejemplo
1 0000 0001 11


Otro "error", no estas usando el valor dato[15] xD por tu condicion.


Para resumirtelo, tu funcion diagnostico es igual a esto:

for (j=0;j<16;j++ )
{
   putc((j&0x01));
}

Encima no sale de ahi, de ese for hasta que envio todo de la UART.
Aunque no lo quieras admitir, estas errandole en temas de programacion bastante simples.
El manual de las funciones de CCS lo tenes en internet, solo busca CCS Manual y lo tenes. Ahi te explica cada una.
Pero el tema de los arrays, eso ya como dije es un error de programacion
« Última modificación: 10 de Septiembre de 2015, 21:54:10 por KILLERJC »

Desconectado yair_xiox

  • PIC16
  • ***
  • Mensajes: 210
Re: ayuda con mejora de programa
« Respuesta #4 en: 10 de Septiembre de 2015, 22:15:24 »
lo que pasa es que en esa señal es una cuadrada aleatoria y le pongo retardos para se demore un poco en cada dato y mande un float porque necesitaba 400 nanosegundos pero como no se puede los converti a 0.4 microsegundos o como hago para hacer 400 nanosegundos, killer entonces pongo esa parte que me pusiste y quito lo de la uart pero entonces porque pin puedo enviar esa señal

Desconectado yair_xiox

  • PIC16
  • ***
  • Mensajes: 210
Re: ayuda con mejora de programa
« Respuesta #5 en: 10 de Septiembre de 2015, 22:19:12 »
killer y si tengo una entrada que si sea una señal cuadrada que varia entre 0 y 1 y lo que necesito es que por el pin que entra hacer un while que dure un tiempo determinado preguntando si la señal esta en 1 o en cero y dependiendo de si se repite mas 1 o 0 en ese intervalo de tiempo prenda o apague los leds como hago eso

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: ayuda con mejora de programa
« Respuesta #6 en: 10 de Septiembre de 2015, 22:52:54 »
Citar
lo que pasa es que en esa señal es una cuadrada aleatoria y le pongo retardos para se demore un poco en cada dato y mande un float porque necesitaba 400 nanosegundos pero como no se puede los converti a 0.4 microsegundos o como hago para hacer 400 nanosegundos, killer entonces pongo esa parte que me pusiste y quito lo de la uart pero entonces porque pin puedo enviar esa señal

Me parece que no tenes en claro lo que es una onda cuadrada, o un tren de pulsos, sino estamos hablando de cosas distintas. Una onda cuadrada o un tren de pulsos no es aleatorio.

Siguiendo con esto:

con un cristal de 4Mhz la maxima velocidad que se ejecuta cada instruccion en ASM es de 1us en los PIC, es decir para cambiar aunque sea un bit, o X bits de un puerto te lleva 1us, ponerlo a 1 y luego a 0, son 2 us.

Tcy = 4/Fosc = 4 / 4Mhz = 1us

Asi que es IMPOSIBLE que tengas 0.4us
Con lo que si hicieras un programa en ASM con un codigo ineficiente (ya que no podrias introducir saltos) te ocuparia al menos un cristal de 10Mhz ( como minimo ). Aun asi no podrias hacer nada mas.
Hacerlo en C es imposible, ya que C usa mas instrucciones de las que necesitaria, y no tenes un control sobre las isntrucciones que se crean.

Citar
killer y si tengo una entrada que si sea una señal cuadrada que varia entre 0 y 1 y lo que necesito es que por el pin que entra hacer un while que dure un tiempo determinado preguntando si la señal esta en 1 o en cero y dependiendo de si se repite mas 1 o 0 en ese intervalo de tiempo prenda o apague los leds como hago eso

Esto es lo mas simple.. Pero tambien todo depende de la velocidad de entrada. tenes que recordar que C agrega mas instrucciones y por lo tanto estas limitado a la onda cuadrada que llegue.
Si usas FAST_IO al igual que tu programa entonces:

Código: C
  1. while(true)
  2.         {
  3.                 if(input(PIN_A4)) output_b(0x00);     // Si te interesa mantener los demas valores de los demas bits del portb , vas a tener que leer el valor , hacerle una and/or y usar eso en el output_b()
  4.                 else output_b(0x0F);                            
  5.         }

Si tuviera que resumir eso en ASM seria:

Código: ASM
  1. CLRF PORTB
  2.     MOVLW 0x0F
  3. loop:
  4.     BTFSC PORTA,4
  5.     GOTO parte2
  6.     MOVWF PORTB
  7.     GOTO loop
  8. parte2:
  9.     CLRF PORTB
  10.     GOTO loop

Creo que seria lo minimo, lo cual son 5 ciclos de instrucciones para cuando es 0, y 6 para cuando es 1.
Asi que la frecuencia maxima de tu onda cuadrada de entrada con ese codigo en ASM es de unos (1/(6us+6us)) 80Khz a 4Mhz.
Si es con C, entonce por las dudas pasalo a 50Khz, y te va permitir detectar cada medio ciclo. aunque de seguro que por ahi se va a saltar uno.
« Última modificación: 11 de Septiembre de 2015, 05:58:35 por KILLERJC »

Desconectado yair_xiox

  • PIC16
  • ***
  • Mensajes: 210
Re: ayuda con mejora de programa
« Respuesta #7 en: 14 de Septiembre de 2015, 12:34:02 »
hola,amigos aun no funciona la señal que yo genero es una señal aleatoria para darle una señal de entrada a un MBI 5039, que es un integrado que maneja una matriz de leds y la salida del MBI es una señal cuadrada que al entrar por a4 siempre prende los leds aunque esten fallando algunos leds de la matriz o prendan todos los leds de la matriz, lo que necesito es detectar con los leds de mi circuito el cambio de los leds de la matriz que prendan cuando falle y apaguen cuando la matriz de leds este funcionando ayuda, no me funciona

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: ayuda con mejora de programa
« Respuesta #8 en: 14 de Septiembre de 2015, 15:35:12 »
Hasta que por fin nos decis que queres hacer o conectar.

Leiste el datasheet del MBI5039 para ver las formas de ondas ?

Lo que vas a necesitar usar un SPI y luego cambiar a manejarlo digital, o hacer un SPI por software. (para no complicarla mucho te recomiendo esta ultima opcion)

Tenes 2 opciones para detectar los errores ( short-circuit / open-circuit ) O usas el In-message ( es decir mientras metes los datos, tenes una salida con los errores) , o se desactiva de la configuracion y luego se pide exclusivamente los errores sin enviar datos.
Todo depende de la cantidad de MBI5039 que tengas, y si quisieras realmente hacerte una libreria creo que prefiero hacerme una con la opcion de In-message desactivado, ya que esta puede ser utilizada tanto para tener 1 o mas MBI5039

Asi que para comenzar habria que hacer unas cuantas funciones, yo po ejemplo te doy estos nombres, vos usas el que quiera ya que no importa que nombre tengan

void vEnviarDatosMBI();
void vEnviarConfigMBI();
int iDetScMBI();
int iDetOcMBI();
short int iDetTempMBI(); (esta es opcional)
void vInitMBI();

Creo que con esas funciones ya estaria.., Ahora necesitamos saber los pines a usar

4 Salidas y una entrada:

Salidas Para: OE , LE , SDI , CLK
Entrada para : SDO

Para enviar los datos debes poner la salida SDI en alto o en bajo y dar un pulso en CLK, es decir pones el valor 0 o 1 en la salida , luego pones en 1 CLK y luego a 0, seguis asi para los 15 valores restantes, cuando termina todo esto, teniendo CLK en 0, pones en 1 LE y luego lo pones en 0.

Para detectar error de Short-Circuit ( Cortocircuito ): Pones en 1 OE, Pones en 1 LE, pones a 1 y luego en 0 a CLK, pones en 0 LE, Pones en 0 OE (respetar el tiempo) , Envias 15 pulsos de CLK ( cuando hablo de pulsos es ponerlo en 1 y luego en 0 ) cada ves que lo pones en 1 lees la entrada, ahi vas a tener los 16 bits de error.

Lo mismo para el de Open-Ciurcuit, nomas que cuando pones en 1 LE tenes que darle 2 ciclos de CLK.
Lo mismo para la temperatura, nomas que son 3 ciclos con el LE, en esta no importa el estado de OE. Asi que lo podes dejar en 0.

Te queda la de configurar los registros internos, este es igual que el de enviar datos, pero cuando se pone el LE en 1, debe haber 4 ciclos de clock, y luego se pone a 0.

Y Finalmente una funcion de inicializacion, que es la que se encarga que al momento de encenderse el circuito configure los pines de ser necesario y escriba en los registros de configuracion los valores para que responda como vos queres, ejemplo el de desactivar el in-message, ganancia de correinte etc.

Creo que separados asi en funciones como te los di no es TAN complejo, lo unico que vas a tener que respetar los tiempos.

Desconectado yair_xiox

  • PIC16
  • ***
  • Mensajes: 210
Re: ayuda con mejora de programa
« Respuesta #9 en: 14 de Septiembre de 2015, 16:52:24 »
gracias killer, tengo 4 MBI 5039 tres de ellos controlan cada uno 16 leds y el ultimo solo 8 leds, me explicas un poco mejor eso de respetar los tiempos y porque dices que SDO es entrada ahi dice que ese es el de salida y se ve la señal de error por ese pin pero hasta ahora yo no he notado la diferencia de esa señal cuando toda la matriz de leds funciona
y cuando algunos leds ya no funcionan la señal sigue igual, y entonces para mejorar el programa me puedes ayudar con la iniciacion de esas funciones,y como es eso de darle masd e un ciclo al CLK
Código: [Seleccionar]
#include <16f73.h>

#fuses XT,NOWDT,PUT, NOPROTECT


#use delay (clock =4000000)



#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use rs232(BAUD=9600, XMIT=PIN_C6, RCV=PIN_C7, BITS=8)

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>





unsigned char datos [16]={0,1,0,1,0,1,0,1,0,1,1,0,1,0,1,1};
 
void diagnostico (void)
{
int j;
delay_us(1);
for (j=0;j<16;j++ )
{
putc(datos[j]);
}
}

void main(){

set_tris_b(0x00);
set_tris_a(0x10);
set_tris_c(0x80);
setup_adc_ports(NO_ANALOGS);



 
output_high(PIN_A0);
 
while(true)
{

if(input(PIN_A4)==0)
{
output_high(PIN_B0);
output_high(PIN_B1);
output_high(PIN_B2);
output_high(PIN_B3);
}
else
{
output_low(PIN_B0);
output_low(PIN_B1);
output_low(PIN_B2);
output_low(PIN_B3);
}
diagnostico();

 
}
}

y como es eso del spi por software

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: ayuda con mejora de programa
« Respuesta #10 en: 14 de Septiembre de 2015, 17:40:44 »
Citar
porque dices que SDO es entrada ahi dice que ese es el de salida

SDO Salida del MBI5039, pero es una entrada para tu PIC

Citar
y se ve la señal de error por ese pin pero hasta ahora yo no he notado la diferencia de esa señal cuando toda la matriz de leds funciona

No se como tenes configurado tu integrado. normalmente por default viene con la opcion "in-message" activado. De ultima podes usar esto y el SPI. Lo que pasa la complicacion a la configuracion del SPI

Configura el SPI a la velocidad que quieras.
Envias los 16*4 bits, cada ves que envias 8 bits recibis 8bits de los errores, comenzarias recibiendo el error 15 del ultimo MBI de la cadena.
Tenes que tener en cuenta de poner a 0 y luego a 1 el OE de todos los integrados para que sea correcto los valores de la deteccion de error.
Fin. xD

Citar
y como es eso de darle masd e un ciclo al CLK
https://www.rcscomponents.kiev.ua/datasheets/mbi5039gf.pdf
Pagina 13

Citar
entonces para mejorar el programa me puedes ayudar con la iniciacion de esas funciones

Con un SPI por HW para escribir y leer los datos de errores seria algo asi, si no mal recuerdo como hacerlo:

Código: C
  1. int Datos[4];
  2. int Errores[4];
  3.  
  4. void vEnviarDatos(short int *ptr_datos,short int *ptr_error)
  5. {
  6.         short int i;
  7.  
  8.         // Muevo OE por un minimo de 400ns , no necesita de demora a que esto como minimo es de 1us con 4Mhz
  9.         OEaCero();
  10.         OEaUno();
  11.  
  12.         //Envio y recibo datos
  13.         for(i=0;i<8;i++)
  14.                 *ptr_error++ = spi_read(*ptr_datos++);
  15.  
  16.         //Muevo el LE para que se latchee los datos
  17.         LEaUno();
  18.         LEaCero();
  19. }
  20.  
  21. void main()
  22. {
  23.         vEnviarDatos(Datos,Errores);
  24. }

Por SW

Código: C
  1. void vEnviarDatos(short int *ptr_datos,short int *ptr_error)
  2. {
  3.         short int j,i,;
  4.  
  5.         OEaCero();
  6.         OEaUno();
  7.  
  8.         for(j=0;j<8;j++ , ptr_error++,ptr_dato++)
  9.         {
  10.                 for(i=0;i<8;i++)
  11.  
  12.  
  13.                         if(*ptr_dato & (1<<i))
  14.                         {
  15.                                 SalidaUno();
  16.                         }
  17.                         else
  18.                         {
  19.                                 SalidaCero();
  20.                         }
  21.                         *ptr_error |= (input(PIN_SDO) << i)
  22.                         CLKUno();
  23.                         CLKCero();
  24.                        
  25.         }
  26.  
  27.         LEaUno();
  28.         LEaCero();
  29. }

Los indices de ambos codigos pueden estar MUY mal (estoy seguro que estan mal), asi que recomiendo revisarlos pero como ves no se te pide nada complejo. si no te gustan los punteros lo haces directamente con los arrays.

Desconectado yair_xiox

  • PIC16
  • ***
  • Mensajes: 210
Re: ayuda con mejora de programa
« Respuesta #11 en: 14 de Septiembre de 2015, 17:56:42 »
gracias, pero entonces para hacer ese cambio en le y oe los pongo en algun pin del micro pero, hay una señal que debo enviar por el pin CLK asi que no se como hacerle ese cambio de 1 a 0 al CLK

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: ayuda con mejora de programa
« Respuesta #12 en: 14 de Septiembre de 2015, 18:05:42 »
gracias, pero entonces para hacer ese cambio en le y oe los pongo en algun pin del micro pero, hay una señal que debo enviar por el pin CLK asi que no se como hacerle ese cambio de 1 a 0 al CLK

por SW, tenes que ponerlo a 0 o a 1, con un output(PIN_XX)
por HW, el mismo hardware del SPI se encarga de generar el CLK.

Desconectado yair_xiox

  • PIC16
  • ***
  • Mensajes: 210
Re: ayuda con mejora de programa
« Respuesta #13 en: 14 de Septiembre de 2015, 18:24:58 »
ok, entonces la señal que yo genero la envio mas bien por el pin SDI

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: ayuda con mejora de programa
« Respuesta #14 en: 14 de Septiembre de 2015, 18:31:31 »
Tenes que generar 2 señales, 1 de CLK y otra de datos ( que iria al SDI)

Si, si lo haces por SW, cualquier pin del PIC hace la funcion de una salida serial para tus datos, y eso iria al SDI del MBI. Tambien cualquier haria de CLK para que entre en el CLK del MBI
Si lo haces por HW, tenes que fijarte cual es la salida del SPI y conectar eso al SDI del MBI, y tambien la salida del ultimo MBI a la entrada del SPI.
« Última modificación: 14 de Septiembre de 2015, 18:44:22 por KILLERJC »


 

anything