Tag Archives: Программирование

AVR. Учебный курс. Стартовая инициализация

Инициализация памяти
Мало кто подозревает о том, что при включении в оперативке далеко не всегда все байты равны 0xFF. Они могут, но не обязаны. Равно как и регистры РОН не всегда равны нулю при запуске. Обычно да, все обнулено, но я несколько раз сталкивался со случаями когда после перезапуска и/или включения-выключения питания, микроконтроллер начинал творить не пойми что. Особнно часто возникает когда питание выключаешь, а потом, спустя некоторое время, пара минут, не больше, включаешь. А всему виной остаточные значения в регистрах.

Итак, возьмите себе за правило после каждого включения, в разделе инициализации, еще даже до инициализации стека, делать зануление памяти и очистку всех регистров. Разумеется делается это все в цикле. Вот примерный вариант кода:

1
2
3
4
5
6
7
8
9
10
11
12
RAM_Flush:	LDI	ZL,Low(SRAM_START)	; Адрес начала ОЗУ в индекс
		LDI	ZH,High(SRAM_START)
		CLR	R16			; Очищаем R16
Flush:		ST 	Z+,R16			; Сохраняем 0 в ячейку памяти
		CPI	ZH,High(RAMEND+1)	; Достигли конца оперативки?
		BRNE	Flush			; Нет? Крутимся дальше!
 
		CPI	ZL,Low(RAMEND+1)	; А младший байт достиг конца?
		BRNE	Flush
 
		CLR	ZL			; Очищаем индекс
		CLR	ZH

Поскольку адрес оперативки у нас двубайтный, то мы вначале смотрим, чтобы старший байт совпал с концом, а потом добиваем оставшиеся 255 байт в младшем байте адреса.
Далее убиваем все регистры от первого до последнего. Все, контроллер готов к работе.

1
2
3
4
5
		LDI	ZL, 30		; Адрес самого старшего регистра	
		CLR	ZH		; А тут у нас будет ноль
		DEC	ZL		; Уменьшая адрес
		ST	Z, ZH		; Записываем в регистр 0
		BRNE	PC-2		; Пока не перебрали все не успокоились

За процедурку зануления регистров спасибо Testicq

Либо значения сразу же инициализируются нужными величинами. Но, обычно, я от нуля всегда пляшу. Поэтому зануляю все.

З.Ы.
Кстати, о оперативке. Нашел я недавно планку оперативной памяти на 1килобайт, древнюю как говно мамонта, еще на ферромагнитных кольцах.

Read More »

AVR. Учебный курс. Флаги и условные переходы

Есть в AVR (да и, пожалуй, во всех остальных процессорах) особый регистр SREG. О нем я несколько раз упоминал в прошлых статьях, но не вдавался в подробности. Чтож, пришло время рассказать, что же это же SREG такой и зачем он нужен.

SREG это регистр состояния ядра. Он так называется Status Register. В этом регистре находится независимых битов — флажков. Которые могут быть либо 1 либо 0, в зависимости от выполненных в прошлом операций.

И вот по тому какие флаги стоят, можно понять что произошло с процессором и что нам дальше делать.

Например, если флаг Z (Zero) выставлен в 1, значит в ходе вычисления предыдущей математической операции в результате образовался ноль.

А если выставлен флаг С (Carry — заем, перенос), то мы из меньшего числа отняли большее, или же прибавили такое число, что результат стал больше 255.

А теперь подробней по каждому флагу.
(далее…)

Read More »

AVR. Учебный курс. Подпрограммы и прерывания

Подпрограммы
Когда один и тот же участок кода часто повторяется, то разумно как то его вынести и использовать многократно. Это дает просто колоссальный выйгрыш по обьему кода и удобству программирования.

Вот, например, кусок кода, передающий в регистр UDR байты с некоторой выдержкой, выдержка делается за счет вращения бесконечного цикла:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
	.CSEG
	LDI R16,Low(RAMEND)	; Инициализация стека
	OUT SPL,R16		; Обязательно!!!
 
	LDI R16,High(RAMEND)
	OUT SPH,R16
 
	.equ	Byte 	= 50
	.equ 	Delay 	= 20
 
	LDI	R16,Byte	; Загрузили значение
Start:	OUT	UDR,R16		; Выдали его в порт
 
	LDI	R17,Delay	; Загрузили длительность задержки
M1:	DEC	R17		; Уменьшили на 1
	NOP			; Пустая операция
	BRNE	M1		; Длительность не равна 0? Переход если не 0
 
	OUT	UDR,R16		; Выдали значение в порт
 
	LDI	R17,Delay	; Аналогично
M2:	DEC	R17
	NOP
	BRNE	M2
 
	OUT	UDR,R16
 
	LDI	R17,Delay
M3:	DEC	R17
	NOP
	BRNE	M3
 
	RJMP	Start		; Зациклим программу

Сразу напрашивается повторяющийся участок кода вынести за скобки.

1
2
3
4
	LDI	R17,Delay
M2:	DEC	R17
	NOP
	BRNE	M2

Для этих целей есть группа команд перехода к подпрограмме CALL (ICALL, RCALL, CALL)
И команда возврата из подпрограммы RET
(далее…)

Read More »

AVR. Учебный курс. Простейшая программа.

Итак, прежде чем что то делать надо понять как вообще выполняется программа в контроллере, как работает ядро процессора. Для этого нам хватит AVR Studio и его эмулятора. Не очень интересно, может даже занудно, но если этот шаг пропустить, то дальнейшие действия будут как бег в темноте.

Поскольку в демоплате Pinboard используется процессор ATmega16, то рассматривать мы будем именно его. Впрочем, как я уже говорил, для других контроллеров AVR это также будет справедливо. Отличия, конечно, есть, но они не существенные.

Запускаем AVR Studio (далее просто студия) и в выскочившем мастере сразу же создаем проект:

Откроется окно:

Увеличить

Оно может выглядеть чуток не так. Дело в том, что интерфейс студии очень легко конфигурируется и перекраивается под себя. Так что можно перетащить панели как нам удобно. Что я и сделал.

Систему команд хорошо бы распечатать себе на листочке. Их там всего около 130, кратким списком (тип команды, что делает и какие операнды) занимает пару листов формата А4. Учить не надо, прочитать раз на десять, чтобы помнить знать что у нас есть. Даже я периодически подглядываю в систему команд, хотя пишу на ассемблере уже много лет.
Я же команды которые буду использовать буду описывать по мере появления.
(далее…)

Read More »

C vs Assembler

Если ты впервые столкнулся с микроконтроллерами, то наверняка у тебя стал выбор на чем писать.

На Си или на Ассемблере. Выбор не прост, не зря программисты однокристальщики раскололись на два непримиримых лагеря. Одни с пеной у рта доказывают, что те кто пишут на Си лохи изнеженные, а настоящий брутальный кодер должен воспринимать только ассемблер. Другие же, усераясь, доказывают, что на ассемблере разве что лампочками помигать можно, а какой либо серьезный проект делать на низком уровне невозможно.

Но, истинна, как всегда, находится посредине. Каждый уважающий себя программер должен знать ассемблер, а вот писать должен на том, что более подходит под масштаб задачи. Особенно это касается микроконтроллеров. (далее…)

Read More »