Radiohobby Forum

Интернет конференция журнала "Радиохобби"

Вы не вошли.

Объявление

Подписка на новые материалы от Николая Сухова - ролики, схемы, модели, онлайн конференции, консультации, чат.

Внимание! Почта в доменах Яндекс и Mail.ru не будет работать в профилях форумчан, из-за введённых правительством Украины санкций против этих компаний. Всем, кто ранее использовал подобную почту, для сохранения прежней функциональности форума, рекомендуется её поменять.

Огромная просьба, заливать тематические картинки и файлы в личные файловые каталоги на форуме, чтобы они не потерялись, со временем!

Ссылка "Загрузки" находится справа внизу формы набора сообщения.

Подписка на журнал "Радиохобби" прекращена. Подробности. Форум же - продолжает свою работу.

#31 31.07.2006 10:53:41

Liv
Ветеран
Откуда: Минск
Здесь с 08.02.2004
Сообщений: 1,233

Re: AVR для "чайников"

Этот пример не показателен. Загрузка регистров периферии, котрая осуществляется через временный регистр (в данном случае это почти аккумулятор) влияния на среднюю производительность оказывает слабо. Вот математика - другое дело.

Так выглядит сложение 4-х байтных чисел на аккумуляторном MCS-51:

mov a,r0
add a,r4
mov r0,a
mov a,r1
addc a,r5
mov r1,a
mov a,r2
addc a,r6
mov r2,a
mov a,r3
addc a,r7
mov r3,a

А так на AVR:

add r0,r4
adc r1,r5
adc r2,r6
adc r3,r7

Отредактировано Liv (31.07.2006 10:54:02)

Вне форума

#32 31.07.2006 13:41:05

Dmitry
Забанен
Откуда: Запорожье
Здесь с 03.02.2004
Сообщений: 3,105
Сайт

Re: AVR для "чайников"

Ясно.


Почему когда мы нарушаем, нас штрафуют, а когда всё делаем правильно, с нас берут налоги?....

Вне форума

#33 31.07.2006 23:28:27

Матроскин
Ветеран
Откуда: Краснодар
Здесь с 06.02.2006
Сообщений: 2,022

Re: AVR для "чайников"

2 Liv
Вот моя программа, о которой я говорил. МК я прошил, но ничего не заработало. Может потому, что старая AVRStudio не работает с новыми МК (ругается на тини2313). Может программа кривая. Не получилось-таки как хотел (сперва отладить, потом показать).

--------------------------------------------------------------------------------------------------
;Частота кварца 4 МГц

;Приступим.
;=============================================

	.include "tn2313def.inc"	;Подключаем файл описания регистров для tiny2313
	
;---------------------------------------------
;Константы: (может понадобятся)

	.equ	IN1_ON = 0x1	;Включен первый вход (с порта получим 00000001)
	.equ	IN2_ON = 0x0	;Включен второй вход (с порта получим 0)
	.equ	IN3_ON = 0x2 	;Включен третий вход (с порта получим 00000010)
	.equ	IN_KONST = 0x3	;Константа для определения состояния 
				         ;переключателя входов (00000011)
	.equ	RELAY_DEL = 1	;Время на переключение реле (полет контактов)
					;(в интервалах переполнения TC0)
	.equ	PWR_SWITCH_DEL = 16	;Время удержания сигнала ENABLE в 1 на время включения питания
					;(в интервалах переполнения TC0)
;---------------------------------------------
;Определим порты:

	.equ	IN_PORT = PORTD         ;Обзываем порт D
	.equ	OUT_PORT = PORTB	;Обзываем порт В 
	.equ	ENABLE_PIN = PB0	;Сигнал ENABLE будем выдавать по линии PB0
	.equ	MUTE_PIN = PB1		;Сигнал MUTE будем выдавать по линии РВ1
	.equ	RELAY_PIN = PB2		;Сигнал включения реле по линии PB2
	.equ	IN1_PIN = PB3		;Включение 1-го входа по линии РВ3
	.equ	IN2_PIN = PB4		;Включение 2-го входа по линии РВ4
	.equ	IN3_PIN = PB5		;Включение 3-го входа по линии РВ5
	.equ	STBY_LED = PB6		;Светодиод STBY по линии РВ6
	.equ	ON_LED = PB7		;Светодиод ON по линии РВ7
	.equ	TUMB_1 = PD0		;Первая нога тумблера входов по линии РD0
	.equ	TUMB_2 = PD1		;Вторая нога тумблера входов по линии РD1
	.equ	TUMB_STB = PD2		;Тумблер STBY/ON по линии PD2

