Ha már DC-AC 1f-3f

Moczik Gabor pm_levlista at progzmaster.hu
Fri Nov 16 16:06:08 CET 2007


Tóth Péter wrote:
>>Ha te megcsinálod a 3 fázis 400 Hz szinuszt abba a prociba....
> 
> Hááát, nem tudom. Szerintem menne. Attól függ, hogy mennyire akarsz 
> pontos szinusz, hány közelítési pontot akarsz.
> 1 megás műveleti sebesség elég kéne hogy legyen...
> 3 szoftver PWM-et kell csinálni, aztán 8-16 közelítési pont alapján 
> pöröghet.

Ha a PIC-nek semmit nem kell csinálnia, csak kiszámított gépi idejű ciklust 
futtat végtelen ciklusban, nincs megszakítás, nincs semmi, akkor viszi.
8-16 pont esetén még lehet hogy 1 MIPS is, de azért én valamivel szebb 
színuszra vágynék, ha már proci van benne.

Csak összehasonlítás végett:
8-bites SPI-s D/A konverteren 50Hz-es szinusz előállítása. A félhullám egy 
200 elemű byte-tömbben tárolva. Az SPI busz szoftveresen. Az SPI-n van még 
egy 16 bites A/D amit egyidejűleg be kell olvasni.
18.432MHz-en nem megy. 40MHz-en már megy, de "nem ér rá" a proci másra.
Végül pár % prociidőt azzal nyertem, hogy az összesen 16 bitnyi adatot nem 
egy ciklusban shifteltem ki és úgy adtam ki, hanem 16x egymás után le lett 
írva az utasítás. így éppen ráér még a főprogram kicsit számolni meg 
elküldeni a mérési eredményt soros porton.

#define DOCLK(bitno) \
     SCLK=0; \
     DAC_CS=0; \
     if (dac_buf&bitno) DAC_DATA=1; else DAC_DATA=0; \
     if (ADC_DATA) adc_buf|=bitno; \
     SCLK=1;

#pragma interrupt_level 1
static void interrupt isr_hi(void)
{
     TESTPIN0=1;
     if (TMR2IF) {
         TMR2IF=0;
         ADC_CONV=0;
         dac_buf = DAC_CONFIG;
         adc_buf=0;
         DOCLK(0x80);
         DOCLK(0x40);
         DOCLK(0x20);
         DOCLK(0x10);
         DOCLK(0x08);
         DOCLK(0x04);
         DOCLK(0x02);
         DOCLK(0x01);
         adc_hi=adc_buf;
         if (halfwave) {
             dac_buf=255-sintab[sin_idx];
         } else {
             dac_buf=sintab[sin_idx];
         }
         DOCLK(0x80);
         DOCLK(0x40);
         DOCLK(0x20);
         DOCLK(0x10);
         DOCLK(0x08);
         DOCLK(0x04);
         DOCLK(0x02);
         DOCLK(0x01);
         adc_lo=adc_buf;
         // deselect DAC
         DAC_CS=1;
         // start next AD conversion
         ADC_CONV=1;
         sin_idx++;
         if (sin_idx==200) {
             // zero crossing
             sin_idx=0;
             halfwave^=1;
         }
     }
     TESTPIN0=0;
}

(még mielőtt szóvá teszi valaki, hogy azért kell ASM-ben, hogy ez ne legyen 
gond, most szólok, hogy ilyen időkritikus dolgoknál meg szoktam nézni a 
generált ASM LIST-et, és úgy írom meg a kódot hogy jó legyen)

A TESTPIN0 egyébként arra jó, hogy szkóppal megnézve rajta a kitöltési 
tényezőt, látszik hogy mennyi időt tölt a proci interruptban :-)

-- 
((( Móczik Gábor  )))--((( E~Mail: pm-junk ~@~ progzmaster ~.~ hu )))
((( Skype: moczik )))



More information about the Elektro mailing list