使用STM32 HAL库实现定时器触发DMA并口数据传输

代码目的:

STM32与FPGA通讯,通过8位并口线进行通讯,16byte的数据在10us之内通过8位并口数据线传给FPGA,FPGA读取该数据。

HAL库设置说明:

时钟采用80MHz,由于16byte的数据要在10us之内传完,那么10/(16*2)=0.3125us/次,也就是传输频率得≥3.2MHz。

定时器设置:为了方便起见,先选用了4MHz的传输频率。80MHz/((1+1) * (9 + 1)) = 4MHz,PWM的占空比为5/10=50%

  • 关于PWM
    PWM中Pulse与占空比有关,当定时器计数递增模式下,计数值从0开始,当CNT的值小于CCRx(也就是Pulse),则输出CH Polarity的极性,当大于CCRx则输出相反极性,当CNT的值=ARR(counter period),则定时器溢出重新开始计数。

  • 启动PWM有3种方式

    顾名思义可以看出来,第一种启动后就开始输出;第二种是带中断方式,能产生中断;第三种就是DMA的方式,这种应用在电机精准步进控制上比较多,我打算通过这章方式应用到数据传输中,因为传输速度比较快,如果人为进行管脚输出我试过,16byte的数据即使在80MHz的时钟下也得50us左右,因为准备用DMA的方式。以上三种方式各有各的应用场景。

  • 定时器触发DMA设置说明:传输方向是内存到外设端口,传输宽度16位=half word

    代码实现

    由于我设置的传输宽度是16位的,因此定义一组16位的数据缓冲区:
    uint16_t databuf[16];
    原来的HAL_StatusTypeDef HAL_TIM_PWM_Start_DMA(TIM_HandleTypeDef *htim, uint32_t Channel, uint32_t *pData, uint16_t Length)查看具体的代码可以知道,主要是针对PWM的占空比进行配置的。因此重写该函数,将外设地址改为GPIOF端口:
    HAL_DMA_Start_IT(htim->hdma[TIM_DMA_ID_CC2], (uint32_t)pData, (uint32_t)(&(GPIOF->ODR)), Length)
    在主函数中进行调用即可。
    MY_TIM_PWM_Start_DMA(&htim5,TIM_CHANNEL_2,(uint32_t *)(&databuf), 16);
    在回调函数HAL_TIM_PWM_PulseFinishedCallback中停止DMA,并置标志位u8dmacop ,为下一次传输做准备。

      while (1)//主函数中
      {
        /* USER CODE END WHILE */
    
        /* USER CODE BEGIN 3 */
    	  if(u8dmacop)
    	  {
    		  u8dmacop = 0;
    			htim5.Instance->CNT = 0;
    			HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6, GPIO_PIN_SET);
    			MY_TIM_PWM_Start_DMA(&htim5,TIM_CHANNEL_2,(uint32_t *)(&databuf), 16);
    	  }
      }
    
    void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
    {
    	if( htim == &htim5)
    	{
    		HAL_GPIO_WritePin(GPIOF, GPIO_PIN_6, GPIO_PIN_RESET);
    		u8dmacop = 1;
    		HAL_TIM_PWM_Stop_DMA(&htim5, TIM_CHANNEL_2);
    		htim5.Instance->CNT = 0;
    	}
    
    }
    

    其中HAL_TIM_PWM_PulseFinishedCallback是计数器CNT = CCRx值时进行触发,另外还有一个函数HAL_TIM_PWM_PeriodElapsedCallback,该函数是计数溢出时触发,也就是整个周期结束,CNT=ARR时。
    为了用示波器查看方便,把缓冲区数据做递增处理,使得8位并口线最低位可以看到数据的来回变化。用示波器在PF7管脚可以看到4MHz的PWM波在输出,数据最低位管脚在2MHz的频率变化,输出波形有8个,也就是16组数据。

    物联沃分享整理
    物联沃-IOTWORD物联网 » 使用STM32 HAL库实现定时器触发DMA并口数据传输

    发表评论