Generovani Frekvence

Zdravim snazim se generovat frekvenci pro piezo sirenku. Frekvence by mela byt 4kHz. Generovani provadim pomoci fce:

[code]void sirena (void)
{
unsigned int i;
unsigned int j;
//sirena pripojena na PF5

for(i=0;i<2000;i=++)
PORTF=0b00100000;
for(j=0;j<2000;j=++)
PORTF=0b00000000;
}[/code]

Ale sirenka nechce vidat ani hlasku poradi mi nekdo?

jakej pouzivas Xtal? predpokladam ze to delas pres atMegu128 podle vystupu takze hadam 16MHZ

Staci napsat

[code]void sirena (void)
{
unsigned int i;
unsigned int j;
//sirena pripojena na PF5

for(i=0;i<2000;i++)
PORTF=0b00100000;
for(j=0;j<2000;j++)
PORTF=0b00000000;
}[/code]

Jasne to byla moje chybka dik za radu.
jen mi to stale nechce generovat zadnej zvuk. Sirenka je pripojena k portu pres kondik a proti zemi takze by melo stait port nastavit do log1 na urcitou dobu.
Prve na tu f=4kHz

to prave meli resit ty for cykly ale nejak nejsem schopem urcit jak dlouho trva jeden for yklus pri Xtalu 16MHz a procesoru ATmega128

dik za radu

Prehlednejsi zapis je
PORTF |= 1<<PF5;
PORTF &= ~(1<<PF5);
a neovlivnuje to ostatni piny :wink:

Mas nastavenej port jako vystup?
DDRF |= (1<<PF5);

Zkus pred “unsigned int i;” a “unsigned int j;” dat jeste “volatile”, zamezi to odstraneni cyklu diky optimalizacim.

Abys zjistil jak dlouho smycka trva, musel by ses podivat do souboru s asemblerem a spocitat to. Lepsi reseni je citac :wink: Pokud neumis preruseni, muzes klidne ve smycce testovat priznak preteceni…

no ja to chtel delat puvodne pres delay(x) ale za x potrebuju dat 0,125 a to ten delay nebere bohuzel

jeden for cyklus by mel trvat 6 instrukci. Tzn,: pri krystalu 16MHz jedna instrukce trva 63,3ns takze jeden for cyklus trva 379,8ns tj. 0,0003798ms.
Takze pozadovanou dobu dostanes pokud for(i=0;i<329;i++)
alespon me to tak vyslo. Ale stejne netusim zda ti to bude neco delat. Ja zapojil sirenku podle prilozeneho obrazku ale nic to nedelalo
zapojeni sirenky.png

myslel jsi to nejak takto?

[code]
SEI
CATEK_PROGRAMU:
// tady neco muzeme delat
JMP ZACATEK_PROGRAMU ; skoci na zacatek (stale dokola)

.ORG OC0addr
RJMP PRERUSENI

// ****************** OBSLUHY PRERUSENI *********************** //
PRERUSENI:
INC INT_CNT ; inkrementuje R2
LDI TEMP,125
CP R2,TEMP ; je-li R2 mensi
BRLO PRYC_LABEL ; nez TEMP jde pryc
CLR INT_CNT

     SBIC    BLIK_PORT_DATA,BLIK_PIN  
     RJMP    CLEAR_PIN_LABEL  
     SBI     BLIK_PORT_DATA,BLIK_PIN  
            RJMP    PRYC_LABEL  

CLEAR_PIN_LABEL:
CBI BLIK_PORT_DATA,BLIK_PIN

PRYC_LABEL:
NOP
RETI [/code]

To si presiel pre istotu z C na ASM?

:stuck_out_tongue:

Len sa kludne vrat k C. Tam to bude OK.
Akurat:

  1. robit presne casove oneskorenie sluckam v C (ale v principe i v ASM :slight_smile:) je zhovadilost. Procesor ma vykonavat uzitocnu cinnost a nie stale codit dokola medzi styrmi instukciami ako taky blbec. Od prekladaca sa aj ocakava, ze vygeneruje co najmensi kod a o to sa aj on snazi. Ak usudi, ze nieco sa v podstate aj tak neprejavi v behu progrmu, tak to jednoducho vyhodi, alebo nejak inak zoptimalizuje. Volatile je riesenie, ale pre tento pripad velmi kostrbate.

  2. sice v tvojom ASM povolujes globalne prerusenie, ale nenasiel som povolenie prerusenia od casovaca, tak ze kod pre prerusenie sa nikdy nevykona.

  3. nenasiel som spravne nastavenie parametrov casovaca.

Skus sa pozriet na uvedene body, snad ti to pomoze posunut sa vpred.

Delka cyklu (kterej nic nedela a neni “odoptimalizovan” :slight_smile:) taky zavisi na pouzity pocitaci promenny… jiny to bude u unsigned char a jiny u int :wink: Je potreba si to zmerit v simulatoru…

Jiny reseni pipaku je v priloze…
main.c (1.24 KB)