Autor Tema: Acelerometro LIS331DL por SPI  (Leído 1075 veces)

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

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3452
    • Pinballsp
Acelerometro LIS331DL por SPI
« en: 02 de Mayo de 2016, 11:52:48 »
.


¿ alguno habeis utilizado el acelerómetro LIS331DL por SPI ?.

Ya he montado todo el programa, y el puñetero chip no responde. Las señales en el analizador lógico parece que son todas correctas, pongo una captura de pantalla, ahí está el Chip Select (D12) que bascula a nivel lógico bajo para selecionar el chip, la señal de reloj (D8) con dos trenes de 8 pulsos uno para el envio de un byte (WriteSPI) y el otro para la lectura de la respuestas del LIS331 (ReasdSPI), la señal SDO del PIC (D10) que muestra que este envía datos al LIS331, y la señal SDI del PIC (D9) que no muestra nada (el LIS331 no responde), coincidiendo con el segundo tren de pulsos del oscilador que se corresponde con el ReadSPI el LIS331 debería de responder por su SDO, pero no saca nada.

Estoy barajando varias posibilidades. El chip LIS331 que me vendieron los chinos es basura (tengo un carrete), el programa tiene algún fallo aunque no parece que sea de configuración de SPI, el chip está mal soldado aunque lo he comprobado al microscopio y no hay cortos entre pines y todos los pines tienen continuidad entre el PIC y el LIS331, y tampoco creo que se haya quemado porque esta soldado en horno.

Me he pedido a Amidata una plaquita de evaluación de ST que lleva soldado este chip con un formato DIP para pincharle con cables directamente, para descartar que el problema esté en el chip, si es así los chinos me la han vuelto a colar (en principio es lo que sospecho).

Este es el código que he creado en C18, a mi me parece que está todo bien, y con las señales del analizador lógico se ve que SPI funciona. Y los comandos a enviar son los que aparecen en el datasheet.

El syncmode lo he probado con FOSC64 y FOSC16, es decir para SPI a 1Mhz y 4Mhz, según el datasheet el chip puede ir hasta a 10 Mhz. El bus mode lo he probado con las cuatro opciones que hay, 00, 01, 10 y 11, y solo veo algún ligero cambio en SDO de LIS331, pero ningún dato de vuelta. He probado metiendo delays por aquí y por allá, y nada.






Configuración del LIS331

Código: C
  1. //***********************************************************************
  2. //*****   Configuro acelerometro  ***************************************
  3. //***********************************************************************
  4. void config_acelerometro(void)
  5. {
  6.    unsigned char sync_mode=0;
  7.    unsigned char bus_mode=0;
  8.    unsigned char smp_phase=0;
  9.    unsigned char w=0;
  10.    unsigned int whoami=0;
  11.  
  12.    CloseSPI(); // Cierro SPI si estaba previamente abierto
  13.  
  14. //--- Configuro SPI MASTER para transmitir en modo Master ---
  15.  //  sync_mode = SPI_FOSC_64 ;
  16.    sync_mode = SPI_FOSC_16 ;
  17.    bus_mode = MODE_10;
  18.    smp_phase = SMPMID;
  19.   // smp_phase = SMPEND;
  20.    OpenSPI(sync_mode,bus_mode,smp_phase );
  21.  
  22.    LATAbits.LATA5 = 0;  // Activo CS en RA5
  23. Delay10TCYx(1);
  24.    putcSPI(0x20); //write to 0x20
  25.    putcSPI(0x37); //normal mode, 400Hz, xyz-enabled
  26. Delay10TCYx(1);
  27.    LATAbits.LATA5 = 1;  // Apago CS en RA5
  28.        
  29.         Delay10TCYx(100);
  30.        
  31.    LATAbits.LATA5 = 0;  // Activo CS en RA5
  32. Delay10TCYx(1);
  33.    putcSPI(0x21); //write to 0x21
  34.    putcSPI(0x00); //HP filter ON (cuttoff@8MHz) = 0x60, HPfilter OFF = 0x00
  35. Delay10TCYx(1);
  36.    LATAbits.LATA5 = 1;  // Apago CS en RA5
  37.        
  38.         Delay10TCYx(100);
  39.        
  40.    LATAbits.LATA5 = 0;  // Activo CS en RA5
  41. Delay10TCYx(1);
  42.         putcSPI(0x23); //write to 0x23
  43.         putcSPI(0x30); //24g
  44. Delay10TCYx(1);
  45.    LATAbits.LATA5 = 1;  // Apago CS en RA5
  46.  
  47.    CloseSPI(); // Cierro SPI si estaba previamente abierto
  48.  
  49. }
  50.  
  51.  


