Autor Tema: Comunicación serie entre pics  (Leído 2141 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado fco1306

  • PIC16
  • ***
  • Mensajes: 128
Comunicación serie entre pics
« en: 22 de Julio de 2011, 15:03:23 »
Estoy intentando hacer una especie de programador de posición de un servo.A un 16f876 conecto un teclado y una pantalla lcd. Una de las salidas del pic la conecto a un 12f629 al que quiero transmitir el valor de posición del servo.Estoy intentando primero algo sencillo. En pbp mando lo siguiente
Código: [Seleccionar]
for c=1 to 8
SerOut PORTb.0, T300, ["A"]
pause 500
next c

El 12f629 lo programo con pic simulator y le digo
Código: [Seleccionar]
Serin GPIO.0, 300, total
If total = "A" Then
rojo = 1
verde = 1
Endif
Tengo conectado un virtual terminal al 12f629 y veo que le llega AAAAA, unas veces 4AAAA y otras 6.¿Alguna idea? Llevo una semana dando mirando por los foros y parece que la comunicación entre pics es un poco complicado.Una cosa es la teoría y otra la práctica.¿Se puede hacer de otra forma?
Muchas gracias

Desconectado fco1306

  • PIC16
  • ***
  • Mensajes: 128
Re: Comunicación serie entre pics
« Respuesta #1 en: 22 de Julio de 2011, 15:58:34 »
 :oops:Me respondo.El problema es que rojo lo tenía conectado a GP.3 y la variable total como word,Una cosa que observo cuando transmito es que si aumento el pause el 12f detecta más veces el envío.
Voy a seguir haciendo pruebas para ver si llega en vez de un caráter ascii una variable.
Al final lo que necesito es que lleguen números de cuatro cifras, ¿me dais alguna pista de cómo puedo seguir?

Desconectado fco1306

  • PIC16
  • ***
  • Mensajes: 128
Re: Comunicación serie entre pics
« Respuesta #2 en: 24 de Julio de 2011, 17:50:59 »
Este es el código que uso para el teclado
Código: [Seleccionar]
'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2011 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 23/06/2011                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************
Define CONF_WORD = 0x3d71
Define osc = 4
include "modedefs.bas"
ADCON1=7     
TRISA = $00 
TRISB = $00 
TRISC = %11110000  ;puerto c teclado 4bits bajos salidas 4 altos entradas
SYMBOL COLUMA =PORTC.0
SYMBOL COLUMB=PORTC.1
SYMBOL COLUMC=PORTC.2
SYMBOL COLUMD=PORTC.3
SYMBOL UNO=PORTC.4
SYMBOL DOS=PORTC.5
SYMBOL TRES=PORTC.6
SYMBOL CUATRO=PORTC.7


'#########################################################################
'define variables
 numero var Byte
 digito var byte[3]
 codigo var byte
 i var byte
 total var word
 v var byte
 a var byte
 b var byte
 c var byte
 d var byte
 m VAR BYTE
 velocidad var word
 valor var word
 
'#########################################################################

 main:  'comienza el programa principal
    a=0
    b=0
    v=0
    pause 500
    Lcdout $fe,1
    LCDOUT $fe,2,  "12F629<A>"
    lcdout $fe,$c0,"16F628-SERVO1<B>"
    pause 1000
    Lcdout $fe,1
    lcdout $fe,2,"16F628-SERVO2<C>"
    pause 1000
    gosub opcion
    select case numero
    case 10
    numero=0
    V=1
    GOSUB MENU_DOS
   
    CASE 11
    numero=0
    V=2
    GOSUB MENU_DOS
   
    CASE 12
    V=3
    numero=0
    GOSUB MENU_DOS
   
    CASE ELSE
    GOTO MAIN   
    end select

End                                               

MENU_DOS:
    Lcdout $fe,1
    LCDOUT $fe,2,  "VELOCIDAD<A>"
    lcdout $fe,$c0,"ANGULO<B>"
    pause 1000
    gosub opcion
 
    select case numero
    case 10
    m=1
    Lcdout $fe,1
    LCDOUT $fe,2,  "TECLEE VELOCIDAD>"
    pause 1000
    lcdout $fe,$c0
    for i=1 to 2
    gosub opcion
    digito[i]=numero
    if digito[i]>9 then goto MENU_DOS
    lcdout $fe,$14,#digito[i]
    pause 50
    next i
    digito[1]=digito[1]*10
    total=digito[1]+digito[2]
    digito[3]=0
    gosub transmitir
    GOTO MAIN
   
   
   
   
    CASE 11
    m=2
    Lcdout $fe,1
    LCDOUT $fe,2,  "ANGULO DCH>"
    pause 1000
    lcdout $fe,$c0
    for i=1 to 3
    gosub opcion
    digito[i]=numero
    if digito[i]>9 then goto MENU_DOS
    lcdout $fe,$14,#digito[i]
    pause 50
    next i
    'digito[1]=digito[1]*100
    DIGITO[2]=DIGITO[2]*10
    total=digito[2]+digito[3]
    gosub transmitir
   
    Lcdout $fe,1
    LCDOUT $fe,2,  "ANGULO IZQ>"
    pause 1000
    lcdout $fe,$c0
    for i=1 to 3
    gosub opcion
    digito[i]=numero
    if digito[i]>9 then goto MENU_DOS
    lcdout $fe,$14,#digito[i]
    pause 50
    next i
    digito[1]=digito[1]*100
    DIGITO[2]=DIGITO[2]*10
    total=digito[1]+digito[2]+digito[3]
    gosub transmitir
     
    GOTO MAIN
    CASE ELSE
    GOTO MAIN   
    end select
   
RETURN




transmitir :
for c=1 to 12
SerOut PORTb.0, T300, [total]
SerOut PORTb.1, T300, [6,6,"OK",#total]
pause 1000
next c
return


opcion:
gosub barrido
gosub ptecla
Return                                           





barrido:

LOW COLUMA
IF UNO=0 THEN NUMERO=1:RETURN;TECLA 1
IF DOS=0 THEN NUMERO=2:RETURN;TECLA 2
IF TRES=0 THEN NUMERO=3:RETURN;TECLA 3
IF CUATRO=0 THEN NUMERO=10:RETURN;TECLA A
HIGH COLUMA
LOW COLUMB
IF UNO=0 THEN NUMERO=4:RETURN;TECLA 4
IF DOS=0 THEN NUMERO=5:RETURN;TECLA 5
IF TRES=0 THEN NUMERO=6:RETURN;TECLA 6
IF CUATRO=0 THEN NUMERO=11:RETURN;TECLA B
HIGH COLUMB
LOW COLUMC
IF UNO=0 THEN NUMERO=7:RETURN;TECLA 7
IF DOS=0 THEN NUMERO=8:RETURN;TECLA 8
IF TRES=0 THEN NUMERO=9:RETURN;TECLA 9
IF CUATRO=0 THEN NUMERO=12:RETURN;TECLA C
HIGH COLUMC
LOW COLUMD
IF UNO=0 THEN NUMERO=13:RETURN;TECLA *
IF DOS=0 THEN NUMERO=0:RETURN;TECLA 0
IF TRES=0 THEN NUMERO=14:RETURN;TECLA #
IF CUATRO=0 THEN NUMERO=15:RETURN;TECLA D
HIGH COLUMD
pause 10
goto barrido

                           
ptecla:
pause 50
espacio:
if UNO=0 or dos=0 or tres=0 or cuatro=0 then espacio
pause 25
return

Me funciona bastante bien.
El del receptor
Código: [Seleccionar]
Define CONF_WORD = 0x3184
Define CLOCK_FREQUENCY = 4
AllDigital
'OPTION_REG = %1011111
'INTCON = %10010000
Symbol rojo = GPIO.1
Symbol boton = GPIO.3
Symbol verde = GPIO.4
Symbol rele = GPIO.2
Symbol servo = GPIO.5
TRISIO = %001001
'#########################################################################
'define variables
Dim velocidad As Byte
Dim n As Byte
Dim total As Byte
Dim total1 As Word
Dim p1 As Byte
Dim p2 As Byte
Dim p3 As Byte
Dim p4 As Byte
Dim posicion As Byte  '1 centro 2-dch 3-izq posicion servo
Dim pulso_dch As Byte  'angulo dch servo
Dim pulso_izq As Byte  'angulo izq servo
Dim outon As Byte  'Tiempo de la señal de control del servo a On (duty cycle)
Dim outon1 As Byte
Dim outoff As Word
Dim periodo As Word
Dim off1 As Word
Dim off2 As Word
Dim off3 As Word
Dim off4 As Word
'##########################################################################
Gosub leer
rojo = 0
verde = 0
servo = 0
periodo = 2000
If posicion = 0xff Then  'el servo se conecta la primera vez
posicion = 01
Write 01, posicion
pulso_dch = 155
Write 03, pulso_dch
pulso_izq = 155
Write 04, pulso_izq
velocidad = 1
Write 06, velocidad
servo = 0
rojo = 1
verde = 1
rele = 0
Endif


If posicion = 02 Then
Call servo_inicio(pulso_dch)
servo = 0
rojo = 1
verde = 0
rele = 0
Endif

If posicion = 03 Then
Call servo_inicio(pulso_izq)
servo = 0
rojo = 0
verde = 1
rele = 1
Endif
'Enable
'######################################################
'inicio programa
main:
Read 01, posicion
Read 03, pulso_dch
Read 04, pulso_izq
Read 06, velocidad
rojo = 0
verde = 0
WaitMs 1000

Serin GPIO.0, 300, total


Serout GPIO.2, 300, #total

If total > 0 And total < 50 Then
Write 06, total

rojo = 1
verde = 1
Endif
WaitMs 1000

If total > 65 And total < 155 Then
rojo = 1
verde = 0
Write 04, total
Endif
WaitMs 1000
If total > 155 And total < 250 Then
rojo = 0
verde = 1
Write 03, total
Endif
WaitMs 1000
If total = 155 Then
rojo = 0
verde = 0
Write 04, total
Write 03, total
Endif
If boton = 1 Then Gosub mover_servo
Goto main

End                                               

'###################################################
'mueve el servo
mover_servo:
'On Interrupt
Gosub leer
'Select Case posicion
'Case 0
If posicion = 01 Then
Call servo_directo(155, 155)
servo = 0
rojo = 0
verde = 0
WaitMs 200
rojo = 0
verde = 1
rele = 0
Write 01, 02
Return
Endif
If posicion = 02 Then
'el servo està en dch y tiene que pasar a izq
Call servo_inverso(pulso_dch, pulso_izq)
servo = 0
rojo = 0
verde = 0
WaitMs 200
rojo = 1
verde = 0
rele = 1
Write 01, 03
Return
Endif
If posicion = 03 Then
'Case 03
Call servo_directo(pulso_izq, pulso_dch)
'el servo está en izq y tiene que pasar a dch
servo = 0
rojo = 0
verde = 0
WaitMs 200
rojo = 0
verde = 1
rele = 0
Write 01, 02
Return
Endif
'Case Else
'EndSelect

'INTCON.1 = 0
'Resume
Return                                           

leer:
Read 01, posicion
Read 03, pulso_dch
Read 04, pulso_izq
Read 06, velocidad
Return                                           


Proc servo_inicio(x As Byte)
Const periodo1 = 2000
Dim outoff1 As Word
outoff1 = (periodo1 - x) * 10  'Calculo tiempo de la señal a Off en uSeg.
For n = 1 To 75  'Se repite durante 1500mSeg. para dar tiempo al servo a posicionarse
ServoOut servo, x  '1.6mSeg. (señal a On)
WaitUs outoff1  'Tiempo de la señal a Off
Next n
End Proc                                         


Proc servo_directo(x1 As Byte, y1 As Byte)
Const periodo2 = 2000
Dim outoff2 As Word
Dim outon_2 As Byte
For outon_2 = x1 To y1  'De un punto a otro
outoff2 = (periodo2 - outon_2) * 10  'Calculo tiempo de la senal a Off en uSeg.
For n = 0 To velocidad  'Control velocidad
ServoOut servo, outon_2  'Senal a on
WaitUs outoff2  'Tiempo de la senal a Off
Next n
Next outon_2
End Proc                                         


Proc servo_inverso(x2 As Byte, y2 As Byte)
Const periodo3 = 2000
Dim outoff3 As Word
Dim outon_3 As Byte
For outon_3 = x2 To y2 Step -1  'De un punto a otro
outoff3 = (periodo3 - outon_3) * 10  'Calculo tiempo de la senal a Off en uSeg.
For n = 0 To velocidad  'Control velocidad
ServoOut servo, outon_3  'Senal a on
WaitUs outoff3  'Tiempo de la senal a Off
Next n
Next outon_3
End Proc                                         

Está en pic simulator, ya que tengo un problema con el 12f629 en pbp.
Recibe números de dos cifras. Cuando quiero mandar uno de tres, cuando mando el ángulo a la dch, me llega cualquier cosa.¿Cómo se podría hacer para que llegaran de tres?
Este es la simulación