BlackJack Napisano Sierpień 5, 2011 Udostępnij Napisano Sierpień 5, 2011 Krótki wstęp Celem tego artykułu jest poruszenie częstych problemów, jakie napotkałem na forum. Czyli głównie obsługi Timerów, serwomechanizmów, oraz paru innych rzeczy, z jakimi borykają się użytkownicy, BASCOM AVR. Przy czym chciałbym się skupić, na rozwiązaniach mniej popularnych w tym środowisku, czyli na próbie stworzenia własnych funkcji, dla BASCOMa, pod ATMegę 8. Chciałbym także na wstępie rozwiać pewne wątpliwości, co do Max rozmiaru kodu wynikowego w najnowszych wersjach BASCOM AVR, która wynosi obecnie 4KB. Procesor Ponieważ jednym z najpopularniejszych procesorów w konstrukcjach robotów jest nadal ATMega 8 i jego nowsze rozwinięcia ATMega 48/88/168 to skupimy się właśnie na tym CPU. Przy czym należy pamiętać, że nowsze ATMegi 48/88/168 są nieco bardziej rozbudowane niż ATMega 8, np. Timer0 i niestety nie kompatybilne od strony rejestrów SFR , lecz metody pokazane w artykule można z powodzeniem przenieść na ATMegi 48/88/168 po uwzględnieniu różnic. Ja dla wygody będę używał czasami skróconego oznaczenia M48/M88/M168 oraz M8. Po wahaniach spowodowanych pewnymi różnicami miedzy M8 a jego nowszymi odsłonami, ostatecznie zdecydowałem, że będę pisał o M8, ponieważ mogą być osoby, które jeszcze używają tych CPU i gdybyśmy się skupili na nowszych jego odmianach, to okazało by się, że w pewnych wypadkach posiadacze M8 zwyczajnie nie mieli by do dyspozycji pewnych zasobów sprzętowych. Należałoby także wspomnieć o pewnej fabrycznej wadzie ATMegi 8 mianowicie ma ona zwarte wewnętrznie końcówki masy cyfrowej i analogowej, co powoduje, że filtry do odkłócania przetwornika ADC nie spełniają do końca swojej funkcji. M48/88/168 tej wady nie posiadają. Jak mnie pamięć nie myli w nowszych ATMegach 8A, usunięto już tę wadę fabryczną. Ja osobiście eksperymenty będę robił na płytce stykowej, bo akurat zestawu do ATmegi 8 nie mam. Używałem takiego schematu, napotkałem także kilka ciekawych problemów, ale o tym wspomnę po drodze. BASCOM AVR Najnowszą wersję Demo BASCOM AVR można sobie ściągnąć ze strony producenta pod tym adresem: http://www.mcselec.com/index.php?option=com_docman&task=cat_view&gid=99&Itemid=54 Jest na samym dole strony. Nie będę tutaj opisywał szczegółowo ani środowiska BASCOM AVR, ani problematyki programatorów czy wgrywania programów do procesora, bo są kursy na diodzie, a programatory i ich obsługa to niezły materiał na osobny artykuł. Jak wygenerować częstotliwość dla diody IR i odbiornika TSOP ? Jednym z częstych pytań spotykanych na forum jest, jak sobie poradzić z wygenerowaniem częstotliwości nośnej dla popularnych czujników serii TSOP lub ich odpowiedników. Więc postaramy się za pomocą jednego z Timerów sprzętowo wygenerować częstotliwość nośną dla układów TSOP. Ogólnie mamy następujące wersje tych układów i częstotliwości nośne dla nich: TSOP1730 30 kHz TSOP1733 33 kHz TSOP1736 36 kHz * TSOP1737 36.7 kHz TSOP1738 38 kHz * TSOP1740 40 kHz * TSOP1756 56 kHz *- tłustym drukiem wyróżniono najczęściej spotykane w konstrukcjach / sklepach. Pierwsze pytanie, jakie nachodzi na myśl to jak szybkiego zegara CPU trzeba użyć? Tu wielu początkujących z obawy, że braknie im mocy obliczeniowej taktuje procesor sporymi zegarami najczęściej 8MHz. Tymczasem w zupełności wystarczają fabryczne ustawienia, czyli taktownie 1MHz. Co ciekawe właśnie na tym zegarze zbudujemy większość przykładów, jeżeli nawet nie wszystkie i zobaczycie sami, że niczego nam nie braknie. Tylko, którego Timera użyć i co do niego wstawić? Ponieważ T0 w M8 jest bardzo biednie uposażony w porównaniu do dwóch pozostałych braci to wykorzystamy do naszych celów 8-bitowy T2. W układach M48/88/168 T0 się spokojnie nadaje, bo ma tryb CTC, który wykorzystamy, nie znaczy to, że na M8 nie da się tego zrobić na T0, ale my chcemy maksymalnie usprzętowić ten proces. 16-bitowy T1 zostawimy w spokoju. Zresztą zaprzęganie go do takiego prostego zadania było by grzechem, niemal wagi ciężkiej. Nas będzie interesował tryb CTC (Clear timer on compare match), ponieważ jest on przeznaczony właśnie do tego celu. Rysunek niżej pokazuje działanie w tym trybie. W tym trybie licznik T2 ( TCNT2 konkretnie) zlicza w górę od 0 do 255, a komparator porównuje jego zawartość z rejestrem OCR2. Kiedy zostaje wykryta zgodność ( TCNT2 = OCR2) wtedy licznik jest automatycznie zerowany, a skojarzona z danym komparatorem końcówka (pin procesora) przyjmuje albo jeden ze zdefiniowanych stanów (zero lub jeden), lub zmienia swój stan na przeciwny ( ten tryb akurat nas interesuje). Ostatecznie można jeszcze zgłaszać przerwania. Teraz czas na trochę obliczeń. Ogólnie wzór na obliczenie wartości, jaką należy wpisać do rejestru komparatora można przedstawić tak: OCR2 = Fosc / (F_wyj * 2) Gdzie: Fosc – to częstotliwość taktowania CPU F_wyj – to częstotliwość, jaką chcemy uzyskać, a mnożymy ją 2x, bo stan pinu w czasie jednego okresu musimy zmienić dwukrotnie. Przykład: Chcemy uzyskać chyba najpopularniejsze 36KHz, przy taktowaniu 1MHz. OCR2A = 1 000 000 / (36 000 * 2) OCR2A = 1 000 000 / 72 000 OCR2A = 13,8 ? Jak to 13,8 ? Ano właśnie, co z tym zrobić, przecież do rejestru OCR2 nie możemy wpisać wartości 13,8. W informatyce jest na to sposób, mianowicie zaokrąglanie. Sposób polega na tym że wartości ułamkowe do 0,49 zaokrąglamy w dół czyli np. 12,4 bierzemy 12, a wartości powyżej 0,49 jak nasze 13,8 zaokrąglamy do góry czyli wyjdzie nam że trzeba wpisać 14. Z tych obliczeń wynika też inna ważna prawda, otóż gdybyśmy chcieli użyć w naszej M8 Timera0 i przerwań od niego, czyli realizować generowanie częstotliwości pół programowo, to nad chodziłyby one na tyle często, że mogłoby nam zabraknąć czasu na inne zadania i musielibyśmy zwiększyć zegar CPU do np. 8MHz. Spokojnie nam nie braknie, 1MHz, bo Timer 2 zrobi wszystko sprzętowo, i nie będzie zawracał głowy programowi, najwyżej program jemu. Ktoś też szybko policzy że przy wartości 14 nie wyjdzie nam 36KHz tylko 35,714KHz ale akurat tym nie musimy się nazbyt martwić ponieważ układy TSOP mają pewną tolerancję ok. +/- 0,4KHz, w której się mieścimy, przy większych odchyłkach zacznie nam spadać czułość odbiornika, a co za tym idzie zasięg. Ogólnie co ciekawe podczas eksperymentów okazało się że układy te maja kosmiczną tolerancję, mój TSOP1133 który powinien być na 33KHz bez problemu wykrywał pilota SONY pracującego na 38KHz. Tabela niżej pokazuje jak zmieniać będzie się nam dokładność generowanej częstotliwości (wartości w nawiasie) w zależności od zegara CPU i wartości wpisanej do OCR2. Jak widać dokładność rośnie wraz ze wzrostem częstotliwości CPU. Z tabeli wynika także, że przy 1MHz obsłużymy większość TSOPów, pewnym wyjątkiem jest układ na 40KHz, ale w jego przypadku wystarczy przeskoczyć na 2MHz, do OCR2 wstawić wartość 25 i wszystko będzie gitara. Ale przejdźmy do pisania procedur. Niestety BASCOM AVR nie pozwala w prosty sposób pisać bibliotek, bo trzeba by je pisać w asemblerze, ale niektóre rzeczy możemy sobie uprościć i zautomatyzować używając poleceń kompilacji warunkowej i w ten sposób przenieść powyższą tabelkę do pliku, który będzie nam definiował automatycznie pewne stałe systemowe zależnie od wybranej częstotliwości CPU. A wygląda to tak: 'definicje warunkowej kompilacji w zależności od F_CPU 'dla 1MHz #if _xtal = 1000000 Const 30kh = 17 Const 33kh = 15 Const 36kh = 14 Const 38kh = 13 Const 40kh = 12 Const 56kh = 9 #else 'jeżeli NIE to sprawdź czy 4MHz 'dla 4MHz #if _xtal = 4000000 Const 30kh = 67 Const 33kh = 60 Const 36kh = 56 Const 38kh = 53 Const 40kh = 50 Const 56kh = 36 #else ' w przeciwnym wypadku zakładamy że jest 8MHz 'dla 8MHz Const 30kh = 133 Const 33kh = 121 Const 36kh = 111 Const 38kh = 105 Const 40kh = 100 Const 56kh = 71 #endif #endif Ja sobie zapisałem to pod nazwą „M8_timers_lib.bas” Użyto tutaj stałej BASCOMowej _xtal, która przechowuje zadeklarowaną w ustawieniach kompilatora, lub poleceniem $crystal wartość określającą częstotliwość CPU. Prosty program demo ma następujący kod: '*************************************************************' '* Program demo użycia Diody IR i odbiornika TSOP1733 *' '* do sterowania diodą IR. *' '* CPU -ATMega8 taktowana 1MHz *' '*************************************************************' $regfile = "m8def.dat" $crystal = 1000000 'konfiguracja portów Config Portb = &B00001111 Config Portc = Input Config Portd = &B00001011 'deklaracje procedur Declare Sub F_ired(byval F_ir As Byte) Declare Sub Ired On Timer0 Czas 'dołączamy nasz wcześniej napisany plik kompilacji warunkowej zależnej od F_CPU $include "M8_timers_lib.bas" 'deklaracje stałych do sterowania Timerem Const T0_stop = 0 Const T0 Set Dioda End If End If Loop End 'procedury związane z diodą IR Sub F_ired(byval F_ir As Byte) Tccr2 = &B10011000 Tcnt2 = 0 If F_ir > 0 Then Ocr2 = F_ir Else Ocr2 = 14 End If End Sub Sub Ired Tccr2 = &B10011000 End Sub Czas: Tccr0 = T0_stop Tcnt0 = Impuls Tccr0 = T0_start Znacznik = 1 Return Jak widać nie użyłem tutaj polecenie Config Timer. Zrobiłem to specjalnie ponieważ chciałem pokazać jak można sterować Timerami, odwołując się bezpośrednio do rejestrów sterujących, za pomocą zdeklarowanych stałych. Warto się nauczyć takiej metody, a to z dwóch powodów: 1. Bardzo przydatne kiedy standardowe funkcje BASCOMa, odmawiają współpracy, i zasypują nas errorami, klasy że w danym CPU, np. nie ma preskalera 16, kiedy wg. noty kat, wyraźnie jest. 2. Zdobyta w ten sposób wiedza o wnętrznościach CPU, przyda się kiedy postanowimy przejść na programowanie w C. Ponieważ pojawiły się pytania jak sterowałem Timerem 2, to małe uzupełnienie. Otóż do sterowania timerem 2 używa się rejestru TCCR2, który ma następują budowę: Znaczenie poszczególnych bitów jest następujące : bit 7 - FOC2 - Force Output Compare. Jest on aktywny tylko i wyłącznie w specyficznych ustawieniach bitów WGM (o których niżej) i nie jest aktywny w trybie PWM. Jest on powiązany z wyjściem OC2 i służy do aktywowania tej funkcji alternatywnej portu PB3, w trybie CTC. bit 6 + bit 3 -WGM20, WGM21 - Waveform Generation Mode. Te dwa bity określają, tryb pracy Timera 2, zgodnie z poniższą tabelką. Gdzie: Mode 0 (WGM21;20 = 00) - Normal Mode, czyli normalna praca T2 jako zwykły Timer. Mode 1 (WGM21;20 = 01) - PWM, Phase Correct. Tryb PWM z korektą Fazy. Mode 2 (WGM21;20 = 10) - CTC Mode, czyli tryb który nas interesuje. Mode 3 (WGM21;20 = 11) - Fast PWM. Tryb szybkiego PWMa. bity 5 i 4 - COM21, COM20 - Compare Match Output Mode. Te dwa bity określają jak zachowywać będzie się końcówka OC2, przy czym ich znaczenie zależy od trybu, jaki wybrano bitami WGM21:0. Ja się skupię tylko na trybie CTC i nie będę opisywał ich znaczenia w trybie PWM. (COM21:0 = 00) - Normal port operation, OC2 disconnected. Port PB3, działa jako zwykła końcówka I/O i nie jest powiązany z Timerem 2. (COM20:1 = 01) - Toggle OC2 on Compare Match. Końcówka OC2, zmienia swój stan na przeciwny, przy kiedy wartość licznika T2 jest równa wartości porównywanej. Tego trybu użyłem do generowania częstotliwości. (COM20:1 = 10) - Clear OC2 on Compare Match. Równość zawartości T2 i rejestru Compare powoduje wyzerowanie końcówki OC2. Ustawić ja na 1 musimy z powrotem sami. (COM20:1 = 11) - Set OC2 on Compare Match. To samo co wyżej, tylko działa odwrotnie czyli ustawia końcówkę OC2 na 1 w chwili zgodności porównania wartości T2 i rej. Compare. Bity 2 do 0 - SC22 do CS20 - Clock Select. Trzy najważniejsze z punktu sterowania bity w tym rejestrze, bo pozwalają uruchomić i zatrzymać Timer 2. Jeżeli mają one wartość 000 - to Timer 2 nie pracuje, czyli ich wyzerowanie jest równoważne z wydaniem BASCOMowej instrukcji Timer2 STOP. Wartość 001 startuje Timer 2 bez podziału częstotliwości, czyli jest on taktowany bezpośrednio zegarem CPU. Wartości z przedziału od 010 do 111 startują Timer 2 z tgz. preskalerem, czyli dzielnikiem który wynosić może zgodnie z tabelą 8 (010), 32 (011), 64 (100), 128 (101), 256 (110) i 1024 (111). Mam nadzieję że te małe uzupełnienie pozwoliło wyjaśnić skąd w programie wzięły się linie Tccr2 = &B10011001 oraz Tccr2 = &B10011000 i co robią. Na filmiku można zobaczyć rezultaty. Serwomechanizmy. Drugi często spotykany problem to jak ruszyć serwomechanizmy za pomocą sprzętowego PWMa. Ja osobiście uważam, że zaprzęganie sprzętowego PWMa do sterowania nawet jednym serwem, biorąc pod uwagę, że nad bywa nam timerów w procesorze, to i tak lekka przesada. My spróbujemy więc ruszyć serwem nie tylko nie korzystając ze sprzętowego PWM, ale wykorzystamy do tego najsłabszy z Timerów w M8 czyli T0, w dodatku spróbujemy ruszyć nie jednym, a kilkoma serwami. Na początek może napiszę jak sterowane są serwa. Otóż serwa są sterowne krótkimi impulsami o czasie trwania od 0,5 do 2ms (dla standardowych serw), które określają kąt obrotu, powtarzanymi co 20ms (ten czas będę nazywał ramką). Mając te informacje możemy sprawdzić czy nasz 8-bitowy T0 podoła temu zadaniu. Przy zegarze 1MHz, 1 takt zegara trwa 1us, a 1ms to 1000us, czyli do odmierzenia 2ms musimy zliczyć 2000 impulsów. Na szczęście nasz T0 ma preskaler, który może dzielić przez 8, 64, 256 i 1024. Nam najbardziej spasuje 8, bo 8 * 255 da nam możliwość odmierzenia 2040us czyli 2,04ms, a 8 będzie nasza rozdzielczością sterowania, czyli najkrótszym krokiem, o czasie trwania 8us, jaki będziemy w stanie wygenerować. Jeszcze, pytanie jak wysterować więcej serw jednym timerem, i ile maksymalnie może ich być. Odpowiedź na to pytanie jest dosyć prosta wystarczy 20ms / 2ms co daje 10 serw. My jednak spróbujemy posterować tylko 5, co w sumie jest dosyć uniwersalną liczbą. A jak to zrobić ? Wystarczy w tablicy przechowywać ustawienia, dla 5 serw i kolejno, co 4ms (20ms / ilość serw), je generować na odpowiednim dla danego serva pinie CPU. '************************************************************************' '* Program sterownia serwami za pomocą Timera 0 w ATMega8 *' '************************************************************************' $regfile = "m8def.dat" $crystal = 1000000 Config Portb = &B00001111 Config Portc = Input Config Portd = &B00111011 Config Timer0 = Timer , Prescale = 8 On Timer0 Servo Dim Serva(5) As Byte Dim Wsk_serva As Byte Dim Impuls As Byte Dim Licz_pom As Word Dim Status As Bit Dim Bit_pom As Bit For Wsk_serva = 1 To 5 Serva(wsk_serva) = Wsk_serva * 4 Serva(wsk_serva) = Serva(wsk_serva) + 123 Next Wsk_serva Wsk_serva = 1 Impuls = 255 - Serva(1) ' oblicz czas_martwy Impuls = Impuls - 8 Load Timer0 , Serva(1) Reset Status Enable Interrupts Enable Ovf0 Start Timer0 Bit_pom = 0 'Set Portd.1 Do If Status = 1 Then If Bit_pom = 0 Then Incr Wsk_serva If Wsk_serva > 5 Then Wsk_serva = 1 End If ' tutaj decydujemy które serwo obsługujemy w bieżącym podejściu. Select Case Wsk_serva: Case 1 : Set Portd.1 Case 2 : Set Portd.3 Case 3 : Set Portd.4 Case 4 : Set Portd.5 Case 5 : Set Portd.6 End Select ' jeżeli wartość dla serwa poniżej 1ms, to ustaw wychylenie na minimum czyli na 1ms. If Serva(wsk_serva) < 125 Then Impuls = 125 Else 'w przeciwnym wypadku załaduj wartość dla serwa minus czas obsługi przerwania. Impuls = Serva(wsk_serva) - 8 End If Set Bit_pom Else , jeżeli koniec cyklu to restartujemy odpowiedni pin dla aktualnego serwa. Select Case Wsk_serva: Case 1 : Reset Portd.1 Case 2 : Reset Portd.3 Case 3 : Reset Portd.4 Case 4 : Reset Portd.5 Case 5 : Reset Portd.6 End Select Impuls = 247 - Serva(wsk_serva) Reset Bit_pom End If Reset Status End If Loop Servo: Stop Timer0 Load Timer0 , Impuls Start Timer0 Set Status Return Program pokazuje tylko idę sterowania, a to dlatego że praktycznie nie zawiera on elementów pozwalających, sterować wszystkimi serwami, tylko po włączeniu zasilania, ustawia jest o zadany kąt. Ale chodziło mi o pokazanie Idei, a nie skonstruowanie gotowca. Oczywiście pokazana Idea, nie jest jedynie słuszna, akurat w przypadku serw, można do problemu podejść na co najmniej 3 - 4 sposoby (zależnie jakimi zasobami CPU dysponujemy). Ale ja chciałem pokazać jak sobie poradzić, w sytuacji kiedy jesteśmy przysłowiowo, przybici do ściany i musimy jakoś poradzić sobie tym co mamy. Jak działa program? Najpierw w pętli FOR.. wypełnia tablicę Serva, wartościami początkowymi. Potem inicjowany jest wskaźnik na serwo nr 1, ładowane są ustawienia Timera, odblokowywane są przerwania i startowany jest Timer 0. Nieco wprawieni BASCOMowcy zauważą jednak, że program nie zmienia serwa co 4ms, jak pisałem wyżej, a co 2ms, więc w jednej 20ms ramce wysterowuje, 2 razy wszystkie serwa. Nie jest to bynajmniej wada, takie podejście upraszcza program, ponieważ nie musimy kombinować jak odmierzać te 4ms, Timerem, który jak wiemy liczy nam tylko 2,04ms maksymalnie, a serwom nie robi to różnicy. Skoro jesteśmy przy czasach to jeszcze ważną rzeczą jest to jak są one w tym programie odmierzane i jak działa sam Timer. Otóż Timer odmierza tak naprawdę 2 czasy dla jednego serwa, czas impulsu dodatniego i czas_martwy, który jest obliczany w taki sposób że od maksymalnej pojemności Timera czyli 255 odejmujemy wartość czasu trwania impulsu dla serwa, i otrzymujemy czas_martwy, czyli czas który trzeba odczekać, aby móc wysterować kolejne serwo. Dodatkowo odejmowana jest pewna wartość stała. Skąd ona się bierze? Otóż obsługa naszego przerwania od Timera 0, zajmuje pewien czas, wynika to z tego że trzeba skoczyć do procedury obsługi przerwania, zatrzymać Timer, załadować go nową wartością, i ponownie wystartować. Mi w symulacji wyszło że to 62 cykle zegara, czyli trzeba odjąć 62 / 8 bo preskaler, czy 7,75 co daje w praktyce liczbę 8. W ten sposób minimalizujemy rozrzut, odmierzanych czasów. wyeliminować się go nie da całkowicie, a to dla tego że wychodzi nam liczba ułamkowa, no i sam oscylator RC którym taktujemy procesor, też idealny nie jest. Podsumowanie. Mój artykuł nie wyczerpuje, tematu Timerów w procesorach AVR, i metod rozwiązywanie różnych problemów, na jakie w praktyce można się natknąć, bo wyszła by mi z tego całkiem pokaźna książka, a musiałem się jakoś sensownie zmieścić w ramach gabarytowych które powodują że jest to artykuł. Nie poruszyłem np. tematu PWM i sterowania silnikami, a to dla tego że pisząc ten tekst, chciałem uniknąć, kopiowania jakiś potocznie znanych informacji z różnego rodzaju kursów czy książek, a z drugiej strony chciałem praktycznie przetestować przykłądy, aby móc podawać w miarę wartościowe i sprawdzone informacje. Druga sprawa to to, że układy realizowałem na płytce stykowej z elementów, wyciągniętych z szuflady, więc nie bylem, np. w stanie przeprowadzić sensownych eksperymentów z silnikami i mostkami, bo po prostu w szufladzie nie leżały, mi potrzebne elementy. Inna sprawa to, że płytka stykowa szybko okazała się dosyć kapryśną podstawą, już same diody IR, dały mi popalić, i początkowo nie wiedziałem gdzie mam błąd, na szczęście doświadczenie zdobyte przy budowie pilota RC5, podpowiedziało mi co robić. Jeszcze lepiej dopiekło mi jedyne serwo które posiadam, okazało się że jest takim prądożercom, że nawet z zasilacza wtyczkowego 500mA, na płytce stykowej tak wariowało napięcie, że restartował mi się procesor. Dopiero rozdzielenie odpowiednio napięć zasilania, pozwoliło mi ruszyć czymkolwiek z miejsca, a i tak było widać, przygasanie LEDy za stabilizatorem. Mam nadzieję że udało mi się stworzyć artykuł inny niż to co do tej pory, ukazało się na FORBOT (była DIODA), który okaże się inspiracją dla innych, i pomocą dla początkujących. Cytuj Link do komentarza Share on other sites More sharing options...
soban Sierpień 5, 2011 Udostępnij Sierpień 5, 2011 Tematy z IR już były. Może masz tu trochę teorii i wszystko wklepane w jedną całość ale trochę za mało jak dla mnie na ten konkurs. Ale gratuluję rozwinięcia tematu Cytuj Link do komentarza Share on other sites More sharing options...
troszyn Sierpień 6, 2011 Udostępnij Sierpień 6, 2011 W informatyce jest na to sposób, mianowicie zaokrąglanie. Sposób polega na tym że wartości ułamkowe do 0,5 zaokrąglamy w dół czyli np. 12,5 bierzemy 12, a wartości powyżej 0,5 jak nasze 13,8 zaokrąglamy do góry czyli wyjdzie nam że trzeba wpisać 14. Wybaczcie być może durne pytanie, w informatyce zaokrągla się inaczej niż w matematyce? Tj. przy 0,5 w dół a nie w górę? Czy spałem na matematyce? Cytuj Link do komentarza Share on other sites More sharing options...
BlackJack Sierpień 6, 2011 Autor tematu Udostępnij Sierpień 6, 2011 I tak jak mówisz jest napisane. wartości ułamkowe do 0,5 zaokrąglamy w dół czyli np. 12,5 bierzemy 12 przy czym do 0,5 należy czytać jako, z 0,5 włącznie. Cytuj 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
Nawyk Sierpień 8, 2011 Udostępnij Sierpień 8, 2011 Jeżeli odrzucaną cyfrą (zastępowaną zerem) jest 0,1,2,3,4, to ostatnia zachowana cyfra nie zmienia się.Jeżeli odrzucaną cyfrą (zastępowaną zerem) jest 5,6,7,8,9, to ostatnia zachowana cyfra jest zwiększana o 1. To tak jeśli chodzi o moje wspomnienia z czasów szkoły 😋 Dlatego 12,5 po zaokrągleniu do cz. całkowitej, powinno wynosić 13... Cytuj Link do komentarza Share on other sites More sharing options...
BlackJack Sierpień 8, 2011 Autor tematu Udostępnij Sierpień 8, 2011 Hm.. faktycznie się pomyliłem. 🤯 Aczkolwiek moja metoda mnie nie zawodziła nigdy. ❓, Już poprawiłem błąd. Cytuj Link do komentarza Share on other sites More sharing options...
KD93 Sierpień 10, 2011 Udostępnij Sierpień 10, 2011 BlackJack, wg mnie lepiej by było gdybyś w trybie CTC objaśnił po prostu jak ustawić rejestr wg tabelki z DS'a ATmegi. Do ustawienia Timera w tryb CTC wystarcza kilka linijek kodu, nie wiem czemu to takie pokomplikowane zrobiłeś. Chyba że się mylę i w ATmedze ustawia się to trudniej niż w ATtiny. Cytuj Link do komentarza Share on other sites More sharing options...
BlackJack Wrzesień 18, 2011 Autor tematu Udostępnij Wrzesień 18, 2011 Zgodnie z sugestiami kolegów uzupełniłem nieco artykuł. Cytuj Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Dołącz do dyskusji, napisz odpowiedź!
Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!