Autor Tema: shiftOut en assembler  (Leído 1834 veces)

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

Desconectado Alan Valdivia

  • PIC10
  • *
  • Mensajes: 4
shiftOut en assembler
« en: 26 de Junio de 2017, 02:07:01 »
Buenas,  necesito emplear la función shiftOut en lenguaje ensamblador, estoy trabajando con un 16F88, lo que quiero hacer es comunicarlo por SPI con un MAX7219, y puesto que tiene SSP y no MSSP, lo único que me queda es hacer una rutina para enviar 16 bits, tal vez haya una manera más sencilla de hacerla que esta, pero no se me ha ocurrido ninguna otra, el problema es que bueno, me trabé en esto, puesto que no se como usar un for en assembler, y tampoco entiendo mucho el "digitalWrite(dataPin, !!(val & (1 << i)))". Si alguno puede explicarme, se lo agradecería muchisimo.

Código: [Seleccionar]
void shiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, uint8_t val)
{
    uint8_t i;

    for (i = 0; i < 8; i++)  {
        if (bitOrder == LSBFIRST)
            digitalWrite(dataPin, !!(val & (1 << i)));
        else   
            digitalWrite(dataPin, !!(val & (1 << (7 - i))));

        digitalWrite(clockPin, HIGH);
        digitalWrite(clockPin, LOW);       
    }
}

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:shiftOut en assembler
« Respuesta #1 en: 26 de Junio de 2017, 13:56:52 »
Lo que tenes ahi es un SPI realizado en software, nada mas, por que no usar el SSP y enviar 2 datos de 8 bits ?

Imagino que sacaste la libreria de un Arduino. Lo unico que hace es discriminar bit a bit y ponerlo en una salida. Me explico un poco mas:

si bitOrder es LSBFIRST y el dato es 0001 1010

Entonces va a enviar los datos en este orden: 0, 1, 0 , 1 , 1 , 0 , 0 , 0
Si no es LSBFIRST lo va a hacer al reves: 0, 0, 0, 1, 1, 0, 1, 0

Luego esta el pulso del clock. Si quisiera usar el SPI para comunicarme con el MAX7219, deberia configura el SSP en modo SPI Master y luego cargar los 2 bytes en el registro para que se envien.
Primero el dato y luego el address ( si es que ves el datasheet del MAX7219 )

Como decia lo mejor es usar el SPI, si aun asi lo queres hacer por software, entonces seria algo asi:

Código: ASM
  1. SPI_OCHO_BITS:
  2.        MOVF    DATO, W
  3.        MOVWF ENVIAR     ; Pongo el dato en un registro aparte
  4.        MOVLW 0x07
  5.        MOVWF CONTADOR ; Cargo el contador para saber cuantos datos a enviar
  6. LOOP:
  7.        RRF  ENVIAR, F
  8.        BTFSC STATUS, C
  9.        GOTO ENVIO_UNO
  10.        BCF   PIN_DATO
  11.        GOTO ENVIO_CLOCK
  12. ENVIO_UNO:
  13.        BSF PIN_DATO
  14. ENVIO_CLOCK:
  15.        BSF   PIN_CLOCK
  16.        BCF   PIN_CLOCK
  17.        DECFSZ CONTADOR,F
  18.        GOTO LOOP
  19.        RETURN

En DATO tenes el dato a enviar, lo pongo en un registro auxiliar que se llama ENVIAR
CONTADOR hace el trabajo de la variable i en el for, el DECFSZ lo que hace es restar 1 y revisar cuadno es 0 CONTADOR asi salir. Sino repite continuamente.
La diferencia radica en que roto y como el bit que queda se va al flag CARRY aprovecho para revisar si es uno o 0 desde alli. Para cambiar y qeu se envie primero el bit de mayor peso, se deberia cambiar solo el RRF por RLF.


 

anything