Mensajes recientes

Páginas: [1] 2 3 4 5 6 7 8 9 10
1
Lenguaje C para microcontroladores PIC / Re:I2C con XC8: Pin SCL como salida?
« Último mensaje por Loudness en 18 de Junio de 2018, 23:02:01 »
Hola de nuevo.

Os cuento que he tenido acceso (por fin!!) a un PIC16F877A y he podido probar el I2C.
He modificado un poco el programa que colgue anteriormente para que despues de escribir un numero en la memoria, lo lea de nuevo, saque el dato por el LCD y aumente el numero para empezar de nuevo.

Y parece que funciona :-/

Ahora solo queda adaptarlo y probarlo para un pic de la serie 16f1, pero eso me llevara mas tiempo asi que de momento pongo el tema como solucionado.

Muchas gracias a todos, en especial a KILLERJC, por su ayuda.

Cuelgo el programa por si le sirve de guia a alguien.

 - Tienes que ingresar para ver archivos adjuntos -

2
* PROYECTOS * / Re:Botones de Inicio, Pausa y Reset en Cronometro con Pic16F877A
« Último mensaje por KILLERJC en 18 de Junio de 2018, 21:04:20 »
Hacerlo con delays es malo, seguramente le erre en tiempo y por mucho. Pero para comenzar no veo mal la idea. Tu programa lo deberias dividir en varias partes que poco a poco podes ir mejorando.. Necesitas:

- Leer los pulsadores y actuar en consecuencia.
- Aumentar el tiempo acumulado en caso de ser necesario
- Mostrar los datos en un display.

Entonces vamos a tener un main algo asi:

Código: C
  1. void main(void)
  2. {
  3.   //Configuracion de pines
  4.  
  5.   while(1)
  6.   {
  7.     LecturaDeSensores();
  8.     if(RelojCorriendo == 1)
  9.     {
  10.         AumentarReloj();
  11.     }
  12.     MostrarEnDisplay();
  13.     Delay_ms(10);
  14.   }
  15. }

