POV (06.09.2011 09:40 - 10:24, просмотров: 270) ответил maik-vs на Ага. Когда я для себя это нарисовал, осталось даже не программировать, а КОДИТЬ :)
Вроде бы вот так получается. Если не я ошибся, то всё очень несложно и есть что упростить. Погонял в симуляторе, вроде похоже... BYTE xdata Power[5] = {0}; // мощща
BYTE IndexPWM;
BYTE MultipPWM = 50; // определяет частоту ШИМ
// 11 момент - чтобы догнать длительность фазы до 255
BYTE xdata TimesPWN[11], // последовательные моменты включения/выключения каналов (свёрнутые в одну фазу)
Channel[1], // канал к которому относится соответствующим момент
State[1]; // что надо сделать с этим каналом
// Подготовка данных для ШИМ
void PreparePWM()
{
BYTE xdata k, i, phase = 0;
WORD xdata Times[2][5]; // последовательные моменты включения/выключения каналов (строка регулирования)
Times[0][0] = 0;
Times[1][0] = Times[0][0]+Power[0];
Times[0][1] = Times[1][0];
Times[1][1] = Times[0][1]+Power[1];
Times[0][2] = Times[1][1];
Times[1][2] = Times[0][2]+Power[2];
Times[0][3] = Times[1][2];
Times[1][3] = Times[0][3]+Power[3];
Times[0][4] = Times[1][3];
Times[1][4] = Times[0][4]+Power[4];
// сворачиваем строку регулирования в матрицу
for (i = 0; i < 5; i++) // 5 каналов
for (k = 0; k < 2; k++) // 2 состояния включить/выключить
{
if (Times[k][i] > 255*(phase+1)) phase++; // попали в другую фазу, надо на новую строку матрицы переходить
TimesPWN[i*2+k] = Times[k][i] - 255*phase;
Channel[i*2+k] = i;
State[i*2+k] = !k;
}
TimesPWN[10] = 255; Channel[10] = 0; State[10] = 0;
IndexPWM = 0;
}
// отработка ШИМ
void WPM() interrupt INTERRUPT_TIMER3
{
WORD temp = 65535 - MultipPWM*TimesPWN[IndexPWM];
TMR3CN &= 0xFB; // TR3 = FALSE;
TMR3L = temp;
TMR3H = temp >> 8;
TMR3CN |= 0x04; // TR3 = TRUE;
switch (Channel[IndexPWM])
{
case 0: K1 = State[IndexPWM]; break;
case 1: K2 = State[IndexPWM]; break;
case 2: K3 = State[IndexPWM]; break;
case 3: K4 = State[IndexPWM]; break;
case 4: K5 = State[IndexPWM]; break;
}
IndexPWM++;
if (IndexPWM > 10) IndexPWM = 0;
}