desktop

Curso de programación de PIC en PICBasic Pro

alguna vez me marco eso el proteus fue porque el tiempo que estaba corriendo el programa no era real y era muy bajo y no se apreciaban los cambios en forma real talvez eso te ayude
te refieres al reloj del pic?, sì es esto, estoy simulando con el oscilador interno (4 mhz),
probe con otros valores y sigue igual. seguiré buscando Gracias
 
me feriero a que cuando tu haces interrupciones o realizas retardos en tu programa no estan bien hechas o el simulador del proteus no la alcanza a semejar a la realidad lo corre a diferente velocidad para que la simulacilon se pueda ver a eso me refiero ex decir lo que tu quieres ver en el proteus no se esta dando de manera real sino que el proteus te lo muestra pero te advierte que necesariamente eso no va a pasar en la realidad
 

Para ayudarte te explicare todo el código y la utilización de los comandos empezando con la función SELECT CASE que es una estructura de control que proporciona PBP para utilizarse se debe empezar con select case y terminar la operación con end select.
Su propósito es el simplificar las estructuras anidadas if, Then, else que utilizamos cuando se da una condición, en los casos en que sea siempre la mima variable y se necesiten varias decisiones en función de los valores posibles, y su estructura es la siguiente:
SELECT CASE variable
CASE valor1: instruccion1

END SELECT
En el ejemplo que posteaste se utiliza de la siguiente manera me tome la liberta de utilizar con el pic 16f877A:
@ DEVICE xt_osc ; definimos Oscilador externo
define osc 4
TRISA=1 ; puerto A como entradas digitales
ADCON1=7
Pause 2000
Loop: ;Bucle principal
Select case PORTA ; condición determinada por el Puerto A del pic 16F877A
; Los casos utilizados se desarrollan bajo las posibles variables obtenidas del puerto A del pic 16F877A, defeneciendo cuatro por las entradas que son dos RA0 y RA1 respectivamente.
Case 0
Gosub izquierda
; En esta condición (PRIMERA) RA1 y RA 0 están a cero lógico con lo que se pretende ir a la rutina de izquierda con el comando GOSUB.
Case 1
Gosub adelante
; En esta condición (segunda) RA1 y RA0 están a cero lógico y a uno lógico respectivamente con lo que se pretende ir a la rutina de adelante con el comando GOSUB.

Case 2
Gosub atras
; En esta condición (tercera) RA1 y RA0 están a uno lógico y a uno lógico respectivamente con lo que se pretende ir a la rutina de adelante con el comando GOSUB.
Case 3
Gosub derecha
; En esta condición (Cuarta) RA1 y RA0 están a uno lógico con lo que se pretende ir a la rutina de derecha con el comando GOSUB.
End select ; fin Del condicional
Goto loop ; crea un bucle cerrado ir a Loop
; En estas rutinas se utiliza el puerto b del pic como complemento siendo cero (0) a cinco (5) RB0 a RB5 respectivamente si te fijas siempre cero (RB0) y tres (RB3) estén a uno lógico ya que habitan los driver para los motores que deben ser servos ya que si fueran dc normales se embalan y no hay control en el giro, la única posibilidad es la utilización de los comandos PWM y HPWM, cuando se ha ejecutado se retorna a la función que fue precedida con el comando RETURN. Los otro pines son los habilitadores de polaridad del motor para que giro en sentido horario y antihorario los cuales son (1, 2, 4,5) o (RB1, RB2, RB4, RB5).
adelante:
high 0:high 1: low 2
high 3:high 4: low 5
return
atras:
high 0:low 1: high 2
high 3:low 4: high 5
return
izquierda:
high 0:low 1: high 2
high 3:high 4: low 5
return
derecha:
high 0:high 1: low 2
high 3:low 4: high 5
return
end
Espero te sea de ayuda para tu proyecto amigo.


amigo atricio me equivoque en condicion tres caso dos es a uno logico en RA1 y cero logico en RA0.

Case 2
Gosub atras
; En esta condición (tercera) RA1 y RA0 están a uno lógico y a uno lógico respectivamente con lo que se pretende ir a la rutina de adelante con el comando GOSUB.

En esta condición (tercera) RA1 y RA0 están a uno lógico y a cero lógico respectivamente con lo que se pretende ir a la rutina de adelante con el comando GOSUB.
 
Última edición:
muchas gracias amigo mecatrodatos eres lo maximo mas o menos ya me las estaba suponiendo...me quedo muy claro ya utilizacion del case ahora una preguntilla en el loop ese debe ser mi programa principal no es verdad porque de ahi me esta mandando a seleccionar los casos verdad y regreso solamente con return puede haber mas de un loop en el mismo programa....muchas gracias me haz dado una gran ayuda cuaquier cosa que no entienda te molestare de nuevo y si mi carrito sale chevere lo posteo con unas foticos etc..
 
a ya listo muchas gracia mira si no es mucha molestia me podrias ayudar anteriormente postearon un programa de conversor analogo digital en que la variable me da hasta 255 que debo hacer para que me de hasta 1024 como dicen o hasta mas que puede leer la variable puedes hecharme una manito con eso por favor

Código:
@devicext_osc ; oscilador externo XT 
define osc 4
define LCD_DREG PORTD
DEFINE LCD_DBIT 0
DEFINE LCD_RSREG PORTD
DEFINE LCD_RSBIT 5
DEFINE LCD_EREG PORTD
DEFINE LCD_EBIT 4
P1 VAR BYTE
P2 VAR BYTE
P3 VAR BYTE
boton var portb.0
ADCON1=%100
INICIO:
PAUSE 300
POTEN1:
    ADCON0=%1000001
    GOSUB MEDIR
    P1= ADRESH
POTEN2:
    ADCON0=%1001001
    GOSUB MEDIR
    P2=ADRESH
POTEN3:
    ADCON0=%1011001
    GOSUB MEDIR
    P3=ADRESH
p1=(p1*500/255)
p2=(p2*30/255)
 
LCDOUT $FE,1,"POT1 POT2 POT3"
LCDOUT $FE,$c1,#p1
lcdout $FE,$c6,#P2
LCDOUT $FE,$cb,#P3
GOTO inicio
MEDIR:
    PAUSE 50
    ADCON0.2=1
    PAUSEUS 50
    RETURN
 
Última edición:
estoy haciendo una calculadora de 4 digitos pero al colocar la operacion mas grande es decir 9999*9999 me da 37601 y donde guardo la multiplicacion es una variable de tipo word, tendra algun detalle el lcd? la programacion es la correcta la estoy haciendo con un 16f877a
 
que tal minssss pues la variable que usas que es word solo almacena datos de 0 a 65535 : Word (dos bytes de longitud, almacena números enteros entre 0 y 65,535)
por lo tanto tendras que realizar un areglo de variables para poder mostrar el resultado de tu multiplicacion que mensionas.

o si puedes colocar tu programa para que te demos una ayudadita ?


saludos ¡¡
 
Última edición:
no se como trabajar con arreglos en lo que a la multiplicacion se refiere, ayuda:confused: estare agradecido, gracias por la pronta respuesta


Código:
DEFINE OSC 20
DEFINE LCD_DREG PORTB 'LCD data port 
DEFINE LCD_DBIT 4 'LCD data starting bit 0 or 4 
DEFINE LCD_RSREG PORTB 'LCD register select port 
DEFINE LCD_RSBIT 0 'LCD register select bit 
DEFINE LCD_EREG PORTB 'LCD enable port 
DEFINE LCD_EBIT 2 'LCD enable bit 
DEFINE LCD_BITS 4 'LCD bus size 4 or 8 
DEFINE LCD_LINES 2 'Number lines on LCD 
DEFINE LCD_COMMANDUS 2000 'Command delay time in us 
DEFINE LCD_DATAUS 50 'Data delay time in us

alldigital 
TRISC=%11110000
TRISB=0

