Autor Tema: Ejemplitos en C para 16F648A  (Leído 609441 veces)

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

Desconectado RaDoN

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 1498
RE: Ejemplitos en C para 16F648A
« Respuesta #195 en: 23 de Diciembre de 2005, 07:20:00 »
vszener no paras tio jeje Giño ¡¡que buen trabajo!! Sonrisa Gigante
Si juegas contra el mejor, pierdes como los demás.

Desconectado monopic

  • PIC10
  • *
  • Mensajes: 25
RE: Ejemplitos en C para 16F648A
« Respuesta #196 en: 29 de Diciembre de 2005, 12:32:00 »
hola amigo v zener, te recuerdas lo de la lcd 2x16 que quiero ver una grafica pues vi un ejemplo, en el foro en el que se visualiaba en la lcd los numeros pero utilizando para cada numero 2 lineas verticales y podian utilizar todas las posiciones de la lcd entonces supongo que tambien se puede,,, lo que quiero hacer es primero hacer una animacion en una cuadricula y luego de que acabe en la misma cuadricula hacer otra animacion diferente por ejemplo mostrar la bateria y luego de que este llena mostrar otra cosa,, me entiendes ,, me das una manito,,, gracias .. feliz año
 

Desconectado vszener

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2395
RE: Ejemplitos en C para 16F648A
« Respuesta #197 en: 30 de Diciembre de 2005, 09:13:00 »
ke tal!!! jeje gracias radon! esto de los pic"s y programarlos ya creo que se lleva e la sangre jeje

Monopic ke tal!!!haber utilizar las filas para hacer una unica animacion la verdad que no es dificil, ya sabemos usar una cuadricula simplemente tenmos que coordinar en que cuadricula escribir....intentalo y yo me pongo manos a la obra en cuanto termine las fiestas!que no tengo disponible mi ordenador y estoy en el de mi hermano que para nada tiene ningun prgrama electronico ni nada con el que trabajar.....tiene intenert de milagro...jeje

Bueno FELIZ AÑO"06 A TODOS!!!!Giño
· Nos vemos en los bares!!!!!
· Mi Blog: Aqueronte

Desconectado mario_pastor

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 101
RE: Ejemplitos en C para 16F648A
« Respuesta #198 en: 11 de Enero de 2006, 20:10:00 »
Escrito originalmente por vszener
Buenasss jeje!!!bien, aqui otro ejmeplito mas con el periferico 7seg...ya sabemos contar desde 0 a 9, desde 9 a 0 e incluso de 0 a 9 y viceversa!!!!!vamos a seguir contando jeje esta vez aqui un ejemplito de un contador desde 00 a 99 y vuelta a empezar...aqui el programita:

////////////////////////////////////////////////////////////////////////////////////
//                     VsZeNeR"05      
//                     18/Agosto/05
//
//   Programa:   Contador del 00 al 99
//   Version:   0.0
//
//   Dispositivo: PIC 16F648A         Compilador:    CCS vs3.227
//   Entorno IDE: MPLAB IDE v7.20      Simulador:    Proteus 6.7sp3
//
//   Notas: Contador del 00 al 99 cada 1s y vuelta a empezar. Tener en cuenta
//         que hay que poner la directiva NOLVP para que el pin B4 sea de salida.
//         Se utiliza variables locales:
//            * i -> indice tabla 7seg para mostrar digito por 1º 7seg
//            * j -> indice tabla 7seg para mostrar digito por 2º 7seg
//            * flag -> variable que cuenta 1s
//            * var -> ajuste fino para que desborde cada segundo
//         Utilizamos la funcion de interrupcion para actualizar indices de la
//         tabla de 7seg para mostrar el digito correspondiente en el respectivo
//         7seg, para ello el TMR0 se desborda cada 1s, para ello debe ser cargado
//         con 61(equivale a un desbordamiento cada 50ms mas o menos), para obtener
//         un desbordamiento de 1s utilizamos una variable(flag) que no entra en
//         la actualizacion de indices hasta transcurrido 1s.
//   Conexiones:
//         · RA0 -> Display 1º 7seg
//         · RA1 -> Display 2º 7seg
//         · RB0 -> a 7seg
//         · RB1 -> b 7seg
//         · RB2 -> c 7seg
//         · RB3 -> d 7seg
//         · RB4 -> e 7seg
//         · RB5 -> f 7seg
//         · RB6 -> g 7seg
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h>            //pic a utilizar          
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP      //ordenes para el programador
#use delay (clock=4000000)         //Fosc=4Mhz
#use standard_io(B)
#use fixed_io(a_outputs=PIN_A0,PIN_A1)   //A0,A1 como salidas en porta