Chequeo acelerómetro con el comando 0x0F que devuelve el identificador del chip (32). En cualquier caso nunca devuelve nada con todos los comandos que he probado, y como se ve en el analizador, SDO del LIS331 permanece siempre en estado lógico alto (0xFF)

Código: C
  1. //***********************************************************************
  2. //*****   Chequeo acelerometro  ***********************************
  3. //
  4. //  SPI_FOSC_16:        Master clock rate is Fosc/16
  5. // SPI_FOSC_64:        Master clock rate is Fosc/64
  6. // SPI_FOSC_TMR2:   Master clock rate is TMR2 output/2
  7. // SLV_SSON (used if device is a slave): SPI Slave mode, /SS pin control enabled
  8. // SLV_SSOFF (used in slave mode only): SPI Slave mode, /SS pin control disabled
  9. // Example: If the required data rate of SPI bus communication has to be at least 1 Mbps, assume that the microcontroller oscillator clock rate is 16 MHz, set the synch-mode: SPI_FOSC_16 (16/16) = 1 Mbps.
  10. // bus_mode: This second parameter specifies the clock edge:
  11. // MODE_00:    Clock is idle low, transmit on rising edge
  12. // MODE_01:    Clock is idle low, transmit on falling edge
  13. // MODE_10:    Clock is idle high, transmit on falling edge
  14. // MODE_11:    Clock is idle high, transmit on rising edge
  15. // smp_phase: This is the input data sampling time:
  16. // SMPEND:    Input data sample at the end of data out
  17. // SMPMID:    Input data sample at middle of data out
  18. // Example Code for master: OpenSPI(SPI_FOSC_16, MODE_00, SMPEND);
  19. // Example Code for slave:    OpenSPI(SLV_SSON, MODE_00, SMPEND);
  20. //
  21. // WriteSPI: This function writes a single byte to the SPI bus and it is the same as the putcSPI.
  22. // Example code: WriteSPI('x');   //Send letter "c" to SPI bus.
  23. // ReadSPI: This function reads a single byte from the SPI bus and it is the same as getcSPI.
  24. // Example code: char data;
  25. // data = ReadSPI();
  26. // putsSPI: This function writes a string to the SPI bus.
  27. // Example code: unsigned char data[] = "Hello World";
  28. // putsSPI(test);
  29. // getsSPI: This function reads a string from the SPI bus. The number of characters to read must be specified in the function argument.
  30. // Example code: getsSPI(data, 10);
  31. // DataRdySPI: This function determines whether the SPI buffer contains data. 0 is returned if there is no data in the SSPBUF register, and 1 is returned if new data is available in the SSPBUF register.
  32. // Example code: While (DataRdySPI());
  33. // This function disables the SPI module.
  34. // Example code: closeSPI();
  35. //***********************************************************************
  36. void chequeo_acelerometro(void)
  37. {
  38.    unsigned char sync_mode=0;
  39.    unsigned char bus_mode=0;
  40.    unsigned char smp_phase=0;
  41.    unsigned char whoami="";
  42.  
  43.    CloseSPI(); // Cierro SPI si estaba previamente abierto
  44.  
  45. //--- Configuro SPI MASTER para transmitir en modo Master ---
  46.     sync_mode = SPI_FOSC_16 ;
  47.   // sync_mode = SPI_FOSC_64 ;
  48.     bus_mode = MODE_10;
  49.    // bus_mode = MODE_10;
  50.     smp_phase = SMPMID;
  51.    // smp_phase = SMPEND;
  52.    OpenSPI(sync_mode,bus_mode,smp_phase );
  53.  
  54.    // Leo registro 0F, que me debe de devolver 32 en hexadecimal, o 50 en decimal, o 00110010 en binario
  55.    Delay10TCYx(100);
  56.    LATAbits.LATA5 = 0;  // Activo CS en RA5
  57.    Delay10TCYx(1);
  58.  
  59.  WriteSPI(0x0F);
  60.  // WriteSPI(0x00);
  61.  while (!DataRdySPI());
  62.  whoami = ReadSPI();
  63.  
  64.   Delay10TCYx(1);
  65.   LATAbits.LATA5 = 1;   // Apago CS en RA5
  66.   // CloseSPI(); // Cierro SPI si estaba previamente abierto
  67. }
  68. //************************************************************************
  69. //************************************************************************
  70. //************************************************************************
  71.  
  72.  



