Sari la conținut
ELFORUM - Forumul electronistilor

Fast PWM cu timer de 16bit -un sfat va rog


spinach

Postări Recomandate

Deci , parerea vostra privind oprirea timerului : opresc prin utilizare PSRSYNC sau scriu permanent TCNT1=0  ?

Părerea mea e să le testezi pe amîndouă şi să vezi care merge mai rapid, deşi ar fi un miracol să obţii 2us la 20MHz.

Link spre comentariu
  • Răspunsuri 36
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • nico_2010

    14

  • spinach

    13

  • ratza

    7

  • one

    3

Top autori în acest subiect

Iar parerea mea este sa folosesti un 74HC123 (durata minima a impulsului este de 20ns la 4.5V), impreuna cu 1-2 cd4051 (folosite pentru comutarea elementelor ce contribuie la generarea impulsului), iar selectia se face cu microcontroller (daca vrei ceva digital).

Solutia digitala este FPGA sau CPLD, insa nu este chiar la indemana tuturor.

Link spre comentariu

 De testat am sa testez , oricum . Scopul mcu este de a genera impulsurile necesare . Evident ca pentru restul ,folosesc ceva din seria cd. Am fost silit , deoarece nu exista comutatoere mecanice cu 4 sectiuni .

Cind am proiectat placa , m-am gindit si la acesta varianta , adica ca s-ar putea ca sa o dau in bara cu utilizarea de mcu.

 

Dar sa revenim .; cu opritul am lamurit-o : trebuie sa testez 

 

Cum sa numar ciclurile ? nu vreu sa folosec interuperi.

-o varianta 1 ar fi sa folosec flagul OCF1A  , fara a activa intreruperea; am mai incercat o data sa il folosesc , dar nu mi-a iesit ; in ds , scrie , cam asa :

"This flag is set in the timer clock cycle after the counter (TCNT1) value matches the Output
Compare Register A (OCR1A). "
si 
"OCF1A is automatically cleared when the Output Compare Match A Interrupt Vector is executed.
Alternatively, OCF1A can be cleared by writing a logic one to its bit location."
Adica daca nu activez intreruperea , trebuie sa il sterg eu .
Eu nu pricep : daca la compare flagul este setat , adca este facut 1 , ca sa il sterg eu scriu tot 1 ?
 

-varianta 2 -sa numar cind contorul devine zero ? sau alta valoare , ca sa fie timp .

 

-varianta 3-sa numar cind esirea OC1A se face 1 ?

 

Care varianta ar fi mai buna ?

Editat de hspinache
Link spre comentariu

Cum sa numar ciclurile ? nu vreu sa folosec interuperi.

Să înţeleg că vrei să faci ceva de gen pulse burst? Dacă da, poţi folosi două timere, al doilea fiind un multiplu exact de cicli al primului. Le porneşti pe ambele şi foloseşti întreruperea pe al doilea. În momentul în care ajungi în întrerupere opreşti sau resetezi ambele timere.

Link spre comentariu

@ratza: mi se pare ca vrea sa faca o baza de timp (probabil pentru un osciloscop !?), a carei declansare sa se produca odata cu aplicarea semnalului pe un port de intrerupere externa. Cel putin eu asta tind sa inteleg din putinul pus la dispozitie de user (interval, sincronizare)

Link spre comentariu

Cred ca tinta globala a aplicatiei nu este semnificativa .

Materialul cu timerul l-am citit . Este foarte bun , dar in cazul meu nu prea ma ajuta.

 

"Dacă-ţi faci probleme de 2 cicli pentru resetat un timer, ţine cont că saltul în întrerupere ia vreo 12"  

Precis se sterge tot in 2 cicluri ?

Editat de hspinache
Link spre comentariu

Cred ca tinta globala a aplicatiei nu este semnificativa .

Materialul cu timerul l-am citit . Este foarte bun , dar in cazul meu nu prea ma ajuta.

In acest caz singura solutie este sa te pui pe studiu intens si sa experimentezi si mai intens, conform principiului "try end error".