Algunas cosa a tener en cuenta al diseñar esto... la idea es que ninguna de esas funciones ocupe demasiado tiempo, sino que lo mas consumidor en todas las instrucciones que puede tener dentro del while sea el delay en este ejemplo. Esto te va a llevar a pensar de otra forma.
Ejemplo, como incremento mis numeros.
Yo se que pasaron 10ms (aproximado) desde que entro la anterior ves, gracias a mi delay de 10ms. Entonces podria aumentar mi decima de milisegundo cada ves que entra.. Supongamos que tenemos estas variables: ( MM:SS:mm

Milisegundo
DecimaMilisegundo
Segundo
DecimaSegundo
Minuto
DecimaMinuto

Entonces al entrar haria:

Código: C
  1. Milisegundo++;
  2. if(Milisegundo>9)
  3. {
  4.   Milisegundo = 0;
  5.   DecimaMilisegundo ++;
  6. }
  7. if(DecimaMilisegundo>9)
  8. {
  9.   DecimaMilisegundo = 0;
  10.   Segundo ++;
  11. }
  12. // etc...

Es decir incremento mi decima y luego corrijo.

Pero.... que pasa con mostrar en el display...
Algo tentador seria hacer esto:

Código: C
  1. void MostrarDisplay(void)
  2. {
  3.       //Muestro Display1
  4.       //delay
  5.       //Muestro Display2
  6.       //delay
  7. }

Pero estariamos agregando delays, y eso afecta a nuestra base de tiempo conocida, que son esos 10ms!!!!!. NO sirve.. vamos a necesitar otra forma que muestre 1 numero y luego salga, pero la proxima ves que entre muestre el numero que le sigue! Para esto lo mejor son los arrays y tener una variable para indicar cual es el que debemos encender.

Todas tus funciones d1,d2,d3, etc se van a simplificar. Y por ahora vamos a usar un switch case, pero podrias tranquilamente tambien usar un array para guardar tus numeros, luego pongo un codigo mas simple.

Código: C
  1. unsigned char ComunPuerto[] = {0b1,0b10,0b100,0b1000,0b10000};
  2. unsigned char numeroDeDigito = 0;
  3.  
  4. void Mostrar_Display(void)
  5. {
  6.   switch(numeroDeDigito)
  7.   {
  8.   case 0:
  9.     PORTC = numero[Milisegundo];
  10.     break;
  11.   case 1:
  12.     PORTC = numero[DecimaMilisegundo];
  13.     break;
  14.   case 2:
  15.     PORTC = numero[Segundo];
  16.     break;
  17.   case 3:
  18.     // seguir rellenenado
  19.   }
  20.   PORTD = ComunPuerto[numeroDeDigito];
  21.   numeroDeDigito++;
  22.   if(numeroDeDigito > sizeof ComunPuerto) numeroDeDigito = 0;
  23. }


Como ves mostramos mucho mas rapido con un array.. que pasaria si crearamos OTRO array para almacenar los numeros a mostrar. Ejemplo:

short numero[]={192,249,164,176,153,146,130,248,128,144};
unsigned char ComunPuerto[] = {0b1,0b10,0b100,0b1000,0b10000,0b100000};
unsigned char NumerosMostrar[] = {1,2,4,8,9,7};      // 12 minutos, 48 segundos, 97 milesimas
unsigned char numeroDeDigito = 0;

Mi funcion de mostrar ahora seria asi:

Código: C
  1. void Mostrar_Display(void)
  2. {
  3.   PORTC = numero[NumerosMostrar[numeroDeDigito]];
  4.   PORTD = ComunPuerto[numeroDeDigito];
  5.   numeroDeDigito++;
  6.   if(numeroDeDigito > sizeof ComunPuerto) numeroDeDigito = 0;
  7. }

Se simplifico bastante no?
Respecto a los sensores, es leer el pin, y si esta activo, podrias por ejemplo cambiar una variable RelojCorriendo, entre 0 y 1, de esa forma podes "parar" (haces que no auemnte la cuenta) el reloj. Y si activa el sensor de reset, procedes a poner a 0 en cada posicion el array NumerosMostrar. Por supuesto, esto va a entrar cada 10ms, por lo que vas a tener que tener en cuenta que si el sensor se mantiene activo por mas de 10ms, no le hagas caso, podes esperar que se suelte por ejemplo. Esta parte te la dejo a vos, venis con una solucion y luego le damos otra vuelta de tuerca.
3
Hola benito, por lo que veo no comprendes como es que funciona una interrupcion. Asi que mejor en ves de complicarnos por ahora sobre como hacer un PWM variable, presiento que es mejor explicar como es que funciona una interrupcion, y como es que debe programarse.


Tu micro, comienza a ejecutar instruccion es en el vector de reset, el vector de reset es el punto de memoria a la que va el micro al momento de producirse un reset, la vuelta de tension, etc.
De alli hace un par de cosas internas para comenzar a manejar el lenguaje C y se llama a la funcion main. Nosotros ponemos un loop infinito alli. Es decir nunca saldria de alli ( por mas que se llame a una funcion volveria al loop infinito) si la ejecucion fuera normal.
Y aqui es donde entra la interrupcion.

Voy a usar una imagen para que se entienda mejor.


La interrupcion ocurre por hardware, y al producirse el micro guarda donde estaba (la instruccion que le tocaba ejecutar) y salta a la posiciion de memoria que maneja las interrupcion, en tu caso pensalo como si fuera la funcion de interrupcion. Ejecuta la funcion esa, y vuelve a donde dejo.
En la imagen podes ver las 2 funciones, el main a la izquierda y la interrupcion a la derecha, cuando se produce la interrupcion el micro guarda la posicion de memoria de la instruccion numero 5 del main. Y se va a ejecutar la interrupcion, cuando sale vuelve donde habia quedado. Y asi continua.

Si uno lo viera "rapidamente" Podria pensar que esas 2 funciones estan ejecutandose de forma "paralela", es decir al mismo tiempo. Pero lo mas importante ahora, es que NUNCA pero NUNCA desde el main, se llama a la funcion de interrupcion como vos estas haciendo, sino que el mismo Timer es quien le avisa al CPU del microcontrolador y este es quien manda a ejecutar esa funcion.

Supongamos que queremos hacer titilar un led con una interrupcion:



Código: C
  1. void TIMER_0(void){
  2.   set_timer0(0);           //Le puse 0 , pero podria ser cualquier numero
  3.   output_toggle(PIN_B0);
  4. }
  5. void main(void){
  6.  
  7.    // Configuracion del timer
  8.    // Activo interrupcion del timer
  9.  
  10.    while(true){
  11.    }                          
  12. }

Como observas, en el main, nuestro micro se pasaria haciendo nada, encerrado en ese while, pero que gracias a la interrupcion sale de alli y ejecuta el toggle, luego vuelve al main.
Pienso que primero deberias comenzar con esto asi.. Luego haces un PWM como lo tenes realizado

Código: C
  1.    int cont;                     //Variable de Contador
  2.    int pwm0;
  3.  
  4. #int_timer0
  5. void TIMER_0(void){       //PWM0
  6.    set_timer0(200);              //Seteo de interrupcion
  7.    if(cont>50)                   //Si cont 50 se inicializa
  8.       cont=0;                    //Cont = 0
  9.    else                          //Caso contrario
  10.       cont++;                    //Incrementa en una unidad cont
  11.    if(cont>0&&cont<pwm0)         //Si 0<Cont<PWM0
  12.       output_high(PIN_a0);       //Salida PWM0 a nivel alto
  13.    else                          //Caso contrario
  14.       output_low(PIN_a0);        //Salida PWM0 a nivel bajo
  15. }

Un par de cambios y otros que no hice pero que deberias.
- Usa las llaves { } en los if y else
- el set_timer siempre al comienzo
- la funcion de interrupcion al uno no deber llamarla, no se le puede pasar valores, por lo tanto sus parametros son void.
- El int cont, deberia ser global, sino donde esta declarado apenas termina la funcion TIMER_0 procede a borrarse, y crearse de nuevo cuando entre. Entonces nunca llegaria a 50.
- Declare otra variable global llamada pwm0, en tu main ahora vas a modificar esa variable en ves de "llamar" a la funcion de interrupcion.


Código: C
  1. void main(){                     //Funcion principal
  2.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);  
  3.    set_timer0(200);
  4.    enable_interrupts(INT_TIMER0);            
  5.    enable_interrupts(GLOBAL);                      
  6.    while(true){
  7.       int b;
  8.       for(b=0;b<50;b++){
  9.       pwm0 = b;
  10.       delay_ms(50);
  11.       }
  12.       for(b=50;b>1;b--){
  13.       pwm0 = b;
  14.       delay_ms(50);
  15.    }                          
  16. }
  17. }
