0

I am trying to write a simple program to take input from user by hterm, when User enters "motor" & "25" the motor will rotate in 25 clockwise and 25 anticlockwise direction

    //Define clock-speed and include necessary headers
    #define F_CPU 1000000
    #include <avr/io.h>
    #include <util/delay.h>
    #include <inttypes.h>
    #include <avr/io.h>
    #include <stdlib.h>
    #include <avr/interrupt.h>
    #include <stdio.h>
    #include <stdint.h>
    #include <util/delay.h>
    #include <ctype.h>

    #define F_CPU 16000000UL
    #define BAUD 9600UL

    char cmd[40];

    void uart_init(void)                            // initializing UART
    {
        UBRRH = 0;
        UBRRL = ((F_CPU+BAUD*8)/(BAUD*16)-1);

        UCSRC |= 0x86;                              // 8N1 Data
        UCSRB  = 0x18;                              // Receiving and Transmitting
    }

    int uart_putch(char ch, FILE *stream)           // Function for sending Data to PC
    {
        if (ch == '\n')
        uart_putch('\r', stream);
        while (!(UCSRA & (1<<UDRE)));
        UDR=ch;
        return 0;
    }

    int uart_getch(FILE *stream)                    // Function for receiving Data from PC
    {
        unsigned char ch;   while (!(UCSRA & (1<<RXC)));
        ch=UDR;

        uart_putch(ch,stream);                      // Echo the output back to the terminal

        return (tolower(ch));

    }

    FILE uart_str = FDEV_SETUP_STREAM(uart_putch, uart_getch, _FDEV_SETUP_RW);  // Important, not deleting

    void loeschen()                     // Delete the String
    {
        int strnglen = 0;
        while (strnglen < 41 && cmd[strnglen] != 0)
        {
            cmd[strnglen]= 0;
            strnglen++;
        }
    }

    // Define the stepping angle
    // Note: Divide by 2 if you are doing half-stepping. for filter test 1.8 defult
    #define MIN_STEP 1.8

    /* Define an array containing values to be sent at the required Port - for Full-stepping

      <first four bits> - <last four bits> = <decimal equivalent>

       00000001 = 1 ; 01000000 = 4
       00000100 = 4 ; 00010000 = 16
       00000010 = 2 ; 00001000 = 8
       00001000 = 8 ; 00100000 = 32
    */
    unsigned short control_array_full[4] = {4,16,8,32};

    /* Define an array containing values to be sent at the required Port - for Half-stepping

    <first four bits> - <last four bits> = <decimal equivalent>

    0000-1001 = 8 + 1 = 9  ; 0010-0100 = 32 + 4 =36
    0000-0001 = 1     ;      0000-0100 = 4
    0000-0101 = 4 + 1 = 5 ;  00010100 = 16 + 4 = 20
    00000100 = 4        ;   00010000  = 16

    00000110 = 4 + 2 = 6  ; 00011000  = 16+8=24
    0000-0010 =          ;  00-001000 = 8
    0000-1010 = 8 + 2 = 10  ; 00-101000 = 40
    0000-1000 = 8            ; 00-100000 = 32
    */
    unsigned short control_array_half[8] = {36,4,20,16,24,8,40,32};


    // Adjust this delay to control effective RPM
    // Do not make it very small as rotor will not be able to move so fast
    // Currently set at 100ms
    void delay()
    {
    _delay_ms(100);
    }

    void move_clockwise(unsigned short revolutions){
      int i=0;
      for (i=0; i < (revolutions* 360 /MIN_STEP) ; i++)

      {

      //Note: Take modulo (%) with 8 when half-stepping and change array too
      PORTD = control_array_half[i % 4];
      delay();
     }

    }

    void move_anticlockwise(unsigned short revolutions){
     int i;
      for (i = (revolutions* 360 /MIN_STEP); i > 0 ; i--){

      //Note: Take modulo (%) with 8 when half-stepping and change array too
      PORTD = control_array_half[i % 4];
      delay();
     }
    }

    int main()
    {

     // Enter infinte loop
     // Make changes here to suit your requirements

     uart_init();                   // initializing UART

     stdout = stdin = &uart_str;        // Necessary to compare whole Strings

      while(1){


          scanf("%s",&cmd);         // Read String from Data Register
    printf ("Please enter number of motor rotation for clockwise and anticlockwise");
          items_read = scanf ("%d", &numbers[i]); // Read integer for motor revolution


          if(strcmp(cmd, "motor") == 0)
          {
              DDRD = 0b00111110; //Set PORTD  4 bits for output
       //Enter number of revolutions required in brackets
            move_clockwise(items_read);

            move_anticlockwise(items_read);
          }   
      DDRD = 0b00000000;
  }
        loeschen();
}