char i=0,j=0,flag=0,var=20;   //variables globales

///LLAMADA FUNCION INTERRUPCION
#INT_TIMER0
void interrupcion()
{
   if(flag>var){      //¿ya es 1 segundo?
      var--;         //SI -> decremento var...
      if(var<18)
         var=20;      //...ajuste fino de 1s
      flag=0;         //reset flag para contar 1s
      if(i>8){      //¿se ha mostrado por 1º 7seg digito 9?
         i=0;      //SI -> i=0 (muestra digito 0) (*)
         j++;      //incremento indice j
         if(j>9){   //¿se ha mostrado por 2º 7seg digito 9?
            j=0;}   //SI -> j=0 (muestra digito 0)
            }
      else{         //(*) NO -> incrementa i
         i++;}
      }
   set_timer0(61);      //reset TMR0
   flag++;            //incremento variable flag
}

///PROGRAMA
void main(void)
{
   int tab7seg[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67};   //7seg hex 0-9
   
   set_tris_b(0x00);                     //portb como salida
   enable_interrupts(INT_TIMER0);            //interrupcion TIMER0 activada
   setup_counters(RTCC_INTERNAL,RTCC_DIV_256);   //configuracion interrupcion TMR0
   set_timer0(61);                        //carga TMR0
   enable_interrupts(GLOBAL);               //activadas interrupciones

   do{                        //bucle...
      output_high(PIN_A1);      //2º 7seg off            
      output_low(PIN_A0);         //1º 7seg on
      delay_ms(15);            
      output_b(tab7seg[ i ]);      //muestra por portb digito 7 segmentos
      output_low(PIN_A1);         //2º 7seg on            
      output_high(PIN_A0);      //1º 7seg off
      delay_ms(15);            
      output_b(tab7seg[ j ]);      //muestra por portb digito 7 segmentos            
      }while(TRUE);            //...infinito         
}

Decir que este ejemplito es bastante curioso aparte por manejar display"s de 7 segmentos multiplexados, por utilizar el TIMER0...es decir la cuenta de 1 segundo se hace atraves del desbordamiento del TMR0.....asi ya sabeis como programar interrupciones.....Giño


Profesor vszener Giño tengo dudas respecto a este ejemplo, básicamente en la interrupción por TMR0 donde mencionas el ajuste fino... se que la interrupción se genera cada 50ms y que con el contador FLAG te aseguras de controlar que sea 1s. Mi pregunta es en que te basas para lo del ajuste fino Helado

Gracias por tu tiempo.
Saludos,
Mario.

Lima - Perú

271071

  • Visitante
RE: Ejemplitos en C para 16F648A
« Respuesta #199 en: 12 de Enero de 2006, 06:51:00 »

tengo dudas respecto a este ejemplo, básicamente en la interrupción por TMR0 donde mencionas el ajuste fino... se que la interrupción se genera cada 50ms y que con el contador FLAG te aseguras de controlar que sea 1s. Mi pregunta es en que te basas para lo del ajuste fino Helado
pues yo tengo las mismas dudas

