精华内容
下载资源
问答
  • 根据实际共平台通信系统的收发耦合特性,从时域角度分析得到系统干扰对消比和有用对消比的计算表达式,并得到干扰对消比和有用对消比随相对时延相位变化的规律。提出一种时延匹配方法,通过匹配参考信号提取点至正交...
  • 研究了一种改进的多级并行干扰对消算法—部分干扰对消算法(P-PIC),该算法在不增加算法复杂度的情况下能有效地提高算法性能。从干扰消除器输入的判决变量入手,从理论上分析了该算法性能的改进,并给出了计算机...
  • 分析了干扰信号非零带宽下,实际自适应干扰对消系统的频域特性和时域特性。非零带宽信号使系统时变,当带宽远小于中心频率时,系统可近似为自适应梳状滤波器。系统的平均收敛速度与总参考信号幅值成正比,干扰对消比...
  • 自己编写的matlab自适应干扰对消程序,通过互相关找匹配相位,再找对消系数
  • 压缩传感域无参考辐射干扰对消技术研究
  • 基于训练模式的自适应干扰对消技术,杨昕橙,赵忠凯,首先,本文自适应对消原理进行了阐述,分析变步长自适应对消原理及特点。其次,提出了一种新的变步长自适应对消算法,其性能
  • 一种改进的部分并行干扰对消多用户检测接收机pdf,一种改进的部分并行干扰对消多用户检测接收机
  • 针对复杂信号环境中非合作信号的电子侦察,为了提高信号的探测性能,提出了一种自适应干扰对消方法.该方法基于FPGA和DSP相结合的数字信号处理系统,通过时序控制、乒乓缓存方式和近实时的对消处理,可以适应干扰...
  • 以有效提高宽带码分多址系统容量为目的,通过理论推导的方法,得出传统双速率系统与干扰对消双速率系统的容量极限。并运用 Monte Carlo积分,理论结果进行了数值分析,得到了上述两系统在不同的扩频比、数据速率差异和...
  • 为提高雷达系统在复杂电磁环境下的抗干扰能力,雷达干扰对消系统及其自适应滤 波算法进行了分析,给出了一种改进的变步长LMS自适应滤波算法。该算法利用类Sigmoid函 数去调节步长,减少了运算量,并在类Sigmoid函数中...
  • 由于环境中存在着判决统计偏差,在一个多用户的环境中,一个PICs(并行干扰对消)系统中的加权系数的表示式,需要进一步的修正来满足环境的变化;结合自适应天线技术,在精确的获得信道知识和不精确估计这两种情况下...
  • CDMA系统中的多址干扰是影响系统性能的主要因素,提出了一种新的域变换结合参数估计抗多址干扰的算法。同文献[1]中的方法相比,在具有相似的误码率性能的基础上,具有更快的收敛性能。
  • 这是分析自适应滤波消除外部干扰的很有效的一种方法,那些研究信号处理的技术人员,学生,老师有很好的参考价值。我在实际的工程项目用使用了这种方法,取的很好的压制干扰的效果。
  • 仿真实验结果表明,多个单一极化干扰源和单个极化干扰自适应旁瓣对消雷达系统分别干扰时,闪烁干扰和极化干扰方法都存在干扰不理想的情况,因此,建议自适应旁瓣对消雷达系统实施旁瓣干扰时,采用多点干扰源...
  • 自适应直达波抑制算法分析的基础上,给出了一种基于多路径对消的直达波抑制算法:首先,利用多路径对消器把参考通道中的多路径干扰对消掉,剩余信号作为参考直达波信号;然后,在目标通道中利用该参考信号进行自适应...
  • 介绍了各类多用户检测算法,并重点分析了并行干扰算法,推导出引人多用户检测(multipleuserdetection,MUD)后HSUPA小区容量计算公式。在此基础上,分析MUD接收机的多用户检测技术HSUPA小区性能提升的影响,并通过...
  • 根据线性调频(LFM)信号群延迟特性,提出了一种针对LFM雷达的回波对消干扰算法。首先将LFM信号与其自身延迟信号的共轭相乘,用所得频率差LFM信号进行移频,然后根据目标雷达散射截面积特性进行幅度和相位调制,可...
  • 为提高雷达的抗干扰能力,首先论述了噪声调频干扰的数学模型与主要参数,采用了基于时域对消的算法抗噪声调频干扰,给出了算法的数学推导过程.该算法通过对数变换,分别由信号的实部与虚部估计出干扰信号的瞬时幅度...
  • 在连续干扰中,对干扰数据的信干功率比进行估计,若干扰频点没有受到其他信号的重叠干扰,则在相中删除,否则连续迭代,直到所有用户译码完成.对于其他模糊用户,采用简化的连续检测方法来判决.仿真结果表明...
  • 米波稀布阵雷达是一种稀疏...但由于对消过程中权系数的计算需要对强相干的接收信号进行矩阵求逆,干扰消对计算精度要求很高,同时在干扰幅度起伏严重的情况下准实时干扰对消性能存在损失,需脉冲重复周期内实时对消。
  • 移频干扰是对抗LFM雷达的一种有效干扰方法,然而常规移频干扰的载波频偏特征可能被用来识别干扰信号,为此,该文提出一种新的干扰特征隐方法。为了隐藏或者消除这个载波频偏,新方法将对干扰信号的脉宽进行一定的截短...
  • 该算法采用两组自适应干扰对消滤波器,利用LMS方法来实现对干扰信号的抑制。通过仿真,在接收端利用频谱和星座图两种途径分析了该算法对干扰信号的抑制效果。仿真结果表明,该算法在不损失带内有用信号电平的情况下...
  • 当馈线发生单相接地故障时,通过控制弧线圈所连接的电力电子开关短时投切阻尼电阻,从而产生频率成分丰富的扰动电流信号,通过在各出线中扰动电流信号进行检测和分析实现故障选线。所提方法不需要额外的信号发生...
  • 提出了一种基于变步长改进型S函数的LMS算法,仿真表明:采用该算法的旁瓣对消系统可快速有效地抑制干扰,有效提高旁瓣对消系统的实时性和稳态性能;并根据实际应用环境的需要进行了实验验证,实验数据表明:当存在...
  • 多址干扰是CDMA系统中较为突出的干扰,利用多个用户信息的干扰对消技术可以有效地抑制这种干扰,而干扰对消技术的实现需要信道的衰落估计。该文介绍了信道估计技术及多用户检测技术,并通过数值分析说明用户数及信道...
  • 借鉴公共电网地磁扰动(GMD)干扰效应的监测技术,结合我国高铁牵引供电系统的结构与接线,研究了GMD干扰高铁电气系统的物理过程与模式,设计了高铁电气系统的GMD干扰监测装置,提出了GMD产生的地磁感应电流(GIC)...
  • 根据对消后的实时功率检测结果,通过微处理器的自动搜索控制程序,调节对消估计信号的幅度和相位,最后实现对消比大于40 dB的直达波射频频段自动对消效果,有效地降低连续波雷达的强直达波的干扰
  • 波超视距雷达中,与副瓣方向一样,主瓣方向也会进入大量的干扰...本文描述了基于最小二乘估计的主瓣干扰对消技术,并该方法进行 了详细的性能分析,与已有的方法相比,具有实现简单,计算量小,干扰抑制效果好的特点
  • 基于递推最小二乘法的自适应正弦干扰对消,有Matlab和C++代码

    自适应噪声对消器的信号模型如下图所示





    Matlab代码如下:

    clear;
    clc;
    
    Ts=0.1;
    num=100;%?采样点数?
    k=1:num;
    x=10*cos(2*pi*k*Ts+0.25*pi);%正弦干扰
    %s=0.5*randn(1,num);
    %x=x+s;
    xr=cos(2*pi*k*Ts);%参考信号
    
    p=2;%滤波器长度
    xita=zeros(p,num-p+1); %保存权值
    err=zeros(1,num-p+1);  %保存误差
    kn=zeros(2,num-p+1);
    
    lamda=0.99; %遗忘因子
    diag_I=[1,0;0,1];
    for i=1:num-p+1   
        
        if i==1
            hn=[xr(1,i);0];
            corr=10^5*diag_I;        
            kn(:,1)=(corr*hn)./(lamda^i+(hn')*corr*hn);%是列向量
            err(1,i)=x(1,i)-xita(1,1)*xr(1,i);
            xita(:,i)=err(1,i).*kn(:,i);   
             corr=(diag_I-kn(:,i)*hn')*corr;
             aaa=1;
        else
           hn=[xr(1,i); xr(1,i-1)];
            kn(:,i)=(corr*hn)./(lamda^i+(hn')*corr*hn);%是列向量
          % fprintf( '%d',(lamda^i+(hn')*corr*hn));
            err(1,i)=x(1,i)-xita(:,i-1)'*hn;
           fprintf('xi=%d tmp=%d\n',x(1,i),xita(:,i-1)'*hn);
          disp(err(1,i));
            xita(:,i)=xita(:,i-1)+err(1,i).*kn(:,i);
            corr=(diag_I-kn(:,i)*hn')*corr;
            disp(corr);
        end
       
       
    end
    
    subplot(2,1,2);
    plot(k(1,1:num-p+1),xita,'r-');
    subplot(2,1,1);
    plot(k(1,1:num-p+1),err,'b-');

    C++代码如下:

    #include <stdio.h>
    #include <iostream>
    #include <stdlib.h>
    #include <math.h>
    #include <fstream>
    #include "_Matrix.h"
    
    using namespace std;
    
    const double pi = 3.14159;
    
    int main()
    {
    	cout<<"基于最小二乘自适应滤波算法的正弦信号干扰对消实验"<<endl;
    	
    	double Ts=0.1;//采样间隔
    	int num = 200;//样本点数
    	double *x=new double[num];
    	double *xr=new double[num];
    	
    	int i,j;
    	for (i=0;i<num;i++){
    		xr[i]=cos(2.0*pi*double(i+1)*Ts);//参考信号	
    	}
    	int mode;
    	cout<<"实验1:普通正弦干扰信号对消"<<endl;
    	cout<<"实验2:幅值和相位差中途变化的正弦干扰信号对消"<<endl;
    	cout<<"请输入数字1或2(若输入数字不为2,则默认进行实验1):";
    
    	cin >>mode;
    	if (mode==2){
    		for(i=0; i<num;i++){
    			if (i<=50){
    				x[i]=10*cos(2.0*pi*double(i+1)*Ts+0.25*pi);//正弦干扰
    			}
    			else{
    				x[i]=5*cos(2.0*pi*double(i+1)*Ts+0.1*pi);//正弦干扰
    			}
    		}
    	}
    	else{
    		for(i=0; i<num;i++){
    				x[i]=10*cos(2.0*pi*double(i+1)*Ts+0.25*pi);//正弦干扰	
    		}	
    	}
    	int p=2;//滤波器长度
    	_Matrix xita(p,num-p+1);
    	xita.init_matrix();
    	double *err = new double[num-p+1];//储存误差
    	//double *kn = new double[2];
    
    	double lamda = 0.99;//遗忘因子
    	_Matrix diag_I(p,p);
    	diag_I.init_matrix();
    	for (i=0;i<p; i++)
    		for (j=0;j<p;j++){
    			if (i==j)
    				diag_I.write(i,j,1);//生成对角阵,特征值为1
    		}
    
    		
    	_Matrix corr(p,p);
    	corr.init_matrix();
    	_Matrix hn(p,1);//列数据向量
    	hn.init_matrix();
    	_Matrix hn_det(1,p);//列数据向量
    	hn_det.init_matrix();
    
    
    	for (i=0;i<num-p+1;i++){
    			_Matrix kn(p,1);
    	kn.init_matrix();
    
    		_Matrix tmp11(1,1);
    		tmp11.init_matrix();
    
    		_Matrix tmp21(2,1);
    		tmp21.init_matrix();
    
    		_Matrix tmp22(2,2);
    		tmp22.init_matrix();
    		if (i==0){
    			for (j=0;j<p-1;j++){//hn[p-1]=0;
    				hn.write(j,0,xr[p-2-j]);
    				hn_det.write(0,j,xr[p-2-j]);
    			}
    
    			int ii,jj;
    			for (ii=0;ii<p; ii++)
    				for (jj=0;jj<p;jj++)
    					corr.write(ii,jj,(100000.0)*diag_I.read(ii,jj));
    			//corr.printff_matrix();
    			tmp21.multiply(&corr,&hn,&tmp21);
    			tmp11.multiply(&hn_det,&tmp21,&tmp11);
    
    			double weight = pow(lamda,i)+tmp11.read(0,0);
    			weight=1.0/weight;
    			for (ii=0;ii<p; ii++)
    				kn.write(ii,0,weight*tmp21.read(ii,0));
    
    			double kn1=kn.read(0,0);
    			double kn2=kn.read(1,0);
    			err[i]=x[i]-xita.read(0,0)*xr[0];
    
    			for (ii=0;ii<p; ii++)
    				xita.write(ii,0,err[i]*kn.read(ii,0));
    			
    			tmp22.multiply(&kn,&hn_det,&tmp22);
    			tmp22.subtract(&diag_I,&tmp22,&tmp22);
    			corr.multiply(&tmp22,&corr,&corr);
    			//corr.printff_matrix();
    			//int aaa; 正确!
    		}
    		else{
    			for (j=0;j<p;j++){//hn[j]=xr;
    				hn.write(j,0,xr[p-2-j+i]);	
    				hn_det.write(0,j,xr[p-2-j+i]);
    			}
    			//hn.printff_matrix();
    			int ii,jj;
    			//corr.printff_matrix();
    			tmp21.multiply(&corr,&hn,&tmp21);
    			//corr.printff_matrix();
    			tmp11.multiply(&hn_det,&tmp21,&tmp11);
    			double ddd=tmp11.read(0,0);
    			double weight = pow(lamda,i)+tmp11.read(0,0);
    			weight=1.0/weight;//正确
    			for (ii=0;ii<p; ii++)
    				kn.write(ii,0,weight*tmp21.read(ii,0));
    
    			//cout<<"kn"<<endl;
    			//kn.printff_matrix();//正确
    			double tmp=0;
    			//cout<<"xita"<<endl;
    			//cout<<xita.read(0,i-1)<<endl;
    			//cout<<xita.read(1,i-1)<<endl;
    			//hn.printff_matrix();
    			for(ii=0;ii<p;ii++){
    				tmp=tmp+xita.read(ii,i-1)*hn.read(ii,0);
    			}
    
    			err[i]=x[i]-tmp;
    			//cout<<"xi="<<x[i]<<"tmp="<<tmp<<endl;
    			cout<<"第"<<i<<"次迭代 err = "<<err[i]<<endl;//正确
    
    			//更新xita
    			for (ii=0;ii<p; ii++)
    				xita.write(ii, i, xita.read(ii,i-1)+err[i]*kn.read(ii,0));
    
    			tmp22.multiply(&kn,&hn_det,&tmp22);
    			tmp22.subtract(&diag_I,&tmp22,&tmp22);
    			corr.multiply(&tmp22,&corr,&corr);
    			//cout<<"corr"<<endl;
    			//corr.printff_matrix();
    			//double aaaaa=1;
    		}
    		//cout<<xita.read(0,i)<<' '<<xita.read(1,i)<<endl;
    	}
    
    	ofstream x_fs,xr_fs,err_fs,xita_fs;
    	x_fs.open("x.txt");
    	xr_fs.open("xr.txt");
    	err_fs.open("err.txt");
    	xita_fs.open("xita.txt");
    
    	for(i=0;i<num;i++){
    		x_fs <<x[i]<< endl;
    		xr_fs <<xr[i]<< endl;
    	}
    	for(i=0;i<num-p+1;i++){
    		err_fs <<err[i] <<endl;
    		for(j=0;j<p;j++){
    			xita_fs <<xita.read(j,i)<<' ';
    		}
    		xita_fs<<endl;
    	}
    	x_fs.close();
    	xr_fs.close();
    	err_fs.close();
    	xita_fs.close();
    	cout << "程序执行完毕,过程数据存储在txt文件中" << endl << endl;
    
    	system("pause");
    }

    矩阵运算的库我是在CSDN的一个博客里找的,但是我忘了作者是谁了,总之不是我写的,在这里先向作者致谢和致歉

    #ifndef _MATRIX_H
    #define _MATRIX_H
    
    //头文件
    #include <stdio.h>
    #include <stdlib.h>
    
    //矩阵数据结构
    //二维矩阵
    class _Matrix
    {
    public:
    	int m;
    	int n;
    	double *arr;
    	
    	//初始化
    	_Matrix(int mm = 0,int nn = 0);
    	//设置m
    	void set_m(int mm);
    	//设置n
    	void set_n(int nn);
    	//初始化
    	void init_matrix();
    	//释放
    	void free_matrix();
    	//读取i,j坐标的数据
    	//失败返回-31415,成功返回值
    	double read(int i,int j);
    	//写入i,j坐标的数据
    	//失败返回-1,成功返回1
    	int write(int i,int j,double val);
    	//C = A + B
    	//成功返回1,失败返回-1
    	int add(_Matrix *A,_Matrix *B,_Matrix *C);
    	//C = A - B
    	//成功返回1,失败返回-1
    	int subtract(_Matrix *A,_Matrix *B,_Matrix *C);
    	//C = A * B
    	//成功返回1,失败返回-1
    	int multiply(_Matrix *A,_Matrix *B,_Matrix *C);
    	//行列式的值,只能计算2 * 2,3 * 3
    	//失败返回-31415,成功返回值
    	double det(_Matrix *A);
    	//求转置矩阵,B = AT
    	//成功返回1,失败返回-1
    	int transpos(_Matrix *A,_Matrix *B);
    	//求逆矩阵,B = A^(-1)
    	//成功返回1,失败返回-1
    	int inverse(_Matrix *A,_Matrix *B);
    	//矩阵行扩展,C = [A B]
    	//成功返回1,失败返回-1
    	int linesExpand(_Matrix *A,_Matrix*B,_Matrix *C);
    	//矩阵列扩展,C = [A B]'
    	//成功返回1,失败返回-1
    	int rowsExpand(_Matrix *A,_Matrix*B,_Matrix *C);
    	//打印2维矩阵
    	void printff_matrix();
    };
    #endif
    

    #include "_Matrix.h"
    
    //矩阵类方法
    //初始化
    _Matrix::_Matrix(int mm,int nn)
    {
    	m = mm;
    	n = nn;
    }
    
    //设置m
    void _Matrix::set_m(int mm)
    {
    	m = mm;
    }
    
    //设置n
    void _Matrix::set_n(int nn)
    {
    	n = nn;
    }
    
    //初始化
    void _Matrix::init_matrix()
    {
    	arr = new double[m * n];
    	for(int i=0;i<m*n;i++)
    		arr[i] = 0;
    }
    
    //释放
    void _Matrix::free_matrix()
    {
    	delete []arr;
    }
    
    //读取i,j坐标的数据
    //失败返回-31415,成功返回值
    double _Matrix::read(int i,int j)
    {
    	if (i >= m || j >= n)
    	{
    		return -31415;
    	}
    	
    	return *(arr + i * n + j);
    }
    
    //写入i,j坐标的数据
    //失败返回-1,成功返回1
    int _Matrix::write(int i,int j,double val)
    {
    	if (i >= m || j >= n)
    	{
    		return -1;
    	}
    	
    	*(arr + i * n + j) = val;
    	return 1;
    }
    
    //C = A + B
    //成功返回1,失败返回-1
    int _Matrix::add(_Matrix *A,_Matrix *B,_Matrix *C)
    {
    	int i = 0;
    	int j = 0;
    	
    	//判断是否可以运算
    	if (A->m != B->m || A->n != B->n || \
    		A->m != C->m || A->n != C->n)
    	{
    		return -1;
    	}
    	//运算
    	for (i = 0;i < C->m;i++)
    	{
    		for (j = 0;j < C->n;j++)
    		{
    			C->write(i,j,A->read(i,j) + B->read(i,j));
    		}
    	}
    	
    	return 1;
    }
    
    //C = A - B
    //成功返回1,失败返回-1
    int _Matrix::subtract(_Matrix *A,_Matrix *B,_Matrix *C)
    {
    	int i = 0;
    	int j = 0;
    	
    	//判断是否可以运算
    	if (A->m != B->m || A->n != B->n || \
    		A->m != C->m || A->n != C->n)
    	{
    		return -1;
    	}
    	//运算
    	for (i = 0;i < C->m;i++)
    	{
    		for (j = 0;j < C->n;j++)
    		{
    			C->write(i,j,A->read(i,j) - B->read(i,j));
    		}
    	}
    	
    	return 1;
    }
    
    //C = A * B
    //成功返回1,失败返回-1
    int _Matrix::multiply(_Matrix *A,_Matrix *B,_Matrix *C)
    {
    	int i = 0;
    	int j = 0;
    	int k = 0;
    	double temp = 0;
    	
    	//判断是否可以运算
    	if (A->m != C->m || B->n != C->n || \
    		A->n != B->m)
    	{
    		return -1;
    	}
    	//运算
    	for (i = 0;i < C->m;i++)
    	{
    		for (j = 0;j < C->n;j++)
    		{
    			temp = 0;
    			for (k = 0;k < A->n;k++)
    			{
    				temp += A->read(i,k) * B->read(k,j);
    			}
    			C->write(i,j,temp);
    		}
    	}
    	
    	return 1;
    }
    
    //行列式的值,只能计算2 * 2,3 * 3
    //失败返回-31415,成功返回值
    double _Matrix::det(_Matrix *A)
    {
    	double value = 0;
    	
    	//判断是否可以运算
    	if (A->m != A->n || (A->m != 2 && A->m != 3))
    	{
    		return -31415;
    	}
    	//运算
    	if (A->m == 2)
    	{
    		value = A->read(0,0) * A->read(1,1) - A->read(0,1) * A->read(1,0);
    	}
    	else
    	{
    		value = A->read(0,0) * A->read(1,1) * A->read(2,2) + \
    				A->read(0,1) * A->read(1,2) * A->read(2,0) + \
    				A->read(0,2) * A->read(1,0) * A->read(2,1) - \
    				A->read(0,0) * A->read(1,2) * A->read(2,1) - \
    				A->read(0,1) * A->read(1,0) * A->read(2,2) - \
    				A->read(0,2) * A->read(1,1) * A->read(2,0);
    	}
    	
    	return value;
    }
    
    //求转置矩阵,B = AT
    //成功返回1,失败返回-1
    int _Matrix::transpos(_Matrix *A,_Matrix *B)
    {
    	int i = 0;
    	int j = 0;
    	
    	//判断是否可以运算
    	if (A->m != B->n || A->n != B->m)
    	{
    		return -1;
    	}
    	//运算
    	for (i = 0;i < B->m;i++)
    	{
    		for (j = 0;j < B->n;j++)
    		{
    			B->write(i,j,A->read(j,i));
    		}
    	}
    	
    	return 1;
    }
    
    //打印2维矩阵
    void _Matrix::printff_matrix()
    {
    	for (int i = 0;i < m;i++)
    	{
    		for (int j = 0;j < n;j++)
    		{
    			printf("%f ",*(arr + i * n + j));
    		}
    		printf("\n");
    	}
    }
    
    //求逆矩阵,B = A^(-1)
    //成功返回1,失败返回-1
    int _Matrix::inverse(_Matrix *A,_Matrix *B)
    {
    	int i = 0;
    	int j = 0;
    	int k = 0;
    	_Matrix m(A->m,2 * A->m);
    	double temp = 0;
    	double b = 0;
    	
    	//判断是否可以运算
    	if (A->m != A->n || B->m != B->n || A->m != B->m)
    	{
    		return -1;
    	}
    	
    	/*
    	//如果是2维或者3维求行列式判断是否可逆
    	if (A->m == 2 || A->m == 3)
    	{
    		if (det(A) == 0)
    		{
    			return -1;
    		}
    	}
    	*/
    	
    	//增广矩阵m = A | B初始化
    	m.init_matrix();
    	for (i = 0;i < m.m;i++)
    	{
    		for (j = 0;j < m.n;j++)
    		{
    			if (j <= A->n - 1)
    			{
    				m.write(i,j,A->read(i,j));
    			}
    			else
    			{
    				if (i == j - A->n)
    				{
    					m.write(i,j,1);
    				}
    				else
    				{
    					m.write(i,j,0);
    				}
    			}
    		}
    	}
    	
    	//高斯消元
    	//变换下三角
    	for (k = 0;k < m.m - 1;k++)
    	{
    		//如果坐标为k,k的数为0,则行变换
    		if (m.read(k,k) == 0)
    		{
    			for (i = k + 1;i < m.m;i++)
    			{
    				if (m.read(i,k) != 0)
    				{
    					break;
    				}
    			}
    			if (i >= m.m)
    			{
    				return -1;
    			}
    			else
    			{
    				//交换行
    				for (j = 0;j < m.n;j++)
    				{
    					temp = m.read(k,j);
    					m.write(k,j,m.read(k + 1,j));
    					m.write(k + 1,j,temp);
    				}
    			}
    		}
    		
    		//消元
    		for (i = k + 1;i < m.m;i++)
    		{
    			//获得倍数
    			b = m.read(i,k) / m.read(k,k);
    			//行变换
    			for (j = 0;j < m.n;j++)
    			{
    				temp = m.read(i,j) - b * m.read(k,j);
    				m.write(i,j,temp);
    			}
    		}
    	}
    	//变换上三角
    	for (k = m.m - 1;k > 0;k--)
    	{
    		//如果坐标为k,k的数为0,则行变换
    		if (m.read(k,k) == 0)
    		{
    			for (i = k + 1;i < m.m;i++)
    			{
    				if (m.read(i,k) != 0)
    				{
    					break;
    				}
    			}
    			if (i >= m.m)
    			{
    				return -1;
    			}
    			else
    			{
    				//交换行
    				for (j = 0;j < m.n;j++)
    				{
    					temp = m.read(k,j);
    					m.write(k,j,m.read(k + 1,j));
    					m.write(k + 1,j,temp);
    				}
    			}
    		}
    		
    		//消元
    		for (i = k - 1;i >= 0;i--)
    		{
    			//获得倍数
    			b = m.read(i,k) / m.read(k,k);
    			//行变换
    			for (j = 0;j < m.n;j++)
    			{
    				temp = m.read(i,j) - b * m.read(k,j);
    				m.write(i,j,temp);
    			}
    		}
    	}
    	//将左边方阵化为单位矩阵
    	for (i = 0;i < m.m;i++)
    	{
    		if (m.read(i,i) != 1)
    		{
    			//获得倍数
    			b = 1 / m.read(i,i);
    			//行变换
    			for (j = 0;j < m.n;j++)
    			{
    				temp = m.read(i,j) * b;
    				m.write(i,j,temp);
    			}
    		}
    	}
    	//求得逆矩阵
    	for (i = 0;i < B->m;i++)
    	{
    		for (j = 0;j < B->m;j++)
    		{
    			B->write(i,j,m.read(i,j + m.m));
    		}
    	}
    	//释放增广矩阵
    	m.free_matrix();
    	
    	return 1;
    }
    
    //C = [A B]
    //成功返回1,失败返回-1
    int _Matrix:: linesExpand(_Matrix *A,_Matrix*B,_Matrix *C)
    {
    	int i = 0;
    	int j = 0;
    	int k = 0;
    	int l = 0;
    	if(A->m!=B->m)
    		return -1;
    	
    	for(i=0;i<A->m;i++)
    		for(j=0;j<A->n;j++)
    			C->write(i,j,A->read(i,j));
    
    	for(i=0;i<B->m;i++)
    		for(j=0;j<B->n;j++)
    			C->write(i,j+A->n,B->read(i,j));
    
    	return 1;
    }
    
    //C = [A B]'
    //成功返回1,失败返回-1
    int _Matrix:: rowsExpand(_Matrix *A,_Matrix*B,_Matrix *C)
    {
    	int i = 0;
    	int j = 0;
    	int k = 0;
    	int l = 0;
    	if(A->n!=B->n)
    		return -1;
    	
    	for(i=0;i<A->m;i++)
    		for(j=0;j<A->n;j++)
    			C->write(i,j,A->read(i,j));
    
    	for(i=0;i<B->m;i++)
    		for(j=0;j<B->n;j++)
    			C->write(i+A->m,j,B->read(i,j));
    
    	return 1;
    }



    展开全文
  • 最近写了一个矩阵键盘抖的程序,主要是功能在于实现不中断主频抖,记录一下。 2021.2.11 之前改了一下,松开判断还是挺重要的,主要能提升用户的按键体验,被干扰触发可能是没什么问题了,但是松开时按键会大幅...

    最近写了一个矩阵键盘消抖的程序,主要是功能在于实现不中断主频消抖,记录一下。

     

    2021.2.11

    之前改了一下,松开判断还是挺重要的,主要能提升用户的按键体验,被干扰触发可能是没什么问题了,但是松开时按键会大幅抖动一下,导致按两下出现。于是设置了两个值,一个按下时间和一个松开时间。也是改到后面,脑中愈发觉得程序正在模拟一个电容按键,不同于的是前后可调。

     

    结构

    (1.0)结构图

     

     

    (1.1)结构图

     

     

     

    代码

     

    键盘按下

    
    uchar KeyTemp_Last=0,KeyN_Last=0;
    //键盘方案 2021.1.27
    //判断占空比,如果接通计数+,断开计数-,再设置两个通断限值
    //那么定时器的计数器需要能够加和减
    
    //抬起时间
    #define keyUpTime_NOM -10
    #define keyUpTime_RE -20
    #define keyUpTime (REISwitch?keyUpTime_NOM:keyUpTime_RE)
    
    //按下时间
    #define keyDownTime_NOM 8
    #define keyDownTime_RE 15
    #define keyDownTime (REISwitch?keyDownTime_NOM:keyDownTime_RE)
    
    uchar keydelay_Nstop(uchar temp)//按键不中断滤波 
    {
    	
    	static uchar keyUpWait=0;//等待抬起
    	uchar temp_return=CheckKeyState;//状态和键值
    	
    	qie[2]=100;//!!!响应误差(0.01s)	
    	if(shi[2]>0)
    	{
    		if((KeyTemp_Last|temp)!=KeyTemp_Last)//实时判断,对比数据,用或来消除杂波
    		{
    			sub[2]=1;//定时器减法
    			
    			if(keyUpWait)//按键已触发
    			{
    				if(mm[2]<=keyUpTime)//2.判断断开阈值(-)
    				KeyTemp_Last=mm[2]=shi[2]=0;
    			}
    			else if(mm[2]<=0)//1.5 按键未触发,判断接通阈值(-)
    				KeyTemp_Last=mm[2]=shi[2]=0;
    		}
    		else
    		{
    			sub[2]=0;//定时器加法
    			if(mm[2]>=shi[2])//1.判断接通阈值(+)
    			{
    				temp_return=KeyTemp_Last;
    				keyUpWait=1;
    				mm[2]=shi[2];
    			}
    		}
    	}
    	else
    	{
    		keyUpWait=0;//等待抬起
    		if(temp!=KeyDT) 
    		{
    			if((temp|0xEF)==0xEF)KeyTemp_Last=0x0F;//获取键值,一行5个
    			if((temp|0xF7)==0xF7)KeyTemp_Last=0x17;
    			if((temp|0xFB)==0xFB)KeyTemp_Last=0x1B;
    			if((temp|0xFD)==0xFD)KeyTemp_Last=0x1D;
    			if((temp|0xFE)==0xFE)KeyTemp_Last=0x1E;
    			if(KeyTemp_Last)
    			{
    			shi[2]=keyDownTime+(mo>0)*8;//!!!这里设置时间 0.01S
    			}
    		}
    		else
    			temp_return=GetKeyState;//键盘选择状态
    			
    	}
    	return temp_return;
    }

     

    主体

    uchar code T_KeyValue[]={0,5,4,9,8,7,6,1,2,3,0,10,11,12,14,13,15,16,17,18,19};
    uchar code T_KeyTemp[]={0,5,4,3,3,5,6,7,2,9,10,11,12,13,14,15,1};
    
    void KeyScan_Nstop()//按键主程序
    {
    	static uchar n=0,key=0;
    	uchar KeyValue;
    	
    	KeyValue=P2&KeyDT;//获取IO
    	KeyValue=keydelay_Nstop(KeyValue);//按键判断
    	if(KeyValue==GetKeyState)//键盘选择,滞后获取
    	{
    	if((++n)==4)n=0;
    	KeyLineOne=(n!=0);
    	KeyLineTwo=(n!=1);
    	KeyLineThr=(n!=2);
    	KeyLineFou=(n!=3);
    	}
    
    	if(KeyValue<=GotKeyState)//获得键值
    	{
    		if(keydown==0)
    		{
    		key=T_KeyValue[T_KeyTemp[(~KeyTemp_Last)&KeyDT]+n*5];//转换键值
    		Form_Key(key);
    		keydown=1;
    		}
    	}
    	else//没有键值
    	key=keydown=0;
    } 

     

    定时器 

    //***************定时器****************************
    void tm0_isr()interrupt 1		//定时器0 100T=1S
    {								
    	uchar i;						
    	TL0 = 0x00;		
    	TH0 = 0xB8;
    	
    	for(i=0;i<10;i++)
    	{
    		if(shi[i]>0)
    		{
    			if(sub[i]==0)//多数判断0,可以少一个jump
    			 mm[i]++;
    			else
    			 mm[i]--;
    
    		if(qie[i]>0) //与主程序响应误差,用倒计时模式,超过则重置检测计数
    			qie[i]--;
    		else 
    			mm[i]=0;//shi[i]=
    		}
    	}
    }

     

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 6,850
精华内容 2,740
关键字:

干扰对消