Спасибо за советы.
В понедельник утром остановился на варианте ниже
PHP код:
#define D22_High PORTA |=B00000001
#define D22_Low PORTA &= B11111110
volatile byte set[7] ;
volatile unsigned int tcnt2 = 206; //32 такта делителя * (256-206)=1600 тактов. То есть каждые 0,1 мс.
volatile unsigned int var = 1 ;
volatile byte pwm_time = 0 ;
void setup()
{
pinMode(22, OUTPUT);
pinMode(2, OUTPUT); // Давление топлива
pinMode(3, OUTPUT); // Давление в коллекторе
pinMode(4, OUTPUT); // Температура топлива
pinMode(5, OUTPUT); // Температура двигателя
TIMSK2 &= ~(1<<TOIE2);
TCCR2A &= ~((1<<WGM21) | (1<<WGM20));
TCCR2B &= ~((1<<WGM22) | (1<<CS22));
TCCR2B |= ((1<<CS21) | (1<<CS20));
ASSR &= ~(1<<AS2);
TIMSK2 |= (1<<TOIE2);
Serial.begin(9600);
}
void loop()
{
if(Serial.available() > 7)
{
if(Serial.read() == 255)
{
for(int i = 0; i < 7; i++)
{
set[i] = Serial.read(); // set[0] - Длительность импульса впрыска, Длительность паузы = set[1] + set[2] * 250
}
}
}
analogWrite(2, set[3]); // Давление топлива
analogWrite(3, set[4]);
analogWrite(4, set[5]); // Температура топлива
analogWrite(5, set[6]); // Температура двигателя
}
//************* прерывание *************
ISR(TIMER2_OVF_vect)
{
TCNT2 = tcnt2;
switch (var)
{
case 1:
pwm_time++;
if(pwm_time < set[0]) D22_High;
else
{
pwm_time=0;
var = 2 ;
}
break;
case 2:
pwm_time++;
if(pwm_time < set[1]) D22_Low;
else
{
if (set[2] > 0) var = 3; else var = 1;
pwm_time=0;
}
break;
case 3:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 1) var = 4; else var = 1;
pwm_time=0;
}
break;
case 4:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 2) var = 5; else var = 1;
pwm_time=0;
}
break;
case 5:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 3) var = 6; else var = 1;
pwm_time=0;
}
break;
case 6:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 4) var = 7; else var = 1;
pwm_time=0;
}
break;
case 7:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 5) var = 8; else var = 1;
pwm_time=0;
}
break;
case 8:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 6) var = 9; else var = 1;
pwm_time=0;
}
break;
case 9:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 7) var = 10; else var = 1;
pwm_time=0;
}
break;
case 10:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 8) var = 11; else var = 1;
pwm_time=0;
}
break;
case 11:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 9) var = 12; else var = 1;
pwm_time=0;
}
break;
case 12:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
if (set[2] > 10) var = 13; else var = 1;
pwm_time=0;
}
break;
case 13:
pwm_time++;
if(pwm_time < 250) D22_Low;
else
{
pwm_time=0;
var = 1;
}
break;
}
}
Увеличил делитель и с точностью до 0.1 мс запустил. Провозился с командой For в таймере, но так и не понял где ошибаюсь, сделал тупо на Case и собрал в корпус.
Подскажите как лучше работать с двух-байтовыми значениями?
p.s. И еще при измерении реального импульса есть ошибка в 10 мкс, т.е. вместо 10,0 мс получается 9,99 мс, при 10,1 получается 10,09 мс и т.д.
Есть ли вариант добавить 0,01 мс ?