Now, The problem is that when I will delete these lines from main()

  items_read = scanf ("%d", &numbers[i]);
  scanf ("%d",&i);

& make items_read in move_clockwise(items_read); as:

move_clockwise(25);
move_anticlockwise(25);

Then when user enters "motor" then motor is running move_clockwise(25); but move_anticlockwise(25); is not running, what I would like is to take both "motor", number for clockwise and number for anticlockwise....

I would really appreciate if anyone can help me with this! Thanks in advance!

4

1 回答 1

0

首先,在我看来,你只是在 loeschen() 中清除“cmd”,但你从来没有评估任何价值。第二个“cmd”不是任何类型的 UART 数据寄存器。

DDRD 是 DataDirectionRegister D,这意味着您可以将某些引脚设置为输入或输出模式。使用 PORTD 将引脚设置为高电平或低电平,例如PORTD |= 1<<PD0;将端口 D 引脚 0 设置为高电平。

我猜您更喜欢德语文档,因为您将一个函数命名为“loeschen()”;-),那么您为什么不访问mikrocontroller.net AVR GCC 教程 (UART)呢?

如果您喜欢更多技术细节的 youtube-stuff,等等:UART 简介

RXT (ATMEGA16) - 例如:

//////////////////////////////////////////////////////////////////////////
// Definitions
//////////////////////////////////////////////////////////////////////////
#define BAUD 9600UL                             
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD)      

#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
#error Baud to high
#endif

#define UART_MAX_STRING_LENGHT 20               // Max lenght


//////////////////////////////////////////////////////////////////////////
// UART-Receive-Variables
//////////////////////////////////////////////////////////////////////////
volatile uint8_t uart_str_complete = 0;                         // FLAG - String received
volatile uint8_t uart_str_count = 0;                            // Current position
volatile char uart_string[UART_MAX_STRING_LENGHT + 1] = "";     // received string


//////////////////////////////////////////////////////////////////////////
// ISR-UART 
//////////////////////////////////////////////////////////////////////////
ISR(USART_RXC_vect)
{
    unsigned char nextChar;
    nextChar = UDR;         // read data from buffer

    if(uart_str_complete == 0)  // UART-String is currently usen
    {
        if(nextChar != '\n' && nextChar != '\r' && uart_str_count < UART_MAX_STRING_LENGHT)
        {
            uart_string[uart_str_count] = nextChar; 
            uart_str_count++;                       
        }
        else
        {
            uart_string[uart_str_count] = '\0'; 
            uart_str_count = 0;                 
            uart_str_complete = 1;
        }
    }
}


//////////////////////////////////////////////////////////////////////////
// Init UART
//////////////////////////////////////////////////////////////////////////
void Init_UART_Async()
{
    UBRRH = UBRR_VAL >> 8;
    UBRRL = UBRR_VAL & 0xFF;

    UCSRB |= (1<<TXEN);                         // UART TX high
    UCSRB |= (1<<RXEN);                         // UART RX high
    UCSRB |= (1<<RXCIE);                        // UART RX Interrupt enable
    UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);   // Asynchron 8N1

    sei();                                      // Enable interrups
}


//////////////////////////////////////////////////////////////////////////
// Main
//////////////////////////////////////////////////////////////////////////
int main(void)
{

    Init_UART_Async();

    while(1)
    {       
        HandleCommunication();      // <-- Handle your communication ;-)

        // and to some other cool stuff here
    }
}


//////////////////////////////////////////////////////////////////////////
// Handle Communication
//////////////////////////////////////////////////////////////////////////
void HandleCommunication()
{
    if(uart_str_complete == 1)
    {
        strcpy(received_string, uart_string);   // copy received string
        strcpy(uart_string, "");                // empty uart-string
        uart_str_complete = 0;                  // set flag to 0

        // handle your communication
    }
}

在了解 UART 的工作原理后,您应该检查您的代码部分,例如“scanf("%s",&cmd);" 在控制台应用程序中 - 更容易找到一些错误。

我希望这对您有所帮助,但我想最好的解决方案是当您知道自己在做什么时。

-疯狂的

于 2013-06-26T07:57:46.497 回答