uint8_t dataLed[3] = {0, 0, 50}; //массив светодиодов
const uint8_t maskLo[] = {0x08, 0x0C}; //маска младшего бита
const uint8_t maskHi[] = {0x80, 0xC0}; //маска старшего бита
const uint8_t maskBit[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; //маска анализа бита
void setup() {
ledInit(); //инициализация шины
}
void loop() {
ledWrite(dataLed, sizeof(dataLed)); //отрисовываем массив
}
//---------------------------------Передача массива данных на шину-----------------------------
void ledWrite(uint8_t* data, uint16_t size) {
ledReset(); //сигнал сброса
for (uint16_t i = 0; i < size; i ++) { //счетчик байт
for (uint8_t b = 0; b < 8; b += 2) { //счетчик бит
SPDR = maskHi[(boolean)(data[i] & maskBit[b])] | maskLo[(boolean)(data[i] & maskBit[b + 1])]; //загружаем 2 бита
while (!(SPSR & (0x01 << SPIF))); //ждем отправки
}
}
}
//------------------------------------Сброс шины-------------------------------------
void ledReset(void) {
__asm__ __volatile__ (
"CBI 0x05, 0x03 \n\t" //LOW на выход пина
"LDI r19, 200 \n\t" //счетчик сигнала reset(50мкс)
//-------------------------------------------------------------------------------
"_LOOP_DELAY_%=: \n\t" //цикл задержки
"NOP \n\t" //пропускаем цикл
"DEC r19 \n\t" //декремент счетчика циклов
"BRNE _LOOP_DELAY_%= \n\t" //переход в начало цикла задержки
:
:
);
}
//---------------------------------Инициализация шины--------------------------------
void ledInit(void) {
DDRB |= (0x01 << 3); //устанавливаем MOSI как выход
SPCR = (0x01 << SPE | 0x01 << SPR0 | 0x01 << MSTR); //включаем SPI с пределителем 4
SPSR = (0x01 << SPI2X); //включаем удвоение скорости
}