dsPIC33 SPI Tx como problemas del maestro

1

Estoy usando un dsPIC33 y solo quiero enviar datos SPI básicos. Sin Rx, solo Tx por ahora para controlar un digipot. El hardware incluye esclavo en el otro extremo, y estoy olfateando la salida con un analizador lógico. Acabo de ver, literalmente, 10 maneras diferentes de hacerlo, pero ninguna de ellas parece estar funcionando.

Problema: datos aleatorios que salen. De vez en cuando tiene sentido como un 3 o 7, pero por lo demás basura.

Tampoco estoy seguro de si está bien que la línea MOSI no siempre vuelva a un valor alto o bajo predeterminado. Por lo general, comienza alto, escribe datos, termina bajo, luego termina arriba en la siguiente ronda, lo que parece extraño.

Otro: cables cortos, ningún IC (potencialmente dañado) en el otro extremo, resistencia de pull-up de 10k en la línea de selección de chip (CS), la velocidad de transmisión más lenta posible (el valor predeterminado es el prescaler de spi y el postcaler), probado 8 y 16 en los modos de bits, probé todos los ajustes en el analizador lógico (primero MSb y primero LSb, etc.), los pines RPn no pueden ser analógicos por defecto, los pines RPn no son entrada RPn, ...

¿No es esto tan simple? ¿Qué podría faltar?

uint16_t main(void) {
  UC_ConfigureOscillator();
  TMRS_Init();
  SPI_Init(38, 39);

  // prime any timers that require it
  TMRS_Start(TX_TIMER, TX_PERIOD);
  volatile uint16_t val = 0;

  // watch the data being transmitted with a logic analyzer
  while (1) {
    // periodically transmit a message
    if (TMRS_Expired(TX_TIMER)) {
      TMRS_Start(TX_TIMER, TX_PERIOD);
      SPI_SendWord(val);
      if (++val > 10) val = 0;
      }
   }

   return 0;
}

void SPI_Init(uint8_t sdo_pin, uint8_t sck_pin) {
  // Configure and initialize the chip-select pin
  _TRISB8 = 0;
  _LATB8 = 1;

  // Configure the SPI clock and MOSI pins
  __builtin_write_OSCCONL(OSCCON & 0xBF);
  _RP39R = 0b001001;
  _RP38R = 0b001000;

  // Configure the interrupt
  _SPI2IE = 0;              // Disable the interrupt
  _SPI2IF = 0;              // Clear the interrupt flag

  _SPI2IE = 1;              // Enable interrupts for this spi module
  _SPI2IP = 2;              // Assign the interrupt priority

  SPI2CON1bits.MODE16 = 1;  // Use in 16-bit mode
  SPI2CON1bits.MSTEN = 1;   // Configure this device as master
  SPI2STATbits.SPIROV = 0;  // Ensure the receive overflow flag begins cleared
  SPI2STATbits.SPIEN = 1;   // Enable the SPI module
  SPI2CON1bits.SMP = 1;     // Sample input data at END of data output time
}

void SPI_SendWord(uint16_t word) {
  uint16_t garbage;

  // lower CS
  _LATB8 = 0;

  // write the given word to the Tx/Rx buffer
  SPI2BUF = word;

  // wait for the transmit buffer to clear
  while (SPI2STATbits.SPITBF == 0);
  // wait for the transmit to begin
  while (SPI2STATbits.SPITBF == 1);

  // Dummy-read the SPIxBUF register to clear flag???
  garbage = SPI2BUF;
}

// Called on 16bits finished shifting in OR out of SPI2 buffer
void __attribute__((__interrupt__, auto_psv)) _SPI2Interrupt(void) {
  // Return CS high
  _LATB8 = 1;

  // Clear the source of the interrupt
  _SPI2IF = 0;
}
    
pregunta tarabyte

1 respuesta

0

Wow, la nueva herramienta no se configuró correctamente. Me encantan estos muchachos enlace , pero no me di cuenta de que mi configuración debería haber sido "Los datos son válidos en el límite del reloj" y no reloj de vanguardia. Configuraciones guardadas ahora.

    
respondido por el tarabyte

Lea otras preguntas en las etiquetas