TODOPIC
Microcontroladores PIC => Lenguaje Basic para microcontroladores PIC => Mensaje iniciado por: Ermola26 en 22 de Noviembre de 2004, 14:52:00
-
Perdona que os moleste, es la primera vez que pregunto en el foro, pero he leido muchos mensajes y he aprendido mucho. Felicidades.
El caso es que tengo una dudilla sobre como usar timer"s con basic. Es más, quisiera saber como se debe programar para usar el timer0 y el timer1 al mismo tiempo, para diferentes aplicaciones, con el mismo pic (pe. el16f876). Por más que busco info no encuentro para basic.
Lo más que encontré fue un código ejemplo del pic simulator ide que usa el timer0 para el refresco de displays, pero si este código lo entiendo a duras penas, cuando intento usar tambien el timer1 acabo como una...aún me queda mucho por saber...
A continuación os expongo el código, a ver si me podeis ayudar para usar además un segundo timer en el código.
Muchisimas gracias de antemano
Dim digit As Byte
Dim digit1 As Byte
Dim digit2 As Byte
Dim mask As Byte
Dim mask1 As Byte
Dim mask2 As Byte
Dim i As Byte
Dim phase As Bit
Symbol d1enable = PORTA.0 "habilita el display de la parte alta del digito
Symbol d2enable = PORTA.1 "habilita el display de la parte baja del digito
TRISB = %00000000 "PORTB y A0, A1, A2 pins como salida
TRISA.0 = 0
TRISA.1 = 0
TRISA.2 = 0
d1enable = False
d2enable = False
mask1 = 0
mask2 = 0
phase = 0
INTCON.T0IE = 1 "habilito interrupcion del timer0
INTCON.GIE = 1 "habilito el registro de interrupciones globales
OPTION_REG.T0CS = 0 "no se, pero necesario
loop:
For i = 0 To 99
digit1 = i / 10 "consigue la parte alta del digito
digit2 = i Mod 10 "consigue la parte baja
TMR0 = 0 "resetea el timer0 para que este no interrumpa antes de conseguir las mascaras
digit = digit1
Gosub getmask "consigue mascara de la parte alta
mask1 = mask
digit = digit2
Gosub getmask "consigue mascara parte baja
mask2 = mask
Gosub show1 "muestra parte alta
Gosub show2 "muestra parte baja
WaitMs 500
Next i
Goto loop
End
On Interrupt "interrupcion del timer0
"el timer0 cuenta 0-255, cuando acaba ejecuta esta rutina
If phase = 0 Then
phase = 1
Gosub show1
Else
phase = 0
Gosub show2
Endif
INTCON.T0IF = 0 "hbilita todas las interrupciones
Resume
getmask:
mask = LookUp(0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f), digit "activacion a nivel alto, catodo comun
"(0,1,2,3,4,5,6,7,8,9) dado un digito (0-9) devuelve en un tipo byte el hex que seria
"2 --> 0x5b --> 0111 1011 --> hgfe dcba
" mask = LookUp(0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f), digit "activacion a nivel bajo, anodo comun
Return
show1:
d2enable = False
PORTB = mask1
d1enable = True
Return
show2:
d1enable = False
PORTB = mask2
d2enable = True
Return
-
Pana ermola26,
Te recomiendo para iniciar en BASIC,(con previos conocimientos en Asm por supuesto y lectura del DS en su TOTALIDAD) este libro: Basic for PIC Microcontrollers
Aqui te pongo un ejemplo sencillo para TMR0(16f84):
symbol LED = PORTB.1 " Led en portb.1
artificio var byte " variable de hasta 255 en valor
TRISB = 0 " Puerto b como salida(todos en cero)
PORTB = 0 "Limpiamos pueto b
INTCON = %00100000 " desactivamos interupciones globales y
" activamos interrupcion por desborde de TMR0(bit 7 y bit 5 de registro intcon)
OPTION_REG = %00000100 " Preescaler a 32(1/32) y activamos pullups
artificio= 0 " variable en cero
TMR0 = 96 " inicia TMR0 en 96(255-96=159 <-- va a contar
"159 veces antes de que surja la interrupcion)
On Interrupt GoTo ISR " declaracion de que cuando ocurra la INT vaya a
"la etiqueta ISR(Interrupt service Routine, rutina
"de servicio de interrupcion)
INTCON = %10100000 " Activamos interupciones globales y activamos
"interrupcion por desborde de TMR0(bit 7 y bit 5
"del registro intcon) desde ahora empieza el conteo
Main: " etiqueta de inicio
If artificio= 200 Then " Si la variable llego a 200
toggle LED " enciende el LED(si estaba en 0 pasa 1 y
"viceversa "toggle" )
artificio= 0 " ..y volvmeos a empezar poniendo en cero la variable
End If " si no, seguimos esperando a que lleguemos a 200
GoTo Main " bucle a la etiqueta de inicio
Disable
ISR:
artificio= artificio+ 1 " en cada paro por interrupcion aumenta variable!!
TMR0 = 96 "reinicializamos el TMR0
INTCON 0.2 = 0 " limpiamos bandera de interrupcion para que
" pueda volver a aocurrir
Resume " regresamos donde nos quedamos
Enable
End
Para el TMR1 es lo mismo , solo cambia el registro(para interrupcion y para conteo) y el TMR1 soporta 16 bytes... es decir que llega muchos mas de 255, jejejeje.
Este y Muchos ejemplos mas se encuentarn en el libro que te indique y es de muchisima ayuda pana
Explicacion de la temporizacion:
El preescaler esta a 1/32 del tiempo, esto es si usas un 16f877 a 4 Mhz
4/fosc = 1mhz como es a 32 el preescaler entonces =31.25 KHZ por lo tanto T=1/f
=0.032 msegundos por cada INCREMENTO DE TMR0, si el tmr0 empieza desde 96 y el limite del TMR0 es de 255(0 a 255)
entonces van a ser 159 pulsos antes de cada interrupcion, esto es:
159 * 0.032= es 5.088 msegundos por cada INTERRUPCION(aprox cada 5 ms) como tiene que incrementar una variable(esto sucede en cada ISR, )hasta 200, y cada interrupcion uscede cada 5 mseg, entonces 5mseg * 200= esto quiere decir que cada SEGUNDO encendera y cada segundo apagara el led.
Como determinar esta temporizaciones?
El artificio de bucle 200 es usado para hacer una temporizacion de 1 segundo ya que el tmr0 no puede contar mas de 255. y el tiempo maximo para la frec maxima seria :1/1mhz= 1msegundo por cada incremento es decir 1ms*255= 255ms(empezando con tmr0=0) por cada interrupcion, por eso es ncesario este artificio.
Aqui otro ejemplo para TMR1:
symbol LED = PORTD.0
artificio var byte
TRISB=%00000000
T1CON=%00000001
PIR1 0# = 0
PIE1= %00000001
artificio= 0
PORTD = 0
On Interrupt GoTo ISR
INTCON = %11000000
Main:
If artificio = 152 Then
toggle LED
artificio= 0
End If
GoTo Main
Disable
ISR:
artificio= artifiio+ 1
PIR1 0# = 0
Resume
Enable
End
Como ves lo indispensable es conocer a fondo el modelo de tu micro, y para esto solo es necesario leer bien el DS del modelo.
Salu2 pana
-
Gracias lager por tu respuesta, en basic y asm estoy bastante puesto por la carrera (informatica), en los pic"s es que comencé hace poquisimo, antes (en la carrera) programé micros de atmel que por lo que estoy viendo es bastante similar...aunque el tema lo tengo algo olvidado...y programaba en "c"
He visto que en este foro predomina la programacion en pbp y simulacion en proteus. He bajado dicho software y comenzado a programar. Espero llegar algun dia a vuestro nivel. Unas preguntillas si me permitiis...
- ¿si uso el timer0 y timer1 en el mismo programa como diferencio quien activó la interrupción?
- ¿puedo obtener un nº con decimales de una operacion, p.e. 32,67?
- en una variable tipo word ¿hay alguna funcion para cambiar el estado de un bit determinado, que indica la posicion una variable? En "c" la funcion sería set_bit(nº del bit a invertir)
-
Por cada interrupción tienes un flag de interrupción en los SFR.
Por ejemplo en TMR0 tienes el flag T0IF. Si usas varias interrupciones en el mismo programa chequeas los flag de interrupción y sabes cual se ha producido. (Leer data sheet para más detalles)
En PBP no tienes variables Float, pero en protón si (amboa son BASIC)
En Protón tienes esta función:
Syntax
SETBIT Variable , Index
Overview
Set a bit of a variable or register using a variable index to the bit of interest.
Operators
Variable - a user defined variable, of type byte, word or dword.
Index - a constant, variable, or expression that points to the bit within Variable
Saludos
Ricky
Madrid-España
-
Muchas gracias, veré el tema del protón, a ver si encuentro algo
-
Pana ermola26,
Para entender realmente los REGISTROS recomiendo que leas el DS como ya te comento el pana Ricky.
Salu2 pana