Okej... Evo jedan sličan primer. Prvo, imamo šemu pločee, pa da znamo šta je gde povezano:
http://www.mikroe.com/eng/downloads/get/312/easypic6_schematic_v101.pdf
Drugo, opet se koriste ugrađene biblioteke koje pravi mikroelektronika, a ja sam lično dokoni protivnik korišćenja istih jer ne možeš dobro ukapirati šta se događa u kontroleru ako ćeš koristi već gotove funkcije. No, nebitno. Pretostavljama da znaš šta je PWM signal, ali ako ne znaš, evo kratkog objašnjenja: PWM je fazno modulisan pravougaoni signal kod kojeg se menja faktor ispune (duty cycle) dok frekvencija i amplituda ostaju iste.
Evo primera:
Dakle, poenta je da tvoj mikrokontroler generiše PWM signal. Gde i kako se to radi videćemo u nastavku. Ovde u primeru sam odabrao ovaj mikrokontroler: PIC16F887. PA da vidimo šta se tu događa.... Jedan način da se generiše PWM je putem digitalnog IO sistema, dakel setuje neki bit na 1 određeno vreme, pa resetuješ na 0 određeno vreme i tako u krug pri tome pazeži da zbir vremena setovanja i vreme resetovanja budu konstantni inače bi menjao frekvenciju. Ovo znači koliko povećaš jedno vreme, za toliko moraš smanjiti drugo. Drugi način, i to mnogo bolji je putem tajmera koji postoje ugrađeni u mikrokontrloler. Obično se oni fabrički izvedu tako da mogu vrlo jednostavno da generišu PWM signal, a to je slučaj i sa ovim mikrokontrolerom. Kad ne bi imao ove ugrađene funkcije za inicijalizaciju, mogao bi opet sam da ih napišeš i to bez puno muke. (možda ti jednom pokažem detaljno kako se to radi, ali ima vremena)
Prvo da vidimo kako izgleda mikrokontroler:
Primetićeš izlaze CCP1 i CCP2 na pinovima 16 i 17. Ti izlazi su u stvari izlazi unutrašnjeg PWM generatora i na njima se javlja PWM kad ga uključiš. To je dakle na portu C, pa ja ne znam šta je tvoj profa zamislio sa porotm D... Valjda da prati veličinu faktora ispune?!
Elem, na pinove 16 i 17 se prikače osciloskopa i posmatra signal koji treba da izgleda kao na slici gore. Idemo dalje. Funkcije
PWM1_Init(5000); // Initialize PWM1 module at 5KHz
PWM2_Init(5000); // Initialize PWM2 module at 5KHz
inicijalizuju tajmere u mikrokontroleru da rade kao PWM generatori i to na 5000 herca u ovom konkretnom slučaju. Posle toga se podesi i faktor ispune:
PWM1_Set_Duty(0); // Set current duty for PWM1
PWM2_Set_Duty(0); // Set current duty for PWM2
Ovako se praktično isključi PWM, jer je vreme setovanja 0% a vreme resetovanja 100%. Posle toga neka petlja podešava faktor ispune, a kako će to da radi je stvar programera. Možeš ga menjati preko nekih dugmića, možeš ga menjati preko analognog ulaza, slati ga serijskom vezom preko RS232 ulaza... Još da napomenem faktor ispune od 100% odgovara vrednosti 255....
U nastavku evo programa koji je ponudila Mikroelektronika, a ja ću ga komentarisati
Kod:
unsigned short current_duty, current_duty1;
//Ovde su deklarisane dve promenjive koje će kasnije trebati, dakle ništa posebno
void InitMain() {
ANSEL = 0; // Ovde se analogni pinovi kofigurišu kao digitalni jer nema potrebe za njihovim korišćejem. DA zadajemo PWM preko nekog potenciometra, onda bi trebalo...
ANSELH = 0;
C1ON_bit = 0; // Komparatori su takođe nepotrebni pa su isključeni
C2ON_bit = 0;
PORTA = 255;
TRISA = 255; // Port A je ulazni jer su dugmići preko kojih povećavamo i smanjujemo faktor ispune na portu A. Ovo znači da u njega treba upisati 255.
PORTB = 0; // Set PORTB to 0
TRISB = 0; //Port B je izlazni ali ga ne koristimo, ne treba nam,
PORTC = 0; // Set PORTC to 0
TRISC = 0; // Port C je izlazni takođe. Mislim da mora biti ovako jer su CCP1 i CCP2 povezani na iste pinove ali možda i ne mora, treba pogleradi u user manual za mikrokontroler...
PWM1_Init(5000);
PWM2_Init(5000); // Inicijalizujemo generatore na 5kHz
}
void main() {
InitMain();
current_duty = 16;
current_duty1 = 16; //Podesimo neki mali faktor ispune svejedno koji
PWM1_Start();
PWM2_Start();
PWM1_Set_Duty(current_duty);
PWM2_Set_Duty(current_duty1); // Potom startujemo generatore sa tim nekim malim početnim faktorom ispune
while (1) { // Sad pravimo beskonačnu petlju u kojoj preko dugmića na RA0 i RA1 za prvi i RA2 i RA3 za drugi PWM generator povećavamo i smanjujemo faktor ispune
if (RA0_bit) { // Button on RA0 pressed
Delay_ms(40);
current_duty++; // Increment current_duty
PWM1_Set_Duty(current_duty);
}
if (RA1_bit) { // Button on RA1 pressed
Delay_ms(40);
current_duty--; // Decrement current_duty
PWM1_Set_Duty(current_duty);
}
if (RA2_bit) { // Button on RA2 pressed
Delay_ms(40);
current_duty1++; // Increment current_duty1
PWM2_Set_Duty(current_duty1);
}
if (RA3_bit) { // Button on RA3 pressed
Delay_ms(40);
current_duty1--; // Decrement current_duty1
PWM2_Set_Duty(current_duty1);
}
Delay_ms(5); // Ovde malo usporimo izvršavanje toka petlje, mada je nebitno....
}
}
E pa slično radi i ovaj primer tvog profe uz neke nebitne stvari tipa ona besmislena pauza na početku. Sad pravo kažem, mislim da ovde ni port B ne mora posebno da se podešava, jer je i on nebitan, a verovatno čak ni port C. Samo analogni ulazi i komparatori i port A na koji su nakačeni dugmići... Ja bih ovde izmenio neke sitnice:
Prvo, port a bih vezao na +5V preko pull-up otpornika a dugmiće RA0 do RA3 na masu. Tako bi u stvari imao obrnutu situaciju, da ti pritisnuto dugme zapravo obara nivo ulaza porta na 0, što je generalno bolja praksa. Kod bi bio neznatno izmenjen, samo bi se pitao da li je RAx_bit == 0. ali to zavsi od konkretnih veza na ploči i onoga što hoćeš da uradiš...