51模拟PELCO-D控制协议
//上位机EXE通过串口实现对C51控制(云台解码原理)
#include <reg51.h>
#include <string.h>
#define INBUF_LEN 8 //8位数据长度
//字节1 字节2 字节3 字节4 字节5 字节6 字节7
//同步字节 地址码 指令码1 指令码2 数据码1 数据码2 校验码
//通信协议: 第1字节,恒为AF,为协议同步字标志,第2字节,为地址码00-FF,其余类推……,字节7为校验码,即1-6个字节后7位的异或校验和。
unsigned char code P1Tab[9] = {0xFE, 0xFD, 0xFB, 0xF7, 0xEF, 0xDF, 0xBF, 0x7F, 0xFF};
unsigned char inbuf1[INBUF_LEN];
unsigned char checksum, count3;
bit read_flag = 0 ;
sbit P27 = P2 ^ 7;
sbit JDQ = P3 ^ 7;
#define BAUD_1200 0xD0 // 波特率为1200
#define BAUD_2400 0xE8 // 波特率为2400
#define BAUD_4800 0xF4 // 波特率为4800
#define BAUD_7200 0xF8 // 波特率为7200
#define BAUD_9600 0xFA // 波特率为9600
#define BAUD_14400 0xFC // 波特率为14400
#define BAUD_19200 0xFD // 波特率为19200
//11.0592最高所支持的波特率为19200
void init_serialcomm( void )
{
SCON = 0x50 ; //SCON: serail mode 1, 8-bit UART, enable ucvr
TMOD |= 0x20 ; //TMOD: timer 1, mode 2, 8-bit reload
PCON |= 0x80 ; //SMOD=1;
TH1 = BAUD_9600 ; //Baud:7200 fosc=11.0592MHz
IE |= 0x90 ; //Enable Serial Interrupt
TR1 = 1 ; // timer 1 run
// TI=1;
}
//向串口发送一个字符
void send_char_com( unsigned char ch)
{
SBUF = ch;
while (TI == 0 );
TI = 0 ;
}
//向串口发送一个字符串,strlen为该字符串长度
void send_string_com( unsigned char *str, unsigned int strlen)
{
unsigned int k = 0 ;
do
{
send_char_com(*(str + k));
k++;
}
while (k < strlen);
}
//串口接收中断函数
void serial () interrupt 4 using 3
{
if (RI)
{
unsigned char ch;
RI = 0 ;
ch = SBUF;
if (ch == 175 ) //检测同步字是否为AF
{
count3 = 0 ;
inbuf1[0] = ch;
checksum = ch - 128 ;
}
else
{
count3++;
inbuf1[count3] = ch;
checksum ^= ch;
if (count3 == (INBUF_LEN - 1 )) //如果串口接收的数据达到INBUF_LEN个
{
if ((!checksum) && (inbuf1[0] == 175)) //校验没错且同步字正确
{
read_flag = 1 ; //就置位取数标志
//if ((inbuf1[2]==0) && (inbuf1[3]==0) && (inbuf1[4]==0) && (inbuf1[5]==0) && (inbuf1[6]==0))
if (inbuf1[2] + inbuf1[3] + inbuf1[4] + inbuf1[5] + inbuf1[6] == 0) //2-6位为零表示停止命令
{
P1 = 0xFF;
JDQ = 0;
}
else
{
P1 = P1Tab[inbuf1[2]];
JDQ = 1;
}
}
else
{
JDQ = 0;
inbuf1[0] = 255;
send_char_com(255);
}
count3 = 0 ;
}
}
}
}
main()
{
P0 = 0xff;
P2 = 0xff;
JDQ = 0;
init_serialcomm(); //初始化串口
while ( 1 )
{
if (read_flag) //如果取数标志已置位,就将读到的数从串口发出
{
read_flag = 0 ; //取数标志清0
send_string_com(inbuf1, INBUF_LEN);
}
}
}
上位机EXE通过串口实现对C51控制(云台解码原理).rar
(363.56 KB, 下载次数: 0)
|