STM32 能做到吗?高手请进,STM32 的 TIM 定时请求DMA SPI 传输?

2019-08-13 22:05发布

STM32  的 TIM  定时启动  SPI  传输?  哪位仁兄能给点建议吗?通过DMA,该如何配置呢? 我的应用是要  与 外面 高速(1us)AD芯片相连,通过SPI DMA驱动,定时1us启动一次,即1us发生一个SPI DMA请求,而不是SPI的TXE RXNE自动发生DMA请求?  STM32 TIM 的DMA   不能将目标地址或源地址   绑到SPI的DR寄存器地址?
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
44条回答
jxc2017jxc
1楼-- · 2019-08-16 00:30
只要NSS置0到第一个clk之间给够了就行。这个是硬件自动产生的,软件产生是不行的,速度不够,否则其它什么活都能干了。
jxc2017jxc
2楼-- · 2019-08-16 01:57
不能干了
jxc2017jxc
3楼-- · 2019-08-16 04:22
SPI普通模式在高速大数据通信下,很难保持稳定,我试了,没有TI模式好。
jxc2017jxc
4楼-- · 2019-08-16 10:12
 精彩回答 2  元偷偷看……
K.O.Carnivist
5楼-- · 2019-08-16 14:46
为什么你以前觉得定时器DMA的外设地址不能设成SPI寄存器呢……DMA控制器这种东西反正文档上没说能操作哪些地址,那么就是所有经过总线矩阵有连接的地址范围都可以吧……

STM32F4_Bus_MTX.png

[mw_shl_code=c,true]#include "stm32f4xx_ll_bus.h"
#include "stm32f4xx_ll_rcc.h"
#include "stm32f4xx_ll_system.h"
#include "stm32f4xx_ll_utils.h"
#include "stm32f4xx_ll_gpio.h"
#include "stm32f4xx_ll_tim.h"
#include "stm32f4xx_ll_dma.h"
#include "stm32f4xx_ll_spi.h"

static uint32_t spiValue = 0xAA;

void SystemClock_Config(void);

int main(void)
{
  SystemClock_Config();

  /* Configure SPI1 */
  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_GPIOB);

  LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_3, LL_GPIO_MODE_ALTERNATE);
  LL_GPIO_SetAFPin_0_7(GPIOB, LL_GPIO_PIN_3, LL_GPIO_AF_5);
  LL_GPIO_SetPinSpeed(GPIOB, LL_GPIO_PIN_3, LL_GPIO_SPEED_FREQ_HIGH);
  LL_GPIO_SetPinPull(GPIOB, LL_GPIO_PIN_3, LL_GPIO_PULL_DOWN);

  LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_4, LL_GPIO_MODE_ALTERNATE);
  LL_GPIO_SetAFPin_0_7(GPIOB, LL_GPIO_PIN_4, LL_GPIO_AF_5);
  LL_GPIO_SetPinSpeed(GPIOB, LL_GPIO_PIN_4, LL_GPIO_SPEED_FREQ_HIGH);
  LL_GPIO_SetPinPull(GPIOB, LL_GPIO_PIN_4, LL_GPIO_PULL_DOWN);

  LL_GPIO_SetPinMode(GPIOB, LL_GPIO_PIN_5, LL_GPIO_MODE_ALTERNATE);
  LL_GPIO_SetAFPin_0_7(GPIOB, LL_GPIO_PIN_5, LL_GPIO_AF_5);
  LL_GPIO_SetPinSpeed(GPIOB, LL_GPIO_PIN_5, LL_GPIO_SPEED_FREQ_HIGH);
  LL_GPIO_SetPinPull(GPIOB, LL_GPIO_PIN_5, LL_GPIO_PULL_DOWN);

  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1);

  LL_SPI_SetBaudRatePrescaler(SPI1, LL_SPI_BAUDRATEPRESCALER_DIV32);
  LL_SPI_SetTransferDirection(SPI1,LL_SPI_FULL_DUPLEX);
  LL_SPI_SetClockPhase(SPI1, LL_SPI_PHASE_2EDGE);
  LL_SPI_SetClockPolarity(SPI1, LL_SPI_POLARITY_HIGH);
  LL_SPI_SetDataWidth(SPI1, LL_SPI_DATAWIDTH_8BIT);
  LL_SPI_SetNSSMode(SPI1, LL_SPI_NSS_SOFT);
  LL_SPI_SetMode(SPI1, LL_SPI_MODE_MASTER);

  LL_SPI_Enable(SPI1);

  /* Configure DMA transfer */  
  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2);

  LL_DMA_ConfigTransfer(DMA2, LL_DMA_STREAM_5, LL_DMA_DIRECTION_MEMORY_TO_PERIPH |
                                               LL_DMA_PRIORITY_HIGH              |
                                               LL_DMA_MODE_CIRCULAR              |
                                               LL_DMA_PERIPH_NOINCREMENT         |
                                               LL_DMA_MEMORY_INCREMENT           |
                                               LL_DMA_PDATAALIGN_BYTE            |
                                               LL_DMA_MDATAALIGN_BYTE);
  LL_DMA_SetChannelSelection(DMA2, LL_DMA_STREAM_5, LL_DMA_CHANNEL_6);
  LL_DMA_ConfigAddresses(DMA2, LL_DMA_STREAM_5, (uint32_t)&spiValue, LL_SPI_DMA_GetRegAddr(SPI1), LL_DMA_GetDataTransferDirection(DMA2, LL_DMA_STREAM_5));
  LL_DMA_SetDataLength(DMA2, LL_DMA_STREAM_5, 1);
  
  LL_DMA_EnableStream(DMA2, LL_DMA_STREAM_5);
  
  /* Configure TIM1 */
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
  
  LL_TIM_SetCounterMode(TIM1, LL_TIM_COUNTERMODE_UP);
  LL_TIM_SetPrescaler(TIM1, __LL_TIM_CALC_PSC(SystemCoreClock, 10000000));
  LL_TIM_SetAutoReload(TIM1, __LL_TIM_CALC_ARR(SystemCoreClock, LL_TIM_GetPrescaler(TIM1), 10000*2));
  LL_TIM_EnableDMAReq_UPDATE(TIM1);

  LL_TIM_EnableCounter(TIM1);

  /* Infinite loop */
  while (1) {}
}
[/mw_shl_code]
K.O.Carnivist
6楼-- · 2019-08-16 20:19
NSS建立时间的意思是STM32的SPI从机要求NSS置零到第一个时钟沿之间至少是4个PCLK,AD7671的SYNC不满足,需要用定时器PWM单做一个NSS。当然这个不重要既然你已经用TI模式了。

5M往上如果没有高速IO电平的话,那还是考虑并行输出的ADC吧。
一个馊主意是试试DCMI。

一周热门 更多>