Autor Tema: Comunicación SPI en Atmega48, funciona cuando quiere  (Leído 2136 veces)

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

Desconectado siarc

  • PIC10
  • *
  • Mensajes: 2
Comunicación SPI en Atmega48, funciona cuando quiere
« en: 21 de Julio de 2014, 00:47:25 »
Hola a todos!

Tengo una gran pregunta en comunicación SPI, he leído el datasheet, buscado ejemplos pero no logro ver por qué funciona aveces si y otras no mi programa. Para entender bien esta comunicación hice el código para que un atmega48 mande el contenido de 1 registro (dado=5) cuando presione un pulsador y regrese a cero, a otro atmega48 y este último lo despliegue por el puerto D, el problema es que a veces lo hace y otras no y realmente no se que pasa,  ¿hay algo que me falta? me ayudaría mucho que me mencionaran cualquier error que noten. Yo creo que tiene que ver con la sincronía pero no encuentro el error.
El código de MASTER es el siguiente:

Código: [Seleccionar]
.include "m48def.inc"                         ;LIBRERIA PRINCIPAL
.device ATmega48

                     
.DEF AUX = R16                   ;DEFINICION DE REGISTROS AUXILIARES
.DEF AUX2 = R17
.DEF AUX3   = R18
.DEF AUX4   = R19
.DEF XOR    = R20
.DEF DADO   = R21
.DEF OTRO   = R22

RCALL   DELAY
LDI     AUX, 0B10000000                       ;PUERTO D COMO ENTRADA
OUT      DDRD,AUX   
LDI       DADO,0B00000110
LDI     AUX2,0B00000000



BOTON_1:
    LDI AUX,0B10000000
    OUT DDRD,AUX
    IN         AUX2,PIND                         ;LEE PIND CONSTANTEMENTE PARA REVISAR SI SE PRESIONA EL BOTÓN
    SBIC    PIND,0   
    RJMP    BOTON_0
    RJMP    BOTON_1

BOTON_0:
 
    LDI       AUX,0B10000000
    OUT DDRD,AUX
    IN AUX2,PIND                         ;LEE PIND CONSTANTEMENTE PARA REVISAR SI SE DEJA DE PRESIONAR 
    SBIC     PIND,0                            ;EL BOTÓN
    RJMP    BOTON_0

RCALL SPI_MASTERINIT
RCALL SPI_MASTERTRANSMIT
RJMP BOTON_1

SPI_MASTERINIT:
                                                                         ;SET MOSI & SCK & SS COMMO SALIDAS, LAS DEMÁS COMO ENTRADAS
LDI AUX2,(1<<DDB3)|(1<<DDB5)|(1<<DDB2)   
OUT DDRB, AUX2                           
                                         
LDI AUX2, (1<<SPE)|(1<<MSTR)|(1<<SPR1)    ;HABILITA SPI, MASTER, SET CLOCK RATE FCK/64
OUT SPCR, AUX2

;************************************************************
    LDS   XOR, PRR  ; REGISTRO  DE REDUCCION DE ENERGÍA (PRR)
    CBR   XOR, 2     ;CAMBIAR PRSPI A 0 PARA ACTIVAR EL USO DE RELOJ
    STS   PRR, XOR
;*********************************************************************
RET

SPI_MASTERTRANSMIT:
    SBI   PORTB,2                              ;SS=0, COMIENZA TRANSMISIÓN DE DATOS (DADO)
    OUT  SPDR,DADO
    CBI   PORTB,2 

WAIT_TRANSMIT:
                                               ;ESPERA QUE LA TRANSMISIÓN SEA COMPLETADA
IN    OTRO,SPSR
SBRS  OTRO,SPIF
RJMP  WAIT_TRANSMIT
;************************************************************
    LDS   XOR, PRR  ; REGISTRO  DE REDUCCION DE ENERGÍA (PRR)
    SBR   XOR, 2     ;CAMBIAR PRSPI A 1 PARA DESACTIVAR EL USO DE RELOJ
    STS   PRR, XOR
;**********************************************************************
RET

;*************************
;SUBRUTINA DE RETARDO
;*************************
DELAY:                                     ;MENOS DE 1 SEG

              ldi  R31, $09
              ldi  R30, $BC
LOOP1:    ldi  R29, $C4
LOOP2:    dec  R29
               brne LOOP2
              dec  R30
              brne LOOP1
       
              nop
RET

El del SLAVE es este:

Código: [Seleccionar]
.include "m48def.inc"             ;LIBRERIA PRINCIPAL
.device ATmega48

                     
.DEF AUX = R16                 ;DEFINICION DE REGISTROS AUXILIARES
.DEF AUX2 = R17
.DEF AUX3   = R18
.DEF AUX4   = R19
.DEF XOR    = R20
.DEF DADO   = R21
.DEF OTRO   = R22

REGRESA:
LDI     AUX3,0B11111111           ;PUERTO D SALIDA                       
OUT     DDRD,AUX3
LDI     AUX2,0B00000000


RCALL   SPI_SLAVEINIT
RCALL   SPI_SLAVERECEIVE
OUT     PORTD, DADO
RCALL   DELAY
RJMP     REGRESA


SPI_SLAVEINIT:                    ;SET MISO OUTPUT, ALL OTHERS INPUT
    LDI    AUX2, (1<<DDB4)       
    OUT    DDRB, AUX2           

;************
;ENABLE SPI
;************
    LDI     AUX2, (1<<SPE)
    OUT     SPCR, AUX2
RET

SPI_SLAVERECEIVE:
    IN      AUX4, PINB
    SBIC    PINB,2
    RJMP    SPI_SLAVERECEIVE

SIGUE:                            ;WAIT FOR RECEPTION COMPLETE
                                 
LDS     AUX,SPSR
SBRS    AUX,SPIF
RJMP    SIGUE                 
IN      DADO, SPDR
SBI     PORTC,5                ;READ RECEIVED DATA

RET


;*************************
;SUBRUTINA DE RETARDO
;*************************
DELAY:                        ;MENOS DE 1 SEG

          ldi  R31, $09
LOOP0:    ldi  R30, $BC
LOOP1:    ldi  R29, $C4
LOOP2:    dec  R29
          brne LOOP2
          dec  R30
          brne LOOP1
       
          nop
RET


Muchas gracias

P.D. Lo estoy manejando con clock interno a 8MHz

Desconectado siarc

  • PIC10
  • *
  • Mensajes: 2
Re: Comunicación SPI en Atmega48, funciona cuando quiere
« Respuesta #1 en: 25 de Julio de 2014, 23:56:40 »
Ya funcionó, el problema principal fue que en conexión uno a uno (un Master y 1 salve) el  pin ss del master va a vcc y el del salve a gnd ( para que el master siempre esté seleccionado como tal y el salve siempre esté recibiendo datos)