Librería para multitarea en GCBasic.

Ver el tema anterior Ver el tema siguiente Ir abajo

Librería para multitarea en GCBasic.

Mensaje por Pikitin el Miér 25 Mar 2009 - 2:29

Después de un tiempo haciendo algunas pruebas de programación multitarea, he visto que en cuanto tienes 6 o 7 tareas ejecutándose el programa se convierte en un lio de variables, contadores, flags, interrupciones, etc.

Para evitar esto y mantener el programa lo más sencillo posible y evitar errores a la hora de asignar contadores, flags, etc. he escrito una pequeña librería que se encarga de todo ese trabajo pesado.

Tal y como está ahora, se pueden ejecutar hasta 8 tareas "simultaneas", aunque se puede aumentar el número si es necesario.

La base de tiempo está establecida en 10 ms, independientemente de la velocidad de reloj, aunque con velocidades "raras" puede no ser muy exacto, pero debería funcionar bién con 4, 8,10,20 MHz.
La base de tiempo está optimizada para reloj de 4 MHz, pero en el archivo hay instrucciones para optimizarla a otras velocidades, aún así el error con otros relojes es de algunos us cada 10 ms, osea que no hay porqué preocuparse a no ser que se necesite mucha precisión.

IMPORTANTE:
Esta librería usa el Timer0, por lo que no se puede usar para otros fines.

Tanto en el archivo de la librería: multitasking.h, como en el ejemplo: multitask_example.gcb hay explicaciones sobre el uso de multitareas.

Los archivos se pueden descargar directamente de aquí (con comentarios en ingles):
https://sourceforge.net/project/showfiles.php?group_id=247157&package_id=301652&release_id=653073

Aquí se puede ver el código con comentarios en español:
Esta es la librería: multitasking.h:

Código:
'_______________________________________________________________________
'
'
'                      Multitasking functions
'
'_______________________________________________________________________
'
'
'    multitasking routines for the GCBASIC compiler
'    2009 Santiago Gonzalez
'
'    This library is free software; you can redistribute it and/or
'    modify it under the terms of the GNU Lesser General Public
'    License as published by the Free Software Foundation; either
'    version 2.1 of the License, or (at your option) any later version.
'    This library is distributed in the hope that it will be useful,
'    but WITHOUT ANY WARRANTY; without even the implied warranty of
'    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
'    Lesser General Public License for more details.
'    You should have received a copy of the GNU Lesser General Public
'    License along with this library; if not, write to the Free Software
'    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
'
'_______________________________________________________________________
'
'
'Notas:
'
'La base de tiempo está fijada en 10 ms, pero puede ser cambiada
'reconfigurando el prescaler de Timer0 y el contador: "timer0_val"
'en las primeras lineas de la función: Init_Multitask
'
'La base de tiempo está optimizada para reloj de 4MHz.
'para optimizarla a otros valores de reloj
'editar la primera liea de la función: Interrupt_Timer0.
'
'Actualmente un máximo de 8 tareas están soportadas.
'para aumentar hasta 16 tareas, declarar la variable "flags" as word
'en la función: Init_Multitask
'y añadir los elementos propios de cada tarea en todas las funciones:
'#ifdef Task9...#endif,....
'editando valores con los nuevos nº de tareas (¡cuidado con los nº de flag!)
'
'El valor máximo para el periodo de tareas: "time_Task(n)" es 255
'Para periodos más largos declarar "cont_Task(n)"
'y "time_Task(n)"  as word en la funcion: Init_Multitask.
'Pero es desable tener variables tipo byte para un código lo más corto posible.
'
'_______________________________________________________________________
 
'Initialisation routine
#startup Init_Multitask

Sub Interrupt_Timer0

    wait 7 us 'Valor optimizado en us = 17-10/(ChipMhz/4)

    TMR0 = timer0_val                    'inicializar contador de timer0

    #ifdef Task1
        cont_Task1 += 1                  'incrementar contador de tarea
        if cont_Task1 >= time_Task1 then  'si el periodo de tarea es alcanzado
            cont_Task1 = 0              'reiniciar contador de tarea
            flag_Task1 = 1              'subir flag de tarea
        End if
        #ifdef Run_Task1
            Do_Task1
        #endif
    #endif

    #ifdef Task2
        cont_Task2 += 1
        if cont_Task2 >= time_Task2 then
            cont_Task2 = 0
            flag_Task2 = 1
        End if
        #ifdef Run_Task2
            Do_Task2
        #endif
    #endif

    #ifdef Task3
        cont_Task3 += 1
        if cont_Task3 >= time_Task3 then
            cont_Task3 = 0
            flag_Task3 = 1
        End if
        #ifdef Run_Task3
            Do_Task3
        #endif
    #endif

    #ifdef Task4
        cont_Task4 += 1
        if cont_Task4 >= time_Task4 then
            cont_Task4 = 0
            flag_Task4 = 1
        End if
        #ifdef Run_Task4
            Do_Task4
        #endif
    #endif

    #ifdef Task5
        cont_Task5 += 1
        if cont_Task5 >= time_Task5 then
            cont_Task5 = 0
            flag_Task5 = 1
        End if
        #ifdef Run_Task5
            Do_Task5
        #endif
    #endif

    #ifdef Task6
        cont_Task6 += 1
        if cont_Task6 >= time_Task6 then
            cont_Task6 = 0
            flag_Task6 = 1
        End if
        #ifdef Run_Task6
            Do_Task6
        #endif
    #endif

    #ifdef Task7
        cont_Task7 += 1
        if cont_Task7 >= time_Task7 then
            cont_Task7 = 0
            flag_Task7 = 1
        End if
        #ifdef Run_Task7
            Do_Task7
        #endif
    #endif

    #ifdef Task8
        cont_Task8 += 1
        if cont_Task8 >= time_Task8 then
            cont_Task8 = 0
            flag_Task8 = 1
        End if
        #ifdef Run_Task8
            Do_Task8
        #endif
    #endif

End Sub


Sub Init_Multitask

    dim flags as byte                  'byte para 8 flags (as word para 16 flags)

    #define timer0_val 256-39*(ChipMhz/4)

    InitTimer0 Osc, PS0_1/256          'Timer0 configurado para 10 ms

    On Interrupt Timer0Overflow Call Interrupt_Timer0

    #ifdef Task1
        dim cont_Task1 as byte          'contador de tarea
        dim time_Task1 as byte          'Periodo de tarea
        #define flag_Task1 flags.0      'flag de tarea
    #endif

    #ifdef Task2
        dim cont_Task2 as byte
        dim time_Task2 as byte
        #define flag_Task2 flags.1
    #endif

    #ifdef Task3
        dim cont_Task3 as byte
        dim time_Task3 as byte
        #define flag_Task3 flags.2
    #endif

    #ifdef Task4
        dim cont_Task4 as byte
        dim time_Task4 as byte
        #define flag_Task4 flags.3
    #endif

    #ifdef Task5
        dim cont_Task5 as byte
        dim time_Task5 as byte
        #define flag_Task5 flags.4
    #endif

    #ifdef Task6
        dim cont_Task6 as byte
        dim time_Task6 as byte
        #define flag_Task6 flags.5
    #endif

    #ifdef Task7
        dim cont_Task7 as byte
        dim time_Task7 as byte
        #define flag_Task7 flags.6
    #endif

    #ifdef Task8
        dim cont_Task8 as byte
        dim time_Task8 as byte
        #define flag_Task8 flags.7
    #endif

End Sub


#ifdef Task1
    Sub Do_Task1
        if flag_Task1 on then
            set flag_Task1 off
            call Task1
        End if
    End Sub
#endif


#ifdef Task2
    Sub Do_Task2
        if flag_Task2 on then
            set flag_Task2 off
            call Task2
        End if
    End Sub
#endif


#ifdef Task3
    Sub Do_Task3
        if flag_Task3 on then
            set flag_Task3 off
            call Task3
        End if
    End Sub
#endif


#ifdef Task4
    Sub Do_Task4
        if flag_Task4 on then
            set flag_Task4 off
            call Task4
        End if
    End Sub
#endif


#ifdef Task5
    Sub Do_Task5
        if flag_Task5 on then
            set flag_Task5 off
            call Task5
        End if
    End Sub
#endif


#ifdef Task6
    Sub Do_Task6
        if flag_Task6 on then
            set flag_Task6 off
            call Task6
        End if
    End Sub
#endif


#ifdef Task7
    Sub Do_Task7
        if flag_Task7 on then
            set flag_Task7 off
            call Task7
        End if
    End Sub
#endif


#ifdef Task8
    Sub Do_Task8
        if flag_Task8 on then
            set flag_Task8 off
            call Task8
        End if
    End Sub
#endif


Y este es el ejemplo:
Código:
'_______________________________________________________________________
'
'
'                      Multitasking example
'
'_______________________________________________________________________
'
'
'    multitasking example for the GCBASIC compiler
'    2009 Santiago Gonzalez
'
'    This program is free software; you can redistribute it and/or
'    modify it under the terms of the GNU Lesser General Public
'    License as published by the Free Software Foundation; either
'    version 2.1 of the License, or (at your option) any later version.
'    This library is distributed in the hope that it will be useful,
'    but WITHOUT ANY WARRANTY; without even the implied warranty of
'    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
'    Lesser General Public License for more details.
'    You should have received a copy of the GNU Lesser General Public
'    License along with this library; if not, write to the Free Software
'    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
'
'_______________________________________________________________________
'
'Notas:
'
'**** ¡¡¡Copiar multitasking.h a "../GCBASIC/include" !!! ****
'
'Hay dos maneras de ejecutar las tareas:
'
' 1)- Dentro del bucle principal:
'  En este ejemplo, las tareas Task2 y Task3.
'  La prioridad de cada tarea está determinada por el orden
'  en que son llamadas en el bucle principal,
'  icluyendo cualquier otra rutina presente en el bucle principal.
'
' 2)- Dentro de la rutina de interrupciones:
'  En este ejemplo, Task1 es ejecutada de esta manera.
'  La prioridad está determinada por el número de tarea, esto es:
'  Task1 es la más prioritaria, y Task8 la menos.
'  Como estas tareas está dentro de interrupciones,
'  serán ejecutadas incluso si otra rutina está corriendo
'  en el bucle principal. Osea estas tareas tienen prioridad sobre
'  las tareas ejecutadas en el bucle principal.
'  Este modo debería ser usado con rutinas cortas
'  para evitar la superposición de interrupciones.
'
'Entonces, en este ejemplo las prioridades de todas las tareas son estas:
'  1º Task1
'  2º ReadAD
'  3º Task3
'  4º Task2
'
'Este ejemplo hará parpadear 3 leds conectados a PORTB.0, PORTB.1, PORT.2
'Led1 cambiará de estado cada 500 ms y Led2 cada 300 ms.
'Led3 parpadeará con un periodo determinado por el valor ADC leido.
'


'-------------------------- CONFIGURAR MICRO ----------------------------
'------------------------------------------------------------------------

#chip 16F876A, 4        'modelo de pic y velocidad de reloj

