Skip to content

Instantly share code, notes, and snippets.

@jerivas
Last active December 28, 2015 09:09
Show Gist options
  • Select an option

  • Save jerivas/7476305 to your computer and use it in GitHub Desktop.

Select an option

Save jerivas/7476305 to your computer and use it in GitHub Desktop.
;Maestro SPI que envía cadenas
;Las direcciones de las cadenas se definen en el bloque VARIABLES
;Carlos Zelada
;Eduardo Rivas
title "PIC18F4550 Envio de cadenas por SPI Modo Maestro"
list p=18F4550
#include <p18f4550.inc>
CONFIG FOSC = INTOSCIO_EC
CONFIG WDT = OFF
CONFIG PBADEN = OFF
CONFIG MCLRE = ON
CONFIG DEBUG = ON
CONFIG LVP = OFF
;VARIABLES
#define input 0x100 ;Direccion de RAM donde se encuentra la cadena recibida
#define output 0x200 ;Direccion de RAM donde se guarda la cadena a enviar
#define len .16 ;Longitud de la cadena de bytes (base 10)
cblock
temp, temp2
endc
;MACROS
;Añade el bit de paridad a una palabra de 7 bits (como un codigo ASCII)
;Cuenta los 1's de la palabra. Numero par, paridad = 0
add_parity macro 7_bit_word
movff 7_bit_word,temp ;Copiar la palabra de siete bits
rlncf temp ;Deshacerse del MSB (alli se añadira la paridad)
movf temp,W ;Copiar la palabra de 7 bits a W
local i = 1
while i < 8
rlncf temp ;Se rota la palabra hacia la izquierda 7 veces
xorwf temp,W ;Se hace XOR con el valor anterior
i += 1
endw ;Al final el MSB será el XOR de los 7 bits, que es la paridad
andlw b'10000000' ;Discriminar todo excepto el MSB que contiene la paridad
iorwf 7_bit_word, f ;Concatenar con la palabra original de 7 bits
endm
;Verifica la paridad de una palabra de acuerdo al algoritmo anterior.
;Si es correcto, retorna en W la palabra de 7 bits, si no, retorna cero.
check_parity macro 8_bit_word
movff 8_bit_word,temp2 ;Guardar la palabra con su paridad
movlw b'01111111' ;Mascara para discriminar el bit de paridad
andwf temp2,F ;Guardar como palabra de 7 bits (ASCII original)
movff 8_bit_word,temp ;Copiar palabra de 8 bits para recalcular paridad
rlncf temp ;Deshacerse del MSB (alli se verificará la paridad)
movf temp,W ;Copiar la palabra a W
local i = 1
while i < 8
rlncf temp ;Se rota la palabra hacia la izquierda 7 veces
xorwf temp,W ;Se hace XOR con el valor anterior
i += 1
endw ;Al final el MSB sera el XOR de los 7 bits, que es la paridad
andlw b'10000000' ;Discriminar todo excepto el MSB que contiene la paridad
iorwf temp2, W ;Concatenar con la palabra guardada de 7 bits
cpfseq 8_bit_word ;Comparar la paridad calculada con la recibida
clrf 8_bit_word ;No concuerdan: guardar un cero en memoria
movff temp2, 8_bit_word ;Si concuerdan: guardar la palabra sin paridad
endm
;Programa principal
org 0
goto main
org 100
main:
bsf OSCCON,6 ;Divisor de preescala del
bsf OSCCON,5 ;reloj a 8Mhz
bsf OSCCON,4
;Configuracion de las lineas fisicas
movlw 0x0f
movwf ADCON1
bcf TRISB,1 ;Salida SCK
bcf TRISC,7 ;Salida SDO
bcf TRISA,1 ;Salida SS
bsf TRISB,0 ;Entrada SDI
bsf TRISD,0 ;Push de entrada
;Configuracion del SPI
movlw B'01000000' ;Muestreo al medio
movwf SSPSTAT
movlw B'00110000' ;Activar el SPI, polaridad, SCK=fosc/4
movwf SSPCON1
;Configuracion de memoria y punteros
lfsr FSR0,output ;Apuntar FSR0 a los datos a enviar
lfsr FSR1,input ;Apuntar FSR1 a los datos a recibir
;Rutina de transmision/recepcion
prep:
clrf FSR0L ;Limpiar puntero de envio
clrf FSR1L ;Limpiar puntero de recepcion
btn_down:
btfss PORTD,0 ;Se presiono el boton?
goto btn_down ;No: Esperar a que se presione
btn_up:
btfsc PORTD,0 ;Si: Se libero el boton?
goto btn_up ;No: Esperar que se libere
com_start:
movf SSPBUF,W ;Si: Lectura tonta del bufer SPI
bcf PIR1,SSPIF ;Limpiar bandera SPI
add_parity INDF0 ;Añadir el bit de paridad antes de enviar
movf INDF0,w
movwf SSPBUF ;Enviar el byte
com_end:
btfss PIR1,SSPIF ;Se completo la transmision?
goto com_end ;No: espere la bandera SPI
movff SSPBUF,INDF1 ;Si: Copiar el byte recibido
check_parity INDF1 ;Verificar la paridad del byte recibido
incf FSR0L ;Aumentar puntero de envio
incf FSR1L ;Aumentar puntero de recepcion
movlw len ;Copiar la longitud a W
cpfseq FSR0L ;Es FSR0L = len? Se transmitio toda la cadena?
goto com_start ;No: Transmitir siguiente byte
goto prep ;Si: Prepararse y esperar el boton
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment