usart.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <fcntl.h>
  4. #include <linux/types.h>
  5. //#include <linux/jiffies.h>
  6. #include <unistd.h>
  7. #include <stdint.h>
  8. #include <string.h>
  9. #include <errno.h>
  10. #include <pthread.h>
  11. #include <fcntl.h>
  12. #include <sys/socket.h>
  13. #include <netdb.h> /* getaddrinfo(3) et al. */
  14. #include <netinet/in.h> /* sockaddr_in & sockaddr_in6 definition. */
  15. #include <net/if.h>
  16. #include <sys/prctl.h>
  17. #include "driver.h"
  18. #include "hal_interface_api.h"
  19. #include <termios.h>
  20. #include <unistd.h>
  21. #include <stdlib.h>
  22. #include <fcntl.h>
  23. #include <linux/kernel.h>
  24. #include <stdio.h>
  25. #include <pthread.h>
  26. #include <string.h>
  27. #include <sys/select.h>
  28. #include <sys/time.h>
  29. char rev_buf[256];
  30. char databuf[] = {1,2,0x33,0x34,0x35,6,7,11,12,89};
  31. int uart_fd;
  32. #define DEV_NAME "/dev/ttyS2"
  33. int Set_Com_Config(int fd, int baud_rate, int data_bits, char parity, int stop_bits)
  34. {
  35. struct termios new_cfg, old_cfg;
  36. int speed;
  37. /*保存并测试现有串口参数设置,在这里如果串口号等出错,会有相关出错信息*/
  38. if(tcgetattr(fd, &old_cfg) != 0) /*该函数得到fd指向的终端配置参数,并将它们保存到old_cfg变量中,成功返回0,否则-1*/
  39. {
  40. perror("tcgetttr");
  41. return -1;
  42. }
  43. /*设置字符大小*/
  44. new_cfg = old_cfg;
  45. cfmakeraw(&new_cfg); /*配置为原始模式*/
  46. new_cfg.c_cflag &= ~CSIZE; /*用位掩码清空数据位的设置*/
  47. /*设置波特率*/
  48. switch(baud_rate)
  49. {
  50. case 2400:
  51. speed = B2400;
  52. break;
  53. case 4800:
  54. speed = B4800;
  55. break;
  56. case 9600:
  57. speed = B9600;
  58. break;
  59. case 19200:
  60. speed = B19200;
  61. break;
  62. case 38400:
  63. speed = B38400;
  64. break;
  65. default:
  66. case 115200:
  67. speed = B115200;
  68. break;
  69. }
  70. cfsetispeed(&new_cfg, speed); //设置输入波特率
  71. cfsetospeed(&new_cfg, speed); //设置输出波特率
  72. /*设置数据长度*/
  73. switch(data_bits)
  74. {
  75. case 5:
  76. new_cfg.c_cflag &= ~CSIZE;//屏蔽其它标志位
  77. new_cfg.c_cflag |= CS5;
  78. break;
  79. case 6:
  80. new_cfg.c_cflag &= ~CSIZE;//屏蔽其它标志位
  81. new_cfg.c_cflag |= CS6;
  82. break;
  83. case 7:
  84. new_cfg.c_cflag &= ~CSIZE;//屏蔽其它标志位
  85. new_cfg.c_cflag |= CS7;
  86. break;
  87. default:
  88. case 8:
  89. new_cfg.c_cflag &= ~CSIZE;//屏蔽其它标志位
  90. new_cfg.c_cflag |= CS8;
  91. break;
  92. }
  93. /*设置奇偶校验位*/
  94. switch(parity)
  95. {
  96. default:
  97. case 'n':
  98. case 'N': //无校验
  99. {
  100. new_cfg.c_cflag &= ~PARENB;
  101. new_cfg.c_iflag &= ~INPCK;
  102. }
  103. break;
  104. case 'o': //奇校验
  105. case 'O':
  106. {
  107. new_cfg.c_cflag |= (PARODD | PARENB);
  108. new_cfg.c_iflag |= INPCK;
  109. }
  110. break;
  111. case 'e': //偶校验
  112. case 'E':
  113. {
  114. new_cfg.c_cflag |= PARENB;
  115. new_cfg.c_cflag &= ~PARODD;
  116. new_cfg.c_iflag |= INPCK;
  117. }
  118. break;
  119. }
  120. /*设置停止位*/
  121. switch(stop_bits)
  122. {
  123. default:
  124. case 1:
  125. new_cfg.c_cflag &= ~CSTOPB;
  126. break;
  127. case 2:
  128. new_cfg.c_cflag |= CSTOPB;
  129. break;
  130. }
  131. /*设置等待时间和最小接收字符*/
  132. new_cfg.c_cc[VTIME] = 1; /* 读取一个字符等待1*(1/10)s */
  133. new_cfg.c_cc[VMIN] = 1; /* 读取字符的最少个数为1 */
  134. /*处理未接收字符*/
  135. tcflush(fd, TCIFLUSH); //溢出数据可以接收,但不读
  136. /* 激活配置 (将修改后的termios数据设置到串口中)
  137. * TCSANOW:所有改变立即生效
  138. */
  139. if((tcsetattr(fd, TCSANOW, &new_cfg))!= 0)
  140. {
  141. perror("tcsetattr");
  142. return -1;
  143. }
  144. return 0;
  145. }
  146. int Uart_Send(int fd, char *data, int data_len)
  147. {
  148. int len = 0;
  149. len = write(fd, data, data_len);
  150. if(len == data_len) {
  151. return len;
  152. } else {
  153. tcflush(fd, TCOFLUSH); //TCOFLUSH刷新写入的数据但不传送
  154. return -1;
  155. }
  156. }
  157. int Uart_Recv(int fd, char *rev_buf, int data_len)
  158. {
  159. int len, fs_sel;
  160. fd_set fs_read;
  161. struct timeval tv_timeout;
  162. FD_ZERO(&fs_read); //清空集合
  163. FD_SET(fd,&fs_read); // 将一个给定的文件描述符加入集合之中
  164. tv_timeout.tv_sec = 5;
  165. tv_timeout.tv_usec = 0;
  166. //使用select实现串口的多路通信
  167. fs_sel = select(fd + 1, &fs_read, NULL, NULL, &tv_timeout); //如果select返回值大于0,说明文件描述符发生了变化
  168. //printf("fs_sel = %d\n",fs_sel); //如果返回0,代表在描述符状态改变前已超过timeout时间,错误返回-1
  169. if(fs_sel)
  170. {
  171. len = read(fd, rev_buf, data_len);
  172. printf("len = %d, fs_sel = %d\n", len, fs_sel);
  173. return len;
  174. }
  175. else
  176. {
  177. return 0;
  178. }
  179. }
  180. int Uart_Init(int fd, int speed, int databits, int parity, int stopbits)
  181. {
  182. //设置串口数据帧格式
  183. if (Set_Com_Config(fd, speed, databits, parity, stopbits) == 0)
  184. {
  185. return 0;
  186. }
  187. else
  188. {
  189. return -1;
  190. }
  191. }
  192. int Uart_Receive_thread(void)
  193. {
  194. int r_count;
  195. int i;
  196. while(1)
  197. {
  198. r_count = Uart_Recv(uart_fd, rev_buf, sizeof(rev_buf));
  199. if(r_count)
  200. {
  201. for(i = 0; i < r_count; i++)
  202. {
  203. printf("rev_buf[%d] = 0x%x\n", i, rev_buf[i]);
  204. }
  205. }
  206. }
  207. }
  208. void Uart_Send_thread(void)
  209. {
  210. int s_count;
  211. while(1)
  212. {
  213. sleep(1);
  214. printf("This is Uart_Send_thread.\n");
  215. s_count = Uart_Send(uart_fd, databuf, strlen(databuf));
  216. if(s_count == -1)
  217. printf("Uart_Send Error!\n");
  218. else
  219. printf("Send %d data successfully!\n", s_count);
  220. }
  221. }
  222. int main(int argc, char *argv[])
  223. {
  224. pthread_t id_Uart_Receive, id_Uart_Send;
  225. int ret1, ret2;
  226. uart_fd = open(DEV_NAME, O_RDWR | O_NOCTTY);
  227. if(uart_fd == -1)
  228. {
  229. printf("Uart Open Failed!\n");
  230. exit(EXIT_FAILURE);
  231. }
  232. if(Uart_Init(uart_fd, 115200, 8, 'N', 1) == -1)
  233. {
  234. printf("Uart_Init Failed!\n");
  235. exit(EXIT_FAILURE);
  236. }
  237. ret1 = pthread_create(&id_Uart_Receive, NULL, (void *) Uart_Receive_thread, NULL);
  238. ret2 = pthread_create(&id_Uart_Send, NULL, (void *) Uart_Send_thread, NULL);
  239. if(ret1!=0){
  240. printf ("Create Uart_Receive_thread error!\n");
  241. close(uart_fd);
  242. exit (1);
  243. }
  244. if(ret2!=0){
  245. printf ("Create Uart_Send_thread error!\n");
  246. close(uart_fd);
  247. exit (1);
  248. }
  249. while(1)
  250. {
  251. printf("This is the main process.\n");
  252. usleep(1000000);
  253. }
  254. pthread_join(id_Uart_Receive, NULL);
  255. pthread_join(id_Uart_Send, NULL);
  256. return 0;
  257. }