最新文�? 企业该如何拥有自主大模型,引领行业未来 学习大模型的必经之路:Transform 大模型与知识智能:心理疾病治疗的新希望 大模型泡沫退去,谁能活到下半场 大模型如何改变内容生态
原创 : FPGA-UART串口 历史版本:
上次修改时间:
; **波特率**又称码元率,是指每秒传输码元的数目,单位波特(Band) \n\n码元:在数字通信中常常用时间间隔相同的符号来表示一个二进制数字[二进制数字](https://baike.baidu.com/item/%E4%BA%8C%E8%BF%9B%E5%88%B6%E6%95%B0%E5%AD%97/5920908?fromModule=lemma_inlink),这样的时间间隔内的信号称为(二进制)码元。 而这个间隔被称为码元长度\n\n### **2.1UART串口发送逻辑分析**\n\n实现设计的模块端口\n\n**输入:**\n\nData[7:0] :  8位输入 对应8个拨码开关   ;\n\n时序电路,所以有CLK时钟,以及Reset_n复位;\n\n**输出:**\n\nuart_tx :  需要发送的数据;\n\nLED :   发送完LED闪烁;\n\n**细节梳理 :**\n\n9600波特率:计数器实现\n\n起始位 bit1,bit2....bit7 停止位(一共10位)----->;定义一个4位计数器 在发送数据时在0-9计数,\n\n然后根据计数器的值 来决定发起始位还是8位数据还是停止位。\n\n其中,每1秒发送一次数据  (每秒都能发送)\n\n当发送到bit3时  我飞快的改变bit4,bit5,bit6,bit7,使其为1,**那我们究竟发0 还是发1呢?**\n\n**答案是肯定发送0  因为在启动发送的时候是0,即使之后变为了1,我们也只能发送启动发送的值 那就得想办法在启动发送的时候把拨码开关的值,存储下来,只发生存储的值。而不管拨码开关当前的值。**\n\n那怎么存呢  ----->;**D触发器 存储特性**\n\n其实就是找到发送完成的时刻。\n\n思路:通过线性序列机,当串口完成发送时,翻转LED状态\n\n### 2.2编写代码分析\n\n输入 : data;Clk;Reset;\n\n输出:uart_tx; LED;\n\n首先 波特率  --->; 波特率计数器   \n\n然后 每一位发送 ----->; 位计数器\n\n之后  位发送逻辑\n\n最后 控制LED翻转\n\n**开发流程可参考([FPGA_Vivado开发流程](https://blog.csdn.net/weixin_46897065/article/details/135588455?spm=1001.2014.3001.5501))**\n\n代码如下\n\n```\nmodule uart_tx0(\n data,\n Clk,\n Reset,\n uart_tx,\n LED\n );\n input [7:0]data;\n input Clk;\n input Reset;\n output reg uart_tx;\n output LED;\n reg LED;\n \n parameter DELAY = 50000000-1; //1000000000/20;\n parameter MCNT_DIV = 5208 - 1; //1000000000/9600/20; \n parameter MCNT_BIT = 10-1;\n \n reg [3:0]bit_count;\n reg en_bud;\n reg [25:0]delay_count;\n //reg [11:0]delay_cnt;\n \n //波特率计数\n reg [12:0]div_count;\n always@(posedge Clk or negedge Reset)\n if(!Reset)\n div_count >;= 0;\n else if(en_bud)begin\n if(div_count >;= MCNT_DIV)\n div_count >;= 0;\n else\n div_count >;= div_count + 1;\n end\n else\n div_count >;= 0;\n \n //使能 \n always@(posedge Clk or negedge Reset)\n if(!Reset)\n en_bud >;= 0;\n else if(delay_count == DELAY)\n en_bud >;= 1;\n else if(div_count ==MCNT_DIV && bit_count == MCNT_BIT)\n en_bud >;= 0;\n \n //位计数\n always@(posedge Clk or negedge Reset)\n if(!Reset)\n bit_count >;= 0;\n else if(div_count == MCNT_DIV)begin\n if(bit_count == MCNT_BIT)\n bit_count >;= 0;\n else\n bit_count >;= bit_count + 1\'d1;\n end\n \n // 1S 延时计数器\n always@(posedge Clk or negedge Reset)\n if(!Reset)\n delay_count >;= 0;\n else if (delay_count == DELAY)\n delay_count >;= 0;\n else\n delay_count >;= delay_count + 1\'d1;\n \n reg[7:0]temp_data;\n always@(posedge Clk or negedge Reset)\n if(!Reset)\n temp_data >;= 0;\n else if(delay_count == DELAY)\n temp_data >;= data;\n else\n temp_data >;= temp_data;\n\n always@(posedge Clk or negedge Reset)\n if(!Reset)\n uart_tx >;= 0;\n else if(en_bud==0)\n uart_tx >;= 1;\n else begin\n case (bit_count)\n 0 : uart_tx >;= 0 ;\n 1 : uart_tx >;= temp_data[0];\n 2 : uart_tx >;= temp_data[1];\n 3 : uart_tx >;= temp_data[2];\n 4 : uart_tx >;= temp_data[3];\n 5 : uart_tx >;= temp_data[4];\n 6 : uart_tx >;= temp_data[5];\n 7 : uart_tx >;= temp_data[6];\n 8 : uart_tx >;= temp_data[7];\n 9 : uart_tx >;= 1; \n default: uart_tx >;= 0; \n endcase\n end\n \n //控制LED翻转\n always@(posedge Clk or negedge Reset)\n if(!Reset)\n LED >;= 0;\n else if(div_count ==MCNT_DIV && bit_count == MCNT_BIT)\n LED >;= ~LED;\n else\n LED >;= 0;\n\nendmodule\n\n```\n\n然后编写testbench测试文件 \n\n代码如下(在测试中我们将时间参数减小便于调试仿真)\n\n```\n`timescale 1ns / 1ps\nmodule uart_tx0_tb();\n reg [7:0]data;\n reg Clk;\n reg Reset;\n wire uart_tx;\n wire LED;\n uart_tx0 uart_tx00(\n .data(data),\n .Clk(Clk),\n .Reset(Reset),\n .uart_tx(uart_tx),\n .LED(LED)\n );\n\n //时间计数参数调小 便于测试仿真\n defparam uart_tx0.DELAY = 500000 -1;\n \n initial Clk = 0;\n always #10 Clk = ~Clk;\n \n initial begin\n Reset = 0;\n data = 0;\n #201\n Reset = 1;\n #100\n data = 8\'h57;\n #20000000;\n data = 8\'h75;\n #20000000;\n $stop;\n end\n \nendmodule\n\n```\n\n仿真波形如下:\n\n对uart发送进行优化  加入Send_GO信号  Baud_Set信号波特率设置,支持 6种,baud set为 3 位\n\n以及发送完成信号\n\n代码如下\n\n```\nmodule uart_tx_3(\n Clk,\n Reset_n,\n Data,\n Send_G0,\n Baud_Set,\n uart_tx,\n Tx_Done\n );\n input Clk; //模块全局时钟 50MHz \n input Reset_n; //模块全局复位信号\n input [7:0]Data; //待传输 8bit 数\n input Send_G0; //发送使能信号\n input [2:0]Baud_Set; //baud set 波特率设置,支持 6种,baud set为 3 位\n output reg uart_tx; //串口发送信号输出\n output reg Tx_Done; //发送结束信号,一个时钟周期高电平\n \n parameter MCNT_BIT = 10-1;\n\n //波特率\n reg [15:0]bps_DR;\n reg [15:0]div_count; //波特率计数器\n reg [3:0]bit_count;\n reg [7:0]temp_data;\n \n always@(*)\n if(!Reset_n)\n bps_DR >;= 1000000000/9600/20;\n else begin\n case(Baud_Set)\n 0:bps_DR = 1000000000/4800/20;\n 1:bps_DR = 1000000000/9600/20;\n 2:bps_DR = 1000000000/19200/20;\n 3:bps_DR = 1000000000/38400/20;\n 4:bps_DR = 1000000000/57600/20;\n 5:bps_DR = 1000000000/115200/20;\n default:bps_DR >;= 1000000000/9600/20; \n endcase\n end\n \n always@(posedge Clk or negedge Reset_n)\n if(!Reset_n)\n div_count >;= 0;\n else if (Send_G0) begin\n if(div_count == bps_DR -1)\n div_count >;= 0;\n else\n div_count >;= div_count + 1\'d1;\n end\n else\n div_count >;= 0;\n \n always@(posedge Clk or negedge Reset_n)\n if(!Reset_n)\n bit_count >;= 0;\n else if(div_count == bps_DR -1)begin\n if(bit_count == MCNT_BIT)\n bit_count >;= 0;\n else\n bit_count >;= bit_count + 1\'d1; \n end\n \n always@(posedge Clk )\n if(Send_G0)\n temp_data >;= Data;\n else\n temp_data >;= temp_data;\n \n always@(posedge Clk or negedge Reset_n)\n if(!Reset_n)\n uart_tx >;= 0;\n else begin\n case (bit_count)\n 0 : uart_tx >;= 0 ;\n 1 : uart_tx >;= temp_data[0];\n 2 : uart_tx >;= temp_data[1];\n 3 : uart_tx >;= temp_data[2];\n 4 : uart_tx >;= temp_data[3];\n 5 : uart_tx >;= temp_data[4];\n 6 : uart_tx >;= temp_data[5];\n 7 : uart_tx >;= temp_data[6];\n 8 : uart_tx >;= temp_data[7];\n 9 : uart_tx >;= 1; \n default: uart_tx >;= uart_tx; \n endcase\n end\n \n \n always@(posedge Clk or negedge Reset_n)\n if(!Reset_n)\n Tx_Done >;= 0;\n else if ((bit_count == MCNT_BIT)&& (div_count == bps_DR -1))\n Tx_Done >;= 1;\n else \n Tx_Done >;= 0;\n \nendmodule\n\n```\n\ntestbench代码:\n\n```\n`timescale 1ns / 1ps\nmodule uart_tx_3_tb();\n reg [7:0]Data;\n reg Clk;\n reg Reset_n;\n reg Send_G0;\n reg [3:0]Baud_Set;\n wire uart_tx;\n wire Tx_Done;\n uart_tx_3 uart_tx_31(\n .Clk(Clk),\n .Reset_n(Reset_n),\n .Data(Data),\n .Send_G0(Send_G0),\n .Baud_Set(Baud_Set),\n .uart_tx(uart_tx),\n .Tx_Done(Tx_Done)\n );\n \n \n initial Clk =1;\n always#10 Clk = ~Clk;\n initial begin\n Reset_n = 0;\n Data =0;\n Send_G0 = 0;\n Baud_Set = 5;\n #201\n Reset_n = 1;\n #100\n \n Data = 8\'h57;\n Send_G0 = 1;\n #20;\n @(posedge Tx_Done);\n Send_G0 = 0;\n #20000;\n \n Data = 8\'h75;\n Send_G0 = 1;\n #20;\n @(posedge Tx_Done);\n Send_G0 = 0;\n #20000;\n $stop;\n end \nendmodule\n\n```\n\n其中在testbench中  新语法 @(posedge TX_done),死循环,一直等待TX_done的到来,再执行下一语句\n\n仿真结果\n\n## 3,实现UART-接收控制器\n\n### 3.1UART串口接收逻辑分析\n\n把接收到的8位串行数据还原出8位并行数据\n\n\nuart串口来说 u有可能不是一个系统 ,两者之间仅通过一根信号线进行通信,那接收方如何恰好接收到数据呢?uart作为异步通信协议,没有同步信号来实现这些功能的。所以在通信之前,收发双方必须提前约定好各种参数(波特率,数据位个数,校验位,停止位位宽等等)![](https://www.testingcloud.club/sapi/api/image_download/c00ccb29-1adf-11ef-bbbc-00163e13fc6a.png)\n\n\n要点1:对于串口接收来说,我们应该怎么样从串行数据中准确的获取到每一位数据?要点1:对于串口接收来说,我们应该怎么样从串行数据中准确的获取到每一位数据?\n\n\n每一位数据的中点![](https://www.testingcloud.club/sapi/api/image_download/c093434e-1adf-11ef-bbbc-00163e13fc6a.png)\n\n\n 当对于数据线上的每一位进行采样时,一般情 况下认为每一位数据的中间点是最稳定的。因此一般应用中,采集中间时刻时的电平即认为 是此位数据的电平,如下图所示。\n\n但是在实际工业应用中,现场往往有非常强的电磁干扰,只采样一次就作为该数据的电 平状态是不可靠的。很有可能恰好采集到被干扰的信号而导致结果出错,因此这里提出以下 改进型的单bit数据接收方式示意图,使用多次采样求概率的方式进行状态判定,如下图所 示。\n\n 在上图中,将每一位数据再平均分成了**16**小段。对于Bit_x这一位数据,考虑到数据 在刚刚发生变化和即将发生变化的这一时期,数据极有可能不稳定的(用深灰色标出的两 段),在这两个时间段采集数据,很有可能得到错误的结果,因此判定这两段时间的电平无 效,采集时直接忽略。而中间这一时间段(用浅灰色标出),数据本身是比较稳定的,一般都代表了正确的结果。也就是前面提到的中间测量方式,但是也不排除该段数据受强电磁干 扰而出现错误的电平脉冲。因此对这一段电平,进行多次采样,并求高低电平发生的概率, 6 次采集结果中,取出现次数多的电平作为采样结果。例如,采样 6 次的结果分别为 1/1/1/1/0/1/,则取电平结果为 1,若为0/0/1/0/0/0,,则取电平结果为0,当 6次采样结果中1 和0各占一半(各3次),则可判断当前通信线路环境非常恶劣,数据不具有可靠性,不进行处理。\n\nFPGA中有专门的边沿检测电路:\n\n检测到uart信号下降沿开始   \n\n在什么时候停止呢?\n\n使用位计数器\n\n### 3.2编写代码分析** **\n\n//波特率计数器逻辑\n\n//UART信号边沿检测逻辑\n\n//波特率计数器使能逻辑\n\n//位计数器逻辑\n\n//位接收逻辑\n\n//接收完成标志信号\n\n**单 bit 异步信号同步设计**\n\n这里串口接收的信号uart_rx相对于FPGA内部信号来说是一个异步信号,如不进行处理直接将其输入使用,容易出现时序违例导致亚稳态。uart_rx信号由外界输入得到,在什么时候得到,我们无法预知和控制, 而其他信号都是由时钟信号驱动,所以uart_rx信号有可能在Clk信号上升沿很近的位置发生变化,甚至同步发生变化,就会导致D触发器无法正确存储D端口数据,无法正确有效的判断存储这个时刻的uart状态,就会引起D触发器输出震荡---->;从而产生亚稳态。\n\n因此这里就需要先将信号同步到 FPGA的时钟域内才可以供后续模块使用,常见的同步方法即使用两级触发器,也就是使 用触发器对信号打两拍的方式进行与系统时钟进行同步,参考电路即如下图所示。其中 uart_rx 为异步串口输入信号,uart_rx_sync2为同步后的信号。\n\n设计代码如下:\n\n```\nmodule uart_rx_0(\n Clk,\n Reset_n,\n uart_rx,\n Baud_Set,\n Data,\n Rx_done\n );\n input Clk;\n input Reset_n;\n input uart_rx;\n input [2:0]Baud_Set;\n output reg [7:0]Data;\n output reg Rx_done;\n \n reg [1:0]uart_rx_r;\n wire posedge_uart_rx;\n wire negedge_uart_rx; \n reg [9:0]Bps_DR; \n reg [9:0]div_count;\n reg [7:0]bit_count; //每位分成16次采样\n reg RX_EN; //检测到下降沿----发送使能 \n reg uart_rx_sync1;\n reg uart_rx_sync2;\n reg [2:0]r_data[7:0];\n reg [2:0]start_bit;\n reg [2:0]stop_bit;\n \n //异步信号转同步\n always@(posedge Clk or negedge Reset_n)\n if(!Reset_n)begin\n uart_rx_sync1 >;= 0;\n uart_rx_sync2 >;= 0;\n end\n else begin\n uart_rx_sync1 >;= uart_rx;\n uart_rx_sync2 >;= uart_rx_sync1;\n end\n \n \n //边沿检测 \n always@(posedge Clk)begin\n uart_rx_r[0] >;= uart_rx_sync2;\n uart_rx_r[1] >;= uart_rx_r[0];\n end\n assign posedge_uart_rx = (uart_rx_r == 2\'b01);\n assign negedge_uart_rx = (uart_rx_r == 2\'b10);\n //波特率设置\n always@(*)\n case(Baud_Set)\n 0: Bps_DR = 1000000000/4800/20/16 - 1;\n 1: Bps_DR = 1000000000/9600/20/16 - 1;\n 2: Bps_DR = 1000000000/19200/20/16 - 1;\n 3: Bps_DR = 1000000000/38400/20/16 - 1;\n 4: Bps_DR = 1000000000/57600/20/16 - 1;\n 5: Bps_DR = 1000000000/115200/20/16 - 1;\n default: Bps_DR = 1000000000/9600/20/16 - 1;\n endcase\n \n always@(posedge Clk or negedge Reset_n)\n if(!Reset_n)\n RX_EN >;= 0;\n else if(negedge_uart_rx)\n RX_EN >;= 1;\n// else if(Rx_done || (stop_bit >;= 4))\n else if((div_count == 1)&&(bit_count ==0)&&(uart_rx_sync2 == 1))\n RX_EN >;= 0;\n else if(Rx_done)\n RX_EN >;= 0; \n \n \n //分频计数器\n always@(posedge Clk or negedge Reset_n)\n if(!Reset_n)\n div_count >;= 0;\n else if(RX_EN) begin\n if(div_count == Bps_DR)\n div_count >;= 0;\n else\n div_count >;= div_count+ 1\'b1;\n end\n else\n div_count >;= 0;\n //位计数器 \n always@(posedge Clk or negedge Reset_n)\n if(!Reset_n) \n bit_count >;= 0;\n else if(RX_EN) begin\n if(div_count == 1)begin\n //if(bit_count == 160 -1 | bit_count == 12 && (start_bit >;2))\n if(bit_count == 159 )\n bit_count >;= 0;\n else\n bit_count >;= bit_count + 1\'b1; \n end \n end\n else\n bit_count >;= bit_count;\n \n always@(posedge Clk or negedge Reset_n)\n if(!Reset_n)begin\n start_bit >;= 0;\n r_data[0] >;= 0;\n r_data[1]>;= 0;\n r_data[2]>;= 0;\n r_data[3]>;= 0;\n r_data[4]>;= 0;\n r_data[5]>;= 0;\n r_data[6]>;= 0;\n r_data[7]>;= 0;\n stop_bit >;= 0;\n end\n else if(div_count == 1)begin\n case(bit_count)\n 0:begin\n start_bit >;= 0;\n r_data[0] >;= 0;\n r_data[1]>;= 0;\n r_data[2]>;= 0;\n r_data[3]>;= 0;\n r_data[4]>;= 0;\n r_data[5]>;= 0;\n r_data[6]>;= 0;\n r_data[7]>;= 0;\n stop_bit >;= 0;\n end\n 6,7,8,9,10,11 :start_bit >;= start_bit + uart_rx_sync2;\n 22,23,24,25,26,27:r_data[0] >;= r_data[0] + uart_rx_sync2;\n 38,39,40,41,42,43:r_data[1] >;= r_data[1] + uart_rx_sync2;\n 54,55,56,57,58,59:r_data[2] >;= r_data[2] + uart_rx_sync2;\n 70,71,72,73,74,75:r_data[3] >;= r_data[3] + uart_rx_sync2;\n 86,87,88,89,90,91:r_data[4] >;= r_data[4] + uart_rx_sync2;\n 102,103,104,105,106,107:r_data[5] >;= r_data[5] + uart_rx_sync2;\n 118,119,120,121,122,123:r_data[6] >;= r_data[6] + uart_rx_sync2;\n 134,135,136,137,138,139:r_data[7] >;= r_data[7] + uart_rx_sync2;\n 150,151,152,153,154,155:stop_bit >;= stop_bit + uart_rx_sync2;\n default:begin\n start_bit >;= start_bit;\n r_data[0] >;= r_data[0];\n r_data[1] >;= r_data[1];\n r_data[2] >;= r_data[2];\n r_data[3] >;= r_data[3];\n r_data[4] >;= r_data[4];\n r_data[5] >;= r_data[5];\n r_data[6] >;= r_data[6];\n r_data[7] >;= r_data[7];\n stop_bit >;= stop_bit ;\n end\n endcase \n end\n always@(posedge Clk or negedge Reset_n)\n if(!Reset_n)\n Data >;= 0;\n else if((div_count == 1) && (bit_count == 159)) begin\n Data[0] >;= (r_data[0] >;= 4) ? 1 : 0;\n Data[1] >;= (r_data[1] >;= 4) ? 1 : 0;\n Data[2] >;= (r_data[2] >;= 4) ? 1 : 0;\n Data[3] >;= (r_data[3] >;= 4) ? 1 : 0;\n Data[4] >;= (r_data[4] >;= 4) ? 1 : 0;\n Data[5] >;= (r_data[5] >;= 4) ? 1 : 0;\n Data[6] >;= (r_data[6] >;= 4) ? 1 : 0;\n Data[7] >;= (r_data[7] >;= 4) ? 1 : 0;\n end \n \n always@(posedge Clk or negedge Reset_n)\n if(!Reset_n) \n Rx_done >;= 0;\n else if((div_count == 1) && (bit_count == 159)) \n Rx_done >;= 1;\n else\n Rx_done >;= 0;\n \n \nendmodule\n\n```\n\n编写测试代码:\n\n```\n`timescale 1ns / 1ps\nmodule uart_rx_0_tb();\n reg Clk;\n reg Reset_n;\n reg uart_rx;\n reg [2:0]Baud_Set;\n wire [7:0]Data;\n wire Rx_done;\n\n uart_rx_0 uart_rx_0(\n .Clk(Clk),\n .Reset_n(Reset_n),\n .uart_rx(uart_rx),\n .Baud_Set(Baud_Set),\n .Data(Data),\n .Rx_done(Rx_done)\n );\n \n initial Clk = 1;\n always #10 Clk = ~Clk;\n \n initial begin\n Reset_n = 0;\n uart_rx = 1;\n #201;\n Reset_n = 1;\n Baud_Set = 5;\n #200;\n uart_tx(8\'b01110101);\n #90000;\n uart_tx(8\'b10111010);\n #90000;\n uart_tx(8\'b11100110);\n #90000;\n #2000;\n $stop;\n end\n \n task uart_tx;\n input [7:0]tx_data;\n begin\n uart_rx = 1;\n #20;\n uart_rx = 0;\n #8680;\n uart_rx = tx_data[0];\n #8680;\n uart_rx = tx_data[1];\n #8680;\n uart_rx = tx_data[2];\n #8680;\n uart_rx = tx_data[3];\n #8680;\n uart_rx = tx_data[4];\n #8680;\n uart_rx = tx_data[5];\n #8680;\n uart_rx = tx_data[6];\n #8680;\n uart_rx = tx_data[7];\n #8680;\n uart_rx = 1;\n #8680;\n end\n endtask\n\n \nendmodule\n\n```\n\n仿真波形如下:\n\n**以上实现了Uart接收模块,然后设计顶层模块----->;控制LED**\n\n代码如下:\n\n```\nmodule uart_rx_LED(\n Clk,\n Reset_n,\n uart_rx,\n LED,\n Rx_Data\n );\n \n input Clk;\n input Reset_n;\n input uart_rx;\n output reg LED;\n output Rx_Data;\n wire Rx_Done;\n uart_rx_0 uart_rx_00(\n .Clk(Clk),\n .Reset_n(Reset_n),\n .uart_rx(uart_rx),\n .Baud_Set(5),\n .Data(Rx_Done),\n .Rx_done(Rx_Done)\n );\n always@(posedge Clk or negedge Reset_n)\n if(!Reset_n)\n LED >;= 0;\n else if(Rx_Done)\n LED >;= ~LED;\nendmodule\n\n```\n\n至此,uart串口发送-接收逻辑到此结束!\n -->
0条评�?
全部评论

关于博主

an actually real engineer

通信工程专业毕业,7年开发经验

技术栈:

精通c/c++

精通golang

熟悉常见的脚本,js,lua,python,php

熟悉电路基础,嵌入式,单片机

耕耘领域:

服务端开发

嵌入式开发

git

>

gin接口代码CURD生成工具

sql ddl to struct and markdown,将sql表自动化生成代码内对应的结构体和markdown表格格式,节省宝贵的时间。

输入ddl:
输出代码:

qt .ui文件转css文件

duilib xml 自动生成绑定控件代码

协议调试器

基于lua虚拟机的的协议调试器软件 支持的协议有:

串口

tcp客户端/服务端

udp 组播/udp节点

tcp websocket 客户端/服务端

软件界面

使用例子: 通过脚本来获得接收到的数据并写入文件和展示在界面上

下载地址和源码

duilib版本源码 qt qml版本源码 二进制包

webrtc easy demo

webrtc c++ native 库 demo 实现功能:

基于QT

webrtc摄像头/桌面捕获功能

opengl渲染/多播放窗格管理

janus meeting room

下载地址和源码

源码 二进制包

wifi,蓝牙 - 无线开关

实现功能:

通过wifi/蓝牙实现远程开关电器或者其他电子设备

电路原理图:

实物图:

深度学习验证工具

vtk+pcl 点云编辑工具

实现功能:

1. 点云文件加载显示(.pcd obj stl)

2. 点云重建

3. 点云三角化

4. 点云缩放

下载地址:

源码 二进制包

虚拟示波器

硬件实物图:

实现原理

基本性能

采集频率: 取决于外部adc模块和ebaz4205矿板的以太网接口速率,最高可以达到100M/8 约为12.5MPS

上位机实现功能: 采集,显示波形,存储wave文件。

参数可运行时配置

上位机:

显示缓冲区大小可调

刷新率可调节

触发显示刷新可调节

进程守护工具

基本功能:

1. 守护进程,被守护程序崩溃后自动重启。

2. 进程输出获取,显示在编辑框中。

二进制包

openblt 烧录工具

基本功能:

1. 加载openblt 文件,下载到具有openblt bootloader 运行的单片机中。

二进制包

opencv 功能验证工具(开源项目二次开发)

基本功能:

1. 插件化图像处理流程,支持自定义图像处理流程。 2. 完善的日志和权限管理

二进制包

又一个modbus调试工具

最近混迹物联网企业,发现目前缺少一个简易可用的modbus调试工具,本软件旨在为开发者提供一个简单modbus测试工具。
主打一个代码简单易修改。
特点:

1. 基于QT5

2. 基于libmodbus

3. 三方库完全跨平台,linux/windows。

二进制包

屏幕录制工具

1. 基于QT5

2. 基于ffmpeg

3. 支持自定义录屏

源代码

开源plutosdr 板卡

1. 完全开源

2. 提高固件定制服务

3. 硬件售价450 手焊产量有线

测试数据

内部DDS回环测试

接收测试

外部发送500MHZ FM波形

硬件原理图

matlab测试

2TRX版本

大部分plutosdr应用场景都是讲plutosdr板卡作为射频收发器来使用。
实际上plutosdr板卡本身运行linux 操作系统。是具有一定脱机运算的能力。 对于一些微型频谱检测,简单射频信号收发等应用完全可以将应用层直接实现在板卡上
相较于通过网卡或者USB口传输具有更稳定,带宽更高等优点。
本开源板卡由于了SD卡启动,较原版pluto支持了自定义启动应用的功能。
提供了应用层开发SDK(编译器,buildroot文件系统)。
通过usb连接电脑,经过RNDIS驱动可以近似为通过网卡连接
(支持固件的开发定制)。

二次开发例子

``` all:
arm-linux-gnueabihf-gcc -mfloat-abi=hard --sysroot=/root/v0.32_2trx/buildroot/output/staging -std=gnu99 -g -o pluto_stream ad9361-iiostream.c -lpthread -liio -lm -Wall -Wextra -lrt
clean:
rm pluto_stream

bsdiff算法补丁生成器

1. 官方bsdiff算法例子自带bzip压缩方式

2. 本例子没有压缩,直接生成补丁文件

3. 图形化界面基于DUILIB

二进制文件

版面分析即分析出图片内的具体文件元素,如文档标题,文档内容,文档页码等,本工具基于cnstd模型

Base64 Image

. 闽ICP备19002644号