Примеры на Ассемблере для микроконтроллеров Atmel AVR
Здесь представлены примеры различных программ на языке Ассемблера для микроконтроллеров Atmel AVR. Примеры выложены в виде проектов для AVR Studio под микроконтроллер ATmega16, поэтому при переносе на другие МК семейства AVR это нужно учитывать. Тактовая частота микроконтроллера во всех примерах 8 МГц (используется тактирование от внутреннего генератора). Код примеров разбит на блоки и снабжен комментариями. При обнаружении ошибок просьба сообщить на почту.
Краткое описание команд Ассемблера AVR представлено здесь.
Подробное описание каждой команды представлено в AVR 8bit Instruction Set.
Для более глубокого изучения ассемблера AVR советую к прочтению книгу Юрия Ревича "Практическое программирование микроконтроллеров Atmel AVR на языке ассемблера". С беcплатным фрагментом книги можно ознакомиться здесь. Также можно изучить различные методические пособия ВУЗов, например, вот.
Также на сайте выложены примеры программ на языке Си.
Start – Заготовка стартовой инициализации микроконтроллера, в которую входят инициализация стека, очистка ОЗУ (SRAM) и регистров общего назначения (R0 - R31), а также глобальный запрет прерываний. Пример кода приведён ниже. При использовании следует помнить, что регистры ввода-вывода (порты, периферия и т.д.) не очищаются, поэтому их НЕОБХОДИМО инициализировать отдельно.
.include "m16def.inc" ; Use AtMega16A
;=================================================
; Имена регистров, а также различные константы
.equ XTAL = 8000000 ; Частота МК
.equ UART_BaudRate = 19200 ; Скорость при связи по UART
.equ UART_BaudDivider = XTAL / (16 * UART_BaudRate) - 1
.equ I2C_Frequency = 80000 ; Частота шины I2C
.equ I2C_BaudDivider = (XTAL / (8 * I2C_Frequency) - 2)
.equ Bit0 = 0b00000001
.equ Bit1 = 0b00000010
.equ Bit2 = 0b00000100
.equ Bit3 = 0b00001000
.equ Bit4 = 0b00010000
.equ Bit5 = 0b00100000
.equ Bit6 = 0b01000000
.equ Bit7 = 0b10000000
.def MulLow = R0 ; Младший регистр результата умножения
.def MulHigh = R1 ; Старший регистр результата умножения
.def Temp0 = R15 ; Регистр с нулевым значением
.def Temp1 = R16
.def Temp2 = R17
.def Temp3 = R18
.def Temp4 = R19
.def Temp5 = R20
.def Temp6 = R21
.def Temp7 = R22
.def Temp8 = R23
.def Counter = R24 ; Регистр счетчик
.def Flags = R25 ; Флаговый регистр
;=================================================
; Сегмент SRAM памяти
.DSEG
;=================================================
; Сегмент EEPROM памяти
.ESEG
;=================================================
; Сегмент FLASH памяти
.CSEG
;=================================================
; Таблица прерываний
.ORG 0x00
RJMP RESET
;=================================================
; Прерывание по сбросу, стартовая инициализация
RESET:
; Инициализация стека
LDI Temp1, LOW(RAMEND)
OUT SPL, Temp1
LDI Temp1, HIGH(RAMEND)
OUT SPH, Temp1
; Очистка ОЗУ и регистров R0-R31
LDI ZL, LOW(SRAM_START) ; Адрес начала ОЗУ в индекс
LDI ZH, HIGH(SRAM_START)
CLR Temp1 ; Очищаем R16
RAM_Flush:
ST Z+, Temp1
CPI ZH, HIGH(RAMEND + 1)
BRNE RAM_Flush
CPI ZL, LOW(RAMEND + 1)
BRNE RAM_Flush
LDI ZL, (0x1F-2) ; Адрес регистра R29
CLR ZH
Reg_Flush:
ST Z, ZH
DEC ZL
BRNE Reg_Flush
CLR ZL
CLR ZH
; Регистры и SRAM полностью очищены (обнулены)
; Но регистры ввода-вывода (IO) НЕОБХОДИМО очищать
; Глобальный запрет прерываний
CLI
Скачать AVR Start.asm
Delays – Библиотека с подпрограммами задержки. Все задержки рассчитаны на тактовую частоту МК 8 МГц. Библиотека включает следующие процедуры:
- Delay1us – Задержка повышенной точности в 1 мкс c учетом длительности RCALL и RET.
- Delay5us – Задержка повышенной точности в 5 мкс c учетом длительности RCALL и RET.
- Delay10us – Задержка повышенной точности в 10 мкс c учетом длительности RCALL и RET.
- Delayus – Задержка высокой точности в несколько десятков микросекунд.
- Delayms – Задержка высокой точности в несколько миллисекунд.
; БИБЛИОТЕКА ЗАДЕРЖЕК (8 МГц)
; Delay1us задержка повышенной точности в 1 мкс c учетом длительности RCALL и RET
; Delay5us задержка повышенной точности в 5 мкс c учетом длительности RCALL и RET
; Delay10us задержка повышенной точности в 10 мкс c учетом длительности RCALL и RET
; Delayus задержка высокой точности в несколько десятков микросекунд
; Delayms задержка высокой точности в несколько миллисекунд
;=================================================
; задержка повышенной точности в 1 мкс c учетом длительности RCALL и RET
; RCALL дает 3 + 1 NOP + 4 RET = 8 - 1 микросекунда при 8МГц
Delay1us:
NOP
RET
;=================================================
; задержка повышенной точности в 5 мкс c учетом длительности RCALL и RET
Delay5us:
PUSH Temp1
LDI Temp1, 9
Delay5us_loop:
DEC Temp1
BRNE Delay5us_loop
POP Temp1
NOP
NOP
RET
;=================================================
; задержка повышенной точности в 10 мкс c учетом длительности RCALL и RET
Delay10us:
PUSH Temp1
LDI Temp1, 23
Delay10us_loop:
DEC Temp1
BRNE Delay10us_loop
POP Temp1
RET
;=================================================
; задержка высокой точности в несколько десятков микросекунд
; вход Temp1 количество необходимых десятков микросекунд
Delayus:
PUSH Temp2
Delayus_loop1:
LDI Temp2, 25
Delayus_loop2:
DEC Temp2
BRNE Delayus_loop2
NOP
NOP
DEC Temp1
BRNE Delayus_loop1
POP Temp2
RET
;=================================================
; задержка высокой точности в несколько миллисекунд
; вход Temp1 количество необходимых миллисекунд
Delayms:
PUSH Temp2
MOV Temp2, Temp1
Delayms_loop:
LDI Temp1, 100
RCALL Delayus
DEC Temp2
BRNE Delayms_loop
POP Temp2
RET
Скачать AVR Delay.asm
Math – Библиотека с подпрограммами математических операций, включает следующие процедуры:
- SUB16X16 – Вычитание 16-разрядных чисел.
- ADD16X16 – Сложение 16-разрядных чисел.
- MUL16X16s – Знаковое умножение 16-разрядных чисел.
- MUL16X16u – Беззнаковое умножение 16-разрядных чисел.
- DIV16X16s – Знаковое деление 16-разрядных чисел.
- DIV16X16u – Беззнаковое деление 16-разрядных чисел.
- DIV16POWER2s – Знаковое деление 16-разрядного числа на степень 2.
- DIV16POWER2u – Беззнаковое деление 16-разрядного числа на степень 2.
- SIGN16 – Смена знака 16-разрядного числа.
- DEC2BCD – Перевол 8-разрядного десятичного числа в двоично-десятичное (BCD).
- BCD2DEC – Перевол 8-разрядного двоично-десятичного (BCD) числа в десятичное.
- CP16X16 – Сравнение 16-разрядных чисел.
- DIGITS8 – Вычисление цифр 8-разрядного числа.
- DIGITS16 – Вычисление цифр 16-разрядного числа.
; БИБЛИОТЕКА ДЛЯ РАБОТЫ С МАТЕМАТИКОЙ
; SUB16X16 вычитание 16-разрядных чисел
; ADD16X16 сложение 16-разрядных чисел
; MUL16X16s знаковое умножение 16-разрядных чисел
; MUL16X16u беззнаковое умножение 16-разрядных чисел
; DIV16X16s знаковое деление 16-разрядных чисел
; DIV16X16u беззнаковое деление 16-разрядных чисел
; DIV16POWER2s знаковое деление 16-разрядного числа на степень 2
; DIV16POWER2u беззнаковое деление 16-разрядного числа на степень 2
; SIGN16 смена знака 16-разрядного числа
; DEC2BCD перевол 8-разрядного десятичного числа в двоично-десятичное (BCD)
; BCD2DEC перевол 8-разрядного двоично-десятичного (BCD) числа в десятичное
; CP16X16 сравнение 16-разрядных чисел
; DIGITS8 вычисление цифр 8-разрядного числа
; DIGITS16 вычисление цифр 16-разрядного числа
;=======================================================================
; вычитание 16-разрядных чисел
; вход: Temp1-Temp2 первый аргумент от H к L
; Temp3-Temp4 второй аргумент от H к L
; выход: Temp1-Temp2 результат от H к L
SUB16X16:
SUB Temp2, Temp4
SBC Temp1, Temp3
RET
;=======================================================================
; сложение 16-разрядных чисел
; вход: Temp1-Temp2 первый аргумент от H к L
; Temp3-Temp4 второй аргумент от H к L
; выход: Temp1-Temp2 результат от H к L
ADD16X16:
ADD Temp2, Temp4
ADC Temp1, Temp3
RET
;=======================================================================
; знаковое умножение 16-разрядных чисел
; вход: Temp1-Temp2 первый аргумент от H к L
; Temp3-Temp4 второй аргумент от H к L
; выход: Temp1-Temp4 результат от H к L
MUL16X16s:
MULS Temp3, Temp1 ; (signed)ah * (signed)bh
MOV Temp5, MulHigh
MOV Temp6, MulLow
MUL Temp4, Temp2 ; al * bl
MOV Temp7, MulHigh
MOV Temp8, MulLow
MULSU Temp3, Temp2 ; (signed)ah * bl
SBC Temp5, Temp0 ; из-за отриц. чисел
ADD Temp7, MulLow
ADC Temp6, MulHigh
ADC Temp5, Temp0
MULSU Temp1, Temp4 ; (signed)bh * al
SBC Temp5, Temp0 ; из-за отриц. чисел
ADD Temp7, MulLow
ADC Temp6, MulHigh
ADC Temp5, Temp0
MOV Temp1, Temp5 ; move result
MOV Temp2, Temp6
MOV Temp3, Temp7
MOV Temp4, Temp8
RET
;=======================================================================
; беззнаковое умножение 16-разрядных чисел
; вход: Temp1-Temp2 первый аргумент от H к L
; Temp3-Temp4 второй аргумент от H к L
; выход: Temp1-Temp4 результат от H к L
MUL16X16u:
MUL Temp3, Temp1 ; (unsigned)ah * (unsigned)bh
MOV Temp5, MulHigh
MOV Temp6, MulLow
MUL Temp4, Temp2 ; al * bl
MOV Temp7, MulHigh
MOV Temp8, MulLow
MUL Temp3, Temp2 ; (unsigned)ah * bl
ADD Temp7, MulLow
ADC Temp6, MulHigh
ADC Temp5, Temp0
MUL Temp1, Temp4 ; (unsigned)bh * al
ADD Temp7, MulLow
ADC Temp6, MulHigh
ADC Temp5, Temp0
MOV Temp1, Temp5 ; move result
MOV Temp2, Temp6
MOV Temp3, Temp7
MOV Temp4, Temp8
RET
;=======================================================================
; знаковое деление 16-разрядных чисел
; вход: Temp1-Temp2 первый аргумент от H к L
; Temp3-Temp4 второй аргумент от H к L
; выход: Temp1-Temp2 результат от H к L
; R13-R14 остаток от H к L
DIV16X16s:
MOV R10, R16 ;вычисляем знак результата
EOR R10, R18 ; знак хранится в R10
SBRS R16, 7 ; проверяем знак делимого
RJMP d16s_1 ; если положительное то идем дальше
COM R16 ; иначе меняем знак делимого
COM R17 ; преобразуем в доп код
SUBI R17, LOW(-1)
SBCI R16, HIGH(-1)
d16s_1:
SBRS R18, 7 ; проверяем знак делителя
RJMP d16s_2
COM R18
COM R19
SUBI R19, LOW(-1)
SBCI R18, HIGH(-1)
; подготовили делимое и делитель
d16s_2:
; очищаем остаток и флаг переноса
CLR R14
CLR R13
CLC
LDI R31, 17 ; init loop counter
d16s_3:
ROL R17 ; shift left dividend
ROL R16
DEC R31 ; decrement counter
BRNE d16s_5 ; if done
SBRS R10, 7 ; if MSB in sign register set
RJMP d16s_4
COM R16 ; change sign of result
COM R17
SUBI R17, LOW(-1)
SBCI R16, HIGH(-1)
d16s_4:
RET
d16s_5:
ROL R14 ; shift dividend into remainder
ROL R13
SUB R14, R19 ; remainder = remainder - divisor
SBC R13, R18
BRCC d16s_6 ; if result negative
ADD R14, R19 ; restore remainder
ADC R13, R18
CLC ; clear carry to be shifted into result
RJMP d16s_3 ; else
d16s_6:
SEC ; set carry to be shifted into result
RJMP d16s_3
;=======================================================================
; беззнаковое деление 16-разрядных чисел
; вход: Temp1-Temp2 первый аргумент от H к L
; Temp3-Temp4 второй аргумент от H к L
; выход: Temp1-Temp2 результат от H к L
; R13-R14 остаток от H к L
;=================================================
DIV16X16u:
; очищаем остаток и флаг переноса
CLR R14
CLR R13
CLC
LDI R31, 17 ; init loop counter
d16u_1:
ROL R17 ; shift left dividend
ROL R16
DEC R31 ; decrement counter
BRNE d16u_2 ; if done
RET ; return
d16u_2:
ROL R14 ; shift dividend into remainder
ROL R13
SUB R14, R19 ;remainder = remainder - divisor
SBC R13, R18
BRCC d16u_3 ; if result negative
ADD R14, R19 ; restore remainder
ADC R13, R18
CLC ; clear carry to be shifted into result
RJMP d16u_1 ; else
d16u_3:
SEC ; set carry to be shifted into result
RJMP d16u_1
;=======================================================================
; знаковое деление 16-разрядного числа на степень 2
; вход: Temp1-Temp2 делимое от H к L
; Temp5 степень 2
; выход: Temp1-Temp2 результат от H к L
DIV16POWER2s:
TST Temp5
BREQ DIV16POWER2s_2
DIV16POWER2s_1:
ASR Temp1
ROR Temp2
DEC Temp5
BRNE DIV16POWER2s_1
DIV16POWER2s_2:
RET
;=======================================================================
; беззнаковое деление 16-разрядного числа на степень 2
; вход: Temp1-Temp2 делимое от H к L
; Temp5 степень 2
; выход: Temp1-Temp2 результат от H к L
DIV16POWER2u:
TST Temp5
BREQ DIV16POWER2u_2
DIV16POWER2u_1:
LSR Temp1
ROR Temp2
DEC Temp5
BRNE DIV16POWER2u_1
DIV16POWER2u_2:
RET
;=======================================================================
; смена знака 16-разрядного числа
; вход: Temp1-Temp2 число от H к L
; выход: Temp1-Temp2 результат от H к L
SIGN16:
COM Temp1
COM Temp2
SUBI Temp2, LOW(-1)
SBCI Temp2, HIGH(-1)
RET
;=======================================================================
; перевол 8-разрядного десятичного числа в двоично-десятичное (BCD)
; вход: Temp1 десятичное число
; выход: Temp1 BCD число
DEC2BCD:
PUSH Temp2
PUSH Temp3
PUSH Temp4
CPI Temp1, 10
BRLO Dec2Bcd_exit
PUSH Temp1
CLR Temp3
LDI Temp2, 10
Dec2Bcd_1:
SUB Temp1,Temp2
INC Temp3
CPI Temp1, 10
BRGE Dec2Bcd_1
CLR Temp4
CLR Temp1
Dec2Bcd_2:
ADD Temp4, Temp2
INC Temp1
CP Temp1, Temp3
BRNE Dec2Bcd_2
POP Temp1
SUB Temp1, Temp4
SWAP Temp3
ADD Temp1, Temp3
Dec2Bcd_exit:
POP Temp4
POP Temp3
POP Temp2
RET
;=======================================================================
; перевол 8-разрядного двоично-десятичного (BCD) числа в десятичное
; вход: Temp1 BCD число
; выход: Temp1 десятичное число
BCD2DEC:
PUSH Temp2
PUSH Temp3
PUSH Temp1
SWAP Temp1
CLR Temp3
CBR Temp1, 0b11110000
MOV Temp3, Temp1
CLR Temp2
Bcd2Dec_1:
ADD Temp1, Temp3
INC Temp2
CPI Temp2, 9
BRNE Bcd2Dec_1
MOV Temp2, Temp1
POP Temp1
CBR Temp1, 0b11110000
ADD Temp1, Temp2
POP Temp3
POP Temp2
RET
;=======================================================================
; сравнение 16-разрядных чисел
; вход: Temp1-Temp2 первый аргумент от H к L
; Temp3-Temp4 второй аргумент от H к L
; выход: смотри флаги
CP16X16:
CP Temp2, Temp4
CPC Temp1, Temp3
RET
;=======================================================================
; вычисление цифр 8-разрядного числа
; вход: Temp1 аргумент
; выход: Temp1-Temp3 цифры от H к L
DIGITS8:
CLR R26
CLR R27
CLR R28
CLR R29
CLR R30
LDI Temp2,100
DIG8_1:
CP Temp1, Temp2
BRLO DIG8_2
SUB Temp1, Temp2
; сотни
INC R26
RJMP DIG8_1
DIG8_2:
LDI Temp2,10
DIG8_3:
CP Temp1, Temp2
BRLO DIG8_4
SUB Temp1, Temp2
; тысячи
INC R27
RJMP DIG8_3
DIG8_4:
; в Temp1 остались только единицы
MOV Temp3, Temp1
MOV Temp1, R26
MOV Temp2, R27
RET
;=======================================================================
; вычисление цифр 16-разрядного числа
; вход: Temp1-Temp2 аргумент от H к L
; выход: Temp1-Temp5 цифры от H к L
DIGITS16:
CLR R26
CLR R27
CLR R28
CLR R29
CLR R30
LDI Temp3, HIGH(10000)
LDI Temp4, LOW(10000)
DIG16_1:
RCALL CP16X16
BRLO DIG16_2
RCALL SUB16X16
; десятки тысяч
INC R26
RJMP DIG16_1
DIG16_2:
LDI Temp3, HIGH(1000)
LDI Temp4, LOW(1000)
DIG16_3:
RCALL CP16X16
BRLO DIG16_4
RCALL SUB16X16
; тысячи
INC R27
RJMP DIG16_3
DIG16_4:
LDI Temp3, HIGH(100)
LDI Temp4, LOW(100)
DIG16_5:
RCALL CP16X16
BRLO DIG16_6
RCALL SUB16X16
; сотни
INC R28
RJMP DIG16_5
DIG16_6:
LDI Temp3, HIGH(10)
LDI Temp4, LOW(10)
DIG16_7:
RCALL CP16X16
BRLO DIG16_8
RCALL SUB16X16
; десятки
INC R29
RJMP DIG16_7
DIG16_8:
; в Temp1-Temp2 остались только единицы
MOV Temp5, Temp2
MOV Temp1, R26
MOV Temp2, R27
MOV Temp3, R28
MOV Temp4, R29
RET
Скачать AVR Math.asm
IO Ports – В данном примере рассматривается работа с портами ввода-вывода. К порту А подключены 8 светодиодов (линии 0-7). К линии 0 порта С подключена кнопка, с подтяжкой на землю. При нажатии кнопка выдает на линию 0 порта С уровень логической единицы. Цикл программы организован следующим образом: при запуске включается бегущий огонь, сначала загорается светодиод на линии 0 порта А, затем на линии 1 и т.д. По достижении линии 7 направление бегущего огня меняется (от 7 к 0). При нажатии на кнопку бегущий огонь останавливается и загораются одновременно все светодиоды. После повторного нажатия на кнопку бегущий огонь продолжает перемещаться с места остановки.
Скачать пример
Dynamic Indication – В данном примере рассматривается работа с 7-сегментным индикатором. В моём случае он имеет 4 разряда (цифры). Поскольку у меня на плате установлены транзисторы для управления разрядами, то управление осуществляется выводом логической единицы и на разряды и на сегменты. Схема подключения следующая: к линиям 0-7 порта C подключены сегменты индикатора, а к линиям 0-3 порта В разряды индикатора. При запуске на индикатор выводятся цифры 1 2 3 4.
Скачать пример
UART – В данном примере рассматривается периферийного модуля UART (универсальный асинхронный приёмопередатчик). Модуль UART можно настроить как на работу с прерываниями, так и без них (вручную, путём работы с флагами). Пример работает следующим образом: при получении байта, МК переходит в обработчик прерывания (используется только прерывание по приёму данных) и разбирает численное значение байта (0-255) на цифры, которые и выводятся на 7-сегментный индикатор. Схема подключения аналогична предыдущему примеру. Передача осуществляется по двум линиям UART (порт D линии 0-1), к которым необходимо подключить линии RX и TX преобразователя USB-UART. Для настройкки без прерываний необходимо обнулить бит RXCIE в регистре UCSRB и вручную опрашивать интерфейс в основном цикле программы.
Скачать пример
Clock – В данном примере рассматривается реализация простых часов с 7-сегментым индикатором и парой кнопок. Только здесь уже требуется 6 разрядов, хотя секунды можно опустить. Кнопки с подтяжкой на землю. При нажатии кнопка выдает на линию высокий логический уровень. Индикатор подключается как и в предыдущих примерах (сегменты к порту C, разряды к порту B), а кнопки к линиям 2-3 порта D. Кнопка PD2 используется для установки минут, а PD3 для установки часов. По нажатию каждой из кнопок увеличивается значение соответствующего разряда (минуты или часы).
Скачать пример
DS18B20 – В данном примере рассматривается работа с цифровым датчиком температуры DS18B20. Показания температуры выводятся на 7-сегментый индикатор. Вывод DQ датчика поключен к линии PC7. Линия должна быть подтянута к плюсу питания резистором на 4.7-10 кОм (согласно документации). Датчик опрашивается каждую секунду. Температура выводится на 4-разрядный индикатор: знак, два разряда на целуюю часть и один на вещественную. Документация к датчику здесь.
Скачать пример
ADC Indication – Данный пример аналогичен примеру с UART. Отличие в том, что байт берется с линии 0 порта А (линия 0 АЦП, ADC0). Микроконтроллер по таймеру производит аналого-цифровое преобразование напряжения на линии 0 порта А, (младшие 2 бита отбрасываются как шум). При измерении используется внутренняя опора 5 В. К линии PD2 порта D подключена кнопка, которая определяет режим вывода показаний. При нажатии на кнопку выводится результат измерений в виде числа от 0 до 255. Если кнопка не нажата, то результат измерений переводится в вольты и выводится на индикатор (с точностью до десятых).
Скачать пример
Fast PWM – В данном примере показана настройка аппаратного ШИМ (широтно-импульсная модуляция, англ. PWM). К линиям 4 и 5 порта D подключены светодиоды, а к линиям 0-3 порта С – кнопки. Кнопки с подтяжкой на землю (при нажатии кнопка выдает на линию порта уровень логической единицы) подключены к линиям 2-5 порта C. Кнопки на линях 2 и 3 соответственно увеличивают и уменьшают коэффициент заполнения ШИМ (меняется яркость светодиода) канала А. Кнопки на линях 4 и 5 соответственно увеличивают и уменьшают коэффициент заполнения ШИМ канала B. Число сравнения для каждого из каналов меняется в диапазоне от 0 до 255. Для канала А шаг изменения равен 10, для канала В шаг равен 5.
Скачать пример
HCSR04 – В данном примере рассматривается работа с ультразвуковым датчиком расстояния HCSR04. К линии PD6 подключен вывод Trigger датчика, а к линии PD7 вывод Echo. Поключение 7-сегментного индикатора аналогично предыдущим примерам. По таймеру микроконтроллер раз в секунду опрашивает датчик и определяет расстояние до препятсвия в миллиметрах. После этого число разбивается на цифры и выводится на дисплей. Документация к датчику здесь.
Скачать пример
Matrix Keyboard – В данном примере показана работа с матричной клавиатурой. Микроконтроллер динамически опрашивает клавиатуру, а затем определяет номер нажатой клавиатуры. Размер поля 3 на 3 – получаем 9 кнопок. Нажатие первых 8-ми приводит к зажиганию светодиода на соответствующей линии порта А, нажатие 9-ой кнопки зажигает все светодиоды порта А. Матричная клавиатура подключается к линиям 0-5 порта С (три столбца и три строки). В архиве схема и печатная плата матричной клавиатуры (Diptrace).
Скачать пример
Shift Register – В данном примере рассматривается работа с модулем SPI на примере сдвигового регистра 74HC595. К регистру подключены светодиоды, в качестве линии CS используется линия 4 порта B (вывод not SS). Линия DS (14 нога) регистра идет к MOSI (PB5), линия SHCP (11 нога) к линии SCK (PB7), линия STCP (12 нога) к линии SS (PB4). Линии MR (10 нога) и OE (13 нога) должны быть подтянуты к высокому и низкому логическим уровням соответственно. По таймеру микроконтроллер меняет состояние светодиодов: поочерёдно горят то чётные светодиоды, то нечётные. Если при этом передать байт по UART'у, то он будет выведен в порт на светодиоды. Чтобы обратно переключиться в режим мигания необходимо послать по UART'у 0x00 (ноль). Документация к микросхеме 74HC595 здесь.
Скачать пример
SG-90 Servo – В данном примере рассматривается работа с сервоприводом SG-90. Используется аппаратный ШИМ. Линия ШИМ сервпопривода подключена к каналу А аппаратного ШИМ. Кнопки поворота подключены к линиям PD2 и PD3. Кнопка на линии PD2 увеличивает длительность импульса, кнопка на линии PD3 уменьшает длительность импульса. Длительность импульса меняется от 1 до 2 мс. Описание сервомотора здесь.
Скачать пример
RGB Lamp – В данном примере рассматривается работа с трехцветным RGB-светодиодом. Реализовано плавное переливание цветов с использованием программного ШИМ. Линии красного, зеленого и синего цветов подключаются соответственно к линиям 2, 3 и 4 порта D.
Скачать пример