문제

8051 마이크로 컨트롤러가 컴퓨터와 무선으로 통신하고 있습니다. 마이크로 컨트롤러는 문자열을 직렬 포트 (DB9)로 보내고 컴퓨터는이 문자열을 받고 조작합니다.

내 문제는 8051이 문자열을 한 번만 전송하는 방법을 모른다는 것입니다. PC 끝에서 문자열을 조작해야하므로 한 번만 받으면됩니다. 현재 C 코드에서는 문자열을 한 번 보내고 있지만 컴퓨터에서 동일한 문자열을 지속적으로 받고 있습니다. 나는 이것이 SBUF의 모든 것이 지속적으로 전송되기 때문이라고 생각합니다. 한 번만 문자열을 보낼 수있는 방법이 있습니까? SBUF를 비우는 방법이 있습니까?

DB9에서 RTS (요청) 핀 (7 번째 핀)을 사용하려고 시도했으나 핀의 전압을 무효화하면 직렬 포트로의 데이터 흐름이 중지되기 때문에 어딘가에 읽었 기 때문입니다. 그래서 내가 한 일은 마이크로 컨트롤러를 프로그래밍하여 문자열을 보내고 DB9 RTS 핀에 연결된 출력 핀으로 로직 레벨 0을 보냈습니다. 그러나 그것은 효과가 없었습니다.

누구든지 제안이 있습니까? 정말 감사합니다.

편집하다

PC에서 사용하는 소프트웨어는 XBEE 모듈 용 X-CTU입니다. 이것은 내 마이크로 컨트롤러의 코드입니다.

include reg51.h 
void SerTx(unsigned char);  
void main(void)  
{  
  TMOD = 0x20;  
  TH1 = 0xFD;  
  SCON = 0x50;  
  TR1 = 1;   

  SerTx('O');  
  SerTx('N');  
  SerTx('L');  
  SerTx('Y'); 

}

void SerTx(unsigned char x)  
{  
  SBUF = x;  
  while(TI==0);   
  TI = 0;   
}  

누군가가 실제로 문자열을 한 번만 보내는 것을 확인할 수 있습니까?

편집하다

Steve, Brookesmoses 및 Neil은 문제를 일으킨 주요 기능 이후에 일어나고 있다고 말했을 때 머리에 못을 박았습니다. 방금 Steve가 제안한 코드를 시도한 코드 (특히 (;;) 및 Main 외부의 SERTX 정의)를 시도했으며 완벽하게 작동했습니다. 컨트롤러가 재부팅되어 동일한 코드가 계속 반복됩니다.

도움을 주셔서 감사합니다! :)

도움이 되었습니까?

해결책

8051이 실제로 데이터를 한 번만 전송하고 있음을 확인할 수 있습니까? 확인하는 한 가지 방법은 UART의 TX 핀에서 무슨 일이 일어나고 있는지 확인하기 위해 범위를 사용하는 것입니다.

PC에서 어떤 소프트웨어를 사용하고 있습니까? Hyperterminal과 같은 간단한 통신 소프트웨어를 사용하는 것이 좋습니다 퍼티. 문자열이 PC로 여러 번 전송되는 것을 보여 주면 8051에서 실행되는 소프트웨어에 결함이있을 가능성이 있습니다.

편집하다: 솔직히 말해서, 이것은 엔지니어가 정기적으로 직면 해야하는 디버깅의 종류처럼 들리므로, 구식의 체계적인 문제 해결을 연습 할 수있는 좋은 기회입니다.

내가 매우 무딘 일 수 있다면 다음을 수행하는 것이 좋습니다.

  1. 디버그. 시도해보십시오 추측하지 마십시오. 실험. 코드를 약간 변경하고 무슨 일이 일어나는지 확인하십시오. 생각할 수있는 모든 것을 시도하십시오. 자세한 내용은 웹을 검색하십시오.
  2. 솔루션을 생성하지 않으면 여기로 돌아와서 필요한 모든 정보를 제공하십시오. 여기에는 관련 코드의 관련 부분, 사용중인 하드웨어에 대한 자세한 내용 및 1 단계에서 시도한 정보에 대한 정보가 포함됩니다.

편집하다: 질문을 편집 할 담당자가 없으므로 다음은 OP가 그녀의 질문에 게시 한 코드입니다.

#include<reg51.h>

void SerTx(unsigned char);

void main(void)
{
    TMOD = 0x20; TH1 = 0xFD; SCON = 0x50; TR1 = 1;
    SerTx('O'); SerTx('N'); SerTx('L'); SerTx('Y');

    void SerTx(unsigned char x)
        { SBUF = x; while(TI==0); TI = 0; } 
}

Neil과 Brooksmoses가 그들의 답변에서 언급 한 바와 같이, 임베디드 시스템에서 주요 기능은 결코 종료되지 않습니다. 따라서 코드를 무한 루프 (실수로 발생하는 일일 수 있음)에 코드를 넣거나 마지막에 무한 루프를 추가하여 프로그램이 효과적으로 중단되어야합니다.