Desconectado vszener

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2395
RE: Ejemplitos en C para 16F648A
« Respuesta #200 en: 12 de Enero de 2006, 12:28:00 »
Buenas!!!haber lo del ajuste fino....el ajuste fino es debido ya que el desbordamiento a efectos practicos(es decir en la vida real) no es perfecta, si programamos el timer para que se desborde y "cuente algo" en este caso segundo veremos, por lo menos en mi caso es asi, que la cuenta no es exacta y esto es debido a la llamada a la interrupcion. Hay herramientas donde podemos manejar el tiempo que tarda en ejecutarse las instrucciones(el MPlab tiene un reloj que cuenta cuanto tiempo tarda en ejecutarse lo que hayamos configurado) yo en estos programas, como todo esta simulado en PROTEUS, he realizado el ajuste fino al reloj de simulacion de PROTEUS(ya que es el entorno donde simulamos el programa), es decir, cargo el programa al pic y le doy a simular, abajo aparece el tiempo que lleva el programa ejecutandose/simulandose, de ese tiempo me he servido para hacer el ajuste fino, cualquier programa que tenga la variable o las instrucciones de "ajuste fino" estan basados en el reloj de PROTEUS de simulacion, si lo simulas veras que el programa sigue al reloj de PROTEUS por lo tanto ya tenemos la temporizacion requerida!

Para ver las diferencias del ajuste fino y sin el, simplemente eliminar dichas sentencias de codigo del "ajuste fino" y vereis que el contador no es perfecto(si hicieramos un reloj sin ajuste fino s descalibraria bastante), en cambio si simulamos con las sentencias de codigo de ajuste fino veremos que la cuenta practicamente es perfecta(si hicieramos un reloj asi veriamos que su calibracion no seria demasiado significativa)

Bueno, despues del rollo espero haber sido claro, vamos en resumen las temporizaciones no son perfectas, igual modo que en ensamblador hay instrucciones como la "nop" que no realiza nada(simplemente "perder tiempo"/ajustar temporizaciones), en estos programas de ajuste fino he ido teniendo en cuenta la tolerancia del timer ajustandolo para que su cuenta sea la mas precisa posible a la cuenta requerida.

Suerte!!!Giño
· Nos vemos en los bares!!!!!
· Mi Blog: Aqueronte

Desconectado pelusac

  • PIC16
  • ***
  • Mensajes: 118
RE: Ejemplitos en C para 16F648A
« Respuesta #201 en: 17 de Enero de 2006, 11:55:00 »
Que tal vszener ,solo escribo para animarte a realizar mas ejemplitos y que los cuelgue en el foro donde paso casi todo mi tiempo libre;
Me gustaria agradecerte el post que has abierto de ejemplos ya que para mi la programacion de micros era imposible hasta realizar todos los ejmplos que has puesto,creo que ya le veo color a esto.RollEyesIdea
Asi que gracias porque tu ayuda ha sido inestimable y muy altruista ya que creo que hay muchos como yo que comen y duermen en tu post;
Bueno pues dicho esto maestro vszener haber si te animas y sigues poniendo ejemplitos que entre tu,nocturno ,redpic.....podeis hacer de esto una maravilla
Saludos de un sevillano ......viva la cerveza!!!!!!!Rebotado

Desconectado monopic

  • PIC10
  • *
  • Mensajes: 25
RE: Ejemplitos en C para 16F648A
« Respuesta #202 en: 18 de Enero de 2006, 17:28:00 »
hola   vzener a ver si me echas una manito a lo de la lcd te acuerdas la idea es hacer una animacion en una cuadricula   y luego otra diferente.... gracias

Desconectado YDAVID

  • PIC10
  • *
  • Mensajes: 3
RE: Ejemplitos en C para 16F648A
« Respuesta #203 en: 19 de Enero de 2006, 16:36:00 »
Gracias por todo esto.
¡ah¡   ¿cuales bares?

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
RE: Ejemplitos en C para 16F648A
« Respuesta #204 en: 20 de Enero de 2006, 06:44:00 »
Primero aunque no hace falta decirlo siquiera, enhorabuena por tu trabajo.
Me ha facilitado las cosas en multiples ocasiones.
ME atreveria a pedirte un favor, en el que creo qeu coincidimos muchos de los del foro.
Yo tenia bajado todos los ejemplos hasta que mi discu duro se averio y los perdi, eran como una libreria de referencias, que usaba para programar.
LA idea de publicarlos con enlace uno a uno me parece magnifica, pero, no habria forma de tenerlos para bajarlos todos agrupados en uno?
Se podria actualizar ese fichero facilmente añadiendo el nuevo ejemplo.
Lo que me ocurre es que bajo algo, y luego me falta algun enlace y tengo que estar ordenando ejemplos por carpetas etc, y ese trabajo que ya estaba hecho se perdio asi que estoy liado
Si fuese posible se que muchos te estaremos agradecidos

