NSS pin sube inmediatamente

3

Estoy trabajando en un proyecto simple con stm32f0. el proyecto es cuando presiono el botón en la placa, el SPI1 de la MCU debe enviar los datos. Todas las cosas funcionan bien pero hay un problema. mira la rutina de interrupción EXTI:

void EXTI0_1_IRQHandler(void)
{
  HAL_NVIC_ClearPendingIRQ(EXTI0_1_IRQn);
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  HAL_GPIO_WritePin( GPIOA , GPIO_PIN_4 , GPIO_PIN_RESET );
  HAL_SPI_Transmit_IT( &hspi1 , (uint8_t*)aTxBuffer , 9 );
  HAL_GPIO_WritePin( GPIOA , GPIO_PIN_4 , GPIO_PIN_SET );
}

dos funciones manejan la interrupción EXTI y luego las ignoran. La tercera función es este HAL_GPIO_WritePin( GPIOA , GPIO_PIN_4 , GPIO_PIN_RESET ); que restablece el pin GPIOA4. Después de esto, tenemos que enviar los datos. ok, entonces usamos esta función HAL_SPI_Transmit_IT( &hspi1 , (uint8_t*)aTxBuffer , 9 ); y para terminar tenemos que configurar el pin nuevamente. Entonces uso esta función HAL_GPIO_WritePin( GPIOA , GPIO_PIN_4 , GPIO_PIN_SET ); . Bien, ahora veamos el resultado.

oh! ¿puedes ver? ¡El pin NSS se apaga inmediatamente! ¿Por qué?

la función HAL_GPIO_WritePin :

/**
  * @brief  Sets or clears the selected data port bit.
  * 
  * @note   This function uses GPIOx_BSRR register to allow atomic read/modify 
  *         accesses. In this way, there is no risk of an IRQ occurring between
  *         the read and the modify access.
  *               
  * @param  GPIOx: where x can be (A..F) to select the GPIO peripheral for STM32F0 family
  * @note   GPIOE is available only for STM32F072.
  * @note   GPIOD is not available for STM32F031.  
  *         For STM32F051 and STM32F030: (0..15) for GPIOA, GPIOB, GPIOC, (2) for GPIOD and (0..1, 4..7) for GPIOF.
  *         For STM32F072: (0..15) for GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, (0..10) for GPIOF.
  *         For STM32F031: (0..15) for GPIOA, GPIOB, (13..15) for GPIOC and (0..1, 6..7) for GPIOF.  
  * @param  GPIO_Pin: specifies the port bit to be written.
  *          This parameter can be one of GPIO_PIN_x where x can be (0..15).
  * @param  PinState: specifies the value to be written to the selected bit.
  *          This parameter can be one of the GPIO_PinState enum values:
  *            @arg GPIO_BIT_RESET: to clear the port pin
  *            @arg GPIO_BIT_SET: to set the port pin
  * @retval None
  */
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
{
  /* Check the parameters */
  assert_param(IS_GPIO_PIN(GPIO_Pin));
  assert_param(IS_GPIO_PIN_ACTION(PinState));

  if (PinState != GPIO_PIN_RESET)
  {
    GPIOx->BSRRL = GPIO_Pin;
  }
  else
  {
    GPIOx->BSRRH = GPIO_Pin ;
  }
}

la función HAL_SPI_Transmit_IT :

/**
  * @brief  Transmit an amount of data in no-blocking mode with Interrupt
  * @param  hspi: SPI handle
  * @param  pData: pointer to data buffer
  * @param  Size: amount of data to be sent
  * @retval HAL status
  */
HAL_StatusTypeDef HAL_SPI_Transmit_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size)
{
  assert_param(IS_SPI_DIRECTION_2LINES_OR_1LINE(hspi->Init.Direction));

  if(hspi->State == HAL_SPI_STATE_READY)
  {
    if((pData == NULL) || (Size == 0)) 
    {
      return  HAL_ERROR;                                    
    }

    /* Process Locked */
    __HAL_LOCK(hspi);

    hspi->State       = HAL_SPI_STATE_BUSY_TX;
    hspi->ErrorCode   = HAL_SPI_ERROR_NONE;
    hspi->pTxBuffPtr  = pData;
    hspi->TxXferSize  = Size;
    hspi->TxXferCount = Size;
    hspi->pRxBuffPtr  = NULL;
    hspi->RxXferSize  = 0;
    hspi->RxXferCount = 0;

    /* Set the function for IT treatement */
    if(hspi->Init.DataSize > SPI_DATASIZE_8BIT )
    {
      hspi->RxISR = NULL;
      hspi->TxISR = SPI_TxISR_16BIT;
    }
    else
    {
      hspi->RxISR = NULL;
      hspi->TxISR = SPI_TxISR_8BIT;
    }

    /* Configure communication direction : 1Line */
    if(hspi->Init.Direction == SPI_DIRECTION_1LINE)
    {
      __HAL_SPI_1LINE_TX(hspi);
    }

    /* Reset CRC Calculation */
    if(hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLED)
    {
      __HAL_SPI_RESET_CRC(hspi);    
    }

    /* Enable TXE and ERR interrupt */
    __HAL_SPI_ENABLE_IT(hspi,(SPI_IT_TXE));

    /* Process Unlocked */
    __HAL_UNLOCK(hspi);

    /* Note : The SPI must be enabled after unlocking current process 
              to avoid the risk of SPI interrupt handle execution before current
              process unlock */

    /* Check if the SPI is already enabled */ 
    if((hspi->Instance->CR1 &SPI_CR1_SPE) != SPI_CR1_SPE)
    {
      /* Enable SPI peripheral */    
      __HAL_SPI_ENABLE(hspi);
    }

    return HAL_OK;
  }
  else
  {
    return HAL_BUSY;
  }
}

esta es la configuración para GPIOA4:

/*Configure GPIO pin : PA4 */
  GPIO_InitStruct.Pin = GPIO_PIN_4;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
pregunta Roh

2 respuestas

2

HAL_SPI_Transmit_IT no envía ningún dato. Simplemente invoca __HAL_SPI_ENABLE que se ejecuta después de que se realiza el ISR.

    
respondido por el venny
1

Debido a que su rutina HAL_SPI_Transmit_IT () no es de bloqueo, tendrá que probar su finalización antes de ejecutar HAL_GPIO_WritePin (GPIOA, GPIO_PIN_4, GPIO_PIN_SET);

Lo más probable es que el lugar para hacer esto sea al final de la rutina de servicio de interrupción de hspi Tx.

    
respondido por el Tut

Lea otras preguntas en las etiquetas