FPGA解析B码----连载1

前言

    现有:STM32已经编写好B码解析程序,现需要采用FPGA解析B码。

    原因:CSDN上找不到编写的B码程序,就算有全部需要下载,穷,没有下载点。

    区别:STM32是顺序执行,方便接收B码和解析B码,同时有PWM采集例程,定时器,计数器。

    难点:FPGA是并行结构,逻辑比较复杂。

写在前面

    之前使用FPGA仅仅是编写了串口,SPI,double双精度数据的运算。对于1s数据和脉宽采集这种还没有编写过,现在尝试采用自己总结的编写方式和规范一步一步的编写B码解析程序。

    写这篇文章的时候,自己还不知道怎么去编写,下面一步一步的将自己的思维方式和程序展示,希望能对学习FPGA的小伙伴和解析B码的小伙伴给与帮助,能节省一定的时间和金钱。也希望能和大家一起学习。

第一章:需求

    输入:B码;

    输出:1PPS信号,UTC时间,B码关键帧信息。

第二章:B码结构

     信号时长:1s;

     信号种类:2ms:0电平(暗红色);5ms:1电平(橙黄色);8ms:标志电平(绿色);

第三章:拆解

    大类拆解:1PPS,B码信息输出;

    小类拆解:脉宽采集,码元存储,时间计算,串口输出。

第四章:显示部分

    这部分最好加上,显示自己的程序正在运行,最好用1个LED灯进行显示,然后最后程序定型之后再给去掉,如果空间大的话那就随意了。

always@(posedge clk or negedge rst_n)
begin
	if (rst_n == 1'b0)
		timer <= 32'd0;                     
	else if (timer == 32'd9_999_999)    
    	timer <= 32'd0;                   
	else
		timer <= timer + 32'd1;            
end

        先来个计数器,一般程序就采用这种格式(这个格式是自己总结的,方便,好看,简单,一句一句的来,以后自己阅读着也能看出来自己写的是啥!)

    (1)复位,变量赋值为0;

    (2)条件1,变量处理1;

    (3)条件2,变量处理2;

    (4)其他条件,变量处理3。

    当然中间也可以再增加其他条件。计数器作用从0加到9999999,然后再回到0。具体最大值多少随便。

    然后再来个点灯,到一定数值,flag加1,然后下次再加1,也就是flag在0和1之间变化。

always@(posedge clk or negedge rst_n)
begin
    if (rst_n == 1'b0)
        flag <= 1'b0;
    else if(timer == 32'd8_999_999) 
        flag <= flag + 1'b1;
    else
        flag <= flag;
end
always@(posedge clk or negedge rst_n)
begin
    if(rst_n == 1'b0) 
	 begin
          led4<=1'b1;
    end
    else begin
    case (flag)
          1'b0   : led4<=1'b1;
          1'b1   : led4<=1'b0;
          default  : led4<=1'b0;
    endcase	
    end	 
end

    结构还是刚才那个结构,复位置0,time的值等于8999999时flag加1,其他条件flag不变。

    复位灯置0,两个条件下LED分别置0和1,代表亮和灭。

    这样LED灯就可以按照一定周期亮和灭了。

第五章:脉宽采集

    思路:这部分我想着大概分成4部分,具体还需要怎么弄,一会编程看看!

    (1)上升沿检测;(2)下降沿检测;(3)沿检测后的计数器启动和停止;(4)脉宽时间计算。

    上升沿检测和下降沿检测程序:

//脉宽的上升沿和下降沿检测
reg        bpluse_en_d0; 
reg        bpluse_en_d1; 
wire       bpluse_falling_flag;
wire       bpluse_rasing_flag;
assign bpluse_falling_flag = (~bpluse_en_d0) & bpluse_en_d1;
assign bpluse_rasing_flag  = (~bpluse_en_d1) & bpluse_en_d0;
always @(posedge clk or negedge rst_n) begin         
    if (!rst_n) begin
        bpluse_en_d0 <= 1'b0;                                  
        bpluse_en_d1 <= 1'b0; 
    end                                                      
    else begin                                               
        bpluse_en_d0 <= bcodein;                               
        bpluse_en_d1 <= bpluse_en_d0;
        		  
    end
end

    检测到上升沿和下降沿时,两个flag分别一个周期的脉冲信号。

//置位time是否开启
reg        timebeginflag; 
always@(posedge clk or negedge rst_n)
begin
	if (rst_n == 1'b0)
		timebeginflag <= 1'd0;                     
	else if (bpluse_rasing_flag == 1)      
    	timebeginflag <= 1'd1;                      
	else if (bpluse_falling_flag == 1)
		timebeginflag <= 1'd0; 
   else 
      timebeginflag <= 1'd0; 	
end

    当上升沿和下降沿时,timebeginflag分别置1和0。

//上升沿之后计数器工作,下降沿之后计数器停止
reg [31:0]      timer;
always@(posedge clk or negedge rst_n)
begin
	if (rst_n == 1'b0)
		timer <= 32'd0;                     
	else if (timebeginflag == 1)      
    	timer <= timer + 32'd1;                     
	else if (timebeginflag == 0)
		timer <= timer;             
end

    上升沿时,time计数器开始计数,下降沿时,time计数器停止。

    这块缺少一个time复位为0的一个条件,这个条件为time计数器中的数据取出后的标志位,当取出time之后,time复位,为下次的脉宽测量做准备。

    脉宽计算程序:

reg    bcodelevel; 
always@(posedge clk or negedge rst_n)
begin
	if (rst_n == 1'b0)
		bcodelevel <= 0;                                        
	else if (bpluse_falling_flag == 1)begin
		if(timer >= 350000)bcodelevel = 3; //P电平
      else if(timer >= 200000)bcodelevel = 2; //1电平
		else if(timer >= 50000 )bcodelevel = 1; //0电平
		else bcodelevel = 0; 
   end
   else 
      bcodelevel <= 0; 	
end

    当下降沿来时,time计数器停止计数,同时判断time中的数据,由于time的数据不那么准确,可以判断大范围之后的电平,大于7ms即为标志电平,大于4ms即为1电平,大于1ms即为0电平。中间用了else,所以3个判断并不冲突。这样就能判断每个脉冲的电平了。

第六章:测试

    程序先编写到此,明天测试编写程序。测试程序直接发送对应的ms数的电平信号,测试能否采集到对应电平。

    整体思路就是先采集上升沿和下降沿,启动计数器,下降沿时判断计数器数据大小,根据数据大小输出电平类型。当然下面还得锁存电平,只能明天考虑了

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值