또한 SERTX 기능은 메인 외부에서 정의되어야합니다. 이것은 성적으로 정확할 수 있지만 다른 기능 내에서 기능을 선언하지 않는 것이 간단하게 유지됩니다.

따라서 이것을 시도해보십시오 (코드를 더 쉽게 이해할 수 있도록 몇 가지 의견을 추가했습니다).

#include<reg51.h>

void SerTx(unsigned char);

void main(void)
{
    /* Initialise (need to add more explanation as to what
        each line means, perhaps by replacing these "magic
        numbers" with some #defines) */
    TMOD = 0x20;
    TH1  = 0xFD;
    SCON = 0x50;
    TR1  = 1;

    /* Transmit data */
    SerTx('O'); SerTx('N'); SerTx('L'); SerTx('Y');

    /* Stay here forever */
    for(;;) {}

}

void SerTx(unsigned char x)
{
    /* Transmit byte */
    SBUF = x;

    /* Wait for byte to be transmitted */
    while(TI==0) {}

    /* Clear transmit interrupt flag */
    TI = 0;
} 

다른 팁

게시 한 코드는 main ()에 루프가 없으므로 'y'를 보낸 후 main ()가 돌아올 때 컴파일러의 C 런타임이 수행하는 작업을 결정해야합니다. 문제가 주어지면 컴파일러가 일부 정리를 수행하는 코드를 생성 한 다음 마이크로를 다시 시작할 수 있습니다 (하드웨어 재설정 일 수도 있고 C 런타임을 다시 시작할 수 있음). 프로그램이 작성한대로 정확하게 작동하는 것처럼 보이지만 Main ()가 호출되기 전후에 발생하는 일이 무시되었습니다.

당신이 당신의 줄을 한 번만 한 번만 보내고 싶다면, 당신은 다음과 같은 것을 필요로합니다. while(1) {} 마지막 캐릭터가 전송 된 후 추가되었습니다. 그러나 당신의 프로그램은 아무것도하지 않습니다. 그것은 빈 루프를 영원히 실행할 것입니다. 다시 시작하고 문자열을 보내려면 재설정 (예 : 전원 순환)이 필요합니다.

마이크로에 Watchdog 타이머가있는 경우 예상치 못한 재설정을 개입하고 강제 할 수 있습니다. 이 경우 각 감시자 재설정마다 문자열이 한 번 전송됩니다 (하드웨어에 따라 요금으로 매 초기와 같은 것일 수 있음).

또한 sertx ()를 정의 한 상태에서 main () 내부에 중첩 된 것은 아마도 원하는 것이 아닐 것입니다.

8051 코드를 보지 않고 문제가 무엇인지 말하기는 어렵습니다. 예를 들어, 해당 측면의 논리 오류는 데이터가 여러 번 전송 될 수 있거나 8051 소프트웨어가 수신되지 않은 ACK를 기다릴 수 있습니다.

일반적으로 8051 코드에서는 각 캐릭터를 명시 적으로 보내야하지만 C 런타임까지 이것이 귀하를 위해 처리한다고 가정합니다.

RTS/CTS의 사용 (보내기 요청/지우기 요청)은 유량 제어 (즉, 버퍼 오버런을 방지하기위한 - 버퍼는 일반적으로 이러한 마이크로 컨트롤러에서 상당히 작습니다) 전송을 중지하지 않기위한 것입니다.

Neil의 답변에 반향 (답변에서 아직 의견을 제시 할 담당자가 없기 때문에) : OS가없는 일반적인 마이크로 컨트롤러 상황에서는 Main의 끝에서 암시 적으로 호출되는 Exit () 함수가 무엇인지 즉시 명확하지 않습니다. ) 또는 더 정확하게는 OS로 돌아올 OS가 없기 때문에 일반적인 "프로그램을 종료하고 OS로 돌아갈 수 없다"고해야합니다.

또한 실제 응용 프로그램에서는 시스템을 끄지 않는 한 프로그램이 중지되기를 거의 원하지 않습니다. 따라서 EXIT () 구현이 확실히하지 말아야 할 한 가지는 많은 코드 공간을 차지하는 것입니다.

내가 작업 한 일부 시스템에서는 Exit ()가 실제로 구현되지 않습니다. 사용하지 않으려면 바이트를 낭비하지 마십시오! 결과적으로 실행 경로가 Main ()의 끝으로 도착하면 칩은 다음 메모리에 발생하는 모든 일이 무엇이든 실행하는 라라 땅으로 방황하며 일반적으로 루프에 갇히거나 결국 빠르게 끝납니다. 불법 opcode로 결함. 그리고 불법 opcode에 대한 결함의 일반적인 결과는 ... 칩을 재부팅하는 것입니다.

그것은 여기서 일어나는 일에 대한 그럴듯한 이론처럼 보입니다.

이 특정 기사는 C가 아닌 조립품이지만 유용 할 수 있습니다.http://www.8052.com/tutser.phtml

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top