« Última modificación: 02 de Mayo de 2016, 12:04:02 por planeta9999 »

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2174
Re:Acelerometro LIS331DL por SPI
« Respuesta #1 en: 02 de Mayo de 2016, 14:23:11 »
De donde has sacado que 0x0F es el identificador del acelerometro?
En la hoja de datos el rango 0 - 1F esta marcado como reservado.

-
Leonardo Garberoglio

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2174
Re:Acelerometro LIS331DL por SPI
« Respuesta #2 en: 02 de Mayo de 2016, 14:28:16 »
En tu ejemplo del analizador lógico el B0 (R/W) está en 0, entonces el LIS esta esperando la direccion y luego el dato a escrivir. Si quieres leer, el B0 debe estar en 1. O sea que en lo 8 bits de la direccion, el MSB debe estar en 1 (0x80 | REG_ADDRESS), luego los el siguiente bit es el de autoincremento de direccion y luego 6 bits de direccion de registro. Enviado eso como primer byte, luego el LIS responderá un byte con el contenido del registro
-
Leonardo Garberoglio

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3452
    • Pinballsp
Re:Acelerometro LIS331DL por SPI
« Respuesta #3 en: 02 de Mayo de 2016, 17:19:52 »
De donde has sacado que 0x0F es el identificador del acelerometro?
En la hoja de datos el rango 0 - 1F esta marcado como reservado.


Está en el datasheet, es la versión DL del LI331 (LIS331DL), hay otras versiones, una analógica y otras digitales con otro juego de registros. Yo pedí a los chinos el LIS331 DLTR, y en el encapsulado lleva impreso 33DL.

https://ptelectronics.ru/wp-content/uploads/STMicroelectronics_LIS331DL_MEMS_motion-sensor.pdf





Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3452
    • Pinballsp
Re:Acelerometro LIS331DL por SPI
« Respuesta #4 en: 02 de Mayo de 2016, 17:27:43 »
En tu ejemplo del analizador lógico el B0 (R/W) está en 0, entonces el LIS esta esperando la direccion y luego el dato a escrivir. Si quieres leer, el B0 debe estar en 1. O sea que en lo 8 bits de la direccion, el MSB debe estar en 1 (0x80 | REG_ADDRESS), luego los el siguiente bit es el de autoincremento de direccion y luego 6 bits de direccion de registro. Enviado eso como primer byte, luego el LIS responderá un byte con el contenido del registro

No se a que te refieres con B0, el Chip select debe de estar siempre a nivel lógico bajo para que el chip sea accesible por SPI, de lo contrario trabaja en I2C.

Creo que  te estás refiriendo a I2C, que no es mi caso, no hay dirección en SPI, solo datos de entrada/salida por SDI/SDO sincronizadas por la señal de reloj, y el chip select para abilitar el chip.

En la captura que he puesto, en D11 está la salida SDO del PIC, que envía los datos al LIS, esos ocho bits sincronizados con el tren de pulsos del oscilador deben de corresponderse el byte que estoy enviando. En esa prueba no se si le enviaba el 0x0F o estaba probando con otros, pero en binario debe de corresponderse con el hexadecimal que puse en el programa. Le envío el byte del registro y leo esperando que el LIS me responda con su contenido, si es un registro RW puedo enviar un segundo byte para pasarle el dato a grabar, o eso es lo que he entenido que hay que hacer. Tambien he mirado un fuente que hay en Sparkfun con el LIS331 para Arduino, y más o menos hace lo mismo.

No se, igual el chip es una versión distinta con otro juego de registros, pero por la foto que he puesto creo que es el LIS331DL o DLTR, que se corresponde con el datasheet que he colgado. Pasado mañana recibiré la placa de evaluación de ST y saldré de dudas.


Este es el fuente de ejemplo que dan en Sparkfun para usar el LIS331 con Arduino. La parte de código con los registros que usan para la configuración, la he cogido de ahí adecuando las instrucciones de SPI en el PIC. Lo que no entiendo es la rutina de lectura porque le meten un segundo byte a 0x00, probé a hacer algo así pero tampoco me funcionó.

Código: C
  1. /*
  2.     3-21-11
  3.     Aaron Weiss, aaron at sparkfun dot com
  4.        
  5.         License: Creative Commons Attribution Share-Alike 3.0
  6.         http://creativecommons.org/licenses/by-sa/3.0
  7.        
  8.         v10 Example
  9.         -outputs x,y,z acceleration values every 1 ms
  10.         -output is driven by a timer overflow interrupt, this allows the user to
  11.          more easily add additional code without messing with the timing
  12.         -values are in g's
  13.        
  14.         LIS331 Accelerometer Configuration:
  15.         4-wire SPI, normal mode, 400Hz
  16.        
  17.         Hardware:
  18.         Atmega328p, 3.3V, ext. 8MHz, 38400 baud
  19.        
  20.         Hardware Conections (LIS to Arduino):
  21.        
  22.         LIS331   |   Arduino
  23.         ---------------------
  24.           VCC    |    VCC (3.3V)
  25.           CS     |    pin 10 (PB2)
  26.           SCL    |    pin 13 (PB5)
  27.           SA0    |    pin 12 (PB4)
  28.           SDA    |    pin 11 (PB3)
  29.           GND    |    pin GND
  30.        
  31.         Note: if you need a higher sampling frequency, you need to run a higher clock,
  32.                   INT functionality not used
  33. */
  34.  
  35. #include <stdlib.h>
  36. #include <stdio.h>
  37. #include <avr/io.h>
  38. #include <avr/pgmspace.h>
  39. #include <avr/interrupt.h>
  40.  
  41. #define MYUBRR 12  //8MHz, 38400bps
  42.  
  43. #define sbi(var, mask)   ((var) |= (uint8_t)(1 << mask))
  44. #define cbi(var, mask)   ((var) &= (uint8_t)~(1 << mask))
  45.  
  46. #define MOSI    3  //PORTB
  47. #define MISO    4  //PORTB
  48. #define SCK     5  //PORTB
  49. #define CS              2  //PORTB
  50.  
  51. #define SCALE 0.0007324  //sets g-level (48 fullscale range)/(2^16bits) = SCALE
  52.  
  53. ///============Initialize Prototypes=====================///////////////////////
  54. void ioinit(void);      // initializes IO
  55. void UART_Init(unsigned int ubrr);
  56. static int uart_putchar(char c, FILE *stream);
  57. uint8_t uart_getchar(void);
  58. static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE);
  59. void delay(uint16_t x); // general purpose delay
  60.  
  61. /////======SPI functions=================================////////////////////////
  62. void SPI_MasterInit(void);
  63. void SPI_MasterTransmit(uint8_t address);
  64.  
  65. /////======Main Prototypes================================////////////////////////
  66. void config(void);
  67. uint8_t read(uint8_t addr);
  68. void accel(void);
  69.  
  70. ///===========Global Vars=============================//////////////////////////
  71. volatile double xaccel, yaccel, zaccel;
  72.  
  73. //=========MAIN================/////////////////////////////////////////////////
  74. ISR(TIMER1_OVF_vect)
  75. {
  76.         //every ms the acceleration values are printed
  77.         TCNT1 = 55536;//(8/8MHz)*(65536bits-55536)=0.01s
  78.         accel(); //update LIS registers
  79.         printf("x=%6.2f,", xaccel);
  80.         printf("y=%6.2f,", yaccel);
  81.         printf("z=%6.2f\n\r", zaccel);
  82. }
  83.  
  84. int main(void)
  85. {      
  86.         ioinit(); //Setup IO pins and defaults
  87.         SPI_MasterInit();
  88.         config();
  89.        
  90.         while(1)
  91.         {      
  92.                 //put your code here
  93.         }
  94.         return (0);
  95. }
  96.  
  97. void config(void)
  98. {
  99.         cbi(PORTB, CS);
  100.         delay(1);
  101.         SPI_MasterTransmit(0x20); //write to 0x20
  102.         SPI_MasterTransmit(0x37); //normal mode, 400Hz, xyz-enabled
  103.         delay(1);
  104.         sbi(PORTB, CS);
  105.        
  106.         delay(100);
  107.        
  108.         cbi(PORTB, CS);
  109.         delay(1);
  110.         SPI_MasterTransmit(0x21); //write to 0x21
  111.         SPI_MasterTransmit(0x00); //HP filter ON (cuttoff@8MHz) = 0x60, HPfilter OFF = 0x00
  112.         delay(1);
  113.         sbi(PORTB, CS);
  114.        
  115.         delay(100);
  116.        
  117.         cbi(PORTB, CS);
  118.         delay(1);
  119.         SPI_MasterTransmit(0x23); //write to 0x23
  120.         SPI_MasterTransmit(0x30); //24g
  121.         delay(1);
  122.         sbi(PORTB, CS);
  123. }
  124.  
  125. //usage: read('hex address'), e.g. read(0x20), reads CTRL_REG1
  126. //returns the value in the address, e.g. read(0x20) = 0x07, returns the default value of 0x20
  127. uint8_t read(uint8_t addr)
  128. {
  129.         uint8_t regbyte;
  130.         uint8_t read = 0;
  131.         read |= (1<<7);
  132.         uint8_t byte = 0;
  133.         byte = read | addr;
  134.        
  135.         cbi(PORTB, CS);
  136.         delay(1);
  137.         SPI_MasterTransmit(byte);
  138.         SPI_MasterTransmit(0x00); //must keep clock moving, so tx another byte
  139.         regbyte = SPDR;
  140.         delay(1);
  141.         sbi(PORTB, CS);
  142.        
  143.         return(regbyte);
  144. }
  145.  
  146. void accel(void)
  147. {      
  148.         uint16_t xl, xh, yl, yh, zl, zh;
  149.         int16_t tempx, tempy, tempz;
  150.        
  151.         cbi(PORTB, CS);
  152.         SPI_MasterTransmit(0xe8); //read bit | consecutive measure bit | 0x28 = 0xe8
  153.         SPI_MasterTransmit(0x00); //must keep clock moving, so tx another byte
  154.         xl = SPDR;
  155.         SPI_MasterTransmit(0x00); //must keep clock moving, so tx another byte
  156.         xh = SPDR;
  157.         SPI_MasterTransmit(0x00); //must keep clock moving, so tx another byte
  158.         yl = SPDR;
  159.         SPI_MasterTransmit(0x00); //must keep clock moving, so tx another byte
  160.         yh = SPDR;
  161.         SPI_MasterTransmit(0x00); //must keep clock moving, so tx another byte
  162.         zl = SPDR;
  163.         SPI_MasterTransmit(0x00); //must keep clock moving, so tx another byte
  164.         zh = SPDR;
  165.         sbi(PORTB, CS);
  166.        
  167.         tempx = (xl|(xh << 8)); //concatenate low and high bits together, load into signed 16 bit
  168.         xaccel = SCALE*tempx;    //multiply by scale factor for g-level
  169.         tempy = (yl|(yh << 8));
  170.         yaccel = SCALE*tempy;
  171.         tempz = (zl|(zh << 8));
  172.         zaccel = SCALE*tempz;
  173. }
  174. ////////////////////////////////////////////////////////////////////////////////
  175. ///==============Initializations=======================================/////////
  176. ////////////////////////////////////////////////////////////////////////////////
  177. void ioinit (void)
  178. {
  179.     //1 = output, 0 = input
  180.     DDRB = 0b11101111; //input on PB4 = MISO
  181.     DDRD = 0b11110010; //PORTD (RX on PD0)
  182.        
  183.         sbi(PORTB, CS);
  184.     UART_Init(MYUBRR);
  185.        
  186.         // Setting Timer 1
  187.         // normal mode
  188.         TCCR1A = 0x00;
  189.         // Set to clk/8
  190.         TCCR1B |= (1<<CS11);
  191.         //enable overflow interrupt
  192.         TIMSK1 |= (1<<TOIE1);
  193.         //load timer with a value to optimize for 1 second,
  194.         TCNT1 = 55536;  //(8/8MHz)*(65536bits-55536)=0.01s
  195.        
  196.         sei(); //turn on global interrupts and enable timer
  197. }
  198.  
  199. void UART_Init(unsigned int ubrr)
  200. {
  201.         int ubrr_new;
  202.         // set baud rate
  203.         ubrr_new = ubrr;
  204.         UBRR0H = ubrr_new>>8;
  205.         UBRR0L = ubrr_new;
  206.  
  207.         // Enable receiver and transmitter
  208.         UCSR0A = (0<<U2X0); //double UART speed
  209.         UCSR0B = (1<<RXEN0)|(1<<TXEN0);
  210.  
  211.         // Set frame format: 8 bit, no parity, 1 stop bit,
  212.         UCSR0C = (1<<UCSZ00)|(1<<UCSZ01);
  213.  
  214.         stdout = &mystdout; //Required for printf init
  215. }
  216.  
  217. static int uart_putchar(char c, FILE *stream)
  218. {
  219.     if (c == '\n') uart_putchar('\r', stream);
  220.  
  221.     loop_until_bit_is_set(UCSR0A, UDRE0);
  222.     UDR0 = c;
  223.    
  224.     return 0;
  225. }
  226.  
  227. uint8_t uart_getchar(void)
  228. {
  229.     while( !(UCSR0A & (1<<RXC0)) );
  230.     return(UDR0);
  231. }
  232. //General short delays
  233. void delay(uint16_t x)
  234. {
  235.   uint8_t y;
  236.   for ( ; x > 100 ; x--){
  237.     for ( y = 0 ; y < 200 ; y++){
  238.     asm volatile ("nop");
  239.     }
  240.   }
  241. }
  242. //==========================//
  243. //
  244. //SPI functions
  245. //
  246. //==========================//
  247. void SPI_MasterInit(void)
  248. {
  249.         DDRB = (1<<DDB3)|(1<<DDB5)|(1<<DDB2)|(1<<DDB1);
  250.         SPCR = (1<<SPE)|(1<<MSTR)|(1<<CPOL)|(1<<CPHA);
  251. }
  252.  
  253. void SPI_MasterTransmit(uint8_t address)
  254. {
  255.         SPDR = address;
  256.         while(!(SPSR & (1<<SPIF)));
  257. }
  258.  
  259.  
