logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATMega32][C] Programowy PWM 8ch

Vampir8 04 Lis 2009 15:05 2114 6
REKLAMA
  • #1 7214668
    Vampir8
    Poziom 16  
    Witam.

    Od 3 dni siedzę już nad programowym PWM. Wykorzystuję do tego przerwanie na timerze, ale coś nie działa tak jak powinno otóż jak nie mam ustawionego stanu 1 na ostatnim bicie portu to PWM dziwnie się zachowuje.

    
    //Includes
    #include "avr/io.h"
    #include "inttypes.h"
    #include "stdio.h"
    #include "util/delay.h"
    #include "avr/interrupt.h"
    #include "usart.h"
    #include "avr/wdt.h"
    
    //Defines
    #define F_CPU 8000000			
    #define LED_PORT	PORTA
    #define LED_DDR		DDRA
    
    //Functions
    void Init_Ports();	//Initialize IO Pins
    void Init_Timer2(); //Initialize Timer
    
    //Variables
    volatile unsigned char val[8];
    int volatile count=1;
    
    int main(){
    	Init_Ports();
    	USART_Init(1);	
            Init_Timer2();
    	wdt_disable();
    	sei();
    	for(;;){
    	//loop
    }
    	return 0;
    }
    
    void Init_Ports(){	
    	LED_DDR = 255; 					//Output
    }
    
    void Init_Timer2(){	
           count=1;
    	   // Reset timer
    	   //ASSR |= _BV(AS2);  
    	   TCNT2 = 0;
    	   // Prescaler 1
    	   TCCR2 |= 0x01;
    	   // Overflow interrupt
    	   TIMSK |= (1<<TOIE2);
    }
    
    ISR(TIMER2_OVF_vect){
            if (count > val[0]) {LED_PORT &=~(1<<0);} else {LED_PORT |=  (1<<0);}
    	if (count > val[1]) {LED_PORT &=~(1<<1);} else {LED_PORT |=  (1<<1);}
    	if (count > val[2]) {LED_PORT &=~(1<<2);} else {LED_PORT |=  (1<<2);}
    	if (count > val[3]) {LED_PORT &=~(1<<3);} else {LED_PORT |=  (1<<3);}
    	if (count > val[4]) {LED_PORT &=~(1<<4);} else {LED_PORT |=  (1<<4);}
    	if (count > val[5]) {LED_PORT &=~(1<<5);} else {LED_PORT |=  (1<<5);}
    	if (count > val[6]) {LED_PORT &=~(1<<6);} else {LED_PORT |=  (1<<6);}
         // if (count > val[7]) {LED_PORT &=~(1<<7);} else {LED_PORT |=  (1<<7);}// z tym tez dziwnie sie zachowuje
            LED_PORT |=(1<<7); //jeżeli to skasuje to PWM dziwnie się zachowuje
    	if (count==64) {count = 1;} else {count++;}
    }


    Odczyt wartości val następuje w przerwaniu USARTa. Co mogę robić nie tak? dlaczego tak się dzieje?

    Proszę o pomoc.
    Pozdrawiam,
    Vampir8
  • REKLAMA
  • #2 7214769
    mirekk36
    Poziom 42  
    no wszystko fajnie ale możesz napisać dokładniej co to znaczy u ciebie, że "się dziwnie zachowuje" ??? bo może problem wcale nie leży w obsłudze przerwania Timera2 - ona wydaje się być poprawna
  • REKLAMA
  • #3 7214801
    Vampir8
    Poziom 16  
    Chodzi o to ze jak obsługuje 7 ledów to wszystko jest ok, na każdej mogę ustawić sobie jasność, a jeżeli włączę obsługę 8 diody to wszystkie zaczynają migać zależnie od podanych wartości (powiedzmy tak ze co 400-500ms następuje zaświecenie i odpowiednio zgaśniecie)

    No i to samo się dzieje jezeli nie wpisze tego
    LED_PORT |=(1<<7);
    w przerwaniu timera albo
    if (count > 64) {LED_PORT &=~(1<<7);} else {LED_PORT |=  (1<<7);}
  • REKLAMA
  • REKLAMA
  • #5 7214962
    Vampir8
    Poziom 16  
    Jeżeli dobrze zrozumiałem to ma to wyglądać tak:
    ISR(TIMER2_OVF_vect){
        //LED_PORT |=(1<<7);
        //if (count > val[0]) {LED_PORT &=~(1<<0);} else {LED_PORT |=  (1<<0);}
    	//if (count > val[1]) {LED_PORT &=~(1<<1);} else {LED_PORT |=  (1<<1);}
    	//if (count > val[2]) {LED_PORT &=~(1<<2);} else {LED_PORT |=  (1<<2);}
    	//if (count > val[3]) {LED_PORT &=~(1<<3);} else {LED_PORT |=  (1<<3);}
    	if (count > val[4]) {LED_PORT &=~(1<<4);} else {LED_PORT |=  (1<<4);}
    	if (count > val[5]) {LED_PORT &=~(1<<5);} else {LED_PORT |=  (1<<5);}
    	if (count > val[6]) {LED_PORT &=~(1<<6);} else {LED_PORT |=  (1<<6);}
        if (count > val[7]) {LED_PORT &=~(1<<7);} else {LED_PORT |=  (1<<7);}
    	if (count==64) {count = 1;} else {count++;}
    }


    i niestety objawy są takie same, próbowałem również dawać po tylko jednym PWM i jak nie ustawie tego
    LED_PORT |=(1<<7);
    to na każdym jest to samo

    coś takiego gdzie tylko zmieniam val i bity portu
    ISR(TIMER2_OVF_vect){
            if (count > val[0]) {LED_PORT &=~(1<<0);} else {LED_PORT |=  (1<<0);}
            LED_PORT |=(1<<7); //jeżeli to skasuje to PWM dziwnie się zachowuje
       if (count==64) {count = 1;} else {count++;}
    }
  • #6 7223616
    Vampir8
    Poziom 16  
    Nikt nie wie?

    To ja powiem że kod jest poprawny, a uC ma uszkodzony port.
    Gdy nie ma obciążenia na LED_PORT.7 timer wariuje, przypisałem inny port i działa elegancko.

    Pozdrawiam
  • #7 7223754
    mirekk36
    Poziom 42  
    Vampir8 napisał:
    Nikt nie wie?

    To ja powiem że kod jest poprawny, a uC ma uszkodzony port.
    Gdy nie ma obciążenia na LED_PORT.7 timer wariuje, przypisałem inny port i działa elegancko.

    Pozdrawiam


    no to rzeczywiście ;) a kto mógłby wiedzieć że ty akurat masz uszkodzony procek
REKLAMA