2017-02-16 1 views
1

나는 GSM 모듈을 구입했으며 USB를 통해 직렬 인터페이스 (FT232의 구성 요소 이름)를 통해 제어하려고합니다.직렬 포트에서 데이터를 계속 수신하는 이유는 무엇입니까?

나는 GSM 모듈 이전에 FT232를 (TX와 RX를 연결하여) 테스트하기 위해 약간의 프로그램을 작성했으며 문제에 직면했다.

데이터를 전송할 수 있으며 (같은 "잘하면") 동일한 데이터를받을 수 있지만 데이터를 반복해서 수신합니다 (종종 '0x0A'와 때로는 원래 데이터 : "AT \ r"). ...

이 문제를 해결하도록 도와 줄 수 있습니까?


코드 결과

#include <fcntl.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/ioctl.h> 
#include <sys/select.h> 
#include <sys/time.h> 
#include <sys/types.h> 
#include <termios.h> 
#include <unistd.h> 

int open_serial(); 

int close_serial(int serial_fd); 

int read_serial (int fd); 

int main() 
{ 
    int serial_fd = open_serial(); 

    if (serial_fd == EXIT_FAILURE) 
     return EXIT_FAILURE; 

    struct termios old_termios; 
    struct termios serial_termios; 

    // Port configuration backup 
    tcgetattr(serial_fd, &old_termios); 
    serial_termios = old_termios; 
    // Port setup 
    serial_termios.c_cflag |= (B9600 | CS8 | CLOCAL | CREAD); 
    serial_termios.c_lflag |= (ICANON); 
    // Port configuration update 
    tcsetattr(serial_fd, TCSANOW, &serial_termios); 

    int num_char; 
    char* str2send = "AT\r"; 

    num_char = write(serial_fd, str2send, strlen(str2send)); 
    if (num_char < 0) 
    { 
     fputs("FAIL !\n", stderr); 
    } 
    else 
    { 
     printf("%d char sended\n", num_char); 
    } 

    fd_set serial_in; 
    int count=0;  

    while ((read_serial(serial_fd) > 0) & (count < 25)) 
     count++; 

    // Port configuration restore 
    tcsetattr(serial_fd, TCSANOW, &old_termios); 

    return close_serial(serial_fd); 
} 

int open_serial() 
{ 
    int serial_fd = open("/dev/ttyUSB0", O_RDWR | O_NOCTTY | O_NDELAY); 

    printf("Serial port opening...\n"); 
    if (serial_fd == -1) 
    { 
     printf("FAIL !\n"); 
     perror("open()"); 
     return EXIT_FAILURE; 
    } 
    printf("SUCCESS ! [FD] : [%02d]\n", serial_fd); 

    return serial_fd; 
} 

int close_serial(int serial_fd) 
{ 
    printf("Serial port closing...\n[FD] : [%02d]\n", serial_fd); 
    if (close(serial_fd) == -1) 
    { 
     printf("FAIL !\n"); 
     perror("close()"); 
     return EXIT_FAILURE; 
    } 
    printf("SUCCESS !\n"); 

    return EXIT_SUCCESS; 
} 
int read_serial (int fd) 
{ 
    char rcv_serial [256]; 
    int max_fd = fd + 1; 
    fd_set input; 
    FD_ZERO(&input); 
    FD_SET(fd, &input); 
    int count; 
    // 1sec timeout 
    struct timeval timeout; 
    timeout.tv_sec = 1; 
    timeout.tv_usec = 0; 

    int nb_char, ret_read; 
    int ret_sel = select(max_fd, &input, NULL, NULL, &timeout); 
    if (ret_sel < 0) 
    { 
     perror("select() :"); 
    } 
    else if (ret_sel == 0) 
    { 
     printf("TIMEOUT\n"); 
    } 
    else 
    { 
     if (FD_ISSET(fd, &input)) 
     { 
      nb_char = 10; 
      ioctl(fd, FIONREAD, &nb_char); 
      printf("%d chars availables\n", nb_char); 
      ret_read = read(fd, &rcv_serial, nb_char); 
      printf("[ RET READ : %d]\n", ret_read); 
      rcv_serial[ret_read] ='\0'; 
      for (count = 0; count < ret_read; count++) 
       printf("[%02X]", rcv_serial[count]); 
      printf("\n"); 
      //printf("[%s]\n", rcv_serial); 
     } 
    } 
    return ret_sel; 
} 

main.c를

Serial port opening... 
SUCCESS ! [FD] : [03] 
3 char sended 
3 chars availables 
[ RET READ : 3] 
[41][54][0A] 
3 chars availables 
[ RET READ : 3] 
[41][54][0A] 
1 chars availables 
[ RET READ : 1] 
[0A] 
3 chars availables 
[ RET READ : 3] 
[41][54][0A] 
1 chars availables 
[ RET READ : 1] 
[0A] 
1 chars availables 
[ RET READ : 1] 
[0A] 
1 chars availables 
[ RET READ : 1] 
[0A] 
3 chars availables 
[ RET READ : 3] 
[41][54][0A] 
1 chars availables 
[ RET READ : 1] 
[0A] 
1 chars availables 
[ RET READ : 1] 
[0A] 
1 chars availables 
[ RET READ : 1] 
[0A] 
Serial port closing... 
+1

, 그것은 동일 할 것입니다. AT 명령은' "\ r \ n" "으로 끝나고"\ n "은' '== 0xA' 일 수 있습니다. –

+0

답변 해 주셔서 감사합니다. 이 명령으로 의미가 있지만 새 메시지 나 수신 전화가 있는지 어떻게 알 수 있습니까? 시리얼 포트를 계속 확인해야합니까? – Teutates

+0

@ Fiddling-Bits, 새로운 데이터를받지 못하면 칩의 레지스터가 변경되지 않고받은 마지막 문자가 포함되어 있다고 말합니다. 많은 의미가 있습니다. 'read_serial'에 대한 그의 부탁은 어떨까요? 새로운 데이터가 수신되지 않는 동안 차단해야하거나 0을 반환해야합니까? –

답변

0

덕분에 코멘트를 @sawdust합니다. 나는이 입력 에코를 사용하지 않도록 내 문제를 해결하기 위해 추가 : 새로운 데이터가 없습니다 때 DR을 읽을 계속되면

serial_termios.c_lflag &= ~(ECHO | ECHOE | ECHONL | IEXTEN) 
관련 문제