1.Jscop软件可以通过jlink以波形方式打印出变量。
2.安装好Segger-Jlink软件,安装好的软件如下图所示
在安装的目录下找到RTT源码,RTT源码路径如下图所示:
3.将RTT源码添加入KEIL工程目录中,并添加头文件和初始化函数
添加头文件: #include "SEGGER_RTT.h"
添加初始化函数:SEGGER_RTT_ConfigUpBuffer(1, "JScope_u2u2u2", buf, 2048, SEGGER_RTT_MODE_NO_BLOCK_SKIP);
初始化函数中u2u2u2 代表打印3个uint16型数据。
添加好的keil工程如下图所示。
4.在工程中添加要打印的数据,
打印函数为:SEGGER_RTT_Write(1,&dd[i], 2);
5.打开Jscop软件,选择新建工程
6.选择目标芯片型号
7.选择目标接口、速度和打印方式
这里我们选择SWD接口,因为我的jlink是隔离型的SWD接口,我们选择打印速度是单片机ADC采集速度的两倍,我这个jlink最高打印速度是9600K,购买连接如下。
/*******************************以下是广告*************************************/
/**********************************************************************************/
8.打印波形展示如下图:
9.上图展示的是采集的电机的电流波形,
图中绿色为原始电机的电流波形,黄色为卡尔曼参数滤波,蓝色为卡尔曼1参数滤波。
从图中可以看出调整卡尔曼滤波Q和R的值可以得出不同的滤波效果。
卡尔曼滤波源代码如下:
typedef struct
{
float LastP;//上次估算协方差 初始化值为0.02
float Now_P;//当前估算协方差 初始化值为0
float out;//卡尔曼滤波器输出 初始化值为0
float Kg;//卡尔曼增益 初始化值为0
float Q;//过程噪声协方差 初始化值为0.001
float R;//观测噪声协方差 初始化值为0.543
}KFP;//Kalman Filter parameter
//2.
KFP KFP_height1={0.02,0,0,0,0.01,0.8};
KFP KFP_height ={0.00,0,0,0,0.05,0.4};
/**
*卡尔曼滤波器
*@param KFP *kfp 卡尔曼结构体参数
* float input 需要滤波的参数的测量值(即传感器的采集值)
*@return 滤波后的参数(最优值)
*/
float kalmanFilter(KFP *kfp,float input)
{
//预测协方差方程:k时刻系统估算协方差 = k-1时刻的系统协方差 + 过程噪声协方差
kfp->Now_P = kfp->LastP + kfp->Q;
//卡尔曼增益方程:卡尔曼增益 = k时刻系统估算协方差 / (k时刻系统估算协方差 + 观测噪声协方差)
kfp->Kg = kfp->Now_P / (kfp->Now_P + kfp->R);
//更新最优值方程:k时刻状态变量的最优值 = 状态变量的预测值 + 卡尔曼增益 * (测量值 - 状态变量的预测值)
kfp->out = kfp->out + kfp->Kg * (input -kfp->out);//因为这一次的预测值就是上一次的输出值
//更新协方差方程: 本次的系统协方差付给 kfp->LastP 威下一次运算准备。
kfp->LastP = (1-kfp->Kg) * kfp->Now_P;
return kfp->out;
}
void main(void)
{
uint16_t tempdate[3];
uint8_t i;
(void)ReadCurrentADVal(&tempdate[1]);//读取电机电流
tempdate[0]=kalmanFilter(&KFP_height,(float)tempdate[1]);//卡尔曼滤波
tempdate[2]=kalmanFilter(&KFP_height1,(float)tempdate[1]);//卡尔曼滤波1
for(i=0;i<3;i++)
SEGGER_RTT_Write(1, &tempdate[i], 2);//打印波形
}