desktop

Curso de programación de PIC en PICBasic Pro

bueno gente. como lo prometido es deuda y aprovechando la inactividad de este tema, voy a poner una nueva consulta.
si recuerdan hace un par de semanas creo, estaba tratando de diseñar un variador brushless sensorless programado en pbasic. logre hacer funcionar la secuencia anterior que es una especie de arranque a ciegas y me estrelle nuevamente con el proceso de la señal de cruce por cero que a diferencia de mi circuito a base de logica cmos, con micro no me anda jeje... estuve investigando un poco para saber como procesarla con el micro y encontre este documento que trata el tema y que por cierto es muy interesante. y en la pagina 72 del mismo encontre una pista interesante de como hacerlo y dice de la siguiente manera:
El detector de Back EMF esta ahora activado junto con las rutinas de
interrupcion de calculo de velocidad y de conmutacion. Esta ultima se realiza
utilizando la informacion provista por el detector de cruces por cero. (a ese ya lo tengo)
Habilitando uno de los contadores disponibles en el microcontrolador, se
cuenta el tiempo exacto que tarda en llegar el cruce por cero del BEMF
desde la ultima conmutacion del driver, este tiempo se usa para calcular el
retardo hasta la siguiente conmutacion.
lo que veo aqui si no me equivoco, es que se utilizan interrupciones para habilitar el contador(¿TIMER?) y asi calcular el tiempo hasta la siguiente conmutacion. ahora viene mi transgresion a la regla del minimo esfuerzo :D ¿como puedo lograr esto con un pic16f628A y pic basic??? :confused: me dan una idea con algunas lineas de codigo si no es mucho pedir? :D saludosss y gracias por perder el tiempo con mis pavadas e intentar ayudarme :LOL:
 
Última edición:
bueno amigos aca estoy de nuevo y esta vez es para preguntar por las interrupciones. encontre un codigo que lee el estado de los pines rb4 a rb7 por medio de interrupciones y lo he practicado pero me encuentro con que pulsando cualquier puerto rb4,5,6,o 7, da lo mismo. me gustaria saber si me pueden dar una idea de como puedo hacer para diferenciar si la interrupcion se produjo en el rb4 o en el rb5 por ejemplo. aca dejo el codigo que encontre. saludosss
Código:
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
TRISA = %00000000 ' Configura el puerto A como salida.
TRISB = %11110000 ' Configura los 4 bits más significativos como
' entrada.
I VAR Byte ' Declaración de la variable "I" tipo Byte
Symbol LED1 = PORTA.0 ' Alias para el pin RA0
Symbol LED2 = PORTA.1 ' Alias para el pin RA1
On Interrupt GoTo Interrup ' Define el vector de interrupción
INTCON = %10001000 ' habilita la interrupción RB4-RB7
Inicio:
LED1 = 1 ' Enciende el Led 1
Pause 1000 ' Pausa de 1 segundo
LED1 = 0 ' Apaga el Led 1
Pause 1000 ' Pausa de 1 segundo
GoTo Inicio ' Salta a la etiqueta "Inicio"
189
Interrup:
Disable
For I = 1 To 6
LED2 = 1 ' Enciende el Led 2
Pause 1000 ' Pausa de 1 segundo
LED2 = 0 ' Apaga el Led 2
Pause 1000 ' Pausa de 1 segundo
Next I
INTCON = %10001000 ' habilita las interrupciones (GIE=1)
' habilita la interrupción RB4-RB7 (RBIE=1)
' Inicializa la interrupción (RBIF=0)
Resume
Enable
End
 
podrias intentarlo con algo como esto...

Código:
Define Osc 4 ' Define el Oscilador para un Cristal
' de 4 Mhz.
TRISA = %00000000 ' Configura el puerto A como salida.
TRISB = %11110000 ' Configura los 4 bits más significativos como
' entrada.
I VAR Byte ' Declaración de la variable "I" tipo Byte
Symbol LED1 = PORTA.0 ' Alias para el pin RA0
Symbol LED2 = PORTA.1 ' Alias para el pin RA1
On Interrupt GoTo Interrup ' Define el vector de interrupción
INTCON = %10001000 ' habilita la interrupción RB4-RB7
Inicio:
LED1 = 1 ' Enciende el Led 1
Pause 1000 ' Pausa de 1 segundo
LED1 = 0 ' Apaga el Led 1
Pause 1000 ' Pausa de 1 segundo
GoTo Inicio ' Salta a la etiqueta "Inicio"
189
Interrup:
Disable
[B]if portb.4 then .... tu rutina
if portb.5 then .... tu rutina
if portb.6 then .... tu rutina
if portb.7 then .... tu rutina[/B]
For I = 1 To 6
LED2 = 1 ' Enciende el Led 2
Pause 1000 ' Pausa de 1 segundo
LED2 = 0 ' Apaga el Led 2
Pause 1000 ' Pausa de 1 segundo
Next I
INTCON = %10001000 ' habilita las interrupciones (GIE=1)
' habilita la interrupción RB4-RB7 (RBIE=1)
' Inicializa la interrupción (RBIF=0)
Resume
Enable
End
 
