Saludos
Hoy quiero compatir con la comunidad un pequeño resumen que he hecho acerca del módulo mssp del microcontrolador PIC16F877. En este resumen se da una idea básica como funciona el módulo, en la segunda parte se da un algoritmo para trabajar el módulo mssp en modo SPI tanto para el maestro como para el esclavo y para finalizar un ejemplo desarrollado en leguaje de máquina para seguir de cerca que es lo que hace la máquina espero les agrade.
[bFuncionamiento de módulo MSSP][/b]
El funcionamiento de módulo MSSP esta gobernado por dos registro. El primero de ellos se llama SSPSR que es un registro de desplazamiento y el registro SSPBUF que actua como buffer cuando la información es transmitida o recibida. El registro SSPBUF se encuentra en la dirección 13h (banco 0) de la memoria RAM, en cambio, el registro SSPSR es un registro al cual el usuario no tienen acceso.
Cuando se requiere transmitir un byte (8 bits), el byte se traspasa al registro SSPBUF y automáticamente el contenido del registro SSPBUF se traspasa al registro SSPSR cuya función es ir despalazando bit a bit el contenido del registro SSPBUF transmitiendo ordenadamente al ritmo de los impulsos de reloj. En recepción, los bits va entrado al ritmo del reloj por un terminal del microcontrolador y se van despalzando, en el momento, en que el registro SSPSR se llena, la información pasa inmediatamente al registro SSPBUF y en ese momento se puede leer su contenido. Más adelante se explicara como actuan los señalizadores en el momento en que el registro SSPBUF se llena en recepción.
Protocolo de comunicación serial SPI
El protocolo de comunicación serial SPI permite la transferencia de datos de 8 bits en serie, los cuales pueden se transmitidos y recibido de forma síncrona y simultanea. Para lograr la comunicación se utiliza unos terminales lo cuales son:
1. Serial Clock (SCK) reloj de sincronización
2. Serial Data In (SDI) entradad de datos en serie
3. Serial Data Out (SDO) salida de datps em serie
4. Selección de esclavo (SS#) sólo se utiza cuando el microcontrolador funciona en modo esclavo
En el microcontrolador PIC16F877 esta lineas vienen implementadas en los siguientes terminales RC3/SD0, RC4/SDI, RC5/SCK y RA5/SS#.
En la mayorias de los casos el microcontrolador trabaja en modo maestro para lo cual los terminales deben ser programados así: RC5/SDO como salida, RC4/SDI como entrada y la linea RC3/SCK también como salida, ahora si el microcontrolador trabajara como esclavo, los terminales RC3/SCK como entrada, RC4/SDI como entrada, RC5/SDO como salida y el terminal RA5/SS# debe estar conectado a tierra.
A continuación una serie de pasos para configurar el módulo MSSP en modo SPI tanto en modo maestro como en modo esclavo:
Microcontrolador como maestro
1. Configurar los terminales RC3/SCK y RC5/SDO como salidas.
2. Configurar el terminal RC4/SDI como entrada.
3. Configurar el microcontrolador en modo maestro programando adecuadamente los bits SSPM3 – SSPM0 del registro SSPCON.
4. Poner en “1” lógico en bit SSPEN del registro SSPCON.
5. Configurar el estado de polaridad del reloj en bit CKP del registro SSPCON.
6. Poner en “1” lógico el bit SMP del registro SSPSTAT.
7. Configurar el flanco del reloj activo en el bit CKE del registro SSPSTAT.
8. Cargar el valor que se desea transmitir en el registro SSPBUF.
Microcontrolador como esclavo
1. Configurar los terminales RC3/SCK y RC5/SDO como lineas de entrada.
2. Configurar el terminal RC4/SDI como salida
3. Configurar el microcontrolador en modo maestro programando adecuadamente los bits SSPM3 – SSPM0 del registro SSPCON, es importante aclarar que la velocidades del reloj tanto para el esclavo como para el maestro deben ser las mismas.
4. Poner en “1” lógico en bit SSPEN del registro SSPCON.
5. Configurar el estado de polaridad del reloj en bit CKP del registro SSPCON.
6. Poner en “0” lógico el bit SMP del registro SSPSTAT.
7. Configurar el flanco del reloj activo en el bit CKE del registro SSPSTAT.
8. Activar la interrupción global y la de periféricos en el registro INTCON.
9. Activar la interrupción para la puerta serie síncrona poniendo en “1” lógico el bit SSPIE del registro PIE1.
10. Una vez detectada la interrupción leer el contenido del valor recibido, es decir, el contenido del registro SSPBUF.
11. Limpiar el respectivo señalizador de interrupción y bit WCOL del registro SSPCON.
“Comunicación entre 2 microcontroladores PIC16F877 utilizando el protocolo SPI”
En el presente ejemplo se va aplicar todo lo estudiado acerca de la comunicación serial en modo SPI, para comunicar 2 microcontroladores PIC16F877 mediante el protocolo SPI.
El programa es sencillo, un microcontrolador actuara como maestro y el otro como esclavo, el microcontrolador maestro tiene como función realizar una conersión A/D por el canal 0, el valor digital capturado por microcontrolador maestro será enviado al microcontrolador esclavo mediante el protocolo SPI y este a su vez mostrara el dato recibido por el puerto B.
A continuación se muestra el código en lenguaje de máquina para el maestro:
;*********************** Registro de control *************************************
status equ 03h
porta equ 05h
portb equ 06h
portc equ 07h
portd equ 08h
porte equ 09h
intcon equ 0bh
pir1 equ 0ch
sspbuf equ 13h
sspcon equ 14h
adcon0 equ 1fh
adresh equ 1eh
trisa equ 85h
trisb equ 86h
trisc equ 87h
trisd equ 88h
trise equ 89h
pie1 equ 8ch
sspstat equ 94h
adresl equ 9eh
adcon1 equ 9fh
;******************************* Registro de usuario ****************************
bandera equ 20h
lectura equ 21h
loop1 equ 22h
loop2 equ 23h
;******************************* Empieza el programa ***************************
list p = 16f877
org 00
goto inicio
org 04
goto inter
;****************************** Rutina que controla las interrupciones ********
inter btfsc pir1,6 ; Pregunta si hubo interrupción por fin
; De conversión A/D
goto convierte
retfie ; Si no hubo interrupción sale de la
; Interrupción
;************* Rutina de atención de interrupción de la conversión A/D *****
convierte
bcf pir1,6 ; Se limpia la bandera de interrupción
movlw d'1'
movwf bandera ; Se pone bandera en 1 para indicar
; Que hubo conversión A/D
movf adresh,0
movwf lectura ; Se leé el valor de la conversión a 8
movwf sspbuf ; Bits se traspasa el valor al registro
; SSPBUF para ser transmitido
retfie ; Sale de la interrupción
;***************************** Rutina de unos microsegundo *******************
retar movlw d'255'
movwf loop1
movlw d'100'
movwf loop2
decfsz loop2,1
goto $-1
decfsz loop1,1
goto $-5
return
;****************************** Rutina principal MAIN() *************************
inicio bcf status,6
bsf status,5 ; Banco 1
movlw b'11111111'
movwf trisb ; Puerto B como entradas digitales
movlw b'11010111'
movwf trisc ; Se configura RC3/SCK como salida,
; RC4/SDI como entrada y
; RC3/SDO como salida
movlw b'11111111'
movwf trisa
movwf trisd
movwf trise ; Puertos A,C,D y E como entradas
; Digitales
clrf adresl ; Se Limpia inicialmente la conversión
movlw b'00000001'
movwf adcon1 ; Se configura el adcon1 para que
; Todas los canales sean
; Entradas análogas y RA3 como Vref+
movlw b'11000000'
movwf sspstat ; Se configura el modo SPI para
; Muestrear al final del Impulso del
; Reloj
movlw b'01000000'
movwf pie1 ; Se activo la interrupción por fin de
; Conversión A/D
bcf status,5 ; Banco 0
clrf portb
clrf lectura
clrf adresh ; Se inicializan todos los registros que
; Se van a trabajar
movlw b'11000000'
movwf intcon ; Se activa la interrupción Global y la
; De periféricos
movlw b'00100000'
movwf sspcon ; Se activa el modo SPI en modo
; Maestro con reloj Fosc/4
movlw b'10000001'
movwf adcon0 ; Se Configura el canal 0 y se activa el
; Inicio de la conversión A/D
bsf adcon0,2
repite
movf bandera,0 ; Se pasa bandera a W
xorlw d'1' ; Comparo si son iguales
btfss status,2
goto repite
clrf bandera
call retar ; Una pequeña rutina de tiempo para
; Volver a iniciar la conversión
bsf adcon0,2 ; Inicia nuevamente la conversión
goto repite ; Bucle infinito
end
Código para el esclavo en el esamblador:
;*********************** Registro de control *************************************
status equ 03h
porta equ 05h
portb equ 06h
portc equ 07h
portd equ 08h
porte equ 09h
intcon equ 0bh
pir1 equ 0ch
sspbuf equ 13h
sspcon equ 14h
trisa equ 85h
trisb equ 86h
trisc equ 87h
trisd equ 88h
trise equ 89h
pie1 equ 8ch
sspstat equ 94h
;******************************* Registro de usuario ****************************
lectura equ 40h ; Variable que contiene el valor
; Recibido por la
; Comunicación SPI
;******************************* Empieza el programa ***************************
list p = 16f877
org 00
goto inicio
org 04
goto inter
;******************** Rutina que controla las interrupciones ******************
inter btfsc pir1,3 ; Pregunta si hubo interrupción por la
; Puerta serie síncrona
goto recibe
retfie ; Si no hubo interrupción sale de la
; interrupción
;************** Rutina de atención de interrupción de la serie sincrona ******
recibe
movf sspbuf,0
movwf lectura ; Se leé el byte recibido
movwf portb
bcf pir1,3 ; Se inicializa la interrupción
bcf sspcon,7 ; Se limpia el bit WCOL si hubo una
; Interrupción
retfie ; Retorna al PCL + 1
;****************************** Rutina principal MAIN() *************************
inicio bcf status,6
bsf status,5 ; Banco 1
movlw b'00000000'
movwf trisb ; Puerto B como salidas digitales
movlw b'11101111'
movwf trisc ; Se configura RC3/SDO como
; Entrada, RC4/SDI como salida y
; RC5/SCK como entrada
movlw b'11111111'
movwf trisa
movwf trisd
movwf trise ; Puertos A,C,D y E como entradas
; Digitales
movlw b'11000000'
movwf sspstat ; Se configura el modo SPI para
; Muestrear al final del Impulso del
; Reloj
movlw b'00001000'
movwf pie1 ; Interrupción por el módulo serie
; Síncrono habilitado
bcf status,5 ; Banco 0
clrf portb
clrf lectura
movlw b'11000000'
movwf intcon ; Se activa la interrupción Global y la ; De periféricos
movlw b'00100100'
movwf sspcon ; Se activa el modo SPI en modo
; Esclavo con reloj SCK
nada goto nada ; Espera interrupción al llenarce el
; SSPBUF
end
Buenos compañeros eso era todo lo que queria compartir con ustedes ojalá el resumen sirva de ayuda a los que se inician con este módulo.