#config HS_OSC, WDT_OFF, LVP_OFF, PWRTE_ON


'---------------------- DEFINICIONES DE TAREAS --------------------------
'------------------------------------------------------------------------

#include multitasking.h

#define Task1 led1      'define subrutina de tarea
#define Run_Task1      'Ejecuta tarea dentro de interrupciones
time_Task1 = 50        'x10 ms = la tarea se ejecutará cada 500 ms

#define Task2 led2
time_Task2 = 30

#define Task3 led3

'---------------------------- PRINCIPAL ---------------------------------

'------------------------------------------------------------------------

Dir PORTA.0 in
Dir PORTB out

do
    time_Task3 = ReadAD(AN0)    'Establece periodo de lED3 al valor ADC leido
    wait 1 ms                  'No se porqué, pero sin esto adc no funciona bien
    Do_task3
    Do_Task2

loop


'----------------------- SUBRUTINAS DE TAREAS ---------------------------
'------------------------------------------------------------------------

Sub led1
    if PORTB.0 on then
        set PORTB.0 off
    else
        set PORTB.0 on
    End if
End Sub

Sub led2
    if PORTB.1 on then
        set PORTB.1 off
    else
        set PORTB.1 on
    End if
End Sub

Sub led3
    if PORTB.2 on then
        set PORTB.2 off
    else
        set PORTB.2 on
    End if
End Sub

Pikitin
veterano
veterano

Mensajes : 623
Fecha de inscripción : 26/11/2008

http://linuxmicros.blogspot.com/

Volver arriba Ir abajo

Re: Librería para multitarea en GCBasic.

Mensaje por Pikitin el Vie 5 Jun 2009 - 1:07

Hay una segunda versión de esta librería con algunas mejoras:

- Se puede (se debe) fijar la base de tiempo en el programa de usuario. De esta forma es mucho más facil crear "multitarea" con distintas bases de tiempo.

- Se puede fijar la duración de cada tarea directamente en unidades de tiempo en vez de en ciclos: us, ms, s. Así se evitan cálculos pesados y no es necesario cambiar la duración de las tareas si se cambia la base de tiempo.

- Hasta 16 tareas normales y 8 tareas largas (LTask), estas LTasks pueden tener un periodo de hasta 65535 veces la base tiempo, con lo que se pueden coseguir periodos de hasta una hora con reloj de 4 Mhz y 65535 us de base de tiempo.
Las tareas normales hasta 255 veces la base de tiempo.

Ahora resulta mucho más facil de usar, evitándose cálculos engorrosos; solo hay que tener en cuenta los límites máximos dependiendo de la velocidad de reloj que se use.

Se puede descargar la librería aquí: multitasking.h

Se agradece cualquier información sobre fallos, sugerencias, etc.

Saludos.

Pikitin
veterano
veterano

Mensajes : 623
Fecha de inscripción : 26/11/2008

http://linuxmicros.blogspot.com/

Volver arriba Ir abajo

Re: Librería para multitarea en GCBasic.

Mensaje por Pikitin el Jue 29 Oct 2009 - 9:56

Otro ejemplo, usando multitasking para generar pwm.

8 leds conectados al puerto B de un 16F627, lo mejor ver un video del efecto en una simulación de ktechlab:

http://piclinux.sourceforge.net/files/videos/rot-led.ogg

Código:
'-------------------------- CONFIGURE MICRO -----------------------------
'------------------------------------------------------------------------
#chip 16F627, 4        'modelo de pic y velocidad de reloj
#config HS_OSC, WDT_OFF, LVP_OFF, PWRTE_ON

'------------------------ TASK's DEFINITIONS ----------------------------
'------------------------------------------------------------------------
#include <multitasking.h>

#define niveles 20                          'Niveles de luz (resolucion de pwm)

#define base_time 500                      'Tiempo base en us

#define Task1 rota_leds
#define Task1_us 255*base_time              'Periodo de tarea en us

#define Task2 calc_output
#define Task2_us base_time       

#define Task7 pwm_period                    'Periodo pwm
#define Run_Task7                          'Run Task inside interrupt subroutine
#define Task7_us niveles*base_time          'Periodo-pwm = resolucion * base time

#define LTask1 life_led                    'LTask es para tareas de periodo largo
#define LTask1_ms 500                      'usar LTask cuando periodo > base_time*255

'----------------------------- REGs DEFs --------------------------------
'------------------------------------------------------------------------
#define total_regs  7
#define registro    77 - total_regs

'------------------------------- MAIN -----------------------------------
'------------------------------------------------------------------------
TRISA = 0
TRISB = 0

for contador = 0 to total_regs
    FSR = registro + contador              'Establece valores iniciales
    INDF = (contador*contador)/3

    puerto = puerto xor 255                'parpadea todo los leds
    wait 200 ms
Next

wait 500 ms

do                  'Bucle principal
    Do_Task1
    Do_Task2
    Do_LTask1
loop

'---------------------------- TASK's SUBs -------------------------------
'------------------------------------------------------------------------
Sub rota_leds 
    for contador = 0 to total_regs
        FSR = registro + contador
        prev = INDF
        INDF = regprev
        regprev = prev
    Next
End Sub

Sub calc_output
        lectura = 0
        FSR = registro
        if INDF > cont_Task7 then lectura.0 = 1
        FSR += 1
        if INDF > cont_Task7 then lectura.1 = 1
        FSR += 1
        if INDF > cont_Task7 then lectura.2 = 1
        FSR += 1
        if INDF > cont_Task7 then lectura.3 = 1
        FSR += 1
        if INDF > cont_Task7 then lectura.4 = 1
        FSR += 1
        if INDF > cont_Task7 then lectura.5 = 1
        FSR += 1
        if INDF > cont_Task7 then lectura.6 = 1
        FSR += 1
        if INDF > cont_Task7 then lectura.7 = 1

        PORTB = lectura