INICIO2:
X VAR BYTE
X=0
Y VAR BYTE
Y=0

SUM VAR WORD
SUM=0
RES VAR WORD
RES=0
MUL VAR word
MUL=0
DIVIN VAR WORD
DIVIN=0
DIVDEC VAR WORD
DIVDEC=0
DECI VAR WORD
DECI=0
G VAR byte
G=0
H VAR byte
H=0
I VAR byte
I=0
P VAR byte
P=0
J VAR BYTE
J=0
K VAR word
K=0
L VAR WORD
L=0
FLAG VAR BYTE
FLAG=0
CLC VAR BYTE
CLC=0

A VAR PORTC.0
B VAR PORTC.1
C VAR PORTC.2
D VAR PORTC.3
UNO VAR PORTC.4
DOS VAR PORTC.5
TRES VAR PORTC.6
CUATRO VAR PORTC.7

LCDOUT $FE, 1

INICIO:

'TECLADO
HIGH A
IF UNO=1 THEN X=1
IF DOS=1 THEN X=2
IF TRES=1 THEN X=3
IF CUATRO=1 THEN X=10
IF UNO=1 || DOS=1 || TRES=1 || CUATRO=1 THEN GOSUB ANTIREBOTE:Y=Y+1
PAUSE 10
LOW A

HIGH B
IF UNO=1 THEN X=4
IF DOS=1 THEN X=5
IF TRES=1 THEN X=6
IF CUATRO=1 THEN X=11
IF UNO=1 || DOS=1 || TRES=1 || CUATRO=1 THEN GOSUB ANTIREBOTE:Y=Y+1
PAUSE 10
LOW B

HIGH C
IF UNO=1 THEN X=7
IF DOS=1 THEN X=8
IF TRES=1 THEN X=9
IF CUATRO=1 THEN X=12
IF UNO=1 || DOS=1 || TRES=1 || CUATRO=1 THEN GOSUB ANTIREBOTE:Y=Y+1
PAUSE 10
LOW C

HIGH D
IF UNO=1 THEN X=20 'ON
IF DOS=1 THEN X=0
IF TRES=1 THEN X=14 'ENTER
IF CUATRO=1 THEN X=13
IF UNO=1 || DOS=1 || TRES=1 || CUATRO=1 THEN GOSUB ANTIREBOTE:Y=Y+1
PAUSE 10
LOW D

IF Y=1 && X<10 THEN G=X:LCDOUT $FE, 2, #X
IF Y=2 && X<10 THEN H=X:LCDOUT $FE, 2, #G, #X
IF Y=3 && X<10 THEN I=X:LCDOUT $FE, 2, #G, #H, #X
IF Y=4 && X<10 THEN P=X:LCDOUT $FE, 2, #G, #H, #I, #X
IF FLAG=0 && Y=0 THEN LCDOUT $FE, 2, "0  "
IF X=10 THEN LCDOUT $FE, 2, "+   "
IF X=11 THEN LCDOUT $FE, 2, "-   "
IF X=12 THEN LCDOUT $FE, 2, "*   "
IF X=13 THEN LCDOUT $FE, 2, "/   "
IF X=20 THEN GOTO INICIO2

'PRIMER NUMERO
IF FLAG=0 THEN
    IF Y=2 && X>=10 THEN
    J=X
    K=G
    LCDOUT $FE, 2, #K
    PAUSE 100
    FLAG=1
    Y=0
    G=0:H=0:I=0:P=0
    ENDIF
    
    if y=3 && x>=10 THEN 
    J=X
    K=(G*10)+H
    LCDOUT $FE, 2, #K
    PAUSE 100
    FLAG=1
    Y=0
    G=0:H=0:I=0:P=0
    ENDIF
    
    IF Y=4 && X>=10 THEN
    J=X
    K=(g*100)+(H*10)+(i)
    LCDOUT $FE, 2, #K
    PAUSE 100
    FLAG=1
    Y=0
    G=0:H=0:I=0:P=0
    ENDIF
    
    IF Y=5 && X>=10 THEN
    J=X
    K=(g*1000)+(H*100)+(i*10)+P
    LCDOUT $FE, 2, #K
    PAUSE 100
    FLAG=1
    Y=0
    G=0:H=0:I=0:P=0
    ENDIF