Si revii doar cu exemple de cod pe care le-ai incercat si nu au functionat asa cum te-ai fi asteptat.

Nici unul dintre noi nu este Mafalda sau Mama Omida sa ghiceasca ce vrei sa construiesti, iar detaliile furnizate pana acum sunt nesemnificative (ca sa nu spun ca sunt in limita de epsilon).

 

L.E.: Da, Timer1 se sterge in doua impulsuri de ceas (sunt doi registri de 8 biti si stergerea fiecaruia dintre ei se face pe perioada unui impuls de ceas)

Link spre comentariu

Si o solutie simpla ca raspuns la una din intrebarile userului hspinache de la postarea nr.18:

//Test pentru utilizarea bitului OCF1A pentru Timer1 setat //pentru a functiona in regim "compare match"//Frecventa oscialtorului: 20MHz//Perioada minima a semnalului la iesire PD4 este de aprox 850ns#include <avr/io.h>int main(void){	DDRD = 0b01111111;		PORTD = 0b00000000;	DDRC = 0b01111111;	PORTC = 0b00000000;		TCCR1B |= 1<<CS10 | 1<<WGM12;// fara prescaler, CTC mode	TIFR1 |= OCF1A;	OCR1A = 1;//cresterea valorii se traduce prin marirea perioadei semnalului de iesire	    while(1)    {		 		 if (TIFR1 &(1<<OCF1A))		   {		   TIFR1 |= (1<<OCF1A); // deoarece nu utilizam intreruperea		                         // trebuie sa resetam bitul OCF1A astfel incat sa permita ca 							  // TIMER1 sa porneasca de a 0		   		   PORTD ^= (1<<4); 		           		  }		   }    	}
Link spre comentariu

"TIFR1 |= OCF1A;"   este ceva lipsa ?

 

da , se pare ca nu am citit bine ;

"• Bit 1 – OCF1A: Timer/Counter1, output compare A match flag

This flag is set in the timer clock cycle after the counter (TCNT1) value matches the Output
Compare Register A (OCR1A)."
 
Pe mintea mea set= trecere in valoare 1 ; se pare ca este pe invers  , adica la "setare" trece in atare zero .
gindesc corect ?
Link spre comentariu

Incercarea de a face primul test , a esuat , din cauza unei probleme de sintaxa . Pun aici ca sa nu mai deschid ceva in plus ;

 

sint in mcu 24 de variante ; un fel de comutator  :

Daca o varianta este scrisa  asa:

 if ((sw !=7)&(!(chkBIT(PINC,0)))&((chkBIT(PINC,1)))&((chkBIT(PINC,2)))&((chkBIT(PINC,3)))&(!(chkBIT(PIND,0))))
     {
....
    }
se compileaza dar nu functioneaza .; ca nu stiu de ce 
 
Daca il scriu asa :
if (sw !=8)
{
  if (PINC & ((1<<PC3)|(1<<PC2)|(1<<PC1)))
     {
        if (!(PINC & (1<<PC0)))
         {
           if ((PIND & (1<<PD0)))
            {
 ......
  }
  }
       }
      }

se compileaza , functioneaza , dar maninca multa memorie !

 

Este vreo metoda mai buna ? 

Editat de hspinache
Link spre comentariu

Foloseste butonul de insertie a codului (adica asta<>).

in alta ordine de idei, in loc de:

if ((sw !=7)&(!(chkBIT(PINC,0)))&((chkBIT(PINC,1)))&((chkBIT(PINC,2)))&((chkBIT(PINC,3)))&(!(chkBIT(PIND,0))))

scrie:

if ((sw !=7)&&(!(chkBIT(PINC,0)))&&((chkBIT(PINC,1)))&&((chkBIT(PINC,2)))&&((chkBIT(PINC,3)))&&(!(chkBIT(PIND,0))))

Este o eroare uzuala cea pe care a facut-o tu.

Link spre comentariu
Vizitator
Acest subiect este acum închis pentru alte răspunsuri.



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări