目 录CONTENT

文章目录

复制的

rhycwu
2024-06-05 / 0 评论 / 0 点赞 / 24 阅读 / 0 字
温馨提示:
本文最后更新于2024-06-06,若内容或图片失效,请留言反馈。 部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

这里是文章1

--- headingNumber: true wrapCode: true enableMacro: true mdOptions: { linkify: true, breaks: true } define: APP_NAME: Yank Note --- :::: tip 版本说明 ::: danger Releases Note v1.0 2023-03-29 ::: + May 9, 2022 at 1:47 PM 调试功能ok + Jun 22, 2022 at 9:47 AMYHPC 告警 激光 逻辑修改 + Jul 6, 2022 at 3:04 PM YHPC数据不全,atp乱转,激光不能关闭 + Jul 12, 2022 at 9:20 AM 浮点运算 IP核升级 todesk远程调试 + Jul 22, 2022 at 4:58 PM 增加告警批号判定 :::: ::: warning 协议与方案原理图 + [2023-03-29 15:30] [立乾合同.pdf (578.88KiB)](./FILES/项目总结_串口及告警系统.md/立乾合同.pdf){.open} [2023-05-24 13:31] [9-36vAECDE_PC104_MF.SCH.1.pdf (88.03KiB)](./FILES/项目总结_串口及告警系统.md/9-36vAECDE_PC104_MF.SCH.1.pdf){.open} [2024-01-02 10:08] [AECDE\_PC104\_MF.SCH.1.pdf (85.21KiB)](./FILES/项目总结_串口及告警系统.md/AECDE_PC104_MF.SCH.1.pdf){.open} [2024-01-02 10:08] [mini104\_feihang.pdf (178.22KiB)](./FILES/项目总结_串口及告警系统.md/mini104_feihang.pdf){.open} [2024-03-25 10:32] [AECDE\_PC104\_MF\_LOC.SCH.1.pdf (205.21KiB)](./FILES/项目总结_串口及告警系统.md/AECDE_PC104_MF_LOC.SCH.1.pdf){.open} [2024-04-29 14:39] [aecde\_pc104\_loc\(1\).pdf (176.59KiB)](./FILES/项目总结_串口及告警系统.md/aecde_pc104_loc%281%29.pdf){.open} 隔离电源版本 + 设计开发计划书docx + PC104开发协议.pdf + pc104告警检验大纲.docx ::: ::: tip 工程和逻辑 Gondola0711 12对差分接收信号,可接4路编码器读数头 + 代码调试: 2人/月 4w8 + 源代码:5w6 + 现场调试费:2000/次 省内 ;外省差旅费甲方负责 + 随板成套:20套,2w; 10套,1w5.。。。 + + 报价92260带板卡 108120 ::: # PC104 目录 [toc]{type: "ol", level: [2,3]} ## 基础准备 ### 串口的帧格式 ![Img](./FILES/项目总结_串口及告警系统.md/2900c04b.png) + 串口的帧格式 {.mindmap} + 格式组成:起始位,帧头,数据位,循环码,校验位,帧尾 + 起始位低电平有效 + 数据采集的clk为串口clk的8倍,16倍,推荐8倍即可。 + 数据抓取在中间位置 + 定义采集计数器cnt=0 + 起始位来时计数,每来一次clk计数器就+1 + 经过4个clk,cnt=4时取到第一个数 + 后面的0<i=i+1<9个数就应该在cnt=4+i*8的时候取 + 取完8位数后计数器归零 + 取完一帧数后将起始拉高,等待下一帧数据 ### 串口的波特率 波特率是指一个位的周期,即一个位所逗留的时间,波特率115200bps表示一秒可以传输115200位。那么一位所需时间为t秒: $$t=\frac1{115200}\$$ ```mermaid graph LR A[1bit所需时间t] --> B(一帧所需时间t*10) --> |如果1帧10位数据| B(一帧所需时间t*10) --> c[一帧时间为10/115200] --> |在115200bps情况下| c[T=10 * 1/115200]--> d[115200/10] --> |那么1秒内可传输的帧数1/T| d[115200/10] ``` 系统时钟和波特率的关系 $$分频系数p=\frac{系统时钟clk}{波特率bps}\$$ $$最大分频计数器n=\frac{分频系数p}2-1|$$ ~~~ clk_p = (cnt==n) ? ~clk_p:0 ; ~~~ ### 数据抓取 对系统时钟要根据串口波特率进行分频处理,发送数据时的分频频率和波特率一致,采集数据时用8倍采样率采集数据的中间位置可保证数据的准确性。 ![Img](./FILES/项目总结_串口及告警系统.md/5307a758.png) ## 串口数据收模块的解析 各端口的接收模块由uart_rx例化而来,由于各波特率和数据的字节数不同所以各uart_rx略有不同 ### 状态机图 ```mermaid stateDiagram-v2 [rxd] --> 起始位 起始位 --> 帧头 起始位 --> 起始位 帧头 --> 起始位 帧头 --> 数据 校验位 --> 起始位 数据 --> 校验位 数据 --> 起始位 帧尾 --> 起始位 校验位 --> 帧尾 帧尾 --> [re_data] ``` ### 有关逻辑(state) #### 初始化(Init): 初始化 ```verilog Init: begin state <= Idle; tally <= 8'd15; trig_r <= 1'b0; trig_v <= 1'b0; rx0<=1'b1; rx1<=1'b1; rx2<=1'b1;rx3<=1'b1; cnt <= 32 data_r <=8'h00; rxd_r <=9'b0000_0000_0; end ``` #### 状态1(Idle) :起始位判断 ```verilog Idle:begin rx0<=rxd;rx1<=rx0;rx2<=rx1;rx3<=rx2;//输入打4拍,取反做与处理判断为真开始采集 tirg_r<=0; //字节数收完标记 trig_v<=0; //数据正确校验码ok标记 cnt<=0; //取一个字节数计数 tall<=0; //取所有字节数计数 if (~rx3 & ~rx2 & ~rx1 & ~rx0) state <= Syn_First; else state <= Idle; end ``` #### 状态2(Syn_Firs) :取8bit数及帧头判断 ```verilog Syn_Firs:begin cnt <= cnt+1; case(cnt) 4+0*8: rxd_r(0) <= rxd; //串行数据rxd保存在并行变量rxd_r[9:0] state <= Syn_Firs; ... 4+7*8: rxd_r(7) <= rxd; //第8位数值 state <= Syn_Firs; 4+57: data_r <= rxd_r[7:0] //保存该字节数在变量data_r[7:0] state <= Syn_Firs; 4+8*8:begin //起始位拉高判断该字节数是否是帧头是就进取值状态不是返回重来 rxd_r(8) <= rxd; rx0<=1'b1; rx1<=1'b1; rx2<=1'b1; rx3<=1'b1; if(data_r==帧头) begin //帧头判断逻辑 state <= Start_rec; //开始进入采集逻辑 end else begin state <= Idle; //返回继续判断起始位 end end end ``` #### 状态3(Start_rec) :采集及校验码判断 ```verilog Start_rec: begin case(cnt) ... 4+57: data_r <= rxd_r[7:0] //取一个字节数 4+8*8:begin rxd_r(8) <= rxd; rx0<=1'b1; rx1<=1'b1; rx2<=1'b1; rx3<=1'b1; tally<=tally+1; //通过tally将一帧所有字节数据取完 if(tall<8‘d17) //数据为16个字节 case(tally) 0: re_data0 <= data_r; trig_r <= 0; 1: re_data1 <= data_r; trig_r <= 0; ... 16: re_data[i]<= data_r; trig_r <= 1; default: trig_r <=0; sata <= Start_rec; end 4+65:begin if(trig_r) begin //全部字节是否完整 if(re_data[i]==前字节和) //比较校验位 data_buf <={帧头,re_data0,...re_datai}; 有效数据 trig_v <= 1; //数据有效标记 state <= Receive_over; ``` #### 状态4(Receive_over) :解析结束 ```verilog Receive_over:begin rx0<=1'b1; rx1<=1'b1; rx2<=1'b1; rx3<=1'b1; trig_r <= 0; trig_v <= 0; state <= Init; end ``` #### 完成解析赋值 ```verilog always @(negedge trig_v) begin re_data <= data_buf; end ``` #### 采集完成标记信号的处理 为了能准确的采集到采集完成标记信号,要将trig_v做拉长处理,拉长时间宽度80us。示意图如下:80us的判断方法依然是用采用计数器,trig_v信号来开始计数,clock计数=299拉低trig_vv信号。 ![Img](./FILES/pc104.md/f1ad1011.png) ## 串口数据的发送 ### 触发信号的判断。用下面代码可以用trig_spor_Re抓取strig_spot的上升沿.依此来判断触发信号是否有效。当触发信号是上升沿有效时开始发送一帧数据 ```verilog always @ (posedge clk460k) begin trig_spot_d <= trig_spot; end assign trig_spot_Re = (!trig_spot_d) & trig_spot; ``` ## 顶层逻辑 由于对方给与的整个逻辑需求不明确,导致实际写逻辑的时候疑问太多,直接导致了工作量的不必要增加。今后对于类似项目的处理就要有前车之鉴。 ### 数据传输与赋值 1. 直接将需要的数据assign就行 2. 数字运算时将除法换算为乘法 3. {}里可以直接调用函数 `assign data = {rx1,rx2,dov(rx3[5:0]),rx0}` 4. 访达 ### 调试中的注意事项 1. 帧头位置是一帧数据的最高位 1. 有校验位的必须算正确,否则认为命令无效 1. 给对方的是128m芯片,烧写mcs时要先擦除一遍,然后只选烧写才行,要将only修改为整个 1. 64m芯片可以一次性擦除、烧写、校验 1. 调试中一些可能用到的命令格式 ```verilog // 调零串口pp值的功能 接收帧格式: 0xee 0x16 0xf0 0x90 字节1 字节2 字节3 字节4 循环码 检验和 0xfe 发送帧格式: 0xee 0x16 0xf0 0x90 0x55 0xaa 循环码 校验和 0xfe 00 自动 c0 维护 c3自检 (bf ff) 45度 ``` ## 调试 ### 激光收发的修改和重写 由于原收发模块中对重复性代码的编写比较正统清晰并没有使用循环和简写的技巧,在开始修改过程中细节上经常出错, 1. 漏改不同代码中不同位置的位宽 2. 重复代码过多口算位宽位置容易出错 ### 模块的优化 ```verilog preamble[0] <= recdata[303:296]; preamble[1] <= recdata[295:288]; 。。。 preamble[12] <= recdata[207:200]; preamble[13] <= recdata[199:192]; 。。。 ``` 如上代码可用for循环代替**矢量做为索引的时候:"+:" 相当于"+=" (DW-1)-ii*8选定了起始,然后从起始开始每次减8,8个取为一组 in[i +: 4]; 特别的,起始和终点都随着i变化,这是不允许的,verilog中只允许起始或终点发生变化,其他保持常量,这样做是为了保证宽度不发生改变** ```verilog for ( ii=0; ii<10; ii=ii+1) begin preamble[ii] <= recdata[(DW-1)-ii*8-:8]; end ``` 直接用参数代替, ```verilog module uart_rx #(parameter integer DW = 224 , FH1 = 8'h7e, FH2 = 8'ha0, FF = 8'he7, N_DATA = 25 //去帧头节数从零开始 ) 。。。 (value + 32'd65): begin if (yxyyjb == 1'b1) begin if ((recdat_r[N_DATA] == FF) && (recdat_r[N_DATA-1] == sum_p)) begin for (kk=0; kk<DW/8-2; kk=kk+1) begin yk_buf[N_DATA-kk] <= recdat_r[kk]; end yk_buf[DW/8-1:DW/8-2] <= {FH1,FH2}; yk_trig <= 1'b1; state <= Receive_over; end else begin state <= Idle; yk_trig <= 1'b0; end ``` 对于向case语句里面的重复代码用 ```verilog 8'd1 : begin Txd <= 1'b0; //Start_bit 0 state <= Start_Tx; end 8'd2,8'd3,8'd4,8'd5,8'd6,8'd7,8'd8,8'd9:begin Txd <= tx_data[Tx_cnt-2]; state <= Start_Tx; end ``` ### 功能的修改 #### 告警器方位俯仰数据的32位转换。函数的公式改为如下代码 ```verilog function [31:0] conv_dat; input [15:0] data_i; input [31:0] p_p; begin conv_dat = data_i * 120 + p_p; // if (data_i >= 16'h7fff) begin // conv_dat = ((data_i / 364 - 90) + p_p) * 186428; // end else begin // conv_dat = ((270 + data_i / 364) + p_p) * 186428; // end end endfunction assign conv_dat_alf = ((conv_dat(AlarmF_rec[231:216], Coef_rec[39:8] )) > 32'h3ffffff) ? ((conv_dat( AlarmF_rec[231:216], Coef_rec[39:8])) - 32'h3ffffff):(conv_dat(AlarmF_rec231:216], Coef_rec[39:8] )); //fw 。。。 assign conv_dat_alf_rec = conv_dat(AlarmF_rec[215:200], Coef_rec[71:40]); assign conv_dat_als_rec = conv_dat(AlarmS_rec[231:216], Coef_rec[71:40]); 。。。 assign atp_fw = (gjfv) ? conv_dat_als_rec:conv_dat_alf_rec; assign atp_fy = (gjfv) ? conv_dat_als_rec:conv_dat_alf_rec; ``` #### p_p值的修改由原来16位的1个pp值改成32位4个pp,pp值修改后数据返回由原来的固定值先修改为pp的调零数据值,为观察直观方便改为ATP收到的最终值,发送的触发信号改为接收的完成信号,即实现发送一次成功命令,助手显示一次返回数据。 ```verilog ee 16 00 00 00 00 00 00 00 00 fe //告警1 ee 17 00 00 00 00 00 00 00 00 fe //告警2 ``` ![Img](./FILES/项目总结_串口及告警系统.md/img-20220620110146.png) #### 激光因为换了厂家接收和发送命令全部做了修改 1. 串口的收发帧格式修改 1. 给1553的修改 1. 给yhpc的修改 1. 功能判断的修改 #### ATP的状态修改 目标有效和任务有效标志的更改,逻辑判断依据:目标个数告警1或2目标个数大于1即1否则为0;任务有效为ATP返回ready后为1. #### 增加电源指示灯和故障灯功能 引出IO31,IO30作为led的驱动信号。i031赋常值1即可实现上电点亮的电源灯指示功能。io功能有74芯片控制了方向所以要实现从fpga发送时就要将74芯片的方向改为由a->b即eio赋0使能74工作,dio为1选择方向。一个74芯片上有16路io信号2组eio和dio,2组可以分别控制AB方向。 ### bug调试 pp值修改用assign代码如下情况时pp1和pp2的值不受条件1和条件2的控制,直接表现为一荣俱荣一损俱损。使用ila功能编译时提示这种组合逻辑环有问题,应该用寄存器变量定义中间变量。 ```verilog assign pp1 = (条件1)?pp:pp1; assign pp2 = (条件2)?pp:pp2: ``` ### 其它 #### 函数定义的中间变量用reg写法和modele类似。 ```verilog function [31:0] outdata ; input [31:0] a; reg [31:0] temp1; begin ... end ``` #### 16位数转换成32位浮点数 + 转换依据X是报文的原始数据,X=(angle+90)*65535/180;angle=X*180/65535-90 + 告警方位偏移量输出7fff时,角度是0°;输出ffff时,角度是90°,输出0000时,角度是-90° 即目的就是将x转换成至少小数点后4位的angle。 ##### 方法一首先想到如下计算函数实现,但仿真结果误差较大。 ```verilog function [31:0] conv_dat32; input [15:0] data_i; reg [15:0] conv_dat1; begin conv_dat1 = (data_i / 364 - 90); if (data_i >= 16'h7fff) begin conv_dat32 = {16'h0,conv_dat1}; end else begin conv_dat32 = {16'hffff, conv_dat1}; end end endfunction ``` ##### 方法二 将16位定点数的转换成32位定点数,然后就行浮点数的A*B-C B=180/65535的浮点数,C为90的浮点数 ```verilog //16位定点转32位定点 assign gj1_fw = {16'h0, AlarmF_rec[231:216]}; ``` ```verilog //32位定点数转成32位浮点数 floating_point_0 floating_point_0_dut ( .aclk(clk8xuart), .s_axis_a_tvalid(1'b1), .s_axis_a_tready(), .s_axis_a_tdata(gj1_fw), .m_axis_result_tvalid(), .m_axis_result_tdata(float_gj1_fw) ); ``` ```verilog //A*B-C,B和C为转换成浮点数的常数 floating_point_2 floating_point_2_dut ( .aclk(clk8xuart), .s_axis_a_tvalid(1'b1), .s_axis_a_tready(), .s_axis_a_tdata(float_gj1_fw), .s_axis_b_tvalid(1'b1), .s_axis_b_tready(), .s_axis_b_tdata(32'h3B340B41), //0.00274658203125 32'h3B340B41 .s_axis_c_tvalid(1'b1), .s_axis_c_tready(), .s_axis_c_tdata(32'h42B40000), .m_axis_result_tvalid(), .m_axis_result_tdata(gj1_fw_d) ); ``` ```verilog //浮点数的加法 floating_point_1 floating_point_1_dut3 ( .aclk(clk8xuart), .s_axis_a_tvalid(1'b1), .s_axis_a_tready(), .s_axis_a_tdata(gj1_fw_d), .s_axis_b_tvalid(1'b1), .s_axis_b_tready(), .s_axis_b_tdata(p_pgj[39:8]), .m_axis_result_tvalid(), .m_axis_result_tdata(float_atp1_fw) ); ``` 仿真后的数据截图 ![Img](./FILES/项目总结_串口及告警系统.md/img-20220711094424.png) ### 仿真命令 写了do文件后 在quesat--->file--->change director ..指定do文件所在路径 .do文件写法 ```verilog if [file exists work] {vdel -all} vlib work vmap work work vlog -f list.f vopt +acc float_top_tb -o float_top_tb_opt -debugdb vsim -vopt float_top_tb_opt log -r /* add wave /* run -all ``` .f文件写法 ```verilog ./src/float_top_tb.sv ./src/float_top.v ./src/fix2float.v ./src/floatingadder.v ``` ## 迷你飞航的逻辑 接74芯led闪串口11收发正常,接15芯lvds,led闪,串口1接收数据led闪 [Luckysheet](){link-type="luckysheet"}

就是为了看长度

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin

评论区