2013-03-21 3 views
2

직렬 포트를 통해 LPC 1786 마이크로 컨트롤러에 명령을 보내려면 어떻게해야합니까? 이 작업을 수행하기 위해이 코드를 사용하여 직렬 포트를 엽니 다.LPC1786과의 직렬 통신

struct termios tio; 
int tty_fd; 

memset(&tio,0,sizeof(tio)); 
tio.c_iflag = 0; 
tio.c_oflag = 0; 
tio.c_cflag = CS8|CREAD|CLOCAL;   // 8n1, see termios.h for more information 
tio.c_lflag = 0; 
tio.c_cc[VMIN] = 1; 
tio.c_cc[VTIME] = 5; 

tty_fd = open(device, O_RDWR | O_NONBLOCK); 
cfsetospeed(&tio, B9600);   // 115200 baud 
cfsetispeed(&tio, B9600);   // 115200 baud 
tcflush(tty_fd, TCIFLUSH); 

이것은 (iMX53)을 사용하는 임베디드 리눅스 시스템 용입니다. 내 PC에서 코드를 컴파일하고 실행할 때. 나는 이것을 얻는다 :

sent: ? 
recieve: Sinchronized<CR><LF> 
sent: Sinchronized<CR><LF> 
recieve: Synchronized<CR>OK<CR><LF> 
sent: 16000<CR><LF> 
recieve: 16000<CR>OK<CR><LF> 

마녀는 좋다. 내가 그것을 컴파일하고 그것을 시스템에 업로드 할 때 나는 이것을 얻는다.

Sent: ? 
HEX: 0x53 0x79 0x6E 0x63 0x68 0x72 0x6F 0x6E 0x69 0x7A 0x65 0x64 0xA 0xA 0x53 0x79 0x6E 0x63 0x68 0x72 0x6F 0x6E 0x69 0x7A 0x65 0xA 
ASCII: SynchronizedSynchronizedOKOKnchronized1K024K024chronized1 

Sent: ? 
HEX: 0xA 0xA 0xA 0xA 0xA 0xA 0xA 0x30 0xA 0xA 0x31 0xA 0xA 0xA 0xA 0xA 0xA 0x34 0xA 0xA 0x31 0xA 0xA 0xA 0xA 0xA 0xA 0xA 0xA 0xA 0A 
ASCII: 014141hronized1111111ronized1 

마녀 종류의 폐허. 쓰기와 읽기를 위해서 나는 write 함수 &을 쓰고있다. 나는 이것이 내가 직렬 포트를 여는 방식과 관련이 있다고 생각한다. 그러나 무엇이 잘못 되었습니까. 나는 다른 설정을 시도했지만 거의 성공하지 못했습니다. 응답으로 나는 "????? 1 ???"을 얻는다. 그리고 대부분의 시간은 읽을 것이 없습니다. (내 자신의 &의 육성쪽으로 기울어 개발 시스템의 일부를 추가)

이 두 :

+2

어떤 보오율로 뛰고 있습니까? 이러한 종류의 문제는 항상 보오율 불일치의 냄새가납니다. 코드에서 9600, 주석에서 115200을 볼 수 있으며 호스트 측에서 무엇이 있는지 전혀 알 수 없습니다. P – slugonamission

+0

다른 속도를 테스트하고있었습니다. 호스트 -> 속도 9600 보드, stty :/dev/ttymxc4 intr =^C; 종료 =^\; 지우기 = ^?; 죽이기 =^U; eof =^D; eol = ; eol2 = ; 시작 =^Q; 정지 =^S; susp =^Z; rprnt =^R; werase =^W; lnext =^V; flush =^O; min = 1; 시간 = 0; -parenb -parodd CS8 hupcl -cstopb cread CLOCAL -crtscts -ignbrk -brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr ICRNL IXON -ixoff -iuclc -ixany -imaxbel opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0 isext ico echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke – DimDqkov

+0

그건 이상한 것입니다. 프로세서의 입력 클럭이 맞습니까? – slugonamission

답변

3

근본적인 문제를 볼 수 있습니다 귀하의 코드가 tty 포트를 (제대로) 초기화하지 않았다는 것을 나타냅니다. 기본적으로 초기화는 tcsetattr()을 호출하여 지정한 업데이트 된 구성을 설치하지 않습니다.

tty 포트를 초기화하는 올바른 방법은 포트를 열고, 현재 속성을 얻고, 프로그램 종료시 복원을 위해 현재 속성을 저장하고, 속성을 수정하고, 속성을 설치하는 것입니다. 그리고 항상 시스템 호출에서 리턴 코드를 테스트하십시오.

