PID

基本公式

kp,ki,kd

在离散化的系统中,kp是误差,ki积分是误差的累加,kd微分当前误差与之前误差的差

P,I,D分别是输出

PID算法的输出是控制量

Kpe(k)
Kd
(e((k)-e(k-1)),D的作用是为了给系统一个阻尼

K1Kie(Kn),

若果是再有负载的情况下,比如电机要带动某个东西的情况下,很有可能会出现PID输出和消耗抵消了

K1就是,使得系统没法达到目标值为了实现在某些情况下加入I,某些情况下不加入I,

I的作用是对P的一个补充作用,但不能让I不断的累加,必须有一个累加的最大值,因为累加过大,会让积分量太大,会出现一个跳变,难以控制

PID调试原则

在输出不震荡时,增大比例系数P

在输出不震荡时,减小积分系数Ki

在输出不震荡时,增大微分系数Kd

pythonk步差分 p阶差分和k步差分的区别_嵌入式硬件

//结构体部分
typedef struct
{
	uint8_t enable 					: 1;	//输出使能
	uint8_t enable_lim_sum_error	: 1;	//积分限幅使能
	uint8_t enable_lim_ouput		: 1;	//输出限幅使能
	uint8_t count					: 4;	
	double kp;  			//比例参数
	double ki;  			//积分参数
	double kd;  			//微分参数

	double lim_sum_error;	//误差积分限幅	
	double lim_output;		//输出限幅 防止输出过大

	double sum_error;		//误差积分
	double last_error;		//上一次的误差
	double last_last_error;	//上上一次的误差
	
	double kd_output;
	double ki_output;
	double kp_output;
	double error_dec;

	double pid_output;
	double error;
} PID_HANDLE, *P_PID_HANDLE;

//代码运算部分
double pidProcess(P_PID_HANDLE phdl, double input, double measure)
{
	double output = 0;
	double error = input - measure;         //计算误差

	phdl->sum_error += error;

	//误差积分限幅
	if(phdl->enable_lim_sum_error == 1 && fabs(phdl->sum_error) > phdl->lim_sum_error)
	{
		if(phdl->sum_error > 0)
			phdl->sum_error = phdl->lim_sum_error;
		else
			phdl->sum_error = -phdl->lim_sum_error;
	}

	output =        phdl->kp * error
				+   phdl->ki * phdl->sum_error
				+   phdl->kd * (error - phdl->last_error) ;
		phdl->kp_output = phdl->kp * error;
		phdl->ki_output = phdl->ki * phdl->sum_error;
		phdl->kd_output = phdl->kd * (error - phdl->last_error);

		phdl->error_dec = error - phdl->last_error;
		
	//输出限幅
	if(phdl->enable_lim_ouput == 1 && fabs(output) > phdl->lim_output)
	{
		if(output > 0)
			output = phdl->lim_output;
		else
			output = -phdl->lim_output;
	}

	//更新误差值
	phdl->last_error = error;

	//是否使能输出
	if(phdl->enable == 1)
	{
		phdl->pid_output = output;
		return output;
	}
	else
	{
		phdl->pid_output = 0;
		return 0;
	}
}

卡尔曼滤波

在含有 不确定信息 的动态系统中使用卡尔曼滤波,对系统下一步走向做出 有根据的预测 ,既是伴随各种干扰,卡尔曼滤波总能指出真实发生的事情。
连续变化的系统中使用卡尔曼滤波是非常理想的,它具有占用内存小的有点(除了前一个状态量外,不需要保留其它历史数据),并且速度很快,很适合应用于实时问题和嵌入式系统。
它是一种结合先验经验、测量更新的状态估计算法。

一阶低通滤波算法

Y(n)=αX(n) + (1-α)Y(n-1)
式中:
α=滤波系数;
X(n)=本次采样值;
Y(n-1)=上次滤波输出值;
Y(n)=本次滤波输出值。
一阶低通滤波法采用本次采样值与上次滤波输出值进行加权,得到有效滤波值,使得输出对输入有反馈作用。

#define a   0.01                // 滤波系数a(0-1) 

char filter(void)
{
    baroOffset  = get_ad(); 
    baro = a * baroOffset  + (1.0f - a) * baroAlt;
    baroAlt = baro;
    return baro;  
}

一阶滤波算法的不足
  滤波系数越小,滤波结果越平稳,但是灵敏度越低;
  滤波系数越大,灵敏度越高,但是滤波结果越不稳定。
  一阶滤波无法完美地兼顾灵敏度和平稳度。有时,我们只能寻找一个平衡,在可接受的灵敏度范围内取得尽可能好的平稳度。而在一些场合,我们希望拥有这样一种接近理想状态的滤波算法。
  即:
  当数据快速变化时,滤波结果能及时跟进(灵敏度优先);
当数据趋于稳定,在一个固定的点上下振荡时,滤波结果能趋于平稳(平稳度优先)。
Y(n)是逐渐向X(n)靠近,滤波系数越大靠近得越快

IIC

I2C(Inter-Integrated Circuit) 是内部整合电路的称呼, 是一种串行通讯总线, 使用多主从架构用以连接低速周边装置而发展
CPU 与被控 IC 之间IC 与 IC 之间进行双向传送, 高速 IIC 总线一般可达 400kbps 以上。
I2C 总线在传送数据过程中共有三种类型信号, 它们分别是:开始信号结束信号应答信号

1、开始信号: SCL 为高电平时, SDA 由高电平向低电平跳变,开始传送数据。
2、结束信号: SCL 为高电平时, SDA 由低电平向高电平跳变,结束传送数据。
3、应答信号:接收数据的 IC 在接收到 8bit 数据后,向发送数据的 IC 发出特定的低电平脉冲,
表示已收到数据。 CPU 向受控单元发出一个信号后,等待受控单元发出一个应答信号, CPU 接
收到应答信号后,根据实际情况作出是否继续传递信号的判断。若未收到应答信号,由判断为
受控单元出现故障。
这些信号中,起始信号是必需的,结束信号和应答信号, 都可以不要。
串行数据线SDA——负责在设备间传输串行数据 
串行时钟线SCL——负责产生同步时钟脉冲

SPI

SPI全称是Serial Perripheral Interface,也就是串行外围设备接口。SPI是Motorola公司推出的一种同步串行接口技术,是一种高速,全双工的同步通信总线。SPI时钟频率相比IIC要高很多,最高可以工作在上百MHZ。
SPI以主从方式工作,通常是有一个主设备和一个或多个从设备,一般SPI需要4根线,但是也可以使用三根线(单向传输),这四根线如下:
1,CS/SS,Slave Select/Chip Select,这个是片选信号线,用于选择需要进行通信的从设备。IIC主机是通过发送从机设备地址来选择需要进行通信的从机设备的,而SPI主机不需要发送从机设备地址,直接将相应的从机设备片选信号拉低即可。
(片选信号,指的是传统南北桥架构的主板中,地址线和数据线分开的BIOS芯片里的22脚的那个信号。)
地址线是用来传输地址信息用的
举个简单的例子:cpu在内存或硬盘里面寻找一个数据时,先通过地址线找到地址,然后再通过数据线将数据取出来。 如果有32根.就可以访问2的32次方的空间,也就是4GB
也就是说,地址线一次确定一个存储单元,地址线上值可能取的所有组合确定了存储单元的个数。所以,存储单元的个数=2^地址线的条数。我们常说的存储容量就是指存储单元的个数。
20根地址线寻址范围是多少?如何运算的? 如果是按照字节编址的,寻址范围就是1MB。 计算方法就是2的20次方
一个存储单元占一个字节。字节可以用来计量存储容量
所以内存容量=4GB=4*(2^10)* (210)*(210)=2^32Byte 因为一个存储单元占用一个字节,所以存储单元个数为2^32 所以地址线条数是32
数据线
英文:data access,其作用是来连接移动设备和电脑的,来达到数据通路的目的。
数据线确定存储字长 数据线有多少条,字长就是多少位。字长是32位 则1字=32bit=4B 则表明处理器一次可以处理4个存储单元 指令长度为4个存储单元。

试题
若内存容量为4GB,字长为32,则( )
A.地址总线和数据总线的宽度都为32
B.地址总线的宽度为30,数据总线的宽度为32
C.地址总线的宽度为30,数据总线的宽度为8
D.地址总线的宽度为32,数据总线的宽度为8
试题答案:A

2,SCK,Serial Clock,串行时钟,和IIC的SCL一样,为SPI通信提供时钟。
3,MOSI/SDO,Master Out Slave In/Serial Data Output,简称主出从入信号线,这根数据线只能用于主机向从机发送数据,也就是主机输出,从机输入。
4,MISO/SDI,Master In Slave Out/Serial Data Input,简称主入从出信号线,这根数据线只能用户从机向主机发送数据,也就是主机输入,从机输出。

UART

UART 在发送或接收过程中的一帧数据由4部分组成,起始位、数据位、奇偶校验位和停止位,如图所示。其中,起始位标志着一帧数据的开始,停止位标志着一帧数据的结束,数据位是一帧数据中的有效数据。

校验位分为奇校验和偶校验,用于检验数据在传输过程中是否出错。

奇校验时,发送方应使数据位中1的个数与校验位中1的个数之和为奇数;接收方在接收数据时, 对1的个数进行检查,若不为奇数,则说明数据在传输过程中出了差错。同样,偶校验则检查1的个数是否为偶数

pythonk步差分 p阶差分和k步差分的区别_数据_02


UART通信过程中的数据格式及传输速率是可设置的,为了正确的通信,收发双方应约定并遵循同样的设置。数据位可选择为5、6、7、8位,其中8位数据位是最常用的,在实际应用中一般都选择8位数据位;校验位可选择奇校验、偶校验或者无校验位;停止位可选择1位(默认), 1.5或2位。

CAN

数据帧,用于发送单元向接收单元传送数据的帧。
远程帧,用于接收单元向具有相同ID的发送单元请求数据的帧。
错误帧,用于当检测出错误时向其它单元通知错误的帧。
过载帧,用于接收单元通知其尚未做好接收准备的帧。
间隔帧,用于将数据帧及遥控帧与前面的帧分离开来的帧。
数据帧和遥控帧有标准格式扩展格式两种格式。标准格式有11个位的标识符(ID),扩展格式有29个位的ID。

SDIO

SDIO总线上都是HOST端发起请求,然后DEVICE端回应请求。其中请求和回应中会数据信息。

  1. Command:用于开始传输的命令,是由HOST端发往DEVICE端的。其中命令是通过CMD信号线传送的。
  2. Response:回应是DEVICE返回的HOST的命令,作为Command的回应。也是通过CMD线传送的。
  3. Data:数据是双向的传送的。可以设置为1线模式,也可以设置为4线模式。数据是通过DAT0-DAT3信号线传输的。

SDIO的每次操作都是由HOST在CMD线上发起一个CMD,对于有的CMD,DEVICE需要返回Response,有的则不需要。
对于读命令,首先HOST会向DEVICE发送命令,紧接着DEVICE会返回一个握手信号,此时,当HOST收到回应的握手信号后,会将数据放在4位的数据线上,在传送数据的同时会跟随着CRC校验码。当整个读传送完毕后,HOST会再次发送一个命令,通知DEVICE操作完毕,DEVICE同时会返回一个响应。
对于写命令,首先HOST会向DEVICE发送命令,紧接着DEVICE会返回一个握手信号,此时,当HOST收到回应的握手信号后,会将数据放在4位的数据线上,在传送数据的同时会跟随着CRC校验码。当整个写传送完毕后,HOST会再次发送一个命令,通知DEVICE操作完毕,DEVICE同时会返回一个响应。