STM32使用外部触发DMA并通过FMC总线传输数据

1.硬件部分

单片机使用STM32F103ZET6,触发源选择信号发生器,该信号发生器产生4us脉冲,触发DMA。本文同时使用信号发生器的信号触发FMC的计数脉冲计数,使用ACTEL 的型号为ProASIC A3P250 VQG100的FPGA产生FMC计数脉冲(FMC传输数据的宽度),本文使用了一个三位计数器产生0-7计数(使用到3位FMC数据线)。


2.软件配置

本文使用高级定时器TIM8,当外部触发该定时器时,该定时器产生连续的16个脉冲,每个脉冲长度位为250ns,16个脉冲的总长为4us。TIM8配置如图所示:选择从模式为触发模式,触发源为外部触发ETR1,该脚硬件连接到信号发生器的输出脚。使用TIM8的单脉冲模式,在CH4通道产生输出捕获比较信号,重复计数器的值为16。

FMC配置如图:选择NE1作为源地址(NE1地址为0X60000000),选择数据位数为16位。将datasetup time设为1,bus turn around time 设为1。

TIM8的DMA中断传输配置如图:源地址不变,目标地址每次+1。

3.程序代码

FPGA产生FMC计数程序为:

module FMC_DMA_Data( sys_clk, sys_rst_n,data_dma,fc_trigger );
input sys_clk, sys_rst_n;
input fc_trigger;//信号发生器的输出作为输入
output [2:0]data_dma;//产生FMC计数,验证DMA传输是否有误
reg [2:0]data_dma1;


//捕获信号发生器信号的下降沿
reg [1:0]delay1_fc_trigger;
always@(posedge sys_clk or negedge sys_rst_n)
    begin
        if(! sys_rst_n)
            delay1_fc_trigger=1'b0;
        else
            delay1_fc_trigger={delay1_fc_trigger,fc_trigger};



    end

wire neg_fc_trigger;

assign neg_fc_trigger=(delay1_fc_trigger[1])&(~delay1_fc_trigger[0]);



//在信号发生器的下降沿计数
always@(posedge sys_clk or negedge sys_rst_n)
    begin
      if(! sys_rst_n) 
            begin  
                data_dma1<=3'd0;
            end
            
       else if(data_dma1==3'd7&&neg_fc_trigger)
          data_dma1<=3'd0;
        else if(data_dma1<3'd7&&neg_fc_trigger)
           data_dma1<=data_dma1+1'b1;

    end
assign data_dma=data_dma1;
//<statements>

endmodule

main.c函数主要程序为:

uint16_t Read_data[1024];//定义目标地址数据,从源地址中读取数据,数据长度为1024

 AD_Address= (uint16_t*)0x60000000;//源地址
//为目标地址数据赋初值,便于观察
for(int i=0;i<1024;i++)


  {Read_data2[i]=1023-i;}


 
 HAL_TIM_OC_Start(&htim8,TIM_CHANNEL_4);//开启定时器输出捕获
 __HAL_TIM_ENABLE_DMA(&htim8,TIM_DMA_CC4);//使能定时器8DMA,定时器触发DMA源选择输出比较通道4
HAL_DMA_Start_IT(&hdma_tim8_ch4_trig_com,(uint32_t)AD_Address,uint32_t)Read_data, 1024)//开启DMA传输中断,DMA传输长度为1024



it.c文件里的主要代码为:

void DMA2_Channel2_IRQHandler(void)
{
  /* USER CODE BEGIN DMA2_Channel2_IRQn 0 */
	uint16_t  Get_Data[1024];//读取目标地址数据
	for(int i=0;i<1024;i++)
	{
		 Get_Data[i]=Read_data2[i]&0007;//因为本文FMC只用到了低3位,所以低三位与1相与
	}
  /* USER CODE END DMA2_Channel2_IRQn 0 */
  HAL_DMA_IRQHandler(&hdma_tim8_ch4_trig_com);//设置断点,进入中断处理程序
  /* USER CODE BEGIN DMA2_Channel2_IRQn 1 */

  /* USER CODE END DMA2_Channel2_IRQn 1 */
}

注意!!!如果信号发生器上升沿作为计数器计数开始,由捕获输入到FPGA信号的上升沿时间不确定,导致FMC计数和16个DMA信号谁先谁后不确定,计数可能提前或者滞后从而产生数据错误。

所以,采用信号发生器产生的下降沿作为FPGA的输入信号

  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值