[Tutorial] y manejo de Proton IDE

hola buena noche, Soy de Venezuela, y recién comienzo en la programación y comenzé con el micro code studio pero por no manera directamente puntos flotante me cambie al proton IDE, actualmente he programado un controlador de temperatura para una incubadora de huevos y me funciona muy bien. la cuestión esta en que a este código deseo incorporarle una rutina que me permita realizar el volteo automático en un tiempo especifico, pero no logra que el programa me corra sin interferir en el control y sensado de la temperatura. como podria hacer para que el volteo se me realize digamos en un segun plano ? que se ejecuten los dos programas pero uno independiente del otro.

en el caso del control de temperatura, este me sensa y controla constantemente y el volteo automatico tendria que realizarse cada 8 horas

como podria yo realizar esto?

ojala puedan ayudarme y se los agradeceria un mundo
 
hola buena noche, Soy de Venezuela, y recién comienzo en la programación y comenzé con el micro code studio pero por no manera directamente puntos flotante me cambie al proton IDE, actualmente he programado un controlador de temperatura para una incubadora de huevos y me funciona muy bien. la cuestión esta en que a este código deseo incorporarle una rutina que me permita realizar el volteo automático en un tiempo especifico, pero no logra que el programa me corra sin interferir en el control y sensado de la temperatura. como podria hacer para que el volteo se me realize digamos en un segun plano ? que se ejecuten los dos programas pero uno independiente del otro.

en el caso del control de temperatura, este me sensa y controla constantemente y el volteo automatico tendria que realizarse cada 8 horas

como podria yo realizar esto?

ojala puedan ayudarme y se los agradeceria un mundo

Hola...Debes ser mas especifico en lo que tienes echo hasta ahora(software, hardware) ya que nosotros solo sabemos lo que tú nos cuentas del proyecto en cuestión. Generalmente se utiliza interrupciones y algún reloj de tiempo real tipo el DS1307 u otro dependiendo del requerimiento del desarrollo, etc.
Saludos.

Ric.
 
HOLA ricbevi, gracias por comentar.

Te cuento.... como mencione anteriormente, hace un tiempo realice un controlador de temperatura para una incubadora de huevos de gallinas y si que me funciona muy bien hasta incluso he llegado a sacar pollitos. el problema que tengo es que al software que realice le quiero anexar una rutina que me permita controlar el volteo automático cada 8:25 horas sin que esta rutina me interfiera en el trabajo del censado de la temperatura, esto seria como correr dos programas al mismo tiempo ó que trabaje en un modo de segundo plano algo asi me imagino yo, no se si estoy equivocado....

cabe mencionar que uso el Proton IDE

aca te dejo el codigo del programa a ver si me puedes dar una mano ya que soy nuevo en esta area.

Código:
'****************************************************************
'*  Name    : control de temperatura.BAS                                       *
'*  Author  : [EMELY SUMOZA]                                    *
'*  Notice  : Copyright (c) 2014 [SMILLER c.a]              *
'*          : All Rights Reserved                                     *
'*  Date    : 20/06/2014                                             *
'*  Version : 1.0                                                         *
'*  Notes   :                                                               *
'*          :                                                                  *
'****************************************************************

Device 16F877A ' Define LCD registers and bits
Declare Xtal=4
TRISA=0
CMCON = 7                    ; Set PORTA and PORTE to digital
;-------------------------------------------------------------------------------

Declare LCD_Type 0           ; definimos el tipo de lcd que se va a utilizar  
Declare LCD_DTPort PORTA     ; Definimos puertos a emplear
Declare LCD_DTPin PORTA.0    ; puertos que se usaran como línea de datos 
Declare LCD_RSPin PORTB.2    ; puerto que va funcionar como RESET
Declare LCD_ENPin PORTB.1    ; Definimos el puerto que va a ENABLE en el LCD

;-------------------------------------------------------------------------------

DQ      VAR     PORTB.0      ; One-wire data pin
count_per_c VAR Byte         ; Count per degree C
;-------------------------------------------------------------------------------

temperature VAR Word            
x VAR Byte
x3 var Float
Tempbaj VAR Float
tempalt VAR Float
;------------------------------------------------------------
rF VAR PORTB.7 
rC VAR PORTB.6
led VAR PORTA.4
enter VAR PORTB.5
bsubir VAR PORTB.4
bbajar VAR PORTB.3
;-------------------------------------------------------------------------------
DIn VAR Byte
DIn = 0
x1 var Float
x1 = 28.2
x2 var Float
x2 = 28

EWrite Din,[x1]
tempalt  = ERead 0
EWrite Din,[X2]        ;contenido inicial 0 de la EEPROM
                               ;lee la EEPROM 0 y lo guarda en tempalt
tempbaj  = ERead 1            ;lee la EEPROM 1 y lo guarda en tempbaj
;-------------------------------------------------------------------------------
Print $fe, 1,"BIENVENIDO" ;limpiar LCD y sacar texto
Print $fe, $c1,"CARGANDO ."
DelayMS 1500
Print $fe, 1,"BIENVENIDO " ;limpiar LCD y sacar texto
Print $fe, $c1,"CARGANDO .." 
DelayMS 1000
Print $fe, 1,"BIENVENIDO" ;limpiar LCD y sacar texto
Print $fe, $c1,"CARGANDO ...."
DelayMS 1000
Print $fe, 1,"TEMPERATURA" ;limpiar LCD y sacar texto
Print $fe, $c1,"CARGANDA "
DelayMS 1000


;-------------------------------------------------------------------------------
inicio:                               ;3 parpadeos del led que indica funciona
For x =1 To 3
High led
DelayMS 500
Low led
DelayMS 300
Next
;-------------------------------------------------------------------------------
mainloop:    ;programa principal de censado de temperatura
        OWrite DQ, 1, [$CC, $44] ' inicia la convención de la temperatura
        High led
        DelayMS 100
        Low led   
        DelayMS 100
        
        OWrite DQ, 1, [$CC, $BE]         ' lee la temperatura
        ORead DQ, 0, [temperature.LowByte, temperature.HighByte]
        temperature = temperature */ 1600
        x3=temperature/100
        Print $fe, 1,"TEMPERATURA"
        Print $fe, $c1, Dec1 x3,06, 223,"C"
        ;-----------------------------------------------------------------------
        For x = 1 To 10 ;repetir 10 veces
        If enter =0 Then grabar1a
       
        DelayMS 10
        If X3 <= tempbaj  Then calentar ;si X3 es <tempbaj ir a calentar 
        If X3 >= tempalt Then enfriar  ;si X3 es >tempALT ir a ENFRIAR
                
        Low rC : Low rF ;apagar los 2 relés
        Next
        
        GoTo mainloop ;continuar censando

calentar:
High rC : Low rF
GoTo mainloop

enfriar:
High rF : Low rC
GoTo mainloop

grabar1a:
GoSub soltar

grabar1:
Print  $fe, 1, "Programar temp."
Print $fe,$c0,"baja= ",Dec1 tempbaj ,223,"C"
DelayMS 50
If bbajar=0 Then restar1
If bsubir=0 Then sumar1
If enter=0 Then grabarA
GoTo grabar1

restar1:
GoSub soltar ;programa antirrebote de tecla
If tempbaj < 1 Then grabar1
tempbaj= tempbaj -0.1
GoTo grabar1

