在Linux环境下采用Pelco D协议的云台控制的实现源代码
#include
"
stdio.h
"
#include
<
stdio.h
>
/**/
/*
标准输入输出定义
*/
#include
<
stdlib.h
>
/**/
/*
标准函数库定义
*/
#include
<
unistd.h
>
/**/
/*
Unix标准函数定义
*/
#include
<
sys
/
types.h
>
/** */
/**
/
#include <sys/stat.h> /*
*/
#include
<
fcntl.h
>
/**/
/*
文件控制定义
*/
#include
<
termios.h
>
/**/
/*
PPSIX终端控制定义
*/
#include
<
errno.h
>
/**/
/*
错误号定义
*/
#define TRUE
0
#define FALSE
-
1

enum
Direct

{
STOP
=
0x00
,
RIGHT
=
0x02
,
LEFT
=
0x04
,
UP
=
0x08
,
DOWN
=
0x10
}
;


int
speed_arr[]
=
{ B38400, B19200, B9600, B4800, B2400, B1200, B300,
B38400, B19200, B9600, B4800, B2400, B1200, B300, }
;

int
name_arr[]
=
{
38400
,
19200
,
9600
,
4800
,
2400
,
1200
,
300
,
38400
,
19200
,
9600
,
4800
,
2400
,
1200
,
300
, }
;


/** */
/**
*@brief 设置串口通信速率
*
@param
fd 类型 int 打开串口的文件句柄
*
@param
speed 类型 int 串口速度
*
@return
void
*/
void
SetSpeed(
int
fd,
int
speed)

{
int
i;
int
status;
struct termios Opt;
tcgetattr(fd,
&
Opt);
for
( i
=
0
; i
<
sizeof(speed_arr)
/
sizeof(
int
); i
++
)

{
if
(speed
==
name_arr[i])

{
tcflush(fd, TCIOFLUSH);
cfsetispeed(
&
Opt, speed_arr[i]);
cfsetospeed(
&
Opt, speed_arr[i]);
status
=
tcsetattr(fd, TCSANOW,
&
Opt);
if
(status
!=
0
)
printf(
"
set_speed [Failue]\n
"
);
return
;
}
tcflush(fd,TCIOFLUSH);
}
}
/** */
/**
*@brief 设置串口数据位,停止位和效验位
*
@param
fd 类型 int 打开的串口文件句柄*
*
@param
databits 类型 int 数据位 取值 为 7 或者8*
*
@param
stopbits 类型 int 停止位 取值为 1 或者2*
*
@param
parity 类型 int 效验类型 取值为N,E,O,,S
*/
int
SetParity(
int
fd,
int
databits,
int
stopbits,
int
parity)

{
struct termios options;
if
( tcgetattr( fd,
&
options)
!=
0
)

{
printf(
"
set_Parity [Failue]\n
"
);
return
(FALSE);
}
options.c_cflag
&=
~
CSIZE;

switch
(databits)
/**/
/*
设置数据位数
*/
{
case
7
:
options.c_cflag
|=
CS7;
break
;
case
8
:
options.c_cflag
|=
CS8;
break
;
default
:
fprintf(stderr,
"
Unsupported data size\n
"
);
return
(FALSE);
}
switch
(parity)

{
case
'
n
'
:
case
'
N
'
:

options.c_cflag
&=
~
PARENB;
/**/
/*
Clear parity enable
*/
options.c_iflag
&=
~
INPCK;
/**/
/*
Enable parity checking
*/
break
;
case
'
o
'
:
case
'
O
'
:

options.c_cflag
|=
(PARODD
|
PARENB);
/**/
/*
设置为奇效验
*/
options.c_iflag
|=
INPCK;
/**/
/*
Disnable parity checking
*/
break
;
case
'
e
'
:
case
'
E
'
:

options.c_cflag
|=
PARENB;
/**/
/*
Enable parity
*/
options.c_cflag
&=
~
PARODD;
/**/
/*
转换为偶效验
*/
options.c_iflag
|=
INPCK;
/**/
/*
Disnable parity checking
*/
break
;
case
'
S
'
:

case
'
s
'
:
/**/
/*
as no parity
*/
options.c_cflag
&=
~
PARENB;
options.c_cflag
&=
~
CSTOPB;
break
;
default
:
fprintf(stderr,
"
Unsupported parity\n
"
);
return
(FALSE);
}
/**/
/*
设置停止位
*/
switch
(stopbits)

{
case
1
:
options.c_cflag
&=
~
CSTOPB;
break
;
case
2
:
options.c_cflag
|=
CSTOPB;
break
;
default
:
fprintf(stderr,
"
Unsupported stop bits\n
"
);
return
(FALSE);
}
/**/
/*
Set input parity option
*/
if
(parity
!=
'
n
'
)
options.c_iflag
|=
INPCK;
options.c_cc[VTIME]
=
150
;
//
15 seconds
options.c_cc[VMIN]
=
0
;

tcflush(fd,TCIFLUSH);
/**/
/*
Update the options and do it NOW
*/
if
(tcsetattr(fd,TCSANOW,
&
options)
!=
0
)

{
perror(
"
SetupSerial 3
"
);
return
(FALSE);
}
return
(TRUE);
}
/** */
/**
*@breif 打开串口
*/
int
OpenDev(
char
*
Dev)

