uart atmel328p

Тема в разделе "Микроконтроллеры AVR", создана пользователем Danil_2002, 5 апр 2019.

  1. Danil_2002

    Danil_2002 Гик

    Добрый день!

    Решил погрузиться в мир микроконтроллеров поглубже и научиться программировать Arduino uno на Си.
    Поставил такую задачу: передать сообщение через uart на компьютер.

    Код (C++):
    #include <avr/io.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>

    ISR(USART_RX_vect)
    {
       PORTB |= (1 << PB5); // если что-то получили, включаем красный диод на выводе PB5
      unsigned char b = 0;
      while (UCSR0A & (1<<RXC0))
      {
      b = UDRE0;
      USART_TransmitByte(b);
      }
        PORTB &= ~(1 << PB5); // и гасим его
    }

    void USART_init(void) // Настраеваем скорость передачи данных
    {
      unsigned int bd = (16000000UL / (16UL * 38400UL) - 1);
      UBRR0L = 103;
      UBRR0H = 0;
      UCSR0B = (1<<RXEN0)|(1<<TXEN0)|(1<<RXCIE0);
      UCSR0C = (1<<USBS0)|(3<<UCSZ00)|(0<<UMSEL00);
    }
    void USART_TransmitByte( unsigned char data )
    {
      /* Wait for empty transmit buffer */
      while ( !( UCSR0A & (1<<UDRE0)) );
      /* Put data into buffer, sends the data */
      UDR0 = data;
    }
    void USART_TransmitText(char* data)
    {
       while (*data != 0)
       {
          /* Wait for empty transmit buffer */
          while ( !( UCSR0A & (1<<UDRE0)) );
          /* Put data into buffer, sends the data */
          UDR0 = *data;
          data++;
       }
    }
    int main (void)
    {
       USART_init();
       USART_TransmitText("hello im ready\r\n");
       sei();
       PORTB &= ~(1 << PB5); // и гасим pb5
     
    }
    В этом коде мне не понятна одна строчка:
    UCSR0C = (1<<USBS0)|(3<<UCSZ00)|(0<<UMSEL00);

    Я знаю что такое побитовое смещение, но почему так, а не так:
    UCSR0C = (1<<USBS0)|(1<<UCSZ00)|(1<<UMSEL00);
    Мы же просто устанавливаем необходимые флаги

    Объясните пожалуйста

    Заранее спасибо
     
  2. AlexU

    AlexU Гуру

    Код (C++):
    UCSR0C = (1<<USBS0)|(3<<UCSZ00)|(0<<UMSEL00);
    3 -- в бинарном виде - это две единички -- 11.
    В данном примере устанавливаются сразу два бита UCSZ00 и UCSZ01. Т.е. будут передаваться 8-ми битовые данные.

    UPD: то же что и:
    Код (C++):
    UCSR0C = (1<<USBS0)|(1<<UCSZ00)|(1<<UCSZ01)|(0<<UMSEL00);
     
  3. parovoZZ

    parovoZZ Гуру

    наерна, не знаешь)))
    здесь
    мы смещаем "1" на то количество бит влево, которое несет в себе переменная/константа UCSZ00.
     
  4. カオナシ

    カオナシ Нерд

    | (0<<UMSEL00) можно смело убрать, так как ничего не дает.
    По "или" собираются только "1"
     
    Airbus нравится это.
  5. Airbus

    Airbus Радиохулиган Модератор

    Да ноли не пишем.Только единички куда надо.
     
  6. parovoZZ

    parovoZZ Гуру

    Я оставляю и подписываю. Потом, когда файл уйдет в другой проект, не надо лезть в дашик (в дашик один фиг лезешь, но хотя бы не за этим), а просто переправил нолики на единички. Выглядит так:
    Код (C++):
    ADCSRA =    (1<<ADEN) |                        // Разрешаем работу ADC
            (1<<ADIE) |                        // Разрешаем прерывание
            (0<<ADATE) |                        // Старт преобразования вручную
            (0<<ADPS2) | (0<<ADPS1) | (0<<ADPS0);                // Прескалер = 2