Skocz do zawartości

[Programowanie] Wakcje z robotyką i AVRami. BASCOM vs Timery.


BlackJack

Pomocna odpowiedź

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ę:

IMG_4e75930e0601a3320.jpg

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ą.

IMG_4e759702669ef4475.jpg

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.

IMG_4e759b14a245f4793.jpg

(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.

 

IMG_4e3bfe551d7899244.thumb.jpg.c5f1d4cf063d5e900c408781fb8df4e1.jpg

Link do komentarza
Share on other sites

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?

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

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

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...

Link do komentarza
Share on other sites

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.

Link do komentarza
Share on other sites

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!

Gość
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.