sumar1:
GoSub soltar
If tempbaj > 100 Then grabar1
tempbaj= tempbaj + 0.1
GoTo grabar1

;..................................................................
grabarA:
GoSub soltar
EWrite 1,[x1] ;escribir en la dirección 0 de la EEPROM
;...................................................................

grabar2:
Print $fe, 1, "Programar temp."
Print $fe,$c0,"alta= ",Dec1 tempalt ,223,"C"
DelayMS 100
If bbajar=0 Then restar2
If bsubir=0 Then sumar2
If enter=0 Then grabarB
GoTo grabar2

restar2:
GoSub soltar
If tempalt < 5 Then grabar2
tempalt= tempalt -0.1
GoTo grabar2

sumar2:
GoSub soltar
If tempalt > 50 Then grabar2
tempalt= tempalt + 0.1
GoTo grabar2

;................................................................
grabarB:
GoSub soltar
EWrite 0,[x2];escribir en la dirección 1 de la EEPROM
GoTo inicio
;................................................................

soltar: ;programa antirrebote de tecla
 
High led:
High PORTB.7
DelayMS 150
Low led

soltar2:
If bbajar=0 Then soltar2
If bsubir=0 Then soltar2
If enter=0 Then soltar2
DelayMS 100
Return
End
 
Última edición por un moderador:
HOLA ricbevi, gracias por comentar.

Te cuento.... como mencione anteriormente, hace un tiempo realice un controlador de temperatura para una incubadora de huevos de gallinas y si que me funciona muy bien hasta incluso he llegado a sacar pollitos. el problema que tengo es que al software que realice le quiero anexar una rutina que me permita controlar el volteo automático cada 8:25 horas sin que esta rutina me interfiera en el trabajo del censado de la temperatura, esto seria como correr dos programas al mismo tiempo ó que trabaje en un modo de segundo plano algo asi me imagino yo, no se si estoy equivocado....

cabe mencionar que uso el Proton IDE

aca te dejo el codigo del programa a ver si me puedes dar una mano ya que soy nuevo en esta area.

Código:
'****************************************************************
'*  Name    : control de temperatura.BAS                                       *
'*  Author  : [EMELY SUMOZA]                                    *
'*  Notice  : Copyright (c) 2014 [SMILLER c.a]              *
'*          : All Rights Reserved                                     *
'*  Date    : 20/06/2014                                             *
'*  Version : 1.0                                                         *
'*  Notes   :                                                               *
'*          :                                                                  *
'****************************************************************

Device 16F877A ' Define LCD registers and bits
Declare Xtal=4
TRISA=0
CMCON = 7                    ; Set PORTA and PORTE to digital
;-------------------------------------------------------------------------------

Declare LCD_Type 0           ; definimos el tipo de lcd que se va a utilizar  
Declare LCD_DTPort PORTA     ; Definimos puertos a emplear
Declare LCD_DTPin PORTA.0    ; puertos que se usaran como línea de datos 
Declare LCD_RSPin PORTB.2    ; puerto que va funcionar como RESET
Declare LCD_ENPin PORTB.1    ; Definimos el puerto que va a ENABLE en el LCD

;-------------------------------------------------------------------------------

DQ      VAR     PORTB.0      ; One-wire data pin
count_per_c VAR Byte         ; Count per degree C
;-------------------------------------------------------------------------------

temperature VAR Word            
x VAR Byte
x3 var Float
Tempbaj VAR Float
tempalt VAR Float
;------------------------------------------------------------
rF VAR PORTB.7 
rC VAR PORTB.6
led VAR PORTA.4
enter VAR PORTB.5
bsubir VAR PORTB.4
bbajar VAR PORTB.3
;-------------------------------------------------------------------------------
DIn VAR Byte
DIn = 0
x1 var Float
x1 = 28.2
x2 var Float
x2 = 28

EWrite Din,[x1]
tempalt  = ERead 0
EWrite Din,[X2]        ;contenido inicial 0 de la EEPROM
                               ;lee la EEPROM 0 y lo guarda en tempalt
tempbaj  = ERead 1            ;lee la EEPROM 1 y lo guarda en tempbaj
;-------------------------------------------------------------------------------
Print $fe, 1,"BIENVENIDO" ;limpiar LCD y sacar texto
Print $fe, $c1,"CARGANDO ."
DelayMS 1500
Print $fe, 1,"BIENVENIDO " ;limpiar LCD y sacar texto
Print $fe, $c1,"CARGANDO .." 
DelayMS 1000
Print $fe, 1,"BIENVENIDO" ;limpiar LCD y sacar texto
Print $fe, $c1,"CARGANDO ...."
DelayMS 1000
Print $fe, 1,"TEMPERATURA" ;limpiar LCD y sacar texto
Print $fe, $c1,"CARGANDA "
DelayMS 1000


;-------------------------------------------------------------------------------
inicio:                               ;3 parpadeos del led que indica funciona
For x =1 To 3
High led
DelayMS 500
Low led
DelayMS 300
Next
;-------------------------------------------------------------------------------
mainloop:    ;programa principal de censado de temperatura
        OWrite DQ, 1, [$CC, $44] ' inicia la convención de la temperatura
        High led
        DelayMS 100
        Low led   
        DelayMS 100
        
        OWrite DQ, 1, [$CC, $BE]         ' lee la temperatura
        ORead DQ, 0, [temperature.LowByte, temperature.HighByte]
        temperature = temperature */ 1600
        x3=temperature/100
        Print $fe, 1,"TEMPERATURA"
        Print $fe, $c1, Dec1 x3,06, 223,"C"
        ;-----------------------------------------------------------------------
        For x = 1 To 10 ;repetir 10 veces
        If enter =0 Then grabar1a
       
        DelayMS 10
        If X3 <= tempbaj  Then calentar ;si X3 es <tempbaj ir a calentar 
        If X3 >= tempalt Then enfriar  ;si X3 es >tempALT ir a ENFRIAR
                
        Low rC : Low rF ;apagar los 2 relés
        Next
        
        GoTo mainloop ;continuar censando

calentar:
High rC : Low rF
GoTo mainloop

enfriar:
High rF : Low rC
GoTo mainloop

grabar1a:
GoSub soltar

grabar1:
Print  $fe, 1, "Programar temp."
Print $fe,$c0,"baja= ",Dec1 tempbaj ,223,"C"
DelayMS 50
If bbajar=0 Then restar1
If bsubir=0 Then sumar1
If enter=0 Then grabarA
GoTo grabar1

restar1:
GoSub soltar ;programa antirrebote de tecla
If tempbaj < 1 Then grabar1
tempbaj= tempbaj -0.1
GoTo grabar1

sumar1:
GoSub soltar
If tempbaj > 100 Then grabar1
tempbaj= tempbaj + 0.1
GoTo grabar1

;..................................................................
grabarA:
GoSub soltar
EWrite 1,[x1] ;escribir en la dirección 0 de la EEPROM
;...................................................................

grabar2:
Print $fe, 1, "Programar temp."
Print $fe,$c0,"alta= ",Dec1 tempalt ,223,"C"
DelayMS 100
If bbajar=0 Then restar2
If bsubir=0 Then sumar2
If enter=0 Then grabarB
GoTo grabar2

restar2:
GoSub soltar
If tempalt < 5 Then grabar2
tempalt= tempalt -0.1
GoTo grabar2