Desconectado vszener

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2395
RE: Ejemplitos en C para 16F648A
« Respuesta #205 en: 20 de Enero de 2006, 11:06:00 »
Buenas!!!!!haber, por partes:
Pelusac GRACIAS!!!!y me alegra muchisimo que ya empieces a programar, y que estos ejemplos te valgan para ello pues me alegra mucho mas!lo de seguir poniendo ejemplitos, pues si!lo malo, es que "creo" que este pic ya se nos esta quedando pequeño, pero todavia falta ver como se programan las interrupciones RS-232(aunque el amigo RedPic las tiene programadas en su post) haber si pongo un ejemplito aqui, y creo que poco mas.....me refiero a los perifericos del 16F648A, mi idea es ampliar el post y meternos de lleno con una familia superior, la familia 18(ya que la familia 24 estan ya!jeje)e ir colocando ejemplos para esta familia compilados en CCS y en el C18 de Microchip, asi realizariamos a la par un estudio tanto de comodidad como de ahorro de codigo de un compilador a otro...esa es mi idea....

monopic ke tal!!!estoy en lo tuyo, pero haber si me muestras que tienes realizado tu, o me cuelgas tu idea, yo en cuanto tenga algo de tiempo me meto manos a la obra!Pero intentalo tu haber que sale....

YDAVID GRACIAS!!!los bares???jeje cualquiera es buen recibido!jeje

Algec GRACIAS!!!con respecto agrupar todos los ejemplos y poder descargarselos todos es una idea bastante buena pero....hay dos problemas, uno es que el almacen no me deja editar mis mensajes(dice que no tengo el nivel suficiente) esto provocaria que a cada ejemplo ir escribiendo un post distinto y creo que eso no contribuiria al orden del almacen....el otro problema es que tampoco puedo subirlos todos al almacen por su "peso", creo que son 12Mb o algo asi...lo que se me ocurre es hacerlos por partes, es decir, post de tandas de ejemplos, en un post del almacen por ejemplo, tener para su descarga 5 ejemplos o los que quepe!

Y bueno, me alegra muchoentrar en este post y ver como la gente les vale de algo estos programitas que aunque parezcan tontos(y lo son!jeje) sirve para aprender a programar los distintos perifericos internos como algunos externos del pic! GRACIAS A TODOS!!!! y a seguir programando!

Suerte!!!Giño
· Nos vemos en los bares!!!!!
· Mi Blog: Aqueronte

Desconectado vszener

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2395
RE: Ejemplitos en C para 16F648A
« Respuesta #206 en: 20 de Enero de 2006, 11:14:00 »
Holaaa!!!bueno, aqui dejo un programa que se sale de la tematica de aprendizaje a programar perifericos internos del pic, pero vamos creo que es ilustrativo a la programacion del mismo y hardware, hace tiempo que pense en regalarle un reloj digital a mi niña, y bueno pue sme puse manos a la obra, el conteo y la realizacion del reloj lo realiza todo el pic, aqui el programa:

