USART Arduino MEGA 1280
- Войдите на сайт для отправки комментариев
Здравствуйте, пишу программу для управления устройством с использованием контроллера AVR на базе ARDUINO MEGA 1280 (далее - МК) в сочетании с ПК.
Дело обстоит так:
1) ПК посылает один байт МК (1 или 2) по USART_0.
2) МК выяснив что это за байт - выполняет инструкцию, которая заключается в передаче устройству двух байт синхронизации (7 и 128) по USART_1 и последующем ожидании одного байта синхронизации по USART_1 от устройства (88).
3) Устройство передаёт байт синхронизации MK (88) по USART_1.
4) Приняв байт синхронизации от устройства (88) по USART_1, МК выдаёт устройству ещё пару байт, на включение опций (7,16 или 7,18) по USART_1.
Проблема возникла на 4-ом шаге. Байт синхронизации МК принимает, но не может выдать последние два байта устройству. Хотя при выполнении 2-го шага, всё передалось без проблем.
вот код:
#define F_CPU 16000000UL #define BAUD 38400 #define UBRR_VAL F_CPU/16/BAUD-1 unsigned char my_com; void usart0_init (unsigned int my_speed) // Инициализация модуля USART_0 { UBRR0H = (unsigned char)(my_speed >> 8); // Установка BAUDRATE UBRR0L = (unsigned char) my_speed; UCSR0A = 0x00; UCSR0B |= (1 << TXEN0); // Разрешение работы передатчика UCSR0B |= (1 << RXEN0); // Разрешение работы приемника UCSR0C |= (1 << UCSZ01)|(1 << UCSZ00); // 8 бит } void usart1_init (unsigned int my_speed) // Инициализация модуля USART_1 { UBRR1H = (unsigned char)(my_speed >> 8); // Установка BAUDRATE UBRR1L = (unsigned char) my_speed; UCSR1A = 0x00; UCSR1B |= (1 << RXEN1); // Разрешение работы приемника UCSR1B |= (1 << TXEN1); // Разрешение работы передатчика UCSR1C |= (1 << UCSZ11)|(1 << UCSZ10); // 8 бит } void setup() { usart0_init (UBRR_VAL); usart1_init (UBRR_VAL); my_com = 0; } void loop() { while(UCSR0A & (1 << RXC0)) // жду пока в регистре UDR0 появится байт { my_com = UDR0; // если появился - присвоил переменной if (my_com == 1) { UDR1 = 7; //1-й байт синхронизации от МК к Устройству UDR1 = 128; //2-й байт синхронизации от МК к Устройству if (UDR1 == 88) //байт синхронизации от Устройства { UDR1 = 7; //вот здесь проблема.. UDR1 = 18; // эти байты не отправляются } } if (my_com == 2) { UDR1 = 7; //1-й байт синхронизации от МК к Устройству UDR1 = 128; //2-й байт синхронизации от МК к Устройству if (UDR1 == 88) //байт синхронизации от Устройства { UDR1 = 7; //вот здесь проблема.. UDR1 = 16; // эти байты не отправляются } } } }
помогите плиз!!
... выполняет инструкцию, которая заключается в передаче устройству двух байт синхронизации (7 и 128) по USART_1 и последующем ожидании одного байта синхронизации по USART_1 ...
В этом проблема.
Никакого ожидания на самом деле нет - байт из UDR1 считывается сразу после передачи двух байт в него. Ответ от устройства ещё не пришёл, регистр UDR1 в этот момент "пуст".
Если не верите, проверьте бит RXC1 в регистре UCSR1A.
насколько я понимаю, байт в регистре остается до тех пор пока его не прочитают..(UDR1 == 88) - вот этим и читаю, после этого регистр - пустой, а в доказательство того, воткнул в каждое из условий Serial.print, откуда очевидно, что байт синхронизации от устройства приходит, и МК его воспринимает должным образом..
Выявил ещё вот, что у МК при указанном раскладе вообще не получается передать более 2 байт, то есть если во 2-м шаге передать устройству не 2 (как изначально) а один байт, то МК получит байт синхронизации и передаст в ответ 1 байт (из двух положеных)..
Строго говоря, читать регистр UDR можно только после того, как вы убедитесь, что в нём уже есть данные для чтения.
Вы же проверяете регистр UCSR0A перед чтением UDR0:
Абсолютно то же самое нужно делать перед проверкой регистра UDR1:
Вот так оно, может быть, и заработает.
Хотя, для полной правильности, перед записью байта тоже неплохо бы убедиться в готовности UART'а к приёму данных: