sei() в прерывании позволяет прервать прерывание таймера на другие прерывания - к примеру, на обработку прихода символа в uart (больше прерываний вроде как не может быть). Поскольку приход символа может скушать заметно времени, может появляется мерцание. Но ни на что больше это влиять не должно в нормальных условиях.
Сдвиг светящихся светодиодов может произойти, если прерывание по приходу символа не успевает обработаться до момента прихода еще одного символа. Размер аппаратного буфера - 1 байт. По прерыванию uart этот символ извлекается и перекладывается в программный буфер, из которого уже извлекаются символы в loop();
Думаю, что loop лучше модифицировать на что-то вроде:
В коде может и накосячил, протестить не на чем. Смысл в том, что не ждать, пока все данные загрузятся, а сразу менять Brightness, по приходу каждого байта.Код:void loop() { if (Serial.available()) { if (Serial.read() == 255) //проверка прификса { for (int i = 0; i < BrightnessSize; i++) { for (;(Serial.available()==0)&&(blank<=100000);blank++); if Serial.available() { Brightness[i] = Serial.read(); // прочитать данные о цветах из порта в массив blank=0; } } } } else { if(blank>100000) { blank=0; for (byte i = 0; i < BrightnessSize; i++) Brightness[i] = 15;} blank++; } }
Не поленился и переписал с нуля главный цикл, так получается проще, хоть и выглядит страшнее. Принцип простой - есть символ - сразу читаем. Если i==BrightnessSize, то означает, что ждем 255-й символ. Иначе - присваиваем в Brightness[i]
Код:uint8_t i; uint16_t blank; setup() { ... i=BrightnessSize; blank=0; } loop() { if (Serial.available()) { uint8_t b=(Serial.read(); if (i=BrightnessSize) { if (b == 255) i=0; else blank++; } else { Brightness[i]=b; blank=0; i++; } } else { _delay_us(200); if (blank<MaxBlank) blank++; else { for (uint8_t j = 0; j < BrightnessSize; j++) Brightness[j] = 15; blank=MaxBlank; } } }




Ответить с цитированием
