desktop

Curso de programación de PIC en PICBasic Pro

hola amigos buenas noches vengo por aca buscando una ayuda con este codigo, es variador de velocidad activado por interrupcion en el puerto B0 y por TMR0, resulta que cuando quiero visualizar en un display LCD, el programa se desconfigura, he tratado de usar la instruccion SEROUT para visualizarlo en otro pic pero tambien pasa lo mismo.
He intentado varias cosas pero no me da :cry: .
De ante mano muchas por tan excelente foro me a ayudado bastanto a enterder el lenguaje Basic.
Aqui el codigo y adjunto la simulacion en proteus 8.

Código:
CLEAR                                                       ;Limpio la memoria RAM
INCLUDE "MODEDEFS.BAS"
DEFINE CHAR_PACING 1000
'************************** CONFIGURACION DE FUSES *****************************

_INTRC_OSC_NOCLKOUT                                         ' Reloj interno solo.-
_WDT_OFF                                                    ' Watchdog Timer desconectado.-
_PWRT_ON                                                    ' Power-On Timer conectado.- 
_BOD_OFF                                                    ' Brown-Out Detect conectado.- 
_MCLR_OFF                                                   ' Master Clear Externo desconectado.-
_LVP_OFF                                                    ' Low-Voltage Programming desconectado.-
_CPD_OFF                                                    ' Data Memory Code Protect desconectado.-
_PROTECT_OFF                                                ' Program Code Protection desconectado.-

'******************** DEFINICION DE REGISTROS Y PUERTOS ************************

CMCON = 7 
TRISA = %0111
TRISB = %00000000
PORTB = %11111100
'PORTB = %001000
'****************** DEFINICION DE LA PANTALLA LCD ******************************

DEFINE LCD_BIT 4
DEFINE LCD_LINES 2
DEFINE LCD_DREG PORTB                                       ; configuro la pantalla LCD
DEFINE LCD_DBIT 4
DEFINE LCD_RSREG PORTB
DEFINE LCD_RSBIT  2
DEFINE LCD_EREG PORTB
DEFINE LCD_EBIT 3

'******************** ASIGNACION DE VARIABLES **********************************
 
DISMINUIR   VAR PORTA.0
START_STOP  VAR PORTA.1
AUMENTAR    VAR PORTA.2
;LEDR        VAR PORTB.3
LEDV        VAR PORTA.3
ON_OFF      VAR BIT
POWER       VAR WORD
VISUALIZAR  VAR BYTE
'******************** ASIGNACION DE ALIAS AL REGISTRO INCONT *******************

SYMBOL GIE  = INTCON.7                                      ;Habilitador de interrupciones, 1 habilita - 0 desabilita 
SYMBOL TOIE = INTCON.5                                      ;Habilita la interrupcion por TMR0, 1 habilita - 0 desabilita
SYMBOL INTE = INTCON.4                                      ;Habilita la interrupcion por RB0, 1 habilita - 0 desabilita
SYMBOL TOIF = INTCON.2                                      ;Bandedera de interrupcion por desborde del TMR0, 1 TMR0 pasa de 255 a 0
SYMBOL INTF = INTCON.1                                      ;Bandera de interrupcion por RB0, 1 cuando ocurre interrupcion por RB0

'******************** ASIGNACION DE ALIAS AL REGISTRO OPTION *******************

'symbol RBPU   = OPTION_REG.7                                ;Activacion de las resistencias PullUp 1 ON - 0 OFF
'SYMBOL INTEDG = OPTION_REG.6                                ;Flanco activo de la int. externa 1 ASCENDENTE - 0 DESCENDENTE
'SYMBOL TOCS   = OPTION_REG.5                                ;Senal de reloj 1 POR RA4 - 0 RELOJ INTERNO
''SYMBOL TOSE   = OPTION_REG.4                                ;Incremento de TMR0 por RA4
'SYMBOL PSA    = OPTION_REG.3                                ;Divisor de frecuencia 1 WTD - 0 TMR0
'SYMBOL PS2    = OPTION_REG.2                                ;1        1        1       1       0       0      0      0
'SYMBOL PS1    = OPTION_REG.1                                ;1 = 256  1 = 128  0 = 64  0 = 32  1 = 16  1 = 8  0 = 4  0 = 2
'SYMBOL PS0    = OPTION_REG.0                                ;1        0        1       0       1       0      1      0

ON INTERRUPT GOTO IRS                                       ;Habilito la interrupcion

'INTCON = %10010000                                          ;Habilito las interrupciones por RB.0 y por el Timer0
'OPTION_REG=%00000101                                        ;configuro el registro OPTION_REG
HIGH LEDV                                                   ;
PAUSE 2000                                                  ;Prender y apagra el led durante 2 segundos
LOW LEDV                                                    ;
POWER= 216                                                  ;Inicio la variable power con 255
TMR0=126                                                    ;Inicio el TMR0 con 126 

'************************* INICIO DEL PROGRAMA *********************************

INICIO:        
'        SEROUT PORTB.2,T2400,[POWER,13,10]  
'        LCDOUT $FE, 1, "ESTADO:"
'        LCDOUT $FE, $C0, dec power,"-", dec TMR0
        'pause  500
        IF  START_STOP=0    THEN PRENDER_APAGAR
        IF  DISMINUIR=0     THEN BAJAR
        IF  AUMENTAR=0      THEN SUBIR
        
