1. 前言  
 在伺服应用中,客户使用DFSDM需要搭配TIM1输出做过电流保护同时做周期封波,如果只用DFSDM模块,我们只能使用模拟看门狗的break信号做其中一种,要么用于过电流保护(OC:Over Current),要么只做周期封波(CBC:Cycle-by-Cycle),而同时完成则需要加入其他外设。本文将就针对这个应用做介绍,硬件测试板为Nucleo-H723ZG。  
 
 2. DFSDM看门狗输出Break信号  
 伺服应用中TIM1产生3对互补输出(6路)PWM用于驱动电机,而电流采样则使用Sigma Delta采样,会使用到STM32H723内部的DFSDM进行数字滤波,滤波输出作为正常电流信号用于电机控制,同时输入电流信号到模拟看门狗,做电流保护功能。  STM32H723的模拟看门狗可以监测电流信号,当超过阈值后,会有Break信号输出,这个信号内部连接到TIM1的Break模块,可以立刻关闭PWM输出,也可以结合TIM1输出自恢复功能(AOE =1)去做CBC功能,见如下结构: 
 
 
 
当我们需要同时做OC以及CBC功能时候,这时候单独的模式就不能实现了,需要结合其他外设去硬件实现。  
 
 3. 实现方式思考  
 我们知道ETR的clear功能可以实现CBC,这样我们需要引进另外一个TIM16,它的输出连接到TIM1的ETR管脚上。同时使用到两个AWD模块,一个输出OC的break信号,一个输出CBC的break信号。  
 
 
▪ DFSDM的Break[0]作为OC(大电流)封波信号,内部输入到TIM1的BKIN1 ▪ DFSDM的Break[1]作为CBC信号,内部输入到TIM16的BKIN ▪ TIM16通道1外接TIM1的ETR管脚,作为ETR信号(TIM1 CBC控制),TIM16 工作在自动输出模式BDTR->AOE=1 ▪ 正常情况下CH1输出高电平,当DFSDM的Break[1]信号产生后,TIM16_CH1 输出低电平,TIM1输出低 ▪ 当DFSDM的Break[1]信号消失后, TIM16_CH1继续输出高电平,TIM1继续PWM输出 
 
4. 功能的CubeMx配置 4.1. DFSDM模块的配置 为了简化测试,我们这边用一个Filter对三个电流通道进行滤波,当然也可以使用三个Filter分别对三个电流信号滤波,对于看门狗的模块则必须三个通道同时输入到同一个看门狗比较模块中,在CubeMx中无此配置,我们需要使用程序单独配置。 
 
 
 
 
 
 
 
 
 
4.2. TIM1的配置  
 作为产生PWM输出的TIM1,需要配置三对互补输出,这边不做详细的配置说明,本例中死区未配置,需要根据实际情况进行配置。这边必须用到两个功能,一个是DFSDM的OC Break功能,一个是ETR的Clear功能,用来做CBC。  
 
 
 
 
 
4.3. TIM16的配置  
 对于TIM16,我们需要配置DFSDM的Break功能,并且TIM16 CH1要输出100%占空比波形,要连接TIM1的ETR,要使能AOE功能,用于CBC功能。 
 
 
5. DFSDM模拟看门狗配置  
 模拟看门狗没有CubeMx的相关配置,需要在程序中进行配置,这边我们需要使用快速模式AWFSEL = 1,外部数据需要是串行输入,独立的看门狗滤波参数,独立运行于电流信号采集,主要配置通道使用(FLTCR2-> AWDCH[7:0]),看门狗上下阈值的配置(FLTAWHTR,FLTAWLTR),Break功能的输出(FLTAWHTR-> BKAWH [3 :0],FLTAWLTR ->BKAWL[3 :0]),做为OC功能的AWD0的配置如下: 