sumar2:
GoSub soltar
If tempalt > 50 Then grabar2
tempalt= tempalt + 0.1
GoTo grabar2

;................................................................
grabarB:
GoSub soltar
EWrite 0,[x2];escribir en la dirección 1 de la EEPROM
GoTo inicio
;................................................................

soltar: ;programa antirrebote de tecla
 
High led:
High PORTB.7
DelayMS 150
Low led

soltar2:
If bbajar=0 Then soltar2
If bsubir=0 Then soltar2
If enter=0 Then soltar2
DelayMS 100
Return
End


Entonces haces lo que te comente...le agregas un DS1307(en el hilo anterior esta el datasheet), si no tienes ejemplos de programación en el foro están(usa el buscador). Básicamente haces lo mismo que cuando lees la temperatura y decides que hacer con ella nada mas que ahora es cuestión de tiempo. Lo puedes intercalar...lees la hora, temperatura y después decides que hacer con cada auno de los diferentes parámetros....si llego la hora volteas, si llego la temperatura mínima enciendes calefacción, etc.
Creo haber visto en el foro un aporte de una incubadora de ese tipo así que deberías de usar el buscador para revisar también al respecto....mira aquí
Saludos.

Ric.
 
hola. bien veo que me entendiste con respecto a lo que requiero hacer.

te dejo una explicación mas sencilla para ver si me ayudas como se realiza una rutina de este tipo.

Comienzo:

Imagínate que en un proyecto usted desea realizar tres trabajos, la cual son---- leer temperatura y otro encender dos led en diferentes tiempos,

1: Que en ningún momento el pic me deje de censar y controlar la temperatura.

2: Que al mismo tiempo que realiza el trabajo (1) me encienda un led por decir cada (X) segundos (ajustable),

3: Que al mismo tiempo que realiza el trabajo (1 y 2) Me encienda un led y me lo deje encendido por (Y) minutos y luego apague.

Lo que deseo realmente es como realizar una rutina que me permita hacer esto pero que ninguna de las 3 funciones intervenga en el trabajo de las demás ( es como tener 3 pic funcionando 1 para la temperatura, uno para un led y el otro para el otro led ) pero los tres pic en uno solo.

Existe la posibilidad de poder realizar esto ?

De mano te agradecería, uno por que estoy realizando este proyecto y otro por que me gustaría aprender como realizar este tipo de rutinas. he pedido ayuda en muchos foros en cuanto a esto pero realmente no la he obtenido.
 
hola. bien veo que me entendiste con respecto a lo que requiero hacer.

te dejo una explicación mas sencilla para ver si me ayudas como se realiza una rutina de este tipo.

Comienzo:

Imagínate que en un proyecto usted desea realizar tres trabajos, la cual son---- leer temperatura y otro encender dos led en diferentes tiempos,

1: Que en ningún momento el pic me deje de censar y controlar la temperatura.

2: Que al mismo tiempo que realiza el trabajo (1) me encienda un led por decir cada (X) segundos (ajustable),

3: Que al mismo tiempo que realiza el trabajo (1 y 2) Me encienda un led y me lo deje encendido por (Y) minutos y luego apague.

Lo que deseo realmente es como realizar una rutina que me permita hacer esto pero que ninguna de las 3 funciones intervenga en el trabajo de las demás ( es como tener 3 pic funcionando 1 para la temperatura, uno para un led y el otro para el otro led ) pero los tres pic en uno solo.

Existe la posibilidad de poder realizar esto ?

De mano te agradecería, uno por que estoy realizando este proyecto y otro por que me gustaría aprender como realizar este tipo de rutinas. he pedido ayuda en muchos foros en cuanto a esto pero realmente no la he obtenido.

Es posible hacer eso y mucho mas con un PIC pero no de la forma que lo planteas...no hace el trabajo de tres PIC si no que lo puede hacer tan rápido que seria como si así lo hicieran. La temperatura no es un parámetro (al menos en esta aplicación) que cambie en el orden de los mili-segundos por lo que no es necesario estar permanentemente sobre ella, y puedes dedicarle tiempo a prender el led que quieres, consultar al IC que te recomendé dedicado al tiempo, etc.
El problema de este y otros foro es que se brinda ayuda no se hacen trabajos a pedido por lo que encontraras ni mas ni menos que eso.
Ejemplo simplificado del programa a hacer

1)Mido la temperatura
2)Consulto el tiempo(o inviertes el orden del proceso uno por el dos según te pazca/convenga))
3)Comparo con los parámetros anteriores y muestro en display si quiero
4)Actuó en consecuencia según mi criterio(calefacción, refrigeración, volteo, etc)
5)repito el ciclo...voy al punto 1

Te reitero usa el buscador del foro que creo haber visto tratado el tema de una incubadora para huevos.

Ric.
 
Última edición:
hola emelyjose,

Lo mejor será que trates con interrupciones, no te garantizo fiabilidad al 100%, yo quería hacer un velocímetro digital usando timer0 y timer1 pero al final desistí, entonces te recomendaría empezar con lo básico sobre ese tema, aquí en el foro hay mucha información al respecto y tambien en la ayuda de proton. Creo que debes mirar la pagina 21 donde se trata algo referente a las interrupciones.

Mucha suerte con el proyecto y no olvides publicar tus avances.
 
Última edición:
Buenas noches, genios. ¿Cómo están todos? Espero que bien.
Hoy les escribo porque necesito un poco de ayuda.

Estoy haciendo un programa con 4 switchs y los switchs deben ser presionados en una secuencia correcta para activar una salida, al transcurrir 3 minutos después de activar dicha salida, el programa vuelve al inicio, hasta ahí todo perfecto.
La pregunta es, si puedo reducir mi programa con otras lineas de código que me faciliten cambiar la secuencia de activación más fácilmente.
¿Alguien me puede regalar una secuencia de While y Wend para saber como trabajan este tipo de instrucciones?

De antemano, muchas gracias.
Código:
Device 16F628A

      Reminders=false
      Config intrc_osc_noclkout,wdt_off,pwrte_on,lvp_off,boden_off,mclre_off
      Reminders =true
Xtal = 4
All_Digital true
 
 TRISA =%00001111
 TRISB =%00000000
 
  
 Dim contador As Word
                            
 Symbol in1=PORTA.0
 Symbol in2=PORTA.1
 Symbol in3=PORTA.2
 Symbol in4=PORTA.3
 
 contador=0  
 PORTA =0
 PORTB =0 
 
 inicio: 
 If in1 = 1 Then 
 GoTo intro2
 EndIf 
 GoTo inicio
;************************************************************************************************************
 intro2:
 contador = contador +1
 If in2 =1 Then 
 contador=0
 GoTo intro3
 EndIf
 
 If in3=1 Then
 GoTo inicio
 If in4=1 Then
 GoTo inicio
 EndIf
 EndIf
 DelayMS 1
 If contador > 2000 Then
 contador =0
 GoTo inicio 
 EndIf 
 GoTo intro2
;************************************************************************************************************* 
 intro3:
 contador = contador +1
 If in3 =1 Then 
 contador=0
 GoTo intro4
 EndIf
 
 If in1=1 Then
 GoTo inicio
 If in4=1 Then
 GoTo inicio
 EndIf
 EndIf
 DelayMS 1
 If contador > 2000 Then
 contador =0
 GoTo inicio 
 EndIf 
 GoTo intro3
 ;**************************************************************************************************************
 intro4:
 contador = contador +1
 If in4 =1 Then 
 contador=0
 GoTo salida
 EndIf
 
 If in1=1 Then
 GoTo inicio
 If in2=1 Then
 GoTo inicio
 EndIf
 EndIf
 DelayMS 1
 If contador > 2000 Then
 contador =0
 GoTo inicio 
 EndIf 
 GoTo intro4