« Última modificación: 02 de Mayo de 2016, 17:37:18 por planeta9999 »

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3452
    • Pinballsp
Re:Acelerometro LIS331DL por SPI
« Respuesta #5 en: 02 de Mayo de 2016, 17:43:45 »
.


Vale, a ver si me aclaro, igual te estás refiriendo a esto que aparece como rutina de lectura en el fuente de ejemplo de Sparkfun, parece que no envían el registro en hexadecimal directamente, sino que lo "preparan" previamente.

Ahi ya me pierdo un poco con lo que están haciendo para preparar el dato a enviarle al LIS. Osea que si quiero leer el registro 0x0F, no le envío por SPI 0x0F sino que hay que meterle todo este galimatías para preparar el dato a enviar. Y luego además metén otro byte a 0x00, no se para que.

En SPDR entiendo que está lo que devuelve el LIS331, pero eso es en un Arduino (supongo que un Atmel), me faltará saber sin con PIC es igual, o tengo que usar el ReadSPI.


//usage: read('hex address'), e.g. read(0x20), reads CTRL_REG1
//returns the value in the address, e.g. read(0x20) = 0x07, returns the default value of 0x20
uint8_t read(uint8_t addr)
{
        uint8_t regbyte;
        uint8_t read = 0;
        read |= (1<<7);
        uint8_t byte = 0;
        byte = read | addr;

       
        cbi(PORTB, CS);
        delay(1);
        SPI_MasterTransmit(byte);
        SPI_MasterTransmit(0x00); //must keep clock moving, so tx another byte
        regbyte = SPDR;
        delay(1);
        sbi(PORTB, CS);
       
        return(regbyte);
}




