Проблема с USART Atmega328p (Arduino Pro Mini)

Тема в разделе "Arduino & Shields", создана пользователем Kisa9000, 30 ноя 2018.

  1. Kisa9000

    Kisa9000 Нуб

    Возникла проблема при отправке информации в Atmega328p.
    Информация на вход RX поступает и по логике должно срабатывать прерывание, но что то как то не так.
    Такой же код использовал на Atmega2560 и все прекрасно работало и сверкало (естественно все регистры проставлены из datasheet).
    Причем данные с Atmega прекрасно отправляются ко мне, а если использовать классические Serial.read() и т.д. то проблем вообще не возникает с приемом и отправкой.
    Вот обращаюсь к вам дорогие форумчане, может что то решим.

    Код (C++):

    #include <avr/io.h>
    #include <avr/interrupt.h>
    int buf;
    void USART_Init(uint16_t baudrate)
    {
       UBRR0H = baudrate >> 8;
       UBRR0L = baudrate;
       UCSR0A = (1 << U2X0);
       UCSR0B = (1 << RXCIE0) | (1 << RXEN0) | (1 << TXEN0);
       UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);
    }

    ISR(USART0_RX_vect)
    {
      PORTB ^= (1<<5);
      buf = UDR0;
    }

    int main()
    {
    USART_Init(16);
    DDRB |= (1 << 5);
    sei();
    while(1){

        }
    }
     
     
    Последнее редактирование: 30 ноя 2018
  2. parovoZZ

    parovoZZ Гуру

    а в 328p точно такой вектор?
     
  3. Kisa9000

    Kisa9000 Нуб

    Вот это кстати интересный момент.
    Arduino IDE (у меня) лопает USART0_RX_vect и USART_RX_vect, но если делать через makefile то компилятор ругается на USART_RX_vect... поэтому собственно и было решение оставить USART0_RX_vect.
     
  4. Limoney

    Limoney Гик

    загляните в datasheet
     
  5. ZAZ-965

    ZAZ-965 Гуру

    У ATmega328p один USART и вектор прерывания USART_RX_vect. Есть ATmega328PB у которого два USART, но на платах Arduino его не видел.
     
  6. parovoZZ

    parovoZZ Гуру

    Не в даташит, а в заголовочник
     
  7. parovoZZ

    parovoZZ Гуру

    Он будет лопать абсолютно любую чушь)))
     
  8. parovoZZ

    parovoZZ Гуру

    Вот сдернул из iom328p.h
    Код (C++):

    /* Interrupt Vectors */
    /* Interrupt Vector 0 is the reset vector. */

    #define INT0_vect_num     1
    #define INT0_vect         _VECTOR(1)   /* External Interrupt Request 0 */

    #define INT1_vect_num     2
    #define INT1_vect         _VECTOR(2)   /* External Interrupt Request 1 */

    #define PCINT0_vect_num   3
    #define PCINT0_vect       _VECTOR(3)   /* Pin Change Interrupt Request 0 */

    #define PCINT1_vect_num   4
    #define PCINT1_vect       _VECTOR(4)   /* Pin Change Interrupt Request 0 */

    #define PCINT2_vect_num   5
    #define PCINT2_vect       _VECTOR(5)   /* Pin Change Interrupt Request 1 */

    #define WDT_vect_num      6
    #define WDT_vect          _VECTOR(6)   /* Watchdog Time-out Interrupt */

    #define TIMER2_COMPA_vect_num 7
    #define TIMER2_COMPA_vect _VECTOR(7)   /* Timer/Counter2 Compare Match A */

    #define TIMER2_COMPB_vect_num 8
    #define TIMER2_COMPB_vect _VECTOR(8)   /* Timer/Counter2 Compare Match A */

    #define TIMER2_OVF_vect_num   9
    #define TIMER2_OVF_vect   _VECTOR(9)   /* Timer/Counter2 Overflow */

    #define TIMER1_CAPT_vect_num  10
    #define TIMER1_CAPT_vect  _VECTOR(10)  /* Timer/Counter1 Capture Event */

    #define TIMER1_COMPA_vect_num 11
    #define TIMER1_COMPA_vect _VECTOR(11)  /* Timer/Counter1 Compare Match A */

    #define TIMER1_COMPB_vect_num 12
    #define TIMER1_COMPB_vect _VECTOR(12)  /* Timer/Counter1 Compare Match B */

    #define TIMER1_OVF_vect_num   13
    #define TIMER1_OVF_vect   _VECTOR(13)  /* Timer/Counter1 Overflow */

    #define TIMER0_COMPA_vect_num 14
    #define TIMER0_COMPA_vect _VECTOR(14)  /* TimerCounter0 Compare Match A */

    #define TIMER0_COMPB_vect_num 15
    #define TIMER0_COMPB_vect _VECTOR(15)  /* TimerCounter0 Compare Match B */

    #define TIMER0_OVF_vect_num  16
    #define TIMER0_OVF_vect   _VECTOR(16)  /* Timer/Couner0 Overflow */

    #define SPI_STC_vect_num  17
    #define SPI_STC_vect      _VECTOR(17)  /* SPI Serial Transfer Complete */

    #define USART_RX_vect_num 18
    #define USART_RX_vect     _VECTOR(18)  /* USART Rx Complete */

    #define USART_UDRE_vect_num   19
    #define USART_UDRE_vect   _VECTOR(19)  /* USART, Data Register Empty */

    #define USART_TX_vect_num 20
    #define USART_TX_vect     _VECTOR(20)  /* USART Tx Complete */

    #define ADC_vect_num      21
    #define ADC_vect          _VECTOR(21)  /* ADC Conversion Complete */

    #define EE_READY_vect_num 22
    #define EE_READY_vect     _VECTOR(22)  /* EEPROM Ready */

    #define ANALOG_COMP_vect_num  23
    #define ANALOG_COMP_vect  _VECTOR(23)  /* Analog Comparator */

    #define TWI_vect_num      24
    #define TWI_vect          _VECTOR(24)  /* Two-wire Serial Interface */

    #define SPM_READY_vect_num    25
    #define SPM_READY_vect    _VECTOR(25)  /* Store Program Memory Read */

    #define _VECTORS_SIZE (26 * 4)
    ISR в параметре слопает абсолютно любой бред.
     
  9. Limoney

    Limoney Гик

    Не заголовочник, а техническая спецификация
     
  10. parovoZZ

    parovoZZ Гуру

    Если копнуть ещё глубже, то в interrupt.h увидим:
    Код (C++):
    #  define ISR(vector, [attributes])
    #else  /* real code */

    #if (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) || (__GNUC__ > 4)
    #  define __INTR_ATTRS used, externally_visible
    #else /* GCC < 4.1 */
    #  define __INTR_ATTRS used
    #endif

    #ifdef __cplusplus
    #  define ISR(vector, ...)            \
        extern "C" void vector (void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__; \
        void vector (void)

    #else
    #  define ISR(vector, ...)            \
        void vector (void) __attribute__ ((signal,__INTR_ATTRS)) __VA_ARGS__; \
        void vector (void)

    #endif
     
  11. Maris_n_s

    Maris_n_s Нуб

    Нужно добавить разрешение прерывания по получению
    UCSR0B|=RXCIE0;//enable interrupt