;************************************************************************************************************** 
 salida:
 contador = contador+1
 High PORTB.2
 PORTB.0=PORTA.0
 PORTB.1=PORTA.1
 If in3=1 Then 
 contador =0
 GoTo bloqueo
 EndIf
 
 DelayMS 45
 If contador > 4000 Then 
 contador=0
 Low PORTB.2
 GoTo inicio
 EndIf 
 GoTo salida
 
 bloqueo:
 contador=contador+1
 
 DelayMS 10
 If contador > 300 Then 
 contador = 0 
 Low PORTB.2
 GoTo inicio
 EndIf
 
 If in3=1 Then 
 GoTo bloqueo
 EndIf
 
 Clear contador
 GoTo salida
 End
 

Adjuntos

  • 4 switches.jpg
    4 switches.jpg
    184.2 KB · Visitas: 41
Hola, tengo una pregunta: Estoy haciendo un tipo tornito y necesitaría ayuda. Es un torno con sensor de chásis abierto. Para que el pic sepa que el chásis está abierto, he colocado uno de esos switchs de "palanca". Lo que necesito es que el motor funcione un tiempo en un sentido (cuando el switch se cierra) y otro tiempo en el sentido contrario (cuando se abre). ¿Qué es lo que puedo hacer? Hice uno que hasta ahora llevo bien, pero sólo cumple con el movimiento una vez. Les dejo el código:


Código:
Stats:
    While PORTB.4 = 0
        DelayMS 100
        If i = 0 Or i = 5 Then
        GoTo Down
    Wend
    While PORTB.4 = 1
        DelayMS 100
        GoTo Up
    Wend
    
    
    
    
Down:
    If PORTB.4 = 0 Then
        If i < 5 Then
            For i = 0 To 5 Step 1
                High PORTB.0
                DelayMS 150
                Low PORTB.0
                High PORTB.1
                DelayMS 150
                Low PORTB.1
                High PORTB.2
                DelayMS 150
                Low PORTB.2
                High PORTB.3
                DelayMS 150
                Low PORTB.3
            Next i
        EndIf
        If i > 0 Then
            For i = 5 To 0 Step -1
                High PORTB.0
                DelayMS 150
                Low PORTB.0
                High PORTB.1
                DelayMS 150
                Low PORTB.1
                High PORTB.2
                DelayMS 150
                Low PORTB.2
                High PORTB.3
                DelayMS 150
                Low PORTB.3
            Next i
        EndIf
    EndIf
    If PORTB.4 = 1 Then
        GoTo Stats
    EndIf

 
Up:
    If PORTB.4 = 1 Then
            If j < 5 Then
                For j = 0 To 5 Step 1
                    High PORTB.3
                    DelayMS 150
                    Low PORTB.3
                    High PORTB.2
                    DelayMS 150
                    Low PORTB.2
                    High PORTB.1
                    DelayMS 150
                    Low PORTB.1
                    High PORTB.0
                    DelayMS 150
                    Low PORTB.0    
                Next j
            EndIf
            If j > 0 Then
                For j = 5 To 0 Step -1
                    High PORTB.3
                    DelayMS 150
                    Low PORTB.3
                    High PORTB.2
                    DelayMS 150
                    Low PORTB.2
                    High PORTB.1
                    DelayMS 150
                    Low PORTB.1
                    High PORTB.0
                    DelayMS 150
                    Low PORTB.0
                Next j
            EndIf          
    EndIf
    If PORTB.4 = 0 Then
        GoTo Stats
    EndIf






End

Resuelto.
 
Última edición:
Ese tipo de PIC tiene varias opciones para configurar el oscilador interno.
• 32 MHz (requires 4x PLL)
•16 MHz
•8 MHz
•4 MHz
•2 MHz
•1 MHz
• 500 kHz (default after Reset)
• 250 kHz
• 125 kHz
• 62.5 kHz
• 31.25 kHz
• 31 kHz (LFINTOSC)

Esa información la puedes encontrar en la hoja de datos.
Por ejemplo, este programa configura el oscilador interno a 32 MHz y hace destellar un LED en RA0 cada 500 ms.
Código:
[B]Device [COLOR=DarkSlateBlue]12F1822[/COLOR]
[COLOR=DarkRed]Reminders[/COLOR] = Off
Config1 [/B]FOSC_INTOSC, WDTE_OFF, PWRTE_ON, FCMEN_OFF, MCLRE_OFF[B]
Config2 [/B]WRT_OFF, PLLEN_OFF, LVP_OFF[B]
[COLOR=DarkRed]Reminders[/COLOR] = On

[COLOR=DarkRed]Xtal[/COLOR] [/B]= 32MHz[B]
Declare [COLOR=DarkRed]Create_Coff[/COLOR] [/B]=[B] On

[/B]Inicio:[B]
    [COLOR=DarkGreen]OSCCON[/COLOR] = [/B]%11110000[B]
    [COLOR=DarkGreen]ANSELA[/COLOR] [/B]= 0[B]
    Symbol[/B] LED = PORTAbits_RA0[B]
    
    
[COLOR=Red]Rem[/COLOR] [/B]Programa principal:[B]

    While [/B]1 = 1[B]
        Toggle [/B]LED[B]
        DelayMS[/B] 500[B]
    Wend
    
    End[/B]
La sintaxis de la palabra de configuración depende de la versión que estés usando.
Este programa fue escrito con el IDE, versión 2.0.1.0 y Compilador, versión 3.5.7.2
 
Saludos foreros, hace tiempo había comenzado con proton pero la deje un poco de lado por la universidad donde utilizaba assembler, pero ahora quiero retomar a proton por que me gusta mas. :D.

Estoy realizando con la ayuda de un ejemplo de paginas anteriores, pruebas sobre la interrupción externa por rb0, utilizo el 16f877a, para ver como funciona y colocarla en un proyecto futuro, entonces hice un contador ascendente y descendente de 0 a 10 y lo muestro en la pantalla, algo muy sencillo, entonces quiero que cuando ocurra la interrupción, colocar "interrupción" en la pantalla y espere un tiempo corto y luego vuelva al programa contador, pero el problema que tengo es que en la simulación cuando activo el pulsador en la pantalla efectivamente se coloca interrupción pero dura mucho tiempo sin volver al programa principal aun cuando coloco un dalayms 1000, la espera es para ver la pantalla y ya.
A que se deberá esto?. Por que dura tanto en volver al programa?, tengo algo mal configurado?. Agradezco a quien pueda ayudarme, ya he recibido ayuda por aquí y estoy muy agradecido, :D. Adjunto el ejemplo
Código:
Device = 16F877A
Config HS_OSC , WDT_OFF , PWRTE_ON , CP_OFF , LVP_OFF 

XTAL 20

Declare LCD_TYPE    Alpha       
Declare LCD_DTPIN   PORTB.4     
Declare LCD_RSPIN   PORTB.2     
Declare LCD_ENPIN   PORTB.3  
Declare LCD_INTERFACE   4       
Declare LCD_LINES   2  

