Beispiel #1
0
//####################################################################################################### 
void pwm_update(void) // PWM Update, berechnet aus den PWM Einstellungen die neuen Werte für die Interruptroutine
{
    uint8_t i, j, k, min;
    uint8_t tmp;
 
    // PWM Maske für Start berechnen und gleichzeitig die Bitmasken generieren und PWM Werte kopieren
 
    tmp=0;
    j = 1;
    for(i=1; i<=(PWM_CHANNELS); i++) 
		{
        main_ptr_mask[i]=~j;                        // Maske zum Löschen der PWM Ausgänge
        pwm_setting_tmp[i] = pwm_setting[i-1];
        if (pwm_setting_tmp[i]!=0) tmp |= j;        // Maske zum setzen der IOs am PWM Start
        j <<= 1;
		}	
    main_ptr_mask[0]=tmp;                           // PWM Start Daten 
 

    // PWM settings sortieren; Einfügesortieren
 
    for(i=1; i<=PWM_CHANNELS; i++) 
		{
        min=255;
        k=i;
        for(j=i; j<=PWM_CHANNELS; j++) 
			{
            if (pwm_setting_tmp[j]<min) 
				{
                k=j;                                // Index und PWM-setting merken
                min = pwm_setting_tmp[j];
				}
			}
        if (k!=i) 
			{
            // ermitteltes Minimum mit aktueller Sortiertstelle tauschen
            tmp = pwm_setting_tmp[k];
            pwm_setting_tmp[k] = pwm_setting_tmp[i];
            pwm_setting_tmp[i] = tmp;
            tmp = main_ptr_mask[k];
            main_ptr_mask[k] = main_ptr_mask[i];
            main_ptr_mask[i] = tmp;
			}
		}
 
    // Gleiche PWM-Werte vereinigen, ebenso den PWM-Wert 0 löschen falls vorhanden
 
    k=PWM_CHANNELS;             // PWM_CHANNELS Datensätze
    i=1;                        // Startindex
 
    while(k>i) 
		{
        while ( ((pwm_setting_tmp[i]==pwm_setting_tmp[i+1]) || (pwm_setting_tmp[i]==0))  && (k>i) ) 
			{
 
            // aufeinanderfolgende Werte sind gleich und können vereinigt werden
            // oder PWM Wert ist Null
            if (pwm_setting_tmp[i]!=0)
                main_ptr_mask[i+1] &= main_ptr_mask[i];        // Masken vereinigen
 
            // Datensatz entfernen,
            // Nachfolger alle eine Stufe hochschieben
            for(j=i; j<k; j++) 
				{
                pwm_setting_tmp[j] = pwm_setting_tmp[j+1];
                main_ptr_mask[j] = main_ptr_mask[j+1];
				}
            k--;
			}
        i++;
		}
    
    // letzten Datensatz extra behandeln
    // Vergleich mit dem Nachfolger nicht möglich, nur löschen
    // gilt nur im Sonderfall, wenn alle Kanäle 0 sind
    if (pwm_setting_tmp[i]==0) k--;
 
    // Zeitdifferenzen berechnen
    
    if (k==0) { // Sonderfall, wenn alle Kanäle 0 sind
        main_ptr_time[0]=(uint16_t)T_PWM*PWM_STEPS/2;
        main_ptr_time[1]=(uint16_t)T_PWM*PWM_STEPS/2;
        k=1;
    }
    else 
		{
        i=k;
        main_ptr_time[i]=(uint16_t)T_PWM*(PWM_STEPS-pwm_setting_tmp[i]);
        j=pwm_setting_tmp[i];
        i--;
        for (; i>0; i--)
			{
            main_ptr_time[i]=(uint16_t)T_PWM*(j-pwm_setting_tmp[i]);
            j=pwm_setting_tmp[i];
			}
        main_ptr_time[0]=(uint16_t)T_PWM*j;
		}
 
    // auf Sync warten
 
    pwm_sync=0;             // Sync wird im Interrupt gesetzt
    while(pwm_sync==0);
 
    // Zeiger tauschen
    cli();
    tausche_zeiger();
    pwm_cnt_max = k;
    sei();
}
Beispiel #2
0
void pwm_update(void) {

	uint8_t i, j, k;
	uint8_t m1, m2, tmp_mask; // ändern uint16_t oder uint32_t für mehr Kanäle
	uint16_t min, tmp_set; // ändern auf uint16_t für mehr als 8 Bit Auflösung

	// PWM Maske für Start berechnen
	// gleichzeitig die Bitmasken generieren und PWM Werte kopieren

	m1 = 1 << PWM_CHANNEL_OFFSET;
	m2 = 0;
	for (i = 1; i <= (PWM_CHANNELS); i++) {
		main_ptr_mask[i] = ~m1; // Maske zum Löschen der PWM Ausgänge
		pwm_setting_tmp[i] = pgm_read_word (& pwmtable[pwm_setting[i - 1]]);
		if (pwm_setting_tmp[i] != 0)
			m2 |= m1; // Maske zum setzen der IOs am PWM Start
		m1 <<= 1;
	}
	main_ptr_mask[0] = m2; // PWM Start Daten

	// PWM settings sortieren; Einfügesortieren

	for (i = 1; i <= PWM_CHANNELS; i++) {
		min = PWM_STEPS - 1;
		k = i;
		for (j = i; j <= PWM_CHANNELS; j++) {
			if (pwm_setting_tmp[j] < min) {
				k = j; // Index und PWM-setting merken
				min = pwm_setting_tmp[j];
			}
		}
		if (k != i) {
			// ermitteltes Minimum mit aktueller Sortiertstelle tauschen
			tmp_set = pwm_setting_tmp[k];
			pwm_setting_tmp[k] = pwm_setting_tmp[i];
			pwm_setting_tmp[i] = tmp_set;
			tmp_mask = main_ptr_mask[k];
			main_ptr_mask[k] = main_ptr_mask[i];
			main_ptr_mask[i] = tmp_mask;
		}
	}

	// Gleiche PWM-Werte vereinigen, ebenso den PWM-Wert 0 löschen falls vorhanden

	k = PWM_CHANNELS; // PWM_CHANNELS Datensätze
	i = 1; // Startindex

	while (k > i) {
		while (((pwm_setting_tmp[i] == pwm_setting_tmp[i + 1]) || (pwm_setting_tmp[i] == 0))
				&& (k > i)) {

			// aufeinanderfolgende Werte sind gleich und können vereinigt werden
			// oder PWM Wert ist Null
			if (pwm_setting_tmp[i] != 0)
				main_ptr_mask[i + 1] &= main_ptr_mask[i]; // Masken vereinigen

			// Datensatz entfernen,
			// Nachfolger alle eine Stufe hochschieben
			for (j = i; j < k; j++) {
				pwm_setting_tmp[j] = pwm_setting_tmp[j + 1];
				main_ptr_mask[j] = main_ptr_mask[j + 1];
			}
			k--;
		}
		i++;
	}

	// letzten Datensatz extra behandeln
	// Vergleich mit dem Nachfolger nicht möglich, nur löschen
	// gilt nur im Sonderfall, wenn alle Kanäle 0 sind
	if (pwm_setting_tmp[i] == 0)
		k--;

	// Zeitdifferenzen berechnen

	if (k == 0) { // Sonderfall, wenn alle Kanäle 0 sind
		main_ptr_time[0] = (uint16_t) T_PWM * PWM_STEPS / 2;
		main_ptr_time[1] = (uint16_t) T_PWM * PWM_STEPS / 2;
		k = 1;
	} else {
		i = k;
		main_ptr_time[i] = (uint16_t) T_PWM * (PWM_STEPS - pwm_setting_tmp[i]);
		tmp_set = pwm_setting_tmp[i];
		i--;
		for (; i > 0; i--) {
			main_ptr_time[i] = (uint16_t) T_PWM * (tmp_set - pwm_setting_tmp[i]);
			tmp_set = pwm_setting_tmp[i];
		}
		main_ptr_time[0] = (uint16_t) T_PWM * tmp_set;
	}

	// auf Sync warten

	pwm_sync = 0; // Sync wird im Interrupt gesetzt
	while (pwm_sync == 0)
		;

	// Zeiger tauschen
	cli();
	tausche_zeiger();
	pwm_cnt_max = k;
	sei();
}