Mega2560, быстрая библиотека для UART (типа CyberLib)

Тема в разделе "Arduino & Shields", создана пользователем Vovka, 20 ноя 2019.

Метки:
  1. Vovka

    Vovka Гик

    Вот потихоньку курю, жаль, что не нашел на русском....
    For interrupt driven USART operation, theGlobal Interrupt Flag should be cleared (and interrupts globally disabled) when doing theinitialization.
    А в примерах нигде такого нет!
     
    timon нравится это.
  2. Daniil

    Daniil Гуру

    см. книгу А.В. Евстисфеева по семейству Mega.
    Я свои первые дашики переводил аккуратно в ворд-файл, через гугл, а потом с гугла на русский переводил. Парочки хватило и начал по аглицки читать
     
  3. SergeiL

    SergeiL Оракул Модератор

    Я еще обычно делаю буфер на прием и на передачу.
    Записал в буфер - свободен.
    Закончилась передача байта - проверил есть еще что в буфере для передачи.
    На приеме - так же считали - закинул в буфер, а main() (loop() )пускай от туда вытаскивают и обрабатывают.
     
  4. asam

    asam Гик

    Так на какой BAUDRATE у вас все работает?
     
  5. Vovka

    Vovka Гик

    Мне буферизация для UART не подойдет, т.к. нужно отлавливать пакет данных с определенным адресом: если байт не начало пакета или не "наш" адресс, то сразу же отправляем в другой UART. Если да, то обработка и отправка во второй UART. В общих словах как-то так...
    GSM-модуль взят из другого рабочего проектам там он работает на 19200. пульт еще не делал, так как застрял с UART

    Мы отвлеклись о темы: мне нужен рабочий код для работы с UART.
    Есть тут человек, который реально с ним работал без Serial и может помочь?
     
  6. asam

    asam Гик

    Ну я рельно работал с UART. 19200 бод это вообще ни о чем. За время приема или отправки одного байта процессор успевает выполнить около 8 тысяч инструкций. Вам вообще не надо трогать код работающий на отправку. Используйте стандартную библиотеку и не парьтесь. Все там успеет отправиться 500 раз. Надо только сделать простенький диспетчер приема даных на прерывании со входного порта. Я вот только не понял у вас три порта задействовано - 1 на прием и 2 на передачу или как еще? И чем "другой UART" отличается от "второй UART"?
     
  7. SergeiL

    SergeiL Оракул Модератор

    Да буферизация ничего не задержит.
    Буферизация помогает не потерять байт, если обработка дольше приема, да и ждать окончания передачи не требуется.
    Закинул несколько байт, не ожидая окончания передачи, а они выдаются один за другим по прерываниям.

    Разбираться с регистрами долго, сгенерил код в ICC посмотрите такие же ли у вас значения загружаются. Билдер никогда не подводил. ;)
    Код (C++):
    //ICC-AVR application builder : 23.11.2019 10:45:10
    // Target : M2560
    // Crystal: 16.000Mhz

    #include <iom2560v.h>
    #include <macros.h>

    void port_init(void)
    {
    PORTA = 0x00;
    DDRA  = 0x00;
    PORTB = 0x00;
    DDRB  = 0x00;
    PORTC = 0x00; //m103 output only
    DDRC  = 0x00;
    PORTD = 0x00;
    DDRD  = 0x00;
    PORTE = 0x00;
    DDRE  = 0x00;
    PORTF = 0x00;
    DDRF  = 0x00;
    PORTG = 0x00;
    DDRG  = 0x00;
    PORTH = 0x00;
    DDRH  = 0x00;
    PORTJ = 0x00;
    DDRJ  = 0x00;
    PORTK = 0x00;
    DDRK  = 0x00;
    PORTL = 0x00;
    DDRL  = 0x00;
    }

    //UART0 initialize
    // desired baud rate: 19200
    // actual: baud rate:19231 (0,2%)
    // char size: 8 bit
    // parity: Disabled
    void uart0_init(void)
    {
    UCSR0B = 0x00; //disable while setting baud rate
    UCSR0A = 0x02;
    UCSR0C = 0x06;
    UBRR0L = 0x67; //set baud rate lo
    UBRR0H = 0x00; //set baud rate hi
    UCSR0B = 0x98;
    }

    #pragma interrupt_handler uart0_rx_isr:iv_USART0_RXC
    void uart0_rx_isr(void)
    {
    //uart has received a character in UDR
    }

    //UART1 initialize
    // desired baud rate:19200
    // actual baud rate:19231 (0,2%)
    // char size: 8 bit
    // parity: Disabled
    void uart1_init(void)
    {
    UCSR1B = 0x00; //disable while setting baud rate
    UCSR1A = 0x02;
    UCSR1C = 0x06;
    UBRR1L = 0x67; //set baud rate lo
    UBRR1H = 0x00; //set baud rate hi
    UCSR1B = 0x98;
    }

    #pragma interrupt_handler uart1_rx_isr:iv_USART1_RXC
    void uart1_rx_isr(void)
    {
    //uart has received a character in UDR
    }

    //call this routine to initialize all peripherals
    void init_devices(void)
    {
    //stop errant interrupts until set up
    CLI(); //disable all interrupts
    XMCRA = 0x00; //external memory
    XMCRB = 0x00; //external memory
    port_init();
    uart0_init();
    uart1_init();

    MCUCR  = 0x00;
    EICRA  = 0x00; //pin change int edge 0:3
    EICRB  = 0x00; //pin change int edge 4:7
    PCICR  = 0x00; //pin change int enable
    PCMSK0 = 0x00; //pin change mask
    PCMSK1 = 0x00; //pin change mask
    PCMSK2 = 0x00; //pin change mask
    EIMSK  = 0x00;
    TIMSK0 = 0x00; //timer0 interrupt sources
    TIMSK1 = 0x00; //timer1 interrupt sources
    TIMSK2 = 0x00; //timer2 interrupt sources
    TIMSK3 = 0x00; //timer3 interrupt sources
    TIMSK4 = 0x00; //timer4 interrupt sources
    TIMSK5 = 0x00; //timer5 interrupt sources
    PRR0   = 0x00;
    PRR1   = 0x00;
    SEI(); //re-enable interrupts
    //all peripherals are now initialized
    }

    //
    void main(void)
    {
    init_devices();
    //insert your functional code here...
    }

     
    mega2560.png
     
  8. SergeiL

    SergeiL Оракул Модератор

    Я бы убрал ожидание окончания передачи в Вашем коде и попробовал.
    Не стоит зависать до окончания передачи в прерывании на прием.
     
    Vovka нравится это.