////////////////////////////////////////////////////////////////////////////////////
//                     VsZeNeR"05      
//                   29/Noviembre/05
//
//   Programa:   Reloj digital 7seg
//   Version:   0.0
//
//   Dispositivo: PIC 16F648A         Compilador:    CCS vs3.236
//   Entorno IDE: MPLAB IDE v7.22      Simulador:    Proteus 6.7sp3
//
//   Notas: Reloj digital en 7seg. Se utiliza un DEC 4555 para realizar el barrido
//         de los 7seg, se usa tambien, un BCD-7Seg 4543 para la visualizacion
//         de los numeros en el 7seg. El reloj esta compuesto de 4 botones.
//         Botones:   Hora/Minutos->RB1:     Cuando estemos en modo Configuracion,
//                                 pasar de hora a minutos para incrementar.
//               + ->RB2:               Para incrementar en una unidad el digito actual.
//               Configuracion/Ok->RB3: Si se pulsa pasamos al modo
//                                 configuracion para poder actualizar
//                                 la hora actual, una vez actualizada,
//                                 si se pulsa pasamos al modo de reloj
//         Conexiones:      A0 -> A 4555 DEC            
//                     A1 -> B 4555 DEC
//                     A2 -> 2 led"s en serie(secundero)
//                     A5 -> Boton reset(externo)                  
//                     B1 -> Boton Hora/Minuto
//                     B2 -> Boton +
//                     B3 -> Boton Configuracion/Ok         
//                     B4 -> A 4543      
//                     B5 -> B 4543        
//                     B6 -> C 4543          
//                     B7 -> D 4543   
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h>               //pic a utilizar          
#fuses XT,NOCPD,NOWDT,NOPUT,NOLVP,NOBROWNOUT      //ordenes para el programador
#fuses INTRC                     //oscilador interno
#use delay (clock=4000000)            //Fosc=4Mhz
#use fixed_io(a_outputs=PIN_A0,PIN_A1,PIN_A2)
#use fixed_io(b_outputs=PIN_B4,PIN_B5,PIN_B6,PIN_B7)
#bit RA2=05.2                     //secundero

///DEFINICION DE FUNCIONES
void configurar(void);

///VARIABLES GLOBALES
char  min1=0,min2=0,hor1=0,hor2=0;
char  flag=0,var=119;                  //variables de ajuste de 1 minuto
char  tab[10]={0x00,0b00010000,0b00100000,0b00110000,
      0b01000000,0b01010000,0b01100000,0b01110000,0b10000000,0b10010000};   //bcd parte alta 0-9
      
///LLAMADA FUNCION INTERRUPCION
#INT_TIMER1
void interrupcion()
{
   if(flag>var){               //¿Ya es 1 minuto?
      var--;                  //SI -> decremento var...
      if(var<118)
         var=120;            //...ajuste fino de 1min
      flag=0;                  //reset flag para contar 1min
      min1++;               
      if(min1>9){               //¿Se ha mostrado xx:x9?         
         min1=0;               //SI -> reset min1 xx:x0
         min2++;
         if(min2>5){            //¿Se ha mostrado xx:59?
            min2=0;            //SI -> reset min2 xx:00
            hor1++;
            if(hor2==2){      //¿Estamos en modo noche 2x:xx?   
               if(hor1>3)      //SI -> ¿Se ha mostrado 23:59?
                  goto noche;}//SI -> ve a noche
            if(hor1>9){         //No estamos en modo noche-> ¿se ha mostrado 19:59?
noche:            hor1=0;         //SI -> reset hor1 x0:00 || noche: reset hor1 x0:00
               hor2++;
               if(hor2>2)      //¿Se ha mostrado 23:59?   
                  hor2=0;      //SI -> reset hor2 00:00
               }
            }
         }
      }
   RA2=!RA2;                  //parpadeo secundero cada 0,5s
   set_timer1(3036);            //reset TMR1
   flag++;                           
}