- /* 
 
 -  * Filter 0 AWD used for CH0,CH1,CH2, work in fast mode 
 
 -  * AWHTR/AWLTR should set to OC threshold 
 
 -  * DFSDM BK[0] used for TIM1 break input 
 
 - */ 
 
 - void DFSDM_AWD_Init(void) 
 
 - { 
 
 -  /* AWFSEL = 1, select AWD self filter for fast response */ 
 
 -  DFSDM1_Filter0->FLTCR1 |= (1<<30); 
 
 -   
 
 -  /* AWD used channel config, here config CH0,CH1,CH2 use same FILTER AWD*/ 
 
 -  DFSDM1_Filter0->FLTCR2 |= (0x07<<16); 
 
 -   
 
 -  /* Set threshold of AWD high and low  
 
 -   * Threshold is signed value, range [-32768,32767] 
 
 -  */ 
 
 -  DFSDM1_Filter0->FLTAWHTR = (20000<<16); 
 
 -  DFSDM1_Filter0->FLTAWLTR = -(20000<<16); 
 
 -   
 
 -  /* Clear Flags */ 
 
 -  DFSDM1_Filter0->FLTAWCFR = 0xFFFF; 
 
 -  
 
 - //---Just example how to reconfig AWD filter parameter, also can config through 
 
 - Cubemx   
 
 -  /* Disable channel */
 
 -  DFSDM1_Channel0->CHCFGR1 &= ~(1<<7); 
 
 -   
 
 -  /* Set AWD filter parameter, config AWFORD(0~3) and AWFOSR(0~31) */ 
 
 -  DFSDM1_Channel0->CHAWSCDR = (0x02<<22) + (0x02<<16); 
 
 -   
 
 -  DFSDM1_Channel0->CHCFGR1 |= (1<<7); 
 
 - //-------------------------------------------------------------//  
 
 -  /* Config break output to TIM1 */ 
 
 -  DFSDM1_Filter0->FLTAWHTR |= 0x01; 
 
 -  DFSDM1_Filter0->FLTAWLTR |= 0x01; 
 
 - } 
 
 
  做为CBC功能的AWD1,配置的阈值上下限需要小于OC功能的AWD0,配置如下: 
 
- /* 
 
 -  * Filter 1 AWD used for CH0,CH1,CH2, work in fast mode 
 
 -  * AWHTR/AWLTR should set to CBC threshold 
 
 -  * DFSDM BK[1] used for TIM16 break input 
 
 -  * AWD work under continous mode, independent from inject convert, not need 
 
 - trigger 
 
 - */ 
 
 - void DFSDM_AWDCBC_Init(void) 
 
 - { 
 
 -  /* AWFSEL = 1, select AWD self filter for fast response */ 
 
 -  DFSDM1_Filter1->FLTCR1 |= (1<<30); 
 
 -   
 
 -  /* AWD used channel config, here config CH0,CH1,CH2 use same FILTER AWD*/ 
 
 -  DFSDM1_Filter1->FLTCR2 |= (0x07<<16); 
 
 -   
 
 -  /* Set threshold of AWD high and low  
 
 -   * Threshold is signed value, range [-32768,32767] 
 
 -  */ 
 
 -  DFSDM1_Filter1->FLTAWHTR = (10000<<16);
 
 -  DFSDM1_Filter1->FLTAWLTR = -(10000<<16); 
 
 -   
 
 -  /* Clear Flags */ 
 
 -  DFSDM1_Filter1->FLTAWCFR = 0xFFFF; 
 
 -  
 
 -  /* Config break output to TIM16 */ 
 
 -  DFSDM1_Filter1->FLTAWHTR |= 0x02; 
 
 -  DFSDM1_Filter1->FLTAWLTR |= 0x02; 
 
 - }
 
  6. 正常电流信号的DMA配置  
 使用CubeMx默认生成STM32H723的RAM没有包含D1域中的RAM,如果定义数组可能会定义到DTCM区域,这个区域无法被DMA1访问,因此我们要定义数组的存储地址,如果使能Cache,还需要在MPU中配置存储属性,这边我们定义存储正常电流信号的DMA数组在SRAM1中(0x30000000),这样在link file中要定义好,数组也要做特别定义。  
 比如link file中定义SRAM1区域  
- SRAM1 0x30000000 0x00004000  { 
 
 -    .ANY (+RW +ZI) 
 
 -    .ANY (.sram1) 
 
 -   }
 
  定义数组到SRAM1中 
- /* Define Array to get inject DFSDM value */ 
 
 - int32_t FLT1_JData[3] __attribute__((section (".sram1")));
 
  启动DFSDM,并且配置DMA源,目标地址,以及DMA传输长度 
- /* Start filter 0 using inject DMA mode */  
 
 -   HAL_DFSDM_FilterInjectedStart_DMA(&hdfsdm1_filter0,FLT1_JData,3);
 
  7. 测试功能  
 我们外部连接TIM16 CH1(PF6)到TIM1的ETR管脚(PE7),使用SPI模拟Sigma Delta 输入,同时可以实时改变AWD的阈值,用于模拟OC功能或者CBC功能波形,在DFSDM_FLTxAWS寄存器可以读取是哪路信号产生的结果。可以看到下面的功能波形。 
 
 
 
 
 
 
 
 
 
 
 
 
  |