Цитата(Xenia @ Oct 18 2009, 19:27)

У вас "лишняя" проверка cmd & 0x80, т.к. тестировать быстрее при сдвиге cmd <<= 1, поскольку этот бит выпадающий.
Это смотря чего хотеть.
Если скважности SCK 2.000 и предельно точной настройки частоты, то да, лучше асм.
Если "лишь бы более-менее близко к 2 и побыстрее", то это пишется левой задней, быстрее заново написать,
чем искать откуда скопипастить, так как писалось уже неоднократно, в том числе ещё для 51-го.
Да, в зависимости от данных слегка дрожит длительность 1-ки.
Что-то не могу придумать пример, где это будет мешать.
Зато одна процедура и на ввод, и на вывод, довольно компактно и быстро.
Код
#include <avr/io.h>
#include "pin_macros.h"
#define SCK B,0,H
#define MOSI B,1,H
#define MISO B,2,H
/* ну и где-то в h-файле, если кого-то "полнота набора" волнует
* static inline uint8_t spi_in(void) { retuirn spi_io(0xFF); }
* static inline void spi_out(uint8_t b) { spi_io(b); }
*/
/* Это под SPI, у которого сдвиг по спаду, приёмник фиксирует по фронту, ну
* данная подпрограмма - после фронта, лишь бы до спада.
*/
uint8_t spi_io(uint8_t b)
{
uint8_t i = 8;
do {
OFF(SCK);
OFF(MOSI);
if(b & 0x80) ON(MOSI);
b <<= 1; // а вот она задержка от выдачи до фронта
ON(SCK);
if( ACTIVE(MISO) ) ++b;
} while(--i);
OFF(SCK);
return b;
}
И компилируется в такое
Код
.global spi_io
.type spi_io, @function
spi_io:
/* prologue: frame size=0 */
/* prologue end (size=0) */
ldi r25,lo8(8)
.L2:
cbi 56-0x20,0 ; SCK = 0
cbi 56-0x20,1 ; MOSI = 0
sbrc r24,7
sbi 56-0x20,1 ; MOSI = 1 если надо
.L3:
lsl r24 ; задержка перед фронтом
sbi 56-0x20,0 ; SCK = 1
sbic 54-0x20,2 ; семплирование входа
subi r24,lo8(-(1))
.L5:
subi r25,lo8(-(-1))
brne .L2
cbi 56-0x20,0
ldi r25,lo8(0)
/* epilogue: frame size=0 */
ret