Por otra parte, para escribir en los registros RW, no veo que preparen el dato, lo envían tal cual, eso lo tengo igual en mi rutina de configuración:

void config(void)
{
   cbi(PORTB, CS);
   delay(1);
   SPI_MasterTransmit(0x20); //write to 0x20
   SPI_MasterTransmit(0x37); //normal mode, 400Hz, xyz-enabled

   delay(1);
   sbi(PORTB, CS);
   
   delay(100);
   
   cbi(PORTB, CS);
   delay(1);
   SPI_MasterTransmit(0x21); //write to 0x21
   SPI_MasterTransmit(0x00); //HP filter ON (cuttoff@8MHz) = 0x60, HPfilter OFF = 0x00

   delay(1);
   sbi(PORTB, CS);
   
   delay(100);
   
   cbi(PORTB, CS);
   delay(1);
   SPI_MasterTransmit(0x23); //write to 0x23
   SPI_MasterTransmit(0x30); //24g

   delay(1);
   sbi(PORTB, CS);
}
« Última modificación: 02 de Mayo de 2016, 17:55:10 por planeta9999 »

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2174
Re:Acelerometro LIS331DL por SPI
« Respuesta #6 en: 02 de Mayo de 2016, 18:03:57 »
Yo estaba viendo la hoja de datos de otro modelo.
Ahora viendo el tuyo aplica lo que te dije. No estaba mirando nada del i2c ni de spurkfun, solo la hoja de datos.
Si vos queres leer el registro 0x1F el primer spiWrite tiene que ser con 0x1F + 0x80, esto es para poner el en 1 el bit 0 que indica lectura de registro. Entonces, cuando pongas otro 8 pulsos de reloj en el bus (con un spi read) el sensor responderá con el dato.
En tu caso el b0 está en 0 y por eso esta en modo escritura y por eso el sensor no te responde nada.
Pagina 21 del datasheet:

