desktop

Curso de programación de PIC en PICBasic Pro

Hola a todos,

agregando al contador de isaiasjea la interrupción externa b0 y desborde por timer1, junto a un pequeña modificación en la simulación en proteus, es posible convertir el contador en una especie de velocímetro o cuentavueltas segun se necesite, en la simulación parece funcionar pero publico la modificación a ver que opinan ustedes.

Código:
;*******************************************************************************
; Programa: Contador.pbp
; Versión: 1.0
; VELOCIMETRO en base a  Contador de 3 digitos y displays de 7 segmentos (0-999)
; controlando 3 74XS164 de D@rkbytes
;*******************************************************************************
@ DEVICE PIC16F628a    ; Microcontrolador utilizado
; Palabra de configuración
@ DEVICE INTRC_OSC_NOCLKOUT,WDT_OFF,PWRT_ON,BOD_OFF,LVP_OFF
;*******************************************************************************
DEFINE OSC 4                ; Definir que se trabajará con 4MHz.
Include "MODEDEFS.BAS"      ; Incluir definiciones del modo serial

CMCON = 7                    ; Comparadores analógicos OFF
TRISA = %11111100
PORTA = TRISA

TRISB = %00000001
PORTB = 0

; Nombres para los pines
Symbol SCL_Pin  = PORTA.0
Symbol SDA_Pin  = PORTA.1
Symbol T1CKPS1   = T1CON.5      'Preescaler para timer1
Symbol T1CKPS0   = T1CON.4      'Preescaler para timer1
Symbol T1OSCEN   = T1CON.3      'Bit de habilitación del Oscilador 
Symbol TMR1CS    = T1CON.1      'Bit selección clock de trabajo (1=clock externo por portc.0, 0=clock interno)
Symbol TMR1ON    = T1CON.0      'Bit de habilitación para el timer1 (1=On, 0=Off)
Symbol TMR1IE    = PIE1.0       'interrupción por timer1
Symbol TMR1IF    = PIR1.0       'bandera desborde tmr1
Symbol GIE       = INTCON.7
Symbol PEIE      = INTCON.6
Symbol INTE      = INTCON.4
Symbol INTF      = INTCON.1
Symbol INTEDG    = OPTION_REG.6
Symbol LED3      = PORTB.3
;----