GOTO INICIO

'************************** PRESION DE TECLAS **********************************

PRENDER_APAGAR:

        IF  START_STOP=0  THEN                              ;Si start-stop es = 0
        while START_STOP=0
        wend       
        pause 50                                            ;pause 50 ms
        toggle ON_OFF                                       ;Colocar en estado contrario la bandera on_off 
                                                            ;(si esta en 1 pase a 0 o viceverza)
        ENDIF
    IF  ON_OFF=1 THEN                                       ;Si on_off esta en 1 
        HIGH LEDV                                           ;Prender led verde        
        OPTION_REG=%11000101                               ;RBPU=1- INTEDG=1- T0CS=0- T0SE=0- PSA=0- PS=64
'        RBPU= 1 : INTEDG= 1 : TOCS= 0 : PSA= 0 : PS2= 1 : PS1=0 : PS0= 1                     
        GIE= 1 : INTE= 1 :
        TRISB.0=1                                           ;Activar la interrupcion por RB0   
    else
        ON_OFF=0
'        IF power <= 255 THEN 
'            POWER = 255
'        ENDIF
        POWER = 216
        TRISB.0=0        
        LOW portb.1
        LOW LEDV
        OPTION_REG=%10000000
        INTCON=%10010000
    ENDIF
GOTO INICIO

BAJAR:

        IF  DISMINUIR=0 THEN
        while DISMINUIR=0
        wend
        POWER=POWER+10 
            IF POWER>=255 THEN 
               POWER = 255                                                         
            ENDIF
        ENDIF
GOTO INICIO

SUBIR:

        IF AUMENTAR=0 THEN
        while AUMENTAR=0
        wend
        POWER=POWER-10    
            IF POWER<=127 THEN 
               POWER=127                            
            ENDIF
        ENDIF
GOTO INICIO

''***************************** INTERRUPCION ************************************
 
disable
IRS:                                 
    if INTF = 1 then                                        ;Pregunto si bandera de interrupcion por RB0 esta en 1 entonces                             
       toie = 1                                             ;Habilita la interrupcion por TMR0 habilita la interrupción por B.0       
       TMR0=126-power                                       ;Variar el valor del TMR0 
       LOW portb.1                                          ;Apago portb.1
       intf = 0                                             ;Bandera de interrupcion por RB0, 0 para inicializar la interrupcion por RB0
    ENDIF

    IF TOIF = 1 THEN                                        ;habilito la bandedera de interrupcion por desborde del TMR0                                                       
       HIGH PORTB.1                                         ;Prendo el puerto portb.1
       TOIF = 0                                             ;Bandedera de interrupcion por desborde del TMR0, 0 para inicializar       
       
    ENDIF

RESUME 'PRENDER_APAGAR                                      ;Volver a donde ocurrio la interrupcion
ENABLE                                                      ;Habilito la interrupcion
END                                                         ;Fin del programa

PD: Disculpa subi los archivos que no eran, el codigo sirve para los dos, lo unico es modificar el codigo para que funcione.

en archivo final con LCD y RS232 esta el codigo del otro pic que recibe los datos.

.
 

Adjuntos

  • VARIADOR DE VELOCIDAD Final con LCD.rar
    25.1 KB · Visitas: 46
  • VARIADOR DE VELOCIDAD Final con LCD y RS232.rar
    28.3 KB · Visitas: 50
Última edición:
Hola amigos, buenas noches, vengo por acá buscando una ayuda con este código, es variador de velocidad activado por interrupción en el puerto B0 y por TMR0, resulta que cuando quiero visualizar en un display LCD, el programa se desconfigura, he tratado de usar la instrucción SEROUT para visualizarlo en otro pic pero también pasa lo mismo.
He intentado varias cosas pero no me da. :cry:
Pues yo veo dos cosas raras con lo que adjuntas.

  1. Únicamente adjuntas el programa de un microcontrolador. U1, pero ese PIC no tiene la pantalla.
  2. Al no tener conectada ninguna pantalla, pues es lógico que cuando uses las instrucciones LCDOut, todo se comporte extraño, porque tienes configurado usar el puerto B para la pantalla y al mismo tiempo para otros periféricos en uso.
 
D@rkbytes, muchas gracias por responder, ya edité de nuevo y monte los archivos correctos para que los puedan mirar.
A ver, algo sigue mal entonces.
Aún sigue faltando un archivo. "ensayo lcd.hex" ese es para U2.
Y para U1, se tiene como referencia al archivo "VARIADOR DE VELOCIDAD FINAL.hex", pero estás adjuntando un archivo llamado "Enlace RS232 y LCD.bas"

Corrige esos detalles y adjunta el proyecto con los archivos correctos en cada PIC, de otra forma no se puede saber qué está pasando.
Comprende que si falta un archivo, no se puede ejecutar la simulación.

El código sirve para los dos, lo único es modificar el código para que funcione.

En el archivo final con LCD y RS232 está el código del otro pic que recibe los datos.
No había visto este nuevo agregado del post #2829.

