我是靠谱客的博主 安详康乃馨,这篇文章主要介绍STM32并口数据通过DMA传输,现在分享给大家,希望可以做个参考。

在工作当中,使用STM32与其他芯片通信,常用的有SPI、UART、I2C等串行类的通信,但是对于ADC等芯片来说,还存在并口类型的通信方式。STM32提供了FSMC功能对总线进行控制。但是对于小封装类的芯片(64PIN)并未提供该功能,那么该怎么处理呢?我认为通过DMA进行并行数据的读写可以解决上述问题。
本方法有个缺陷就是必须使用同一组IO口,如PA或PB,这样直接对寄存器IDR进行读写,达到同时读写端口的目的。
使用的DMA也有要求,之前在网上搜集DMA传输IO口方法的时候,看到有人在论坛里讨论可行性,发现需要查看STM32F系列的各型号的DMA总线,比如我使用的F4系列的DMA总线。在这里插入图片描述
其中,DMA1的外设port只连接到了APB1上,不能作为IO的外设端,只能使用DMA2。
使用定时器TIM1的溢出作为触发传输,设置不同的定时时间,则得到不同的采样率。
定时器1配置:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void MX_TIM1_Init(void) { TIM_ClockConfigTypeDef sClockSourceConfig = {0}; TIM_MasterConfigTypeDef sMasterConfig = {0}; htim1.Instance = TIM1; htim1.Init.Prescaler = 16; htim1.Init.CounterMode = TIM_COUNTERMODE_UP; htim1.Init.Period = 98; htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter = 0; htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE; if (HAL_TIM_Base_Init(&htim1) != HAL_OK) { Error_Handler(); } sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; if (HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) { Error_Handler(); } sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET; sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; if (HAL_TIMEx_MasterConfigSynchronization(&htim1, &sMasterConfig) != HAL_OK) { Error_Handler(); } }

定时器DMA配置

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
if(tim_baseHandle->Instance==TIM1) { /* USER CODE BEGIN TIM1_MspInit 0 */ //hdma_tim1_up.XferCpltCallback = myDMA;//若需要DMA传输满,则配置DMA中断 /* 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_PERIPH_TO_MEMORY; hdma_tim1_up.Init.PeriphInc = DMA_PINC_DISABLE; hdma_tim1_up.Init.MemInc = DMA_MINC_ENABLE;//存储数组地址增加 hdma_tim1_up.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; hdma_tim1_up.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; hdma_tim1_up.Init.Mode = DMA_NORMAL;//如需一直保存,则配置为DMA_CIRCULAR hdma_tim1_up.Init.Priority = DMA_PRIORITY_HIGH; 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 */ /* USER CODE END TIM1_MspInit 1 */ }

主函数内或需要的地方配置开启DMA

复制代码
1
2
3
4
HAL_TIM_Base_Start(&htim1); HAL_DMA_Start_IT(&hdma_tim1_up,(uint32_t)&GPIOB->IDR,(uint32_t)ADC_RcvBuf,4096); __HAL_TIM_ENABLE_DMA(&htim1, TIM_DMA_UPDATE);

完成。
注:主要注意的地方就是DMA1/2的选择。

最后

以上就是安详康乃馨最近收集整理的关于STM32并口数据通过DMA传输的全部内容,更多相关STM32并口数据通过DMA传输内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(82)

评论列表共有 0 条评论

立即
投稿
返回
顶部