ok, gracias lubeck, es lo que estaba pensando. en ese caso las interrupciones no hacen falta. todavia no entiendo bien que diferencia hay entre una interrupcion y un if...then. jeje...
muchas gracias amigo.
saludosss
 
en ese caso las interrupciones no hacen falta. todavia no entiendo bien que diferencia hay entre una interrupcion y un if...then. jeje...

es que son cosas diferentes una interrupcion y una sentencia if, then...

digamos que con la interrupcion el micro esta ejecutando una rutina o bucle... cuando cambia de estado un registro que desencadene una interrupcion en este caso el del puerto b, esa rutina se interrumpe o se desatiende y se ejecuta por decirlo asi una subrutina propia de la interrupcion...

por ejemplo... si yo estoy comiendo plácidamente y en eso suena el telefono, entonces este me interrumpe de lo que estoy haciendo y tengo que contestar la llamada... tons el estar comiendo es el bucle principal, el sonido del telefono es la interrupcion, y el contestar el telefono es la subrutina de la interrupcion...

dentro de esa subrutina de la interrupcion ,ya que fue interrumpido el bucle principal, ya puedes seleccionar con una sentencia if then con cual fue echa la interrupcion....

hago la aclaracion que si hay una sentencia Pause dentro de la bucle principal (como el pause 1000 de tu ejemplo) y se desencadena un interrupcion primero termina el pause y despues pasa a la subrutina de la interrupcion, o lo que es lo mismo un pause no se interrumpe en PBP..
 
Última edición:
Hola muchachos ahora que veo el codigo nunca he manejado interrupciones voy a ponerlo a prueba con un circuito sencillo con el pic12f509, aparte me surge una duda con una parte del código que se para que sirve mas no uso esa exactamente para lograr lo mismo.

es; Symbol LED1 = PORTA.0 ,yo lo hago asi; LED1 var porta.0

afecta en algo, las dos formas son validas?
Ya que si afecta lo tomaría en cuenta para mis códigos...gracias
 
ok, entonces la diferencia es que se gana tiempo con una interrupcion ¿verdad?
Mm, no ...

en realidad una interrupcion se usa o es util porque se interrumpe el software por hardware, es decir que aunque el micro este ocupado en otras cosa se enterara si se efectúa una interrupción. digamos que si no utilizas las interrupciones y esta ocupado el micro en algo y se presiona o se modifica el puertob, puede que ni se entere si lo haces por software.

no hay diferencia entre una y otra porque tienen fines distintos.
 
jeje... bueno, entonces digamos que utilizar interrupciones resulta ser mucho mejor que un simple IF THEN. perdon por ser tan bestia jajaja...
EDIT:
no vayan a pensar algo asi... :LOL:
 
Última edición:
Yo diria que depende de lo que se necesite y como lo ocupes....y no siempre es necesario utilizarlas

digamos que si yo tengo esto...

Código:
on interrupt goto subint

main

for I=1 to 100
 toggle porta.0
next I
goto main

subint:
Disable
 toggle portb.1
INTCON = %10001000 
Resume
Enable
End

si te fijas nada tiene que ver con los if then, pero me sirve para interrumpir una sentencia For Next
y vaya se pueden poner un sin fin de algoritmos en los que sea necesario y en los que no...

(el codigo que puse es solo ilustrativo le faltan mas cosas para funcionar :D)
 
Una cosa que note es que el pic12f509 al parecer no tiene interrupciones, otra yo conozco las interrupciones y se que hay varias y como funcionan mas no las he aplicado a ningún programa ya que no he tenido la necesidad, una interrupción según mi concepto es como una parada de emergencia, la cual actua de inmediato, mas hay diferentes modos de aplicarlo de echo se puede encontrar bastante al respecto en internet.

1. - Mediante una accion interna. El desbordamiento de la Pila (Stack) por una operacion indebida, por ejemplo:
Al completarse la escritura de datos en una EEPROM.
Por desbordamiento del registro TMR0 al rebasar el valor 255 (FFh) a 0.

2. - Mediante una accion externa, la mas util. Al producirse un cambio del nivel en uno de sus pines por una accion externa.
Estando en el modo de reposo (SLEEP), un cambio de nivel en el pin RB0/INT .
Un cambio de nivel en uno de los pines RB4 a RB7 estando configurados como entrada.

Eso por ejemplo, tratando de hacer interrupciones con el 12f509 pero al parecer con el picbasic pro no se puede, si alguien sabe algo al respecto me avise gracias.

Al no poder hacerlo por interrupciones, la idea era que en cualquier parte del programa al yo presionar un botón este dejara lo que esta haciendo y se fuera una sub-rutina y ejecutara el incremento de una variable y dependiendo del valor saltara a otra sub-rutina, luego pensé que no tenia mucha lógica hacerlo interrupción ya que al terminar la interrupción este volvería donde quedo antes de la interrupción, asi que lo que hice fue utilizar el call en cada parte del programa calculando que cada cierta cantidad de instrucciones ejecutadas me diera aproximadamente 200ms y luego ejecutar el call del pin del boton y de esa forma hacer un tipo de interrupción sin necesidad de volver al ultimo estado antes de la interrupción si no continuar con el resto del código.