Vamos a empezar por corregir la palabra de configuración:
La que tienes no es válida para PICBasic Pro.
Debes usar ésta, tomando como base la que pusiste:
Código:
[COLOR=SeaGreen]@ Device INTRC_OSC_NOCLKOUT,WDT_OFF,MCLR_OFF,PWRT_ON,BOD_OFF,LVP_OFF[/COLOR]
También es necesario que especifiques la frecuencia de operación con Define OSC 4 ( Por ejemplo.)
En este caso no hay problema, pues estás usando el oscilador interno de un PIC16F628A y por defecto estará en 4MHz. Y PBP usa esa frecuencia por defecto cuando no se especifíca.
Pero si usas un cristal u otra frecuencia que no sea de 4MHz. Si tendrás que definirla.
Tampoco es conveniente que coloques retardos dentro del bucle cuando haces uso de SerIn

Ahora, ¿Podrías explicar con detalles qué es lo que ocurre?
¿Cuál es el problema específicamente cuando te refieres a que el programa se desconfigura?
 
Última edición:
A ver, algo sigue mal entonces.
Aún sigue faltando un archivo. "ensayo lcd.hex" ese es para U2.
Y para U1, se tiene como referencia al archivo "VARIADOR DE VELOCIDAD FINAL.hex", pero estás adjuntando un archivo llamado "Enlace RS232 y LCD.bas"

Corrige esos detalles y adjunta el proyecto con los archivos correctos en cada PIC, de otra forma no se puede saber qué está pasando.
Comprende que si falta un archivo, no se puede ejecutar la simulación.


No había visto este nuevo agregado del post #2829.

Hola darkbyte lo unico que hay que hacer es montarle nuevamente el codigo hex a los micros, osea los que adjunte, los que aparecen como referencia no son, no se porque lo esta mostrando.
El archivo rar que dice VARIADOR DE VELOCIDAD Final con LCD.rar es el codigo que coloque en el post y sirve para el que dice VARIADOR DE VELOCIDAD Final con LCD y RS232.rar, para el pic que recibe el dato tambien le montas el archivo .hex que se encuentra VARIADOR DE VELOCIDAD Final con LCD y RS232.
de :apreton: muchas gracias
 
Vamos a empezar por corregir la palabra de configuración:
La que tienes no es válida para PICBasic Pro.
Debes usar ésta, tomando como base la que pusiste:
Código:
[COLOR=SeaGreen]@ Device INTRC_OSC_NOCLKOUT,WDT_OFF,MCLR_OFF,PWRT_ON,BOD_OFF,LVP_OFF[/COLOR]

Hola, en esta parte me toco colocar la configuracion de los fuses asi ya que utilizo w7 a 64 bit y no me dejaba compilar con el que trae PBP.


Tampoco es conveniente que coloques retardos dentro del bucle cuando haces uso de SerIn

Bueno en esta parte si me perdi, yo he puesto el SEROUT en la interrupcion, en la etiqueta inicio y a un asi el programa no trabaja bien.

Ahora, ¿Podrías explicar con detalles qué es lo que ocurre?
¿Cuál es el problema específicamente cuando te refieres a que el programa se desconfigura?

Este programa lo que hace es detectar el cruce por cero por B.0 a 60 Hz de la red, yo cojo los dos ciclos y me queda en 120 Hz, la cosa radica en que cuando voy a ingresar el codigo para visualizar en el LCD o con la instruccion SEROUT, ya no me trabaja a los 120 Hz y se distorciona el ciclo de trabajo.

Una pregunta cuantos ciclos de maquina utiliza la instruccion LCDOUT y la SEROUT?
 
Este programa lo que hace es detectar el cruce por cero por B.0 a 60 Hz de la red, yo cojo los dos ciclos y me queda en 120 Hz.
La cosa radica en que cuando voy a ingresar el código para visualizar en el LCD o con la instrucción SEROUT, ya no me trabaja a los 120 Hz y se distorciona el ciclo de trabajo.

Una pregunta: ¿Cuantos ciclos de maquina utiliza la instrucción LCDOUT y la SEROUT?
OK. He realizado algunos cambios importantes al programa, tanto en la forma de llamar a las rutinas, ahora se hace uso de la instrucción "Button", el uso del módulo USART para mejorar la transmisión y recepción de datos, y otras cosas como la activación y detención del motor.

Anteriormente estabas creando una contención lógica al hacer salida RB0. Ahora eso se ha corregido.

Ahora ya se puede visualizar correctamente la lectura RS-232 en la pantalla, esto te servirá para mirar bien el valor enviado por el PIC transmisor.

El diseño de simulación también lo he modificado para trabajar únicamente con señales digitales y hacer más ligera la ejecución.
Sobre este aspecto hay algo importante. Tu simulador es una versión inferior al que yo tengo y posiblemente no puedas abrir el que adjunto, pero también incluyo el mismo diseño con la versión 7.10 que sí podrás abrir con la versión 8.
Ejecuta ISIS y en el dialogo de abrir, seleccionas Desing Files en vez de Project Files.

Así como está ahora el programa de control del motor, ya será más fácil que puedas encontrar errores.
Necesitas ver como funciona ahora e ir viendo la forma de onda en cuanto al valor de POWER.

Y en cuanto a cuantos ciclos de máquina se ejecutan en las instrucciones LCDOut y SerOut, es complicado saber, se tendrían que encontrar esas rutinas en el archivo *.lst que se crea al compilar.