;----------------------------------------------
;Глобальные регистровые переменные:

	.def temp = r16			;Временный регистр temp
	
;----------------------------------------------
;Сегмент данных, будем описывать переменные в ОЗУ

.DSEG

IN_SW_MODE: .byte 1		;Переменная состояния переключателя входов
PWR_SW_MODE: .byte 1		;Переменная состояния переключателя STBY/ON
RELAY_TMR: .byte 1		;Программый таймер задержки на время переключения реле
PWR_SWITCH_TMR: .byte 1		;Программый таймер удержания сигнала ENABLE в 1 на время включения питания
;----------------------------------------------
;Сегмент кода:

.CSEG

;Векторы прерываний

.org 0			;По адресу 0 вектор сброса, 
	
	rjmp START	;переход на основную программу

.org OVF0addr	;По адресу OVFaddr обработка прерывания по переполнению таймера 0

	rjmp TCOVF
;------------------------------------------------

START:	ldi temp,RAMEND		;Загружаем в temp RAMEND из 2313def.inc
	out SPL,temp		          ;Инициализируем стек
	
;Настройка портов:

	ldi temp,0xFF		;Забиваем в temp FF
	out DDRB,temp		;Настраиваем порт В на вывод 
	clr temp		         ;чистим temp
	out DDRD,temp		;Настраиваем порт D на ввод
	
	
;Инициализация переменных
	
	ldi temp,RELAY_DEL	         ;Загружаем в temp константу RELAY_DEL
	sts RELAY_TMR,temp	         ;Присваиваем это значение таймеру
				                  ;задержки на время переключения реле
	ldi temp,PWR_SWITCH_DEL	;Загружаем в темп константу PWR_SWITCH_DEL
	sts PWR_SWITCH_TMR,temp	;Присваиваем это значение таймеру удержания
				                  ;ENABLE при включении питания 
	clr temp		                  ;чистим temp
	sts IN_SW_MODE,temp	         ;Загружаем в переменную IN_SEL_MODE нули
	sts PWR_SW_MODE,temp	;Згружаем в переменную PWR_SW_MODE нули
	
;Настройка оборудования

	ldi temp,(1<<CS02)|(1<<CS01)|(1<<CS00)	;предделитель таймера ставим на значение СК/1024
						;теперь ТС0 будет переполняться каждые 65,536 мс
						;при частоте кварца 4 МГц
	out TCCR0,temp		;записываем это значение в регистр TCCR0
	ldi temp,(1<<TOIE0)	;бит TOIE0 равен 1, остальные нули
	out TIMSK,temp		;Разрешаем прерывание по переполнению таймера 0
		
	sei			;Общее разрешение прерываний


;----------------------------------------------	
; Основной цикл программы

;Первноначальная установка переключателей

;Опрашиваем тумблер STBY/ON

	in temp,IN_PORT		;читаем в темп весь порт D
	andi temp,1		         ;Лог. И с единицей. В итоге имеем в темпе 1 если
				          ;тумблер STBY/ON в положении "ON" и 0 если в "STBY"
	sts PWR_SW_MODE,temp	;Сохраняем новое значение
	rcall STBY_ON		;Вызываем подпрограмму включения/выключения питания	

;Опрашиваем переключатель входов

	in temp,IN_PORT		;Читаем в темп весь порт D
	andi temp,IN_KONST	;Лог. "И" содержимого порта В с числом 00000011
				         ;В рез-те биты со всех линий обнуляться, а в битах 0 и 1 
				         ;получим число, соответствующее состоянию тублера входов. 
	sts IN_SW_MODE,temp	;Сохраняем это значение в IN_SEL_MODE
	rcall INSW		         ;Вызываем подрограмму переключения входов.

;Дальше идет циклическое сканирование состояния переключателей
;и вызов необходимых подпрограмм в случае изменения 
;состояния какого-либо из них

;Опрашиваем тумблер STBY/ON

SWSCAN:	in temp,IN_PORT		;Снова тоже самое
	andi temp,1		;
	cpi temp,PWR_SW_MODE	;Сравниваем текущее сост. тумблера STBY/ON с предидущим
	breq INSCAN		         ;Если равно, переходим дальше
	rcall STBY_ON		         ;иначе вызываем подпрограмму включения/выключения питания

;Опрашиваем переключатель входов

INSCAN:	in temp,IN_PORT		;
	andi temp,IN_KONST	;
	cpi temp,IN_SW_MODE	;Сравниваем текущее состояние переключателя входов и переменную
	breq SWSCAN		;Если равно, то ничего не делаем и повторяем все снова, 
				         ;иначе вызываем переключение
	rcall INSW		;
	rjmp SWSCAN		;Цикл 