ENDIF

'SEGUNDO NUMERO
iF FLAG=1 THEN
    IF Y=2 && X=14 THEN 
    L=G
    LCDOUT $FE, 2, #L
    PAUSE 100
    CLC=1
    GOSUB OPERACIONES
    ENDIF
    
    IF Y=3 && X=14 THEN
    L=(G*10)+H
    LCDOUT $FE, 2, #L
    PAUSE 100
    CLC=1
    GOSUB OPERACIONES
    ENDIF
    
    IF Y=4 && X=14 THEN
    L=(g*100)+(H*10)+i
    LCDOUT $FE, 2, #L
    PAUSE 100
    CLC=1
    GOSUB OPERACIONES
    ENDIF
    
    IF Y=5 && X=14 THEN
    L=(g*1000)+(H*100)+(i*10)+P
    PAUSE 10
    LCDOUT $FE, 2, #L
    PAUSE 100
    CLC=1
    GOSUB OPERACIONES
    ENDIF
ENDIF

GOTO INICIO

ANTIREBOTE:
IF UNO=1 || DOS=1 || TRES=1 || CUATRO=1 THEN
GOTO ANTIREBOTE
ELSE
RETURN
ENDIF

OPERACIONES:

IF CLC=1 THEN
    IF J=10 THEN
    SUM=K+L
    LCDOUT $FE, 2, #k, "+", #l,"="
    LCDOUT $FE, $C0, #SUM
    PAUSE 100
    X=0
    ENDIF
    
    IF J=11 THEN
        IF L>K THEN
        RES=L-K
        LCDOUT $FE, $C0,"-", #RES        
        ELSE
        RES=K-L
        LCDOUT $FE, $C0, #RES
        ENDIF
    LCDOUT $FE, 2, #K, "-",#L,"="
    PAUSE 100
    X=0
    ENDIF
    
    IF J=12 THEN
    MUL=(K*L)
    LCDOUT $FE, 2, #k, "*",#L,"="
    LCDOUT $FE, $C0, #MUL
    PAUSE 100
    X=0
    ENDIF
    
    IF J=13 THEN
    DIVIN=K/L
    DIVDEC=K//L
    DECI=(DIVDEC*100)/L
    LCDOUT $FE, 2, #k, "/",#L,"="
    LCDOUT $FE, $C0, #DIVIN,".",#DECI
    PAUSE 100
    X=0
    ENDIF

HIGH D
IF UNO=1 THEN X=20 'ON
IF DOS=1 THEN X=0
IF TRES=1 THEN X=14 'ENTER
IF CUATRO=1 THEN X=13
IF UNO=1 || DOS=1 || TRES=1 || CUATRO=1 THEN GOSUB ANTIREBOTE:Y=Y+1
PAUSE 10
LOW D

IF X=20 THEN LCDOUT $FE,1,"0":GOTO INICIO2
GOTO OPERACIONES

ELSE
GOTO INICIO
ENDIF
 
saludos mecatrodatos:D he estado leyendo este post y veo que eres muy bueno con el pbasic. por eso, queria pedirte si puedes ayudarme a comprender como utilizar el serin y serout del pbasic. te explico un poco lo que quiero hacer.
mi idea es implementar un control remoto basado en el pic16f84A pero la verdad que no entiendo muy bien como utilizar estas dos instrucciones:oops:. una idea basica seria por ejemplo que si yo presiono un boton en el transmisor, en el receptor se encienda el led que corresponde al mismo. te paso un dibujo del circuito basico espero que se entienda:). solo necesito un par de lineas de codigo como para guiarme. un saludo y espero puedas ayudarme gracias:apreton:picserie.JPG
 