Dim I As Word 
Cls 

On_Hardware_Interrupt GoTo MyInt
INTCON = %11010000          ; Configurar la Interrupción solo por RB0
OPTION_REG.6 = 0            ; Activar la interrupción por flanco de bajada en RB0

INICIO:
; Aquí tu código principal (Esto es un ejemplo)

    For I = 0 To 10
    
    Print At 1, 1, "Numero", DEC4 I
    DelayMS 500
    Next I 
    
   DelayMS 100
   
    For I = 10 To 0 Step -1   
    
    Print At 1, 1, "Numero", DEC4 I
    DelayMS 500
    Next I 
    
  
       GoTo INICIO

; Esta parte es el controlador de la interrupción.

; Aquí se llega al ejecutarse la interrupción.
Disable
MyInt:
    Context SAVE              ; Guardar el contexto de los registros.
    INTCON.1 = 0            ; Limpiar la bandera de interrupción por RB0
; Aquí el código que se ejecutara durante la interrupción del programa principal.
    Cls
    Print At 1, 1, "Interrupcion"      
   DelayMS 1000
    INTCON=%10010000   
    Context Restore          ; Restaurar el contexto de los registros.
    Resume
    Enable    
    
   
    End
 
No veo nada extraño en el programa que pueda provocar el exceso de retardo que mencionas.
El programa en sí, si tiene algunos detalles que corregir, pero nada para que se tarde tanto en salir de la interrupción.

Si estás simulando, verifica que la frecuencia del microcontrolador sea la misma que en el programa.
 
Pensé en esos mismo pero ya verifique la frecuencia y está bien, me puedes decir que detalles debo mejorar.

Le quite el retardo y funciona bien. Claro la pantalla que dice interrupcion apenas se puede Ver, Pero si vuelve al programa dél contador.
 
Realicé el montaje físicamente para comprobar lo que mencioné, y no existe el retardo excesivo que mencionas.
También hice una simulación, y si el PIC tiene los 4 MHz por defecto del simulador y en el programa 20 MHz, entonces si existe una velocidad de ejecución muy lenta.
Este error al simular es muy común y ya lo había comentado en alguna ocasión.
También he comentado que al simular se deben usar frecuencias bajas. (Esto mejora el proceso porque no se sobrecarga el simulador.)

Si vas a simular debes establecer una frecuencia de 1 MHz o 4 MHz y al microcontrolador le estableces esa frecuencia.
Ya cuando realices el proyecto físicamente, vuelves a establecer la frecuencia normal de operación.

Estos serían los cambios en el programa y basados en la sintaxis de Proton IDE:
PHP:
    Device = 16F877A
    Reminders = Off
    Config HS_OSC, WDT_OFF, PWRTE_ON, LVP_OFF
    Reminders = On

    Declare Xtal 20MHz

    Declare LCD_Type    Alpha       
    Declare LCD_DTPin   PORTB.4     
    Declare LCD_RSPin   PORTB.2     
    Declare LCD_ENPin   PORTB.3  
    Declare LCD_Interface   4       
    Declare LCD_Lines   2  

    Dim I As Byte                ; Como se va a contar hasta 10, no es necesaria una variable del tipo Word

Inicio:  

    On_Hardware_Interrupt GoTo MyInt
    INTCON = %11010000          ; Configurar la Interrupción solo por RB0
    OPTION_REGbits_INTEDG = 0   ; Activar la interrupción por flanco de bajada en RB0
    
    Cls                         ; Inicializa y limpia la pantalla

; Aquí tu código principal (Esto es un ejemplo)
    While 1 = 1
        For I = 0 To 10
            Print At 1, 1, "Numero: ", Dec2 I   ; Usar Dec2, porque sólamente usaremos dos dígitos.
            DelayMS 500
        Next I 
    
        DelayMS 100
   
        For I = 10 To 0 Step -1       
            Print At 1, 1, "Numero: ", Dec2 I
            DelayMS 500
        Next I 
    
    Wend

; Esta parte es el controlador de la interrupción.
; Aquí se llega al ejecutarse la interrupción.
MyInt:
    Context Save                ; Guardar el contexto de los registros.
    
    If INTCONbits_INTF = 1 Then ; Comprobar el bit INTF (External Interrupt Flag Bit)
        ; Aquí el código que se ejecutara durante la interrupción del programa principal.
        Print At 1, 1, "Interrupcion"      
        DelayMS 1000
        Cls                     ; Limpiamos la pantalla al final
                                ; Porque el texto mostrado es superior al anterior.
        INTCONbits_INTF = 0     ; Limpiar la bandera de interrupción por RB0
    End If
    
    Context Restore             ; Restaurar el contexto de los registros.
      
    End
Dejé los mismos comentarios, agregué otros, lo mejoré un poco y eliminé las partes de código redundantes.

Realiza una prueba en físico y verás que el retorno de la interrupción debe durar un poco más de 1 segundo debido al tiempo que tarden en ejecutarse las instrucciones subsecuentes, incluyendo las de escritura para la pantalla. (Unos cuantos milisegundos más)
 
Última edición:
Hola. Tengo un problema para controlar unos servo motores con el PIC16F877A, usando proton.

Primero quise trabajarlos usando una variable Word, pero tengo que apagarla al final para que siga corriendo la programación y no me sirve para la aplicación que le quiero dar a los servos, debido a que vuelven a quedar libra y no quedan en la posición deseada.

He estado intentando hacerlo con HPWM, pero con los datos que me indica colocar, no sé cómo determinar el valor del ciclo de trabajo, la frecuencia y el periodo que son necesarios para poder trabajar con los servo motores.
O no sé qué otra función puedo utilizar para controlar los servo motores.

Gracias por la ayuda que me puedan dar.
 
Última edición por un moderador:
Hola. Tengo un problema para controlar unos servo motores con el PIC16F877A, usando proton.

Primero quise trabajarlos usando una variable Word, pero tengo que apagarla al final para que siga corriendo la programación y no me sirve para la aplicación que le quiero dar a los servos, debido a que vuelven a quedar libra y no quedan en la posición deseada.
¿A qué te refieres con apagar una variable y con que vuelven a quedar libra? :confused:

He estado intentando hacerlo con HPWM, pero con los datos que me indica colocar, no sé cómo determinar el valor del ciclo de trabajo, la frecuencia y el periodo que son necesarios para poder trabajar con los servo motores.
O no sé qué otra función puedo utilizar para controlar los servo motores.
El uso de las instrucciones se encuentra en el documento de ayuda de Proton IDE
Gracias por la ayuda que me puedan dar.
¿Ya leíste la hoja de datos del servo motor que estás usando?

Proton es para lenguaje Basic y en el Foro se encuentran muchos ejemplos para controlar servo motores.
 
He estado intentando hacerlo con HPWM, pero con los datos que me indica colocar, no sé cómo determinar el valor del ciclo de trabajo, la frecuencia y el periodo que son necesarios para poder trabajar con los servo motores.
O no sé qué otra función puedo utilizar para controlar los servo motores.

Gracias por la ayuda que me puedan dar.

Para utilizar los servo motores, debes utilizar la instrucción SERVO

main:
if porta.0 = 0 then
servo portb.0, 1500 'centra el servo
endif
goto main
 
Hola continuando con el manejo de Proton ide dejo aquí una test para un lcd 16x2