4
Todo en microcontroladores PIC / Re:makefile error
« Último mensaje por KILLERJC en 18 de Junio de 2018, 14:01:02 »
Ese es el error de que ya no puede seguir, no sirve de nada, seguramente el error se encuentra mas arriba, si es posible pasa el texto completo que da la salida de compilacion.
5
* PROYECTOS * / Botones de Inicio, Pausa y Reset en Cronometro con Pic16F877A
« Último mensaje por JM89 en 18 de Junio de 2018, 10:26:18 »
Buen dia Compañeros,

Reciban un cordial saludo desde Colombia

Estoy iniciando en el mundo de los pic y hace rato estoy en el trabajo de realizar un cronometro de seis digitos (Min, Seg y Dec-Seg), con un Pic16F877A, ya pude desarrollar la idea pero estoy estancado en el control del cronometro ya que desde el momento de que recibe energia este empieza el conteo, y lo que necesito es poder iniciarlo con un sensor qrd1114 y detenerlo con otro qrd1114 y poderle dar reset para que inicie otra vez en 0's.

Adjunto el codigo, lo estoy desarrollando en en MikroC Pro for PIC 2013

Puertos C y D estan como salidas para los 7 Segmentos

Les Agradeceré eternamente su ayuda.


#define datos PORTC
void d1 ()   {
portd=0b00000001;
           }
           
void d2 ()   {
portd=0b00000010;
           }
           
           void d3 ()   {
portd=0b00000100;
           }
               void d4 ()   {
portd=0b00001000;
           }
                 void d5 ()   {
portd=0b00010000;
           }
           void d6 ()   {
portd=0b00100000;
           }

short numero[]={192,249,164,176,153,146,130,248,128,144
};
int i,minuto,minuto1,segundo,segundo1,milisegundo,milisegundo1;


void main() {



adcon1=6;

TRISC=0;
TRISD=0;


PORTC=0;
PORTD=0;


while(1)  {






for(minuto1=0;minuto1<=5;minuto1++){
for(minuto=0;minuto<=9;minuto++){

for(segundo1=0;segundo1<=5;segundo1++){
for(segundo=0;segundo<=9;segundo++){

for(milisegundo1=0;milisegundo1<=9;milisegundo1++){
for(milisegundo=0;milisegundo<=9;milisegundo++){


if(minuto1==5 & minuto==9){
minuto=0;
minuto1=0;
}
for(i=0;i<1;i++) {

d6();
datos=numero[milisegundo];
delay_ms(1);
d5();
datos=numero[milisegundo1];
delay_ms(1);

d4();
datos=numero[segundo];
delay_ms(1);
d3();
datos=numero[segundo1];
delay_ms(1);

d2();
datos=numero[minuto];
delay_ms(1);
d1();
datos=numero[minuto1];
delay_ms(1);
}
         }
         }
         }

        }
      }
          }
         }
       }





