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
//结构体部分
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的个数是否为偶数。
UART通信过程中的数据格式及传输速率是可设置的,为了正确的通信,收发双方应约定并遵循同样的设置。数据位可选择为5、6、7、8位,其中8位数据位是最常用的,在实际应用中一般都选择8位数据位;校验位可选择奇校验、偶校验或者无校验位;停止位可选择1位(默认), 1.5或2位。
CAN
数据帧,用于发送单元向接收单元传送数据的帧。
远程帧,用于接收单元向具有相同ID的发送单元请求数据的帧。
错误帧,用于当检测出错误时向其它单元通知错误的帧。
过载帧,用于接收单元通知其尚未做好接收准备的帧。
间隔帧,用于将数据帧及遥控帧与前面的帧分离开来的帧。
数据帧和遥控帧有标准格式和扩展格式两种格式。标准格式有11个位的标识符(ID),扩展格式有29个位的ID。
SDIO
SDIO总线上都是HOST端发起请求,然后DEVICE端回应请求。其中请求和回应中会数据信息。
- Command:用于开始传输的命令,是由HOST端发往DEVICE端的。其中命令是通过CMD信号线传送的。
- Response:回应是DEVICE返回的HOST的命令,作为Command的回应。也是通过CMD线传送的。
- 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同时会返回一个响应。