У меня есть ATTiny, который должен получать команды через UART. У меня есть простой дисплей из восьми светодиодов, который должен показывать содержимое самого последнего полученного байта. Я использую прерывание для чтения данных по мере их получения. Независимо от того, какие данные я отправляю, UDR всегда читает 0xFF
в прерывании. Я знаю, что прерывание запускается, так как дисплей меняется с 0x00
на 0xFF
, но он никогда не отображает значение, которое я отправил по последовательной шине.
Вот как я включаю UART.
UBRRH = UBRRH_VALUE;
UBRRL = UBRRL_VALUE;
#if USE_2X
UCSRA |= (1U << U2X);
#else
UCSRA &= ~(1U << U2X);
#endif
// Enable receiver and interrupt
UCSRB = (1U << RXEN) | (1U << RXCIE);
// No parity, 8 Data Bits, 1 Stop Bit
UCSRC = (1U << UCSZ1) | (1U << UCSZ0);
Это код в прерывании. Я протестировал display()
, и он работает правильно сам по себе, что означает, что message
всегда 0xFF
.
ISR(USART_RXC_vect) {
uint8_t message = UDR;
display(message);
}
Я уверен, что мой компьютер отправляет правильную информацию, но я только проверил это с псевдотерминалом для распечатки отправленных байтов. Я собираюсь sn oop аппаратное соединение с осциллографом, но не думаю, что это проблема. Есть ли что-то, из-за чего UDR всегда читается как 0xFF?
Изменить: я отслеживал соединение с помощью осциллографа и проверял, что компьютер отправляет правильные данные с правильной скоростью. Однако ATTiny не работает с правильной скоростью передачи данных. При скорости 2400 бод импульсы должны быть длиной около 400 микросекунд, однако микроконтроллер выдает импульсы длительностью более 3 миллисекунд. Это объясняет, почему он всегда будет читать 0xFF, компьютер будет отправлять почти весь байт, когда контроллер думает, что он получает стартовый бит, когда контроллер пытается прочитать оставшиеся данные, строки будут отключены, в результате чего он прочитает все. Я до сих пор не знаю, почему это так, поскольку считаю, что правильно устанавливаю скорость передачи данных на контроллере.
Изменить: проблема решена. По умолчанию предварительный делитель тактовой частоты установлен на 8, поэтому устройство работало только на 1 МГц, а не на 8 МГц. Установка предделителя часов на 1 решила проблему.