TODOPIC
Microcontroladores PIC => Lenguaje Basic para microcontroladores PIC => Mensaje iniciado por: edrp en 02 de Julio de 2012, 21:40:25
-
Buenas, estoy realizando un programa en mikrobasic con un pic 16f628a, lo que hace basicamente es leer los codigos RC5 de un control y segun el numero precionado activa la salida correspondiente en el puerto a, el programa funciona bien, cunado presiono la tecla 1, enciende el LED colocado en el puerto A bit 0, pero cuando presiono el numero 2 enciende el LED puerto A bit 1 y se apaga el bit 0, ya no se que hacer, les copio parte del codigo para que me puedan dar una mano. El programa simulado en Proteus funciona de maravillas.
Main:
TRISA = %00000000
PORTb.0 = 0
TRISB = 0
PORTB = 0xFF
TRISB = %00000001
porta = 0x00
'Reset de variables
Inicio_Bit_1=0
Inicio_Bit_2=0
Toggle_Bit=0
Comando=0
Sistema=0
Control=0
n3=0
t=0
a=0
d = 0
j = 0
Lcd_Init() ' Initialize Lcd
Lcd_Cmd(_LCD_CLEAR) ' Clear display
Lcd_Cmd(_LCD_CURSOR_OFF) ' Cursor off
lcd_out(2,2,"RC5")
while true
Inicio:
BD1 = 0
WHILE PORTb.0 = 1
Comando=0
Sistema=0
Control=0
WEND
BD1 = 0
WHILE (PORTb.0= 0) And (BD1 < Glitch)
INC(BD1)
WEND
IF BD1 > Glitch THEN
delay_ms(1)
goto inicio
End if
ComandoAnt = Comando 'Guarda los valores anteriores por si hay algun error
SistemaAnt = Sistema
Delay_us(200) '200us de respiro para el procesamiento del primer dato
Inicio_Bit_1.0=Bit_IR 'Bits de inicio
Inicio_Bit_2.0=Bit_IR
Sistema.4=Bit_IR 'Bits de Sistema
Sistema.3=Bit_IR
Sistema.2=Bit_IR
Sistema.1=Bit_IR
Sistema.0=Bit_IR
Comando.5=Bit_IR 'Bits de comando
Comando.4=Bit_IR
Comando.3=Bit_IR
Comando.2=Bit_IR
Comando.1=Bit_IR
Comando.0=Bit_IR
'Bit de Toggle
Toggle_Bit = Toggle_Bit xor 1
select case comando ' en esta variable se muestra correctamente la tecla presionada
case 1
porta.0 = toggle_bit
case 2
porta.1 = toggle_bit
case 3
porta.2 = toggle_bit
case 4
porta.3 = toggle_bit
end select
'Presentamos la informacion de comando recibida
bytetostr(comando,txt)
LCD_out(1,1,"com: "+txt)
bytetostr(a,txt)
lcd_out(2,1,"sistema: "+txt)
bytetostr(tecla,txt)
lcd_out(1,9,"tcl: "+txt)
Delay_ms(10)
wend
End.
muchas gracias
-
Que tal amigo, mira ese programa ya lo relicé hace tiempo y con algunas modificaciones lo hice trabajar, no obtatnte trabajo pero nunca pude entender la lógica del algoritmo por lo que lo deseché en mi carpeta de programas, voy a buscarlo y lo posteo,por lo pronto te dejo este otro programa que decodifica el RC5 con el PIC16F628 pero con otro logaritmo.
Como comentario estoy considerando el receptor IR con nivel bajo al recibir señal.
program IR_RC5_A
' Trabaj OK 10 Junio 2012
' PORTB.0 entrada (normalmente alta) debido al receptor IR
' PIC16F628 a 16 MHZ 128 us por cada interrupción, 0.5 us/tick
' evento ideal min max
' short pulse 889us 444us 1333us
' short space 889us 444us 1333us
' long pulse 1778us 1334us 2222us
' long space 1778us 1334us 2222us
' Para calculo de número de declaraciones se toman valores min y divide por
' el número de cuentas de las interrupciones del timer (.000128)
' entonces .000444 / .000128 = 3.46xx o redoneando a 3
' Valores mínimo y máximo de números de usar
' min para short pulse = 444uS / 128uS = 3.4 o 3
' max para short pulse = 1333 / 128 = 10.4 o 10
' min para long pulse = 1334 / 128 = 10.4 o 11 (redondeo para evitar empalme)
' max para long pulse = 2222 / 128 = 17.3 o 17
DIM i, Datos as short
dim irProc as byte
dim irState as byte
dim irTmr as byte
dim irTmrCtr as byte
dim irTime as byte
dim irBitState as byte
dim irData as word
dim Recep as byte
dim Sistema, Comando as byte
const MID1 = 1 'Posición a la mitad de un "1"
const MID0 = 2 'Posición a la mitad de un "0"
const START1 = 3 'Estado que suge de o lleva a un "1"
const START0 = 4 'Estado que surge o lleva a un "0"
const IRERROR = 5 'Situación originada por un error
const IRSHORT = 0 'Señal IR corta
const IRLONG = 1 'Señal IR larga
sub procedure interrupt
INTCON = %10100000
inc(irTmr) ' Cada desborde por interrupción =128uS
inc(irTmrCtr) ' Contador de interrupciones
' Si en el proceso se obtiene un pulso o espacio en la entrada procesa
if irProc = 1 then ' Ve si está listo para recibir trama
' En caso de error esperar comando IR
if IRState = IRERROR then ' Hubo error?
if irTmrCtr > 194 then '1.778mS*14 bits=24.88ms/.128uS= 194 cuentas
irProc = 0 '
end if
else
if i<0 then ' Si hay 14 bits tenemos un código
Datos=1
irProc = 0
end if
if PORTB.0 = irBitState then ' Cambia estado de bit
irBitState = 1 - irBitState ' Toggle actual bitstate
if (irTmr > 11) and (irTmr < 17) then ' Obteniendo valor del tiempo
irTime = IRLONG
else
if (irTmr > 3) and (irTmr < 10) then
irTime = IRSHORT
else
irState = IRERROR ' De ser error entonces reset
end if
end if
irTmr = 0 ' reset Timer
select case irState
case MID1
if irTime = IRSHORT then
irState = START1
else ' Si no tiene que ser largo
irState = MID0
ClearBit (IRDATA,i)
dec(i)
end if
case MID0
if irTime = IRSHORT then
irState = START0
else ' Ha sido largo
irState = MID1
SetBit (IRDATA,i)
dec(i)
end if
case START1
if irTime = IRSHORT then
irState = MID1
SetBit(IRDATA,i)
dec(i)
else ' Ha sido largo (es un error)
irState = IRERROR
end if
case START0
if irTime = IRSHORT then
irState = MID0
ClearBit (IRDATA,i)
dec(i)
else ' Ha sido largo (esto es un error)
irState = IRERROR
end if
end select
else
' 2252uS es demasiado largo... reset 2252uS=27*85uS
if irTmr > 17 then ' 2252u seconds is too long... reset
irState = IRERROR
end if
end if
end if
else ' Si hay error
if PORTB.0 = 0 then ' No procesa pero mira si debe empezar
irProc = 1
i=13
irBitState = 1
irState = MID1 ' Mid1 bit state
SetBit (IRDATA,i) ' Set initial bit
dec(i)
irTmr = 0
irTmrCtr = 0
end if
end if
end sub
main:
OPTION_REG = %00000000 ' Prescale:2, CK interno
INTCON = %10100000 ' Activo TMR0
CMCON=7
TRISA = 0
TRISB = 1
PortA=0
PORTB = 0
irProc = 0 ' 0 = no procesa ; 1 = procesando
Recep=0
while true
if Datos = 1 then ' Se recibió un dato de 14 bits?
Delay_ms(500)
irProc = 0
Comando = (irData)and($3F) ' Extrae código de comando enviado
Sistema = irData >> 8 ' Desplaza bits derecha y extrae código disposit.
Datos = 0 ' Inicializamos la bandera de recepción
irData=0
SetBit(PortA,3) ' Parpadeo de LED indicador de Recepción
' * generación de las salidas en función de comandos recibidos
'Tecla 0 apaga todos los canales
if comando=0 then
delay_ms(100) ' retardo
portA=0 ' Apaga todo el puerto
end if
if comando=1 then
delay_ms(100) ' retardo
if portA.0=0 then ' Si el pin esta en bajo
portA.0=1 ' cambio al nivel alto
else
portA.0=0 ' si estaba en alto cambio a nivel bajo
end if
end if
if comando=2 then
delay_ms(100)
if portA.1=0 then
portA.1=1
else
portA.1=0
end if
end if
if comando=3 then
delay_ms(100)
if portA.2=0 then
portA.2=1
else
portA.2=0
end if
end if
Delay_ms(5)
ClearBit(PortA,3)
end if
wend
end.