Código:
'PROJECT PBP TO PROTON

Device 16F877A
'SUSCRIBETE A MI CANAL EN YOUTUBE  --->https://www.youtube.com/KORZ ES
'ORIGINAL TOPIC ---> http://www.picbasic.co.uk/forum/showthread.php?t=18416&page=2&highlight=matrix+serial
'VIDEO ----> https://www.youtube.com/watch?v=HugwQ4b9iBU 
'DIGITAL RESITOR http://www.protonbasic.co.uk/archive/index.php/t-53777.htm

Xtal 20
				
                                  
'Declare NO_Clrwdt	' watchdog is cleared manually  PBP a Proton+ conversion 
                    'more info --->http://www.protonbasic.co.uk/group.php?gmid=35&do=discuss#gmessage35  
                  

Declare Watchdog = 1

Declare All_Digital = True
Declare LCD_Type 0      ' LCD alfanumerica
Declare LCD_Interface 4 ' 4 lineas de datos
Declare LCD_DTPin PORTA.0 ' lineas de datos al PORTB RB4->RB7
Declare LCD_ENPin PORTB.3 ' EN al pin RB2
Declare LCD_RSPin PORTA.4 ' RS al pin RB3
Declare LCD_Lines 2       ' LCD de cuatro lineas
Declare LCD_DataUs  50				' LCD timing  
Declare LCD_CommandUs 2000				'
'
DATA  142,145,145,143,129,130,140,128		'9 digit roll stored horizontal
DATA  142,145,147,149,153,145,142,128		'0
DATA  132,140,132,132,132,132,142,128		'1
DATA  142,145,129,130,132,136,159,128		'2
DATA  159,130,132,130,129,145,142,128		'3
DATA  130,134,138,146,159,130,130,128		'4
DATA  159,144,158,129,129,145,142,128		'5
DATA  134,136,144,158,145,145,142,128		'6
DATA  159,129,130,132,136,136,136,128		'7
DATA  142,145,145,142,145,145,142,128		'8
DATA  142,145,145,143,129,130,140,128		'9
DATA  142,145,147,149,153,145,142,128		'0
'
DATA %01110000 ' invader frame a
DATA %00011000 ' stored vertical
DATA %01111101 '
DATA %10110110 '
DATA %10111100 '
DATA %00111100 '
DATA %10111100 '
DATA %10110110 '
DATA %01111101 '
DATA %00011000 '
DATA %01110000 '
DATA %10011100 ' invader frame b
DATA %10011000 ' stored vertical
DATA %01111101 '
DATA %00110110 '
DATA %00111100 '
DATA %00111100 '
DATA %00111100 '
DATA %00110110 '
DATA %01111101 '
DATA %10011000 '
DATA %10011100 '
'
DATA  "  edit 2015" ' original LC2D V2 - (c) Brek Martin 
'