;---------------------------------------------

;Подпрограмма включения/выключения питания

STBY_ON: sbi OUT_PORT,MUTE_PIN	;Коротим вход усилка
	nop			;Небольшая задержка
	nop			;чтобы ключи MUTE успели 
	nop			;открыться
	nop	
	sbis IN_PORT,TUMB_STB	;Проверяем, включен ли тумблер STBY/ON
	rjmp OFF		;если да, то переходим на выключение,
				;если нет, включаем

;Включение питания

	sbi OUT_PORT,ENABLE_PIN	;Запрещаем подключение АС
	nop
	nop
	nop
	nop
	sbi OUT_PORT,RELAY_PIN	;Включаем питание
	
;Теперь даем задержку подключения АС (16 интервалов переполнения ТС0
;(около 1с)) 

ONDEL:	lds temp,PWR_SWITCH_TMR	;Грузим в temp переменную PWR_SWITCH_TMR
	 tst temp		                           ;проверяем ее значение
	brne ONDEL		                           ;если она не ноль, то зацикливаемся, если 0
				                           ;то перезагружаем PWR_SWITCH_TMR
	ldi temp,PWR_SWITCH_DEL	
	sts PWR_SWITCH_TMR,temp	
	
;Задержка сформирована,разрешаем подключение АС, 
;снимаем Mute и идем на выход

	cbi OUT_PORT,ENABLE_PIN	;разрешаем подключение АС и даем задержку
				                   ;на переключение реле
ENDEL:	lds temp,RELAY_TMR	;Грузим в temp переменную RELAY_TMR
	tst temp		;проверяем ее значение
	brne ENDEL		;если она не ноль, то зацикливаемся, если 0
				;то перезагружаем RELAY_TMR
	ldi temp,RELAY_DEL	
	sts RELAY_TMR,temp	
	
	ldi temp,1		                  ;сохраняем 
	sts PWR_SW_MODE,temp	;состояние тумблера STBY/ON
	cbi OUT_PORT,MUTE_PIN	;Снимаем Mute
	cbi OUT_PORT,STBY_LED	;Гасим "STBY"
	sbi OUT_PORT,ON_LED	         ;Зажигаем светодиод "ON"
	rjmp PWROUT		           ;Выходим

;Выключение питания

OFF:	sbi OUT_PORT,ENABLE_PIN	;Запрещаем подключение АС (реле отпустит) 
				                 ;и даем задержку на переключение реле
OFFDEL:	lds temp,RELAY_TMR	;Грузим в temp переменную RELAY_TMR
	tst temp		                  ;проверяем ее значение
	brne OFFDEL		         ;если она не ноль, то зацикливаемся, если 0
				                 ;то перезагружаем RELAY_TMR
	ldi temp,RELAY_DEL	
	sts RELAY_TMR,temp		
	cbi OUT_PORT,RELAY_PIN	;Отключаем питание
	cbi OUT_PORT,ON_LED	          ;Гасим "ON" 
	sbi OUT_PORT,STBY_LED	;Зажигаем "STBY"
	ldi temp,0		                   ;сохраняем 
	sts PWR_SW_MODE,temp	;состояние тумблера STBY/ON
PWROUT:	ret			;Выходим

;---------------------------------------------

;Подпрограмма переключения входов

INSW:	sbi OUT_PORT,MUTE_PIN	;Коротим вход усилка
	nop			;Небольшая задержка
	nop			;чтобы ключи MUTE успели 
	nop			;открыться
	nop

SWITCH: in temp,IN_PORT		;Читаем порт D
	andi temp,IN_KONST	;Получаем состояние переключателя
	cpi temp,IN1_ON		;Сраниваем с "условием включенности" входа 1
	brne IN2		          Не равно -> идем дальше, иначе включаем первый	
	sbi OUT_PORT,IN1_PIN	;Включаем 1-й, остальные обнуляем
	cbi OUT_PORT,IN2_PIN
	cbi OUT_PORT,IN3_PIN
	sts IN_SW_MODE,temp	;Сохраняем новое значение IN_SW_MODE
	rjmp DELAY		         ;Идем на DELAY
IN2:	cpi temp,IN2_ON		;Сраниваем с "условием включенности" входа 2
	brne IN3		          ;Не равно -> идем дальше, иначе включаем второй
	cbi OUT_PORT,IN1_PIN	
	sbi OUT_PORT,IN2_PIN	;Включаем 2-й, остальные обнуляем
	cbi OUT_PORT,IN3_PIN
	sts IN_SW_MODE,temp	;Сохраняем новое значение IN_SW_MODE
	rjmp DELAY		         ;Идем на DELAY
	
