#硬件设计
构想:输入:上升(48V~6)、下降(48V-5);上限位、下限位;
1.硬件电路图(方案一:限位信号输入——单片机——控制输出,缺点:具有滞后性;)
方案二:限位信号输入——继电器——控制启动/停止;具体看图示
结合厂家提供电气原理图(厂家结构很简单,通过SB1接通控制接触器吸合,平台上升;反之泄压)
#软件实现
##2软件流程
###2.1开启举升任务
2.1.1在freertos.c内增加开启举升任务
1)定义变量
osThreadId_t LoadingUnloadTaskHandle;
uint32_t LoadingUnloadTaskBuffer[ 1024 ];
osStaticThreadDef_t LoadingUnloadTaskControlBlock;
const osThreadAttr_t LoadingUnloadTask_attributes = {
.name = "LoadingUnloadTask",
.cb_mem = &LoadingUnloadTaskControlBlock,
.cb_size = sizeof(LoadingUnloadTaskControlBlock),
.stack_mem = &LoadingUnloadTaskBuffer[0],
.stack_size = sizeof(LoadingUnloadTaskBuffer),
.priority = (osPriority_t) osPriorityNormal,
};
2)创建任务
LoadingUnloadTaskHandle = osThreadNew(loadingUnload_task, NULL, &LoadingUnloadTask_attributes);
3)任务函数
void loadingUnload_task(void *argument)
{
/* USER CODE BEGIN main_task */
/* Infinite loop */
static uint32_t current_time_ms;
current_time_ms = osKernelGetTickCount();
static uint32_t time_cnt_ms = 0;
uint16_t task_delay_time = 10;
for(;;)
{
current_time_ms += task_delay_time;
osDelayUntil(current_time_ms);//任务时间
time_cnt_ms += task_delay_time;
if(time_cnt_ms > 100000)
time_cnt_ms = task_delay_time;
LoadingUnload_Task( time_cnt_ms );//进入Main_Task函数
}
/* USER CODE END main_task */
}
综合上述三个步骤,创建了一个举升任务函数
###2.2实现举升逻辑
2.2.1添加思路:
1)上线后——非最低位降落到最低位置;
2)开启往复运动:最低——最高——泄压最低;完成一个循环
2.2.2代码实现
static uint8_t syncStep = 0;
/*计算平台当前高度*/
if(IN_UP_LIMIT == 0)
{//上限位触发
Lift_Flag = 1;//最高
}
else if(IN_DOWN_LIMIT == 0)
{//下限位触发
Lift_Flag = 2;//最低
}
else
{
Lift_Flag = 3;//中间
}
/*举升下降手自动处理处理*/
switch(syncStep)
{
case 0:
{
if(Lift_Flag == 1 || Lift_Flag == 3)//最高|中间
{
OUT_DOWN_CONTROL(1);//下降控制
}
if(Lift_Flag == 2)
syncStep = 1;
break;
}
case1:
{
if( IN_DOWN_LIMIT == 0)
{
OUT_DOWN_CONTROL(0);//释放下降控制
}
syncStep = 2;
break;
}
case 2:
{
OUT_UP_CONTROL(1);//上升控制
{
if( IN_UP_LIMIT == 0)
{
OUT_UP_CONTROL(0);//释放上升控制
syncStep = 3;
}
}
break;
}
case 3:
{
OUT_DOWN_CONTROL(1);//下降控制
if( IN_DOWN_LIMIT == 0 )
{
OUT_DOWN_CONTROL(0);//释放下降控制
}
break;
}
default:
{}
}
###2.3增添启动/停止按钮
2.3.1添加思路
启动按钮按下->检测到上升沿->松开,检测到下降沿->完整的一次按下松开,状态翻转
2.3.2代码实现
bool button_status = 0;//启动停止
uint8_t button_status_flag = 0;//标志位
if( IN_UP_LIMIT ==1)
{
button_status_flag = 1;
}
if(button_status_flag == 1)
{
if(IN_UP_LIMIT == 0)
{
button_status = ! button_status; //button_status状态取反
button_status_flag = 0;
}
}
//停止和自动
if(button_status == 1)
{//相关变量清零
OUT_UP_CONTROL(0);
OUT_DOWN_CONTROL(0);
}
else
{//自动举升降落往返运动
}
###2.2测试应用优化——反复不停歇工作,导致电机温升过快,发烫
2.2.1)第一时间和供应商联系获取建议工作周期
液压站厂家建议持续运行3分钟,休息9分钟;
解析:1:3的工作时间比;实际载重后上升+下降(15+21S左右),间歇120S
在程序中增加一次举升完成后,停机等待120S再次启动
2.2.2)对于厂家提供的不实际的说明给予否定
eg:他有保护的 油温高于125度 就会自己停
具体查看硬件电路后,该款型只有电磁阀和继电器,没有驱动器,更没有温度检测装置,所以厂家提供信息不准确;
2.2.3)在自动运行过程中一定要做足安全防护——降落有硬保护,举升——无机械硬保护
增加举升触发限位后在继续举升的第二层防护——金属接近开关
作用:举升过头会触发金属接近开关,模式切换成手动(停机保护等待人来处理)
2.2.4)程序死机——增加看门狗复位功能
看门狗定义:看门狗,又叫 watchdog timer,是一个定时器电路, 一般有一个输入,叫喂狗,一个输出到MCU的RST端,MCU正常工作的时候,每隔一端时间输出一个信号到喂狗端,给 WDT 清零,如果超过规定的时间不喂狗,(一般在程序跑飞时),WDT 定时超过,就回给出一个复位信号到MCU,是MCU复位. 防止MCU死机. 看门狗的作用就是防止程序发生死循环,或者说程序跑飞。
工作原理:在系统运行以后也就启动了看门狗的计数器,看门狗就开始自动计数,如果到了一定的时间还不去清看门狗,那么看门狗计数器就会溢出从而引起看门狗中断,造成系统复位。所以在使用有看门狗的芯片时要注意清看门狗。(硬件看门狗和软件看门狗两种)
a)
xEventGroupSetBits(EventGroupHandler_WWDG,EVENTBIT_LOAD_TASK);
b)
#define EVENTBIT_ALL (EVENTBIT_MAIN_TASK | EVENTBIT_ETH_TASK | EVENTBIT_WIFI_TASK | EVENTBIT_LOAD_TASK)
作用:程序跑飞后,会自己重启继续运行
Why:为什么自己的程序会跑飞呢?——程序里面部分存在漏洞