Como nota final:
Los programas los compilé usando PBP3, pero puedes comentar la palabra de configuración y cargar los archivos *.hex, en vez de los archivos *.cof.

Y así como tienes declarada la palabra de configuración, no creo que tenga efecto.
Mira por aquí para que veas como lo puedes hacer con Windows a 64 bits. Fuses con MPASM
 

Adjuntos

  • 16F628A Variador de velocidad.rar
    100.5 KB · Visitas: 72
Pregunta:

alguien sabe como detectar un deborde de una suma de dos variables con ensamblador embebido, en otras palabras, quiero hacer una suma y ver si deborda.

pseudocodigo:
A var byte
B var byte

A=100
B=180
A=A+B

Aqui el resultado A seria 280 pero como es de tipo byte desbordaria y queria saber si se coloca el valor en el registo F o W como 1 si se desborda o 0 si no desborda o en alguna bandera. para despues mover ese valor con RLF a una variable Temp mas o menos asi:

@ RLF X,w
donde X es 1 si debordo y 0 si no desbordo la suma...

ya lo intente pero no funciono, porque al parecer ahi no se registra el desborde y quiero hacer la rotacion en ensamblador para evitar usar mucho codigo, o algun algoritmo que no implique usar mucho codigo BASIC que genere mucho codigo ASM.

espero haberme explicado XD
 
Última edición:
El codigo con referente al reloj calentario lo estaba realizando teniendo las siguientes consideraciones, selecionar el dia , el mes ,el año y el uso horario es decir 24 hrs y 12 hrs en el utimo caso apareciendo en el lcd AM y PM respectivamente por medio de tres pulsadores, se podia acceder al menu correspondiente actualizandose el reloj una vez configurado. lo de la alarma tiene el mismo principio ya que solamente habria que accesar a la memoria EEPROM del pic a utilizar guardar una constante para luego cambiarla por medio de un menu y activarla cuando llegase la hora.

dejo aqui el codigo en pic basic pro es extenso
Código:
'RELOJ CALENDARIO CON PIC 16F84a ,LCD Y DS 1307
'CONFIGURACION OSCILADOR

@ device xt_osc ; oscilador externo XT 
define osc 4 ; especifica que se va a utilizar uno de 4 Mhz 


'CONFIFURACION LCD
		
Define LCD_DREG PORTA	
Define LCD_DBIT 0	
Define LCD_RSREG PORTA	
Define LCD_RSBIT 6	
Define LCD_EREG PORTA	
Define LCD_EBIT 7	
Define LCB_BITS 4	
Define LCD_LINES 2	
Define LCD_COMMANDUS 2000
Define LCD_DATAUS 50	

'CONFIGURACION DS1307 

SQWpin var PORTB.0
SCLpin var PORTB.1
SDApin var PORTB.2
		
'CONFIGURACION DE PINES
		
DecButton var PORTB.4	' Presionar para decrementar
SetButton var PORTB.5	' Presionar para memorizar
IncButton var PORTB.6	' Presionar para incrementar
		
'CPNFIGURACION MESES,DIAS

Data @0,74,97,110,70,101,98,77,97,114,65,112,114
		' Jan Feb Mar Apr
Data 77,97,121,74,117,110,74,117,108,65,117,103
		' May Jun Jul Aug
Data 83,101,112,79,99,116,78,111,118,68,101,99
		' Sep Oct Nov Dec
Data 84,117,101,87,101,100,84,104,117,70,114,105
		' Tue Wed Thu Fri
Data 83,97,116,83,117,110,77,111,110
		' Sat Sun Mon
'CREACION DE VARIABLES

CounterA var byte	
CounterB var byte	
CounterC var byte	
CounterD var byte	
RTCSec var byte		
RTCMin var byte		
RTCHour var byte	
RTCWDay var byte	
RTCDay var byte		
RTCMonth var byte	
RTCYear var byte	
RTCCtrl var byte	
SetTime var byte	
SetSec var byte		
SetMin var byte		
SetHour var byte	
SetDay var byte		
SetMonth var byte	
SetYear var byte	
TimeOut var word	

'CONTANTES DEL PROGRAMA 
ButtonRepeat con 200 

'inicio del programa
goto JumpStart
ConvertBCD:
CounterB=CounterA DIG 1
CounterB=CounterB<<4
CounterB=CounterB+CounterA DIG 0
Return

DisplayMonth:
CounterB=CounterB*3-3	
DisplaySequence:
For CounterA=CounterB to CounterB+2
Read CounterA,CounterD
LCDOut CounterD
Next CounterA
Return

'SUBRUTINA PARA NUMERO DE DIAS Y MESES
FindDays:
LookUp SetMonth-1,[31,28,31,30,31,30,31,31,30,31,30,31],CounterA
If SetMonth=2 then
If (SetYear&$03)=0 then CounterA=29
endif
Return
	
'SUBRUTINA RETARDO DE BOTONES

SetButtonRelease:
LCDOut $FE,1
While SetButton=0:Wend
Pause 250	
Return

JumpStart:
CMCON=%00000111		
TRISA=%00000000		 
TRISB=%11111111		
OPTION_REG.7=0		

Pause 200		

ReDisplay:
LCDOut $FE,1	
ReDisplayLoop:

'RUTINA PARA LEER INTEGRADO DS1307

I2CRead SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCYear,RTCCtrl]

