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的输入信号
作者:qq_43169706