tty_fd = open(device, O_RDWR | O_NONBLOCK); 
    if (tty_fd< 0) { 
     syslog(LOG_DEBUG, "failed to open: %d, %s", tty_fd, strerror(errno)); 
     exit (-1); 
    } 
    rc = tcgetattr(tty_fd, &tio); 
    if (rc < 0) { 
     syslog(LOG_DEBUG, "failed to get attr: %d, %s", rc, strerror(errno)); 
     exit (-2); 
    } 
    savetio = tio; /* preserve original settings for restoration */ 

    spd = B9600; 
    cfsetospeed(&tio, (speed_t)spd); 
    cfsetispeed(&tio, (speed_t)spd); 

    cfmakeraw(&tio); 

    tio.c_cc[VMIN] = 1; 
    tio.c_cc[VTIME] = 5; 

    tio.c_cflag &= ~CSTOPB; 
    tio.c_cflag &= ~CRTSCTS; /* no HW flow control? */ 
    tio.c_cflag |= CLOCAL | CREAD; 
    rc = tcsetattr(tty_fd, TCSANOW, &tio); 
    if (rc < 0) { 
     syslog(LOG_DEBUG, "failed to set attr: %d, %s", rc, strerror(errno)); 
     exit (-3); 
    } 

은 물론 또한 케이블 링이있을 수 있습니다 및 하드웨어 문제는 여전히 해결해야하지만, TTY 포트가 당신이 원하는 또는 필요 작동 상태로 초기화되지 않았기 때문에, 아무것도 예상대로 작동 할 가능성이 없습니다.

programming the serial port에 대한 안내입니다.

+0

tcsetattr을 호출하지 않는 것이 주요 문제였습니다. 나는 가이드를 살펴보고 약간의 변화를 구현했다. 나는 오히려 어리 석다고 느낀다. 얼마나 많은 시간을이 grrr에 썼는가. 이제는 잘 작동합니다. 고맙습니다. – DimDqkov

1

여기가이 질문에 대한 좋은 디버깅 의견을 많이하지만 직렬 링크를 확인하기 위해 항목의 요약 목록입니다 일종의 초기 디자인 레벨 검사입니다. 때때로 그들을 다시 방문하게됩니다 :

  • 데이터 시트를 확인하십시오 : 전압 레벨이 일치합니까? 예 : "True"RS232 대 TTL, 12v 대 5v 대 3v
  • 케이블 또는 회로 연결이 끊어집니다. 접지가 필요합니까? TX + TX- 등의 matchup이 다르면 rx가 tx로 이동합니까? (그것이 사용자 정의 또는 수작업으로 제작 케이블의 경우 특히)

이 더 일반적으로 다음과 같습니다 전송 속도는

  • 는, 데이터를 확인 정지 비트 및 제어 설정에 맞게 흐름과 일치

    • 확인하는 것이 양끝 모두
    • 낮은 전송 속도가 작동합니까?
    • 대체 케이블을 시도 할 가능성이 있습니까?
    • 가능성이 다른 PC를 시도하십시오 (랩톱 AC 전원으로 문제가 생길 수있는 이상한 접지 루프가 있음)
    • 가능하면 한쪽 끝을 "알려진 양"으로 만드십시오.

    이들은되는 희소 검사 :

    • 확인 직렬 주변기기의 전송 속도를 공급하는 임의의 입력 클록 설정. 범위 밖으로
    • 브레이크와 봐 신호가 손상지고있는 경우 (방법 "광장"당신의 레벨 변경은 그들이 당신이 당신의 하드웨어의 전압 레벨이 생각하는 것과 일치 할)
  • 1

    다른 답변에서 언급 된 문제 외에도, 하나의 가능한 원인은 MCU UART로 공급되는 잘못된 프리 스케일러 클럭입니다. UART는 +/- 3 %의 클록 정확도가 필요합니다. 사전 스케일러가 정확하지 않으면 정확히의 문제에 설명 된 문제가 발생합니다. 대부분의 경우 데이터가 정상적으로 보입니다. 그런 다음 갑자기 쓰레기가 생깁니다.

    문제를 해결할 때 수신자 측에서 오버런, 프레이밍 오류 등을 확인해야합니다. 오실로스코프로 신호를 확인하고 통신 속도를 측정하십시오. 은 오실로스코프가없는 임베디드 애플리케이션을 개발할 수 없으며 디버거와 마찬가지로 필수 도구입니다.

    1

    나는 마음에서 하드웨어 사람, 그래서 이런 일이 일어날 때, 나는 바닥에서 시작하는 경향이

    • 이 범위 또는 로직 분석기를 나가서 전송되는 비트 봐. 전송 속도를 확인하십시오. 문자를 확인하십시오. 비트를 해석하는 범위는 여기에 큰 도움이됩니다.

    • 만약 정상이면 바이트가 내장 프로세서로 들어가는 것을 확인하고 확인을 클릭합니다. 인터럽트 서비스 루틴을 확인하십시오. 항목을 입력 할 때 비트를 설정하고 종료하기 전에 선택을 취소하십시오. 들어오는 문자가 ISR을 초과하지 않는지 확인하십시오.

    거기에서부터 작업하십시오 - 저수준 드라이버가 ISR에서 데이터를 가져오고 있습니까?

    +0

    이것은 꽤 좋은 조언입니다. 그리고 이것은 제가 고위 동료 중 한 명이 제가 그에게 문제에 관해 이야기했을 때 한 것입니다. – DimDqkov