If RTCSec.7=1 then goto SetUpPreset
If SetButton=0 then
Gosub SetButtonRelease
goto Setup
endif	

'RUTINA PARA MOSTRAR VALOR EN LCD

LCDOut $FE,$80
If RTCHour.6=1 then
CounterA=(RTCHour>>4)&$01
else
CounterA=(RTCHour>>4)&$03
endif
CounterA=CounterA*10+(RTCHour&$0F)
If RTCHour.6=1 then
LCDOut #CounterA
else
LCDOut #CounterA Dig 1,#CounterA Dig 0
endif
LCDOut ":",#(RTCMin>>4)&$0F,#RTCMin&$0F,":"
LCDOut #(RTCSec>>4)&$0F,#RTCSec&$0F," "
IF RTCHour.6=1 then
If RTCHour.5=1 then
LCDOut "PM"
else
LCDOut "AM"
endif
endif

LCDOut " ",$FE,$C0
CounterB=RTCWDay*3+33	
Gosub DisplaySequence	
LCDOut " ",#(RTCDay>>4)&$0F,#RTCDay&$0F," "
CounterB=((RTCMonth>>4)&$0F)*10+(RTCMonth&$0F)
Gosub DisplayMonth
LCDOut " 20",#(RTCYear>>4)&$0F,#RTCYear&$0F,$FE,$80
Pause 250		' Repeat about 4 times/sec
Goto ReDisplayLoop

SetupPreset:
RTCSec=$00		'
RTCMin=$15		
RTCHour=$13		
RTCWDay=$01	
RTCDay=$12		
RTCMonth=$06	
RTCYear=$02		
RTCCtrl=$10		

Setup:
SetTime=RTCHour.6	
If SetTime=1 then
				
SetHour=(RTCHour>>4)&$01
				
else
SetHour=(RTCHour>>4)&$03
			
endif
SetHour=SetHour*10+(RTCHour&$0F)
If SetTime=1 then
If RTCHour.5=1 then
If SetHour<12 then SetHour=SetHour+12
			
else
If SetHour=12 then SetHour=0
endif
endif
SetMin=((RTCMin>>4)&$0F)*10+(RTCMin&$0F)
SetSec=((RTCSec>>4)&$0F)*10+(RTCSec&$0F)
SetYear=((RTCYear>>4)&$0F)*10+(RTCYear&$0F)
SetMonth=((RTCMonth>>4)&$0F)*10+(RTCMonth&$0F)
SetDay=((RTCDay>>4)&$0F)*10+(RTCDay&$0F)
		
CounterC=0		
TimeOut=0		
SetupLoop:
LCDOut $FE,1,"Set "
	
If CounterC=0 then
LCDOut "Mode"
endif
If CounterC=1 then 
LCDOut "Hours"
endif
If CounterC=2 then
LCDOut "Minutes"
endif
If CounterC=3 then 
LCDOut "Seconds"
endif
If CounterC=4 then
LCDOut "Year : 20"
endif
If CounterC=5 then
LCDOut "Month"
endif
If CounterC=6 then
LCDOut "Day"
endif
If CounterC<>4 then LCDOut " :"
		
SetupDisplayLoop:
			
If CounterC=0 then
LCDOut $FE,$8B
If SetTime=0 then
LCDOut "24HR"
else 
LCDOut "12HR"
endif
LCDOut $FE,$8B
endif
If CounterC=1 then
CounterA=SetHour
If SetTime=1 then
LCDOut $FE,$8E
			
If CounterA<12 then
LCDOut "AM"
else
LCDOut "PM"
endif
If CounterA=0 then CounterA=12
If CounterA>12 then CounterA=CounterA-12
endif
LCDOut $FE,$8C,#CounterA
If CounterA<10 then LCDOut " "			
LCDOut $FE,$8C
endif
			
If CounterC=2 then
LCDOut $FE,$8E,#SetMin
If SetMin<10 then LCDOut " "
LCDOut $FE,$8E
endif
			
If CounterC=3 then
LCDOut $FE,$8E,#SetSec
If SetSec<10 then LCDOut " "
LCDOut $FE,$8E
endif
			
If CounterC=4 then
LCDOut $FE,$8D,#SetYear DIG 1,#SetYear Dig 0
LCDOut $FE,$8D
endif
		
If CounterC=5 then
LCDOut $FE,$8C
CounterB=SetMonth
Gosub DisplayMonth
LCDOut $FE,$8C
endif
			
If CounterC=6 then
LCDOut $FE,$8A,#SetDay
If SetDay<10 then LCDOut " "
LCDOut $FE,$8A
endif
	
SetupEntryLoop:
			
If DecButton=0 then
			
If CounterC=0 then
If SetTime=0 then 
SetTime=1
else
SetTime=0
endif
endif
				
If CounterC=1 then
If SetHour=0 then
SetHour=23
else
SetHour=SetHour-1
endif
endif
			
If CounterC=2 then
If SetMin=0 then
SetMin=59
else
SetMin=SetMin-1
endif
endif
If CounterC=3 then
If SetSec=0 then
SetSec=59
else
SetSec=SetSec-1
endif
endif
			
If CounterC=4 then
If SetYear=0 then
SetYear=99
else
SetYear=SetYear-1
endif
endif
If CounterC=5 then
If SetMonth=1 then
SetMonth=12
else
SetMonth=SetMonth-1
endif
					
