2014-11-23 4 views
-2

우리는 AT89S51 마이크로 컨트롤러를 사용하여 DC 모터 컨트롤러 용 코드를 개발하고 있습니다. 우리는 코드 개발을 위해 임베디드 C를, IDE는 Keil 마이크로 비전을, 마이크로 컨트롤러에 .hex 파일을 업로드하려면 Progisp를, 직렬 인터페이스에는 PUTTY를 사용합니다.직렬 DC 모터 제어를 사용하여 8051

#include <reg51.h> 
#include <stdio.h> 
unsigned int k; 
sbit motor = P1^0; 

void delay (int q) { 
    int w; 
    for (w = 0; w < q; w++); 
} 

void next_line() 
{ 
    SBUF = 10; // go to next line 
    while(TI == 0); 
    TI = 0; 
    SBUF = 13; // go to the beginning of the line 
    while(TI == 0); 
    TI = 0; 
} 

unsigned char receive() //Function to receive serial data 
{ 
    unsigned char value; 
    while (RI == 0); 
    value=SBUF; 
    P1=value; 
    RI=0; 
    return value; 
} 

void start() 
{ 
    SCON=0x50; 
    TMOD=0x20; 
    TH1=0xFD; 
    TR1=1; 
    TI=1; 
} 

int i; 

main() 
{ 
    while (1) 
    { 
    unsigned char speed = 0; 
    start(); 
    speed=receive(); 
    switch (speed) 
    { 
    case '1': 
     k=90; // 90 msec out of 100 msec 
     next_line(); 
     break; 
    case '0': 
     k=10; // 10 msec out of 100 msec 
     next_line(); 
     break; 
    }; 
    for(i=0; i<100; i++) 
    { 
     if (i<k) { 
     motor = 0; 
     } 
     else { 
     motor = 1; 
     } 
    } 
    } 
} 

우리는 '1'버튼을 누른 후 '0'버튼을 눌렀을 때 10 % 전원으로 전환 할 때 모터가 90 % 전원에서 작동하도록 기대 : 여기

는 코드입니다. 그러나 일부 키보드 버튼 (1,4,5,8)은 모터를 켜고 일부 버튼 (2,3,6,7)은 모터를 끄게됩니다. 나는 부적절한 작업의 본질을 이해할 수 없다. 제발,이 문제로 우리를 도울 수 있습니까? 감사 미리

+1

의 내 (테스트되지 않은!) 재 작성은 여기 시리얼 문자 입력을 확인한다 루틴? 직렬 포트 설정 (속도, 정지 비트, 패리티 등)이 일치하지 않아 장치에서 읽을 때 ASCII 코드가 엉망이 될 수 있습니까? –

+0

고맙습니다. @JimLewis, 다른 문자를 사용하면 오류가 반복되므로 오류의 원인이라고 생각합니다. 퍼티를 사용하여 k 변수를 입력 할 수 있습니까? 즉, 퍼티 창에 55를 입력 할 수 있습니까? 그러면 전원이 55 %로 설정되어 있습니까? – brainkz

+3

'P1 = value;'가 의도 한 바가 무엇인지 짐작하기가 어렵습니다.홀수 번호의 ASCII 코드로 모터를 켜는 것 외에도 :) –

답변

2

나는 문제에 대한 추측을 위험에 빠뜨리고 그것에 대해 위험을 무릅 쓰려한다. 메인 루프는 시리얼 포트를 읽기 전에 아주 짧은 시간 동안 모터 비트에 쓰기 만하고 어떤 듀티 사이클이 선택 되더라도 모터 쓰기는 제어 포트 비트에 1을 남기므로 모터 실행 중이거나 중지 된 상태로 두어야합니다. 그러나 OP는 열쇠를 누르는 것이 모터를 멈추거나 움직이는 것이라고 말한다. 함수는 입력을 기다린 후 (비트가 정의되지 않음)에 반환 한 다음 반환합니다. 그것이 모터를 제어하고 있다고 생각하기 쉽지만, OP의 주요 프레스의 LSB는 모터 제어와 일치하지 않습니다. 그래서 무엇입니까? 모터를 시작하는 키는 모두 비트 1로되어 있고 모터를 멈추게하는 키는 모두 비트 1로 설정되어 있습니다. 그래서 내 첫번째 추측은 영업 이익은 모터 제어에 대한 잘못된 비트를 정의했다고 올바른 선언이

sbit motor = P1^1; 

는 다음의 비트 1에서 receive() 함수에서

P1 = value; 

내 두 번째 추측이 줄을 제거 있다는 것이다 키 누름은 모터 논리가 반전되어 0이 모터를 구동하고 1이 모터를 정지시키는 것입니다. 그 위에, 메인 루프 그래서 당신은 당신의`receive` 읽을 키 입력을 보낼 퍼티 세션을 사용하고 main()

main() 
{ 
    unsigned char speed; 
    int k = 10;      // default is 'slow' 
    int i; 
    start();      // moved outside of loop 
    while (1)      // repeat until power off 
    { 
     while (RI == 0)    // repeat until serial data in 
     { 
      for(i=0; i<100; i++) // duty cycle 
       if (i<k) 
        motor = 1;  // off: or 0x02 if required for b1 
       else 
        motor = 0;  // on: I have inverted the logic 
     } 

     speed=receive();   // get key press 
     switch (speed) 
     { 
      case '1': 
       k=90;    // 90 msec out of 100 msec 
       next_line(); 
       break; 
      case '0': 
       k=10;    // 10 msec out of 100 msec 
       next_line(); 
       break; 
     } 
    } 
} 
1

main의 내 while 루프는 P1 동일시되었다 motor에 기록하여 수행, 10 % 또는 90 %의 듀티 사이클에 1 비트의 모터 제어를 설정하는 것으로 보인다. 그러나 100 번 쓰기 후에는 이 호출되며, 키를 누를 때까지 기능이 복귀하지 않기 때문에 모터가 계속 실행됩니다. 그래서 나는 왜 모터가 때때로 멈추는 지 이해하지 못한다. 함수가 돌아 오면 case 문은 다른 어떤 키가 눌려 졌는지를 고려하지 않으므로 이전 키 입력에서 k을 단순히 설정하면됩니다. 또한 은 RXD를 기다린 후받은 문자를 P1 모터 컨트롤에 씁니다. 따라서 RXD의 LSB는 모터를 제어하는 ​​데 사용됩니다. 하지만 그것은 버그입니다. 왜냐하면 P1에서 반환 될 때 다시 작성되기 때문입니다.

+0

물론 모터 제어 타이밍은 나머지 프로그램과 완전히 독립적 일 필요는 없습니다. 예를 들어 PWM 또는 영리 타이머 하드웨어 주변 장치를 사용합니다. 메인 루프에서 일부 I/O 핀을 토글하고 실시간 성능을 기대할 수는 없습니다. – Lundin

+0

네, 시리얼 데이터 입출력도 마찬가지입니다. 이상적으로는 인터럽트로 처리해야하지만 너무 길다면 적어도 읽기 전에 커밋하기 전에 주 루프의 RXD 플래그를 확인하십시오. –