; Declaración de variables
KILOMETRAJE VAR WORD
Counter VAR Word
Dsp1    VAR Byte
Dsp2    VAR Byte
Dsp3    VAR Byte
Index   VAR Byte
;{{{{{
 ; Declaración de variables
 T  VAR Byte
 X  VAR Byte
TIMER1 VAR Word
PRECARGA  VAR Word
INTB0   VAR Byte
;}}}}

 PRECARGA=40536             ' Valor obtenido con la calculadora RRPicTimerCalculator  para que salte el timer1 cada 100ms
 TMR1H=PRECARGA.HighByte    ' Precargamos el timer1 inicialmente 
 TMR1L=PRECARGA.LowByte

 
 On Interrupt GoTo interrupcion '  En caso de interrupción ir a subrutina interrupción
 INTCON=%10010000               '  el bit 7 habilita las interrupciones en general
                                '  El bit 4 habilita la  interrupción B.0 
  T1CON=%00001101               '  Timer1 on, incremento por Osc interno  
  

Clear       ; Inicializar variables a 0 (Limpiar RAM)
; Mandar ceros en formato 7 segmentos a los registros de desplazamiento.
ShiftOut SDA_Pin,SCL_Pin,LSBFIRST,[$FC,$FC,$FC]

MainProgram:

    Gosub   Tabla                       ; Ir a las tablas de conversión
    
    GoTo MainProgram
   
   interrupcion: 
                 
  If INTF=1 Then    INTB0=INTB0+1   ' Contamos los giros que da la rueda
  INTE=1                            ' Habilitar la interrupción nuevamente
  INTF=0                            'Borrar la bandera de int B.0
  
  Resume                     ' Retorna al programa donde ocurrió la interrupción 
  Enable                     ' Habilita las interrupciones después del handler 
  END
Tabla:
; Subrutina de conversión para código de 7 segmentos cátodo común.
    Index = Counter DIG 0   ; Tomamos las unidades
    LookUp Index,[$FC,$60,$DA,$F2,$66,$B6,$BE,$E0,$FE,$F6],Dsp1

    Index = Counter DIG 1   ; Tomamos las decenas
    LookUp Index,[$FC,$60,$DA,$F2,$66,$B6,$BE,$E0,$FE,$F6],Dsp2

    Index = Counter DIG 2   ; Tomamos la centenas
    LookUp Index,[$FC,$60,$DA,$F2,$66,$B6,$BE,$E0,$FE,$F6],Dsp3
; Mandamos los datos hacia los registros de desplazamiento.   
    ShiftOut SDA_Pin,SCL_Pin,LSBFIRST,[Dsp1,Dsp2,Dsp3]
    Return

No te quiero pinchar el globo, pero el problema de los velocimetros o cuenta vueltas de "vehiculos" que implementan display 7 segmentos, es malisima la visualizacion de los valores... mas aun cuando hay una histeresis, producto del ciclo o loop del programa... se entiende? no esta mal la idea de implementar la interrupcion por hardware mas un timer...fijate que ya lo mencione anteriormente aca, en un tema similar al tuyo.... :cool:
 
Hola torres.electrico,

Pues es una lástima que no funcione bien, yo nunca lo he implementado y ahora menos lo haré, sinembargo me parece haber visto uno hecho en assembler que funcionaba y tenía un video en youtube, al menos eso parece. En fin, si surge una idea para ese proyecto publicala pues sería fabuloso hacerlo.

Suerte y gracias por el comentario.
 
Hola torres.electrico,

Pues es una lástima que no funcione bien, yo nunca lo he implementado y ahora menos lo haré, sinembargo me parece haber visto uno hecho en assembler que funcionaba y tenía un video en youtube, al menos eso parece. En fin, si surge una idea para ese proyecto publicala pues sería fabuloso hacerlo.

Suerte y gracias por el comentario.

Hola, ya esta planteado con un display 16x2 y hasta la funcion de corte RPM... el problema de los display 7 segmentos, es la visualizacion por ejemplo en una aclerada brusca... si estas contando las RPM, el ojo en vista panoramica no alcanza a distinguir bien los numeros y se leen inconcientemente mas ochos que otra cosa... distinto a mirarlo fijo, ahi se ve una pequeña oscilacion final, pero se puede ajustar con programacion...
Ojo, en elm display LCD no cambia mucho el tema de la oscilacion... pero se ve un poco mas claro :rolleyes:
 
Saludos,

Siguiendo entonces con el tema, para un velocímetro lo mejor es no hacerlo con pic?
Entonces no tenemos precisión de tiempo aunque utilicemos una fuente de clock externa, que se puede hacer ante este problema...

Yo tenía planeado construirme tanto el velocímetro como un pirómetro, al menos por acá se le conoce con ese nombre, utilizado para los hornos de vitrofusión para controlar las curvas de temperatura. Si no existe la manera de tener un tiempo preciso que opciones usar.

Suerte a todos.
 
Tengo que realizar un proyecto con Pic 12f509, pero realizando unas pruebas, con proteus y todo esto.

Al momento de ver los nombres de los pines en proteus, sus "ports" se llaman GP, pero al momento de colocar portgp.0, portgp.1 no funciona. He intentado con porta y portb pero nada ademas en el proteus sale como 12c509 espero tu respuesta
 
Al momento de ver los nombres de los pines en proteus, sus "ports" se llaman GP, pero al momento de colocar portgp.0, portgp.1 no funciona. He intentado con porta y portb pero nada ademas en el proteus sale como 12c509 espero tu respuesta
El nombre del puerto en los PIC12 se llama GPIO
GPIO.0
GPIO.1
GPIO.2
Etc.
Ó GPIO = Valor ; (%Binario, Decimal y $Hexadecimal)
Para la configuración de entradas y salidas, es TRISIO
TRISIO.0
TRISIO.1
TRISIO.2
Etc.
Ó TRISIO = Valor ; (%Binario, Decimal y $Hexadecimal)

En Proteus te sirve igual el 12C509A, la letra F (Flash) significa que el PIC es reprogramable.
Los PIC con letra C, son PIC's OTP (One Time Programmable) solo los puedes grabar una vez.

Suerte.
 
Saludos,Siguiendo entonces con el tema, para un velocímetro lo mejor es no hacerlo con pic?

No no no no :no: Yo no dije en ningun momento que no es mejpor hacerlo con un micropic... Yo lo que mencione, es que implementar un display 7 segmentos para un velocimetro de "automovil", no es lo recomendado por la visualizacion...

Yo tenía planeado construirme tanto el velocímetro como un pirómetro, al menos por acá se le conoce con ese nombre, utilizado para los hornos de vitrofusión para controlar las curvas de temperatura. Si no existe la manera de tener un tiempo preciso que opciones usar.

El pirometro si es factible realizarlo con un display 7 segmentos, ya que la curva de temperatura, no es brusca... Es el proyecto mas sencillo que hay con display 7 segmentos... Estoy navegando desde el telefono celular por que no estoy en mi casa hasta el 19 de marzo, asi que acá te dejo un ejemplo y ma adelante cuando llegue, lo subo acá como corresponde:

Cuando nos vemos en la necesidad de hacer una conversion de Binario a Decimal, picbasic pro inclye un operador que puede ser empleado para este proposito... El operador DIG (mal llamado comando); El operador DIG devuelve el valor de un dígito decimal . Simplemente se le indica el número de dígito a conocer ( 0 - 4 , siendo 0 el primero de la derecha) y ya está.
Dicho de otra manera, para deglosar el valor binario y extraer el valor deseado, hay que especificar con el numero de digito siguiente de la variable a la que vas a extraer el digito... Suponiendo que solo quieres que extraiga el segundo valor, tienes que poner el bit 1 logicamente, y te funcionara, si quieres el tercer valor tienes que poner el bit2 y asi sucesvamente.
Acordate que el operador funciona de la siguiente forma :

Variable = DIG Value , Digit number

_donde variable es es la variable donde guardara el valor extraido
_DIG es el comando
_Value es el valor o la variable de donde vas a extraer el digito
_y numero digito es el BIT que quieres extraer de Value


Un ejemplo sencillo:

B0 = 123 ;setea B0 en 123
B1 = B0 DIG 1 ;setea B1 en 2 (dígito 1 de 123)

Veamos un ejemplo practico, en el cual transformamos el valor binario a decimal empleando el operador DIG.
Los fuses tendrian que modificarlos a sus gusto y aplcacion; A esto sumale que necesitaras un 7447 para decodificar la salida del pic y obtener la multiplexacion a los display 7 segmentos....

Rutina Sensor Temperatura Display 7Segmentos:

DEFINE ADC_BITS 8
DEFINE ADC_CLOCK 3
DEFINE ADC_SAMPLEUS 50

Adc VAR BYTE
Temp VAR WORD
unid VAR BYTE
dece VAR BYTE
cent VAR BYTE

TRISA = 11111
TRISB = 000000
;configuramos todo el puerto B como salida

ADCON1 = 001000 ; Chequea esta configuracion por que varia segun micro

Inicio:
ADCIN 0,Adc
Temp = Adc*150/77
unid = Temp DIG 0
PORTB = unid + 224
Pause 5
dece = Temp DIG 1
PORTB = dece + 208
Pause 5
cent = Temp DIG 2
PORTB = cent + 176
Pause 5
GoTo Inicio

attachment.php


Video:

(extraido de http://www.picbasic.co.uk/forum/con...8Binary-to-Decimal-conversion%29-en-Espa%F1ol ahi podes descargar el hex y archivo proteus)

PD: Estimadisimo amigo moderador.... quiero pensar que no lo vas a tomar como spam el tema...¿verdad? saludos
 
Hola torres,

Ah.... gracias por la aclaración, ya había utilizado el Dig pero con proton, sinembargo ahora recuerdo haber armado algo básico en protoboard y haber tenido problemas en la visualización así como comentas uhm... lo que si me inquieta es como ajustar con más precisión los tiempos pues me parece muy crítico que uno se dé al trabajo de armar algo y si es, quizás en un futuro, para comercializar, salga con fallas o inprecisiones se lleva al traste el esfuerzo, tomemos por ejemplo el código que expuse anteriormente, basado también en ejemplos de aquí y otros espacios como éste, me tomó varios días cuadrarle, digamos que eliminamos en problema de visualización que no es tan grave, entonces que hago si resulta que los datos arrojados son inexactos, a mi forma de ver es un gran dilema.

Bueno, mil gracias por atender estas inquietudes.
 
Hola torres,

Ah.... gracias por la aclaración, ya había utilizado el Dig pero con proton, sinembargo ahora recuerdo haber armado algo básico en protoboard y haber tenido problemas en la visualización así como comentas uhm... lo que si me inquieta es como ajustar con más precisión los tiempos pues me parece muy crítico que uno se dé al trabajo de armar algo y si es, quizás en un futuro, para comercializar, salga con fallas o inprecisiones se lleva al traste el esfuerzo, tomemos por ejemplo el código que expuse anteriormente, basado también en ejemplos de aquí y otros espacios como éste, me tomó varios días cuadrarle, digamos que eliminamos en problema de visualización que no es tan grave, entonces que hago si resulta que los datos arrojados son inexactos, a mi forma de ver es un gran dilema.

Bueno, mil gracias por atender estas inquietudes.

Cuando hablamos de led respectivamente en estos tipos de proyectos, a modo de tips te comento, que para que se visualice bien un display 7 segmentos, no podemos refrezcar la informacion a imprimir en elm display en un tiempo menor a 50ms, ya que es ahi donde arranca el problema de que se ven todos "8" o algunos numeros no se ven bien definidos... al refrezcar en un tiempo menor a los 50ms, lo que obtenemos es un efecto de "persistencia de la visión" y eso es recomendable para otro tipos de proyectos (matrices seriales).
Como la curva de temperatura y o velocidad no es tan brusca y no hay grandes cambios en 50 / 60 ms, no afectaria el valor de la lectura verdadera; O sea, si leemos la temperatura, la convertimos en digital, la procesamos con calculos matematicos lineales y luego la imprimimos, tenemos mas o menos (segun cristal) un trabajo no mayor a los 100ms.. a esto le sumamos una breve pausa cuando esta en estado alto en los puertos, y ya tenemos el delay que neesitamos... obviamente, siempre estamos hablando de tiempos inferiores al segundo.
Si requeris de algo certificado, tienes que tener en cuenta que los comandos / lineas, segun cristal, tienen un tiempo dado de trabajo... eso hay que tenerlo en cuenta cuando uno quiere hacer un cronometro, u cosas que trabajan con tiempos... Igualmente, puedes emplear para estos casos especiales ASM.
exitos
 
'¿que instrucción en pic basic puedo usar para contar 5 minutos y me mantenga en high un puerto' se los agradecería mucho
Instrucción para retardos de 5 minutos no existe.
Puedes usar Pause para retardos en mili segundos y PauseUs para retardos en micro segundos.

Lo que se puede hacer es una rutina para ese propósito.
Aquí adjunto dos ejemplos para generar retardos largos de tiempo.
El primer ejemplo es simplemente para un uso básico, y el segundo es más complejo.
En el segundo utilice activación por interrupción externa del pin RB0 y retardos en ensamblador.
Éste segundo ejemplo es para mostrar como crear subrutinas en código ensamblador con PBP.

Suerte.
 

Adjuntos

  • 16F628A Timer.rar
    16 KB · Visitas: 222
  • 16F628A Timer II.rar
    16.8 KB · Visitas: 209
Instrucción para retardos de 5 minutos no existe.
Puedes usar Pause para retardos en mili segundos y PauseUs para retardos en micro segundos.

Lo que se puede hacer es una rutina para ese propósito.
Aquí adjunto dos ejemplos para generar retardos largos de tiempo.
El primer ejemplo es simplemente para un uso básico, y el segundo es más complejo.
En el segundo utilice activación por interrupción externa del pin RB0 y retardos en ensamblador.
Éste segundo ejemplo es para mostrar como crear subrutinas en código ensamblador con PBP.

Suerte.

hola D@rkbytes me parece excelente tu programa pero quisiera que me digas que función realiza la palabra "REM" cuando escribes esta parte:

Disable ; Deshabilita interrupciones en el controlador
Rem Controlador de la interrupción por RB0
Contar:
INTCON.1 = 0 ; Limpiar flag INTF (Interrupción externa por RB0)
t1 = 1 ; Cargar esta variable con el valor 1
LED_Red = 1 ; Encender el LED rojo
Rem Procedimiento para Retardos de tiempo (By: D@rkbytes)
Loop1: ; Etiqueta para realizar un bucle
t1 = t1 + 1
Rem Dos retardos de 500Ms = 1 segundo
Rem Se puede eliminar el encendido y apagado del LED,
Rem y hacer dos retardos de 500Ms

lo leí muy bien pero no entiendo esta función agradecería que me expliques y perdona la ignorancia:oops:
 
hola D@rkbytes me parece excelente tu programa pero quisiera que me digas que función realiza la palabra "REM" cuando escribes esta parte:

Disable ; Deshabilita interrupciones en el controlador
Rem Controlador de la interrupción por RB0
Rem = Remark (Observación, comentario, nota)
Es como hacer ' Comentario ó ; Comentario.
Solo que al estar en negrita, hace más notorio el comentario.
El compilador omite lo que hay después de Rem
Sirve solamente para hacer comentarios importantes dentro del programa.

Saludos.
 
Hola amigos primero que todo quiero decirles que ya e intentado resolverlo por mi cuenta pero realmente no se como hacerlo lo que quiero saber es como puedo en un pic16f628a con un pulsador ejecutar barias tareas por ejemplo cuando lo pulso una ves ejecuta una tarea cuando lo pulso de nuevo ejecuta otra asi yo estube intentando con el comando on interupt pero no me funciono ojala que puedan ayudarme gracias de ante mano.
 
Hola amigos primero que todo quiero decirles que ya e intentado resolverlo por mi cuenta pero realmente no se como hacerlo lo que quiero saber es como puedo en un pic16f628a con un pulsador ejecutar barias tareas por ejemplo cuando lo pulso una ves ejecuta una tarea cuando lo pulso de nuevo ejecuta otra asi yo estube intentando con el comando on interupt pero no me funciono ojala que puedan ayudarme gracias de ante mano.
Puedes incrementar el valor de una variable y luego usar Select Case

Por ejemplo para 5 programas...
Código:
Programa VAR Byte

Inicio:
    If PORTA.0 = 0 Then
    Pause 250
    If Programa >4 Then Programa = 0
    Programa = Programa +1
    GoSub Programas
    EndIf
    GoTo Inicio

Programas:
    Select Case Programa
    Case 1
    ; Programa 1
    Case 2
    ; Programa 2
    Case 3
    ; Programa 3
    Case 4
    ; Programa 4
    Case 5
    ; Programa 5
    End Select
    Return
Suerte.
 
hermano te agradesco la ayuda pero lo que yo quiero hacer es mas o menos lo siguinte, yo quiero hacer una lampara que funciona con 3 led y lo que quiero es que cada ves que yo precione un boton yo pueda programar tareas como encender 1 y apagar otro o y cuendo precione de nuevo realizar otra tarea y asi no se si me entiendes mira a ver que puedes hacer por mi gracias
 
Así como te mencione anteriormente funciona para lo que quieres hacer.
Pero sube el código que tengas hecho, junto con algún diagrama, para entenderte mejor.
 
Saludos a todos!

Ya hace algun tiempo me compré un programador (el K150) me ha salido bien y todo, la tragedia fue a la hora de programar jaja.

Estoy jugando con PicBasic y el pic 12F629, simplemente me dije "bueno, con algo pequeño está bien" no necesito tantos puertos para los proyectitos que tengo en mente asi que me viene de perlas.

El problema es este: quiero hacer un contador de eventos usando siempre el 12F629, configuré todos los puertos como salidas (excepto el GP3/patita4, que sólo funciona como entrada o MCLR) y con oscilador interno, estoy usando este programa que saqué de un libro:

Trisio=0 ;hace todos los pines del puerto B como salidas
boton VAR gpio.3 ;asigna el nombre de botón al puerto A.1
num VAR BYTE ;crea la variable num con un tamaño de 255
num= 0 ;carga el valor inicial de 0 a la variable num

pulsar:

gpio=num ;indica sacar el valor de num a través del puerto B
IF boton=0 THEN contar ;pregunta si el botón ha sido presionado
GOTO pulsar ;ir a pulsar, mantiene encerrado

contar:
IF boton=0 THEN contar ;espera a que suelte el botón para continuar
PAUSE 200 ; espera de 200 mls para estabilizar el botón
num=num + 1 ;suma 1 a la variable num y el nuevo valor le guarda en num
GOTO pulsar ; volver al principio del programa

END ; fin de la programación

Como habran notado en los comentarios (que no modifiqué) el programa fue diseñado para un pic mas grande, lo que yo quiero y no se como hacer está en la sexta linea, donde asigna a gpio=num (originalmente era PORTB=num) dado que el 12F629 solo maneja 6 puertos, el conteo lo hace como si fueran 6 salidas (lo que no es asi).

Ya en concreto mi duda es: puedo asignarle a la variable "num" solo un rango de puertos y no en general? solo gp0, gp1 y gp2 (patitas 7, 6 y 5 respectivamente)

Gracias!
 
en concreto mi duda es: puedo asignarle a la variable "num" solo un rango de puertos y no en general? solo gp0, gp1 y gp2 (patitas 7, 6 y 5 respectivamente)
Una manera sencilla de hacerlo sería usando la instrucción LookUp
Adjunto un ejemplo para que te des una idea de como se haría.

Suerte.
 

Adjuntos

  • 12F629 LEDs con LookUp.rar
    8.2 KB · Visitas: 208
Saludos a todos!

Ya hace algun tiempo me compré un programador (el K150) me ha salido bien y todo, la tragedia fue a la hora de programar jaja.

Estoy jugando con PicBasic y el pic 12F629, simplemente me dije "bueno, con algo pequeño está bien" no necesito tantos puertos para los proyectitos que tengo en mente asi que me viene de perlas.

El problema es este: quiero hacer un contador de eventos usando siempre el 12F629, configuré todos los puertos como salidas (excepto el GP3/patita4, que sólo funciona como entrada o MCLR) y con oscilador interno, estoy usando este programa que saqué de un libro:

Trisio=0 ;hace todos los pines del puerto B como salidas
boton VAR gpio.3 ;asigna el nombre de botón al puerto A.1
num VAR BYTE ;crea la variable num con un tamaño de 255
num= 0 ;carga el valor inicial de 0 a la variable num

pulsar:

gpio=num ;indica sacar el valor de num a través del puerto B
IF boton=0 THEN contar ;pregunta si el botón ha sido presionado
GOTO pulsar ;ir a pulsar, mantiene encerrado

contar:
IF boton=0 THEN contar ;espera a que suelte el botón para continuar
PAUSE 200 ; espera de 200 mls para estabilizar el botón
num=num + 1 ;suma 1 a la variable num y el nuevo valor le guarda en num
GOTO pulsar ; volver al principio del programa

END ; fin de la programación

Como habran notado en los comentarios (que no modifiqué) el programa fue diseñado para un pic mas grande, lo que yo quiero y no se como hacer está en la sexta linea, donde asigna a gpio=num (originalmente era PORTB=num) dado que el 12F629 solo maneja 6 puertos, el conteo lo hace como si fueran 6 salidas (lo que no es asi).

Ya en concreto mi duda es: puedo asignarle a la variable "num" solo un rango de puertos y no en general? solo gp0, gp1 y gp2 (patitas 7, 6 y 5 respectivamente)

Gracias!

Hola...define los fusibles , oscilador y frecuencia del mismo, así como si vas a usar Gpio.3 como entrada y 0,1,2 como salidas al hacer Trisio debes darle el valor = %1000 o sea en decimal 8(GP.3 como entrada y GP.2,GP.1,GP.0 como salida) limita después de incrementar la variable el valor a representar a decimal 7(%111) que es el máximo valor a representar ya que no dispones mas que de 3 pines. Puede ser mediante una comparación
Código:
IF num = 8 then num = 0
Saludos

Ric.
 
Atrás
Arriba