微弱信号二次谐波检测的FPGA的实现-总结
首先还是把握大的系统框架:

我要实现的部分不包括DA以及AD的转换,主要是将SSP接收到的数据送入到FIFO中,然后经过FIR带通滤波器的处理后对该信号计算幅值并做PSD,然后处理的信号经过积分够一方面送入到FIFO一方面进行均值滤波(实际上就是在一定的积分门时间内做累加操作)。最后结果通过通信模块RS232 送入到上位机,此外信号源2经过缓冲放大然后AD转换后送入到FIFO,也是通过RS232送入到上位机。
二次谐波幅值计算
先计算二次谐波幅值。
二次谐波的计算主要利用的是正余弦信号的周期性;信号经FIR带通滤波后主要含有8kHz的二次谐波,可用公式表示为
(4.5.1)
其中,是二次谐波幅值,,
将各次采样的点编号为1,2,3,4,5,6,7,8,那么这8采样的表达式的相位之间满足相差90度
A/D转换器的采样频率为64kHz而二次谐波频率为8kHz,即一个周期采样8个点,所以有
A0^2+A2^2=A^2,而且A1^2+A3^2=A^2;
通过40次定时中断采样40个点,32阶的FIR带通滤波器滤波后的最后8个点作为计算二次谐波幅值的数据点,因此可求得二次谐波幅值实际上就是这8次采样点的数据分别平方求和以后开根号,然后除以2(右移一位)来实现的
检波与积分反馈
在调试试验阶段预先调整好传感器输出信号与定时器匹配输出的8kHz检波信号同相(通过设置定时器计数器的初值),而设计的FIR带通滤波器不改变8kHz二次谐波的相位,在以后的测量中通过检波程序判断这两个信号是否还同相,就可知道所测信号的方向。
具体检波过程:在二次谐波的一个周期8个点内,找出最大值x[count],如果对应的检波信号c[count]为1(同相)则信号为正,如果c[count]为0(反相)则信号为负。
系统的积分是对每次计算出的二次谐波幅值进行累加求和。本系统反馈的是8K的幅值。假定幅值也是有正负的,当通过检波判断信号为正时幅值也为正,反之为负。每循环一次,计算一次二次谐波幅值,接着进行累加,然后把累加量通过D/A转换器反馈出去,直至使二次谐波幅值小于一个很小的预定值反馈才中止。此时,最后一次反馈的积分值可代表信号大小与方向。
理想情况下,预定值为0,实际情况中预定值不可能设置为0,否则系统一直反馈下去。增大预定值可以减小每次测量的反馈次数,从而使系统的测量时间更短,但是预定值也不能太大,否则积分值不能真实反映实际大小。预定值大小可以在调试程序过程中根据系统要求进行选择。
总结:这里边涉及到的主要的FPGA设计的关键部分主要有
1)多个输入的平方和开根号的问题(cordic算法来实现开根号的处理)
2)FIR带通滤波器的FPGA实现()
3)SPI传输信号的FPGA实现(FPGA作为主机,往从机发送数据的过程)
4)系统在门控时间内积分的实现(累加的过程实际上可以达到均值滤波的效果)
5)FIFO做数据缓冲模块的实现。(主要用在AD转换以及DA转换的时候两个不同类型之间的数据的缓冲的问题)
关于cordic实现求幅值的计算(开方根)
module cordic
(
//input signals
clk,
rst,
Data_i,
Data_q,
//output signals
Z_valid,
Magnitude,
y,
Phase
); /*****************************************************/
/*------- Input and Output Ports declaration --------*/
/*****************************************************/
input clk;
input rst;
input [:] Data_i;
input [:] Data_q; output Z_valid;
output [:] Magnitude;
output [:] Phase;
output [:] y;
/*****************************************************/
/*------- Ports Type declaration --------*/
/*****************************************************/
reg Z_valid;
reg [:] Magnitude;
wire [:] Phase;
reg [:] y;
/*****************************************************/
/*------- Parameters declaration --------*/
/*****************************************************/ parameter Coef0 = 'h20000; //arctan(1/2^0 ) = 45
parameter Coef1 = 'h12e40; //arctan(1/2^1 ) = 26.565051
parameter Coef2 = 'h09fb4; //arctan(1/2^2 )
parameter Coef3 = 'h05111; //arctan(1/2^3 )
parameter Coef4 = 'h028b1; //arctan(1/2^4 )
parameter Coef5 = 'h0145d; //arctan(1/2^5 )
parameter Coef6 = 'h00a2f; //arctan(1/2^6 )
parameter Coef7 = 'h00518; //arctan(1/2^7 )
parameter Coef8 = 'h0028c; //arctan(1/2^8 )
parameter Coef9 = 'h00146; //arctan(1/2^9 )
parameter Coef10 = 'h000a3; //arctan(1/2^10)
parameter Coef11 = 'h00051; //arctan(1/2^11)
parameter Coef12 = 'h00029; //arctan(1/2^12)
parameter Coef13 = 'h00014; //arctan(1/2^13)
parameter Coef14 = 'h0000a; //arctan(1/2^14)
parameter Coef15 = 'h00005; //arctan(1/2^15)
parameter Coef16 = 'h00003; //arctan(1/2^16)
parameter Coef17 = 'h00001; //arctan(1/2^17) /*****************************************************
---- Variable declaration
*****************************************************/
reg [:] Cnt; wire [:] Data_i_inv;
wire [:] Data_q_inv; reg [:] X_in_reg;
reg [:] Y_in_reg; reg [:] Data_in_reg; wire [:] X_in[:];
wire [:] Y_in[:];
wire [:] Z_in[:];
wire [:] a_in[:]; wire [:] X_out[:];
wire [:] Y_out[:];
wire [:] Z_out[:]; reg [:] Phase_reg0;
reg [:] Phase_reg1;
wire [:] Phase_carry;
reg [:] Magnitude_reg; /*****************************************************/
/*------- Main Code --------*/
/*****************************************************/ assign a_in[ ] = Coef0;
assign a_in[ ] = Coef1;
assign a_in[ ] = Coef2;
assign a_in[ ] = Coef3;
assign a_in[ ] = Coef4;
assign a_in[ ] = Coef5;
assign a_in[ ] = Coef6;
assign a_in[ ] = Coef7;
assign a_in[ ] = Coef8;
assign a_in[ ] = Coef9;
assign a_in[] = Coef10;
assign a_in[] = Coef11;
assign a_in[] = Coef12;
assign a_in[] = Coef13;
assign a_in[] = Coef14;
assign a_in[] = Coef15;
assign a_in[] = Coef16;
assign a_in[] = Coef17; always @ ( posedge clk or posedge rst )
begin
if ( rst )
Cnt <= 'b0;
else if ( Cnt < 'd20 )
Cnt <= Cnt + 'b1;
else
;
end always @ ( posedge clk or posedge rst )
begin
if ( rst )
Z_valid <= 'b0;
else if ( Cnt >= 'd20 )
Z_valid <= 'b1;
else
Z_valid <= 'b0;
end genvar i;
generate
for ( i = ; i < ; i = i + )
begin : U_Cordic_pipe
cordic_pipe cordic_pipe
(//input signals
.clk ( clk ),
.rst ( rst ),
.X_in ( X_in[i] ),
.Y_in ( Y_in[i] ),
.Z_in ( Z_in[i] ),
.Iteration ( a_in[i] ),
.Shiftbit ( i ),
//output signals
.X_out ( X_out[i] ),
.Y_out ( Y_out[i] ),
.Z_out ( Z_out[i] )
);
end
endgenerate assign Data_i_inv = ~Data_i + 'b01;
assign Data_q_inv = ~Data_q + 'b01; always @ ( posedge clk or posedge rst )
begin
if ( rst )
begin
X_in_reg <= 'b0;
Y_in_reg <= 'b0;
end
else if ( Data_q[] == 'b1 )
begin
X_in_reg <= { {{Data_q_inv[]}}, Data_q_inv };
Y_in_reg <= { {{Data_i[]}}, Data_i };
end
else
begin
X_in_reg <= { {{Data_q[]}}, Data_q };
Y_in_reg <= { {{Data_i_inv[]}}, Data_i_inv };
end
end assign Z_in[] = 'b0;
assign X_in[] = X_in_reg;
assign Y_in[] = Y_in_reg; genvar j;
generate
for ( j = ; j < ; j = j + )
begin : XYZ_IN
assign X_in[j] = X_out[j-];
assign Y_in[j] = Y_out[j-];
assign Z_in[j] = Z_out[j-];
end
endgenerate always @ ( posedge clk or posedge rst )
begin
if ( rst )
Data_in_reg[] = 'b0;
else
Data_in_reg[] = Data_q[];
end genvar k;
generate
for ( k = ; k < ; k = k + )
begin : Rotate_back
always @ ( posedge clk or posedge rst )
begin
if ( rst == 'b1 )
Data_in_reg[k] <= 'b0;
else
Data_in_reg[k] <= Data_in_reg[k-];
end
end
endgenerate always @ ( posedge clk or posedge rst )
begin
if ( rst )
Phase_reg0 <= 'b0;
else if ( Data_in_reg[] == 'b0 )
Phase_reg0 <= { Z_out[][], Z_out[] } + 'h40000;
else
Phase_reg0 <= { Z_out[][], Z_out[] } - 'h40000;
end assign Phase_carry = ( Phase_reg0[] == 'b0 ) ? ( Phase_reg0 + 21'b010 ) : ( Phase_reg0 + 'b00001 ); always @ ( posedge clk or posedge rst )
begin
if ( rst)
Phase_reg1 <= 'b0;
else if ( ( Phase_carry[:] == 'b00 ) || ( Phase_carry[20:19] == 2'b11 ) )
Phase_reg1 <= Phase_carry[:];
else if ( Phase_carry[] == 'b0 )
Phase_reg1 <= 'h3ffff;
else
Phase_reg1 <= 'h20000;
end assign Phase = ( Z_valid == 'b1 ) ? Phase_reg1 : 18'b0; always @ ( posedge clk or posedge rst )
begin
if ( rst )
Magnitude_reg <= 'b0;
else
begin
Magnitude_reg <= X_out[][:];
y <=Y_out[][:];
end
end always @ ( posedge clk or posedge rst )
begin
if ( rst)
Magnitude <= 'b0;
else
Magnitude <= Magnitude_reg;
end endmodule module cordic_pipe
(
//input signals
clk,
rst,
X_in,
Y_in,
Z_in,
Iteration,
Shiftbit,
//output signals
X_out,
Y_out,
Z_out
); /*****************************************************/
/*------- Input and Output Ports declaration --------*/
/*****************************************************/
input clk;
input rst;
input [:] X_in;
input [:] Y_in;
input [:] Z_in;
input [:] Iteration;
input [:] Shiftbit; output [:] X_out;
output [:] Y_out;
output [:] Z_out; /*****************************************************/
/*------- Ports Type declaration --------*/
/*****************************************************/
reg [:] X_out;
reg [:] Y_out;
reg [:] Z_out; wire [:] X_in_shift;
wire [:] Y_in_shift; /*****************************************************
---- Variable declaration
*****************************************************/ /*****************************************************/
/*------- Main Code --------*/
/*****************************************************/ cordic_shift U_cordic_shift
(
.X_in ( X_in ),
.Y_in ( Y_in ),
.Shiftbit ( Shiftbit ), .X_in_shift ( X_in_shift ),
.Y_in_shift ( Y_in_shift )
); always @ ( posedge rst or posedge clk )
begin
if( rst )
begin
X_out <= 'b0;
Y_out <= 'b0;
Z_out <= 'b0;
end
else if ( Y_in[] == 'b0 )
begin
X_out <= X_in + Y_in_shift;
Y_out <= Y_in - X_in_shift;
Z_out <= Z_in + Iteration;
end
else
begin
X_out <= X_in - Y_in_shift;
Y_out <= Y_in + X_in_shift;
Z_out <= Z_in - Iteration;
end
end endmodule module cordic_shift
(
//input signals
X_in,
Y_in,
Shiftbit,
//output signals
X_in_shift,
Y_in_shift
); /*****************************************************/
/*------- Input and Output Ports declaration --------*/
/*****************************************************/
input [:] X_in;
input [:] Y_in;
input [:] Shiftbit; output [:] X_in_shift;
output [:] Y_in_shift; /*****************************************************/
/*------- Ports Type declaration --------*/
/*****************************************************/ reg [:] X_in_shift;
reg [:] Y_in_shift; always @ ( X_in or Shiftbit )
begin
case ( Shiftbit )
'b0 : X_in_shift = X_in;
'd1 : X_in_shift = { {1{X_in[19]}}, X_in[19:1] };
'd2 : X_in_shift = { {2{X_in[19]}}, X_in[19:2] };
'd3 : X_in_shift = { {3{X_in[19]}}, X_in[19:3] };
'd4 : X_in_shift = { {4{X_in[19]}}, X_in[19:4] };
'd5 : X_in_shift = { {5{X_in[19]}}, X_in[19:5] };
'd6 : X_in_shift = { {6{X_in[19]}}, X_in[19:6] };
'd7 : X_in_shift = { {7{X_in[19]}}, X_in[19:7] };
'd8 : X_in_shift = { {8{X_in[19]}}, X_in[19:8] };
'd9 : X_in_shift = { {9{X_in[19]}}, X_in[19:9] };
'd10 : X_in_shift = { {10{X_in[19]}}, X_in[19:10] };
'd11 : X_in_shift = { {11{X_in[19]}}, X_in[19:11] };
'd12 : X_in_shift = { {12{X_in[19]}}, X_in[19:12] };
'd13 : X_in_shift = { {13{X_in[19]}}, X_in[19:13] };
'd14 : X_in_shift = { {14{X_in[19]}}, X_in[19:14] };
'd15 : X_in_shift = { {15{X_in[19]}}, X_in[19:15] };
'd16 : X_in_shift = { {16{X_in[19]}}, X_in[19:16] };
'd17 : X_in_shift = { {17{X_in[19]}}, X_in[19:17] };
default : X_in_shift = 'b0;
endcase
end always @ ( Y_in or Shiftbit )
begin
case ( Shiftbit )
'b0 : Y_in_shift = Y_in;
'd1 : Y_in_shift = { {1{Y_in[19]}}, Y_in[19:1] };
'd2 : Y_in_shift = { {2{Y_in[19]}}, Y_in[19:2] };
'd3 : Y_in_shift = { {3{Y_in[19]}}, Y_in[19:3] };
'd4 : Y_in_shift = { {4{Y_in[19]}}, Y_in[19:4] };
'd5 : Y_in_shift = { {5{Y_in[19]}}, Y_in[19:5] };
'd6 : Y_in_shift = { {6{Y_in[19]}}, Y_in[19:6] };
'd7 : Y_in_shift = { {7{Y_in[19]}}, Y_in[19:7] };
'd8 : Y_in_shift = { {8{Y_in[19]}}, Y_in[19:8] };
'd9 : Y_in_shift = { {9{Y_in[19]}}, Y_in[19:9] };
'd10 : Y_in_shift = { {10{Y_in[19]}}, Y_in[19:10] };
'd11 : Y_in_shift = { {11{Y_in[19]}}, Y_in[19:11] };
'd12 : Y_in_shift = { {12{Y_in[19]}}, Y_in[19:12] };
'd13 : Y_in_shift = { {13{Y_in[19]}}, Y_in[19:13] };
'd14 : Y_in_shift = { {14{Y_in[19]}}, Y_in[19:14] };
'd15 : Y_in_shift = { {15{Y_in[19]}}, Y_in[19:15] };
'd16 : Y_in_shift = { {16{Y_in[19]}}, Y_in[19:16] };
'd17 : Y_in_shift = { {17{Y_in[19]}}, Y_in[19:17] };
default : Y_in_shift = 'b0;
endcase
end endmodule
微弱信号二次谐波检测的FPGA的实现-总结的更多相关文章
- 利用过采样技术提高ADC测量微弱信号时的分辨率
1. 引言 随着科学技术的发展,人们对宏观和微观世界逐步了解,越来越多领域(物理学.化学.天文学.军事雷达.地震学.生物医学等)的微弱信号需要被检测,例如:弱磁.弱光.微震动.小位移.心电.脑电等[1 ...
- 【原创】MHA二次检测功能测试
MHA提供了很多扩展的功能,其中有一个参数是secondary_check_script,这个参数可以使我们自定义扩展多路由,多链路的二次检测功能.减少网络故障切换,降低脑裂的发生. 在虚拟机上做了如 ...
- 边沿检测方法-FPGA入门教程
本节实验主要讲解FPGA开发中边沿检测方法,我们在设计中会经常用到.这个地方大家一定要理解. 1.1.1.原理介绍 学习HDL语言设计与其他语言不一样,HDL语言设计需要考虑更多的信号的电气特性,时序 ...
- ECG信号读出,检测QRS,P,T 波(小波去噪,并根据检测),基于BP辨识的神经网络
这学期的课程选择神经网络.最后的作业处理ECG信号,并利用神经网络识别. 1 ECG引进和阅读ECG信号 1)ECG介绍 详细ECG背景应用就不介绍了,大家能够參考百度 谷歌.仅仅是简单说下ECG ...
- Python公众号开发(二)—颜值检测
上篇文章,我们把自己的程序接入了微信公众号,并且能把用户发送的文本及图片文件原样返回.今天我们把用户的图片通过腾讯的AI平台分析后再返回给用户. 为了防止我的文章被到处转载,贴一下我的公众号[智能制造 ...
- AI佳作解读系列(二)——目标检测AI算法集杂谈:R-CNN,faster R-CNN,yolo,SSD,yoloV2,yoloV3
1 引言 深度学习目前已经应用到了各个领域,应用场景大体分为三类:物体识别,目标检测,自然语言处理.本文着重与分析目标检测领域的深度学习方法,对其中的经典模型框架进行深入分析. 目标检测可以理解为是物 ...
- 视频场景切换检测的FPGA实现
本文将继续讲述图像处理算法的FPGA实现,后续可能更新图像旋转(1080P).画中画.快速DCT等算法.视频场景切换检测常用于视频编解码领域,我选用的算法是双阈值灰度直方图检测法,起初在MATLAB上 ...
- 谈谈MySQL死锁之二 死锁检测和处理源码分析
这一篇主要是通过一个实验来进行描述,过程是比较枯燥的. 实验准备 create table test_lock(id int auto_increment primary key ,stock int ...
- Netty实践二(心跳检测)
我们使用Socket通信一般经常会处理多个服务器之间的心跳检测,一般来讲,我们去维护服务器集群,肯定要有一台或几台服务器主机(Master),然后还应该有N台(Slave),那么我们的主机肯定要时时刻 ...
随机推荐
- 如何编译生成 mkfs.ubifs、ubinize 工具
参考文档: 1.<CoM335X linux开发指南.pdf>的附件1 2.ubifs的制作,移植的重点详解(使用交叉编译器) 3.UBIFS文件系统简介 与 利用mkfs.ubifs和u ...
- Spring原理系列一:Spring Bean的生命周期
一.前言 在日常开发中,spring极大地简化了我们日常的开发工作.spring为我们管理好bean, 我们拿来就用.但是我们不应该只停留在使用层面,深究spring内部的原理,才能在使用时融汇贯通. ...
- Vue.js 之 过渡动画
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- windows 10 远程连接出现CredSSP加密Oracle修正错误
以下方法只受用于windows专业版或者企业版 . 解决方法: 运行 gpedit.msc 本地组策略: 计算机配置>管理模板>系统>凭据分配>加密Oracle修正 选择启用并 ...
- 视觉slam十四讲个人理解(ch7视觉里程计1)
参考博文::https://blog.csdn.net/david_han008/article/details/53560736 https://blog.csdn.net/n66040927/ar ...
- js中要声明变量吗?
你好,js语言是弱类型语言,无需申明即可直接使用,默认是作为全局变量使用的.建议:在function里时应使用var 申明变量,这样改变量仅仅只在function的生存周期内存在,不会污染到,全局控件 ...
- 吴裕雄--天生自然 PHP开发学习:MySQL 预处理语句
<?php $servername = "localhost"; $username = "root"; $password = "admin& ...
- centos 部署WGCLOUD
服务端: 一.安装jdk 1.查看安装配置 jdk: 命令:java -version 2.查看系统是否自带 jdk rpm -qa |grep java rpm -qa |grep jdk rp ...
- thrift生成c++服务端和客户端
https://blog.csdn.net/jdx0909/article/details/84727523 https://blog.csdn.net/luoyexuge/article/detai ...
- Linux之程序的开始和结束
1.main函数由谁来调用 (1).编译链接时的引导代码. 操作系统下的应用程序其实是在main函数执行前也需要先执行一段引导代码才能去执行main函数,我们写应用程序时不用考虑引导代码的问题,编译链 ...