;Если с IN1_ON и с IN2_ON не совпало, значит тумблер стоит в 3-ем положении. 
;Включаем третий вход.

IN3:	cbi OUT_PORT,IN1_PIN	
	cbi OUT_PORT,IN2_PIN	
	sbi OUT_PORT,IN3_PIN	;Включаем 3-й, остальные обнуляем
	sts IN_SW_MODE,temp	;Сохраняем новое значение IN_SW_MODE

;Вход переключен, формируем задержку на время переключения реле 
;(в 1 интервал переполнения ТС0)
	
DELAY:	lds temp,RELAY_TMR	;Грузим в temp переменную RELAY_TMR
	tst temp		;проверяем ее значение
	brne DELAY		;если она не ноль, то зацикливаемся, если 0
				;то перезагружаем RELAY_TMR
	ldi temp,RELAY_DEL	
	sts RELAY_TMR,temp		


;Задержка сформирована, снимаем Mute и выходим нах..!!
	
	cbi OUT_PORT,MUTE_PIN
OUT:	ret			;выход наверх


;=========================================================

;Обработка прерывания по переполнению таймера 0
;Здесь обслуживаем 2 программых таймера: RELAY_TMR и PWR_SWITCH_TMR

TCOVF:	push temp			;опускаем в стек регистр temp (сохраняем)
	in temp,SREG			;Загружаем SREG в temp
	push temp			;сохраняем SREG в стеке		
	lds temp,RELAY_TMR		;загружаем в temp переменную RELAY_TMR
	tst temp			;проверяем ее значение
	breq OVF_1			;если ноль, то ничего с ней не делаем (идем на метку OVF_1)
	dec temp			;если не ноль, то декрементируем temp
	sts RELAY_TMR,temp		;присваиваем переменной RELAY_TMR новое значение (декрементированное)
OVF_1:	lds temp,PWR_SWITCH_TMR		;Загружаем переменную PWR_SWITCH_TMR
	tst temp			;Проверяем значение
	breq OVF_2			;если ноль, то ничего с ней не делаем (идем на метку OVF_2)
	dec temp			;если не ноль, то декрементируем temp
	sts PWR_SWITCH_TMR,temp		;присваиваем переменной PWR_SWITCH_TMR новое значение (декрементированное)	
OVF_2:	pop temp 			;восстанавливаем SREG
	out SREG,temp			;загружаем temp в SREG
	pop temp			;восстанавливаем регистр temp из стека
	reti				;выход из обработчика и разрешение прерываний

-------------------------------------------------------------------------------------------------------

Вот сильно упрощенная (и сильно условная) схема планируемого устройства:

1696425037de.jpg


......There is someone in my head, but it's not me.......

Вне форума

#34 01.08.2006 21:42:06

Liv
Ветеран
Откуда: Минск
Здесь с 08.02.2004
Сообщений: 1,233

Re: AVR для "чайников"

Текст программы плохо передавать через сообщения форума, теряются табуляции. Пришлите текст программы на почту, не хочу делать исправления в испорченном тексте.

Порты описываете неправильно. Не обязательно делать весь порт выходным или входным. Каждую линию можно настроить индивидуально на ввод или вывод. Лучше сделать так:

#define ENABLE_PIN PORTB,PB0    ;Сигнал ENABLE будем выдавать по линии PB0
#define MUTE_PIN PORTB,PB1        ;Сигнал MUTE будем выдавать по линии РВ1
...
#define TUMB_1 PIND,PD0        ;Первая нога тумблера входов по линии РD0
и т.д.
Далее формируем байт для задания направления портов:
.equ DIRB = (1<<PB0) | (1<<PB1) и еще что надо на вывод
.equ DIRD = 0
Далее формируем байт включения подтягивающих резисторов (если это ввод) или начального состояния портов (если это вывод):
.equ PUPB = что надо установить в единицу после сброса
.equ PUPD = (1<<PD0) | и так далее, на каких входах нужно включить подтягивающие резисторы

Затем при инициализации портов пишем:

ldi    temp,PUPB
out    PORTB,temp ;включаем подтягивающие резисторы/начальное состояние для порта B
ldi    temp,DIRB   
out    DDRB,temp ;задаем направление для порта B
   
ldi    temp,PUPD
out    PORTD,temp ;включаем подтягивающие резисторы/начальное состояние для порта B
ldi    temp,DIRD
out    DDRD,temp ;задаем направление для порта B

