servoMotor/APP/Device/Device_speed/speed_to_servoMotor.c

335 lines
10 KiB
C
Raw Permalink Normal View History

2025-10-11 03:40:39 +00:00
#include "speed_to_servoMotor.h"
#ifdef PTZ_SERVO_MOTOR
2025-10-14 02:48:50 +00:00
//云台伺服电机通信信号量,增加发送的数据信号量+1发送完成信号量-1
BSP_OS_SEM g_horiSpeedSem;
BSP_OS_SEM g_vertSpeedSem;
//云台伺服电机能否发生数据互斥量
BSP_OS_SEM g_horiSpeedMutex;
BSP_OS_SEM g_vertSpeedMutex;
uint16_t memBuffer[linkListNodeLen * sendDataBufNumber * 2] = {0};
OS_MEM *g_memPtr;
ptzServoLinkList g_servoMotorLinkList = {0};
2025-10-11 03:40:39 +00:00
//发送云台实际转速
void ptz_send_speed(char dev, char speed)
{
unsigned char Speed1[7] = {0xff,0x00,0xd0,0x00,0x00,0x00,0x00};
unsigned char Speed2[7] = {0xff,0x00,0xd0,0x00,0x00,0x00,0x00};
unsigned short int HSpeed = 0;
unsigned short int VSpeed = 0;
Speed1[1] = g_ptz.address;
Speed2[1] = g_ptz.address;
HSpeed = (unsigned short int)(g_ptz.hori_speed_actual * 100 + 0.5);
Speed1[3] = 0X03;//水平电机
Speed1[4] = (unsigned char)(HSpeed >> 8);
Speed1[5] = (unsigned char)(HSpeed & 0x00ff);
Speed1[6] = MotorCalPelcoDSUM(Speed1,sizeof(Speed1));
VSpeed = (unsigned short int)(g_ptz.vert_speed_actual * 100 + 0.5);
Speed2[3] = 0X04;//垂直电机
Speed2[4] = (unsigned char)(VSpeed >> 8);
Speed2[5] = (unsigned char)(VSpeed & 0x00ff);
Speed2[6] = MotorCalPelcoDSUM(Speed2,sizeof(Speed2));
switch(speed)
{
case 1://只查询水平转速
ptz_send_data(dev,Speed1,sizeof(Speed1));
break;
case 2://只查询垂直转速
ptz_send_data(dev,Speed2,sizeof(Speed2));
break;
default://水平转速垂直转速都查询
ptz_send_data(dev,Speed1,sizeof(Speed1));
ptz_send_data(dev,Speed2,sizeof(Speed2));
break;
}
}
2025-10-14 02:48:50 +00:00
/*!
\brief
\param[in] data
\param[out] none
\retval none
*/
void servoLinkListMemPut(linkList *data)
{
if (data == NULL) {
return;
}
linkList *ptr;
ptr = data;
data = data->next;
OSMemPut(g_memPtr, (uint8_t *)ptr);
}
/*!
\brief
\param[in] motor
horiMotor
vertMotor
\param[in] *data
\param[in] dataLen
\param[in] priority
\param[out] none
\retval none
*/
void servoSendData(uint8_t motor,uint8_t *data, uint8_t dataLen, uint8_t priority)
{
if ((motor != horiMotorType) && (motor!= vertMotorType)) {
return;
}
if (data == NULL) {
return;
}
if (dataLen > sendDataBufLen) {
return;
}
if ((priority != highPriority) && (priority != lowPriority)) {
return;
}
2025-10-11 03:40:39 +00:00
2025-10-14 02:48:50 +00:00
linkList *ptr = NULL;
CPU_INT08U err;
//保存数据到链表节点
ptr = OSMemGet(g_memPtr, &err);
ptr->length = dataLen;
memcpy(ptr->data, data, dataLen);
//将节点添加进入链表中
if (motor == horiMotorType) {
if (g_servoMotorLinkList.horiMotor.linkListNum > sendDataBufNumber) {
OSMemPut(g_memPtr, ptr);
return;
2025-10-11 03:40:39 +00:00
}
2025-10-14 02:48:50 +00:00
if (priority == highPriority) {
g_servoMotorLinkList.horiMotor.LinkListTail_H = ptr;
if (g_servoMotorLinkList.horiMotor.LinkListHead_H == NULL) {
g_servoMotorLinkList.horiMotor.LinkListHead_H
= g_servoMotorLinkList.horiMotor.LinkListTail_H;
}
}
else {
g_servoMotorLinkList.horiMotor.LinkListTail_L = ptr;
if (g_servoMotorLinkList.horiMotor.LinkListHead_L == NULL) {
g_servoMotorLinkList.horiMotor.LinkListHead_L
= g_servoMotorLinkList.horiMotor.LinkListTail_L;
}
}
//释放信号量,通知能发送一次
OSSemPost(g_horiSpeedSem);
}
else {
if (g_servoMotorLinkList.vertMotor.linkListNum > sendDataBufNumber) {
OSMemPut(g_memPtr, ptr);
return;
2025-10-11 03:40:39 +00:00
}
2025-10-14 02:48:50 +00:00
if (priority == highPriority) {
g_servoMotorLinkList.vertMotor.LinkListTail_H = ptr;
if (g_servoMotorLinkList.vertMotor.LinkListHead_H == NULL) {
g_servoMotorLinkList.vertMotor.LinkListHead_H
= g_servoMotorLinkList.vertMotor.LinkListTail_H;
}
}
else {
g_servoMotorLinkList.vertMotor.LinkListTail_L = ptr;
if (g_servoMotorLinkList.vertMotor.LinkListHead_L == NULL) {
g_servoMotorLinkList.vertMotor.LinkListHead_L
= g_servoMotorLinkList.vertMotor.LinkListTail_L;
}
}
//释放信号量,通知能发送一次
OSSemPost(g_vertSpeedSem);
2025-10-11 03:40:39 +00:00
}
}
2025-10-14 02:48:50 +00:00
static void ptz_hori_servo_task()
{
CPU_INT08U err;
while(1) {
// if(g_ptz.hori_start_stop_set == PTZ_HORI_START)
// {
// }
// if(g_ptz.hori_start_stop_set == PTZ_HORI_STOP)
// {
// }
OSSemPend(g_horiSpeedMutex, 0, &err);
OSSemPend(g_horiSpeedSem, 0, &err);
2025-10-11 03:40:39 +00:00
2025-10-14 02:48:50 +00:00
// 高优先级链表中数据先发送
if (g_servoMotorLinkList.horiMotor.LinkListHead_H != NULL) {
//发送数据
g_servoMotorLinkList.horiMotor.linkListNum = highPriority;
continue;
}
// 高优先级链表中无数据时,发送低优先级中的数据
if (g_servoMotorLinkList.horiMotor.LinkListHead_L != NULL) {
//发送数据
g_servoMotorLinkList.horiMotor.linkListNum = lowPriority;
}
else {
pdebug(DEBUG_LEVEL_FATAL,"ptz_hori_servo_task no data...\n\r");
2025-10-11 03:40:39 +00:00
}
}
}
2025-10-14 02:48:50 +00:00
static void ptz_vert_servo_task()
{
CPU_INT08U err;
while(1) {
// if(g_ptz.vert_start_stop_set == PTZ_VERT_START)
// {
// }
// if(g_ptz.vert_start_stop_set == PTZ_VERT_STOP)
// {
// }
OSSemPend(g_vertSpeedMutex, 0, &err);
OSSemPend(g_vertSpeedSem, 0, &err);
// 高优先级链表中数据先发送
if (g_servoMotorLinkList.vertMotor.LinkListHead_H != NULL) {
g_servoMotorLinkList.vertMotor.linkListNum = highPriority;
continue;
}
// 高优先级链表中无数据时,发送低优先级中的数据
if (g_servoMotorLinkList.vertMotor.LinkListHead_L != NULL) {
g_servoMotorLinkList.vertMotor.linkListNum = highPriority;
}
else {
pdebug(DEBUG_LEVEL_FATAL,"ptz_vert_servo_task no data...\n\r");
}
}
}
2025-10-11 03:40:39 +00:00
2025-10-14 02:48:50 +00:00
static OS_STK task_hori_servo_stk[TASK_HORI_PID_STK_SIZE];
static void creat_task_hori_servo_task(void)
2025-10-11 03:40:39 +00:00
{
CPU_INT08U task_err;
CPU_INT08U name_err;
2025-10-14 02:48:50 +00:00
task_err = OSTaskCreateExt((void (*)(void *)) ptz_hori_servo_task,
2025-10-11 03:40:39 +00:00
(void *) 0,
2025-10-14 02:48:50 +00:00
(OS_STK *)&task_hori_servo_stk[TASK_HORI_PID_STK_SIZE - 1],
2025-10-11 03:40:39 +00:00
(INT8U ) TASK_HORI_PID_PRIO,
(INT16U ) TASK_HORI_PID_PRIO,
2025-10-14 02:48:50 +00:00
(OS_STK *)&task_hori_servo_stk[0],
2025-10-11 03:40:39 +00:00
(INT32U ) TASK_HORI_PID_STK_SIZE,
(void *) 0,
(INT16U )(OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR));
#if (OS_TASK_NAME_EN > 0)
OSTaskNameSet(TASK_HORI_PID_PRIO, "ptz_hori_step_speed_task", &name_err);
#endif
if ((task_err == OS_ERR_NONE) && (name_err == OS_ERR_NONE)) {
pdebug(DEBUG_LEVEL_INFO,"create ptz_hori_step_speed_task success...\n\r");
} else {
pdebug(DEBUG_LEVEL_FATAL,"create ptz_hori_step_speed_task failed...\n\r");
}
}
2025-10-14 02:48:50 +00:00
static OS_STK task_vert_servo_stk[TASK_VERT_PID_STK_SIZE];
static void creat_task_vert_servo_task(void)
2025-10-11 03:40:39 +00:00
{
CPU_INT08U task_err;
CPU_INT08U name_err;
2025-10-14 02:48:50 +00:00
task_err = OSTaskCreateExt((void (*)(void *)) ptz_vert_servo_task,
2025-10-11 03:40:39 +00:00
(void *) 0,
2025-10-14 02:48:50 +00:00
(OS_STK *)&task_vert_servo_stk[TASK_VERT_PID_STK_SIZE - 1],
2025-10-11 03:40:39 +00:00
(INT8U ) TASK_VERT_PID_PRIO,
(INT16U ) TASK_VERT_PID_PRIO,
2025-10-14 02:48:50 +00:00
(OS_STK *)&task_vert_servo_stk[0],
2025-10-11 03:40:39 +00:00
(INT32U ) TASK_VERT_PID_STK_SIZE,
(void *) 0,
2025-10-14 02:48:50 +00:00
(INT16U )(OS_TASK_OPT_STK_CHK | OS_TASK_OPT_STK_CLR));
2025-10-11 03:40:39 +00:00
#if (OS_TASK_NAME_EN > 0)
2025-10-14 02:48:50 +00:00
OSTaskNameSet(TASK_VERT_PID_PRIO, "ptz_vert_servo_task", &name_err);
2025-10-11 03:40:39 +00:00
#endif
if ((task_err == OS_ERR_NONE) && (name_err == OS_ERR_NONE)) {
2025-10-14 02:48:50 +00:00
pdebug(DEBUG_LEVEL_INFO,"create ptz_vert_servo_task success...\n\r");
2025-10-11 03:40:39 +00:00
} else {
2025-10-14 02:48:50 +00:00
pdebug(DEBUG_LEVEL_FATAL,"create ptz_vert_servo_task failed...\n\r");
2025-10-11 03:40:39 +00:00
}
}
void init_speed_module(void)
{
2025-10-14 02:48:50 +00:00
g_horiSpeedSem = OSSemCreate(0);
g_vertSpeedSem = OSSemCreate(0);
g_horiSpeedMutex = OSSemCreate(1);
g_vertSpeedMutex = OSSemCreate(1);
OSSemPost(g_horiSpeedMutex);
OSSemPost(g_vertSpeedMutex);
CPU_INT08U err;
g_memPtr = OSMemCreate(memBuffer, sendDataBufNumber * 2, linkListNodeLen, &err);
if (err != OS_ERR_NONE) {
pdebug(DEBUG_LEVEL_FATAL, "Failed to create the motor memory pool\n\r");
}
//初始化链表头尾
g_servoMotorLinkList.horiMotor.LinkListHead_H = NULL;
g_servoMotorLinkList.horiMotor.LinkListHead_L = NULL;
g_servoMotorLinkList.horiMotor.LinkListTail_H = NULL;
g_servoMotorLinkList.horiMotor.LinkListTail_L = NULL;
g_servoMotorLinkList.horiMotor.linkListPriority = nonePriority;
g_servoMotorLinkList.horiMotor.linkListNum = 0;
g_servoMotorLinkList.vertMotor.LinkListHead_H = NULL;
g_servoMotorLinkList.vertMotor.LinkListHead_L = NULL;
g_servoMotorLinkList.vertMotor.LinkListTail_H = NULL;
g_servoMotorLinkList.vertMotor.LinkListTail_L = NULL;
g_servoMotorLinkList.vertMotor.linkListPriority = nonePriority;
g_servoMotorLinkList.vertMotor.linkListNum = 0;
2025-10-11 03:40:39 +00:00
servoMotorInit();
2025-10-14 02:48:50 +00:00
Init_ServoMotorRecv();
creat_task_hori_servo_task();
creat_task_vert_servo_task();
2025-10-11 03:40:39 +00:00
}
2025-10-14 02:48:50 +00:00
2025-10-11 03:40:39 +00:00
#endif