Gosub FindDays
If SetDay>CounterA then SetDay=CounterA
endif
			
If CounterC=6 then
Gosub FindDays
If SetDay=1 then
SetDay=CounterA
else
SetDay=SetDay-1
endif
endif
Pause ButtonRepeat
TimeOut=0
Goto SetUpDisplayLoop
endif
			
If IncButton=0 then
				
If CounterC=0 then
If SetTime=1 then 
SetTime=0
else
SetTime=1
endif
endif
			
If CounterC=1 then
If SetHour=23 then
SetHour=0
else
SetHour=SetHour+1
endif
endif
				
If CounterC=2 then
If SetMin=59 then
SetMin=0
else
SetMin=SetMin+1
endif
endif
			
If CounterC=3 then
If SetSec=59 then
SetSec=0
else
SetSec=SetSec+1
endif
endif
				
If CounterC=4 then
If SetYear=99 then
SetYear=0
else
SetYear=SetYear+1
endif
endif
			
If CounterC=5 then
If SetMonth=12 then
SetMonth=1
else
SetMonth=SetMonth+1
endif
				
Gosub FindDays
If SetDay>CounterA then SetDay=CounterA
endif
				
If CounterC=6 then
Gosub FindDays
If SetDay=>CounterA then
SetDay=1
else
SetDay=SetDay+1
endif
endif
Pause ButtonRepeat
TimeOut=0
Goto SetupDisplayLoop
endif
		
If SetButton=0 then
CounterC=CounterC+1
				
TimeOut=0
If CounterC>6 then
			
LCDOut $FE,1,"Memorizar"
				
CounterA=SetHour
If SetTime=1 then
If CounterA>12 then CounterA=CounterA-12
If CounterA=0 then CounterA=12
endif
Gosub ConvertBCD
RTCHour=CounterB
					
If SetTime=1 then
RTCHour.6=1
					
If SetHour=>12 then RTCHour.5=1
					
endif
				
CounterA=SetMin
Gosub ConvertBCD
RTCMin=CounterB
				'
CounterA=SetSec
Gosub ConvertBCD
RTCSec=CounterB
				
CounterA=SetYear
Gosub ConvertBCD
RTCYear=CounterB
				
CounterA=SetMonth
Gosub ConvertBCD
RTCMonth=CounterB
				
CounterA=SetDay
Gosub ConvertBCD
RTCDay=CounterB
			
CounterA=SetYear+4
CounterB=SetMonth
If SetMonth<3 then
CounterA=CounterA-1
CounterB=CounterB+12
endif
CounterD=(SetDay+(153*CounterB-457)/5+365*CounterA+CounterA/4-CounterA/100+CounterA/400+2) MOD 7
RTCWDay=CounterD+1
I2CWrite SDApin,SCLpin,$D0,$00,[RTCSec,RTCMin,RTCHour,RTCWDay,RTCDay,RTCMonth,RTCYear,RTCCtrl]
Pause 1000
Gosub SetButtonRelease
Goto ReDisplay
endif
Gosub SetButtonRelease
Goto SetupLoop	
endif

Pause 1		
TimeOut=TimeOut+1
If TimeOut>20000 then goto ReDisplay
Goto SetupEntryLoop	
End

Espero le sea de utilidad a nuestro amigo electroandres

Hola, podrias explicar el programa. gracias
 
Pregunta:

¿Alguien sabe como detectar un desborde de una suma de dos variables con ensamblador embebido?
En otras palabras, quiero hacer una suma y ver si desborda.

pseudocodigo:
A var byte
B var byte

A=100
B=180
A=A+B

Aquí el resultado A seria 280 pero como es de tipo byte desbordaría y quería saber si se coloca el valor en el registro F o W como 1 si se desborda o 0 si no desborda o en alguna bandera, para después mover ese valor con RLF a una variable Temp más o menos así:

@ RLF X,w
Donde X es 1 si desbordó y 0 si no desbordó la suma.

Ya lo intenté pero no funcionó, porque al parecer ahí no se registra el desborde y quiero hacer la rotación en ensamblador para evitar usar mucho código, o algún algoritmo que no implique usar mucho código BASIC que genere mucho código ASM.

Espero haberme explicado.
A ver si entendí y con esto lo puedes hacer:
PHP:
sumar
    movlw    valor        ; Mover el contenido de "valor" a W
    addwf    suma,w        ; Sumar W con el contenido de "suma"
    btfsc    STATUS,C    ; Comprobar si hubo desborde con el bit Carry
    goto    desborde    ; Si se produce desborde, ir a "desborde"
    clrf    x            ; No se produjo desborde, limpiar "x" x = 0
    return                ; Regresar
desborde
    movlw    .1            ; W = 1
    movwf    x            ; Poner en 1 el bit 0 de "x" x = 1
    return                ; Regresar
Por este mismo tema subí un ejemplo de cómo declarar la variables para usarlas dentro del código ensamblador.

Las variables a usar serían: valor, suma y x
 
Hola a todos. Espero me puedan ayudar, soy novato en PICBasic Pro.