End Sub

Sub pwm_period                  'esta tarea solo es necesaria para tener cont_task7
    nop
End Sub

Sub life_led
    PORTA = PORTA xor 1          'invierte salida RA0
End Sub

Pikitin
veterano
veterano

Mensajes : 623
Fecha de inscripción : 26/11/2008

http://linuxmicros.blogspot.com/

Volver arriba Ir abajo

Re: Librería para multitarea en GCBasic.

Mensaje por Pikitin el Vie 30 Oct 2009 - 9:24

Otro ejemplito: voltimetro simple 0-5v
Y un video de la simulación: http://piclinux.sourceforge.net/files/videos/volt0.ogg

Código:
'________________________________________________________________________________
'
'                        Voltimetro 0-5V
'________________________________________________________________________________
'

#chip 16F876a, 4'MHz

#config HS_OSC, WDT_OFF, LVP_OFF, PWRTE_ON

#include <adc-87X.h>
#include <multitasking.h>

'________________________________________________________________________________
'______ TAREAS __________________________________________________________________

#define base_time 10000        'base de tiempo = 10.000 us = 10 ms

#define Task1 lectura_ADC      'Lectura ADC
#define Task1_ms 200

#define Task2 print_display    'Muestra valores en 7seg
#define Task2_ms 10

#define Task7 led_testigo      'Led parpadeante, testigo de funcionamiento
#define Task7_ms 500

'________________________________________________________________________________
'______ PRINCIPAL _______________________________________________________________

TRISA = 1
TRISB = 0
TRISC = 0

display = 1

adc_conf8 FOSC/32, A1_R0    'Cofigura ADC
adc_open CH0                'Abrir canal 0
 
do                          'Bucle principal
    Do_Task1
    Do_Task2
    Do_Task7

loop

'________________________________________________________________________________
'_______ SUBRUTINAS ____________________________________________________________

Sub lectura_ADC
    lectura = adc_read8/5
    digito1 = lectura/10            'unidad (entero de la división)
    digito2 = SysCalcTempX          'decimal (módulo de la división)
End Sub

Sub print_display
    if display = 1 then
        valor(digito1)
        movwf PORTB
        PORTC.4 = 0
        PORTC.5 = 1
        display = 2
    else
        valor(digito2)
        movwf PORTB
        PORTC.4 = 1
        PORTC.5 = 0
        display = 1
    End if
End Sub

Sub led_testigo
    PORTC = PORTC xor 1            'invierte RC0
End Sub

Sub valor(lectu) #NR
    asm pagesel valor
    PCL += lectu
    retlw    63
    retlw    6
    retlw    91
    retlw    79
    retlw    102
    retlw    109
    retlw    125
    retlw    7
    retlw    127
    retlw    103
End Sub

Pikitin
veterano
veterano

Mensajes : 623
Fecha de inscripción : 26/11/2008

http://linuxmicros.blogspot.com/

Volver arriba Ir abajo

Re: Librería para multitarea en GCBasic.

Mensaje por maigke el Sáb 7 Nov 2009 - 1:25

Hola que tal!

Esta muy bueno el gcbasic!
ya lo estoy probando con pikdev para programar y gedit como IDE para programar
Jugando un poco con la rutina que muestras con la multitarea funca muy bien para el
micro que expones, sin embargo veo que no me funciona para un pic18f2550

y me manda la siguiente lista de errores

Great Cow BASIC (0.9 12/8/2009)

Compilando /home/mike/Documentos/GCBasic/rot-led.bas ...
Hecho

Ensamblando programa ...
/home/mike/Documentos/GCBasic/rot-led.asm:283:Error [113] Symbol not previously defined (OPTION_REG).
/home/mike/Documentos/GCBasic/rot-led.asm:283:Error [113] Symbol not previously defined (OPTION_REG).
/home/mike/Documentos/GCBasic/rot-led.asm:285:Error [113] Symbol not previously defined (OPTION_REG).
/home/mike/Documentos/GCBasic/rot-led.asm:285:Error [113] Symbol not previously defined (OPTION_REG).

Hecho.

la modificacion que hice y que me funciono para encender y apagar un led fue la siguiente
'-------------------------- CONFIGURE MICRO -----------------------------
'------------------------------------------------------------------------
#chip 18F2550, 20 'modelo de pic y velocidad de reloj


'------------------------ TASK's DEFINITIONS ----------------------------
'------------------------------------------------------------------------
#include

#define niveles 20 'Niveles de luz (resolucion de pwm)

como verás es lo mismo. solo cambie la info del chip, por lo fuses no me preocupo, pues ya lo probe antes asi con otro programa muy sencillo y si jala tal cual esta (Ya lo probe de forma física )

Código:

' led que parpadea
#chip 18F2550, 20  ' modelo del procesador y velocidad del reloj

#define led PORTB.6

main:
    TRISB=0
    PORTB = 0

    led =1
    wait 1000 ms
    led = 0
    wait 1000 ms
goto main


el asm que me tira este código es el siguiente:
Código:

;Program compiled by Great Cow BASIC (0.9 12/8/2009)
;Need help? See the GCBASIC forums at http://sourceforge.net/forum/?group_id=169286,
;check the documentation or email w_cholmondeley@users.sourceforge.net.

;********************************************************************************

