Sunteți pe pagina 1din 7

L7: UTILIZARE TIMER ȘI SEMNALE PWM

OBIECTIV

În acest laborator, se va proiecta un player audio folosind numărătorul (timer), semnale PWM și întreruperi.
Playerul audio va reda o simplă piesă muzicală folosind difuzorul și va reprezenta de asemenea, melodia muzicii cu
ajutorul LED-urilor. Două potențiometre sunt utilizate pentru reglarea vitezei muzicii și, respectiv, a volumului.

Analog In 0 Digital Out Analog In 1 Vcc

Potențiometre 1 și 2 Speaker
DETALII DE IMPLEMENTARE

HARDWARE

FREEDOM KL25Z

Descrierile pinilor de la bord Freedom KL25Z sunt prezentate mai jos:

Modulul Timer

Indiferent de capacitate sa, modulul TIMER poate funcționa în două moduri: ca numărător (counter) sau ca
temporizator (timer). Un timer monitorizează semnale care au o distribuție în timp constantă și uniformă (semnale
de tact). Un counter monitorizează semnale care au o distribuție aleatoare în timp (semnale de la dispozitive
externe).

Un timer poate fi utilizat pentru:


• Controlarea de evenimente
• Producerea de întârzieri foarte precise
• Generarea de semnale cu formă specifică
• Contorizarea de evenimente/semnale din exterior
• Multi-tasking: prioritizarea evenimentelor
Semnale PWM

Pulse Width Modulation (PWM) este un termen utilizat pentru descrierea unui tip de semnal digital. Modularea
lățimii pulsului este utilizată într-o varietate de aplicații, inclusiv circuite de control sofisticate. Un exemplu de
utilizare constă în controlul intensității luminoase a LED-uri RGB sau pentru a controla direcția unui servomotor.
Modularea lățimii pulsului permite variația cât timpului în care semnalul este activ într-un mod analog. În timp ce
semnalul poate fi doar high (de obicei 5V) sau low (0V) în orice moment, se poate schimba proporția de timp în
care semnalul este High.

Un semnal periodic este definit de frecvență (f) și perioadă (T): x(t) = x(t+T).

Frecvența reprezintă numărul de apariții ale unui eveniment în cadrul unei unități de timp (Hertz sau cicluri/sec).
Perioada este inversul frecvenței f = 1/T.

Un alt concept important este reprezentat de factorul de umplere – duty-cycle (procentele dintr-o perioadă când
semnal este activ).

FUNCȚII SOFTWARE

În tabelul următor sunt prezentate funcții care pot fi utilizate în implementare:

Numele funcției Descriere


Funcții pentru Timer
void start () Pornire numărător
void stop () Oprire numărător
void reset () Resetare numărător la valoarea 0
float read () Preluarea timpului în secunde
int read_ms () Preluarea timpului în milisecunde
int read_us () Preluarea timpului în microsecunde
Funcții Time Ticker
Atașare funcție care trebuie apelată de Ticker , specificând
void attach (void(*fptr)(void), float t)
intervalul în secunde
void attach (T *tptr, void(T::*mptr)(void), Atașare funcție membru care trebuie apelată de Ticker ,
float t) specificând intervalul în secunde
void attach_us (void(*fptr)(void), unsigned Atașare funcție care trebuie apelată de Ticker , specificând
int t) intervalul în microsecunde
void attach_us (T *tptr, void(T::*mptr)(void), Atașare funcție membru care trebuie apelată de Ticker ,
unsigned int t) specificând intervalul în microsecunde
void detach () Detașare funcției.
Rutina de tratare înregistrată cu timerul care realizează
static void irq (uint32_t id)
întreruperea.
PWM output functions

PwmOut (PinName pin) Creare conexiune PwmOut cu un pin specificat.

Void write (float value) Setare duty-cycle, specificat ca procent (float)


Returnare setarea curentă a duty-cycle, măsurată ca procent
float read ()
(float)
Setare perioadă PWM, specificată în secunde (float), menținând
void period (float seconds)
duty-cycle la valoarea setată.
Setare perioadă PWM, specificată în milisecunde (int), menținând
void period_ms (int ms)
duty-cycle la valoarea setată.
Setare perioadă PWM, specificată în microsecunde (int),
void period_us (int us)
menținând duty-cycle la valoarea setată.
Setare lățime a pulsului PWM, specificată în secunde (float),
void pulsewidth (float seconds)
menținând perioada aceeași.
Setare lățime a pulsului PWM, specificată în milisecunde (int),
void pulsewidth_ms (int ms)
menținând perioada aceeași.
Setare lățime a pulsului PWM, specificată în microsecunde (int),
void pulsewidth_us (int us)
menținând perioada aceeași.
PwmOut & operator= (float value) O reprezentare simplificată pentru funcția write()
PwmOut & operator float () O reprezentare simplificată pentru funcția read()

