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

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

Desconectado vszener

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2395
RE: Ejemplitos en C para 16F648A
« Respuesta #165 en: 05 de Noviembre de 2005, 07:00:00 »
Buenas!!!haber no tengo tiempo para probarlo ya que estoy de un lado para el otro haber si cuando me siente con tiempo lo compruebo....decirte que puedes poner archivos .h tantos como quieras a priori, es mas, si haces un programa largo lo ideal es que estructures el codigo mediante librerias(mediante .h) por lo tanto, si es bastante largo y debes utilizar mas de una variable global, define un archivo .h que solamente tenga las variables globales, despues si usas mas de una interrupcion, crea un archivo .h que solo tenga las interrupciones y asi igual con todo, vamos que al final solo te quede el codigo del main y muchos includes, asi tendras un codigo perfectamente estructurado...haber si este lunes o martes pongo un ejemplo de prueba.....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 #166 en: 05 de Noviembre de 2005, 07:04:00 »
Bueno estaba apunto de cerrar el post y el puntero del raton se quedo en esta instruccion de la funcion void enciende(tiempo,canal):
Codigo:

case 3:

while(fin==0)
{
if(cont12<3) //Se deja el primer paso del contador por seguridad
output_low(PIN_A4); //2 bits a 0
else
if(cont12=3)
ouput_high(PIN_A4); //3º bit a 1
else
......


Cuidado...la comprobacion debe ir con doble igual: if(cont12==3) okis???
Suerte!!!Giño
· Nos vemos en los bares!!!!!
· Mi Blog: Aqueronte

Desconectado andresitovv

  • PIC10
  • *
  • Mensajes: 40
RE: Ejemplitos en C para 16F648A
« Respuesta #167 en: 06 de Noviembre de 2005, 08:47:00 »
Muchas gracias por tu tiempo. Sí, eso me di cuenta el otro día, soy un pokito despistao programando. Me di cuenta porque cuando cambiaba de canales y pasaba por el tercero la cosa no iba bien. Mi único problema era q una variable global definida en main.c no podía utilizarla luego en un archivo.h., pero me he dado cuenta que para solucionarlo solo tengo q incluir   #include "main.c"    en el archivo.h, creo, voy a probar. Mi problema ahora es q cuando compilo se me abre el archivo 18f452.h y me dice: "can not change device type this far into the code". He probado muchas cosas y no sé como quitarlo!! Gracias!!!

Desconectado vszener

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2395
RE: Ejemplitos en C para 16F648A
« Respuesta #168 en: 06 de Noviembre de 2005, 14:35:00 »
Buenas!!!haber si te miras la help del compilador CCS veras que dicho error es porque pones la definicion del dispositivo despues de generar el codigo, vamos despues de compilarlo, entonces para solucionarlo, debes poner el include del PIC en el primer archivo del proyecto asi ya estara definido para todo el programa. Antes de incluir el main.c en el include prueba a crear una libreria donde solamente declares las funciones globales a utilizar y despues incluyelas en el programa principal asi sera menos lioso y mas estructurado. 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 #169 en: 07 de Noviembre de 2005, 01:34:00 »
Buenas!!!bien el ejemplito de hoy consiste en manejar igualmente que el programa anterior el modulo CCP1 en modo PWM, pero en vez de ser constante como el anterior a 50% la anchura de pulso, se ha programado para que sea variable a 50% y al 75%, tambien este programa pretende aparte de manejar dicho modulo, la utilizacion y creacion de archivos .h, los cuales haran que el programa principal main este mas estructurado en tema codigo:

////////////////////////////////////////////////////////////////////////////////////
//                     VsZeNeR"05      
//                    6/Noviembre/05
//
//   Programa:   Uso del CCP1 como PWM al 50% y 75%
//   Version:   1.0
//
//   Dispositivo: PIC 16F648A         Compilador:    CCS vs3.236
//   Entorno IDE: MPLAB IDE v7.22      Simulador:    Proteus 6.7sp3
//
//   Notas: Usamos el modulo CCP1 como PWM, para ello configuramos el TMR2 de sus tres
//         formas distintas mediante el preescales(1,4,16) que nos dara distintas frecuencias.
//         El ciclo viene determinado por (1/clock)*4*t2div*(periodo+1), donde en este caso
//         clock=4MHz y periodo=127.
//         Frecuencias:
//               ·T2_DIV_BY_1  -> 128us  -> 7,81KHz
//               ·T2_DIV_BY_4  -> 512us  -> 1,95KHz
//               ·T2_DIV_BY_16 -> 2,05ms -> 487,8Hz
//         La anchura de pulso en nivel alto depende de la relacion valor*(1/clock)*t2div donde
//         valor=%nivel alto del pulso.
//         Anchura del pulso(Duty):
//         *Para 50%:
//            ·128us   -> 64us   -> 64us/(1*(1/4000000))    = 256
//            ·512us   -> 256us  -> 256us/(4*(1/4000000))   = 256
//            ·2,05ms  -> 1,02ms -> 1,02ms/(16*(1/4000000)) = 256
//         *Para 75%:
//            ·128us   -> 96us   -> 96us/(1*(1/4000000))    = 384
//            ·512us   -> 384us  -> 384us/(4*(1/4000000))   = 384
//            ·2,05ms  -> 1,54ms -> 1,54ms/(16*(1/4000000)) = 384
//         Este programa tambien ha pretendido abarcar como crear archivos .h para
//         que dicho codigo sea mas estructurado.
//         Conexiones:      B0 -> E            
//                     B1 -> RS         
//                     B2 -> RW      
//                     B4 -> D4        
//                     B5 -> D5            
//                     B6 -> D6   
//                     B7 -> D7
//                     B3 -> Canal 1 osciloscopio
//                     A0 -> Boton
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h>            //pic a utilizar          
#include<vs_fuses&demas.h>         //libreria manejo fuses
#define use_portb_lcd TRUE         //definir portb lcd
#include<lcd.c>                  //libreria manejo lcd
#include<vs_variables_globales.h>      //libreria manejo de funciones
#include<vs_funciones.h>            //libreria manejo de variables

///PROGRAMA
void main(void)
{
   setup_ccp1(CCP_PWM);    //ccp1 modo PWM
   
   lcd_init();            //inicializa lcd
   
   cambia_frec( );      //muestra primera frec
   cambia_duty( );      //muestra primer ancho de pulso
   
   for( ; ; ){      //bucle...
      if(!input(PIN_A0)){            //¿se ha pulsado el boton?
         do{                     //SI -> eliminar...            
         }while(!input(PIN_A0));      //...rebotes del boton
         opcion++;               //apunta a siguiente frec
         if(opcion>2)            //¿ya se han mostrado todas las frec?
            opcion=0;            //SI -> resetea opcion
         cambia_frec( );      //cambia frecuencia
         }
         
      if(!input(PIN_A1)){            //¿se ha pulsado el boton?
         do{                     //SI -> eliminar...            
         }while(!input(PIN_A1));      //...rebotes del boton
         duty++;               //apunta a siguiente frec
         if(duty>1)            //¿ya se han mostrado todas las anchuras de pulso?
            duty=0;            //SI -> resetea duty
         cambia_duty();      //cambia anchura pulso
         }
      }         //...infinito
}


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

Desconectado andresitovv

  • PIC10
  • *
  • Mensajes: 40
RE: Ejemplitos en C para 16F648A
« Respuesta #170 en: 07 de Noviembre de 2005, 02:43:00 »
Gracias, pero como te dije habia ya investigado y nada. Aunque en el primer archivo ponga #include <18F452.h> luego al compilar se me abre el 18F452.h y me da el error ese. Si pongo lo de #device 18F452 en el primer archivo sino lo quito del 18F452.h me dice lo mismo. Total, que lo quité lo de #device del .h y se vuelve abrir diciendo que necesita una directiva device antes. He probado mil formas (incluyendo archivos, haciendo includes, poniendo muchos #device...), pero no tengo manera, siempre hay un error. Prueba verás... simplemente intenta utilizar una variable global en distintos archivos y si te funciona me pasas el código!! Por supuesto probé lo de hacerlo todo ordenadito creando las variables goblales y directivas en un .h. Gracias!!

Desconectado andresitovv

  • PIC10
  • *
  • Mensajes: 40
RE: Ejemplitos en C para 16F648A
« Respuesta #171 en: 07 de Noviembre de 2005, 02:44:00 »
Puede ser porque tenga mucho código en un solo archivo? Se me olvidaba decir que utilizo la versión 3.187 del CCS. Gracias!!

Desconectado vszener

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2395
RE: Ejemplitos en C para 16F648A
« Respuesta #172 en: 07 de Noviembre de 2005, 05:21:00 »
Haber....lo de utilizar una variable global en muchos archivos pues en el ultimo ejemplo(el 46 creo) hay declaradas dos variables globales que se utilizan tanto en el programa principal main y despues en la libreria vs_funciones.h, haber si el problema va ser el orden en el main, es decir, el primer include que hagas debe ser las variables globales, despues vendrian las funciones(que pueden o no utilizar dichas variables) y asi seguido....a mi el programa numero 46 que lo he realizado mediante librerias no me ha dado problema, miratelo! y ya me cuentas, con respecto a la version, yo uso ahora la 3.236 pero vamos que desde la 3.227 que es la primera version que yo use no he tenido problemas en temas de crear y utilizar librerias....Suerte!!!Giño
· Nos vemos en los bares!!!!!
· Mi Blog: Aqueronte

Desconectado andresitovv

  • PIC10
  • *
  • Mensajes: 40
RE: Ejemplitos en C para 16F648A
« Respuesta #173 en: 08 de Noviembre de 2005, 02:27:00 »
Pues al final lo he resuelto!! Los ejemplitos no me han servido mucho, pero gracias por los ánimos y los suerte!! Es que cuando hay 4 o 5 archivos.h y todos se necesitan entre ellos no es fácil compilar con el tema de los #include"s. Le tuve que dar muchas vueltas!! Gracias y ciao. Si a alguien le interesa que lo ponga todo...aunq es un poco largo.

Desconectado vszener

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2395
RE: Ejemplitos en C para 16F648A
« Respuesta #174 en: 08 de Noviembre de 2005, 08:35:00 »
Supongo que tu error estaba en el orden de declaracion de los includes....bueno de todas formas me alegro de que lo solucionaras!!!Giño
· Nos vemos en los bares!!!!!
· Mi Blog: Aqueronte

Desconectado vszener

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2395
RE: Ejemplitos en C para 16F648A
« Respuesta #175 en: 08 de Noviembre de 2005, 09:00:00 »
Buneasss!!!Bien el ejemplito de hoy trata de como insertar codigo ASM en nuestro programa en C. Normalmente dicho codigo en ASM se hace para temporizaciones muy finas, en este caso lo usaremos para gobernar el programa. Dicho programa realiza la iluminacion sucesiva de 4 led"s mediante un decodificador, en ASM se ha programado como manejar la variable cont para dar la instruccion a que led encender, el programa tambien realiza a la vez, la cuenta ascendente de un numero bcd 0a9 mediante un bcd-7seg, esta vez el codigo ASM se encarga de todo tanto de la variable como de mostrarlo por pantalla....bueno no me enrrollo mas!!!jeje aqui el programa:

////////////////////////////////////////////////////////////////////////////////////
//                     VsZeNeR"05      
//                    8/Noviembre/05
//
//   Programa:   Led"s & display 7seg andodo comun
//   Version:   0.0
//
//   Dispositivo: PIC 16F648A         Compilador:    CCS vs3.236
//   Entorno IDE: MPLAB IDE v7.22      Simulador:    Proteus 6.7sp3
//
//   Notas: Este programa muestra como incorporar codigo ASM en nuestro programa en C.
//         Los modulos en asm manejan lso perifericos(uno es una barra de led"s, se
//         iluminan hasta 4 led"s de forma consecutiva y vuelta a empezar, y el otro
//         maneja un contador ascendente bcd de 0a9 y vuelta a empezar). Se usa los
//         perifericos decodificador 4555 y bcd-7seg 74247.
//         Conexiones:      A0 -> A 4555 DEC            
//                     A1 -> B 4555 DEC         
//                     B4 -> A 74247      
//                     B5 -> B 74247        
//                     B6 -> C 74247          
//                     B7 -> D 74247   
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h>               //pic a utilizar          
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP      //ordenes para el programador
#fuses INTRC                     //oscilador interno
#use delay (clock=4000000)            //Fosc=4Mhz
#use fast_io(a)
#use fast_io(b)
#byte PORTB=0x06                  //definicion del PORTB
#byte STATUS=0x03                  //definicion del STATUS

///PROGRAMA
void main(void)
{
   char cont=0;         //definicion de...
   signed char bcd=-1;      //...variables
   
   set_tris_a (0x00);      //porta salida
   set_tris_b (0x00);      //portb salida
   
   for( ; ; ){   //bucle...   
      output_a(cont);      //enciende led correspondiente
      
      #asm            //modulo asm para manejar bcd->7seg
      movlw   1         ;w <- 1
      addwf   bcd,1      ;bcd <- w + bcd
      movf   bcd,0      ;w <- bcd
      sublw   10         ;10- w
      btfsc   STATUS,2   ;¿se ha llegado a 9?
      goto   igual      ;SI->ve a igual
      swapf   bcd,0      ;NO: w <- parte alta bcd
      goto   muestra      ;ve a muestra
igual:   
      movlw   0         ;w <- 0
      movwf   bcd         ;bcd <- w
muestra:
      movwf   PORTB      ;PORTB <- w
      #endasm            //fin modulo asm para manejar bcd->7seg
      
      delay_ms(450);
      
      #asm            //modulo asm para manejar led"s
      movlw   1         ;w <- 1
      addwf   cont,1      ;cont <- w + cont
      #endasm          //fin modulo asm para manejar led"s
      
      if(cont>3)         //¿se ha mostrado el ultimo led?
         cont=0;         //SI-> reset cont
      }      //...infinito
}

Los perifericos que utilizamos, sus data sheet son:
Para el decodificador 4555:
http://pdf.alldatasheet.com/datasheet-pdf/view/26919/TI/CD4555BE.html
Para el bcd/7seg 74247:
http://pdf.alldatasheet.com/datasheet-pdf/view/27400/TI/SN74247N.html
Hasta pronto!!!Giño
· Nos vemos en los bares!!!!!
· Mi Blog: Aqueronte

Desconectado vszener

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2395
RE: Ejemplitos en C para 16F648A
« Respuesta #176 en: 08 de Noviembre de 2005, 09:03:00 »
Desde este enlace os podeis descargar lo necesario para el programa anterior: C & ASM


PD: Recordar que muchas veces si queremos hacer temporizaciones finas o simplemente ahorrar algo de kb"s de codigo en el .HEX es interesante y necesario incorporar dichas sentencias de codigo en ASM


Suerte!!! :wink:
« Última modificación: 25 de Mayo de 2006, 11:10: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 #177 en: 15 de Noviembre de 2005, 08:05:00 »
Buenas!!!!bien, el programa de hoy se basa en las interrupciones producidas al cambio de estado por uno de los pines del portb dedicados a dicha tarea, los pines que generan interrupcion son <4:7>. El programa en si realiza la secuencia de luces del coche fantastico con 4 led"s hasta que uno de los pines <4:7> cambia de estado del port b, entonces genera una interrupcion y realiza una secuencia de iluminacion de los led"s distinta, aparte cada vez que estemos en una interrupcion se iluminara el led conectado al pin b0....bueno aqui el codigo!:

////////////////////////////////////////////////////////////////////////////////////
//                     VsZeNeR"05      
//                   15/Noviembre/05
//
//   Programa:   Interrupcion debido a cambio de estado del portb <4:7>
//   Version:   0.0
//
//   Dispositivo: PIC 16F648A         Compilador:    CCS vs3.236
//   Entorno IDE: MPLAB IDE v7.22      Simulador:    Proteus 6.7sp3
//
//   Notas: Este programa muestra como funciona la interrupcion de cambio de estado de
//         algunos de los pines <4:7> del portb. Mientras no se pulse ningun boton,
//         ilumina 4 led"s de forma consecutiva y viceversa, cuando se produce un
//         cambio de estado en algunos de los pines del port b <4:7> genera interrupcion.
//         Se ha programado de tal forma que sepa diferenciar que pin genera la interrupcion.
//         Interrupcion:
//                     B4 -> Se produce la secuencia de iluminacion 1 vez
//                     B5 -> Se produce la secuencia de iluminacion 2 veces
//                     B6 -> Se produce la secuencia de iluminacion 3 veces
//                     B7 -> Se produce la secuencia de iluminacion 4 veces
//         Conexiones:      A0 -> led            
//                     A1 -> led
//                     A2 -> led
//                     A3 -> led
//                     B0 -> led         
//                     B4 -> boton      
//                     B5 -> boton        
//                     B6 -> boton          
//                     B7 -> boton   
//////////////////////////////////////////////////////////////////////////////////

#include <16f648a.h>               //pic a utilizar          
#fuses XT,NOWDT,NOPROTECT,PUT,NOLVP      //ordenes para el programador
#fuses INTRC                     //oscilador interno
#use delay (clock=4000000)            //Fosc=4Mhz
#use standard_io(a)
#use fast_io(b)
#byte port_b=0x06                  //declaracion del puerto b

///DECLARACION DE FUNCIONES GLOBALES
void led(void);      //funcion que ejecuta la iluminacion del porta dada la interrupcion

///DECLARACION DE VARIABLES GLOBALES
int last_b;         //variable de almacenar el estado del portb

///LLAMADA FUNCION INTERRUPCION
#INT_RB
void IntPortB4_7( )
{   
   char cont=0;            //contador para la iluminacion de la interrupcion   
      byte changes;             //variable que almacena que pin a realizado la interrupcion
      
      output_high(PIN_B0);      //indicador interrupcion on
      
      changes = last_b ^ port_b;   //changes<-pin que genera la interrupcion

      last_b = port_b;         //last_b=como estaba el portb antes de interrupcion

      if (bit_test(changes,4 )&& !bit_test(last_b,4))      //¿PIN_B4 genera interrupcion?
      led( );                                 //SI -> ejecuta 1 vez funcion led()
    if (bit_test(changes,5)&& !bit_test (last_b,5)){   //¿PIN_B5 genera interrupcion?   
      do{                                    //SI -> ejecuta 2 veces funcion led()
         led( );
         cont++;
         }while(cont<2);
      }
    if (bit_test(changes,6)&& !bit_test (last_b,6)){   //¿PIN_B6 genera interrupcion?
      do{                                    //SI -> ejecuta 3 veces funcion led()
         led( );
         cont++;
         }while(cont<3);
      }
    if (bit_test(changes,7)&& !bit_test (last_b,7)){   //¿PIN_B7 genera interrupcion?
      do{                                    //SI -> ejecuta 4 veces funcion led()
         led( );
         cont++;
         }while(cont<4);
      }
   
   cont=0;            //reset variable cont
   output_low(PIN_B0);   //indicador interrupcion off
}

///PROGRAMA
void main(void)
{
   char led_on=0b0001;            //led a iluminar

   set_tris_b (0b11111110);      //portb entrada menos pin B0 es salida
   
   enable_interrupts(int_rb);      //activar interrupcion rb4:7
   enable_interrupts(GLOBAL);      //activar interrupciones

   do{                        //bucle...
      
      do{      //iluminacion hacia izquierda
         output_a(led_on);
         rotate_left(&led_on,1);
         delay_ms(300);
         }while(bit_test(led_on,3)==0);
      
      do{      //iluminacion hacia derecha
         output_a(led_on);
         rotate_right(&led_on,1);
         delay_ms(300);
         }while(bit_test(led_on,0)==0);
      last_b = input_b( );   
      }while(TRUE);            //...infinito
}
///FUNCION QUE EJECUTA LA SECUENCIA DE ILUMINACION DEBIDO A INTERRUPCION POR EL PORTB4:7
void led(void)
{
   signed char i;               //variable indice
   int leds[2]={0b1001,0b0110};    //led"s
      
   for(i=0;i<2;i++){            //led"s on fuera-dentro
         output_a(leds[ i ]);      //ilumino led"s correspondientes
         delay_ms(150);
         }
      for(i=1;i>-1;i--){         //led"s on dentro-fuera
         output_a(leds[ i ]);      //ilumino led"s correspondientes
         delay_ms(150);
         }
}

Decir, que en este ejemplo se ha programado de tal manera que podamos saber que pin genero la interrupcion, segun sea el pin la secuencia de luces de interrupcion se repetira mas o menos veces hasta terminar y volver al programa principal. La parte del codigo para averiguar el pin que genero la interrupcion esta en la ayuda del compilador(CCS) asi no se pierde tiempo en crear otro....bueno hasta la proxima!!!Giño
· Nos vemos en los bares!!!!!
· Mi Blog: Aqueronte

Desconectado vszener

  • Moderador Local
  • PIC24H
  • *****
  • Mensajes: 2395
RE: Ejemplitos en C para 16F648A
« Respuesta #178 en: 15 de Noviembre de 2005, 08:07:00 »
Desde este enlace os podeis descargar lo necesario del ejemplo anterior: Interrupciones de los pines del portb <4:7>

Ya keda menos para navidad!!! :wink:
« Última modificación: 25 de Mayo de 2006, 11:12:32 por vszener »
· Nos vemos en los bares!!!!!
· Mi Blog: Aqueronte

Desconectado ElRival

  • PIC10
  • *
  • Mensajes: 16
RE: Ejemplitos en C para 16F648A
« Respuesta #179 en: 18 de Noviembre de 2005, 12:38:00 »
Hola a todos !! Tengo una duda, en el ejemplo de "hola mundo" con la pantalla LCD, si tenemos el pic16f877, se haría todo igual ? Y los pines que nos sobran del LCD,que hacemos con ellos ? me refiero a que en el programa pone las conexiones que hay que hacer, pero a  mi me sobran pines, los pondría a masa o a Vcc ???
 
Gracias !!