despues de mucho tiempo regreso, y con un problemita: tengo 20 focos, que se encienden en orden, cada vez que pongo una moneda en la ranura, pero cada foco se debe de apagar 10 segundos despues de encendido independiente de que otros esten encendidos o apagados, ademas si se apago alguno, cuando se apague un foco e ingrese una moneda se prenden los focos en orden el objetivo es encender todos los focos
 
que tal cripty podrias explicar un poquito mas claro lo que quieres realizar es que no entendip .

y si tienes algun esquema mucho mejor para poder ayudarte un poco.

saludos ¡¡

a creo que ya entendi aver lo que quieres es que al pasar una moneda en una ranura(un sensor ) se enciendan los 20 focos pero uno por uno y asu vez irse apagando despues de haber pasado un tiempo de 10 segundos.

es correcto ?
 
Última edición:
OK, lo entendiste pero ademas para prenderse el foco siguiente los de atras deben de estar todos prendidos, si alguno esta apagado, ese se prendera primero
 
Buanas con todos; tengo una duda no se si me la puedan absolver; la duda es la siguiente:
Quiero controlar la temperarura de un foco, para lo cual estoy utilizando un LM35 el cual sensa la temperatura del foco y me manda la informacion a un pic 16F877A el cual realiza una conversion A/D y luego realiza una comparacion entre la temperatura que quiero y la temperatura que tengo con lo cual voy a generar un pulso a la salida por un pin del pic para activar a mi triac con lo cual voy de esta forma a controlar la luminosidad de mi foco;controlando esta luminosidad logro controlar la temperatura de mi foco.
Obs: foco es de 60W-220V
controlador es un PIC16F877A
MOC 3021(para aislar nuestro PIC de la parte de potencia)
sensor es el LM35

LA CONSULTA ES SI ES QUE UNO DE USTEDES TIENE UN CODIGO EN C PARA PODER GUIARME O HAYA HECHO ESTE MISMO PROYECTO PUEDA ENVIARME TIPS ACERCA DE LO QUE QUIERO DESARROLLAR.

gracias y saludos
 
que tal lobito fiee en esta pagina excelente de ucontrol tienen elaborado un programa para medir 4 temperaturas: http://www.ucontrol.com.ar/forosmf/programacion-en-c/medidor-de-4-temperaturas-con-lm35-y-lcd-2x16/

espero y te ayude puesto que este curso es de pic basic pro.

medidor-de-4-temperaturas-con-lm35-y-lcd-2x16
 
Última edición:
ya lo termine, pero me gustaria ver que opinan del codigo, ¿se puede optimizar?

Código:
define osc 4
trisa=0
trisb=1

OPTION_REG=%01000100
intcon=%10110000

n   var bit[20]    'vector de banderas
x   var byte[20]   'vector de conteo
i   var byte       'indice de vectores
t   var byte       'timer
f   var byte       'numero de focos -1
p1  var byte 
P2  VAR BYTE
P3  VAR BYTE
LaT  con 1
A1  con 2
CK1 con 3
A2  con 4
CK2 con 5
A3  con 6
CK3 con 7
minu con 240       '4 minutos 4*60
seg  con 122       '1 segundo
low Lat                
i=0 : t=0 : f=19 : p1=0 : p2=0 : p3=0
portb=0

ON INTERRUPT GOTO tiempo

loop:
if t=seg then
t=0                      'reset del tiempo

 for I=0 to f           
  if n[i]=1 then         'verifico el flag
   x[i]=X[i]+1           'incremento las cuentas
  endif
  if x[i]=minu then      'verifico limite de cuentas
   n[i]=0                'reset de flag
   x[i]=0                'reset de contador
  endif
 next i
FOR I=0 TO 7        'secuencia para ordenar los flag
 p1=p1<<1            'y enviarlos por comunicacion serie sincrona
 P1=p1|n[i]           'a los conversores serie, paralelo 
NEXT i
shiftouT a1,ck1,1,[p1]
FOR I=8 TO 15
 p2=p2<<1
 P2=p2|n[i]