///PROGRAMA
void main(void)
{   
   enable_interrupts(INT_TIMER1);            //interrupcion TIMER1 activada
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);      //configuracion TMR1
   set_timer1(3036);                     //carga TMR1 para desvordar cada 0.5s
   enable_interrupts(GLOBAL);               //activadas interrupciones

   do{            //bucle...
      output_low(PIN_A0);         //Primer 7seg...
      output_low(PIN_A1);         //...on
      output_b(tab[min1]);
      delay_ms(10);
      output_low(PIN_A1);         //Segundo 7seg...
      output_high(PIN_A0);      //...on
      output_b(tab[min2]);
      delay_ms(10);
      output_high(PIN_A1);      //Tercer 7seg...
      output_low(PIN_A0);         //...on
      output_b(tab[hor1]);
      delay_ms(10);
      output_high(PIN_A0);      //Cuarto 7seg...
      output_high(PIN_A1);      //...on
      output_b(tab[hor2]);
      delay_ms(10);
      if(!input(PIN_B3)){         //¿Se ha pulsado boton Configuracion?
         while(!input(PIN_B3)){}   //SI -> elimina rebotes pulsador...
         configurar();         //...ve a configurar
         }
   }while(TRUE);   //...infinito
}
///FUNCION QUE CONFIGURA LA HORA ACTUAL
void configurar(void){
   boolean sal=0;
   char menu=0;                  //menu=0: incremento minutos || menu=1: incremento horas
   disable_interrupts(GLOBAL);         //todas las interrupciones desactivadas
   do{
      do{
      output_a(0b00);
      output_b(tab[min1]);
      delay_ms(10);
      output_a(0b01);
      output_b(tab[min2]);
      delay_ms(10);
      output_a(0b10);
      output_b(tab[hor1]);
      delay_ms(10);
      output_a(0b11);
      output_b(tab[hor2]);
      delay_ms(10);
      if(!input(PIN_B1)){            //¿Se ha pulsado boton Horas/Minutos?
         while(!input(PIN_B1)){}
         menu=!menu;               //SI -> Cambia minutos/horas y viceversa
         }
      if(!input(PIN_B2)){            //¿Se ha pulsado boton +?
         while(!input(PIN_B2)){}
         sal=1;                  //SI -> incrementa una unidad el digito(segun variable menu)
         }
      if(!input(PIN_B3)){            //¿Se ha pulsado boton Ok?
         while(!input(PIN_B3)){}
         sal=1;                  //SI -> salir...
         menu=2;                  //...modo Configurar y mostrar hora actualizada
         }
      }while(sal==0);
      
      sal=0;                     //reset variable sal
      if(menu==0){               //¿Incremento digito de minutos?
         min1++;                  //SI         
         if(min1>9){               //¿Se ha mostrado xx:x9?         
            min1=0;               //SI -> reset min1 xx:x0
            min2++;
            if(min2>5)            //¿Se ha mostrado xx:59?
               min2=0;            //SI -> reset min2 xx:00
            }
      }   
      if(menu==1){               //¿Incremento digito horas?
         hor1++;                  //SI
         if(hor2==2){            //¿Estamos en modo noche 2x:xx?
            if(hor1>3)            //SI -> ¿se ha mostrado 23:xx?
               goto night;         //SI -> ve a night
            }
         if(hor1>9){               //No estamos en modo noche->¿se ha mostrado 19:xx?
night:         hor1=0;               //SI -> reset hor1 10:xx ||modo noche: reset hor1 20:xx
            hor2++;
            if(hor2>2)            //¿Se ha mostrado 23:xx?
               hor2=0;            //SI -> reset hor2 00:xx
               }
      }
      }while(menu<2);
      enable_interrupts(GLOBAL);      //todas las interrupciones desactivadas
      set_timer1(3036);            //carga TMR1
      flag=0;                     //reset variables...
      var=119;                  //...ajuste de 1min
}
         
Bien decir, que este no fue el programa final que grabe en el pic....pero bueno, creo que este es mas ilustrativo a la programacion, el que finalmente grabe en el pic manejaba la hora en una variable y mediante una funcion obtenia los valores a representar.....

Ya sabemos que hora es tanto con una RTC como con este ejemplo!!!!

Suerte!!!Giño
· Nos vemos en los bares!!!!!
· Mi Blog: Aqueronte

Desconectado vszener

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2395
RE: Ejemplitos en C para 16F648A
« Respuesta #207 en: 20 de Enero de 2006, 11:15:00 »
Desde esta direccion os podeis descargar los archivos necesarios para el programa anterior: reloj digital


Suerte!!! :wink:
« Última modificación: 25 de Mayo de 2006, 11:18:40 por vszener »
· Nos vemos en los bares!!!!!
· Mi Blog: Aqueronte

Desconectado vszener

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2395
RE: Ejemplitos en C para 16F648A
« Respuesta #208 en: 27 de Enero de 2006, 06:27:00 »
Buenas!!!!GRACIAS pelusac!, bueno decir que el indice se ha añadido el apartado REVISION, este apartado esta dedicado a programas anteriores mejorados, asi que para una implementacion real de cualquier programa se recomienda usar la revision si esta disponible.....

