我想用单片机读取ADS8695芯片的ADC值,单片机作为主机,ADC作为从机。SPI的CS端用TIM1的PWM替代,同时利用TIM1的UP事件,触发一次SPI发送,我的数据是32位的,通过UP事件触发的SPI发送只发送8位,导致SPI接收到的只有8位,请问该怎么解决呢?如何让UP事件触发的SPI发送能发送32位的数据呢。谢谢 |
你如果想发送32位,每次更新事件后,你可以连续发送4个字节数据。另外,F407SPI支持16位数据模式,每次更新事件发2个半字数据也可以的。其中SPI的发送,基于查询或者中断方式还是DMA方式都可以。
你如果想发送32位,每次更新事件后,你可以连续发送4个字节数据。另外,F407SPI支持16位数据模式,每次更新 ...
if(tim_baseHandle->Instance==TIM1) { /* USER CODE BEGIN TIM1_MspInit 0 */ /* USER CODE END TIM1_MspInit 0 */ /* TIM1 clock enable */ __HAL_RCC_TIM1_CLK_ENABLE(); /* TIM1 DMA Init */ /* TIM1_UP Init */ hdma_tim1_up.Instance = DMA2_Stream5; hdma_tim1_up.Init.Channel = DMA_CHANNEL_6; hdma_tim1_up.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_tim1_up.Init.PeriphInc = DMA_PINC_ENABLE; hdma_tim1_up.Init.MemInc = DMA_MINC_DISABLE; hdma_tim1_up.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_tim1_up.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_tim1_up.Init.Mode = DMA_CIRCULAR; hdma_tim1_up.Init.Priority = DMA_PRIORITY_LOW; hdma_tim1_up.Init.FIFOMode = DMA_FIFOMODE_DISABLE; if (HAL_DMA_Init(&hdma_tim1_up) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(tim_baseHandle,hdma[TIM_DMA_ID_UPDATE],hdma_tim1_up); /* USER CODE BEGIN TIM1_MspInit 1 */ __HAL_TIM_CLEAR_IT(&htim1,TIM_IT_UPDATE); //HAL_NVIC_EnableIRQ(DMA2_Stream5_IRQn);//打开DMA中断 HAL_DMA_Start(&hdma_tim1_up,(uint32_t)arry_spi_tx, (uint32_t)&SPI1->DR,D_ADS8695_LENGTH); __HAL_TIM_ENABLE_DMA(&htim1,TIM_DMA_UPDATE); __HAL_TIM_ENABLE(&htim1); HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_1); /* USER CODE END TIM1_MspInit 1 */ } 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 PA5 ------> SPI1_SCK PA6 ------> SPI1_MISO PA7 ------> SPI1_MOSI */ GPIO_InitStruct.Pin = ADS8695_SCL_Pin|ADS8695_SDI_Pin; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); GPIO_InitStruct.Pin = ADS8695_SDO_Pin; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; GPIO_InitStruct.Alternate = GPIO_AF5_SPI1; HAL_GPIO_Init(ADS8695_SDO_GPIO_Port, &GPIO_InitStruct); /* SPI1 DMA Init */ /* SPI1_RX Init */ hdma_spi1_rx.Instance = DMA2_Stream0; hdma_spi1_rx.Init.Channel = DMA_CHANNEL_3; hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE; hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_spi1_rx.Init.Mode = DMA_CIRCULAR; hdma_spi1_rx.Init.Priority = DMA_PRIORITY_LOW; hdma_spi1_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE; hdma_spi1_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; hdma_spi1_rx.Init.MemBurst = DMA_MBURST_INC4; hdma_spi1_rx.Init.PeriphBurst = DMA_PBURST_INC4; if (HAL_DMA_Init(&hdma_spi1_rx) != HAL_OK) { Error_Handler(); } __HAL_LINKDMA(spiHandle,hdmarx,hdma_spi1_rx); /* SPI1_TX Init */ hdma_spi1_tx.Instance = DMA2_Stream3; hdma_spi1_tx.Init.Channel = DMA_CHANNEL_3; 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_LOW; hdma_spi1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; 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 */ //注册传输完成中断 HAL_DMA_RegisterCallback(&hdma_spi1_rx, HAL_DMA_XFER_CPLT_CB_ID, ADS8695_DmaCplCb); HAL_DMA_Start_IT(&hdma_spi1_rx, (uint32_t)&SPI1->DR, (uint32_t)S_GLOBAL_VARIBLE.ARRYI_ADS8695_DATA,D_ADS8695_LENGTH); SET_BIT(SPI1->CR2,SPI_CR2_RXDMAEN); __HAL_SPI_ENABLE(&hspi1); /* USER CODE END SPI1_MspInit 1 */ } 这是我的程序,如何在UP事件来到时发送 呢 我是采用 HAL_DMA_Start(&hdma_tim1_up,(uint32_t)arry_spi_tx, (uint32_t)&SPI1->DR,D_ADS8695_LENGTH); 这个函数的 如何让他发送 32位数据呢 这个函数只发送8位数据
你如果想发送32位,每次更新事件后,你可以连续发送4个字节数据。另外,F407SPI支持16位数据模式,每次更新 ...
是在定时器更新中断中完成SPI的发送吗?能不能通过某些设置让SPI自动发送32位数据呢。我是通过 HAL_DMA_Start(&hdma_tim1_up,(uint32_t)arry_spi_tx, (uint32_t)&SPI1->DR,D_ADS8695_LENGTH); 这个函数完成更新事件触发DMA的,但是这个方式,只能发送一次,也就是8位,不能发送32位 请问这个该怎么解决呢?
请ST的技术支持帮忙回复下把 如何让定时器更新事件触发DMA传输的时候,在没有任何干预的情况下 可以让SPI一次性输出至少18位 3个字节的数据?? 网上找了很多资料 都说做不到 只能通过事件中断来发送SPI数据,这样人为的中断干预会让程序变得不可控,毕竟要采集2048个点,要中断2048次,这个太频繁了,不知道是不是还有其他隐藏的设置可以做到让SPI在定时器更新事件触发的DMA能够发送3个以上字节???
请ST的技术支持帮忙回复下把 如何让定时器更新事件触发DMA传输的时候,在没有任何干预的情况下 可以让SPI一 ...
对于STM32F4系列,没法一个事件触发多个DMA传输。 我之前的想法是1个更新事件,基于更新中断发送多个SPI数据。 你现在数据较多,不希望过多中断干预可以理解,也是你当前的真实需求。 比方你希望通过SPI发送1024个数据,使用定时器触发DMA也是可以的。 这里定时器事件作为DMA触发源,传输指定个数后,可以4个,可以是1024个,然后DMA停止传输。 当然,这里每个数据的传输还是对应1个定时器事件。不知这样是否可以满足你的应用需求。
请ST的技术支持帮忙回复下把 如何让定时器更新事件触发DMA传输的时候,在没有任何干预的情况下 可以让SPI一 ...
对于STM32F4系列,一般没法一个事件触发多个DMA传输。 我之前的想法是1个更新事件,基于更新中断发送多个SPI数据。 你现在数据较多,不希望过多中断干预可以理解,也是你当前的真实需求。 比方你希望通过SPI发送1024个数据,使用定时器触发DMA也是可以的。 这里定时器事件作为DMA触发源,传输指定个数后,可以4个,可以是1024个,然后DMA停止传输。 当然,这里每个数据的传输还是对应1个定时器事件。不知这样是否可以满足你的应用需求。