Код:
#include <iopins.h>
#include <pinlist.h>
#include <latch.h>
#include "uart.h"
using namespace IO;
#include <avr/version.h>
#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#define BrightnessSize 42
#define TCNT2_Const 256-60
#define MaxBlank 65000
uint8_t volatile PWM_Counter=0;
uint8_t Brightness[BrightnessSize];
typedef Pb2 SSPin;
typedef Pd0 SerialIn_Pin;
typedef Pd1 SerialOut_Pin;
void Timer(void);
//int8_t RealCannels[42] ={37,39,35, 18,20,16, 17,19,15, 10,12,8, 9, 11, 7,
// 1,3,13, 2,4,0, 14, 6, 5, 27,26,25, 21,23,33,
// 22,24,34, 29,31,41, 30,32,28, 38,40,36};
int8_t RealCannels[42] ={37,39,35, 18,20,16, 17,19,15, 10,12,8, 9, 11, 7,
1,3,13, 2,4,0, 14, 6, 5, 27,26,25, 21,23,33,
22,24,34, 29,31,41, 30,32,28, 38,40,36};
int main (void)
{
uint8_t i;
i=1;
DDRB=0;;
Pb5::SetDirWrite();
Pb3::SetDirWrite();
Pd7::SetDirWrite();
SSPin::SetDirWrite();
SPSR = (1<<SPI2X); // SPI set clock rate fck/2
SPCR = (1<<SPE)|(1<<MSTR); // Enable SPI, Master
for (int i=0;i<BrightnessSize;i++) //обнулить массив
{
Brightness[i]=0;
}
TIMSK2 &= ~(1<<TOIE2); //разрешения прерывания по переполнению таймера/счетчика Т2
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));// Режим работы таймера/счетчика
TCCR2B &= ~(1<<WGM22);// Режим работы таймера/счетчика
TCCR2B |= (1<<CS21); //установка предделителя 64
ASSR &= ~(1<<AS2); //Выбор источника синхронизации таймера если AS2=0 от системного генератора
TCNT2 = TCNT2_Const; // 16000000/256/100/64=8 tcnt2=256-8=248.
TIMSK2 |= (1<<TOIE2);//Разрешение прерывания по переполнению Т2.
sei();
uint16_t blank=0;
uartInit();
uartSetBaudRate(115200);
SerialIn_Pin::SetDirRead();
SerialOut_Pin::SetDirWrite();
// UCSR0C=(1<<UCSZ01)|(1<<UCSZ00);
uint8_t TimerCurrPWM=0;
for(;;)
{
if (!uartReceiveBufferIsEmpty())
{
blank=0;
uint8_t b=uartGetByte();
if (i>=BrightnessSize)
{
if (b == 255)
{
i=0;
blank=0;
}
else
blank++;
}
else
{
Brightness[RealCannels[i]]=b;
blank=0;
i++;
}
}
else
{
if (blank<MaxBlank)
{
if (TimerCurrPWM!=PWM_Counter)
{
blank++;
TimerCurrPWM=PWM_Counter;
}
}
else
{
for (uint8_t j = 0; j < BrightnessSize; j++)
Brightness[j] = 15;
blank=MaxBlank;
}
}
}
}
//void Timer(void)
SIGNAL(TIMER2_OVF_vect)
{
Pd7::Set();
Pd7::Set();
Pd7::Clear();; //формируем положительный импульс защелки
uint8_t PWM_Counter_v=PWM_Counter; // поскольку PWM_Counter объявлена как valotile, обращение к ней - всегда обращение в память. Поэтому создаем локальную копию, она будет храниться в регистре.
TCNT2 = TCNT2_Const;
uint8_t byte_shift;
uint8_t * CBright;
CBright = (uint8_t *)&Brightness[0];
uint8_t j=0;
for (j=6;j>0;j--)
{
byte_shift = 0;
if(*CBright>PWM_Counter_v) byte_shift|= 1;
CBright++;
byte_shift = byte_shift<<1;
if(*CBright>PWM_Counter_v) byte_shift|= 1;
CBright++;
byte_shift = byte_shift<<1;
if(*CBright>PWM_Counter_v) byte_shift|= 1;
CBright++;
byte_shift = byte_shift<<1;
if(*CBright>PWM_Counter_v) byte_shift|= 1;
CBright++;
byte_shift = byte_shift<<1;
if(*CBright>PWM_Counter_v) byte_shift|= 1;
CBright++;
byte_shift = byte_shift<<1;
if(*CBright>PWM_Counter_v) byte_shift|= 1;
CBright++;
byte_shift = byte_shift<<1;
if(*CBright>PWM_Counter_v) byte_shift|= 1;
CBright++;
byte_shift = byte_shift<<1;
SPDR = byte_shift; //отправляем в шину SPI
}
PWM_Counter++;
}
ps. прошу того, у кого заработает под средой arduino, выложить скетч, чтобы каждый не мучался.