bit 0: RW bit. When 0, the data DI(7:0) is written into the device. When 1, the data DO(7:0) from the device is read. In latter case, the chip will drive SDO at the start of bit 8.
bit 1: MS bit. When 0, the address will remain unchanged in multiple read/write commands. When 1, the address will be auto incremented in multiple read/write commands.
bit 2-7: address AD(5:0). This is the address field of the indexed register.

bit 8-15: data DI(7:0) (write mode). This is the data that will be written into the device (MSb
first).
bit 8-15: data DO(7:0) (read mode). This is the data that will be read from the device (MSb
first)


saludos!
-
Leonardo Garberoglio

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3452
    • Pinballsp
Re:Acelerometro LIS331DL por SPI
« Respuesta #7 en: 02 de Mayo de 2016, 18:08:48 »


Vale, ya lo entiendo, gracias elgarbe, voy a probar.

Me tenía que haber leido el datasheet detenidamente en vez de presuponer las cosas. Yo simplemente le enviaba por SPI el registro a leer (por ejemplo el 0x0F) y esperaba la respuesta del LIS, y claro así no responde nada.

Osea que para leer el registro 0x0F, tengo que enviar realmente 0x8F, y lo mismo con todos los registros que quiera leer, poner el primer bit a 1 en binario y pasarlo a hexadecimal.
« Última modificación: 02 de Mayo de 2016, 18:12:26 por planeta9999 »

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2174
Re:Acelerometro LIS331DL por SPI
« Respuesta #8 en: 02 de Mayo de 2016, 18:12:09 »
No hay porque!

Che, consulta, has hecho algo con el SIM900? necesito enviar un sms cada 1 minutos, algo bien simple y estoy buscando el hardware minimo del SIM900 en lo posible con antena impresa en el PCB... Recuerdo que estuviste trabajando pero creo que con el 908?

saludos
-
Leonardo Garberoglio

Desconectado planeta9999

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 3452
    • Pinballsp
Re:Acelerometro LIS331DL por SPI
« Respuesta #9 en: 02 de Mayo de 2016, 18:27:42 »
.

Si, pero ese proyecto al final no lo acabé, el "cliente" me dejó colgado y de esto ya va para cuatro meses.

En mi caso iba a utilizar la red GPRS con comandos AT para enviar datos a un servidor web, creo que con el SIM900 en principio y luego me pasé al SIM800L. Pero me quedé en el PCB, con un par de prototipos montados y probando el PI32 para meterle me booloader encriptado. Ya no hice más porque además el cliente me llamaba casi a diario para cambiarme cosas del diseño, y me hizo incluso prepararle una página web en 24 horas para hacer una demo a sus clientes. No llegué a programar nada para controlar el SIM.

Todo para nada, tiempo y dinero perdido, tengo algunos clientes interesados en aplicarlo en algunas máquinas en explotación para control de recaudaciones, igual un día de estos lo acabo.

De todos los SIM que miré el más interesante por precio y prestaciones era el SIM800L, lo tienes muy barato en los chinos, incluso te venden unas plaquitas listas para usar con una pequeña antena de alambre y el lector de tarjetas SIM, muy barato.

Aquí colgué este post con información bastante detallada:
http://www.todopic.com.ar/foros/index.php?topic=45496.0
« Última modificación: 02 de Mayo de 2016, 18:29:47 por planeta9999 »

Desconectado elgarbe

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2174
Re:Acelerometro LIS331DL por SPI
« Respuesta #10 en: 02 de Mayo de 2016, 18:49:03 »
excelente, eso es lo que buscaba!

gracias
-
Leonardo Garberoglio


 

anything