对于快速入门STM32CubeMX,可以参考
【STM32】HAL库 STM32CubeMX系列学习教程
——————————
一、硬件参数与配置:
核心:STM32F407ZET6
外设ADC:ADS1258 数量:3个
※ 核心与3个ADC使用SPI总线 “一主多从” 方式连接,PCB布线的方式与下图一致。
※ 在电路板上STM32与三个ADS1258在同一直线上分布,STM32在一端,三个ADC依次排布。
※ 离STM32最远ADC的DRDY硬件管脚与STM32的EXTI line4 interrupt连接。
1.1 STM32CubeMX的设置
1.1.1 时钟树配置如下:
1.1.2 ADC输入的CLK由STM32的定时器TIM4控制,时钟树中APB1 Timer Clock = 84MHz,由下图配置生成PWM来当作ADC输入的CLK,CLK的频率为84/8 = 10.5MHz,
1.1.3 使用STM32的SPI3通讯协议,SPI3_RX的DMA Request与DMA1 Stream0连接,SPI3_TX的DMA Request与DMA1 Stream0连接。由于ADS1258的Datasheet中对SPI速率的要求,确定了STM32与ADC之间的SPI通讯速率为5.25MBits/s,即SCLK = 5.25MBits/s
1.2 ADS1258的设置
1.2.1 在整个系统初始化时,STM32向ADS1258发送一系列寄存器指令,将ADS1258的采样模式设置为Auto-Scan Mode、在该模式下使能需要采样的模拟信号输入管脚(已使能管脚按ADS1258 datasheet中的Channel ID,自动转换至待采样的模拟信号输入管脚)。
1.2.2 ADS1258在Auto-Scan Mode的Data Rate的计算公式如下,初始化设置中fclk = 10.5MHz,DR = 10b,TD = 8,CHOP = 0,计算得Data Rate = 5043Hz,即每个ADC的每次采样完成后DRDY引脚输出的信号频率为5043Hz。
二、运行逻辑
2.1 功能概述
在电路设计上,三个ADC的采样启停通过硬件连接由STM32的同步控制,且ADS1258的采样模式为Auto-Scan Mode,因此三个ADC能够同时将预定的输入模拟信号进行采样并转换为数字量,即在任一ADC的两个DRDY信号之间,三个ADC均在硬件上一一对应的模拟信号输入管脚进行采样。在两个DRDY之间,STM32需要通过SPI协议接收三组 4 Bytes 的数字量,为了在接收数据的同时不占用核心的处理,所以选择了非阻塞式的SPI-DMA传输,可以按照三个ADC的硬件摆放顺序,将三组数字量依次且完整接收。
2.2 功能实现
2.2.1 主要函数分析
使用EXTI line4 interrupt中断,离STM32最远ADC的DRDY管脚为中断信号源,在STM32的外部中断回调函数中,使用HAL库中的HAL_SPI_TransmitReceive_DMA函数,在两个DRDY信号之间(即下一次ADC采样完成前),通过类似递归的逻辑,将三个ADC的采样数据通过SPI协议传输至STM32。
HAL_StatusTypeDef HAL_SPI_TransmitReceive_DMA(SPI_HandleTypeDef *hspi, uint8_t *pTxData, uint8_t *pRxData, uint16_t Size)
使用 HAL_SPI_TransmitReceive_DMA函数,STM32需要发送1个字节的“通道数据读取指令”,紧接着便可接收4个字节ADC的采样数据,其中接收的第1个字节为状态字节,后3个字节为24位采样数据(通讯时序图见ADS1258的datasheet)。通过对HAL_SPI_TransmitReceive_DMA函数的源码、断点调试及相应寄存器的分析,确定了在stm32f4xx_it.c文件中的DMA1_Stream5_IRQHandler函数中用户可编辑代码段,可成功调用HAL_SPI_TransmitReceive_DMA函数。
void DMA1_Stream5_IRQHandler(void)
2.2.2 中断函数
相关中断的中断向量表如下图。
在HAL_SPI_TransmitReceive_DMA函数中会产生DMA1_Stream0_IRQHandler中断服务函数和DMA5_Stream0_IRQHandler中断服务函数的中断信号,即在外部中断服务函数执行完成后,会依次执行DMA1_Stream0_IRQHandler中断服务函数和DMA5_Stream0_IRQHandler中断服务函数。这两个中断服务函数中默认执行HAL_DMA_IRQHandler函数,其分别与SPI3_RX和SPI3_TX相应的&hdma_spi3_rx和&hdma_spi3_tx句柄绑定(下图为1.1.3 图表中设置生成的代码)。
在HAL_DMA_IRQHandler(&hdma_spi3_rx)前加入延时,一是为了避免当HAL_SPI_TransmitReceive_DMA函数正在运行过程中再次调用该函数,而导致DMA相关寄存器未复位,最终导致硬件执行错误;二是为了避免STM32还未完整接收某一个ADC传输的数据时,紧邻的ADC就开始发送数据,而导致的数据冲突。
在HAL_DMA_IRQHandler(&hdma_spi3_tx)后加入上述程序,是当外部中断回调函数中的HAL_SPI_TransmitReceive_DMA函数成功执行后,即第一个ADC发送数据并被STM32完整接收后,开始准备接收第二个和第三个ADC的数据。adDataChannel变量是“递归”的条件判断,即当三个ADC的数据全部发送并被STM32完整接收后,开始准备下一轮的数据接收。