Проблемы с USART? Приветствую.
Суть : через терминал посылаются байты 0, либо 1, либо 2. В зависимости от этого светодиод зажигается либо 1, либо 2, либо 3 раза.
Проблема: когда посылаю 2, то должен сразу 3 раза поморгать светодиод, однако приходится 2 посылать 3 раза, и только на 3-й раз светодиод моргает 3 раза. Тоже самое когда посылаю 0 или 1, только на второй раз начинает нормально моргать светодиод (т.е только когда второй раз байт отправил).
В чем причина?
Вот код на Atmel Studio.#define F_CPU 16000000UL
#include
#include
#include "USART.h"
void led_blink()
{
if(USART_reciv() == '0') //моргаем 1 раз
{

PORTB |= (1 << 2);
_delay_ms(100);
PORTB &= ~(1 << 2);
}
else if(USART_reciv() == '1') // моргаем 2 раза
{

PORTB |= (1 << 2);
_delay_ms(100);
PORTB &= ~(1 << 2);
_delay_ms(100);
PORTB |= (1 << 2);
_delay_ms(100);
PORTB &= ~(1 << 2);
}
else if(USART_reciv() == '2') // если прислали 2, то моргаем 3 раза
{

PORTB |= (1 << 2);
_delay_ms(100);
PORTB &= ~(1 << 2);
_delay_ms(100);
PORTB |= (1 << 2);
_delay_ms(100);
PORTB &= ~(1 << 2);
_delay_ms(100);
PORTB |= (1 << 2);
_delay_ms(100);
PORTB &= ~(1 << 2);
}
}
int main(void)
{

DDRB = 0xFF; // led
DDRD |= (1 << 1); //tx
DDRD &= ~(1 << 0); //rx

USART_init(MYUBRR); //инициализируем USART, MYUBRR - это скорость передачи, по спец формуле рассчитывается

USART_transmit('O'); USART_transmit('k'); USART_transmit('!'); USART_transmit(0x0d);
USART_transmit(0x0a); //отправляем "Ок!" в терминал, чтобы проверить работу USART



while (1)
{
led_blink();
_delay_ms(10); // думал поставить задержку, чтобы решить проблему, но все так же
}
}

21 Авг 2019 в 06:22
198 +1
0
Ответы
1

Проблема заключается в том, что вы вызываете функцию USART_reciv() в каждом условии if. Это означает, что каждый раз, когда функция вызывается внутри условия if, она читает новый символ из USART. Поэтому, когда вы отправляете '2', первый вызов USART_reciv() читает '2', но при следующем вызове внутри того же условия if он пропускает '2' и снова считывает следующий символ.

Для исправления этой проблемы вам следует считать символ из USART один раз и сохранить его в переменной, чтобы использовать его в каждом условии if. Например:

void led_blink()
{
char received_char = USART_reciv();
if (received_char == '0') //моргаем 1 раз
{
PORTB |= (1 << 2);
_delay_ms(100);
PORTB &= ~(1 << 2);
}
else if (received_char == '1') // моргаем 2 раза
{
PORTB |= (1 << 2);
_delay_ms(100);
PORTB &= ~(1 << 2);
_delay_ms(100);
PORTB |= (1 << 2);
_delay_ms(100);
PORTB &= ~(1 << 2);
}
else if (received_char == '2') // если прислали 2, то моргаем 3 раза
{
PORTB |= (1 << 2);
_delay_ms(100);
PORTB &= ~(1 << 2);
_delay_ms(100);
PORTB |= (1 << 2);
_delay_ms(100);
PORTB &= ~(1 << 2);
_delay_ms(100);
PORTB |= (1 << 2);
_delay_ms(100);
PORTB &= ~(1 << 2);
}
}

Попробуйте внести эту коррекцию в ваш код и посмотрите, исправляет ли это проблему.

20 Апр в 13:19
Не можешь разобраться в этой теме?
Обратись за помощью к экспертам
Название заказа не должно быть пустым
Введите email
Бесплатные доработки
Гарантированные бесплатные доработки
Быстрое выполнение
Быстрое выполнение от 2 часов
Проверка работы
Проверка работы на плагиат
Интересные статьи из справочника
Поможем написать учебную работу
Название заказа не должно быть пустым
Введите email
Доверьте свою работу экспертам
Разместите заказ
Наша система отправит ваш заказ на оценку 84 622 авторам
Первые отклики появятся уже в течение 10 минут
Прямой эфир