From 64a011b4cc321c654c5040d935c6325d95229f35 Mon Sep 17 00:00:00 2001 From: Sergey Yarkov Date: Sun, 15 Oct 2023 19:32:55 +0300 Subject: [PATCH] =?UTF-8?q?Create=20=D0=BF=D1=83=D0=B1=D0=BB=D0=B8=D0=BA?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D1=8E=20=E2=80=9C=D1=80=D0=B5=D0=B0=D0=BB?= =?UTF-8?q?=D0=B8=D0=B7=D0=B0=D1=86=D0=B8=D1=8F-=D0=B7=D0=B0=D0=B4=D0=B5?= =?UTF-8?q?=D1=80=D0=B6=D0=B5=D0=BA-=D0=B2-avr-=D0=BC=D0=B8=D0=BA=D1=80?= =?UTF-8?q?=D0=BE=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D0=BB=D0=B5?= =?UTF-8?q?=D1=80=D0=B5=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡ-Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ-Π²-avr-ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π΅.md | 609 ++++++++++++++++++ ...΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΡ-Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ-Π²-avr-ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π΅.md | 607 +++++++++++++++++ 2 files changed, 1216 insertions(+) create mode 100644 src/content/blog/en/рСализация-Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ-Π²-avr-ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π΅.md create mode 100644 src/content/blog/ru/рСализация-Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ-Π²-avr-ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π΅.md diff --git a/src/content/blog/en/рСализация-Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ-Π²-avr-ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π΅.md b/src/content/blog/en/рСализация-Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ-Π²-avr-ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π΅.md new file mode 100644 index 0000000..8a1eea1 --- /dev/null +++ b/src/content/blog/en/рСализация-Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ-Π²-avr-ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π΅.md @@ -0,0 +1,609 @@ +--- +coverImage: null +draft: true +author: Π‘Π΅Ρ€Π³Π΅ΠΉ Π―Ρ€ΠΊΠΎΠ² +title: РСализация Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ Π² AVR ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π΅ +description: ΠžΡ‡Π΅Π½ΡŒ часто Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°Ρ… приходится Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΡƒ. НапримСр + ΠΏΡ€ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΊΠ°ΠΊΠΎΠ³ΠΎ Π»ΠΈΠ±ΠΎ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π² точности Π²Ρ‹Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ + Ρ‚Π°ΠΉΠΌΠΈΠ½Π³ΠΈ, ΠΈΠ»ΠΈ ΠΆΠ΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΊΠ°ΠΊΡƒΡŽ Π»ΠΈΠ±ΠΎ Π»ΠΎΠ³ΠΈΠΊΡƒ Ρ€Π°Π· Π² нСсколько часов + ΠΈΠ»ΠΈ Π΄Π½Π΅ΠΉ. Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ рассмотрСны нСсколько способов Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ. +tags: + - AVR + - Tutorial +pubDate: 2023-10-15T16:28:52.587Z +updatedDate: 2023-10-15T16:28:52.601Z +--- +## Бпособы Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ + +БущСствуСт Π΄Π²Π° способа ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΡƒ - это ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Π½Ρ‹Π΅ **Ρ‚Π°ΠΉΠΌΠ΅Ρ€Ρ‹** ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° ΠΈΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ простой **Ρ†ΠΈΠΊΠ»** ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ выполняСтся ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ количСство Ρ‚Π°ΠΊΡ‚ΠΎΠ². ΠŸΡ€Π΅ΠΈΠΌΡƒΡ‰Π΅ΡΡ‚Π²ΠΎ использования Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π° ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° ΠΏΠ΅Ρ€Π΅Π΄ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΌ Ρ†ΠΈΠΊΠ»ΠΎΠΌ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π·Π° счСт Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎ Ρ€Π°Π±ΠΎΡ‚Π° Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π°-счСтчика Π½Π΅ зависит ΠΎΡ‚ выполнСния основной ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Но ΠΈΠ½ΠΎΠ³Π΄Π° Π½ΡƒΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΡƒ всСго Π² нСсколько микросСкунд, Ρ‡Ρ‚ΠΎ особо Π½Π΅ повлияСт Π½Π° Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… случаях, Ρ‚ΠΎΠ³Π΄Π° ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π² сторону простых Ρ†ΠΈΠΊΠ»ΠΎΠ². Π‘ΡƒΠ΄Π΅Ρ‚ рассмотрСн Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΠΈ с Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ Π² нСсколько часов ΠΈΠ»ΠΈ Π΄Π½Π΅ΠΉ. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π±ΡƒΠ΄ΡƒΡ‚ прСдставлСны Π½Π° языкС Π‘ΠΈ ΠΈ АссСмблСра для ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° AVR ATtiny45v. Π’ качСствС основной ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π±ΡƒΠ΄Π΅Ρ‚ ΠΌΠΎΡ€Π³Π°ΡŽΡ‰ΠΈΠΉ свСтодиод ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Ρ€Π°Π· Π² 0.5 сСкунд. + +## Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Ρ†ΠΈΠΊΠ» + +Для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ этого способа Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ для Π½Π°Ρ‡Π°Π»Π° Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΊΠΎΠ»-Π²ΠΎ Ρ‚Π°ΠΊΡ‚ΠΎΠ² процСссора для выполнСния Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ Π² N сСкунд ΠΈ Π·Π°Ρ‚Π΅ΠΌ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ†ΠΈΠΊΠ». НапримСр для МК с частотой Π² 8MHz ΠΎΠ΄ΠΈΠ½ Ρ‚Π°ΠΊΡ‚ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π²Π΅Π½ 1/8 = 0.125uS. Π—Π½Π°Ρ‡ΠΈΡ‚ Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π°ΡΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΊΠΎΠ»-Π²ΠΎ Ρ‚Π°ΠΊΡ‚ΠΎΠ² Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π² 0.5 сСкунд Ρ‚ΠΎ это Π±ΡƒΠ΄Π΅Ρ‚ (0.5 *1,000,000)* 8 = 4,000,000 Ρ‚Π°ΠΊΡ‚ΠΎΠ², Ρ‚.Π΅ ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Π° ΠΎΡ‚ частоты МК. + +РСализация Ρ†ΠΈΠΊΠ»Π° Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ Π½Π° ассСмблСрС: + +```asm +.MACRO delay16 + ldi delay8_r, LOW(@0 * F_CPU / 4 - 3) ; 1 + ldi delay16_r, HIGH(@0 * F_CPU / 4 - 3) ; 1 + rcall DELAY16_LOOP ; 3 +.ENDMACRO + +DELAY16_LOOP: + subi delay8_r, 1 ; 1 + sbci delay16_r, 0 ; 1 + brcc DELAY16_LOOP ; 1 = false, 2 = true + ret ; 4 +``` + +КаТдая инструкция Π² ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π΅ выполняСтся Π·Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ ΠΊΠΎΠ»-Π²ΠΎ Ρ‚Π°ΠΊΡ‚ΠΎΠ² (ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ Π² ΠΊΠΎΠ΄Π΅ Π²Ρ‹ΡˆΠ΅). НапримСр инструкция **ldi** выполняСтся Π·Π° ΠΎΠ΄ΠΈΠ½ Ρ‚Π°ΠΊΡ‚, Π° инструкция **brcc** выполняСтся Π·Π° Π΄Π²Π° Ρ‚Π°ΠΊΡ‚Π° - ΠΊΠΎΠ³Π΄Π° условиС Π²Π΅Ρ€Π½ΠΎ ΠΈ Π·Π° ΠΎΠ΄ΠΈΠ½ Ρ‚Π°ΠΊΡ‚ ΠΊΠΎΠ³Π΄Π° условиС Π½Π΅Π²Π΅Ρ€Π½ΠΎ. На ΠΊΠΎΠ»-Π²ΠΎ Ρ‚Π°ΠΊΡ‚ΠΎΠ² Ρ‚Π°ΠΊ ΠΆΠ΅ влияСт ΠΈ Ρ€Π°Π·Ρ€ΡΠ΄Π½ΠΎΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ счСтчика (см. [AVR Instruction Set](http://ww1.microchip.com/downloads/en/devicedoc/atmel-0856-avr-instruction-set-manual.pdf)). + +### ПояснСния ΠΊ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ + +Π’ Π΄Π°Π½Π½ΠΎΠΉ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ макрос **delay16** ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ ΠΊΠΎΠ»-Π²ΠΎ Ρ‚Π°ΠΊΡ‚ΠΎΠ² Π² Π΄Π²Π° 8-ΠΌΠΈ Π±ΠΈΡ‚Π½Ρ‹Ρ… рСгистра ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Ρ‹ ΠΊΠ°ΠΊ младший ΠΈ ΡΡ‚Π°Ρ€ΡˆΠΈΠΉ. Π—Π°Ρ‚Π΅ΠΌ вызываСтся ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° выполнСния Ρ†ΠΈΠΊΠ»Π°. Π—Π°Ρ‡Π΅ΠΌ Π½ΡƒΠΆΠ½ΠΎ Π² расчСтС Ρ‚Π°ΠΊΡ‚ΠΎΠ² Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠ΅ число Π½Π° 4? ΠŸΠΎΡΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ Π½Π° ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ **DELAY16_LOOP** которая выполняСт Π΄Π΅ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ 16-Ρ‚ΠΈ Π±ΠΈΡ‚Π½ΠΎΠ³ΠΎ числа, Π²Ρ‹ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅ Ρ‡Ρ‚ΠΎ ΠΎΠ΄Π½Π° итСрация Ρ†ΠΈΠΊΠ»Π° Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ 4 Ρ‚Π°ΠΊΡ‚Π°. ΠžΡ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠ³ΠΎ числа ΠΎΡ‚Π½ΠΈΠΌΠ°Π΅ΠΌ 3 для компСнсации Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ. + +Π’ ΠΈΡ‚ΠΎΠ³Π΅ максимальная Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ° которая ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒΡΡ ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ МК Π² 8MHz Π²Ρ‹Π·Π²Π°Π² этот макрос равняСтся 65535/8 *4 = 32767.5uS Ρ‡Ρ‚ΠΎ Π½Π΅ совсСм ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для мигания свСтодиодом. Π§Ρ‚ΠΎ Π±Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΡƒ дольшо ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ 24 Π±ΠΈΡ‚Π° для хранСния ΠΊΠΎΠ»-Π²Π° Ρ‚Π°ΠΊΡ‚ΠΎΠ². Π’ΠΎΠ³Π΄Π° максимальная Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ° составит 16,777,216/8* 5 = 10.48сСк. Π’ ΠΈΡ‚ΠΎΠ³Π΅ получаСтся такая ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° с ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‰ΠΈΠΌΡΡ свСтодиодом Ρ€Π°Π· Π² 0.5 сСкунд: + +```asm +.EQU F_CPU = 8 ; MHz + +.DEF t1 = r16 +.DEF t2 = r17 +.DEF delay24_r = r18 +.DEF delay16_r = r19 +.DEF delay8_r = r20 + +.EQU LED_DDR = DDRB +.EQU LED_PORT = PORTB +.EQU LED_PIN_DATA = PINB +.EQU LED_PIN = PB0 + +.MACRO delay24 + ldi delay8_r, LOW(@0 * F_CPU / 5 - 3) + ldi delay16_r, HIGH(@0 * F_CPU / 5 - 3) + ldi delay24_r, BYTE3(@0 * F_CPU / 5 - 3) + rcall DELAY24_LOOP +.ENDMACRO + +.CSEG + +.ORG 0x00 + rjmp RESET_vect + +RESET_vect: + ldi t1, LOW(RAMEND) + out SPL, t1 + +INIT: + ldi t1, (1< +#include + +#define PIN_LED PB0 + +int main(void) { + DDRB |= _BV(PIN_LED); + PORTB = 0x00; + for(;;) { + _delay_ms(500); + PORTB ^= _BV(PIN_LED); + } + return 0; +} +``` + +Π’Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡ†ΠΈΡŽ: + +```c +avr-gcc -Wall -mmcu=attiny45 -Os main.c +avr-objcopy -j .text -j .data -O ihex a.out main.hex +``` + +## Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Ρ‹ + +Π§Ρ‚ΠΎ Ссли ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ Π·Π°Ρ‚Ρ€Π°Ρ‡ΠΈΠ²Π°Ρ‚ΡŒ процСссорноС врСмя Π½Π° Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Ρ†ΠΈΠΊΠ»Π° Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ? Как ΠΎΡ‚ΠΌΠ΅Ρ‡Π°Π»ΠΎΡΡŒ Ρ€Π°Π½Π΅Π΅ Ρ€Π°Π±ΠΎΡ‚Π° Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π°-счСтчика Π½Π΅ зависит ΠΎΡ‚ выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Π‘Ρ‡Π΅Ρ‚Ρ‡ΠΈΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ Ρ…ΠΎΡ‚ΡŒ Ρ€Π°Π· Π² сСкунду ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ процСссора с частотой Π² 8MHz. БущСствуСт нСсколько способов ΠΊΠ°ΠΊ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΡƒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ 8-ΠΌΠΈ ΠΈΠ»ΠΈ 16-Ρ‚ΠΈ Π±ΠΈΡ‚Π½Ρ‹Π΅ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Ρ‹. Π― ΠΎΠΏΠΈΡˆΡƒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠ· Π½ΠΈΡ…. + +### 8-ΠΌΠΈ Π±ΠΈΡ‚Π½Ρ‹ΠΉ Ρ‚Π°ΠΉΠΌΠ΅Ρ€ с ΠΏΡ€Π΅Π΄Π΄Π΅Π»ΠΈΡ‚Π΅Π»Π΅ΠΌ 16384 + +Для ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° ATtiny45v ΠΈΠΌΠ΅ΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ 8-ΠΌΠΈ Π±ΠΈΡ‚Π½Ρ‹Π΅ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Ρ‹, ΠΏΡ€ΠΈΡ‡Π΅ΠΌ Ρƒ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· Π½ΠΈΡ… (TIMER1) имССтся Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΡŒ частоты Π½Π° 16384 Ρ‡Ρ‚ΠΎ ΠΎΡ‡Π΅Π½ΡŒ ΡƒΠ΄ΠΎΠ±Π½ΠΎ: + +![Π’Π°Π±Π»ΠΈΡ†Π° Π²Ρ‹Π±ΠΎΡ€Π° прСддСлитСля для Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π° 1](/media/screen-3.png "Π’Π°Π±Π»ΠΈΡ†Π° Π²Ρ‹Π±ΠΎΡ€Π° прСддСлитСля для Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π° 1") + +Π’Π°Π±Π»ΠΈΡ†Π° Π²Ρ‹Π±ΠΎΡ€Π° прСддСлитСля + +Π‘ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Π°ΠΉΠΌΠ΅Ρ€ Π² CTC (Clear on Timer Compare match) Ρ€Π΅ΠΆΠΈΠΌΠ΅. Π˜Ρ‚ΠΎΠ³ΠΎΠ²Π°Ρ частота Ρ€Π°Π±ΠΎΡ‚Ρ‹ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π°-счСтчика Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π²Π½Π°: 8MHz/16384 = 488.28Hz. Один Ρ‚ΠΈΠΊ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π° Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π²Π½ΡΡ‚ΡŒΡΡ 1/488.28 = 2048uS. Π—Π½Π°Ρ‡ΠΈΡ‚ для 0.5 сСкунд Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π²Π½ΡΡ‚ΡŒΡΡ 0.5*488.38 = 244.14 Ρ‚ΠΈΠΊΠΎΠ² Ρ‡Ρ‚ΠΎ достаточно для 8-Π±ΠΈΡ‚. Π‘ΡƒΠ΄Π΅ΠΌ Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ число Π² рСгистр сравнСния OCRn ΠΈ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π½ΠΈΠ΅ ΠΏΡ€ΠΈ совпадСнии. + +ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π½Π° ассСмблСрС: + +```nasm +.DEF t1 = r16 +.DEF t2 = r17 + +.EQU LED_DDR = DDRB +.EQU LED_PORT = PORTB +.EQU LED_PIN_DATA = PINB +.EQU LED_PIN = PB0 + +.CSEG + +.ORG 0x00 + rjmp RESET_vect + +.ORG 0x03 + rjmp TIMER1_COMPA + +RESET_vect: + ldi t1, LOW(RAMEND) + out SPL, t1 + +INIT: + ldi t1, (1< +#include + +#define LED_DDR DDRB +#define LED_PORT PORTB +#define LED_PIN_DATA PINB +#define LED_PIN PB0 + +/* + * Timer Counter 1 + * Mode: CTC + * Prescaler: 16384 + */ +void setup_tc1(void) { + TCCR1 |= _BV(CTC1) | _BV(CS13) | _BV(CS12) | _BV(CS11) | _BV(CS10); + TCNT1 = 0x00; + OCR1A = 244; + OCR1C = 244; + TIMSK |= _BV(OCIE1A); +} + +void setup_ports(void) { + DDRB |= _BV(LED_PIN); + PORTB = 0x00; +} + +/* + * Interrupt every 0.5 sec + */ +ISR(TIMER1_COMPA_vect) { + LED_PORT ^= _BV(LED_PIN); +} + +void system_init(void) { + setup_ports(); + setup_tc1(); + sei(); +} + +int main(void) { + system_init(); + for (;;) { + asm("nop"); + } + return 0; +} +``` + +### 8-ΠΌΠΈ Π±ΠΈΡ‚Π½Ρ‹ΠΉ Ρ‚Π°ΠΉΠΌΠ΅Ρ€ с ΠΏΡ€Π΅Π΄Π΄Π΅Π»ΠΈΡ‚Π΅Π»Π΅ΠΌ 1024 + +Π§Ρ‚ΠΎ Ссли доступСн ΠΏΡ€Π΅Π΄Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΡŒ частоты Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π° 1024? Π’ΠΎΠ³Π΄Π° рСгистр для сравнСния OCRn Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π²Π½ΡΡ‚ΡŒΡΡ 3906, Ρ‡Ρ‚ΠΎ Π½Π΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для 8-ΠΌΠΈ Π±ΠΈΡ‚Π½ΠΎΠ³ΠΎ рСгистра. Как Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΠΌΠΎΠΆΠ½ΠΎ ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ количСство ΠΏΠ΅Ρ€Π΅ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΉ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π°. 3906.25/255 = 15 ΠΏΠ΅Ρ€Π΅ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΉ. + +ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π½Π° ассСмблСрС: + +```nasm +.DEF t1 = r16 +.DEF t2 = r17 +.DEF tc1_ovf_cnt = r18 + +.EQU LED_DDR = DDRB +.EQU LED_PORT = PORTB +.EQU LED_PIN_DATA = PINB +.EQU LED_PIN = PB0 + +.EQU TC1_OVF_COMPARE_VAL = 15 + +.CSEG + +.ORG 0x00 + rjmp RESET_vect + +.ORG 0x04 + rjmp TIMER1_OVF + +RESET_vect: + ldi t1, LOW(RAMEND) + out SPL, t1 + +INIT: + ldi t1, (1< +#include + +#define TC1_OVF_COMPARE_VAL 15 + +#define LED_DDR DDRB +#define LED_PORT PORTB +#define LED_PIN_DATA PINB +#define LED_PIN PB0 + +static volatile uint8_t tc1_ovf_cnt = 0; + +/* + * Timer Counter 1 + * Mode: Normal + * Prescaler: 1024 + */ +void setup_tc1(void) { + TCCR1 |= _BV(CS13) | _BV(CS11) | _BV(CS10); + TCNT1 = 0x00; + TIMSK |= _BV(TOIE1); +} + +void setup_ports(void) { + DDRB |= _BV(LED_PIN); + PORTB = 0x00; +} + +ISR(TIMER1_OVF_vect) { + tc1_ovf_cnt++; + if (tc1_ovf_cnt == TC1_OVF_COMPARE_VAL) { + LED_PORT ^= _BV(LED_PIN); + tc1_ovf_cnt = 0; + } +} + +void system_init(void) { + setup_ports(); + setup_tc1(); + sei(); +} + +int main(void) { + system_init(); + for (;;) { + asm("nop"); + } + return 0; +} +``` + +### Π”Π»ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ° + +Π‘Ρ‹Π²Π°ΡŽΡ‚ случаи ΠΊΠΎΠ³Π΄Π° Π½ΡƒΠΆΠ½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΊΠ°ΠΊΡƒΡŽ Π»ΠΈΠ±ΠΎ Π»ΠΎΠ³ΠΈΠΊΡƒ Ρ€Π°Π· Π² нСсколько часов ΠΈΠ»ΠΈ Π΄Π½Π΅ΠΉ. РСшСниСм являСтся завСсти Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Π³Π΄Π΅ Π±ΡƒΠ΄Π΅ΠΌ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ количСство ΠΏΡ€ΠΎΡˆΠ΅Π΄ΡˆΠΈΡ… сСкунд с ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° Π½Π°Ρ‡Π°Π»Π° отсчСта Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π°, Π° Π² ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π½ΠΈΠΈ пСрСполнСния Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π° Π±ΡƒΠ΄Π΅ΠΌ ΡƒΠΆΠ΅ ΡΡ€Π°Π²Π½ΠΈΠ²Π°Ρ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика с Π·Π°Π΄Π°Π½Π½Ρ‹ΠΌ числом. Π‘Π»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ свСтодиод Ρ€Π°Π· Π² 6 часов. + +```nasm +.DEF t1 = r16 +.DEF t2 = r17 +.DEF tc1_ovf_cnt = r18 + +.EQU LED_DDR = DDRB +.EQU LED_PORT = PORTB +.EQU LED_PIN_DATA = PINB +.EQU LED_PIN = PB0 + +.EQU TC1_OVF_COMPARE_VAL = 30 + +.DSEG +.ORG SRAM_START + +ellapsed_seconds: .BYTE 2 + +.CSEG + +.ORG 0x00 + rjmp RESET_vect + +.ORG 0x04 + rjmp TIMER1_OVF + +RESET_vect: + ldi t1, LOW(RAMEND) + out SPL, t1 + +INIT: + ldi t1, (1< +#include + +#define TC1_OVF_COMPARE_VAL 30 + +#define LED_DDR DDRB +#define LED_PORT PORTB +#define LED_PIN_DATA PINB +#define LED_PIN PB0 + +static volatile uint8_t tc1_ovf_cnt = 0; +static volatile uint16_t ellapsed_seconds = 0; + +/* + * Timer Counter 1 + * Mode: Normal + * Prescaler: 1024 + */ +void setup_tc1(void) { + TCCR1 |= _BV(CS13) | _BV(CS11) | _BV(CS10); + TCNT1 = 0x00; + TIMSK |= _BV(TOIE1); +} + +void setup_ports(void) { + DDRB |= _BV(LED_PIN); + PORTB = 0x00; +} + +ISR(TIMER1_OVF_vect) { + tc1_ovf_cnt++; + + if (tc1_ovf_cnt == TC1_OVF_COMPARE_VAL) { + tc1_ovf_cnt = 0; + ellapsed_seconds++; + + /* Every 6 hours */ + if (ellapsed_seconds == 21600) { + LED_PORT ^= _BV(LED_PIN); + ellapsed_seconds = 0; + } + } +} + +void system_init(void) { + setup_ports(); + setup_tc1(); + sei(); +} + +int main(void) { + system_init(); + for (;;) { + asm("nop"); + } + return 0; +} +``` + +## Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ + +РассмотрСны Π΄Π²Π° основных способа Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Ρ‹ ΠΈ Ρ†ΠΈΠΊΠ»Ρ‹. Выяснили Ρ‡Ρ‚ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ‚Π°ΠΉΠΌΠ΅Ρ€-счСтчик ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΡƒ, которая Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ основной ΠΏΠΎΡ‚ΠΎΠΊ выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Для Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ, Π³Π΄Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΡˆΠ΅Π΄ΡˆΠ΅Π΅ врСмя Π² сСкундах ΠΈΠ»ΠΈ часах, ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅. + +## ΠŸΠΎΠ»Π΅Π·Π½Ρ‹Π΅ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Ρ‹ + +* [AVR Instruction Set](https://ww1.microchip.com/downloads/en/devicedoc/atmel-0856-avr-instruction-set-manual.pdf) +* [AVR130: Setup and Use of AVR Timers](https://ww1.microchip.com/downloads/en/Appnotes/Atmel-2505-Setup-and-Use-of-AVR-Timers_ApplicationNote_AVR130.pdf) +* [AVR Delay Loop Calculator](http://darcy.rsgc.on.ca/ACES/TEI4M/AVRdelay.html) +* [AVR Timer Calculator](https://eleccelerator.com/avr-timer-calculator/) \ No newline at end of file diff --git a/src/content/blog/ru/рСализация-Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ-Π²-avr-ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π΅.md b/src/content/blog/ru/рСализация-Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ-Π²-avr-ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π΅.md new file mode 100644 index 0000000..be6e2eb --- /dev/null +++ b/src/content/blog/ru/рСализация-Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ-Π²-avr-ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π΅.md @@ -0,0 +1,607 @@ +--- +author: Π‘Π΅Ρ€Π³Π΅ΠΉ Π―Ρ€ΠΊΠΎΠ² +title: РСализация Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ Π² AVR ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π΅ +description: ΠžΡ‡Π΅Π½ΡŒ часто Π² ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°Ρ… приходится Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΡƒ. НапримСр + ΠΏΡ€ΠΈ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΊΠ°ΠΊΠΎΠ³ΠΎ Π»ΠΈΠ±ΠΎ ΠΏΡ€ΠΎΡ‚ΠΎΠΊΠΎΠ»Π° Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π² точности Π²Ρ‹Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ + Ρ‚Π°ΠΉΠΌΠΈΠ½Π³ΠΈ, ΠΈΠ»ΠΈ ΠΆΠ΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΊΠ°ΠΊΡƒΡŽ Π»ΠΈΠ±ΠΎ Π»ΠΎΠ³ΠΈΠΊΡƒ Ρ€Π°Π· Π² нСсколько часов + ΠΈΠ»ΠΈ Π΄Π½Π΅ΠΉ. Π’ этой ΡΡ‚Π°Ρ‚ΡŒΠ΅ рассмотрСны нСсколько способов Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ. +tags: + - AVR + - Tutorial +pubDate: 2023-10-15T16:28:52.587Z +updatedDate: 2023-10-15T16:28:52.601Z +--- +## Бпособы Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ + +БущСствуСт Π΄Π²Π° способа ΠΊΠ°ΠΊ ΠΌΠΎΠΆΠ½ΠΎ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΡƒ - это ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Π½Ρ‹Π΅ **Ρ‚Π°ΠΉΠΌΠ΅Ρ€Ρ‹** ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° ΠΈΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ простой **Ρ†ΠΈΠΊΠ»** ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ выполняСтся ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ количСство Ρ‚Π°ΠΊΡ‚ΠΎΠ². ΠŸΡ€Π΅ΠΈΠΌΡƒΡ‰Π΅ΡΡ‚Π²ΠΎ использования Π°ΠΏΠΏΠ°Ρ€Π°Ρ‚Π½ΠΎΠ³ΠΎ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π° ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° ΠΏΠ΅Ρ€Π΅Π΄ ΠΎΠ±Ρ‹Ρ‡Π½Ρ‹ΠΌ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½Ρ‹ΠΌ Ρ†ΠΈΠΊΠ»ΠΎΠΌ Π·Π°ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Π² Π½Π΅Π±Π»ΠΎΠΊΠΈΡ€ΡƒΡŽΡ‰Π΅ΠΌ Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΈ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π·Π° счСт Ρ‚ΠΎΠ³ΠΎ Ρ‡Ρ‚ΠΎ Ρ€Π°Π±ΠΎΡ‚Π° Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π°-счСтчика Π½Π΅ зависит ΠΎΡ‚ выполнСния основной ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Но ΠΈΠ½ΠΎΠ³Π΄Π° Π½ΡƒΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΡƒ всСго Π² нСсколько микросСкунд, Ρ‡Ρ‚ΠΎ особо Π½Π΅ повлияСт Π½Π° Ρ€Π°Π±ΠΎΡ‚Ρƒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π² Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… случаях, Ρ‚ΠΎΠ³Π΄Π° ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π² сторону простых Ρ†ΠΈΠΊΠ»ΠΎΠ². Π‘ΡƒΠ΄Π΅Ρ‚ рассмотрСн Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΠΈ с Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ Π² нСсколько часов ΠΈΠ»ΠΈ Π΄Π½Π΅ΠΉ. ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π±ΡƒΠ΄ΡƒΡ‚ прСдставлСны Π½Π° языкС Π‘ΠΈ ΠΈ АссСмблСра для ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° AVR ATtiny45v. Π’ качСствС основной ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π±ΡƒΠ΄Π΅Ρ‚ ΠΌΠΎΡ€Π³Π°ΡŽΡ‰ΠΈΠΉ свСтодиод ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ΡΡ Ρ€Π°Π· Π² 0.5 сСкунд. + +## Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Ρ†ΠΈΠΊΠ» + +Для Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ этого способа Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ для Π½Π°Ρ‡Π°Π»Π° Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΊΠΎΠ»-Π²ΠΎ Ρ‚Π°ΠΊΡ‚ΠΎΠ² процСссора для выполнСния Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ Π² N сСкунд ΠΈ Π·Π°Ρ‚Π΅ΠΌ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Ρ†ΠΈΠΊΠ». НапримСр для МК с частотой Π² 8MHz ΠΎΠ΄ΠΈΠ½ Ρ‚Π°ΠΊΡ‚ Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π²Π΅Π½ 1/8 = 0.125uS. Π—Π½Π°Ρ‡ΠΈΡ‚ Ρ‡Ρ‚ΠΎΠ±Ρ‹ Ρ€Π°ΡΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ ΠΊΠΎΠ»-Π²ΠΎ Ρ‚Π°ΠΊΡ‚ΠΎΠ² Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ Π² 0.5 сСкунд Ρ‚ΠΎ это Π±ΡƒΠ΄Π΅Ρ‚ (0.5 *1,000,000)* 8 = 4,000,000 Ρ‚Π°ΠΊΡ‚ΠΎΠ², Ρ‚.Π΅ ΠΏΠΎΠ»ΠΎΠ²ΠΈΠ½Π° ΠΎΡ‚ частоты МК. + +РСализация Ρ†ΠΈΠΊΠ»Π° Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ Π½Π° ассСмблСрС: + +```asm +.MACRO delay16 + ldi delay8_r, LOW(@0 * F_CPU / 4 - 3) ; 1 + ldi delay16_r, HIGH(@0 * F_CPU / 4 - 3) ; 1 + rcall DELAY16_LOOP ; 3 +.ENDMACRO + +DELAY16_LOOP: + subi delay8_r, 1 ; 1 + sbci delay16_r, 0 ; 1 + brcc DELAY16_LOOP ; 1 = false, 2 = true + ret ; 4 +``` + +КаТдая инструкция Π² ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π΅ выполняСтся Π·Π° ΠΎΠΏΡ€Π΅Π΄Π΅Π»Π΅Π½Π½ΠΎΠ΅ ΠΊΠΎΠ»-Π²ΠΎ Ρ‚Π°ΠΊΡ‚ΠΎΠ² (ΠΊΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ Π² ΠΊΠΎΠ΄Π΅ Π²Ρ‹ΡˆΠ΅). НапримСр инструкция **ldi** выполняСтся Π·Π° ΠΎΠ΄ΠΈΠ½ Ρ‚Π°ΠΊΡ‚, Π° инструкция **brcc** выполняСтся Π·Π° Π΄Π²Π° Ρ‚Π°ΠΊΡ‚Π° - ΠΊΠΎΠ³Π΄Π° условиС Π²Π΅Ρ€Π½ΠΎ ΠΈ Π·Π° ΠΎΠ΄ΠΈΠ½ Ρ‚Π°ΠΊΡ‚ ΠΊΠΎΠ³Π΄Π° условиС Π½Π΅Π²Π΅Ρ€Π½ΠΎ. На ΠΊΠΎΠ»-Π²ΠΎ Ρ‚Π°ΠΊΡ‚ΠΎΠ² Ρ‚Π°ΠΊ ΠΆΠ΅ влияСт ΠΈ Ρ€Π°Π·Ρ€ΡΠ΄Π½ΠΎΡΡ‚ΡŒ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ½ΠΎΠ³ΠΎ счСтчика (см. [AVR Instruction Set](http://ww1.microchip.com/downloads/en/devicedoc/atmel-0856-avr-instruction-set-manual.pdf)). + +### ПояснСния ΠΊ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ + +Π’ Π΄Π°Π½Π½ΠΎΠΉ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ макрос **delay16** ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Π·Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ ΠΊΠΎΠ»-Π²ΠΎ Ρ‚Π°ΠΊΡ‚ΠΎΠ² Π² Π΄Π²Π° 8-ΠΌΠΈ Π±ΠΈΡ‚Π½Ρ‹Ρ… рСгистра ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΏΠΎΠΌΠ΅Ρ‡Π΅Π½Ρ‹ ΠΊΠ°ΠΊ младший ΠΈ ΡΡ‚Π°Ρ€ΡˆΠΈΠΉ. Π—Π°Ρ‚Π΅ΠΌ вызываСтся ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° выполнСния Ρ†ΠΈΠΊΠ»Π°. Π—Π°Ρ‡Π΅ΠΌ Π½ΡƒΠΆΠ½ΠΎ Π² расчСтС Ρ‚Π°ΠΊΡ‚ΠΎΠ² Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠ΅ число Π½Π° 4? ΠŸΠΎΡΠΌΠΎΡ‚Ρ€ΠΈΡ‚Π΅ Π½Π° ΠΏΠΎΠ΄ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡƒ **DELAY16_LOOP** которая выполняСт Π΄Π΅ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ 16-Ρ‚ΠΈ Π±ΠΈΡ‚Π½ΠΎΠ³ΠΎ числа, Π²Ρ‹ ΡƒΠ²ΠΈΠ΄ΠΈΡ‚Π΅ Ρ‡Ρ‚ΠΎ ΠΎΠ΄Π½Π° итСрация Ρ†ΠΈΠΊΠ»Π° Π·Π°Π½ΠΈΠΌΠ°Π΅Ρ‚ 4 Ρ‚Π°ΠΊΡ‚Π°. ΠžΡ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π½ΠΎΠ³ΠΎ числа ΠΎΡ‚Π½ΠΈΠΌΠ°Π΅ΠΌ 3 для компСнсации Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ. + +Π’ ΠΈΡ‚ΠΎΠ³Π΅ максимальная Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ° которая ΠΌΠΎΠΆΠ΅Ρ‚ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒΡΡ ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ МК Π² 8MHz Π²Ρ‹Π·Π²Π°Π² этот макрос равняСтся 65535/8 *4 = 32767.5uS Ρ‡Ρ‚ΠΎ Π½Π΅ совсСм ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для мигания свСтодиодом. Π§Ρ‚ΠΎ Π±Ρ‹ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΡƒ дольшо ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ 24 Π±ΠΈΡ‚Π° для хранСния ΠΊΠΎΠ»-Π²Π° Ρ‚Π°ΠΊΡ‚ΠΎΠ². Π’ΠΎΠ³Π΄Π° максимальная Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ° составит 16,777,216/8* 5 = 10.48сСк. Π’ ΠΈΡ‚ΠΎΠ³Π΅ получаСтся такая ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° с ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°ΡŽΡ‰ΠΈΠΌΡΡ свСтодиодом Ρ€Π°Π· Π² 0.5 сСкунд: + +```asm +.EQU F_CPU = 8 ; MHz + +.DEF t1 = r16 +.DEF t2 = r17 +.DEF delay24_r = r18 +.DEF delay16_r = r19 +.DEF delay8_r = r20 + +.EQU LED_DDR = DDRB +.EQU LED_PORT = PORTB +.EQU LED_PIN_DATA = PINB +.EQU LED_PIN = PB0 + +.MACRO delay24 + ldi delay8_r, LOW(@0 * F_CPU / 5 - 3) + ldi delay16_r, HIGH(@0 * F_CPU / 5 - 3) + ldi delay24_r, BYTE3(@0 * F_CPU / 5 - 3) + rcall DELAY24_LOOP +.ENDMACRO + +.CSEG + +.ORG 0x00 + rjmp RESET_vect + +RESET_vect: + ldi t1, LOW(RAMEND) + out SPL, t1 + +INIT: + ldi t1, (1< +#include + +#define PIN_LED PB0 + +int main(void) { + DDRB |= _BV(PIN_LED); + PORTB = 0x00; + for(;;) { + _delay_ms(500); + PORTB ^= _BV(PIN_LED); + } + return 0; +} +``` + +Π’Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ ΠΊΠΎΠΌΠΏΠΈΠ»ΡΡ†ΠΈΡŽ: + +```c +avr-gcc -Wall -mmcu=attiny45 -Os main.c +avr-objcopy -j .text -j .data -O ihex a.out main.hex +``` + +## Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Ρ‹ + +Π§Ρ‚ΠΎ Ссли ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Π½Π΅ Π½ΡƒΠΆΠ½ΠΎ Π·Π°Ρ‚Ρ€Π°Ρ‡ΠΈΠ²Π°Ρ‚ΡŒ процСссорноС врСмя Π½Π° Π²Ρ‹ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ Ρ†ΠΈΠΊΠ»Π° Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ? Как ΠΎΡ‚ΠΌΠ΅Ρ‡Π°Π»ΠΎΡΡŒ Ρ€Π°Π½Π΅Π΅ Ρ€Π°Π±ΠΎΡ‚Π° Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π°-счСтчика Π½Π΅ зависит ΠΎΡ‚ выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Π‘Ρ‡Π΅Ρ‚Ρ‡ΠΈΠΊ ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒΡΡ Ρ…ΠΎΡ‚ΡŒ Ρ€Π°Π· Π² сСкунду ΠΏΡ€ΠΈ Ρ€Π°Π±ΠΎΡ‚Π΅ процСссора с частотой Π² 8MHz. БущСствуСт нСсколько способов ΠΊΠ°ΠΊ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΡƒ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ 8-ΠΌΠΈ ΠΈΠ»ΠΈ 16-Ρ‚ΠΈ Π±ΠΈΡ‚Π½Ρ‹Π΅ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Ρ‹. Π― ΠΎΠΏΠΈΡˆΡƒ Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΈΠ· Π½ΠΈΡ…. + +### 8-ΠΌΠΈ Π±ΠΈΡ‚Π½Ρ‹ΠΉ Ρ‚Π°ΠΉΠΌΠ΅Ρ€ с ΠΏΡ€Π΅Π΄Π΄Π΅Π»ΠΈΡ‚Π΅Π»Π΅ΠΌ 16384 + +Для ΠΌΠΈΠΊΡ€ΠΎΠΊΠΎΠ½Ρ‚Ρ€ΠΎΠ»Π»Π΅Ρ€Π° ATtiny45v ΠΈΠΌΠ΅ΡŽΡ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ 8-ΠΌΠΈ Π±ΠΈΡ‚Π½Ρ‹Π΅ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Ρ‹, ΠΏΡ€ΠΈΡ‡Π΅ΠΌ Ρƒ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΈΠ· Π½ΠΈΡ… (TIMER1) имССтся Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΡŒ частоты Π½Π° 16384 Ρ‡Ρ‚ΠΎ ΠΎΡ‡Π΅Π½ΡŒ ΡƒΠ΄ΠΎΠ±Π½ΠΎ: + +![Π’Π°Π±Π»ΠΈΡ†Π° Π²Ρ‹Π±ΠΎΡ€Π° прСддСлитСля для Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π° 1](/media/screen-3.png "Π’Π°Π±Π»ΠΈΡ†Π° Π²Ρ‹Π±ΠΎΡ€Π° прСддСлитСля для Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π° 1") + +Π’Π°Π±Π»ΠΈΡ†Π° Π²Ρ‹Π±ΠΎΡ€Π° прСддСлитСля + +Π‘ΡƒΠ΄Π΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Π°ΠΉΠΌΠ΅Ρ€ Π² CTC (Clear on Timer Compare match) Ρ€Π΅ΠΆΠΈΠΌΠ΅. Π˜Ρ‚ΠΎΠ³ΠΎΠ²Π°Ρ частота Ρ€Π°Π±ΠΎΡ‚Ρ‹ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π°-счСтчика Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π²Π½Π°: 8MHz/16384 = 488.28Hz. Один Ρ‚ΠΈΠΊ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π° Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π²Π½ΡΡ‚ΡŒΡΡ 1/488.28 = 2048uS. Π—Π½Π°Ρ‡ΠΈΡ‚ для 0.5 сСкунд Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π²Π½ΡΡ‚ΡŒΡΡ 0.5*488.38 = 244.14 Ρ‚ΠΈΠΊΠΎΠ² Ρ‡Ρ‚ΠΎ достаточно для 8-Π±ΠΈΡ‚. Π‘ΡƒΠ΄Π΅ΠΌ Π·Π°ΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ число Π² рСгистр сравнСния OCRn ΠΈ Π³Π΅Π½Π΅Ρ€ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π½ΠΈΠ΅ ΠΏΡ€ΠΈ совпадСнии. + +ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π½Π° ассСмблСрС: + +```nasm +.DEF t1 = r16 +.DEF t2 = r17 + +.EQU LED_DDR = DDRB +.EQU LED_PORT = PORTB +.EQU LED_PIN_DATA = PINB +.EQU LED_PIN = PB0 + +.CSEG + +.ORG 0x00 + rjmp RESET_vect + +.ORG 0x03 + rjmp TIMER1_COMPA + +RESET_vect: + ldi t1, LOW(RAMEND) + out SPL, t1 + +INIT: + ldi t1, (1< +#include + +#define LED_DDR DDRB +#define LED_PORT PORTB +#define LED_PIN_DATA PINB +#define LED_PIN PB0 + +/* + * Timer Counter 1 + * Mode: CTC + * Prescaler: 16384 + */ +void setup_tc1(void) { + TCCR1 |= _BV(CTC1) | _BV(CS13) | _BV(CS12) | _BV(CS11) | _BV(CS10); + TCNT1 = 0x00; + OCR1A = 244; + OCR1C = 244; + TIMSK |= _BV(OCIE1A); +} + +void setup_ports(void) { + DDRB |= _BV(LED_PIN); + PORTB = 0x00; +} + +/* + * Interrupt every 0.5 sec + */ +ISR(TIMER1_COMPA_vect) { + LED_PORT ^= _BV(LED_PIN); +} + +void system_init(void) { + setup_ports(); + setup_tc1(); + sei(); +} + +int main(void) { + system_init(); + for (;;) { + asm("nop"); + } + return 0; +} +``` + +### 8-ΠΌΠΈ Π±ΠΈΡ‚Π½Ρ‹ΠΉ Ρ‚Π°ΠΉΠΌΠ΅Ρ€ с ΠΏΡ€Π΅Π΄Π΄Π΅Π»ΠΈΡ‚Π΅Π»Π΅ΠΌ 1024 + +Π§Ρ‚ΠΎ Ссли доступСн ΠΏΡ€Π΅Π΄Π΄Π΅Π»ΠΈΡ‚Π΅Π»ΡŒ частоты Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π½Π° 1024? Π’ΠΎΠ³Π΄Π° рСгистр для сравнСния OCRn Π±ΡƒΠ΄Π΅Ρ‚ Ρ€Π°Π²Π½ΡΡ‚ΡŒΡΡ 3906, Ρ‡Ρ‚ΠΎ Π½Π΅ ΠΏΠΎΠ΄Ρ…ΠΎΠ΄ΠΈΡ‚ для 8-ΠΌΠΈ Π±ΠΈΡ‚Π½ΠΎΠ³ΠΎ рСгистра. Как Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ ΠΌΠΎΠΆΠ½ΠΎ ΡΡ‡ΠΈΡ‚Π°Ρ‚ΡŒ количСство ΠΏΠ΅Ρ€Π΅ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΉ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π°. 3906.25/255 = 15 ΠΏΠ΅Ρ€Π΅ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠΉ. + +ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° Π½Π° ассСмблСрС: + +```nasm +.DEF t1 = r16 +.DEF t2 = r17 +.DEF tc1_ovf_cnt = r18 + +.EQU LED_DDR = DDRB +.EQU LED_PORT = PORTB +.EQU LED_PIN_DATA = PINB +.EQU LED_PIN = PB0 + +.EQU TC1_OVF_COMPARE_VAL = 15 + +.CSEG + +.ORG 0x00 + rjmp RESET_vect + +.ORG 0x04 + rjmp TIMER1_OVF + +RESET_vect: + ldi t1, LOW(RAMEND) + out SPL, t1 + +INIT: + ldi t1, (1< +#include + +#define TC1_OVF_COMPARE_VAL 15 + +#define LED_DDR DDRB +#define LED_PORT PORTB +#define LED_PIN_DATA PINB +#define LED_PIN PB0 + +static volatile uint8_t tc1_ovf_cnt = 0; + +/* + * Timer Counter 1 + * Mode: Normal + * Prescaler: 1024 + */ +void setup_tc1(void) { + TCCR1 |= _BV(CS13) | _BV(CS11) | _BV(CS10); + TCNT1 = 0x00; + TIMSK |= _BV(TOIE1); +} + +void setup_ports(void) { + DDRB |= _BV(LED_PIN); + PORTB = 0x00; +} + +ISR(TIMER1_OVF_vect) { + tc1_ovf_cnt++; + if (tc1_ovf_cnt == TC1_OVF_COMPARE_VAL) { + LED_PORT ^= _BV(LED_PIN); + tc1_ovf_cnt = 0; + } +} + +void system_init(void) { + setup_ports(); + setup_tc1(); + sei(); +} + +int main(void) { + system_init(); + for (;;) { + asm("nop"); + } + return 0; +} +``` + +### Π”Π»ΠΈΡ‚Π΅Π»ΡŒΠ½Π°Ρ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠ° + +Π‘Ρ‹Π²Π°ΡŽΡ‚ случаи ΠΊΠΎΠ³Π΄Π° Π½ΡƒΠΆΠ½ΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΡΡ‚ΡŒ ΠΊΠ°ΠΊΡƒΡŽ Π»ΠΈΠ±ΠΎ Π»ΠΎΠ³ΠΈΠΊΡƒ Ρ€Π°Π· Π² нСсколько часов ΠΈΠ»ΠΈ Π΄Π½Π΅ΠΉ. РСшСниСм являСтся завСсти Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½ΡƒΡŽ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½ΡƒΡŽ Π³Π΄Π΅ Π±ΡƒΠ΄Π΅ΠΌ Ρ…Ρ€Π°Π½ΠΈΡ‚ΡŒ количСство ΠΏΡ€ΠΎΡˆΠ΅Π΄ΡˆΠΈΡ… сСкунд с ΠΌΠΎΠΌΠ΅Π½Ρ‚Π° Π½Π°Ρ‡Π°Π»Π° отсчСта Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π°, Π° Π² ΠΏΡ€Π΅Ρ€Ρ‹Π²Π°Π½ΠΈΠΈ пСрСполнСния Ρ‚Π°ΠΉΠΌΠ΅Ρ€Π° Π±ΡƒΠ΄Π΅ΠΌ ΡƒΠΆΠ΅ ΡΡ€Π°Π²Π½ΠΈΠ²Π°Ρ‚ΡŒ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ счСтчика с Π·Π°Π΄Π°Π½Π½Ρ‹ΠΌ числом. Π‘Π»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ свСтодиод Ρ€Π°Π· Π² 6 часов. + +```nasm +.DEF t1 = r16 +.DEF t2 = r17 +.DEF tc1_ovf_cnt = r18 + +.EQU LED_DDR = DDRB +.EQU LED_PORT = PORTB +.EQU LED_PIN_DATA = PINB +.EQU LED_PIN = PB0 + +.EQU TC1_OVF_COMPARE_VAL = 30 + +.DSEG +.ORG SRAM_START + +ellapsed_seconds: .BYTE 2 + +.CSEG + +.ORG 0x00 + rjmp RESET_vect + +.ORG 0x04 + rjmp TIMER1_OVF + +RESET_vect: + ldi t1, LOW(RAMEND) + out SPL, t1 + +INIT: + ldi t1, (1< +#include + +#define TC1_OVF_COMPARE_VAL 30 + +#define LED_DDR DDRB +#define LED_PORT PORTB +#define LED_PIN_DATA PINB +#define LED_PIN PB0 + +static volatile uint8_t tc1_ovf_cnt = 0; +static volatile uint16_t ellapsed_seconds = 0; + +/* + * Timer Counter 1 + * Mode: Normal + * Prescaler: 1024 + */ +void setup_tc1(void) { + TCCR1 |= _BV(CS13) | _BV(CS11) | _BV(CS10); + TCNT1 = 0x00; + TIMSK |= _BV(TOIE1); +} + +void setup_ports(void) { + DDRB |= _BV(LED_PIN); + PORTB = 0x00; +} + +ISR(TIMER1_OVF_vect) { + tc1_ovf_cnt++; + + if (tc1_ovf_cnt == TC1_OVF_COMPARE_VAL) { + tc1_ovf_cnt = 0; + ellapsed_seconds++; + + /* Every 6 hours */ + if (ellapsed_seconds == 21600) { + LED_PORT ^= _BV(LED_PIN); + ellapsed_seconds = 0; + } + } +} + +void system_init(void) { + setup_ports(); + setup_tc1(); + sei(); +} + +int main(void) { + system_init(); + for (;;) { + asm("nop"); + } + return 0; +} +``` + +## Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ + +РассмотрСны Π΄Π²Π° основных способа Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ‚Π°ΠΉΠΌΠ΅Ρ€Ρ‹ ΠΈ Ρ†ΠΈΠΊΠ»Ρ‹. Выяснили Ρ‡Ρ‚ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡ Ρ‚Π°ΠΉΠΌΠ΅Ρ€-счСтчик ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π·Π°Π΄Π΅Ρ€ΠΆΠΊΡƒ, которая Π½Π΅ Π±ΡƒΠ΄Π΅Ρ‚ Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ основной ΠΏΠΎΡ‚ΠΎΠΊ выполнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹. Для Π΄Π»ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Π·Π°Π΄Π΅Ρ€ΠΆΠ΅ΠΊ, Π³Π΄Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ ΠΎΡ‚ΡΠ»Π΅ΠΆΠΈΠ²Π°Ρ‚ΡŒ ΠΏΡ€ΠΎΡˆΠ΅Π΄ΡˆΠ΅Π΅ врСмя Π² сСкундах ΠΈΠ»ΠΈ часах, ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅. + +## ΠŸΠΎΠ»Π΅Π·Π½Ρ‹Π΅ ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Ρ‹ + +* [AVR Instruction Set](https://ww1.microchip.com/downloads/en/devicedoc/atmel-0856-avr-instruction-set-manual.pdf) +* [AVR130: Setup and Use of AVR Timers](https://ww1.microchip.com/downloads/en/Appnotes/Atmel-2505-Setup-and-Use-of-AVR-Timers_ApplicationNote_AVR130.pdf) +* [AVR Delay Loop Calculator](http://darcy.rsgc.on.ca/ACES/TEI4M/AVRdelay.html) +* [AVR Timer Calculator](https://eleccelerator.com/avr-timer-calculator/) \ No newline at end of file