DEFINIREA NOTELOR MUZICALE

Pentru a reda muzică, este necesar să se definească o listă de note care pot fi utilizate pentru redare, inclusiv
notele muzicale (frecvența sunetului, de exemplu, do, re, mi, fa, sol, la, si) și lungimea pauzelor (beat-ului). Pentru
a face acest lucru, trebuie să se ajustaze perioada PWM, astfel încât să poată produce o frecvență corectă pentru
fiecare notă muzicală și perioada de beat pentru a produce ritmul dorit. După definirea notei muzicale și a lungimii
pentru pauze, se poate utiliza o melodie cunoscută, de exemplu Jingle Bells.
CODUL APLICAȚIEI

• Definire note de bază:

# define Do 0.5
# define Re 0.45
# define Mi 0.4
# define Fa 0.36

# define No 0

• Definire lungime pauză:

# define b1 0.5 //nota intreaga


# define b2 0.25 //doime

• Realizare melodie

float note []={ Mi, No, Mi …


float beat [] ={ b3, b3, b3 …

• Definie intrări analogice (2 potențiometre) și ieșiri PWM (speaker și LED-uri)

• Definire time ticker

• Scriere ISR pentru time ticker ISR, care va fi apelată periodic, după fiecare notă muzicală.

o Actualizare frecvență PWM pentru următoarea notă

o Actualizare lungime pauză pentru următoarea notă muzicală (reconfigurare timp de întrerupere)

o Actualizare luminozitate LED-uri pentru a reflecta schimbarea melodiei.

o Intrările celor două potențiometre vor fi utilizate pentru reglarea volumului și a vitezei.

• În programul principal

o Inițializarea time ticker

o Funcție Sleep pentru așteptare întrerupe


Codul programului:

#include "mbed.h"

//Definire frequencta notelor de baza


# define Do 0.5
# define Re 0.45
# define Mi 0.4
# define Fa 0.36
# define So 0.33
# define La 0.31
# define Si 0.3
# define No 0

//Definere lungime pauza beat length (nota intreaga,doime, patrime si optime)


# define b1 0.5
# define b2 0.25
# define b3 0.125
# define b4 0.075

//Definire piesa muzicala


float note[] = { Mi,No,Mi,No,Mi,No, Mi,No,Mi,No,Mi,No, Mi,No,So,No,Do,No,Re,No,Mi,No,
Fa,No,Fa,No,Fa,No,Fa,No, Fa,No,Mi,No,Mi,No,Mi,No,Mi,No, Mi,Re,No,Re,Mi, Re,No,So,No };
float beat[] = { b3,b3,b3,b3,b2,b2, b3,b3,b3,b3,b2,b2, b3,b3,b3,b3,b3,b3,b3,b3,b2,b1,
b3,b3,b3,b3,b3,b3,b3,b3, b3,b3,b3,b3,b3,b3,b4,b4,b4,b4, b2,b3,b3,b2,b2, b2,b2,b2,b2 };

//Definire intrari analogice


AnalogIn pot1(A0);
AnalogIn pot2(A1);

//Definire iesire PWM petnru speaker


PwmOut Speaker(PTC8);

//Definire iesiri PWM pentru LED-uri RGB


PwmOut RedLed(PTB18);
PwmOut GreenLed(PTB19);
PwmOut BlueLed(PTD1);

//Definire time ticker


Ticker timer;

//Static variable
static int k;

/*----------------------------------------------------------------------------
Interrupt Service Routine
*----------------------------------------------------------------------------*/

//Definire ISR pentru ticker


void timer_ISR() {
if (k < (sizeof(note) / sizeof(int))) {
if (note[k] == No) //daca este o pauza
Speaker = 0; //Setare duty cycle la zero
else {
Speaker.period(0.005 * note[k]);
//Setare perioada PWM, care determina nota
Speaker = 0.01 * pot2.read();
//Setare duty cycle pentru a determina volumul melodiei
}
k++;

//Setare timp pentru urmatoare intrerupere , determinat de pauza curenta


si de potentiometre
timer.attach(&timer_ISR, ((beat[k] / 2) + (pot1.read() / 2)));

//actualizare LED-uri RGB


RedLed = note[k];
GreenLed = (1 - note[k]);
BlueLed = beat[k];
}
else {
k = 0; //daca s-a terminat melodia, porneste de la început
Speaker = 0;
}
}

/*----------------------------------------------------------------------------
MAIN
*----------------------------------------------------------------------------*/

int main() {
timer.attach(&timer_ISR, 1); //Initializare time ticker

while (1)
__WFI(); //sleep-on-exit
}

Teme:

1. Modificați aplicația pentru a putea reda o altă melodie.


2. De ce nu s-a putut utiliza în acest caz un alt tip de semnal pentru controlul speaker-ului și a LED-urilor?
3. Cum este codificat factorul de umplere în cadrul programului?

S-ar putea să vă placă și