Вы не вошли.
Этот пример не показателен. Загрузка регистров периферии, котрая осуществляется через временный регистр (в данном случае это почти аккумулятор) влияния на среднюю производительность оказывает слабо. Вот математика - другое дело.
Так выглядит сложение 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)
Вне форума
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 ;выход из обработчика и разрешение прерываний -------------------------------------------------------------------------------------------------------
Вот сильно упрощенная (и сильно условная) схема планируемого устройства:
......There is someone in my head, but it's not me.......
Вне форума
Текст программы плохо передавать через сообщения форума, теряются табуляции. Пришлите текст программы на почту, не хочу делать исправления в испорченном тексте.
Порты описываете неправильно. Не обязательно делать весь порт выходным или входным. Каждую линию можно настроить индивидуально на ввод или вывод. Лучше сделать так:
#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)
Вне форума
Вне форума
2 Liv
Спасибо за ответ.
Программу я вам на мыло вышлю, но вот тока есть одна проблема. Я что-то сделал со своим tiny2313, теперь он не отвечает программатору. Раньше прошивался (хотя потом и не работало ничего) теперь вообще труп. Толи я его ушатал, толи с фузами что-то напортачил (кстати, ничего в них не пойму !). Завтра возьму его на работу, поставлю на "Тритон" (есть там такой зверский программатор за 250$), хоть проверю, живой он или нет. Ни ваша ни моя программа не заработала у меня на железе. Блин, чем дальше в лес, тем толще партизаны, ёшкин кот...
......There is someone in my head, but it's not me.......
Вне форума
2 Матроскин
tiny2313 тем и плоха, что надо заботится о фузах. Хотя их можно и не трогать, с завода включен внутренний RC-генератор на 8 МГц. Для экспериментов пойдет. Вам нужно начинать с самой простой программы, но нужно заставить её работать в железе. Напишите что-то типа
ldi r16,0xff
out DDRB,r16
loop:
inc r16
out PORTB,r16
rjmp loop
и посмотрите осциллографом, то делается на порту B.
Вне форума
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.......
Вне форума
Блин, ничего не пойму. На Тритоне есть возможность программировать фузы. Но какое значение брать?? В даташите вот что:
Какое значение должен иметь CKSEL для работы с внешним кварцем на 4 МГц?? 1101??
......There is someone in my head, but it's not me.......
Вне форума
Своевременнный вопрос.... сегодня как раз тиньку хотел запаивать в макет. а внутренной генератор меня не устраивает
Вне форума
[ Сгенерировано за 0.062 сек, 7 запросов выполнено - Использовано памяти: 666.3 Кбайт (Пик: 716.66 Кбайт) ]