【问题标题】:Atmega 32, Program to drive motor , How to take input integer from userAtmega 32,驱动电机的程序,如何从用户那里获取输入整数
【发布时间】:2013-06-12 23:25:44
【问题描述】:

我正在尝试编写一个简单的程序来通过 hterm 获取用户的输入,当用户输入“电机”和“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);

然后当用户输入“电机”然后电机正在运行move_clockwise(25);move_anticlockwise(25); 没有运行,我想要的是同时使用“电机”,顺时针的数字和逆时针的数字......

如果有人可以帮助我,我将不胜感激! 提前致谢!

【问题讨论】:

  • 您的程序的某些部分(例如用于收集字符串)似乎丢失了。但也许你应该先做一个更简单的测试用例,去掉除了两个移动命令之外的所有东西。如果您以其他顺序发出它们,先逆时针,还是单独调用它们会发生什么?或者您可以制作一个初步测试程序,该程序在收到每个连续字符时前进一次。
  • 我尝试只使用 scanf 和 printf,scanf 正在工作,但 printf 或 puts 都不适合我!!,谁能告诉我我在这里做错了什么我也想要用户的 int

标签: embedded atmega


【解决方案1】:

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

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

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

如果您喜欢技术更详细的 youtube 内容,瞧: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",&cmd);"在控制台应用程序中 - 更容易发现一些错误。

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

-疯狂

【讨论】:

  • 谢谢它真的有帮助,我发现我的uart_init() 工作不正常,所以我也更正了void USARTInit(uint16_t ubrr_value) { UBRRL = ubrr_value; UBRRH = (ubrr_value&gt;&gt;8); UCSRC=(1&lt;&lt;URSEL)|(3&lt;&lt;UCSZ0); UCSRB=(1&lt;&lt;RXEN)|(1&lt;&lt;TXEN); } 当我将 txd 连接到串行的 txd 时,我检查了 Atmega32 的连接atmega32 的端口和 rxd 到串口的 rxd 现在工作正常。而且,我在想​​是不是应该是相反的顺序!
猜你喜欢
  • 1970-01-01
  • 2017-10-07
  • 2013-01-18
  • 2019-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-31
相关资源
最近更新 更多