你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

请问一下STM32F103C8T6的Hardwar NSS Output ENABLE后cs持续拉低是为什么

[复制链接]
Legend-奇君 提问时间:2026-5-8 11:07 / 未解决

我不太清楚为什么Hardwar NSS为什么不能在发送完以后自动拉高,我尝试过通过在HAL_SPI_Transmit_DMA函数前后添加开关nss或者开关spi的指令,但是这种做法会使得spi无法启动,如果不添加将会让cs信号持续低电平,下面是我的控制代码和spi配置代码。

/ USER CODE BEGIN Header /

/**


  • @file dma.c

  • @brief This file provides code for the configuration

  • of all the requested memory to memory DMA transfers.

  • @attention

  • Copyright (c) 2026 STMicroelectronics.

  • All rights reserved.

  • This software is licensed under terms that can be found in the LICENSE file

  • in the root directory of this software component.

  • If no LICENSE file comes with this software, it is provided AS-IS.


*/

/ USER CODE END Header /

/ Includes ------------------------------------------------------------------/

include "dma.h"

/ USER CODE BEGIN 0 /

/ USER CODE END 0 /

/----------------------------------------------------------------------------/

/ Configure DMA /

/----------------------------------------------------------------------------/

/ USER CODE BEGIN 1 /

/ USER CODE END 1 /

/**

  • Enable DMA controller clock

*/

void MX_DMA_Init(void)

{

/ DMA controller clock enable /

__HAL_RCC_DMA1_CLK_ENABLE();

/ DMA interrupt init /

/ DMA1_Channel3_IRQn interrupt configuration /

HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);

}

/ USER CODE BEGIN 2 /

static uint8_t dac_tx_buf[3];

uint8_t wTransferState = TRANSFER_COMPLETE;

uint8_t i=0;

uint16_t val;

void DAC_WriteA_DMA(uint16_t data)

{

while(wTransferState == TRANSFER_WAIT);

dac_tx_buf[0] = DAC_CH_A;

dac_tx_buf[1] = (data >> 8) & 0xFF;

dac_tx_buf[2] = data & 0xFF;

wTransferState = TRANSFER_WAIT;

HAL_SPI_Transmit_DMA(&hspi1, dac_tx_buf, 3); }

void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)

{

if(hspi == &hspi1)

{

wTransferState = TRANSFER_COMPLETE;

} }

void DAC_GenSawtooth_2P2KHz(void)

{

static uint16_t dac_val = 0;

DAC_WriteA_DMA(dac_val);

dac_val += 384;

if(dac_val >= MAX_DAC_VALUE)

{

dac_val = 0;

} }

/ USER CODE END 2 /

/ USER CODE BEGIN Header /

/**


  • @file spi.c

  • @brief This file provides code for the configuration

  • of the SPI instances.

  • @attention

  • Copyright (c) 2026 STMicroelectronics.

  • All rights reserved.

  • This software is licensed under terms that can be found in the LICENSE file

  • in the root directory of this software component.

  • If no LICENSE file comes with this software, it is provided AS-IS.


*/

/ USER CODE END Header /

/ Includes ------------------------------------------------------------------/

include "spi.h"

/ USER CODE BEGIN 0 /

/ USER CODE END 0 /

SPI_HandleTypeDef hspi1;

DMA_HandleTypeDef hdma_spi1_tx;

/ SPI1 init function /

void MX_SPI1_Init(void)

{

/ USER CODE BEGIN SPI1_Init 0 /

/ USER CODE END SPI1_Init 0 /

/ USER CODE BEGIN SPI1_Init 1 /

/ USER CODE END SPI1_Init 1 /

hspi1.Instance = SPI1;

hspi1.Init.Mode = SPI_MODE_MASTER;

hspi1.Init.Direction = SPI_DIRECTION_2LINES;

hspi1.Init.DataSize = SPI_DATASIZE_8BIT;

hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;

hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;

hspi1.Init.NSS = SPI_NSS_HARD_OUTPUT;

hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16;

hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;

hspi1.Init.TIMode = SPI_TIMODE_DISABLE;

hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

hspi1.Init.CRCPolynomial = 10;

if (HAL_SPI_Init(&hspi1) != HAL_OK)

{

Error_Handler(); }

/ USER CODE BEGIN SPI1_Init 2 /

/ USER CODE END SPI1_Init 2 /

}

void HAL_SPI_MspInit(SPI_HandleTypeDef* spiHandle)

{

GPIO_InitTypeDef GPIO_InitStruct = {0};

if(spiHandle->Instance==SPI1)

{

/ USER CODE BEGIN SPI1_MspInit 0 /

/ USER CODE END SPI1_MspInit 0 /

/ SPI1 clock enable /

__HAL_RCC_SPI1_CLK_ENABLE();

__HAL_RCC_GPIOA_CLK_ENABLE();

/**SPI1 GPIO Configuration

PA4 ------> SPI1_NSS

PA5 ------> SPI1_SCK

PA7 ------> SPI1_MOSI

*/

GPIO_InitStruct.Pin = GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7;

GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;

GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;

HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

/ SPI1 DMA Init /

/ SPI1_TX Init /

hdma_spi1_tx.Instance = DMA1_Channel3;

hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;

hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;

hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;

hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;

hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;

hdma_spi1_tx.Init.Mode = DMA_NORMAL;

hdma_spi1_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;

if (HAL_DMA_Init(&hdma_spi1_tx) != HAL_OK)

{

Error_Handler();

}

__HAL_LINKDMA(spiHandle,hdmatx,hdma_spi1_tx);

/ SPI1 interrupt Init /

HAL_NVIC_SetPriority(SPI1_IRQn, 0, 0);

HAL_NVIC_EnableIRQ(SPI1_IRQn); / USER CODE BEGIN SPI1_MspInit 1 /

/ USER CODE END SPI1_MspInit 1 /

}

}

void HAL_SPI_MspDeInit(SPI_HandleTypeDef* spiHandle)

{

if(spiHandle->Instance==SPI1)

{

/ USER CODE BEGIN SPI1_MspDeInit 0 /

/ USER CODE END SPI1_MspDeInit 0 /

/ Peripheral clock disable /

__HAL_RCC_SPI1_CLK_DISABLE();

/**SPI1 GPIO Configuration

PA4 ------> SPI1_NSS

PA5 ------> SPI1_SCK

PA7 ------> SPI1_MOSI

*/

HAL_GPIO_DeInit(GPIOA, GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7);

/ SPI1 DMA DeInit /

HAL_DMA_DeInit(spiHandle->hdmatx);

/ SPI1 interrupt Deinit /

HAL_NVIC_DisableIRQ(SPI1_IRQn); / USER CODE BEGIN SPI1_MspDeInit 1 /

/ USER CODE END SPI1_MspDeInit 1 /

}

}

/ USER CODE BEGIN 1 /

/ USER CODE END 1 /

收藏 评论2 发布时间:2026-5-8 11:07

举报

2个回答
butterflyspring 回答时间:5 天前
试了一下,禁止SPI工作,似乎也没有拉高。
不过这个手册上也说了,不会自动拉高的。
从应用上讲,控制从设备想拉高的话,开始通过IO口比较灵活,在开始时拉低,在完成的回调里拉高。
xmshao 回答时间:4 天前

估计stm32早期的32F系列这个地方都有这个缺陷,后来新推出的STM32G/H/U等系列的SPI都支持NSSP模式,即发完一串数据后可以自动拉高,不要再手动去拉高。

我们做选型时尽量选择新推出的系列,其实性价比更高。

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版