Suerte!!!Giño
· Nos vemos en los bares!!!!!
· Mi Blog: Aqueronte

Desconectado vszener

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2395
RE: Ejemplitos en C para 16F648A
« Respuesta #209 en: 27 de Enero de 2006, 06:31:00 »
Buenas!!!!aqui os dejo lo que os dije!el manejo d ela interrupcion serial!, este ejemplo sirve como revision del programa 29, el cual se encarga de la escritura y lectura de la eeprom interna del pic, en este caso de 256k, aqui el programa:

////////////////////////////////////////////////////////////////////////////////////
//                     VsZeNeR"06      
//                     23/Enero/06
//
//   Programa:   RS232 Y PIC
//   Version:   1.0 REVISION del programa 45
//
//   Dispositivo: PIC 16F648A         Compilador:    CCS vs3.242
//   Entorno IDE: MPLAB IDE v7.30      Simulador:    Proteus 6.7sp3
//
//   Notas: Se interacciona el PC con el PIC mediante RS232 para el tratamiento de la memoria
//         eeprom interna,se muestra por v.terminal un menu:
//               · 0 -> Muestra nuevamente el menu
//               · 1 -> LLena la eeprom a 0xFF
//               · 2 -> Lee la eeprom en modo hex
//               · 3 -> Escribe en la eeprom
//               · 4 -> Lee la eeprom en modo texto(ASCII)
//         Todas las acciones se realizan mediante la interrupcion del puerto serial.
//         Al comienzo del programa, realizar el paso 1. en caso de empezar a escribir
//         en la eeprom!. Decir que las funciones gethex1() y gethex() estan sacadas
//         de la libreria incluida en CCS, input.c, estan puestas en el programa
//         por la pequeña modificacion en la funcion gethex1() que, en este caso, solo
//         permite el paso de digitos comprendidos entre 0-f o 0-F. Tener en cuenta
//         que los datos a introducir deben ser en hexadecimal, por ejmeplo, en el
//         caso de almacenar en la letra "a" minuscula en la posicion 00 de la eeprom
//         interna del pic, habra que realizar los siguientes pasos:
//               1. Pulsamos 3 para escribir en la eeprom interna
//            2. Ponemos la direccion 00 (esta en hexadecimal!)
//            3. Damos el valor en hex de la letra a=0x61
//            4. Leemos la memoria para ver que se almacenado correctamente(pulsando 2)
//         La eeprom interna del 16F648A  es de 256k.
//
//   Conexiones:      B2 -> TxD
//               B1 -> RxD                
//////////////////////////////////////////////////////////////////////////////////
#include <16f648a.h>                     //pic a utilizar          
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP,NOBROWNOUT   //ordenes para el programador
#fuses RC_IO                           //reloj interno
#use delay (clock=4000000)                  //Fosc=4Mhz
#use rs232(baud=9600, xmit=PIN_b2, rcv=PIN_b1)   //manejo del RS232                     

///DECLARACION DE VARIABLES GLOBALES
boolean menu=1,opcion=1;      //si menu=0 se muestra el menu de inicio...
                        //...si opcion=1 estamos en modo direccion
                        //      opcion=0 estamos en modo dato

///DECLARACION DE FUNCIONES
BYTE gethex1( );      //verifica que esta dentro del rango y muestra por pantalla
BYTE gethex( );      //devuelve el numero en hex