;Set up the assembler options (Chip type, clock source, other bits and pieces)
 LIST p=18F2550, r=DEC
#include
 CONFIG WDT=OFF, LVP=OFF, MCLRE=OFF, FOSC=HS

;********************************************************************************

;Set aside memory locations for variables
DELAYTEMP    EQU    0
DELAYTEMP2    EQU    1
SysWaitTempMS    EQU    2
SysWaitTempMS_H    EQU    3

;********************************************************************************

;Vectors
    ORG    0
    bra    BASPROGRAMSTART
    ORG    8
    retfie

;********************************************************************************

;Start of program memory page 0
    ORG    12
BASPROGRAMSTART
;Call initialisation routines
    rcall    INITSYS

;Start of the main program
MAIN
    clrf    TRISB,ACCESS
    clrf    PORTB,ACCESS
    bsf    PORTB,6,ACCESS
    movlw    232
    movwf    SysWaitTempMS,ACCESS
    movlw    3
    movwf    SysWaitTempMS_H,ACCESS
    rcall    Delay_MS
    bcf    PORTB,6,ACCESS
    movlw    232
    movwf    SysWaitTempMS,ACCESS
    movlw    3
    movwf    SysWaitTempMS_H,ACCESS
    rcall    Delay_MS
    bra    MAIN
BASPROGRAMEND
    sleep
    bra    $

;********************************************************************************

Delay_MS
    incf    SysWaitTempMS_H, F,ACCESS
DMS_START
    movlw    227
    movwf    DELAYTEMP2,ACCESS
DMS_OUTER
    movlw    6
    movwf    DELAYTEMP,ACCESS
DMS_INNER
    decfsz    DELAYTEMP, F,ACCESS
    bra    DMS_INNER
    decfsz    DELAYTEMP2, F,ACCESS
    bra    DMS_OUTER
    decfsz    SysWaitTempMS, F,ACCESS
    bra    DMS_START
    decfsz    SysWaitTempMS_H, F,ACCESS
    bra    DMS_START
    return

;********************************************************************************

INITSYS
    clrf    BSR,ACCESS
    clrf    TBLPTRU,ACCESS
    bcf    ADCON0,ADON,ACCESS
    bcf    ADCON2,ADFM,ACCESS
    bsf    ADCON1,PCFG3,ACCESS
    bsf    ADCON1,PCFG2,ACCESS
    bsf    ADCON1,PCFG1,ACCESS
    bsf    ADCON1,PCFG0,ACCESS
    movlw    7
    movwf    CMCON,ACCESS
    clrf    PORTA,ACCESS
    clrf    PORTB,ACCESS
    clrf    PORTC,ACCESS
    clrf    PORTE,ACCESS
    return

;********************************************************************************


 END

veo que en la libreria de multitasking que nos hiciste favor de publicar lleva una parte en ensamblador que hace referencia al OPTION_REG.
Código:

    movlw    192                        'configure Timer0
    andwf    OPTION_REG,F
    movf    SysCalcTempA,W
    iorwf    OPTION_REG,F
    clrwdt

Donde configuras al timer0 para que sea la base de tiempo, sin embargo en el archivo .inc del 18F2550
dicho registro no se encuentra.

tomado de gputils mike@mike:/usr/share/gputils/header$ nano p18f2550.inc
Código:

;==========================================================================
;      18xxxx Family        EQUates
;==========================================================================
FSR0            EQU 0
FSR1            EQU 1
FSR2            EQU 2

FAST            EQU 1

W              EQU 0
A              EQU 0
ACCESS          EQU 0
BANKED          EQU 1
;==========================================================================

;==========================================================================
;      16Cxxx/17Cxxx Substitutions
;==========================================================================
  #define DDRA  TRISA      ; PIC17Cxxx SFR substitution
  #define DDRB  TRISB      ; PIC17Cxxx SFR substitution
 #define DDRD  TRISD      ; PIC17Cxxx SFR substitution
  #define DDRE  TRISE      ; PIC17Cxxx SFR substitution

