Jak powinien wyglądać kod w języku .C i w j.ASM na Attiny 2313A według poniższych wskazówek. Oto te wskazówki :
"Cały czas mowa o precyzyjnych częstotliwościach, współczynniku wypełnienia a uczepiłaś się najgorszego z możliwych rozwiązań mając sprzętowe sterowanie GPIO, gdzie trzeba liczyć każdy cykl maszynowy jak w latach 80.
W Generatorze DDS z EP 6/2018 jest sprzętowe sterowanie wyjściem:
void Timer1_Start(uint8_t dzielnik)
{
// OCR1B=dzielnik;
OCR1B=dzielnik;
//Output compare toggles OC1A pin
// TCCR1A |= 0x40; // COM1A = 1
TCCR1A |= 0x10; // COM1B = 1
//start timer without prescaler
TCCR1B = 0b00001001; // WGM 12=1, CS=1
DDRD |= _BV(PD4);
}
Uzyskasz DOKŁADNIE 50% bez liczenia cykli. Nie muszą być włączone przerwania ale mogą. Program główny może robić co chce a nie wpłynie to na generowany przebieg bez względu na to, czy przerwania będą włączone czy nie. Max częstotliwość to Fclk/2, uzyskaj taką przez delay. Taki program jest krótszy niż z delay. Jeśli częstotliwość jest zbyt duża należy timery połączyć w kaskadę.
Można także użyć timera w trybie PWM. Używając OCRxA można ustawić próg zliczania a co za tym idzie, precyzyjnie regulować częstotliwość.
Głupotą jest, mając możliwości sprzętowe, rozwiązywać problem w sposób programowy.
Uważasz, że nie mam racji? Napisz na innych forach i zweryfikuj moją wiedzę."
Tak, sens wskazówek jest zasadniczo poprawny: na ATtiny2313A przebieg o precyzyjnej częstotliwości i dokładnym wypełnieniu 50% należy generować sprzętowo, przez Timer1 i wyjście OC1x, a nie przez pętle delay i ręczne przełączanie GPIO. Trzeba jednak skorygować dwa istotne błędy z przytoczonego fragmentu: na ATtiny2313A wyjścia OC1A i OC1B są na PB3 i PB4, a nie na PD4/PD5; dodatkowo w trybie CTC mode 4 wartość TOP ustala OCR1A, a nie OCR1B. Zatem pokazany kod w tej postaci nie jest poprawny dla regulacji częstotliwości na OC1B. (ww1.microchip.com)
Najprostsze i najczystsze rozwiązanie dla przebiegu prostokątnego 50% to:
OCR1A = 0 i preskalera N = 1. (ww1.microchip.com)Przytoczone wskazówki są słuszne co do idei, ale wymagają doprecyzowania pod konkretny układ ATtiny2313A. Najważniejsze jest rozróżnienie trzech rzeczy:
W cytacie ustawiono:
TCCR1A |= 0x10; czyli COM1B0 = 1, a więc sprzętowe przełączanie OC1B,DDRD |= _BV(PD4);, czyli jako wyjście ustawiany jest PD4.To się nie zgadza z mapą pinów ATtiny2313A, bo:
Czyli jeśli chcesz używać COM1B0, to musisz wystawić sygnał na PB4, nie na PD4. (ww1.microchip.com)
Drugi błąd jest bardziej subtelny: w trybie CTC mode 4 (WGM13:0 = 0100) licznik zeruje się przy dopasowaniu do OCR1A. To znaczy, że częstotliwość ustala OCR1A, a nie OCR1B. OCR1B w tym trybie może generować zdarzenie porównania dla kanału B, ale nie definiuje TOP. Innymi słowy: jeśli ustawisz tylko OCR1B, to nie ustawiasz okresu timera. (ww1.microchip.com)
Jeżeli celem jest:
to najlepsze rozwiązanie jest takie:
OCR1A = TOP,To jest rozwiązanie lepsze od delay, bo przełączanie pinu realizuje blok sprzętowy timera, a nie CPU. Z praktycznego punktu widzenia oznacza to, że pętla główna może wykonywać inne zadania i nie zmieni to generowanej częstotliwości ani wypełnienia; ograniczeniem pozostaje jedynie stabilność źródła zegara mikrokontrolera. To jest wniosek wynikający z tego, że wyjście OC1x jest sterowane bezpośrednio przez moduł compare timera po ustawieniu bitów COM1x i odpowiedniego bitu DDR. (ww1.microchip.com)
Poniżej jest wersja, którą uznałbym za wzorcową dla prostokąta 50% na OC1A / PB3:
#define F_CPU 8000000UL
#include <avr/io.h>
#include <stdint.h>
static inline uint16_t timer1_top_from_freq(uint32_t f_cpu,
uint16_t prescaler,
uint32_t f_out)
{
return (uint16_t)((f_cpu / (2UL * prescaler * f_out)) - 1UL);
}
/*
* Generator prostokąta 50% na OC1A (PB3)
* Tryb: CTC, TOP = OCR1A
*
* f_out = F_CPU / (2 * N * (1 + OCR1A))
*
* cs_bits:
* (1<<CS10) -> N = 1
* (1<<CS11) -> N = 8
* (1<<CS11) | (1<<CS10) -> N = 64
* (1<<CS12) -> N = 256
* (1<<CS12) | (1<<CS10) -> N = 1024
*/
void Timer1_Square_OC1A_Start(uint16_t top, uint8_t cs_bits)
{
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = top; // TOP dla trybu CTC mode 4
DDRB |= _BV(PB3); // PB3 = OC1A jako wyjście
TCCR1A = _BV(COM1A0); // Toggle OC1A on Compare Match
TCCR1B = _BV(WGM12) | (cs_bits & 0x07); // CTC, start timera
}
int main(void)
{
// Przykład: 1 kHz przy F_CPU = 8 MHz, preskaler = 1
// OCR1A = 8000000 / (2*1*1000) - 1 = 3999
uint16_t top = timer1_top_from_freq(F_CPU, 1, 1000);
Timer1_Square_OC1A_Start(top, _BV(CS10));
while (1)
{
// Kod główny może robić co chce.
// Generacja przebiegu jest sprzętowa.
}
}
Ten kod jest zgodny z dokumentacją: COM1A0=1 daje przełączanie wyjścia OC1A przy compare match w trybie nie-PWM, a WGM12=1 wybiera tryb CTC mode 4, gdzie OCR1A jest TOP. Pin wyjściowy to PB3, bo to właśnie on pełni funkcję OC1A w ATtiny2313A. (ww1.microchip.com)
Dla maksymalnej częstotliwości wystarczy:
Timer1_Square_OC1A_Start(0, _BV(CS10));
Wtedy dostajesz:
\[
f{OUT}=\frac{F{CPU}}{2}
\]
czyli np. przy 8 MHz będzie to 4 MHz. (ww1.microchip.com)
Poniżej odpowiednik asemblerowy dla OC1A / PB3. Zakładam F_CPU = 8 MHz i wyjście 1 kHz, czyli OCR1A = 3999 = 0x0F9F. Na ATtiny2313A stos jest reprezentowany przez SPL jako pojedynczy 8-bitowy rejestr. (ww1.microchip.com)
; Uwaga: nazwa pliku include zależy od toolchainu.
; W AVRASM zwykle spotyka się np. "tn2313Adef.inc"
.include "tn2313Adef.inc"
.cseg
.org 0x0000
rjmp RESET
RESET:
; Inicjalizacja stosu
ldi r16, low(RAMEND)
out SPL, r16
; Wyłączenie / wyzerowanie Timer1 przed konfiguracją
clr r16
out TCCR1A, r16
out TCCR1B, r16
; PB3 = OC1A jako wyjście
sbi DDRB, DDB3
; OCR1A = 3999 = 0x0F9F -> 1 kHz przy 8 MHz, N=1
ldi r16, high(3999)
out OCR1AH, r16
ldi r16, low(3999)
out OCR1AL, r16
; Toggle OC1A on Compare Match
ldi r16, (1<<COM1A0)
out TCCR1A, r16
; CTC mode 4 (WGM12=1), preskaler = 1 (CS10=1)
ldi r16, (1<<WGM12) | (1<<CS10)
out TCCR1B, r16
MAIN:
rjmp MAIN
Ten kod działa sprzętowo, bez przerwań, bez delay, bez liczenia cykli w pętli. Dokładnie taki styl implementacji wynika z architektury timera i jest poprawniejszy od „programowego machania pinem”. (ww1.microchip.com)
Jeżeli z jakiegoś powodu chcesz wyjście na OC1B, to na ATtiny2313A będzie to PB4, nie PD4 ani PD5. Dodatkowo, jeśli chcesz aby kanał B był „wyjściem częstotliwości”, to nie możesz w trybie 4 traktować OCR1B jako rejestru wyznaczającego okres. W trybie 4 okres nadal ustala OCR1A. Z tego powodu najprościej jest użyć kanału A. Jeżeli koniecznie chcesz kanał B i osobny rejestr TOP, wtedy poprawną drogą jest CTC mode 12 z TOP = ICR1 albo przejście w tryb PWM. To jest wniosek z tabeli trybów pracy Timer1. (ww1.microchip.com)
Przykład C dla OC1B / PB4 z TOP = ICR1:
#include <avr/io.h>
#include <stdint.h>
void Timer1_Square_OC1B_Start(uint16_t top, uint16_t phase, uint8_t cs_bits)
{
if (phase > top) phase = top;
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
ICR1 = top; // TOP w CTC mode 12
OCR1B = phase; // pozycja zbocza w ramach cyklu
DDRB |= _BV(PB4); // PB4 = OC1B
TCCR1A = _BV(COM1B0); // Toggle OC1B on Compare Match
TCCR1B = _BV(WGM13) | _BV(WGM12) | (cs_bits & 0x07);
}
Tu ważna uwaga praktyczna: w tym wariancie częstotliwość wyznacza ICR1, a nie OCR1B. OCR1B określa moment przełączenia w obrębie zliczania, czyli fazę zbocza względem początku cyklu. (ww1.microchip.com)
Wtedy cytowana rada też jest słuszna: trzeba użyć PWM, a nie trybu toggle. Dla Timer1 najpraktyczniejszy wariant to Fast PWM mode 14:
ICR1 ustala TOP, czyli częstotliwość,OCR1A lub OCR1B ustala wypełnienie,Przykład C dla PWM na OC1B / PB4:
#include <avr/io.h>
#include <stdint.h>
void Timer1_PWM_OC1B_Start(uint16_t top, uint16_t duty, uint8_t cs_bits)
{
if (duty > top) duty = top;
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
ICR1 = top; // TOP = częstotliwość
OCR1B = duty; // duty = wypełnienie
DDRB |= _BV(PB4); // PB4 = OC1B
// Fast PWM, mode 14: WGM13:0 = 1110
// Non-inverting on OC1B
TCCR1A = _BV(COM1B1) | _BV(WGM11);
TCCR1B = _BV(WGM13) | _BV(WGM12) | (cs_bits & 0x07);
}
W tym wariancie:
\[
f{PWM}=\frac{f{clk_I/O}}{N\cdot(1+ICR1)}
\]
a dla trybu nieodwróconego wypełnienie jest w przybliżeniu proporcjonalne do OCR1B. To jest właściwa metoda, gdy potrzebujesz np. 10%, 25%, 73% itd. W trybie toggle uzyskujesz z definicji 50%. (ww1.microchip.com)
W aktualnej dokumentacji Microchip dla ATtiny2313A/4313 nadal obowiązuje to samo mapowanie pinów i ta sama logika pracy Timer1: OC1A = PB3, OC1B = PB4, w CTC mode 4 TOP jest w OCR1A, a w CTC mode 12 TOP jest w ICR1. W tym sensie „aktualna wiedza” potwierdza, że właściwy kierunek to użycie peryferiów sprzętowych zamiast opóźnień programowych. (ww1.microchip.com)
W praktyce embedded to nadal jest najlepsza praktyka projektowa: jeśli mikrokontroler ma moduł compare/PWM, należy go wykorzystać. „Liczenie cykli w pętli” ma sens głównie w sytuacjach wyjątkowych, np. przy bit-bangingu wymuszonym przez brak zasobów sprzętowych. W przypadku ATtiny2313A taki przymus tutaj nie występuje. To jest wniosek inżynierski oparty na możliwościach Timer1 opisanych w dokumentacji. (ww1.microchip.com)
W trybie toggle on compare match pin OC1A lub OC1B zmienia stan przy każdym kolejnym zdarzeniu compare. Ponieważ te zdarzenia występują okresowo co dokładnie taką samą liczbę taktów timera, czas stanu wysokiego i niskiego jest identyczny. Stąd bierze się dokładne 50%, bez zależności od długości kodu głównego. (ww1.microchip.com)
delayPętla z delay:
Timer sprzętowy eliminuje te problemy, bo pin przełącza peryferium, a nie program. To jest dokładnie ta przewaga, o której mówi cytowana wskazówka. Wniosek wynika z architektury modułu compare. (ww1.microchip.com)
W CTC Timer1 nie ma podwójnego buforowania TOP tak jak pewne tryby PWM. Jeśli podczas pracy wpiszesz nowe OCR1A mniejsze od bieżącego TCNT1, może dojść do pominięcia najbliższego compare i timer dojdzie aż do 0xFFFF, zanim znowu zsynchronizuje się z nową wartością. Jeżeli chcesz dynamicznie zmieniać częstotliwość, najbezpieczniej:
TCNT1,albo rozważyć tryb Fast PWM z OCR1A jako TOP, który ma buforowanie OCR1A. (ww1.microchip.com)
W tym problemie nie ma szczególnego aspektu etycznego, ale są aspekty techniczne i bezpieczeństwa:
To nie zmienia samej logiki programu, ale wpływa na wynik w praktycznym układzie.
ICR1 jako TOP i OCR1B lub OCR1A jako duty. (ww1.microchip.com)Jedna z odpowiedzi przykładowych online była niepoprawna, bo traktowała PD4 jako OC1B i przypisywała OCR1B rolę rejestru ustalającego częstotliwość w CTC mode 4. To nie odpowiada dokumentacji ATtiny2313A. Druga odpowiedź online była również niepełna, bo konfigurowała CTC bez rzeczywistego włączenia poprawnego sprzętowego przełączania OC1A/OC1B. Dlatego nie należy tych przykładów kopiować bez korekty. (ww1.microchip.com)
Warto też doprecyzować terminologię: opisane tu rozwiązanie jest świetnym generatorem prostokąta opartym o timer. Jeśli ktoś mówi o „DDS”, to w ścisłym sensie zwykle ma na myśli akumulator fazy i syntezę numeryczną, a nie zwykły toggle na compare. W Twoim pytaniu jednak najważniejszy jest praktyczny efekt: stabilny, sprzętowo generowany sygnał.
Jeżeli chcesz temat pogłębić, sensowne kolejne kroki to:
OCR1A podczas pracy,Jeśli chcesz, mogę w następnym kroku dopisać jeszcze:
Najkrócej: idea użycia sprzętowego timera jest poprawna, ale przytoczony kod trzeba poprawić pod ATtiny2313A. Dla prostokąta 50% najlepszy jest Timer1 w CTC + toggle OC1A na PB3 + OCR1A jako TOP. Jeśli potrzebujesz regulowanego wypełnienia, przechodzisz na PWM. Błędy, które trzeba bezwzględnie usunąć, to błędne przypisanie pinu OC1B oraz błędne traktowanie OCR1B jako rejestru ustalającego częstotliwość w CTC mode 4. (ww1.microchip.com)
Jeżeli chcesz, przygotuję teraz drugą wersję odpowiedzi: tylko gotowy kod C i ASM bez objaśnień, od razu do wklejenia do projektu.
Chcę aby zmiana polaryzacji była co 64 sekund ,50% duty , z kwarcem zegarkowym 32.768 KHz , chba on jest najbardziej odpowiedni , chba że znasz lepszy .
Tak — kwarc zegarkowy 32,768 kHz jest bardzo dobrym, a w praktyce najwygodniejszym wyborem do uzyskania zmiany stanu co 64 s przy 50% duty.
Kluczowe punkty:
Jeżeli używasz ATtiny2313A, to najlepsza praktyczna metoda to:
Masz wymaganie:
To trzeba rozumieć tak:
Zatem pełny okres wynosi:
[
T = 64\ \text{s} + 64\ \text{s} = 128\ \text{s}
]
A częstotliwość sygnału wyjściowego:
[
f_{out} = \frac{1}{128}\ \text{Hz}
]
Częstotliwość zegarkowa:
[
32768\ \text{Hz} = 2^{15}
]
To jest standard właśnie dlatego, że daje bardzo wygodne dzielenie przez 2.
Jeżeli chcesz przełączenie stanu co 64 s, to liczba impulsów wejściowych między przełączeniami wynosi:
[
32768 \cdot 64 = 2097152 = 2^{21}
]
Czyli:
To jest sytuacja niemal idealna dla:
Jeżeli to ma być na ATtiny2313A, to najbardziej eleganckie rozwiązanie jest takie:
To daje:
Masz dwie wygodne konfiguracje, obie są dokładne.
[
f_{T1} = \frac{32768}{1024} = 32\ \text{Hz}
]
Aby uzyskać przełączenie co 64 s:
[
64 \cdot 32 = 2048
]
W trybie CTC licznik zlicza od 0 do OCR1A, więc:
[
OCR1A = 2048 - 1 = 2047
]
To jest bardzo wygodne ustawienie.
[
f_{T1} = \frac{32768}{64} = 512\ \text{Hz}
]
[
64 \cdot 512 = 32768
]
[
OCR1A = 32767
]
Też idealnie poprawne.
Praktycznie polecam:
bo jest czytelniej i prościej.
Jeżeli rzeczywiście pracujesz na ATtiny2313A, to logika konfiguracji wygląda tak:
#define F_CPU 32768UL
#include <avr/io.h>
static void init_64s_toggle(void)
{
// OC1A jako wyjście
DDRB |= (1 << PB3);
// Timer1: toggle OC1A on compare match
TCCR1A = (1 << COM1A0);
// CTC, preskaler 1024
TCCR1B = (1 << WGM12) | (1 << CS12) | (1 << CS10);
// 64 s na jedno przełączenie
OCR1A = 2047;
}
int main(void)
{
init_64s_toggle();
while (1)
{
// nic nie trzeba robić
}
}
To zadziała poprawnie tylko wtedy, gdy mikrokontroler jest faktycznie taktowany z zewnętrznego kwarcu 32,768 kHz, a fuse bity są ustawione na:
Pojawiła się sugestia użycia asynchronicznego Timer2 z kwarcem zegarkowym. Dla ATtiny2313A to nie jest właściwy kierunek. W praktyce dla tego układu poprawne podejście to:
Czyli w tym konkretnym przypadku lepiej myśleć o:
Jeżeli nie chcesz używać mikrokontrolera, to także da się to zrobić bardzo dobrze.
Wtedy potrzebujesz:
Najważniejsze:
Jeśli chcesz rozwiązanie:
to układ CMOS + kwarc zegarkowy jest dobry, ale:
To jest bardzo ważne rozróżnienie.
Jeżeli potrzebujesz tylko sygnału logicznego:
Jeżeli potrzebujesz rzeczywistego odwracania polaryzacji na obciążeniu, to sam pin mikrokontrolera nie wystarczy. Wtedy potrzebujesz jeszcze:
Dobór zależy od:
Przykładowo:
W praktyce inżynierskiej nadal stosuje się trzy główne klasy rozwiązań:
| Rozwiązanie | Zaleta | Wada | Kiedy wybrać |
|---|---|---|---|
| Kwarc 32,768 kHz + licznik/timer | bardzo prosty, tani, energooszczędny | typowa dokładność zależna od temperatury | większość zastosowań |
| RTC z kompensacją temperatury | bardzo wysoka dokładność | większa cena i złożoność | gdy czas ma być stabilny w szerokim zakresie temperatur |
| Wewnętrzny RC MCU | najmniej elementów | dużo gorsza dokładność | tylko gdy precyzja nie ma znaczenia |
Obecnie standardowe podejście jest takie:
Dla Twojego wymagania 64 s / 50% duty:
Typowy kwarc zegarkowy ma np. około ±20 ppm.
To oznacza błąd rzędu:
[
64\ \text{s} \cdot 20 \cdot 10^{-6} = 1{,}28\ \text{ms}
]
na pojedynczym odcinku 64 s, pomijając wpływ temperatury i starzenia.
W skali doby daje to około:
[
86400\ \text{s} \cdot 20 \cdot 10^{-6} \approx 1{,}7\ \text{s/dobę}
]
Czyli:
Przy 32,768 kHz trzeba pamiętać, że taki rezonator:
Dlatego należy:
Tak, ale tylko w określonym sensie:
W tym przypadku aspekt etyczny jest marginalny, ale technicznie trzeba uwzględnić:
Jeżeli układ pracuje w urządzeniu użytkowym:
To jest rozwiązanie:
Jeżeli chcesz dopracować układ, warto przeanalizować dalej:
Jeśli chcesz, mogę w następnym kroku przygotować jedną z trzech rzeczy:
Tak, 32,768 kHz to właściwy wybór. Do przełączania co 64 s z 50% duty pasuje niemal idealnie, bo daje dokładne dzielenie binarne bez błędu.
Najlepsza praktyczna odpowiedź:
Jeżeli chcesz, mogę od razu narysować Ci konkretny schemat połączeń i podać ustawienia fuse bitów dla ATtiny2313A.
gotowy schemat na ATtiny2313A,
Tak — poniżej masz gotowy, praktyczny schemat bazowy na ATtiny2313A.
Zakładam, że chodzi o układ z kwarcem 32,768 kHz oraz wyjściem PB3/OC1A, które ma zmieniać stan co 64 s. Jeśli Twoim celem jest tylko „goły” mikrokontroler do dalszego projektu, to ten sam schemat stanowi poprawną bazę sprzętową.
Poniżej podaję dwie wersje:
+5V
│
[10k]
│
RESET ────────────┴─────────────── złącze ISP: RESET
│
VCC ───────────────────────────── +5V
GND ───────────────────────────── GND
Między VCC i GND:
C3 = 100 nF ceramiczny, jak najbliżej mikrokontrolera
XTAL1 ─────┬────[ Kwarc 32.768 kHz ]────┬──── XTAL2
│ │
C1 18..22 pF C2 18..22 pF
│ │
GND GND
PB5/MOSI ───────────────────────────── złącze ISP MOSI
PB6/MISO ───────────────────────────── złącze ISP MISO
PB7/SCK ───────────────────────────── złącze ISP SCK
VCC ───────────────────────────── złącze ISP VCC
GND ───────────────────────────── złącze ISP GND
PB3/OC1A ───────────────────────────── wyjście sygnału 64 s / 64 s
| Element | Wartość | Uwagi |
|---|---|---|
| C3 | 100 nF | obowiązkowy kondensator odsprzęgający |
| R1 | 10 kΩ | podciąganie RESET do VCC |
| X1 | 32,768 kHz | kwarc zegarkowy |
| C1, C2 | 18–22 pF | dobra wartość startowa; zależy od CL kwarcu |
| Złącze ISP | 6 pin | do programowania AVR |
Jeżeli na wyjściu ma być realne odwracanie „+ / –” na obciążeniu, dodaj stopień wykonawczy:
PB3/OC1A ──[1k]──B NPN (np. BC337)
C─────────────┬──── cewka przekaźnika ─── +5V
E─────────────┘
│
GND
Dioda równolegle do cewki:
anoda -> kolektor tranzystora
katoda -> +5V
PRZEKAŹNIK DPDT
NC1 o──── GND_obc
COM1 o──── LOAD_A
NO1 o──── +V_obc
NC2 o──── +V_obc
COM2 o──── LOAD_B
NO2 o──── GND_obc
To daje pełne odwrócenie polaryzacji.
Sam pin PB3:
Na podstawie dostarczonych odpowiedzi online najpewniejsze źródło odniesienia dla ATtiny2313A to:
To częstotliwość:
[
32768 = 2^{15}
]
Dzięki temu bardzo wygodnie dzieli się ją przez preskalery i timery.
Przy preskalerze 1024:
[
\frac{32768}{1024} = 32 \text{ Hz}
]
Aby uzyskać przełączenie co 64 s:
[
32 \cdot 64 = 2048
]
Zatem:
[
OCR1A = 2048 - 1 = 2047
]
Dla PB3/OC1A:
To daje:
W jednej z przykładowych odpowiedzi padło 33 pF, ale dla typowego kwarcu zegarkowego to bywa zbyt dużo.
Praktycznie zalecam:
Przybliżenie:
[
CL \approx \frac{C1 \cdot C2}{C1 + C2} + C{stray}
]
Dla 22 pF i typowych pojemności pasożytniczych układ zwykle pracuje poprawnie.
Najbezpieczniej projektować po nazwach sygnałów:
Numeracja zależy od obudowy i biblioteki EDA, więc przed wykonaniem PCB trzeba ją zweryfikować z notą katalogową dla konkretnej wersji: PU / SU / MU / MMH.
W elektronice użytkowej i przemysłowej trzeba uwzględnić:
Jeżeli układ ma być częścią urządzenia komercyjnego:
Przy przełączaniu co 64 s:
To oznacza, że dla przekaźnika mechanicznego trwałość staje się realnym parametrem projektowym.
Tu trzeba wprost skorygować rozbieżność z przykładowych odpowiedzi.
Dla pracy z kwarcem 32,768 kHz Low-Frequency Crystal:
Rozumowanie:
To daje:
[
1110\,0110_2 = 0xE6
]
#define F_CPU 32768UL
#include <avr/io.h>
int main(void)
{
DDRB |= (1 << PB3); // PB3/OC1A jako wyjście
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
OCR1A = 2047; // 64 s przy 32.768 kHz i /1024
TCCR1A = (1 << COM1A0); // toggle OC1A on compare match
TCCR1B = (1 << WGM12) // CTC
| (1 << CS12)
| (1 << CS10); // preskaler 1024
while (1)
{
// opcjonalnie sleep
}
}
Twoje pytanie jest bardzo krótkie:
„gotowy schemat na ATtiny2313A”.
To może oznaczać kilka rzeczy:
Dlatego podałem wariant najbardziej użyteczny: pełny schemat bazowy + wersję wykonawczą.
Jeśli układ ma pracować latami i bezgłośnie, lepiej zamiast przekaźnika dać:
Jeżeli chcesz rozwinąć projekt, sensowne następne kroki to:
Najprostszy gotowy schemat na ATtiny2313A powinien zawierać:
Jeśli chcesz naprawdę odwracać polaryzację obciążenia, dołóż:
Najważniejsza korekta techniczna: dla tej konfiguracji poprawny low fuse to 0xE6.
Jeżeli chcesz, mogę Ci w następnym kroku przygotować: