generátor ATmega328,

Diskuze a poradna o programátorech a programování různých obvodů

Moderátor: Moderátoři

Odpovědět
Zpráva
Autor
Uživatelský avatar
ok1ift
Příspěvky: 3
Registrován: 06 črc 2016, 02:00

generátor ATmega328,

#1 Příspěvek od ok1ift »

Dobrý den, měl bych otázku na někoho z Vás, a sice, jde li generovat s AT328 průběh viz příloha? Nastavení frekvence by mělo být cca od 5 do 50kHz.
Snažil jsem se řešit s Timerem1 a COMPA_vect následovně:

int main(void)
{

DDRB |=(0x04) | (0x02);
TIMSK1 |= (1 << OCIE1A) | (1 << OCIE1B); //ISR(TIMER1_COMPA_vect)
TIFR1 |= (OCF1A) | (OCF1B);
TCCR1A = 0;
TCCR1C = 0;
setFrequency(25000);
on();
a=1;
sei();
while(1)
{

}
return 0;
}


ISR(TIMER1_COMPA_vect)
{
if(a)
{
OCR1A = top - 50; // sestupná
a = 0;
}else
{
OCR1A = top + 50; // vzestupná
a = 1;
}
}

void setFrequency(uint16_t freq)
{
uint32_t requiredDivisor = (F_CPU/2)/freq;
uint16_t prescalerVal;
uint8_t prescalerBits;

if (requiredDivisor < 65536UL)
{
prescalerVal = 1;
prescalerBits = 1;
}

else if (requiredDivisor < 8 * 65536UL)
{
prescalerVal = 8;
prescalerBits = 2;
}
else if (requiredDivisor < 64 * 65536UL)
{
prescalerVal = 64;
prescalerBits = 3;
}
else if (requiredDivisor < 256 * 65536UL)
{
prescalerVal = 256;
prescalerBits = 4;
}
else
{
prescalerVal = 1024;
prescalerBits = 5;
}

top = ((requiredDivisor + (prescalerVal/2))/prescalerVal) - 1;
//TCCR1A = 0;
TCCR1B = (1 << WGM12)| prescalerBits ;
//TCCR1C = 0;
OCR1A = top;//(top & 0xFF);

}
void on()
{
TCNT1H = 0;
TCNT1L = 0;
TCCR1A |= (1 << COM1A0);

}

// Turn the frequency off and turn of the IR LED
void off()
{
TCCR1A &= ~(1 << COM1A0);
}
//******************************************

jak ale zakomponovat fázově posunutý druhý výstup, to nevím. Frekvence je samozřejmě obojí shodná.

Uživatelský avatar
Jirka525
Příspěvky: 325
Registrován: 22 kvě 2013, 02:00
Bydliště: Psáry JN79GW

#2 Příspěvek od Jirka525 »

Pokud jsem dobře pochopil ty průběhy, tak jsou stejné, pouze časově posunuté. Takže pokud jsi vygeneroval průběh "a", tak průběh b = a+zpoždění. Pro tuto úlohu bych si napsal funkci ton(bool signal, uint32_t zpozdeni) - zpožděděné zapnutí. Pak by průběh "b" mohl vypadat přibližně takto.

sig_b(bool sig_a, uint32_t zpozdeni)
{
static bool pom_a, pom_a1 = 1, pom_b;
if(a & !pom_a)
{
pom_a = a; //vzestupna hrana
}
if(!a & pom_a1)
{
pom_a = a; //sestupna hrana
}
if(ton(pom_a, zpozdeni)
{
pom_b = 1;
pom_a = 0;
pom_a1 = 1;
}
if(ton(!pom_a1, zpozdeni)
{
pom_b = 0;
pom_a = 0;
pom_a1 = 1;
}
return(pom_b);
}
Naposledy upravil(a) Jirka525 dne 08 črc 2016, 08:29, celkem upraveno 1 x.
Jirka

Uživatelský avatar
Bernard
Příspěvky: 3614
Registrován: 27 kvě 2005, 02:00

#3 Příspěvek od Bernard »

Taky by se mohly časovačem generovat intervaly 1/6f, a protáčet proměnnou stavu automatu
++sa; sa=sa % 6;

a potom:
switch sa {
case 0: a=1;
case 1:;
case 2:a=0;
case 3:b=1;
case 4:;
case 5:b=0;
}

Uživatelský avatar
Ondra2
Příspěvky: 530
Registrován: 19 bře 2014, 01:00

#4 Příspěvek od Ondra2 »

Tady: http://www.kerrywong.com/2010/12/26/mod ... -with-avr/
jenom otocis smysl jednoho compare bloku, viz datasheet.

Uživatelský avatar
ok1ift
Příspěvky: 3
Registrován: 06 črc 2016, 02:00

#5 Příspěvek od ok1ift »

Ahoj a díky všem, v pondělí se k tomu dostanu a vyzkouším to. Martin.

Uživatelský avatar
ok1ift
Příspěvky: 3
Registrován: 06 črc 2016, 02:00

#6 Příspěvek od ok1ift »

Ondro2, díky za nakopnutí, chodí to excelentně. Je to přesně to co jsem potřeboval.

Odpovědět

Zpět na „Programování PIC, ATMEL, EEPROM a dalších obvodů“