Hice un ejemplo con el 12f629 que anexo esta funcionando bastante bien, ahora si ven que se puede mejorar avísenme y les agradecería.:apreton:
 

Adjuntos

  • secuenciador.rar
    16.3 KB · Visitas: 239
Última edición:
gracias estoy practicando con camtasia les dejo un vídeo de la explicación del circuito es uno de mis primeros vídeos así que disculpen si no se oye muy bien y si me equivoque al expresarme...:rolleyes:


saludosss
 
hola amigos tengo un problema (cuando no :D ) estoy tratando de implementar un programa muy simple en un pic12f675, se trata de hacer titilar un led en el gpio.0. lo he simulado en proteus y funciona, pero en la realidad no me funciona... aca dejo el programita para ver si alguno de uds me da una idea de que puedo estar haciendo mal. ¿me ayudan??? gracias :)
saludosss
Código:
@ DEVICE pic12F675, intrc_osc_noclkout, wdt_off, pwrt_on, mclr_off, bod_off, protect_off


adcon0=0     '  desactiva el ADC
ansel=0 '  digital
cmcon=7'comparador apagado
trisio=0
VRCON=0 
define OSCCAL_1K 
     L1 VAR GPIO.0
     inicio:
     high L1
     pause 500
     low L1
     pause 500
     goto inicio
 
estas utilizando un oscilador externo? Yo desactivaría el pwrt lo digo por a mi me a dado bastantes problemas, es una opcion en caso de que haya un bajo de voltaje el pic se resetea y eso es fastidioso si se esta probando en un protoboard ya que normalmente siempre hay muchas interferencias, no necesitas desactivar el adc yo por experiencia no lo he utilizado y funciona sin desactivarlo, el seteo del osccal creo le falta un 1 al final segun el manual, "DEFINE OSCCAL_1K 1", por otro lado no veo la frecuencia de trabajo del pic, si es interno seria "DEFINE OSC 4".Bueno eso de momento te dejo un ejemplo de como lo colocaría yo:


@ DEVICE pic12F675, intrc_osc, wdt_off, pwrt_on, mclr_off, bod_off, protect_off

DEFINE OSC 4
DEFINE OSCCAL_1K 1

CMCON = 7
TRISIO=%00001000

L1 VAR GPIO.0

INICIO:
high L1
pause 500
low L1
pause 500
goto INICIO

Aparte hay algún motivo especial para setear el pic?
 
Aparte hay algún motivo especial para setear el pic?

hola reyvilla, gracias por responder. te comento que estoy tratando de utilizar el oscilador interno del pic y no, la verdad solo intento hacer que el led encienda y se apague pero no logro hacer que funcione en el montaje real. no soy un experto en esto, solo hice copi paste de la configuracion de otro programita para el mismo pic voy a desactivar el pwrte en el codigo que has dejado, lo voy a compilar y aver que sucede jeje. luego te aviso que sucedio...
saludosss
 
dale espero lo pruebes, el "DEFINE OSCCAL_1K 1" es para hacer un seteo del oscilador interno del pic, seria como calibrar el pic o algo así, no esto muy claro de su uso, para utilizar el oscilador interno, dentro de la configuración de los fuses colocas nada mas " intrc_osc" y luego lo defines "DEFINE OSC 4" y listo no necesitas mas nada.Espero por tus pruebas...saludoss

PD:Ya vi la razón de esa definición, y si tiene que ver con la calibración del oscilador interno, resulta los pic con oscilador interno hay que antes de programar anotar el valor del osccal eso para que en caso de que se borre del pic poder programarselo luego. Esa instruccion segun el link que coloco es para que el PBP lo mantenga y segun mejora la sincronizacion. Revisalo y ya veras como es la cosa...saludoss

http://www.ucontrol.com.ar/forosmf/programacion-en-basic/oscilador-interno-pic12f629/
 
Última edición:
bueno amigo. compile y probe el codigo que me dejaste y funciona pero aveces, al parecer seria problema de calibracion del oscilador interno. yo uso un jdm para cargar mis pics, por lo general utilizo pic16f628 y no tengo problemas. pero parece que con los pic12fxx, existe el problema de que ese programador o mejor dicho, icprog o winpic, le borra el valor de calibracion de fabrica y lo sustituye poniendo uno por defecto con lo que el oscilador interno se vuelve inestable y los programas no funcionan correctamente. encontre un firm aqui para recalibrar el oscilador interno del pic. se vale de un circuito con el que supuestamente se recalibra el oscilador intero, lo voy a probar mañana. de ultima, voy a comprar el pic y esta vez voy a tener la precaucion de copiar la linea donde sale el valor osccal y pegarla debajo del pic jeje... hasta que consiga un PIC18F2550 para hacerme un pickit usb, dicen que con ese programador no existe este problema :)
despues te cuento como me fue... gracias, saludos.
 
D@rio

En Córdoba Capital y en una empresa de estaba sobre la calle Deheza y ahora se mudo se conseguia el 18F2550, cualquier cosa te la paso por MP.

Saludos, JuanKa.-
 
Atrás
Arriba