;==========================================================================
;
;      Register Definitions
;
;==========================================================================
;----- Register Files -----------------------------------------------------
UFRM            EQU  H'0F66'
UFRML            EQU  H'0F66'
UFRMH            EQU  H'0F67'
UIR              EQU  H'0F68'
UIE              EQU  H'0F69'
UEIR            EQU  H'0F6A'
UEIE            EQU  H'0F6B'
USTAT            EQU  H'0F6C'
UCON            EQU  H'0F6D'
UADDR            EQU  H'0F6E'
UCFG            EQU  H'0F6F'
UEP0            EQU  H'0F70'
UEP1            EQU  H'0F71'
UEP2            EQU  H'0F72'
UEP3            EQU  H'0F73'
UEP4            EQU  H'0F74'
UEP5            EQU  H'0F75'
UEP6            EQU  H'0F76'
UEP7            EQU  H'0F77'
UEP8            EQU  H'0F78'
UEP9            EQU  H'0F79'
UEP10            EQU  H'0F7A'
UEP11            EQU  H'0F7B'
UEP12            EQU  H'0F7C'
UEP13            EQU  H'0F7D'
UEP14            EQU  H'0F7E'
UEP15            EQU  H'0F7F'
PORTA            EQU  H'0F80'
PORTB            EQU  H'0F81'
PORTC            EQU  H'0F82'
PORTE            EQU  H'0F84'
LATA            EQU  H'0F89'
LATB            EQU  H'0F8A'
LATC            EQU  H'0F8B'
DDRA            EQU  H'0F92'
TRISA            EQU  H'0F92'
DDRB            EQU  H'0F93'
TRISB            EQU  H'0F93'
DDRC            EQU  H'0F94'
TRISC            EQU  H'0F94'
OSCTUNE          EQU  H'0F9B'
PIE1            EQU  H'0F9D'
PIR1            EQU  H'0F9E'
IPR1            EQU  H'0F9F'
PIE2            EQU  H'0FA0'
PIR2            EQU  H'0FA1'
IPR2            EQU  H'0FA2'
EECON1          EQU  H'0FA6'
EECON2          EQU  H'0FA7'
EEDATA          EQU  H'0FA8'
EEADR            EQU  H'0FA9'
RCSTA            EQU  H'0FAB'
TXSTA            EQU  H'0FAC'
TXREG            EQU  H'0FAD'
RCREG            EQU  H'0FAE'
SPBRG            EQU  H'0FAF'
SPBRGH          EQU  H'0FB0'
T3CON            EQU  H'0FB1'
TMR3L            EQU  H'0FB2'
TMR3H            EQU  H'0FB3'
CMCON            EQU  H'0FB4'
CVRCON          EQU  H'0FB5'
CCP1AS          EQU  H'0FB6'
ECCP1AS          EQU  H'0FB6'
CCP1DEL          EQU  H'0FB7'
ECCP1DEL        EQU  H'0FB7'
BAUDCON          EQU  H'0FB8'
CCP2CON          EQU  H'0FBA'
CCPR2            EQU  H'0FBB'
CCPR2L          EQU  H'0FBB'
CCPR2H          EQU  H'0FBC'
CCP1CON          EQU  H'0FBD'
CCPR1            EQU  H'0FBE'
CCPR1L          EQU  H'0FBE'
CCPR1H          EQU  H'0FBF'
ADCON2          EQU  H'0FC0'
ADCON1          EQU  H'0FC1'
ADCON0          EQU  H'0FC2'
ADRES            EQU  H'0FC3'
ADRESL          EQU  H'0FC3'
ADRESH          EQU  H'0FC4'
SSPCON2          EQU  H'0FC5'
SSPCON1          EQU  H'0FC6'
SSPSTAT          EQU  H'0FC7'
SSPADD          EQU  H'0FC8'
SSPBUF          EQU  H'0FC9'
T2CON            EQU  H'0FCA'
PR2              EQU  H'0FCB'
TMR2            EQU  H'0FCC'
T1CON            EQU  H'0FCD'
TMR1L            EQU  H'0FCE'
TMR1H            EQU  H'0FCF'
RCON            EQU  H'0FD0'
WDTCON          EQU  H'0FD1'
HLVDCON          EQU  H'0FD2'
LVDCON          EQU  H'0FD2'
OSCCON          EQU  H'0FD3'
T0CON            EQU  H'0FD5'
TMR0L            EQU  H'0FD6'
TMR0H            EQU  H'0FD7'
STATUS          EQU  H'0FD8'
FSR2L            EQU  H'0FD9'
FSR2H            EQU  H'0FDA'
PLUSW2          EQU  H'0FDB'
PREINC2          EQU  H'0FDC'
POSTDEC2        EQU  H'0FDD'
POSTINC2        EQU  H'0FDE'
INDF2            EQU  H'0FDF'
BSR              EQU  H'0FE0'
FSR1L            EQU  H'0FE1'
FSR1H            EQU  H'0FE2'
PLUSW1          EQU  H'0FE3'
PREINC1          EQU  H'0FE4'
POSTDEC1        EQU  H'0FE5'
POSTINC1        EQU  H'0FE6'
INDF1            EQU  H'0FE7'
WREG            EQU  H'0FE8'
FSR0L            EQU  H'0FE9'
FSR0H            EQU  H'0FEA'
PLUSW0          EQU  H'0FEB'
PREINC0          EQU  H'0FEC'
POSTDEC0        EQU  H'0FED'
POSTINC0        EQU  H'0FEE'
INDF0            EQU  H'0FEF'
INTCON3          EQU  H'0FF0'
INTCON2          EQU  H'0FF1'
INTCON          EQU  H'0FF2'
PROD            EQU  H'0FF3'
PRODL            EQU  H'0FF3'
PRODH            EQU  H'0FF4'
TABLAT          EQU  H'0FF5'
TBLPTR          EQU  H'0FF6'
TBLPTRL          EQU  H'0FF6'
TBLPTRH          EQU  H'0FF7'
TBLPTRU          EQU  H'0FF8'
PC              EQU  H'0FF9'
PCL              EQU  H'0FF9'
PCLATH          EQU  H'0FFA'
PCLATU          EQU  H'0FFB'
STKPTR          EQU  H'0FFC'
TOS              EQU  H'0FFD'
TOSL            EQU  H'0FFD'
TOSH            EQU  H'0FFE'
TOSU            EQU  H'0FFF'



de acuerdo al archivo de configuracion del GcBasic que se encuentra en
mike@mike:/usr/share/GcBasic$ nano gcbasic.ini

el compilador que se utiliza para el ensamblador que genera GcBasic es gputils

Código:

'Assembler to use
'MPASM settings
'Filename, is relative to GCBASIC directory unless a full path is given
Assembler = gpasm
'Parameters
AssemblerParams = --hex-format inhx32 --radix DEC --warning 2 --ignore-case --f$
'GCASM settings
'Assembler = GCASM
'No params needed for GCASM


Será posible que la rutina no funcione con la familia 18F25XX o en que me estoy equivocando?
Por tu tiempo, muchas gracias!!