{
int
fd
=
open( Dev, O_RDWR );
//
| O_NOCTTY | O_NDELAY
if
(
-
1
==
fd)

{
return
-
1
;
}
else
{
return
fd;
}
}
inline
int
CheckSum(
char
*
strCommOut)

{
int
sum
=
0
;
for
(
int
i
=
1
; i
<
6
; i
++
)

{
sum
+=
strCommOut[i];
}
if
(sum
>
0xFF
)
strCommOut[
6
]
=
sum
%
0x100
;
else
strCommOut[
6
]
=
sum;
}
char
*
MakeDirect(
char
*
strCommOut,
char
chDirrect,
char
chCammerID)

{
strCommOut[
0
]
=
0xFF
;
strCommOut[
1
]
=
chCammerID;
strCommOut[
2
]
=
0x0
;
strCommOut[
3
]
=
chDirrect;
strCommOut[
4
]
=
0x20
;
strCommOut[
5
]
=
0x20
;
CheckSum(strCommOut);
return
strCommOut;
}
void
Running(
int
fd,
char
chCammerID,
char
chDir)

{
char
strCommOut[
7
];
MakeDirect(strCommOut,chDir,chCammerID);
write(fd,strCommOut,sizeof(strCommOut));
}
int
main()

{
char
*
dev2
=
"
/dev/ttyS2
"
;
//
/dev/ttyS2对应串口com3 /dev/ttyS0对应com1
int
fd
=
OpenDev(dev2);
if
(fd
>
0
)
SetSpeed(fd,
2400
);
//
设置波特率
else
{
printf(
"
Can't Open Serial Port '%s'\n
"
,dev2);
return
-
1
;
}
if
(SetParity(fd,
8
,
1
,
'
N
'
)
==
-
1
)

{
printf(
"
Set Parity Error\n
"
);
return
-
1
;
}
Running(fd,
2
,LEFT);
//
让地址为2的摄像头左转
printf(
"
press any key to stop.\n
"
);
getchar();
Running(fd,
2
,STOP);
//
让地址2摄像头停止转动
return
0
;
}
PELCO-D:
数据格式:1位起始位、8位数据、1位停止位,无效验位。波特率:2400B/S
命令格式:
字节1
|
字节2
|
字节3
|
字节4
|
字节5
|
字节6
|
字节7
|
同步字节
|
地址码
|
指令码1
|
指令码2
|
数据码1
|
数据码2
|
校验码
|
1.该协议中所有数值都为十六进制数
2.同步字节始终为FFH
3.地址码为摄像机的逻辑地址号,地址范围:00H–FFH
4.指令码表示不同的动作
5.数据码1、2分别表示水平、垂直方向速度(00-3FH),FFH表示“turbo”速度
6.校验码 = MOD[(字节2 + 字节3 + 字节4 + 字节5 + 字节6)/100H]
以地址码0x01为例:
{0xff,0x01,0x00,0x08,0x00,0xff,0x08,}//上
{0xff,0x01,0x00,0x10,0x00,0xff,0x10,}//下
{0xff,0x01,0x00,0x04,0xff,0x00,0x04,}//左
{0xff,0x01,0x00,0x02,0xff,0x00,0x02,}//右
{0xff,0x01,0x00,0x20,0x00,0x00,0x21,}//变倍短
{0xff,0x01,0x00,0x40,0x00,0x00,0x41,}//变倍长
{0xff,0x01,0x00,0x80,0x00,0x00,0x81,}//聚焦近
{0xff,0x01,0x01,0x00,0x00,0x00,0x02,}//聚焦远
{0xff,0x01,0x02,0x00,0x00,0x00,0x03,}//光圈小
{0xff,0x01,0x04,0x00,0x00,0x00,0x05,}//光圈大
{0xff,0x01,0x00,0x0b,0x00,0x01,0x0d,}//灯光关
{0xff,0x01,0x00,0x09,0x00,0x01,0x0b,}//灯光开
{0xff,0x01,0x00,0x07,0x00,0x01,0x09,}//转至预置点001
{0xff,0x01,0x00,0x03,0x00,0x01,0x05,}//设置预置点001
{0xff,0x01,0x00,0x05,0x00,0x01,0x07,}//删除预置点001
以上对应的停命令均是:
{0xff,0x01,0x00,0x00,0x00,0x00,0x01,}//停命令