Atmega 32,用于驱动电机的程序,如何从用户获取输入整数

时间:2013-06-12 23:25:45

标签: embedded atmega

我正在尝试编写一个简单的程序,当用户输入“motor”& “25”电机将以25°顺时针方向和25°逆时针方向旋转

    //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();
}

现在,问题是当我从main()

中删除这些行时
  items_read = scanf ("%d", &numbers[i]);
  scanf ("%d",&i);

&安培;在move_clockwise(items_read);中将items_read设为:

move_clockwise(25);
move_anticlockwise(25);

然后当用户输入“motor”然后电机正在运行move_clockwise(25);但是move_anticlockwise(25);没有运行,我想要的是“电机”,顺时针编号和逆时针编号。 ..

如果有人能帮助我,我真的很感激! 提前谢谢!

1 个答案:

答案 0 :(得分:0)

首先,在我看来,你只是在loeschen()中清除“cmd”,但你永远不会有任何价值。 第二个“cmd”不是任何类型的UART dataregister。

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

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

如果你喜欢更多技术细节的youtube-stuff,瞧瞧:Introduction to 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“,&amp; cmd);”在控制台应用程序中 - 更容易发现一些错误。

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

-Crazy