***********************************************
Crees que sea util esta información??, la voy a revisar al rato, ya me lanzo a mi casita
http://www.mikroe.com/forum/viewtopic.php?t=21894&sid=433454ea33b6b1a7719d31eeda349bcd
avatar
maigke
Asiduo del Foro
Asiduo del Foro

Mensajes : 210
Fecha de inscripción : 12/04/2009
Edad : 40
Localización : Mexico

Volver arriba Ir abajo

Re: Librería para multitarea en GCBasic.

Mensaje por maigke el Sáb 7 Nov 2009 - 1:43

Parace que ya quedo la modificacion que realize y ya me compilo y funciono mas o menos, aun tengo que ver que onda con el reloj fue la siguiente

Código:


movlw    192                        'configure Timer0
   
    andwf  T0CON,F    ' de acuerdo al link que esta anteriormente este registro es bit a bit igual a OPTION_REG
    movf    SysCalcTempA,W
   
    iorwf    T0CON,F
    clrwdt


Con eso ya me compilo, solo me falta ver que onda, al menos los leds prenden y si cambia la frecuencia, esto lo estoy revisando con un frecuencimetro.

Espero sea bueno el arreglo

Gracias!!!

pd. ademas de que tuve que cambiar el nombre de la libreria por multitasking2.h para no borrar la tuya
y anexar la modificacion en el /usr/share/GcBasic/include

mike@mike:/usr/share/GcBasic/include$ ls
3pi.h DS18s20.h lego.h multitasking2.h template.h
adc-87X.h eracer.h lowlevel multitasking.h terminal-pic.h
comp-87X.h gcalpha.h lowlevel.dat srf04.h
mike@mike:/usr/share/GcBasic/include$
avatar
maigke
Asiduo del Foro
Asiduo del Foro

Mensajes : 210
Fecha de inscripción : 12/04/2009
Edad : 40
Localización : Mexico

Volver arriba Ir abajo

Re: Librería para multitarea en GCBasic.

Mensaje por Pikitin el Sáb 7 Nov 2009 - 11:49

Gracias por la informacion... y por la solución!

Para no tener dos archivos puedes probar a sustituir esto:
Código:
movlw    192                        'configure Timer0
    andwf    OPTION_REG,F
    movf    SysCalcTempA,W
    iorwf    OPTION_REG,F
    clrwdt

Por esto:
Código:
    #IFDEF VAR(OPTION_REG)
        movlw    192                        'configure Timer0 16f
        andwf    OPTION_REG,F
        movf    SysCalcTempA,W
        iorwf    OPTION_REG,F
        clrwdt
    #ENDIF
   
    #IFDEF VAR(T0CON)
        movlw    192                        'configure Timer0 18f
        andwf    T0CON,F
        movf    SysCalcTempA,W
        iorwf    T0CON,F
        clrwdt
    #ENDIF

Si los dos registros son iguales bit a bit, esto debería funcionar.

Si ves que funciona coméntalo para actualizar el archivo.


Saludos.

Pikitin
veterano
veterano

Mensajes : 623
Fecha de inscripción : 26/11/2008

http://linuxmicros.blogspot.com/

Volver arriba Ir abajo

Re: Librería para multitarea en GCBasic.

Mensaje por Pikitin el Sáb 7 Nov 2009 - 16:17

Maigke... creo que OPTION_REG y T0CON no son exactamente iguales:

En el enlace que pusiste:
You should set TMR0ON bit, as well as T08BIT to enable Timer0 and set it to 8-bit mode:

Code:
T0CON = %11000111

Los bits 6 y 7 de OPTION_REG no se usan para timer0, y parece que en los 18f o al menos en algunos de ellos es necesario iniciar el timer0 y decirle que en modo 8 bits... en los 16f timer0 siempre está funcionando y siempre es a 8 bits; no tengo idea de esto, sería cuestión de mirarse el datasheet del pic que estés usando y comprobar esto.

Si esto es así habría que poner a 1 los bits 6 y 7, en #IFDEF VAR(T0CON)


Saludos.

Pikitin
veterano
veterano

Mensajes : 623
Fecha de inscripción : 26/11/2008

http://linuxmicros.blogspot.com/

Volver arriba Ir abajo

Re: Librería para multitarea en GCBasic.

Mensaje por maigke el Dom 8 Nov 2009 - 19:39

Cierto!!! en el pic hay que habilitar el timer y ademas configurar el tamaño del timer 0 ya sea a 16 bits o a 8 bits! Very Happy

Gracias haré las modificaciones y te tendré al tanto, si esto queda, el multitasking será mucho mejor con los pic18
avatar
maigke
Asiduo del Foro
Asiduo del Foro

Mensajes : 210
Fecha de inscripción : 12/04/2009
Edad : 40
Localización : Mexico

Volver arriba Ir abajo

Re: Librería para multitarea en GCBasic.

Mensaje por maigke el Dom 8 Nov 2009 - 21:19

Hola analizando la rutina, vi lo siguiente

Código:

    movlw    192                        'configure Timer0
    andwf    OPTION_REG,F
    movf    SysCalcTempA,W
    iorwf    OPTION_REG,F
    clrwdt

el movlw 192 carga el siguiente numero binario 1100 0000, poniendo en 11 los bits 7 y 6 del Registro
pero mas abajo vemos un and, dejando el valor que tenian esos bits y limpiando los demas
posterior leemos el registro SysCalcTempA y lo vaciamos en el Option Reg a través de una Or inclusiva
y por ultimo limpiamos el wdt