Далее в программе переключаем выводы портов так:

sbi ENABLE_PIN
cbi ENABLE_PIN

а опрашиваем так:

sbic TUMB_1
rjmp XXX ;переход на XXX, если бит установлен

По схеме: переключатели и кнопки лучше вешать с порта на землю, а на порту включать pull-up.

Ну и конструкции типа "cpi temp,PWR_SW_MODE" не имеют права на жизнь, прочитайте внимательно и почитайте систему команд.

AVRStudio Вам надо обновить. Ну найдите где-то нормальный Интернет и качните.

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

Отредактировано Liv (01.08.2006 21:42:55)

Вне форума

#35 01.08.2006 22:51:59

adsh
Реалист
Откуда: Киев
Здесь с 16.01.2004
Сообщений: 4,746
Сайт

Re: AVR для "чайников"

Liv пишет:

Текст программы плохо передавать через сообщения форума, теряются табуляции.

Если использовать тег "code" и заменить табуляции соответствующим числом пробелов - всё передастся без искажений.


Саша

Вне форума

#36 01.08.2006 23:11:11

Матроскин
Ветеран
Откуда: Краснодар
Здесь с 06.02.2006
Сообщений: 2,022

Re: AVR для "чайников"

2 Liv
Спасибо за ответ.
Программу я вам на мыло вышлю, но вот тока есть одна проблема. Я что-то сделал со своим tiny2313, теперь он не отвечает программатору. Раньше прошивался (хотя потом и не работало ничего) теперь вообще труп. Толи я его ушатал, толи с фузами что-то напортачил (кстати, ничего в них не пойму !). Завтра возьму его на работу, поставлю на "Тритон" (есть там такой зверский программатор за 250$), хоть проверю, живой он или нет. Ни ваша ни моя программа не заработала у меня на железе. Блин, чем дальше в лес, тем толще партизаны, ёшкин кот... sad


......There is someone in my head, but it's not me.......

Вне форума

#37 02.08.2006 02:48:21

Liv
Ветеран
Откуда: Минск
Здесь с 08.02.2004
Сообщений: 1,233

Re: AVR для "чайников"

2 Матроскин
tiny2313 тем и плоха, что надо заботится о фузах. Хотя их можно и не трогать, с завода включен внутренний RC-генератор на 8 МГц. Для экспериментов пойдет. Вам нужно начинать с самой простой программы, но нужно заставить её работать в железе. Напишите что-то типа

ldi r16,0xff
out DDRB,r16
loop:
inc r16
out PORTB,r16
rjmp loop

и посмотрите осциллографом, то делается на порту B.

Вне форума

#38 02.08.2006 06:58:22

Матроскин
Ветеран
Откуда: Краснодар
Здесь с 06.02.2006
Сообщений: 2,022

Re: AVR для "чайников"

2 Liv доброе утро!
При программировании я ввел следующие значения:
         % Fuse added: WDTON=1
    % Fuse added: RSTDSBL=1
    % Fuse added: CKSEL=6
    % Fuse added: SUT=2
(Программатор AVReal под ByteBlaster), остальные не трогал. Я хотел спросить, есть ли какая возможность онулить эти фузы или хотя бы сбросить на установки по умолчанию?? Просто сначала он определялся и шился, а потом перестал...


......There is someone in my head, but it's not me.......

Вне форума

#39 02.08.2006 08:55:50

Матроскин
Ветеран
Откуда: Краснодар
Здесь с 06.02.2006
Сообщений: 2,022

Re: AVR для "чайников"

Блин, ничего не пойму. На Тритоне есть возможность программировать фузы. Но какое значение брать?? В даташите вот что:
e8d7481a3d80.jpg
Какое значение должен иметь CKSEL для работы с внешним кварцем на 4 МГц?? 1101??


......There is someone in my head, but it's not me.......

Вне форума

#40 02.08.2006 09:52:00

Jaxon
радиолюбовник
Откуда: Николаев
Здесь с 22.01.2004
Сообщений: 3,016

Re: AVR для "чайников"

Своевременнный вопрос.... сегодня как раз тиньку хотел запаивать в макет. а внутренной генератор меня не устраивает

Активен

Сейчас в этой теме пользователей: 0, гостей: 2
[Bot] ClaudeBot,
[Bot] AhrefsBot

Подвал форума

Под управлением FluxBB
Модифицировал Visman

[ Сгенерировано за 0.049 сек, 7 запросов выполнено - Использовано памяти: 667.52 Кбайт (Пик: 717.88 Кбайт) ]