choco_amore Napisano Kwiecień 20, 2022 Udostępnij Napisano Kwiecień 20, 2022 Cześć Wszystkim! Mam problem związany z wykorzystaniem 8 bitowego timer/counter0 w mojej płytce Arduino UNO. Programuję w czystym C z wykorzystaniem Visual Studio Code. Założeniem programu jest odczyt wartości napięcia z pinu A0, a następnie regulacja wypełnienia sygnału PWM na podstawie wartości tego napięcia. Program zrealizowałem w następujący sposób: Konfiguracja sygnału PWM na pinach PD5 i PD6(odpowiednio OC0B i OC0A). Tryb FAST PWM, preskaler 1024, ustawianie pinów w momencie zgodności licznika timera z OCR0A i OCR0B, zerowanie przy wartości maksymalnej licznika. Konfiguracja ADC. W nieskończonej pętli while przypisywanie wartości z ADC dla rejestrów OCR0A i OCR0B na podstawie czego jest ustawiane wypełnienie na wyjściach OC0A i OC0B. #include <avr/io.h> #include <util/delay.h> #include <stdint.h> //definicja funkcji przetwornika ADC i pinu wejsciowego #define ADC_PIN 0 uint16_t adc_read(uint8_t adcx); int main(void) { // ustawiamy PD5 i PD6 jako wyjścia DDRD = 0b111111; // ustawiamy tryb PWM 3 // wyjście PD5 pracuje w trybie normalnym // wyjście PD6 pracuje w trybie normalnym TCCR0A = (1<<COM0A1)|(0<<COM0A0)|(1<<COM0B1)|(0<<COM0B0)|(1<<WGM02)|(1<<WGM01)|(1<<WGM00); // Ustawiamy rejestry porównań OCR0A = 1; OCR0B = 1; //ustawienie prescalera TCCR0B = (1<<CS02)|(0<<CS01)|(1<<CS00); //uruchomienie ADC ADCSRA |= (0<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADEN); while (1) { // przypisanie wartosci rejestru OCRnX wartosci napiecia z ADC _delay_ms(10); OCR0A = adc_read(ADC_PIN)/4; OCR0B = adc_read(ADC_PIN)/4; } } uint16_t adc_read(uint8_t adcx) { //wybor pinu wejscia ADMUX = 0b01000000; ADMUX |= adcx; //uruchomienie konwersji ADCSRA |= _BV(ADSC); //petla do oczekiwania na koniec konwersji, bit ADCSRA jest zerowany na koniec konwersji while ( (ADCSRA & _BV(ADSC)) ); //zwracanie wartosci konwersji return ADC; } W przypadku pinu PD5 układ działa zgodnie oczekiwaniami. Przy zmniejszaniu napięcia na wejściu ADC LED gaśnie, przy zwiększeniu napięcia LED świeci mocniej. Problem pojawia się dla PD6. LED nie świeci. Piny mają identyczną konfiguracje, natomiast działają inaczej. W czym może być problem? Dokumentację techniczną przejrzałem 10 razy i nie mogłem znaleźć żadnej informacji co może wywoływać taki stan. Link do komentarza Share on other sites More sharing options...
etet100 Kwiecień 21, 2022 Udostępnij Kwiecień 21, 2022 W tym trybie OCR0A używany jest zdaje się jako TOP czyli maksymalna wartość licznika. Spróbuj `(0<<WGM02)|(1<<WGM01)|(1<<WGM00);` bo wtedy TOP jest na stałe 0xFF i powinno działać jak chcesz. Nawiasem mówiąc dziwne że cokolwiek działa. 1 Link do komentarza Share on other sites More sharing options...
choco_amore Kwiecień 21, 2022 Autor tematu Udostępnij Kwiecień 21, 2022 Po ustawieniu timera w tryb FAST PWM z TOP 0xFF dalej nie ma żadnej reakcji na pinie PD6. PD5 działa tak jak powinien. Link do komentarza Share on other sites More sharing options...
farmaceuta Kwiecień 21, 2022 Udostępnij Kwiecień 21, 2022 Nie chce mi sie niuchac po rejestrach...a drugi led napewno dziala? Kabelkologia wporzadku? A delay_ms z ktorego timera korzysta? Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
farmaceuta Kwiecień 21, 2022 Udostępnij Kwiecień 21, 2022 (edytowany) Czekaj czekaj...a w tym trybie nie wykorzystujesz przypadkiem obu rejestrow (OCRA/OCRB) do generowania czestotliwosci i wypelnienia?? OCRA=czestotliwosc, OCRB=wypelnienie? (Ok pomylka...teraz zauwazylem ze uzywasz 3 trybu) Edytowano Kwiecień 21, 2022 przez farmaceuta Link do komentarza Share on other sites More sharing options...
etet100 Kwiecień 21, 2022 Udostępnij Kwiecień 21, 2022 Zdecydowanie trzeba zacząć od zwykłego blinka i zobaczyć czy port/diody działają. Link do komentarza Share on other sites More sharing options...
farmaceuta Kwiecień 21, 2022 Udostępnij Kwiecień 21, 2022 No i mialem racje...uzywasz trybu 7! A nie 3...w tym trybie pin A nie jest uzywany bo jego rejestr jest zarezerwowany dla czestotliwosci (chyba)... Cytat..."W trybach, w których TOP jest definiowany przez rejestr, taki jak OCR1A, służy on do regulacji CZĘSTOTLIWOŚCI PWM. W innych trybach (stałe wartości TOP) częstotliwość jest stała, ale można użyć dwóch kanałów wyjściowych i ustawić dwa cykle pracy na kanałach A i B. Ale w trybie, w którym OCR1A jest na górze, kanał A nie jest już używany jako PWM wyjście. Jedynym zastosowaniem OCR1A jest regulacja częstotliwości. " zobacz sobie na bity...zwlaszcza na WGM02... Reansumujac wpisz tam zero i powinno zadzialac.. Link do komentarza Share on other sites More sharing options...
choco_amore Kwiecień 21, 2022 Autor tematu Udostępnij Kwiecień 21, 2022 (edytowany) Drodzy Koledzy, udało mi się dojść do rozwiązania problemu. Zarówno w trybie 3 i 7 PWM problem wyglądał podobnie. Rozwiązaniem problemu okazał się sposób ustawiania bitów. W pierwszym sposobie nie ustawiłem wyjścia nr 6, bo dałem za małą liczbę.... Bardzo głupi błąd. Było: DDRD = 0b111111; ... ADMUX = 0b01000000; ADMUX |= adcx; Jest: DDRD |= (1<<DDD5)|(1<<DDD6); ... //wybor pinu wejscia ADMUX |= (1<<REFS0) | (0<<MUX0); ADMUX |= adcx; Dziękuję wszystkim za chęć pomocy, pozdrawiam. 🙂 Edytowano Kwiecień 21, 2022 przez choco_amore Link do komentarza Share on other sites More sharing options...
etet100 Kwiecień 21, 2022 Udostępnij Kwiecień 21, 2022 I dlatego tak ważna jest dbałość o kod. Porządne formatowanie. 1 Link do komentarza Share on other sites More sharing options...
farmaceuta Kwiecień 21, 2022 Udostępnij Kwiecień 21, 2022 (edytowany) A ktos glosno krzyczal zeby nie ustawiac rejestrow liczbami binarnymi a juz napewno nie hex'em, a tylko i wylacznie nazwami poszczegolnych bitow😉 Edytowano Kwiecień 21, 2022 przez farmaceuta 1 Link do komentarza Share on other sites More sharing options...
Krawi92 Kwiecień 21, 2022 Udostępnij Kwiecień 21, 2022 (edytowany) Ustawiając jakiekolwiek bity polecam używać przesunięć bitowych, zamiast 0b01101101 czy 0x7D. Łatwo o pomyłkę, a i czytelność kodu jest mniejsza. Wiadomo, jakbyś chciał na caly rejestr wystawić jedynki to szybciej będzie napisać 0xFF, ale przy pojedynczych lepiej to robić czytelniej. A w twoim pierwszym kodzie jest cały mix 🙃 nawet znalazło się makro _BV Nie jest to jakiś błąd, wszystko ma prawo działać, tylko osobiście myślę że styl programowania powinien być w miarę uporządkowany. Edytowano Kwiecień 21, 2022 przez Krawi92 1 Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Bądź aktywny - zaloguj się lub utwórz konto!
Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony
Utwórz konto w ~20 sekund!
Zarejestruj nowe konto, to proste!
Zarejestruj się »Zaloguj się
Posiadasz własne konto? Użyj go!
Zaloguj się »