tomando como base tus comentarios la solucion solo consistira en nuevamente hacer una Or
con el numero 1100 000 al finalizar para no alterar los valores de los bits descargados
forzando así a 1 los valores de los bits 6 y 7 del tmr0
Código:

  #ifdef var(OPTION_REG)
    movlw    192                        'configure Timer0
    andwf    OPTION_REG,F
    movf    SysCalcTempA,W
    iorwf    OPTION_REG,F
    clrwdt
  #endif

  #ifdef var(T0CON)
    movlw 192            'configura TMR0 PIC18
    andwf T0CON,F
    movf SysCalcTempA,W
    iorwf T0CON,F
    movlw 192            'cargamos de nuevo el 0xc0                                            TTTT TTTT
    iorwf T0CON,F        ' hacemos un OR con T0CON  y lo guardamos ahi mismo Or  1100 0000
    clrwdt                                                                                  res en T0Con  11TT TTTT
  #endif


Esos bits sirven para habilitar el TMR0 y ajuste de 8bits el bit6, si esta en 1 el tmr0 es de 8 bits y si es cero esta a 16bits.

Saludos, si hay algun error por fa comentenlo!
veremos que podemos hacer entre todos
gracias
avatar
maigke
Asiduo del Foro
Asiduo del Foro

Mensajes : 210
Fecha de inscripción : 12/04/2009
Edad : 40
Localización : Mexico

Volver arriba Ir abajo

Re: Librería para multitarea en GCBasic.

Mensaje por Pikitin el Dom 8 Nov 2009 - 21:57

el movlw 192 carga el siguiente numero binario 1100 0000, poniendo en 11 los bits 7 y 6 del Registro
pero mas abajo vemos un and, dejando el valor que tenian esos bits y limpiando los demas
posterior leemos el registro SysCalcTempA y lo vaciamos en el Option Reg a través de una Or inclusiva
y por ultimo limpiamos el wdt
Si... exacto, se trata de no tocar los bits 6 y 7 de OPTION_reg que se usan para otras cosas


tomando como base tus comentarios la solucion solo consistira en nuevamente hacer una Or
con el numero 1100 000 al finalizar para no alterar los valores de los bits descargados
forzando así a 1 los valores de los bits 6 y 7 del tmr0
Ok... esa solución debería funcionar.
Pero, se podría optimizar un poco: dijimos que en los pic16f no queremos tocar los bit 6 y 7, de ahí las dos primeras lineas... pero en los 18f si que queremos modificar esos valores, así que: porqué no usar esas dos primeras lineas precisamente para eso?
Otra cosa que se me pasó es que clrwdt es común en los dos casos, así que se puede quedar fuera de los #ifdef
Y ya puestos a quitar lineas... el movlw 192 también es común osea que también se podría sacar:

Código:

    movlw    192

  #ifdef var(OPTION_REG)      'configura TMR0 PIC16F
    andwf    OPTION_REG,F
    movf    SysCalcTempA,W
    iorwf    OPTION_REG,F
  #endif

  #ifdef var(T0CON)            'configura TMR0 PIC18F
    movwf T0CON
    movf SysCalcTempA,W
    iorwf T0CON,F
  #endif

    clrwdt

Creo que así también debería funcionar... no?

Pikitin
veterano
veterano

Mensajes : 623
Fecha de inscripción : 26/11/2008

http://linuxmicros.blogspot.com/

Volver arriba Ir abajo

Re: Librería para multitarea en GCBasic.

Mensaje por maigke el Lun 9 Nov 2009 - 3:41

Saludos, pues en definitva no funciono como me esperaba, debe haber otros cambios mmm habra que buscarlos mas a fondo.

hice la prueba en hardware y en simulacion del proteus

bueno estaremos siguiendo este caso
avatar
maigke
Asiduo del Foro
Asiduo del Foro

Mensajes : 210
Fecha de inscripción : 12/04/2009
Edad : 40
Localización : Mexico

Volver arriba Ir abajo

Re: Librería para multitarea en GCBasic.

Mensaje por Pikitin el Lun 30 Ene 2012 - 7:06

He subido una nueva versión que funciona tanto con Pics como Avrs, debería funcionar también con pic18f, o al menos algunos.

Ahora se pueden crear pwm facilmente, hay que definir la resolución y las salidas:
#define pwm_res 40

#define pwm1_out PORTB.1
#define pwm2_out PORTB.2

Luego para ajustar el duty, por ejemplo:

pwm1_duty = 10
pwm2_duty = variable

He subido un ejemplo al widget de descargas: GcBasic>Ejemplos>pwmled.gcb

El ejemplo más simple, un led que se enciende y apaga progresivamente:

Código:
' Pwm led en PORTB.0

'------------------------ CHIP CONFIG -----------------------------------
'------------------------------------------------------------------------
#chip 16f628a, 20
#config HS_OSC, WDT_OFF, LVP_OFF, PWRTE_ON, MCLR_ON

'------------------------ MULTITASKING ----------------------------------
'------------------------------------------------------------------------
#include <multitasking.h>

#define base_time 500
#define pwm_res 40
#define pwm1_out PORTB.0


'------------------------ MAIN LOOP -------------------------------------
'------------------------------------------------------------------------

Do
  for pwm1_duty = 0 to 40
    wait 100 ms
  Next
 
  for pwm1_duty = 40 to 0
    wait 100 ms
  Next
Loop


Pikitin
veterano
veterano

Mensajes : 623
Fecha de inscripción : 26/11/2008

http://linuxmicros.blogspot.com/

Volver arriba Ir abajo

Re: Librería para multitarea en GCBasic.

Mensaje por Contenido patrocinado


Contenido patrocinado


Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba

- Temas similares

 
Permisos de este foro:
No puedes responder a temas en este foro.