NEXT i 
shiftouT a2,ck2,1,[p2]
FOR I=16 TO 19
 p3=p3<<1
 P3=p3|n[i]
NEXT i 
shiftouT a3,ck3,1,[p3]
high Lat
pause 10
low lat
endif
goto loop

disable
tiempo:
if intcon.2=1 then           'interrupcion por tiempo
 t=t+1                       'aumento el conteo anidado del tiempo
 intcon.2=0
 intcon.7=1
endif

if intcon.1=1 then           'interrupcion por moneda
   intcon.1=0
   intcon.7=1
 for i=0 to f
  if n[i]=0 then                'seteo de flags
   n[i]=1
   enable
   goto loop                    'seteado el flag salta de ahi
  endif  
 next i
endif
resume
enable
 
:)hola gente, yo por aqui de nuevo pidiendo una manito:D
les cuento que ya pude hacer funcionar el control remoto con pic digital de cuatro canales. funciona igual que un ht12.
ahora me gustaria hacer un sistema parecido pero con la diferencia que, envez de leer un pulsador y hacer encender un led en el receptor, se pueda leer un potenciometro y mover un servo en el receptor. de manera que se comporte como un control remoto proporcional. que buena idea ¿no?
les cuento que ya estoy desarrollando un programita para los pic´s. aqui estan...
:unsure:lo unico que no se porque razon no me funciona... ¿alguien podria decirme que estoy haciendo mal??? denme una manito cheee... despues subo el circuito para compartirlo. un saludo y gracias:apreton:

transmisor

include "modedefs.bas"
trisb=0
portb=0
pos var byte
serieout var portb.0
potein var porta.0
pote:
Pot potein, 127,pos
serout serieout,T2400,[pos]
goto pote
end

receptor

include "modedefs.bas"
pos var byte
servo1 var byte
cont var byte
portb=0
trisb=0
loop:
serin porta.0,T2400,servo1,pos
for cont = 0 to 50
pulsout servo1,pos
pause 15
next cont
goto loop
 
yo hace poco que estoy en el foro, e posteado muy poco pero e leido mucho. estoy haciendo una alarma con pic para mi auto pero tengo que saber como se implementa el ON INTERRUPT. la alarma que estoy haciendo va a comandar las luses bajas, las luses de interior y un par de cosas mas que se me ocurrieron. ahora mi problema es que no puedo postear el programa que estoy haciendo porque estoy navegando con el celular y no me da las opciones de cargar imagenes. Desde ya mucha gracias y el foro esta re bueno.
 
ON INTERRUPT GOTO label es como un GOSUB solo que despues de cada intruccion que esta en el programa revisa el registro de interrupciones INTCON para ver si ocurio una interrupcion; es decir el programa esta continuamente pendiente de si ha ocurrido una interrupcion; si ocurre una interrupcion salta hacia la label y ejecuta el codigo que esta ahi otra diferencia es que una sub rutina termina en return mientras que el label de la interrupcion termina en un resume ademas cabe resaltar que dentro del codigo del label debes de resetear el registro INTCON y el bit de interrupcion detro de este para que se active frente a una nueva interrupcion; ademas hay que tener en cuenta que mientras haya ocurrido una interrupcion y saltemos a nuestro label no es necesario que se este comprobando que haya ocurrido una nueva interrupcion eso se logra poniendo DISABLE una linea antes del label y para reanudar la comprobacion de interrupciones ponemos un ENABLE una linea despues del RESUME asi ya no se comprueba si haya ocurrido una interrupcion cuando ejecutamos el codigo de nuestro label (esto ultimo se basa en el hecho de que cuando ocurre una interrupcion se modifica el bit de la interrupcion y el bit de habilitacion global de interrupciones es decir no se notifican nuevas interrupciones hasta que este ultimo bit no se ponga en 1 todo esto para que se atienda la interrupcion) un ejemplo lo tienes lineas arriba en el programan que postie ahi esta todo lo que explique; cualquier consulta no dudes en hacerla en el foro entre todos aprendemos mucho bye
 
Atrás
Arriba