He estado intentando realizar un circuito con el PIC16F628A.
Al presionar un pulsador encender un led en modo estrobo, apagarlo con el mismo pulsador al volver a presionarlo, pero solo he podido lograr encenderlo, y después quiero apagarlo con el mismo pulsador y no se apaga.

Muchas gracias por su ayuda .

Código:
EST VAR BYTe
BUT VAR BYTE
BUT = 0 
X VAR BIt

 
 
 
TRISB = %11000000  ;configuracion de salidas y entradas del puerto  B

                   
 RECIBIR:
 
 
 
 IF PORTB.7 = 1 THEN
   X = X + 1
 While  X = 1 \'Condicional While - Wend
 
    HIgh PORTB.3    \'Enciende el led estrobo 
    PAUSE 120   \'pause de 0.12 segundos
    LOW PORTB.3    \'Apaga el led estrobo 
    PAUSE 120  \'pause de 0.12 segundo
      
 Wend
 ENDIF   
   
 BUTTON PORTB.6,1,0,0,BUT,0,RECIBIR 
 TOGGLE PORTB.3
  
GOTO RECIBIR 

   
 End
 
Última edición por un moderador:
Te falta alguna instrucción para que X vuelva a 0.

Algo así:
Código:
IF PORTB.7 = 1 THEN
	IF X = 1 THEN
		LOW PORTB.3	; aquí apagamos
		X = 0
	ELSE
		HIGH PORTB.3	; aquí encendemos
		X = 1
	ENDIF

	PAUSE 120
ENDIF
 
Hola a todos. Espero me puedan ayudar, soy novato en PICBasic Pro.

He estado intentando realizar un circuito con el PIC16F628A.
Al presionar un pulsador encender un led en modo estrobo, apagarlo con el mismo pulsador al volver a presionarlo, pero solo he podido lograr encenderlo, y después quiero apagarlo con el mismo pulsador y no se apaga.
Prueba de esta manera:
Código:
; Declaración de varibles.
B0          Var Byte
Flag        Var Bit

; Nombres para los pines.
Symbol LED      = PORTB.4
Symbol Pulsador = PORTB.0


Inicio:
    CMCON = 7               ; Comparadores analógicos OFF
    OPTION_REG = 0          ; Pull-Ups (PORTB) y Falling edge (INT-RB0)
    INTCON = %11010000      ; Habilitar interrupción por RB0
    
    On Interrupt GoTo SDI_RB0
    
    Flag = 1
    Low LED        

Programa:
    Button Pulsador,0,10,255,B0,0,Programa
        While Flag = 0 
            Toggle LED
            Pause 50
        Wend
        Low LED
        Flag = 0
    GoTo Programa

SDI_RB0:
    Disable
    
    If INTCON.1 = 1 Then INTCON.1 = 0   ; Limpiar flag INTF
    
    If Flag = 0 Then Flag = 1
    
    Resume
    Enable
    
    End
Espero que sea lo que quieres hacer.
Si tienes problema con los fuses para la palabra de configuración, no dudes en preguntar.

Suerte.
 
:)Gracias amigos, una última duda en el caso de querer hacer el led titile o centelle , como seria para hacer que al pulsar el sw titile y al volver a pulsar el mismo sw se apague. Muchas gracias y saludos:apreton:
 
Última edición:
:)Gracias amigos. Una última duda: En el caso de querer hacer que el led titile o centelle.
¿Cómo sería para hacer que al pulsar el sw titile y al volver a pulsar el mismo sw se apague?
Creo que no probaste el código que puse, ese programa eso es lo que hace.
Mencionaste hacer un estrobo. ¿No?
Con una presión del pulsador se enciende y apaga el LED cada 50ms y con otra se apaga.

Edit:
Mejoras para eliminar rebotes del pulsador...
Código:
; Declaración de variables.
B0          Var Byte
Flag        Var Bit

; Nombres para los pines.
Symbol LED      = PORTB.4
Symbol Pulsador = PORTB.0


Inicio:
;    CMCON = 7               ; Comparadores analógicos OFF
    OPTION_REG = 0          ; Pull-Ups (PORTB) y Falling edge (INT-RB0)
    INTCON = %11010000      ; Habilitar interrupción por RB0
    
    ; Activar el servicio de interrupciones.
    On Interrupt GoTo SDI_RB0
    
    Flag = 1                ; "Flag" en 1 al iniciar.
    Low LED                 ; "LED" en 0 al iniciar.

Programa:
    Button Pulsador,0,127,255,B0,0,Programa
       Pause 50
       
        While Flag = 0      ; Mientras "Flag" es 0... 
            Toggle LED      ; Cambiar de estado "LED"
            Pause 50        ; Hacer un retardo. (Aquí se cambia el tiempo del destello)
        Wend                ; Salir del bucle cuando "Flag" cambie a 1
        
        Low LED             ; "LED" en 0
        
        While Pulsador = 1  ; Mientras "Pulsador" esté en 1...
            Pause 20        ; Hacer un retardo de 20ms.
        Wend                ; Salir cuando "Pulsador" sea 0
        
        Flag = 0            ; Establecer "Flag" en 0
        
    GoTo Programa

