oddy
|
分享:
▲
▼
嗯嗯 ok啊 可是程式碼有點囉唆 滿長的 而且因為才剛碰這東西 所以很多是拼拼湊湊的 主要是要用 02 read input atatus 03 read holding registers 04 read input registers 這三個 function 之前有搜尋過大陸網站 可能是簡體字的關係 看不太懂 麻煩各位幫忙嚕 第一個是uart.c 複製程式
/*
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <ctype.h>
#include <termios.h>
#include <asm/io.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "uart.h"
#define FALSE -1
#define TRUE 0
#define IS 0x02
#define HR 0x03
#define IR 0x04
#define READ_IS 0x02
#define READ_HR 0x03
#define READ_IR 0x04
#define PROTOCOL_EXCEPTION 0x81
#define PROTOCOL_ERR 1
const unsigned char auchCRCHi[] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40
} ;
const unsigned char auchCRCLo[] = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80,
0x40
};
//static int devfd;
//設置序列埠通信速率
int baud_rate[] = { B9600, B9600, B9600, B9600};
int name_speed[] = {9600, 9600, 9600, 9600};
void set_speed(int fd, int speed){
int i;
int status;
struct termios Opt;
tcgetattr(fd, &Opt);
for ( i= 0; i < sizeof(baud_rate) / sizeof(int); i++) {
if (speed == name_speed[i]) {
tcflush(fd, TCIOFLUSH);
cfsetispeed(&Opt, baud_rate[i]);
cfsetospeed(&Opt, baud_rate[i]);
status = tcsetattr(fd, TCSANOW, &Opt);
if (status != 0) {
perror("tcsetattr fd1");
return;
}
tcflush(fd,TCIOFLUSH);
}
}
}
//設置序列埠資料位元,校驗位和停止位元(8, N, 1)
int set_parity(int fd,int databits,int parity,int stopbits)
{
struct termios options;
if ( tcgetattr( fd,&options) != 0)
{
perror("SetupSerial 1");
return(FALSE);
}
options.c_cflag &= ~CSIZE;
if (databits == 8) options.c_cflag |= CS8; /*設置資料位元數為 8*/
if (parity == 'N'){ options.c_cflag &= ~PARENB; /* Clear parity enable 設為無效驗*/
options.c_iflag &= ~INPCK; } /* Enable parity checking */
if (stopbits == 2) options.c_cflag |= CSTOPB; /* 設置停止位 2*/
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);
}
//打開介面
int OpenDev(char *Dev)
{
int fd = open( Dev, O_RDWR ); //| O_NOCTTY | O_NDELAY
if (-1 == fd) //避免只用一個=等號的錯誤
{
perror("Can't Open Serial Port RS485");
return -1;
}
else
return fd;
}
//使用crc驗證
unsigned short crc(unsigned char *puchMsg , unsigned short usDataLen)
{
unsigned char uchCRCHi = 0xFF ; /* high byte of CRC initialized */
unsigned char uchCRCLo = 0xFF ; /* low byte of CRC initialized */
unsigned uIndex ; /* will index into CRC lookup table */
while (usDataLen--) /* pass through message buffer */
{
uIndex = uchCRCHi ^ *puchMsg++ ; /* calculate the CRC */
uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex];
uchCRCLo = auchCRCLo[uIndex];
}
return (uchCRCHi << 8 | uchCRCLo);
}
//建立rtu模式
void construct_rtu_frm ( unsigned char *dst_buf, unsigned char *src_buf, unsigned char lenth)
{
unsigned short crc_tmp = crc(src_buf, lenth);
*(src_buf+lenth) = crc_tmp >> 8 ;
*(src_buf+lenth+1) = crc_tmp & 0xff;
lenth++;
//lenth++;
while (lenth--)
{
*dst_buf = *src_buf;
dst_buf++;
src_buf++;
}
}
//02 讀取輸入狀態
int rtu_read_input_status(unsigned char device_adr, unsigned char *com_buf, int start_address, int lenth)
{
unsigned char tmp[64], tmp_lenth = 6;
tmp[0] = device_adr;
tmp[1] = READ_IS;
tmp[2] = 0x00;
tmp[3] = start_address - 1;
tmp[4] = 0;
tmp[5] = lenth;
construct_rtu_frm ( com_buf,tmp,tmp_lenth);
return 8;
}
//03 讀取保持暫存器
int rtu_read_hldreg ( unsigned char device_adr,unsigned char *com_buf,int start_address,int lenth)
{
unsigned char tmp[64], tmp_lenth = 6;
tmp[0] = device_adr;
tmp[1] = READ_HR;
tmp[2] = 0x00;
tmp[3] = start_address - 1;
tmp[4] = 0;
tmp[5] = lenth;
construct_rtu_frm ( com_buf,tmp,tmp_lenth);
return 8;
}
// 4 發送讀取輸入暫存器
int rtu_read_inptreg( unsigned char device_adr,unsigned char *com_buf,int start_address,int lenth)
{
unsigned char tmp[64], tmp_lenth = 6;
tmp[0] = device_adr;
tmp[1] = READ_IR;
tmp[2] = 0x00;
tmp[3] = start_address - 1;
tmp[4] = 0;
tmp[5] = lenth;
construct_rtu_frm ( com_buf,tmp,tmp_lenth);
return 8;
}
/*//RTU 接收分析:
dest_p 接收到資料指標
sourc_p 串口接收緩衝區指標
data_start_address 開始地址*/
int rtu_data_anlys(int *dest_p, unsigned char *source_p, int data_start_address, int fr_lenth)
{
unsigned short crc_result, crc_tmp;
unsigned char tmp1, tmp2, shift;
crc_tmp = *(source_p + fr_lenth-2); // crc 第一位元組
crc_tmp = crc_tmp * 256 + *( source_p+fr_lenth-1); // CRC 值
crc_result = crc(source_p, fr_lenth-2); // 計算CRC 值
if ( crc_tmp != crc_result ) // CRC 校驗正確
{
//hld_reg[0x31]++;
return -1;
}
switch ( *(source_p+1) ) // 功能碼
{
case READ_IS: //讀取輸入狀態
for ( tmp1=0; tmp1<*( source_p+2); tmp1++)
{
shift = 1;
for (tmp2=0; tmp2<8; tmp2 ++)
{
*(dest_p + data_start_address + tmp1*8 + tmp2) = shift & *( source_p+3);
*( source_p+3)>>=1;
}
}
break;
case READ_HR: //讀取保持寄存器
for ( tmp1=0; tmp1<*( source_p+2); tmp1+=2)
{
*(dest_p + data_start_address+ tmp1/2)= *( source_p+tmp1+3)*256 + *( source_p+tmp1+4) ;
}
break ;
case READ_IR: //讀取輸入寄存器
for ( tmp1=0; tmp1<*( source_p+2); tmp1+=2)
{
*(dest_p + data_start_address+ tmp1/2) = *( source_p+tmp1+3)*256 + *( source_p+tmp1+4) ;
}
break;
case PROTOCOL_EXCEPTION:
return -1*PROTOCOL_ERR;
//break;
default:
return -1*PROTOCOL_ERR;
//break;
}
return 0;
}
// 2004/12/2 Milkyway.Lee
int read485reg_init(int brt)
{
/*if (brt == 2400)
{
// Setup Baud rate 2400
*(volatile unsigned short*) BRSR1 = (ARM_CLOCK/(16 * UART3_BIT_RATE)) - 1;
}
else if (brt == 4800)
{
// Setup Baud rate 4800
*(volatile unsigned short*) BRSR1 = (ARM_CLOCK/(16 * UART2_BIT_RATE)) - 1;
}
else*/ if (brt == 9600)
{
//default: Setup Baud rate 9600
*(volatile unsigned short*) BRSR1 = (ARM_CLOCK/(16 * UART1_BIT_RATE)) - 1;
}
*(volatile unsigned short*) MSR1 = 0x0000; // disable all interrupt
*(volatile unsigned short*) RFCR1 = 0x8200; // clear Rx FIFO
*(volatile unsigned short*) TFCR1 = 0x8200; // clear Tx FIFO
*(volatile unsigned short*) LCR1 = 0x0000; // no-BREAK
// *(volatile unsigned short*) TFCR1 &= 0x7FFF; //set counter 0
*(volatile unsigned short*) BITDIR0 &= 0xEFEF; // GIO 12&4 Output
PRINTK("Clear Count : %x\n", (*(volatile unsigned short*) RFCR1 & 0x003F));
PRINTK("Rec Empty Flag : 0x%x\n", (*(volatile unsigned short*) SR1 & 0x0004));
return 1;
}
int write485sd(char* sendbuf, unsigned short len)
{
unsigned short usbuf; unsigned int j=0; unsigned short i;
PRINTK("sendbuf = %x %x %x %x %x %x\n",
*sendbuf,*(sendbuf+1),*(sendbuf+2),*(sendbuf+3),*(sendbuf+4),*(sendbuf+5));
*(volatile unsigned short*) TFCR1 &= 0x8000; // Clear Tx FIFO
*(volatile unsigned short*)BITSET0 = 0x1010; // SET GIO12 & GIO4
i=len;
while (i)
{
//check TX FIFO has data?
usbuf = *(volatile unsigned short*) SR1 & 0x0001;
if (usbuf == 1)
{
*(volatile unsigned short*) DTRR1 = *sendbuf++;
i--;
}
}
//usleep(8000);
//while((*(volatile unsigned short*) SR1 & 0x0001)!=0x01 ){j++;} //Send FIFO is empty status
j=6;
while (j)
{
//check TX FIFO has data?
usbuf = *(volatile unsigned short*) SR1 & 0x0001;
if (usbuf == 1)
{
*(volatile unsigned short*) RFCR1 &= 0x8000; // clear Rx FIFO
// *(volatile unsigned short*)BITCLR0 = 0x1010; //CLR GIO12 & GIO4
j=0;
}
}
// *(volatile unsigned short*) RFCR1 &= 0x8000; // clear Rx FIFO
*(volatile unsigned short*)BITCLR0 = 0x1010; //CLR GIO12 & GIO4
}
int read485sd(char* buf)
{
unsigned int tmp=0,count=0,i;
unsigned char Data[120];
tmp=0;
while(1)
{
if ((*(volatile unsigned short*) RFCR1 & 0x003F) != 0x0 )
{
Data[tmp]= 0x00;
Data[tmp]= *(volatile unsigned short*) DTRR1 & 0xff; // read data from dsc25 register
tmp++;
count = 0;
}
else
{
count++;
for (i=0;i<500;i++)
{
}
if (count>3)
{
memcpy(buf,Data,tmp);
/* PRINTK("Data = %x %x %x %x %x %x\n",
Data[0],Data[1],Data[2],Data[3],Data[4],Data[5]);
*(volatile unsigned short*) RFCR1 = 0x8200; // clear Rx FIFO
*(volatile unsigned short*) RFCR1 &= 0x7FFF;
PRINTK("Received Byte = %d\n",tmp);
return tmp; */
}
}
}
}
int msec_delay(int m_sec)
{
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = m_sec*1000;
select(1,NULL,NULL,NULL,&tv);
return 0;
}
第二個是main.c 複製程式
/*
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <getopt.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <errno.h>
#include <linux/types.h>
#include <unistd.h>
#include <sys/times.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/ioctl.h>
#include <net/if.h>
#include <netdb.h>
#include <ctype.h>
#include <fcntl.h>
#include <termios.h> /*PPSIX終端控制定義*/
#include <errno.h>
#include "uart.h"
#define PRINTK(str...) printf(str)
#define GIO_DO_ENABLE 0x8000 //GIO15
#define FALSE -1
#define TRUE 0
#define READ_IS 02
#define READ_HR 03
#define READ_IR 04
#define PROTOCOL_EXCEPTION 0x81
#define PROTOCOL_ERR 1
int IS[64], HR[64], IR[64];
int read485reg_init(int brt);
int OpenDev(char *Dev);
void set_speed(int fd, int speed);
int set_parity(int fd,int databits,int parity,int stopbits);
int rtu_read_input_status(unsigned char device_adr, unsigned char *com_buf, int start_address, int lenth);
int rtu_read_hldreg ( unsigned char device_adr,unsigned char *com_buf,int start_address,int lenth);
int rtu_read_inptreg( unsigned char device_adr,unsigned char *com_buf,int start_address,int lenth);
int rtu_data_anlys(int *dest_p, unsigned char *source_p, int data_start_address, int fr_lenth);
//char resp_cmd[120];
static char resp_cmd[80];
int name_speed[4];
static int rd_result;
// MAIN()
int main(int argc, char *argv[])
{
int fd;
char tx_buf[256], rx_buf[256], *dev ="/dev/ttyS0";
fd = OpenDev(dev);
*(unsigned short*)DIR0 = *(unsigned short*)DIR0 & (~GIO_DO_ENABLE);
*(unsigned short*)BITCLR0 = GIO_DO_ENABLE ;
//set baud rate: 2400 4800 9600
read485reg_init(9600);
while(1)
{
if ((*(volatile unsigned short*) RFCR1 & 0x003F) != 0x0 )
{
memset(resp_cmd,0x00,sizeof(resp_cmd));
rd_result = read485sd(resp_cmd);
PRINTK("Get from Sensor %d bytes:\n",rd_result);
PRINTK("Command %s:\n",resp_cmd);
}
else
{
PRINTK("THERE is NOthing\n"); // no data
break;
}
}
if (fd>0)
set_speed(fd,*name_speed);
else{
printf("Can't Open Serial Port!\n");
exit(0);
}
if (set_parity(fd, 8, 'N', 2)== FALSE)
{
printf("Set Parity Error\n");
exit(1);
}
/*
while(1)
{
while((nread = read(fd,buff,512))>0)
{
printf("\nLen %d\n",nread);
buff[nread+1]='\0'
printf("\n%s",buff);
}
}*/
rtu_read_input_status(1,tx_buf,1,3);
write (fd, tx_buf, sizeof(tx_buf));
//PRINTK("Command 02: [%x] [%x] [%x] [%x] [%x] [%x]\n",
//tx_buf[0],tx_buf[1],tx_buf[2],tx_buf[3],tx_buf[4],tx_buf[5]);
read (fd, rx_buf, sizeof(rx_buf));
rtu_data_anlys(IS, rx_buf, 1, 6);
PRINTK("Response Data 02: [%x] [%x] [%x] [%x] [%x] [%x]\n",
rx_buf[0],rx_buf[1],rx_buf[2],rx_buf[3],rx_buf[4],rx_buf[5]);
rtu_read_hldreg(1,tx_buf,1,10);
write (fd, tx_buf, sizeof(tx_buf));
//PRINTK("Command 03: [%x] [%x] [%x] [%x] [%x] [%x]\n",
//tx_buf[0],tx_buf[1],tx_buf[2],tx_buf[3],tx_buf[4],tx_buf[5]);
read (fd, rx_buf, sizeof(rx_buf));
rtu_data_anlys(HR, rx_buf, 1, 6);
PRINTK("Response Data 03: [%x] [%x] [%x] [%x%x] [%x%x] [%x%x] [%x%x] [%x%x] [%x%x] [%x%x] [%x%x] [%x%x] [%x%x] [%x] [%x]\n",
rx_buf[0],rx_buf[1],rx_buf[2],rx_buf[3],rx_buf[4],rx_buf[5],rx_buf[6],rx_buf[7],rx_buf[8],rx_buf[9],rx_buf[10],rx_buf[11],rx_buf[12],rx_buf[13],rx_buf[14],rx_buf[15],rx_buf[16],rx_buf[17],rx_buf[18],rx_buf[19],rx_buf[20],rx_buf[21],rx_buf[22],rx_buf[23],rx_buf[24]);
rtu_read_inptreg(1,tx_buf,1,5);
write (fd, tx_buf, sizeof(tx_buf));
//PRINTK("Command 04: [%x] [%x] [%x] [%x] [%x] [%x]\n",
//tx_buf[0],tx_buf[1],tx_buf[2],tx_buf[3],tx_buf[4],tx_buf[5]);
read (fd, rx_buf, sizeof(rx_buf));
rtu_data_anlys(IR, rx_buf, 1, 6);
PRINTK("Response Data 04: [%x] [%x] [%x] [%x%x] [%x%x] [%x%x] [%x%x] [%x%x] [%x] [%x]\n",
rx_buf[0],rx_buf[1],rx_buf[2],rx_buf[3],rx_buf[4],rx_buf[5],rx_buf[6],rx_buf[7],rx_buf[8],rx_buf[9],rx_buf[10],rx_buf[11],rx_buf[12],rx_buf[13],rx_buf[14]);
close(fd);
return 0;
}
|