Цитата(NikitoS-86 @ Dec 10 2008, 11:07)

когда прошивал фьюзы - был абсолютно уверен, что если выбрать в закладке фьюзов в последней строке что-то типа внешнего тактового источника и нажать програм, то всё будет как надо...
Вот-вот... тоже попался на удочку визардов. Пользуюсь AVReal. Читаю описание
всех фузов, пишу .bat с командной строкой, абсолютно уверен, что "оно само" ничего лишнего не сделает.
Цитата(NikitoS-86 @ Dec 10 2008, 11:07)

Просто когда мне надо переслать 1 байт - всё замечательно, он ушёл и бог с ним... А если целый пакет?
В данном случае целый пакет вы не получите, потому что уже сидите в прерывании приема. Если надо переслать несколько байт, то используют промежуточный буфер в озу и прерывание по освобождению UDR, а не по окончанию передачи. Примерно вот так (код для меги8, но идея понятна):
CODE
#define TX_BUFFER_SIZE 8
uint8_t volatile TxHead;
uint8_t volatile TxTail;
uint8_t TxPool[TX_BUFFER_SIZE];
void send_byte(unsigned char byte)
{
uint8_t Tmp = TxHead;
while((uint8_t)(Tmp - TxTail) >= (uint8_t) TX_BUFFER_SIZE)
; // buffer full, wait
TxBuffer[ Tmp ] = Byte;
Tmp = (Tmp + 1) & (TX_BUFFER_SIZE - 1);
TxHead = Tmp;
UCSRB |= (1<<UDRIE);
}
void send_str(PGM_P string)
{
char c;
while( (c = pgm_read_byte(string++)) != '\x0' )
{
send_byte( c );
}
}
void send_str_P(char * string)
{
char c;
while( (c = *string++) != '\x0' )
{
send_byte( c );
}
}
ISR(USART_UDRE_vect)
{
UCSRB &= ~(1<<UDRIE);
sei();
{
uint8_t Tmp = TxTail;
UDR = TxBuffer[ Tmp ];
Tmp = (Tmp + 1) & (TX_BUFFER_SIZE - 1)
TxTail = Tmp;
if(Tmp != TxHead) // more data pending in buffer
{
UCSRB |= (1<<UDRIE);
}
}
}
или, в простейшем случае, без прерываний:
Код
void send_byte(uint8_t Byte)
{
while(!(UCSRA & (1<<UDRE)));
UDR = Byte;
}
В любом случае ожидание должно происходить вне обработчика прерывания.
Цитата(NikitoS-86 @ Dec 10 2008, 11:07)

Не получится ли так, что просто в цикле будет так, что следующий пакет будет наступать на пятки предыдущему? Или может тут как раз стоит подумать о прерывании по окончании передачи?
В случае "эха" - не получится. И прерывание по освобождению UDR. Прерывание об окончании передачи используется для другого - например, для отключения передатчика в RS485.
Цитата(NikitoS-86 @ Dec 10 2008, 11:07)

4) И ещё вопрос... Ситуация - надо отослать массив данных, например, short (2 байта)... Мне достаточно написать:
UDDR0=Mass[i]
и он сам поймёт, что надо просто тупо запихать сначала первый байт инта, потом второй? Или же надо самостоятельно ему поочереди запихнуть сначала первый байт, потом второй?
Конечно самостоятельно. В вашей строке он запихнет только i-тый элемент массива. Можно написать универсальную функцию:
Код
void send_block(void const *ptr, uint8_t size)
{
while(size--)
{
send_byte(*ptr++);
}
}
void test()
{
unsigned char Mass[2];
unsigned short Short;
send_block(Mass, sizeof(Mass));
send_block(&Short, sizeof(Short));
}