///LLAMADA FUNCION INTERRUPCION
#int_rda
void rs232()
{
   BYTE i=0,j=0,address,value;         //definicion...
   char digito;               //...variables
   
   disable_interrupts(global);      //apago interrupcion
   
   digito=getc();               //almaceno dato serial(rs232) en digito
   
   puts("
****************************************************" );   
   
   switch(digito){
      case "0":      menu=!menu;                  //muestra menu
                  break;
      case "1":      printf("LLenando buffer..." ) ;   //llena memoria 0xff
                     for(i=0; i<16;i++){                    
                           for(j=0; j<16;j++)
                              write_eeprom(i*16+j,0xff);
                           }
                     puts(" Buffer completado!" );
                     break;
         case "2":      puts("Realizando Lectura...
" );   //opcion que realiza la lectura modo hex
                    puts("00  01  02  03  04  05  06  07  08  09  0A 0B  0C  0D 0E 0F" );
                     puts("==============================================" );
                     for(i=0;i<16;i++) {          
                        for(j=0;j<16;j++) {
                            printf("%2x ",read_eeprom(i*16 +j) );
                        }
                        printf("|| %3x0
",i );                  
                     }
                     puts("
Lectura finalizada!" );
                     break;
         case "3":      printf("
Direccion a cambiar: " );   //opcion que realiza la escritura
                   address = gethex( );                  //le damos la direccion
                   printf("
Nuevo valor: " );
                   opcion=0;                        //modo datos
                   value = gethex( );                  //le damos el dato a escribir
                   opcion=1;                        //modo direcciones
                   printf("
Realizando escritura..."Giño;
                   write_eeprom(address,value);         //escribe en la eeprom
                   printf(" Escritura finalizada!
"Giño;
                     break;
         case "4":      puts("Realizando Lectura...
" );   //opcion que realiza la lectura modo texto
                    puts("00  01  02  03  04  05  06  07  08  09  0A 0B  0C  0D 0E 0F" );
                     puts("==============================================" );
                     for(i=0;i<16;i++) {          
                        for(j=0;j<16;j++) {
                            printf("%c ",read_eeprom(i*16 +j));
                        }
                        printf("|| %3x0
",i );                  
                     }
                     puts("
Lectura finalizada!" );
                     break;
         default:      puts("Opcion incorrecta, para ver Menu pulse 0    VsZeNeR"06" );   
      }
    puts("****************************************************
" );
    enable_interrupts(global);      //activamos de nuevo la interrupcion serial rs-232
}

///PROGRAMA
void main(void)
{   
   setup_oscillator(OSC_4MHZ);      //reloj interno de 4MHz
     enable_interrupts(int_rda);      //activo interrupcion serial rs-232
      enable_interrupts(global);      //habilito la interrupcion
         
   do{            //bucle...
      puts("Lectura/Escritura de EEPROM interna    VsZeNeR"06
" );      //menu...   
      puts("==============================================
" );
      puts("Seleccione opcion:
" );
      puts("¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨" );
      puts("   0->Ver opciones" );
      puts("   1->LLenar buffer" );
      puts("   2->Lectura modo HEX" );
      puts("   3->Escritura EEPROM" );
      puts("   4->Lectura modo TEXTO" );                           //...principal
      menu=1;                     //muestra menu solamente una vez
      while(menu==1){}            //espera tecla pulsada por teclado(rs-232)
   }while(TRUE);   //...infinito
}
///FUNCION QUE SELECCIONA DIGITO CORRESPONDIENTE
BYTE gethex1() {
    char digit;
   
   do{                  //espera hasta tener un dato correcto
       digit = getc( );
       if(opcion==0)      //si estamos introduciendo un dato no hace falta las restricciones
          break;
    }while((digit<"0" || digit>"9") && (digit<"A" || digit>"F") && (digit<"a" || digit>"f") );

   putc(digit);            //muestra por pantalla el dato introducido

   if(digit<="9")         //se ha introducido un numero
     return(digit-"0");
   else                  //se ha introducido una letra
     return((toupper(digit)-"A")+10);
}
///FUNCION QUE DEVUELVE EL NUMERO HEXADECIMAL
BYTE gethex() {
   int lo,hi;

   hi = gethex1( );      //parte alta
   lo = gethex1( );      //parte baja
   if(lo==0xdd)
     return(hi);
   else
     return( hi*16+lo );
}

Bueno, recordar que si quereis implementarlo en la vida real debereis retocar el formato de presentacion del menu, ya que en proteus no reconoce algunos como en y tal....asi que se ha programado para una "aceptable" vision en proteus!

Suerte!!!Giño
· Nos vemos en los bares!!!!!
· Mi Blog: Aqueronte