Curso de programación de PIC en PICBasic Pro

Hola amigo, me parece que meti la pata en la cconfiguracion de los registros, por que me parece raro que funcione por separado, y junto no funcione....
ahi en el programa, configure la interrupcion por timer, el pwm por hardware y entre ahora en duda si configure bien los dos puertos analogicos para leer ...
Se me chispoteo algo seguro, pero a simple vista no lo veo, y eso me pone mas de los pelos



mira Ricardo.... quiero probar estas configuraciones
Código:
ADCON0=%11000000       
ADCON1=%10000000     
TRISA=%11111111                    
TRISB=%11111111
TRISC=%00000000
TRISD=%00000000
       
OPTION_REG=%10000010        
INTCON=%10100001           
TMR0=0 
T2CON = %00000110
PR2=124     
DEFINE    ADC_BITS    10        
DEFINE    ADC_CLOCK    3        
DEFINE    ADC_SAMPLEUS 50

y ahora no puedo... mepa que despues del escaner antivirus me borro algo por que me sale esto al compilar:

errores.jpg

Ahora si que estoy por romper la maquina :(
 
Última edición:
Hola amigo, me parece que metí la pata en la configuración de los registros, por que me parece raro que funcione por separado, y junto no funcione.
Ahí en el programa, configuré la interrupción por timer, el pwm por hardware y entré ahora en duda si configuré bien los dos puertos analógicos para leer.
Se me chispoteo algo seguro, pero a simple vista no lo veo, y eso me pone más de los pelos
Mira el ejemplo que dejo adjunto, en él se hace uso de interrupciones, ADC, LCD y PWM por hardware.

El programa realiza lo siguiente:
.- Se leen dos canales analógicos a 10 bits.
.- Se muestra el valor de ambos canales sobre una pantalla LCD 16x2.
.- Se realiza una interrupción por desborde del Timer0 y otra por cambio de estado en el puerto B <RB4,RB7>
.- Se genera una señal PWM por hardware de 5000Hz.

Esto se realiza en el ejemplo sin conflicto alguno.

Mira las configuraciones realizadas.
Espero te sirvan para comprender y analizar en dónde pueden estar los errores de tu programa.

Suerte.
 

Adjuntos

  • 16F877A Ints, ADC, PWM, LCD.rar
    42.1 KB · Visitas: 117
Última edición:
uuuuuu, excelente, ahi lo mire desde el TXT y despues simule; Me gusto mucho la manera en que lo haces mucho mas liviano al programa :aplauso:... Al parecer, y si no mal entendi tu ejemplo, le pifie con mi configuracion:

ADCON1=%10000010
OPTION_REG=%10000010

pero lo uqe no me cierra es que con mi configuracion An0 y 1 estan habilitados al igual que tu ejemplo...

ADCON1 = %10000000 ; Conversión con justificación a la derecha (AN1, AN0)

mirá, dejame ver si saco algo en limpio con tu ejemplo y lo que escribi yo... El registro de ADCON1 seria entonces:

bit7 _ justificacion a la derecha (1 activa - 0 apaga)
bit6 _ implementacion del reloj en la lectiura / conversion
bit5 _ no se usa
bit4 _ no se usa
bit3-2-1-0 _ se configura los puertos de los cuales, esta seria la tabla de configuracion:

0000 = A7 :An / A6:An / A5:An / A4:An / A3:An / A2:An / A1:An / A0:An

0001 = A7 :An / A6:An / A5:An / A4:An / A3:Vref / A2:An / A1:An / A0:An

0010 = A7Dig / A6Dig / A5Dig / A4:An / A3:An / A2:An / A1:An / A0:An

0011 = A7Dig / A6Dig / A5Dig / A4:An / A3:Vref / A2:An / A1:An / A0:An

0100 = A7Dig / A6Dig / A5Dig / A4:An / A3:An / A2Dig / A1:An / A0:An

0101 = A7Dig / A6Dig / A5Dig / A4:An / A3:Vref / A2ig / A1:An / A0:An

011x = A7Dig / A6Dig / A5Dig / A4Dig / A3Dig / A2Dig / A1:ADig / A0ig

1000 = A7:An / A6:An / A5:An / A4:An / A3:Vref / A2:Vref / A1:An / A0:An

1001 = A7Dig / A6Dig / A5:An / A4:An / A3:An / A2:An / A1:An / A0:An

1010 = A7Dig / A6Dig / A5:An / A4:An / A3:Vref / A2:An / A1:An / A0:An

0011 = A7Dig / A6Dig / A5:An / A4:An / A3:Vref / A2:Vref / A1:An / A0:An

1100 = A7Dig / A6Dig / A5Dig / A4:An / A3:Vref / A2:Vref / A1:An / A0:An

1101 = A7Dig / A6Dig / A5Dig / A4Dig / A3:Vref / A2:Vref / A1:An / A0:An

1110 = A7ig/ A6ig / A5ig / A4ig / A3ig / A2ig / A1ig / A0:An

1111 = A7ig/ A6ig / A5ig / A4ig / A3:Vref / A2:Vref / A1ig / A0:An


:unsure: ahora tengo que resolver el tema este que no me compila... y despues voy a tomar parte de tu idea y ejemplo para hacerlo mas funcional al programa y te comento como me fue... de paso, ya con el compilador funcionando, quizas pueda ver con mas exactitud donde esta el error viendo tu ejemplo.
Gracias amigazo (y)
 
Saludos... estoy haciendo un transmisor de presión, caudal, volumen con un 16F876A y se me complico en la etapa del conteo de volumen.

Tr_Pres_Cau_Vol.jpg

El sensor de presion (Nuova FIMA ST1 ), es un transmisor con salida opcional 4-20mA / 0-5V/ 0-10V; Yo opte por la salida 4-20mA.
El controlador del sensor de caudal (FlowMeet FM-500), me da una salida 4-20mA para caudal (100L/m max.) y una salida de pulsos para Volumen con factor K programable (yo pienso setearlo a 1 pulso por unidad de volumen). Esta ultima parte es un poco engorrosa, ya que en el manual dice:

Es común contar con la necesidad de tener una salida proporcional al volumen medido, la serie FM-500 resuelve esto de la siguiente manera:

se dividen los pulsos de entrada por un factor independiente, con este resultado se generan pulsos de salida, en lo que sigue la explicacion ttrataremos con dos factores
FACTOR_K: factor calibrado para el sensor mecanico
FACTOR_Kout: valor programado para obtener pulsos de salida deseados.
Si el fabricante entrega un equipo con FACTOR_K=125.400, esto quiere decir que el elemento mecanico genera 125.4 pulsos por unidad de volumen, al ser el FACTOR_Kout podemos obtener todas las combinaciones de pulsos posib les a la salida, por ejemplo:

1 pulso de salida por cada pulso de entrada FACTOR_Kout= 00001.000
1 pulso de salida por cada unidad de volumen FACTOR_Kout=00125.400
10 pulso de salida por cada unidad de volumen FACTOR_Kout=00012.540
etc.


La salida de pulsos tiene un ciclo de trabajo de 50% (frec max 200Hz) y funciona en tiempo real, no genera trenes de pulsos, si no que constantemente actualiza la salida, esto permite que el equipo sea prover-fiendly, esta característica es muy importante ya que permite controlar la totalidad del sistema mediante un prover.
a lo cual supongo e interpreto que me da un pulso por cada unidad de volumen y contándolos por segundo, los voy sumando y con esto saco el volumen instantáneo... El tema esta en como realizar el conteo y que no se me desborde la variable puls (byte) y se me ponga en cero... Calculo yo que puedo llegar a contabilizar como max. un volumen de 9.900Lts.
Esto es lo que tengo hasta el momento:

Código:
count PORTB.1,1000,puls
temp3 = temp3 + puls

ADCIN 0, ent420_presion                            ;600bar/1024=presion
TEMP1 = 488 * ent420_presion                       ; 1024*488=499712
VAL1 = DIV32 10
LCDOUT $fe,1,"P:",DEC VAL1 DIG 3,DEC VAL1 DIG 2,".",DEC VAL1 DIG 1, DEC VAL1 DIG 0,"Bar"

PAUSE 5

ADCIN 1, ent420_caudal                            ;1000ltsM/1024=caudal
TEMP2 = 488 * ent420_caudal                       ; 1024*488=499712
VAL2 = DIV32 10
lcdout $fe,$C0,"C:",DEC VAL2 DIG 3,DEC VAL2 DIG 2,"L/m Vol",dec temp3

PAUSE 5
Creería que puede llegar a funcionar la lectura de todo, pero estaría el error de desbordamiento en la sección del conteo de volumen histórico; Alguien me da alguna idea... Saludos a todos

---------- Actualizado después de 36 minutos ----------


bueno... :unsure: Por el momento, tendré que hacer que la variable puls sea del tipo word para que haga el conteo hasta 9999... después veré si hay alguna otra manera para no tener que partir el word en dos byte y enviar ese dato a la PC y desde el soft juntar los dos byte :oops:
 
Última edición por un moderador:
¡Hola,feliz año 2015 a todos!
Bueno pues con la novedad de que necesito un poco de ayuda de ustedes
y quiero que me ayuden a resolver algunas dudas sobre una practica que quiero realizar y es la siguiente:

controlar y visualizar 3 entradas ADC con el PIC16f887 atravez de tres potenciometros a 10 bits o a 8 bits(cualquiera)

saben ya lo he realizado pero con un solo canal ADC y funciona bien pero aqui mi duda es como configurar
los registros ADCON0 y ADCON1 para que pueda manejar las 3 entradas analogicas y mostrarlas en un display lcd
ya le eche una leida al datasheet PIC16F887 pero no le hallo la manera lo unico que rescate es que este pic usa
los ANSEL (parte baja) ANSELH (PARTE ALTA) para configurar cuales pines seran digitales y cuales analogicos.
en los pic que he trabajado el PIC16F877A y el PIC16F819 en sus datasheet ya traen una tabla para seleccionar
cuantos canales y cuales se van van a utilizar pero como tengo 2 PIC16F887 los quiero poner a trabajar

En resumen quiero por favor quien haya manejado este pic que me ayude a configurar el ADCON0 y el ADCON1,o que me de alguna
idea o algun ejemplo,logicamente cuando ya se manejan mas de 2 potenciometros o sensores analogicos.
el programa esta en pic basic pro.

Otra duda que tengo es que este pic trabaja a 10 bits de resolucion ADC y por ahi he leido que si pongo en el ADCON1
el bit 7 justificado a la derecha trabajara a 10 bits y si pongo justificado a la izquierda trabajara a 8 bits es cierto
o me equivoco? bueno esto fue lo que entendi.

Aqui el programa y diagrama en proteus.
 

Adjuntos

  • ADC_PIC16F887.rar
    15.3 KB · Visitas: 55
  • ADC_PIC16F887.jpg
    ADC_PIC16F887.jpg
    136.9 KB · Visitas: 35
En resumen, quiero por favor quien haya manejado este pic que me ayude a configurar el ADCON0 y el ADCON1, o que me de alguna idea o algún ejemplo, lógicamente cuando ya se manejan mas de 2 potenciometros o sensores analógicos.
El programa está en pic basic pro.
Pues así como tienes tu programa, tan sólo te hace falta usar los otros canales, no has configurado los registros ANSEL y ANSELH, así que se encuentran todos sus bits en 1.
ANSEL = ANS 7<>0 y ANSELH = ANS 13<>8
Entonces los pines donde tienes conectados los potenciómetros, serán análogos.
Así que si usas ADCIn 0, 1 y 2, debes obtener las lecturas de esos canales.
Pero si quieres que los canales sobrantes sean digitales, entonces configuras ANSEL y ANSELH de esta forma:
ANSEL = %00000111
ANSELH = 0

Como ya usaste algunas configuraciones usando las definiciones de PBP para el conversor ADC, entonces sale sobrando que configures el registro ADCON0.

ADCON1 no quedará bien configurado usando las definiciones de PBP para 10 bits y es donde entra esta parte...
Otra duda que tengo es que este pic trabaja a 10 bits de resolución ADC y por ahí he leído que si pongo en el ADCON1 el bit 7 justificado a la derecha trabajara a 10 bits y si pongo justificado a la izquierda trabajara a 8 bits. ¿Es cierto o me equivoco?
Bueno, esto fue lo que entendí.
Lo que hace el bit 7 (ADFM = A/D Conversion Result Format Select bit) del registro ADCON1, es lo siguiente...
1 = Justificación a la derecha. Los 6 bits más significativos de ADRESH se leerán como "0"
0 = Justificación a la izquierda. Los 6 bits menos significativos de ADRESL se leerán como "0"

Y por eso se pone el bit 7 en 1 cuando se usan los10 bits, pues resulta más sencilla la lectura de los registros ADRESL y ADRESH con el resultado de ADRESH justificado a la derecha.

Así que nada más te resta la configuración de los registros ANSEL y ANSELH para convertir los pines con ADC no usados, en digitales.

Nota, algo importante:
Cuando muestras valores con más de un dígito usando DEC Valor, es mejor que lo hagas tomando en cuenta cuantos dígitos máximo serán mostrados.
Esto lo haces usando DECX (Donde X será la cantidad de dígitos a mostrar)
Así evitas que valores anteriores que queden en la CGRAM, alteren la visualización del resultado actual.

Entonces si usas 10 Bits = 1023, usas Dec4 y de esta forma cuando la lectura decremente, se observaran ceros a la izquierda.
 
Última edición:
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.
 
Atrás
Arriba