Atmega328p и инкремент. энкодер

Тема в разделе "Микроконтроллеры AVR", создана пользователем flaber98, 23 мар 2020.

  1. flaber98

    flaber98 Нуб

    Написал быдлокод для проверки работы энкодера, всё вроде бы четко отрабатывает, но если вместо

    Код (C++):
    if(Rotation_direction() != 0)
        {
            USART_Transmit(rotation);
        }
    я напишу
    Код (C++):
     if(Rotation_direction() == 1 )
        {
        a++;
        USART_Transmit(a);
        }else if (Rotation_direction() == -1 ){a--;    USART_Transmit(a);}
    , то во втором случае при вращении на 1 шаг, данные в UART могут не отправляться раза 3 подряд. В чем прикол?Буду благодарен за помощь

    Код (C++):
    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>
    #define BAUD 9600
    #define MYUBRR    F_CPU/8/BAUD-1

    volatile int rotation = 0;
    volatile int rotation_lst = 0;
    uint8_t last_state = 0;

    void init_uart(unsigned short uValue  ){
        // setting the baud rate  based on the datasheet
        UBRR0H =0x00;//(unsigned char)  ( uValue>> 8);  // 0x00
        UBRR0L =0x0C;//(unsigned char) uValue;  // 0x0C
        // enabling TX & RX
        UCSR0B = (1<<RXEN0)|(1<<TXEN0);
        UCSR0A = (1<<UDRE0)|(1<<U2X0);
        UCSR0C =  (1 << UCSZ01) | (1 << UCSZ00);    // Set frame: 8data, 1 stop

    }

    unsigned char USART_Receive( void )
    {
        /* Wait for data to be received */
        while ( !(UCSR0A & (1<<RXC0)) )
        ;
        /* Get and return received data from buffer */
        return UDR0;
    }
    void USART_Transmit( unsigned char data )
    {
        /* Wait for empty transmit buffer */
        while ( !( UCSR0A & (1<<UDRE0)) )
        ;
        /* Put data into buffer, sends the data */
        UDR0 = data;
    }



    void int_ini(void)

    {
         //включим прерывания INT0 по нисходящему фронту
         //EICRA |= (1 <<ISC00 );
         EICRA = 5; //dec = 5  bin = 0101; любое изменение на  INT0 и INT1 *** dec = 0 bin = 0; лог 0 на ноге

     
         //разрешим внешние прерывания INT0
         EIMSK |= (1<<INT0);
         EIMSK |= (1<<INT1);
    }


    uint8_t GetState()
    {
        return ~(PIND & ( (1<<PIND2) | (1<<PIND3) ) ) ;
    }
    ISR(INT0_vect)
    {
            switch(last_state)
            {
                case 255:
                {
                    if(GetState() == 247) rotation++;
                    if(GetState() == 251) rotation--;
                    break;
                }
             
                case 247:
                {
                    if(GetState() == 243) rotation++;
                    if(GetState() == 255) rotation--;
                    break;
                }
                case 243:
                {
                    if(GetState() == 251) rotation++;
                    if(GetState() == 247) rotation--;
                    break;
                }
                case 251:
                {
                    if(GetState() == 255) rotation++;
                    if(GetState() == 243) rotation--;
                    break;
                }
            }
            last_state = GetState();
    }

    ISR(INT1_vect)
    {
            switch(last_state)
            {
                case 255:
                {
                    if(GetState() == 247) rotation++;
                    if(GetState() == 251) rotation--;
                    break;
                }
             
                case 247:
                {
                    if(GetState() == 243) rotation++;
                    if(GetState() == 255) rotation--;
                    break;
                }
                case 243:
                {
                    if(GetState() == 251) rotation++;
                    if(GetState() == 247) rotation--;
                    break;
                }
                case 251:
                {
                    if(GetState() == 255) rotation++;
                    if(GetState() == 243) rotation--;
                    break;
                }
            }
            last_state = GetState();
            //USART_Transmit(rotation);
    }

    uint8_t Rotation_direction()
    {
        if (abs(rotation) - abs(rotation_lst) == 4  )
        {
            rotation_lst = rotation;
            return 1;
        }else if (abs(rotation) - abs(rotation_lst) == -4 ){rotation_lst = rotation; return -1;}
        return 0;
    }

    int main ()

    {
        int a = 0;
        int_ini();
        sei();
        DDRD = 0b00000000; //задаём порты B на вход 0b76543210 - номер ножек
        //PORTD = 0b11110011; //по умолчанию всё выключено ноги 2,3 - HI-Z, остальные - PullUp
        PORTD = 0b11110011; //по умолчанию всё выключено ноги 2,3 - HI-Z, остальные - PullUp
        init_uart(MYUBRR);
        for(;;)
        {
        if(Rotation_direction() != 0)
        {
            USART_Transmit(rotation);
        }
     
     
        /*
        if(Rotation_direction() == 1 )
        {
        a++;
        USART_Transmit(a);
        }else if (Rotation_direction() == -1 ){a--;    USART_Transmit(a);}
        */


     
        }
        return 0;
    }


    upd:тему можно закрывать , разобрался
     
    Последнее редактирование: 24 мар 2020