ceju.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #include<stdio.h>
  2. #include<termios.h>
  3. #include<string.h>
  4. #include<sys/types.h>
  5. #include<sys/stat.h>
  6. #include<fcntl.h>
  7. #include<unistd.h>
  8. #include<stdlib.h>
  9. #include<stdint.h>
  10. int set_uart(int fd,int speed,int bits,char check,int stop)
  11. {
  12. struct termios newtio,oldio;
  13. if(tcgetattr(fd,&oldio)!=0)
  14. {
  15. printf("tcgetattr oldio error\n");
  16. return -1;
  17. }
  18. bzero(&newtio,sizeof(newtio));
  19. newtio.c_cflag |= CLOCAL | CREAD ;
  20. newtio.c_cflag &= ~CSIZE;
  21. switch(bits)
  22. {
  23. case 7:
  24. newtio.c_cflag |= CS7;
  25. break;
  26. case 8:
  27. newtio.c_cflag |=CS8;
  28. break;
  29. }
  30. switch(check)
  31. {
  32. case 'O':
  33. newtio.c_cflag |= PARENB;
  34. newtio.c_cflag |= PARODD;
  35. newtio.c_iflag |= (INPCK|ISTRIP);
  36. break;
  37. case 'E':
  38. newtio.c_cflag |= PARENB;
  39. newtio.c_cflag |=~PARODD;
  40. newtio.c_iflag |= (INPCK|ISTRIP);
  41. break;
  42. case 'N':
  43. newtio.c_cflag &= ~PARENB;
  44. break;
  45. }
  46. switch(speed)
  47. {
  48. case 9600:
  49. cfsetispeed(&newtio,B9600);
  50. cfsetospeed(&newtio,B9600);
  51. break;
  52. case 115200:
  53. cfsetispeed(&newtio,B115200);
  54. cfsetospeed(&newtio,B115200);
  55. break;
  56. }
  57. switch(stop)
  58. {
  59. case 1:
  60. newtio.c_cflag &= ~CSTOPB;
  61. break;
  62. case 2:
  63. newtio.c_cflag |=CSTOPB;
  64. break;
  65. }
  66. tcflush(fd,TCIFLUSH);
  67. if(tcsetattr(fd,TCSANOW,&newtio)!=0)
  68. {
  69. printf("tcsetattr newtio error\n");
  70. return -2;
  71. }
  72. return 0;
  73. }
  74. uint16_t CRC16_Modbus(uint8_t *data, uint8_t length) {
  75. uint16_t crc = 0xFFFF; // 初始化CRC寄存器
  76. for (uint8_t i = 0; i < length; i++) {
  77. crc ^= data[i]; // 与当前字节异或
  78. for (uint8_t j = 0; j < 8; j++) { // 处理每一位
  79. if (crc & 0x0001) {
  80. crc = (crc >> 1) ^ 0xA001; // 异或多项式
  81. } else {
  82. crc >>= 1;
  83. }
  84. }
  85. }
  86. // 高低字节交换
  87. return (crc >> 8) | (crc << 8);
  88. }
  89. int main(int argc,char *argv[])
  90. {
  91. int fd;
  92. unsigned char buf[128];
  93. int count;
  94. fd= open("/dev/ttyS7",O_RDWR |O_NOCTTY | O_NDELAY);
  95. if(fd < 0)
  96. {
  97. printf("open ttyS7 error\n");
  98. return -1;
  99. }
  100. /*
  101. fd= open("/dev/ttyS9",O_RDWR |O_NOCTTY | O_NDELAY);
  102. if(fd < 0)
  103. {
  104. printf("open ttyS9 error\n");
  105. return -1;
  106. }
  107. */
  108. set_uart(fd,9600,8,'N',1);
  109. // 定义要发送的十六进制数据:01 03 02 01 00 01 D4 72
  110. unsigned char send_data[] = {0x01, 0x03, 0x02, 0x01, 0x00, 0x01, 0xD4, 0x72};
  111. uint16_t crc_data= CRC16_Modbus(send_data, 6);
  112. printf("读取到 %X 字节响应数据:\n", crc_data);
  113. int send_len = sizeof(send_data); // 获取数据长度(8字节)
  114. // 发送数据
  115. ssize_t write_ret = write(fd, send_data, send_len);
  116. if (write_ret < 0)
  117. {
  118. perror("write serial port error");
  119. close(fd);
  120. return -1;
  121. }
  122. printf("成功发送 %zd 字节数据:", write_ret);
  123. for (int i = 0; i < send_len; i++)
  124. {
  125. printf("%02X ", send_data[i]);
  126. }
  127. printf("\n");
  128. //write(fd,argv[1],strlen(argv[1]));
  129. sleep(1);
  130. count=read(fd,buf,sizeof(buf));
  131. if (count < 0)
  132. {
  133. perror("read serial port error");
  134. }
  135. else if (count == 0)
  136. {
  137. printf("未读取到响应数据\n");
  138. }
  139. else
  140. {
  141. printf("读取到 %d 字节响应数据:", count);
  142. for (int i = 0; i < count; i++)
  143. {
  144. printf("%02X ", buf[i]); // 十六进制格式打印响应
  145. }
  146. printf("\n");
  147. }
  148. close(fd);
  149. return 0;
  150. }