6
Microcontroladores ARM / Re:NXP RT1020, LQFP100/144, Cortex M7, 500Mhz, ya disponible.
« Último mensaje por planeta9999 en 18 de Junio de 2018, 08:05:30 »
 
Hoy recibí la placa de evaluación para el RT1020, con un día de antelación. Esta placa instala un LQFP144 a 500Mhz. Parece que no hay Hyperflash, solo QSPI y SDRAM. Supongo que solo podrá arrancar desde SD o QSPI, a diferencia de la placa de evaluación del RT1050 que además añade Hyperflash.

El SDK del RT1020 ya está disponible para MCUXpresso. Lo descargué e instalé, en general bien aunque las Peripheral Tools y la configuración gráfica del Reloj no están disponibles aún. Lleva muchos ejemplos de código fuente y documentación, eso está muy bien, lo que siempre le he pedido a un entorno de desarrollo, fuentes de ejemplo a cascoporro, que es como mejor se aprende en vez de Manuales de Referencia con miles de páginas que no hay quien se las trague.

Con la placa solo dan un cable micro USB, eso es todo, un poco rácanos. No hay ningún software, CD o DVD, solo un documento impreso del Packing List, donde lleva impresa la dirección web nxp.com/MIMXRT1020EVKQSG, para en teoría descargar la Guía de Usuario de la placa, pero esa dirección no funciona. Espero que el día 26 estén disponibles el Datasheet, el Manual de Referencia del micro y el Manual de usuario de la Placa de Evaluación.

La primera impresión es buena, tanto el hardware, como el SDK prometen mucho, ya estoy preparado para migrar todos mis desarrollos de Kinetis y STM32, a esta maravilla que es la serie RT de NXP.

Por cierto, en la última foto, hay un chip de la placa que no consigo identificar, con la referencia que lleva impresa no me sale nada por Google, solo se ve que lo fabrica NXP.
















7
Todo en microcontroladores PIC / makefile error
« Último mensaje por eb en 18 de Junio de 2018, 06:36:05 »
make[2]: *** [dist/default/production/sonometro.production.hex] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2

BUILD FAILED (exit value 2, total time: 9s)

Me sale este error y no sé cómo solucionarlo, agradecería cualquier ayuda al respecto. Adjunto el archivo del programa
8
Foro Técnico / Re:Catastofreee!!! se quemó el lavarropas
« Último mensaje por bahiarca en 17 de Junio de 2018, 21:36:41 »
Lo que haya tenido estaba para encender el led que tiene al lado (junto con el otro transistor)

Que esté o no esté no afecta al funcionamiento. Si la placa no anda el problema grueso es otro.



Y no tenia un marcado el transistor que estaba alli ? La otra que te queda es tratar de dilucidar que conexiones tiene y ver si es un PNP o NPN, o que alimenta ese transistor. Para ver si podes poner cualquier otro transistor.

Otro indice es buscar si hay algun circuito parecido ( como por ejemplo al lado ) que poseen las mismas resistencias y ver que transistore usa.. Ya que se suele usar 1 o 2 modelos como mucho (de cada uno PNP y NPN ) para toda la placa, excepto etapas que neseciten un plus de corriente/tension

Gracias ya me dijeron cual era en otro foro
9
Foro Técnico / Re:Catastofreee!!! se quemó el lavarropas
« Último mensaje por Eduardo2 en 17 de Junio de 2018, 17:28:05 »
Lo que haya tenido estaba para encender el led que tiene al lado (junto con el otro transistor)

Que esté o no esté no afecta al funcionamiento. Si la placa no anda el problema grueso es otro.

10
Lenguaje C para microcontroladores PIC / Re:Librería I2C para pic18f4550??
« Último mensaje por AngelGris en 17 de Junio de 2018, 16:40:30 »
Hola electroipod.
El compilador CCS y si mal no recuerdo el XC8 tiene librerías para dicho módulo.
Páginas: [1] 2 3 4 5 6 7 8 9 10