#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include "rs232.h"
#include <assert.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#define CMD_HEAD1 0
#define CMD_HEAD2 1
#define CMD_DEVICE_ID 2
#define CMD_ACTION 3
#define CMD_TAIL 4
#define CMD_STATE 3 //for responses
#define PERSON_IN 1
#define NO_PERSON 2
#define NO_DEVICE 0xff
#define DEVICE_INIT 4
#define BUS_ERR 5
#define NO_RESPONSES 0
#define DEVICE_RS485 "/dev/rs485driver"
#define RS485_SEND 1
#define RS485_RECEIVE 2
#define CMD_LENGTH 5
#define BUZZ_ON 1
#define BUZZ_TIME 3
#define NO_RESPONSES_TIME 2
#define MAX_DEVICE 34
struct PortInfo ports[MAX_PORTS];
int fd485;
int ret_485;
int portno;
int fdcom;
unsigned char device_id = 0;
unsigned char ask_cmd[CMD_LENGTH];
unsigned char device_state[256]; //设备状态,1--表示上次检查有人进来;2---表示上次检查没人进来;3--表示上次检查没回应;4表示系统正在初始化。0xff--表示没有此设备(NO_RESPONSES_TIME次查询没回应表示此设編号设备不存在
unsigned char responses_cmd_y[CMD_LENGTH];
unsigned char responses_cmd_n[CMD_LENGTH];
unsigned char responses_cmd_init[CMD_LENGTH];
int OpenComConfig(int port, const char deviceName[], long baudRate, int parity, int dataBits, int stopBits, int iqSize, int oqSize);
void init_buf(void); //初始化所有缓冲区
int check_rev_cmd(unsigned char buf[CMD_LENGTH], unsigned char id_check);
int ask_id(unsigned char id); //查询id机子状态,返回1,表示有人进入房间,返回2表示没人进入房间,返回3表示此系统正在初始化。返回0表示没有回应,返回0xff表示设备不存在,返回5表示总线错誤
void init_buf(void)
{
unsigned int i;
device_id = 0;
fd485 = -1;
ret_485 = -1;
portno = 2;
fdcom = -1;
ask_cmd[CMD_HEAD1] = 0xfe;
ask_cmd[CMD_HEAD2] = 0xaa;
ask_cmd[CMD_DEVICE_ID] = 0x00;
ask_cmd[CMD_ACTION] = 0x01;
ask_cmd[CMD_TAIL] = 0x55;
responses_cmd_y[CMD_HEAD1] = 0xfe;
responses_cmd_y[CMD_HEAD2] = 0xaa;
responses_cmd_y[CMD_DEVICE_ID] = 0x00;
responses_cmd_y[CMD_STATE] = 0x01; //no person in the room
responses_cmd_y[CMD_TAIL] = 0x55;
responses_cmd_n[CMD_HEAD1] = 0xfe;
responses_cmd_n[CMD_HEAD2] = 0xaa;
responses_cmd_n[CMD_DEVICE_ID] = 0x00;
responses_cmd_n[CMD_STATE] = 0x02; //there are person in the room
responses_cmd_n[CMD_TAIL] = 0x55;
responses_cmd_init[CMD_HEAD1] = 0xfe;
responses_cmd_init[CMD_HEAD2] = 0xaa;
responses_cmd_init[CMD_DEVICE_ID] = 0x00;
responses_cmd_init[CMD_STATE] = 0x04; //there are person in the room
responses_cmd_init[CMD_TAIL] = 0x55;
for (i = 0; i < 0xff; i++)
device_state[i] = 0;
}
int check_rev_cmd(unsigned char *buf, unsigned char id_check)
{
int i;
responses_cmd_y[CMD_DEVICE_ID] = id_check;
responses_cmd_n[CMD_DEVICE_ID] = id_check;
printf("\n");
printf("Id = [%02d ] %02x ", id_check,id_check);
printf(" ");
for (i = 0; i < CMD_LENGTH; i++) {
printf("%02x ", buf[i]);
}
printf("\n");
if (memcmp(buf, responses_cmd_y, CMD_LENGTH) == 0) {
return (int) buf[CMD_STATE];
} else if (memcmp(buf, responses_cmd_n, CMD_LENGTH) == 0) {
return (int) buf[CMD_STATE];
} else if (memcmp(buf, responses_cmd_init, CMD_LENGTH) == 0) {
return (int) buf[CMD_STATE];
} else {
return -1;
}
}
int ask_id(unsigned char id)
{
int ask_ret;
unsigned char rev_buf[CMD_LENGTH];
int nWritten_com = -1;
int nRead_com = -1;
if (device_state[id] == 0xff) return NO_DEVICE;
ask_cmd[CMD_DEVICE_ID] = id;
ret_485 = ioctl(fd485, RS485_SEND, NULL);
nWritten_com = ComWrt(portno, ask_cmd, CMD_LENGTH);
ret_485 = ioctl(fd485, RS485_RECEIVE, NULL);
nRead_com = ComRd(portno, rev_buf, CMD_LENGTH, 2000);
if (nRead_com > 0)
{
ask_ret = check_rev_cmd(rev_buf, id);
if (ask_ret > 0) {
device_state[id] = ask_ret;
return ask_ret;
} else
return BUS_ERR;
} else
{
if (device_state[id] < 0x02)
device_state[id] = 3;
else if (device_state[id] > 0x02 && device_state[id] < 0xff)
{
device_state[id]++;
if (device_state[id] - 2 >= NO_RESPONSES_TIME)
device_state[id] = NO_DEVICE;
} else;
return NO_RESPONSES;
}
}
int OpenCom(int portNo, const char deviceName[], long baudRate)
{
return OpenComConfig(portNo, deviceName, baudRate, 1, 8, 1, 0, 0);
}
long GetBaudRate(long baudRate)
{
long BaudR;
switch (baudRate) {
case 115200:
BaudR = B115200;
break;
case 57600:
BaudR = B57600;
break;
case 19200:
BaudR = B19200;
break;
case 38400:
BaudR = B38400;
break;
case 9600:
BaudR = B9600;
break;
default:
BaudR = B0;
}
return BaudR;
}
/*
** Function: OpenComConfig
**
** Description:
** Opens a serial port with the specified parameters
**
** Arguments:
** portNo - handle used for further access
** deviceName - the name of the device to open
** baudRate - rate to open (57600 for example)
** parity - 0 for no parity
** dataBits - 7 or 8
** stopBits - 1 or 2
** iqSize - ignored
** oqSize - ignored
**
** Returns:
** -1 on failure
**
** Limitations:
** parity, stopBits, iqSize, and oqSize are ignored
*/
int OpenComConfig(int port, const char deviceName[], long baudRate, int parity, int dataBits, int stopBits, int iqSize, int oqSize)
{
struct termios newtio;
ports[port].busy = 1;
strcpy(ports[port].name, deviceName);
if ((ports[port].handle = open(deviceName, O_RDWR, 0666)) == -1) {
perror("open");
// assert(0);
}
/* set the port to raw I/O */
newtio.c_cflag = CS8 | CLOCAL | CREAD;
newtio.c_cflag &= ~PARENB;
newtio.c_cflag &= ~CSTOPB; /* 1 stop bit */
//newtio.c_iflag &= ~INPCK;
newtio.c_iflag = IGNPAR;
newtio.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
//newtio.c_iflag &=(IXON|IXOFF|IXANY);
newtio.c_oflag = 0;
//newtio.c_oflag &= ~OPOST;
newtio.c_lflag = 0;
newtio.c_cc[VINTR] = 0;
newtio.c_cc[VQUIT] = 0;
newtio.c_cc[VERASE] = 0;
newtio.c_cc[VKILL] = 0;
newtio.c_cc[VTIME] = 1;
newtio.c_cc[VMIN] = 18;
newtio.c_cc[VSWTC] = 0;
newtio.c_cc[VSTART] = 0;
newtio.c_cc[VSTOP] = 0;
newtio.c_cc[VSUSP] = 0;
newtio.c_cc[VEOL] = 0;
newtio.c_cc[VREPRINT] = 0;
newtio.c_cc[VDISCARD] = 0;
newtio.c_cc[VWERASE] = 0;
newtio.c_cc[VLNEXT] = 0;
newtio.c_cc[VEOL2] = 0;
cfsetospeed(&newtio, GetBaudRate(baudRate));
cfsetispeed(&newtio, GetBaudRate(baudRate));
tcsetattr(ports[port].handle, TCSANOW, &newtio);
return 0;
}
/*
** Function: CloseCom
**
** Description:
** Closes a previously opened port
**
** Arguments:
** The port handle to close
**
** Returns:
** -1 on failure
*/
int CloseCom(int portNo)
{
if (ports[portNo].busy) {
close(ports[portNo].handle);
ports[portNo].busy = 0;
return 0;
} else {
return -1;
}
}
/*
** Function: ComRd
**
** Description:
** Reads the specified number of bytes from the port.
** Returns when these bytes have been read, or timeout occurs.
**
** Arguments:
** portNo - the handle
** buf - where to store the data
** maxCnt - the maximum number of bytes to read
**
** Returns:
** The actual number of bytes read
*/
int ComRd(int portNo, char buf[], int maxCnt, int Timeout)
{
int actualRead = 0;
fd_set rfds;
struct timeval tv;
int retval;
if (!ports[portNo].busy) {
assert(0);
}
/* camp on the port until data appears or 5 seconds have passed */
FD_ZERO(&rfds);
FD_SET(ports[portNo].handle, &rfds);
tv.tv_sec = Timeout / 1000;
tv.tv_usec = (Timeout % 1000) * 1000;
retval = select(16, &rfds, NULL, NULL, &tv);
if (retval) {
actualRead = read(ports[portNo].handle, buf, maxCnt);
}
return actualRead;
}
/*
** Function: ComWrt
**
** Description:
** Writes o
- 1
- 2
- 3
前往页