Dim dis[51] As Byte 				    ' monochrome display buffer 24x17   
Dim rolls[8] As Byte
'How does one alias an element in a byte array?
Dim rolls0 As rolls#0 : Dim rolls1 As rolls#1
Dim rolls2 As rolls#2 : Dim rolls3 As rolls#3	    '
Dim rolls4 As rolls#4 : Dim rolls5 As rolls#5	    '
Dim rolls6 As rolls#6 : Dim rolls7 As rolls#7
Dim L0 As Byte					              ' LCD RAM index and used as counter
Dim CW As Byte : Dim CL As Byte			    ' multi purpose counters
Dim lind As Byte : Dim pind As Byte			    ' framebuffer indexing variables
Dim slug As Byte :Dim invert As Byte			    ' set invert 0xFF to invert display
Dim wtemp As Word					    '
Dim temp As wtemp.Byte0				    '
Dim tempb As wtemp.Byte1				    '
Dim px As Byte	: Dim py As Byte			    ' coordinates for library routines
'''''''''''''''''''''''''''''''''''''''''''''''''''''
'         END OF DISPLAY BUFFER CODESPACE           '
'''''''''''''''''''''''''''''''''''''''''''''''''''''
'
Dim x As Byte	' user coordinates for 2D graphics
Dim y As Byte	' these are for the user program
'
Dim dy As Byte	' line drawing variables can
Dim y1 As Byte	' be removed if not using lines
Dim y0 As Byte	' line drawing may break if start
Dim dx As Byte	' and end points are the same
Dim x1 As Byte	' which is not yet tested
Dim x0 As Byte	' thanks to oogabooga to for
Dim stepx As Byte	' optimisation of my code for
Dim stepy As Byte	' PBP unsigned integer bytes
Dim frac As Byte	' expand to words for bigger LCD
'
Dim ftick As Byte	' frame count variables can
Dim frame As Byte	' be removed if not counting
'
Dim dval As Byte	' value for printed variable
Dim digit As Byte	' buffer for printing sprites
Dim index As Byte	' eeprom index for sprite data
Dim dgx As Byte	' coordinates to print sprite
Dim dgy As Byte	'
Dim demd As Byte	' actual digits on the screen
Dim demdl As Byte	'
Dim dfc As Byte	' digit frame counter
'
'	circle drawing variables can be removed
'	if you remove the circle drawing routine
'   	some variables are shared with square drawing
'	this circle routine is borrowed from the GLCD
'	library posted by Dave on MELabs PBP forum
'	do not draw circles with radius less than 3.
'
Dim cx As Byte	' shared with square drawing routine
Dim cy As Byte	'
Dim glc_x As Byte	'
Dim glc_y As Byte	'
Dim glc_s As Word	' slope
Dim radius As Byte	' radius
'
Dim cdx As Byte	' circle demo horizontal coordinate
'
Dim doff As Byte	' digit odometer effect variables
Dim doffl As Byte	'
Dim doffm As Byte	'
Dim dcompl As Byte '
Dim dcompm As Byte '
Dim ddirl As Bit	' digit counting direction variables
Dim ddirm As Bit	' not implemented yet - out of memory
'
Dim xdir As Bit	' direction variables that can be
Dim ydir As Bit	' removed if not running the demo
'
Dim backled As Bit ' LED backlight flash status
'
invert = $FF	' 0xFF to invert display colours
'
'
' execution time!
'
CMCON = 7	' set portb to digital
TRISB.6 = 0	'set LCD backlight output
'
'the demo program turns on the backlight
'turn it on here if your program does not
'portb.6 = 1'turn on LCD backlight
'
backled = 1	' initially set led backlight on
ftick = 0	' reset demo section counter
frame = 0	' reset frame counters
x = 2		' set intial point coordinates
y = 2		'
cdx = 11	' set initial circle position
dfc = 0		' reset some variables that could
doff = 0	' break things if not initialised
dval = 0	'
demd = 0	'
demdl = 0	'
digit = 0	'
'
DelayMS 1200	'delayms for LCD to start
Print $FE,1	'clear LCD
'
'
cycle:		' main routine - demo user program
@ clrwdt	; clear watchdog timer manually
'
x = x - 1		' move the point for the demo
If xdir = 0 Then	' the moving point controlls
x = x + 2		' most of the demo parts
EndIf
y = y - 1
If ydir = 0 Then
y = y + 2
EndIf
'
If ftick < 4 & ftick != 1 Then ' draw the moving point
px = x+0 : py = y+0 ' draw point
GoSub setpixel
EndIf
'
If ftick = 0 Then 	' draw rest of the ball around moving point
px = x+1 : py = y+0	' this is the first demo part
GoSub setpixel
px = x-1 : py = y+0
GoSub setpixel
px = x+0 : py = y+1
GoSub setpixel
px = x+0 : py = y-1
GoSub setpixel
EndIf
'
If x > 21 And xdir = 0 Then ' check the screen bounds
xdir = 1		     ' for the point we are moving around
EndIf   
If x < 1 And xdir = 1 Then
xdir = 0
EndIf
If y > 15 And ydir = 0 Then
ydir = 1
EndIf
If y < 1 And ydir = 1 Then
ydir = 0
EndIf
'
If ftick = 1 Then 	' draw dynamic circles
cx = x : cy  = y	' this is the second demo part
radius = (y/2) + 2
GoSub  drawcircle
EndIf
'
If ftick = 2 Then 	' draw dynamic lines
x0 = 0 : y0 = 0		' which is an example of diagonal lines
x1 = x : y1 = y
GoSub drawline
x0 = x : y0 = y
x1 = 22 : y1 = 0
GoSub drawline
x0 = x : y0 = y
x1 = 22 : y1 = 16
GoSub drawline
x0 = 0 : y0 = 16
x1 = x : y1 = y
GoSub drawline
EndIf
'
If ftick = 3 Then	' draw the crosshair effect
x0 = x : y0 = 0		' which is an example of straight lines
x1 = x : y1 = 16
GoSub drawline
x0 = 0 : y0 = y
x1 = 22 : y1 = y
GoSub drawline
EndIf
'
If ftick = 4 Then 	' draw digits
dval = demd /10		' which is an example of drawing sprites
demdl = demd		' where the data was stored horizontal
demdl = demdl - (dval * 10)
dgx = x-6 : dgy = y-4
GoSub printdigit
dval = demdl
dgx = x+1 : dgy = y-4
GoSub printdigit
EndIf
'
If ftick = 5 Then	' squares
x0 = 11 : y0 = 8
radius = dfc
GoSub drawsquare
EndIf
'
If ftick = 6 Then	' squares with strobe
radius = dfc		' coords were set in previous section
GoSub drawsquare
EndIf
'
If ftick = 7 Then	' more squares
x0 = x : y0 = y
radius = 5
GoSub drawsquare
EndIf
'
If ftick = 8 Then	' dynamic squares
x0 = x : y0 = y
radius = y/2
GoSub drawsquare
EndIf
'
If ftick = 9 Then	' draw invader sprite
dgx = x-5 : dgy = y-4	' which is an example of animated sprite
GoSub printsprite	' where the data was stored vertically
EndIf
'
If ftick = 10 Then	' circles trick
cx = cdx : cy  = 8	' a trick to look like the entire LCD is used
radius = 7
GoSub  drawcircle
cx = cdx + 24
GoSub  drawcircle
cdx = cdx - 1
EndIf
'
If ftick == 11 Or ftick == 12 Then	' dynamic circles trick with strobe
cx = cdx : cy  = 8		' a trick to look like the entire LCD is used
radius = (y/2) + 2		'
If ftick = 12 Then
cy = 15 - y
EndIf
GoSub  drawcircle
cx = cdx + 24
GoSub  drawcircle
cdx = cdx - 1
EndIf
'
If ftick = 13 Then	' rolling odometer effect display
dval = demd /10		' the odometer display also moves
demdl = demd		' around the display
demdl = demdl - (dval * 10)
If dval != dcompm Then
'ddirm = 0		' determine digit count direction
'IF dval < dcompm THEN	' odometer only works on a variable
'ddirm = 1		' that is being incremented by one
'ENDIF			' not enough memory to reverse
dcompm = dval
doffm = 8
EndIf
doff = doffm
If doffm > 0 Then
doffm = doffm - 1
EndIf
dgx = x-6 : dgy = y-4
GoSub printdigit
If demdl != dcompl Then
'ddirl = 0		' determine digit count direction
'IF demdl < dcompl THEN	' oops, ran out of memory to reverse
'ddirl = 1		' the roll direction of movement
'ENDIF			' so this is incomplete
dcompl = demdl
doffl = 8
EndIf
doff = doffl
If doffl > 0 Then
doffl = doffl - 1
EndIf
dval = demdl
dgx = x+1 : dgy = y-4
GoSub printdigit
EndIf
'
If ftick == 14 Then ' dynamic squares trick
x0 = cdx : y0  = 8  ' a trick to look like the entire LCD is used
radius = (y/2) + 2  '
GoSub  drawsquare
x0 = cdx + 24
GoSub  drawsquare
cdx = cdx - 1
EndIf
'
If cdx = 242 Then	' check bounds for moving circle demos
cdx = 10		'
EndIf			'
'
If ftick = 15 Then	' reset demo section counter
ftick = 0		' there are currently fifteen demo parts
doff = 0
EndIf	
'
'
GoSub writecg		' write the frame buffer to LCD
'
'
frame = frame + 1	' count actual frames
If frame = 150 Then	'
frame = 0		'
ftick = ftick + 1	' frame counter increments demo counter
invert = $00		' revert to normal after first section
EndIf
'
dfc = dfc + 1		' increment the dynamic squares width
If dfc > 8 Then		'
dfc = 0			'
demd = demd + 1		' increment counter for display variable
EndIf			'
If demd > 99 Then	' keep display variable in two digit range
demd = 0		'
EndIf			'
'
If ftick = 4 Or ftick = 9 Or ftick = 13 Then	' variable sprite delay
DelayMS ftick*20					' for all digit and invader sprites
EndIf						' otherwise lcd lag messes up the display
'
PORTB.6 = 1					' strobe the LED backlight
If ftick = 6 Or ftick = 11 Then			' for these demo sections only
backled = backled + 1				' alternate backlight status
PORTB.6 = backled				' set led backlight to current status
EndIf						'
'
GoTo cycle					' end main routine - do the next frame
'
'
'
'
setpixel:	  ' size and performance win for V2
lind = py * 3 ' byte index for line
pind = 0
slug = px
If px > 7 Then
pind = 1
slug = px - 8
EndIf
If px > 15 Then
pind = pind + 1
slug = px - 16
EndIf
If lind+pind < 51 Then ' range check
temp = dis[lind+pind]
For CW = 0 To 7
If slug = CW Then
temp.7 = 1
EndIf
wtemp = wtemp << 1
Next CW
dis[lind+pind] = tempb
EndIf
Return
'
writecg:	' size, ram and performance win for V2
L0 = $40	' reset lines
For CL = 0 To 7 ' write first half of display
For CW = 0 To 3
rolls[CW] = (dis[0] ^ invert) >> 3
GoSub Rotate
Next CW
Print $FE,L0+$00,rolls[0]
Print $FE,L0+$08,rolls[1]
Print $FE,L0+$10,rolls[2]
Print $FE,L0+$18,rolls[3]
L0 = L0 + 1'
Next CL
For CW = 0 To 23 ' skip invisible line
GoSub RotateDisplay
Next CW
L0 = $60	' reset lines
For CL = 0 To 7 ' write second half of display
For CW = 0 To 3
rolls[CW] = (dis[0] ^ invert) >> 3
GoSub Rotate
Next CW
Print $FE,L0+$00,rolls[0]
Print $FE,L0+$08,rolls[1]
Print $FE,L0+$10,rolls[2]
Print $FE,L0+$18,rolls[3]
L0 = L0 + 1'
Next CL
' draw to LCD
Print $FE,$80	'draw first line of display
For CL = 0 To 3
Print 0,1,2,3	'
Next CL
Print $FE,$C0	'draw second line of display
For CL = 0 To 3
Print 4,5,6,7					'
Next CL
Return
'
printdigit:	' print a single digit to screen
index = dval * 8' set index position for digit
For L0 = 0 To 7
GoSub readeep
For CL = 0 To 4
If digit.4 = 1 Then
px = dgx+CL : py = dgy+L0
GoSub setpixel
EndIf
digit = digit << 1
Next CL
index = index + 1
Next L0
Return
'
printsprite:	' print a monochrome graphic sprite to screen
index = 88	' set index position for sprite
If frame.3 = 1 Then ' select frame
index = index + 11
EndIf
For L0 = 0 To 10
GoSub readeep
For CL = 0 To 7
If digit.0 = 1 Then
py = dgx+CL : px = dgy+L0
GoSub setpixel
EndIf
digit = digit >> 1
Next CL
index = index + 1
Next L0
Return
'
readeep:
'READ index+8,digit		' not ever using the rolling odometer effect
digit = ERead (index-doff)+8' are using rolling odometer effect sometimes
Return				' slight performance penalty if you are
'
drawsquare:		' draw square to screen
  cx = radius : cy = 0
  While cx >= cy
	px = cx + x0 : py = cy + y0
	GoSub setpixel
	px = cy + x0 : py = cx + y0
	GoSub setpixel
	px = -cx + x0 : py = cy + y0
	GoSub setpixel
    px = -cy + x0 : py = cx + y0
	GoSub setpixel
    px = -cx + x0 : py = -cy + y0
	GoSub setpixel
    px = -cy + x0 : py = -cx + y0
	GoSub setpixel
    px = cx + x0 : py = -cy + y0
	GoSub setpixel
    px = cy + x0 : py = -cx + y0
	GoSub setpixel
    cy = cy + 1
  Wend
Return
'
drawcircle:		' draw circle to screen
  	glc_x = 0
  	glc_y = radius
  	glc_s = 2-2*radius
  	While glc_x <= glc_y
	px = glc_x+cx : py=glc_y+cy
	GoSub setpixel
	px = cx-glc_x : py=glc_y+cy
	GoSub setpixel
	px = cx+glc_x : py=cy-glc_y
	GoSub setpixel
	px = cx-glc_x : py=cy-glc_y
	GoSub setpixel
	px = glc_y+cx : py=glc_x+cy
	GoSub setpixel			
	px = cx-glc_y : py=cy+glc_x
	GoSub setpixel
	px = cx+glc_y : py=cy-glc_x
	GoSub setpixel
	px = cx-glc_y : py=cy-glc_x
	GoSub setpixel
	If glc_s.15 =1 Then
    glc_s = glc_s + (4*glc_x + 6)
    Else
    glc_s = glc_s + (4*(glc_x-glc_y) + 10)
    glc_y = glc_y - 1
	EndIf
	glc_x = glc_x + 1
  	Wend
Return
'
drawline:	' draw any line to screen including diagonals
	stepx = 0
	stepy = 0
	frac = 0
	'line from start point x0,y0 to destination point x1,y1.
	dy = y1 - y0
	dx = x1 - x0
	If dy > 128 Then
    dy = 0 - dy
    stepy = stepy - 1
    Else
    stepy = 1
    EndIf
	If dx > 128 Then
    dx = 0 - dx
    stepx = stepx - 1
    Else
    stepx = 1
    EndIf
	dy = dy << 1
	dx = dx << 1
    'draw pixel
	px = x0 : py = y0
	GoSub setpixel
	If dx > dy Or dx > 128 Then
    frac = dy - (dx >> 1)
    While x0 != x1
    If frac < 128 Then
	y0 = y0 + stepy
 	frac = frac - dx
	EndIf
    x0 = x0 + stepx
    frac = frac + dy
    'draw pixel
	px = x0 : py = y0
	GoSub setpixel
    Wend
	Else
    frac = dx - (dy >> 1)
    While y0 != y1
    If frac < 128  Then 
	x0 = x0 + stepx
	frac = frac - dy
	EndIf
    y0 = y0 + stepy
    frac = frac + dx
    'draw pixel
	px = x0 : py = y0
	GoSub setpixel
    Wend
	EndIf
Return
'
Rotate:									' the only assembler routine
GoSub rota								' needed for speed
rota:									' by neglecting to carry the
GoSub RotateDisplay						' status bit, it also clears
GoSub RotateDisplay						' the buffer for the next frame
RotateDisplay:							' bitwise rotate array right


   @ Rlf        dis + 50       ,F				; ditching the first bit
   @ Rlf        dis+49		,F				;
   @ Rlf        dis+48		,F				;
   @ Rlf        dis+47		,F				;
   @ Rlf        dis+46		,F				;
   @ Rlf        dis+45		,F				;
   @ Rlf        dis+44		,F				;
   @ Rlf        dis+43		,F				;
   @ Rlf		 dis+42		,F				;
   @ Rlf		 dis+41		,F				;
   @ Rlf		 dis+40		,F				;
   @ Rlf		 dis+39		,F				;
   @ Rlf		 dis+38		,F				;
   @ Rlf		 dis+37		,F				;
   @ Rlf		 dis+36		,F				;
   @ Rlf		 dis+35		,F				;
   @ Rlf		 dis+34		,F				;
   @ Rlf		 dis+33		,F				;
   @ Rlf		 dis+32		,F				;
   @ Rlf		 dis+31		,F				;
   @ Rlf		 dis+30		,F				;
   @ Rlf		 dis+29		,F				;
   @ Rlf		 dis+28		,F				;
   @ Rlf		 dis+27		,F				;
   @ Rlf		 dis+26		,F				;
   @ Rlf		 dis+25		,F				;
   @ Rlf		 dis+24		,F				;
   @ Rlf		 dis+23		,F				;
   @ Rlf		 dis+22		,F				;
   @ Rlf		 dis+21		,F				;
   @ Rlf		 dis+20		,F				;
   @ Rlf		 dis+19		,F				;
   @ Rlf		 dis+18		,F				;
   @ Rlf		 dis+17		,F				;
   @ Rlf		 dis+16		,F				;
   @ Rlf		 dis+15		,F				;
   @ Rlf		 dis+14		,F				;
   @ Rlf		 dis+13		,F				;
   @ Rlf		 dis+12		,F				;
   @ Rlf		 dis+11		,F				;
   @ Rlf		 dis+10		,F				;
   @ Rlf		 dis+9		,F				;
   @ Rlf		 dis+8		,F				;
   @ Rlf		 dis+7		,F				;
   @ Rlf		 dis+6		,F				;
   @ Rlf		 dis+5		,F				;
   @ Rlf		 dis+4		,F				;
   @ Rlf		 dis+3		,F				;
   @ Rlf		 dis+2		,F				;
   @ Rlf		 dis+1		,F				;
   @ Rlf		 dis+0		,F				;
   @ Bcf		 dis+50		,0				;clear MSB
Return


Aqui el video simulando en Proteus



res.JPG

En Proteus se selecciona - > resistencia tipo digital para este caso
 
Atrás
Arriba