; Servicio de interrupción por RB0
SDI_RB0:
    Disable                 ; Desactivar interrupciones.
    
    If INTCON.1 = 1 Then    ; Si es interrupción por RB0, entonces...
        If Flag = 0 Then    ; Si "Flag" está en 0, entonces...
            Flag = 1        ; Establecer "Flag" en 1
        EndIf
        INTCON.1 = 0        ; Limpiar flag INTF
    EndIf
    
    Resume                  ; Retornar al programa (RETFIE)
    Enable                  ; Volver a activar interrupciones.
    
    End
Al pin del pulsador se le tiene que colocar un capacitor de 100nF hacia negativo.
 
Última edición:
Hola Darkbytes :), Si lo probé el problema que tuve fue que no me fije con que lógica tenías tú el pulsador en el código que me enviaste, yo lo tenía con lógica Activo-Alto, y por eso no me funciono, la primera vez, hasta que vi tu otro comentario, fue que pensé que algo avía hecho mal ya era justo lo que necesito (y), me doy cuenta que yo anda muy lejos de encontrar el código apropiado.

Te agradezco mucho tu ayuda,:apreton:
 
Hola Darkbytes. :) Si lo probé.
El problema que tuve fue que no me fijé con que lógica tenías tú el pulsador en el código que me enviaste.
Yo lo tenía con lógica Activo-Alto, y por eso no me funciono la primera vez.
OK. Para que eso no te vuelva a suceder, debes analizar los parámetros de la instrucción "Button"
Sobre todo el segundo "Down" = Estado del pin cuando se oprime el pulsador (0 o 1)
La ayuda de PBP dijo:
Down State of pin when button is pressed (1..0)
También está la configuración del registro OPTION_REG que en el comentario dice lo siguiente:
"Falling edge (INT-RB0)" O sea, la interrupción ocurrirá por flanco de bajada. (Cuando RB0 pase de 1 a 0)
Notarás que está todo en 0 porque nos interesa tener el bit 7 (RBPU) y el 6 (INTEDG) en 0
Los demás no importa que queden en 0 pues no se van a usar y no afectan al programa si quedan en 0.

En el post anterior puse el código comentado y con unas mejoras para tratar de evitar los rebotes del pulsador.

Suerte.
 
Hola, buenas tardes.
Estoy iniciando con el uso de los LCD y pulsadores tomando como ejemplo el siguiente ejercicio donde se realiza con 2 pulsadores un incremento y decremento de un valor mostrado en el LCD.

¿Quisiera saber como haría para ir de la letra "A" a la letra "Z" o de la letra "Z" a la "A" con este mismo ejemplo de programa?

Gracias.

Código:
DEFINE LCD_DREG PORTB ' Indica que el Bus estará conectado en el Puerto B

DEFINE LCD_DBIT 4      ' Selección del Bit de inicio del puerto en el uC para el
                                ' bus de datos de la LCD
DEFINE LCD_RSREG PORTB ' Indica al uC que el pin "RS" estará en el Puerto D
DEFINE LCD_RSBIT 3     ' "RS" estará conectado en RB3
DEFINE LCD_EREG PORTB  ' Indica al uC que el pin "E" estará en el Puerto D
DEFINE LCD_EBIT 2      ' "E" estará conectado en RB2
Define Osc 4            ' Define el Oscilador para un Cristal
                             ' de 4 Mhz.
TRISA = $FF            ' Configura el puerto A como entrada.
TRISB = $00            ' Configura el puerto B como salida.
Dato Var Byte          ' Declaración de la Variable "Dato" tipo Byte.
Dato = 25              ' Inicializa la Variable Dato = 25.
Lcdout $fe, 1          ' Limpia la pantalla
Inicio:

Lcdout $fe,2              ' Inicio de la primera línea.
Lcdout "P1 Suma P2 Resta" ' Escribe mensaje en la primera línea.
Lcdout $fe,$C0,"Dato: ",Dec Dato," " ' Escribe el mensaje en la 2da línea
                                     ' seguido del valor cargado en la
                                     ' variable "Dato" en Decimal.
                                     
                                     
                                     
If PORTA.1 = 1 And Dato < 50 Then Call Suma 
                                            ' La siguiente instrucción pregunta si hay un "1" en RA1 y si la variable
                                            ' "Dato" es menor a 50. Si se cumplen estas dos condiciones, hace un salto
                                            ' con retorno a la subrutina "Suma".  
                        
                                            
If PORTA.3 = 1 And Dato > 0 Then Call Resta ' La siguiente instrucción pregunta si hay un "1" en RA3 y si la variable
                                            ' "Dato" es mayor a 0. Si se cumplen estas dos condiciones, hace un salto
                                            ' con retorno a la subrutina "Resta".



GoTo Inicio                ' Salta a la etiqueta "Inicio".
Suma:
Dato = Dato + 1            ' Incrementa en una unidad la variable "Dato".
Pause 350                  ' Realiza una pausa de 350 milisegundos para evitar
                           ' que el incremento de la variable sea muy acelerado
                           ' mientras el pulsador "P1" esté presionado.
Return                     ' Retorna una línea después del llamado "Call Suma".
Resta:
Dato = Dato - 1            ' Decrementa en una unidad la variable "Dato".
Pause 350                  ' Realiza una pausa de 350 milisegundos para evitar
                           ' que el decremento de la variable sea muy acelerado
                           ' mientras el pulsador "P2" esté presionado.
Return                     ' Retorna una línea después del llamado "Call Resta".
End
 
Última edición por un moderador:
Atrás
Arriba