Stránka 1 z 1

PWM

Napsal: 16 pro 2009, 18:36
od mirecc
Mam jeden problem robil som program na PWM na C/C2 pre atmega8, len mi to pwm nejde, neviete mi poradit???
Tu je program>
#include <C:\WinAVR-20090313\avr\include\avr\io.h>


#define increaseButton_PRESSED !(PIND & 0x40)
#define increaseButton_OPEN (PIND & 0x40)
#define decreaseButton_PRESSED !(PIND & 0x80)
#define decreaseButton_OPEN (PIND & 0x80)


#define COUNTER_MIN 0x0090
#define COUNTER_MAX 0x00f8
#define KROK 0x0008

void port_init(void)
{
PORTB = 0x00;
DDRB = 0x08;
PORTC = 0x00;
DDRC = 0x00;
PORTD = 0xC0;
DDRD = 0x00;
}


void timer2_init(void)
{
TCCR2 = 0x61; //setup
OCR2 = COUNTER_MIN;

}

void init_devices(void)
{
//stop errant interrupts until set up
//CLI(); //disable all interrupts
port_init();
timer2_init();

//MCUCR = 0x00;
//GICR = 0x00;
//TIMSK = 0x00; //timer interrupt sources
//SEI(); //re-enable interrupts
//all peripherals are now initialized
}


//***** DELAY OF 1 mSEC (appx.) *******

void delay_ms(int miliSec) //for 1 Mhz crystal
{
int i,j;

for(i=0;i<miliSec;i++)
for(j=0;j<100;j++)
{
asm("nop");
asm("nop");
}
}

//************************ main ***************************

void main(void)
{
unsigned int counter = COUNTER_MIN;

init_devices();

while(1)
{

}

if(increaseButton_PRESSED)
{
delay_ms(20);
if(increaseButton_OPEN)
while(increaseButton_PRESSED);
delay_ms(20);

if(counter >= COUNTER_MAX)
counter = COUNTER_MAX;
else
counter += KROK;
OCR2 = counter;

}
else
{
delay_ms(20);

if(decreaseButton_OPEN) ;
while(decreaseButton_PRESSED);
delay_ms(20);

if(counter <= COUNTER_MIN)
counter = COUNTER_MIN;
else
counter -= KROK;
OCR2 = counter;

}

}

//****************************** END ***************

Napsal: 16 pro 2009, 20:01
od Andrea
No jestli jsi to psal opravdu ty, tak umíš docela dobře anglicky.
Jak zjišťuješ, jestli ta PWM funguje nebo ne?

Napsal: 16 pro 2009, 20:49
od mirecc
Andrea píše:No jestli jsi to psal opravdu ty, tak umíš docela dobře anglicky.
Jak zjišťuješ, jestli ta PWM funguje nebo ne?

osciloskop

Napsal: 16 pro 2009, 21:06
od Andrea
A jak ten překladač pozná, co máš za procesor? Tam, co jsi ten program opajcoval, mají na začátku #include <iom8v.h>, tak jestli by tam nemělo být něco podobnýho pro AVR GCC.

Napsal: 16 pro 2009, 21:40
od GeorgeB
Andrea píše:Tam, co jsi ten program opajcoval, mají ...

Přesně: http://images.robolabz.multiply.multipl ... =279223533 :D

Napsal: 16 pro 2009, 22:47
od mtajovsky
- máte ten program nějaký "vykuchaný". Zastaví se to na while(1){} a nic se dál nebude dít. V originále je tam "cosi" navíc. :D

- vidím špatně udělanou funkci pro zpožďování. Převážná část kódu bude v těch cyklech for a ne v nop. Takže výsledek silně závisí na tom, jakou optimalizaci překladač provede. Pro zpožďování jsou určené funkce z avr-libc _delay_ms() a _delay_us().

Napsal: 17 pro 2009, 08:06
od Andrea
On tam těch chyb vyrobil víc, ale na funkci PWM by neměli mít vliv.

Napsal: 17 pro 2009, 10:29
od Atlan
Toje tak aj opajcovat treba vediet :D sadnut studovat...

Napsal: 17 pro 2009, 10:49
od Zmije
Pokud to překládaš ve WinAVR pomocí GCC, tak naprosto špatně pracuješ s vektory přerušení, na začátek musíš dát kromě #include <avr/io.h> ještě #include <avr/interrupt.h> a obsluhu přerušení potom dát do ISR( TIMER2_COMP_vect ){ //nejaky kod }pokud chceš obsloužit přerušení od c/t2 při shodě, ostatní vektory viz. tabulka.
PS: nezapomeň povolit globální přerušení sei() ;

Napsal: 17 pro 2009, 11:01
od Zmije
Dodávám, že tabulka platí pro ATmega16, pro ostatní procesory se potřebné informace nachází v datasheetech.