Пн сен 25, 2017 11:19:51
Вс окт 01, 2017 06:19:15
Вт окт 17, 2017 13:49:46
Вт окт 17, 2017 14:30:25
Вт окт 17, 2017 16:23:55
Я бы использовал таймер (частота 1Гц), в прерывании таймера изменял бы состояние первой пары св-диодов.dumbass писал(а):Программа на АSM для тини2313...Чего хочется: есть две кнопки( с фиксацией). Нажимаем одну - первая пара св-диодов должна моргать (частота 1Гц). Нажимаем вторую кнопку - другая пара св-диодов должна просто засветится.
Вт окт 17, 2017 16:59:42
Ср окт 18, 2017 06:08:23
Ср окт 18, 2017 08:55:40
Ср окт 18, 2017 23:08:12
Чт окт 26, 2017 08:43:22
// Команда для переименования регистров.
.def ZERO=R22;
.def XXX=R23;
.list; // Отоброжения листинга исполнения команды.
.cseg; работаем с програмной памятью а не озу или eeprom
.org 0; устанавливаем начальную позицию строки
rjmp START; Reset Handler
rjmp START; IRQ0 Handler
rjmp START;; PCINT0Z Handler
rjmp START; Timer0 Overflow Handler
rjmp START; EEPROM Ready Handler
rjmp Comparator; Analog Comparator Handler
rjmp ObrobotkaTIM0_COMPA; TIM0_COMPA CompareA Handler
rjmp START; Timer0 CompareB Handler
rjmp START; Watchdog Interrupt Handler
rjmp START; ADC Conversion Handler
//Оброботка прерывания от компаратора
Comparator:
CLI; команда запрещает глобальные прерывания.
cbi DDRB,4; - Устанавливаем порт как на выход,
sbi PORTB,4; - Подкючаем подтягивающий резистор для включения лампы
sei; - команда разрешает глобальные прерывания
reti; - Выход с под программы прерывания
//оброботка прерывания порта INT0, по высокому сигналу.
//Прерывания при совапдении таймера
ObrobotkaTIM0_COMPA:
inc XXX;
reti;
/*Код установки таймера счетчика*/
TIMER:
/*
TIFR0 - регистр индикации флагов прерывания
TOV0 - флаг индикации по переполнению таймера
OCF0A,OCF0B - флаг индикации по совпадению.
OCR0A,OCR0B - регистр установки значения для совпадения.
TCCR0A - регистр управления A;
TCCR0B - регистр управления B;
*TIMSK0 - Регистр выбора режима срабатывания прерывания
TOIE0 - по переполнению, OCIE0A - по совпадению со значанием в регистре А,
OCIE0B - по совпадению со значанием в регистре B.
*/
ldi R16, (1<<OCIE0A);Установка режима по совпадению с А;
out TIMSK0, R16;
ldi R16, 0xFF; Устанавливаем значение при совпадении с А
out OCR0A, R16;
ldi R16, 0x00;// Сбрасываем все флаги таймера
out TIFR0, R16;
/*Скорость работы таймера выбираем СК/1024 - где СК - частота работы микроконтролера
в нашем случаи мы выставляем во fuces clkdiv8 что обеспечит нам частоту 9,6Мhz/8=1,2Mhz значит
скорость работы таймера будет 1,2Mhz/1024=1,17Khz что увеличивает счет значения. Чем меньше
частота тем большее время срабатывания до прерывания*/
ldi R16, (1<<CS02)|(0<<CS01)|(1<<CS00);
out TCCR0B, R16;
ret; //возврат из подпрограммы TIMER:
//Определяем начальные параметры микроконтролера.
START:
CLI; команда запрещает глобальные прерывания.
//инициализация стэка.(установка максимально размера ОЗУ);
ldi R17, RAMEND;
out SPL, R17;
ldi ZERO, 0x00; //Присваеваем значение 0 переменной zero;
//Отключаем аналогово-цифровой преобразователь
CBI ADCSRA, ADEN;
//Подключаем компаратор для сравнения сигналов
////Команда CBI устанавливает значение в 0 регистра ACSR ячейки ASD что включает компаратор - по умолчанию он и так включен;
CBI ACSR, ACD;
//Команда SBI устанавливает значение в 1 регистра ACSR ячейки ACIE которая включает разрешения прерывания от компаратора.
SBI ACSR, ACIE;
//Устанавливаем условие генерации прерывания выставляем изменения сосотояния от 0 до 1;
sbi ACSR, ACIS1;
sbi ACSR, ACIS0;
//инициализация портов ввода вывод
//Устанавливаем работу портов на вход и выход.
//Устанавливаем выходы DDB1 и DDB0 работу на вход для компаратора
//Если порт DDB установлен в 1 то данный порт является входам,
//а если в 0 то выходам.
ldi R16,(0<<DDB5)|(0<<DDB4)|(0<<DDB3)|(0<<DDB2)|(1<<DDB1)|(1<<DDB0);
out DDRB, R16;
//Разрешаем глобальные прерывания
sei;
//Переходим к основному циклу проверки
rjmp START1;
START1:
nop;
rjmp START1;
Чт окт 26, 2017 10:48:51
//Если порт DDB установлен в 1 то данный порт является входам,
//а если в 0 то выходам.
//Отключаем аналогово-цифровой преобразователь
; CBI ADCSRA, ADEN;
//Подключаем компаратор для сравнения сигналов
////Команда CBI устанавливает значение в 0 регистра ACSR ячейки ASD что включает компаратор - по умолчанию он и так включен;
;CBI ACSR, ACD;
//Команда SBI устанавливает значение в 1 регистра ACSR ячейки ACIE которая включает разрешения прерывания от компаратора.
;SBI ACSR, ACIE;
//Устанавливаем условие генерации прерывания выставляем изменения сосотояния от 0 до 1;
LDI R22,1<<ACIS1|1<<ACIS0|1<<ACIE
OUT ACSR,R22
LDI R22,1<<AIN1D|1<<AIN0D
OUT DIDR0,R22
;sbi ACSR, ACIS1;
;sbi ACSR, ACIS0
Чт окт 26, 2017 10:59:57
Чт окт 26, 2017 11:04:28
Чт окт 26, 2017 11:13:31
// Команда для переименования регистров.
.def ZERO=R22;
.def XXX=R23;
.list; // Отоброжения листинга исполнения команды.
.cseg; работаем с програмной памятью а не озу или eeprom
.org 0; устанавливаем начальную позицию строки
rjmp START; Reset Handler
rjmp START; IRQ0 Handler
rjmp START;; PCINT0Z Handler
rjmp START; Timer0 Overflow Handler
rjmp START; EEPROM Ready Handler
rjmp Comparator; Analog Comparator Handler
rjmp ObrobotkaTIM0_COMPA; TIM0_COMPA CompareA Handler
rjmp START; Timer0 CompareB Handler
rjmp START; Watchdog Interrupt Handler
rjmp START; ADC Conversion Handler
//Оброботка прерывания от компаратора
Comparator:
CLI; команда запрещает глобальные прерывания.
sbi PORTB,4; - Подкючаем подтягивающий резистор для включения лампы
sei; - команда разрешает глобальные прерывания
reti; - Выход с под программы прерывания
//оброботка прерывания порта INT0, по высокому сигналу.
//Прерывания при совапдении таймера
ObrobotkaTIM0_COMPA:
inc XXX;
reti;
/*Код установки таймера счетчика*/
TIMER:
/*
TIFR0 - регистр индикации флагов прерывания
TOV0 - флаг индикации по переполнению таймера
OCF0A,OCF0B - флаг индикации по совпадению.
OCR0A,OCR0B - регистр установки значения для совпадения.
TCCR0A - регистр управления A;
TCCR0B - регистр управления B;
*TIMSK0 - Регистр выбора режима срабатывания прерывания
TOIE0 - по переполнению, OCIE0A - по совпадению со значанием в регистре А,
OCIE0B - по совпадению со значанием в регистре B.
*/
ldi R16, (1<<OCIE0A);Установка режима по совпадению с А;
out TIMSK0, R16;
ldi R16, 0xFF; Устанавливаем значение при совпадении с А
out OCR0A, R16;
ldi R16, 0x00;// Сбрасываем все флаги таймера
out TIFR0, R16;
/*Скорость работы таймера выбираем СК/1024 - где СК - частота работы микроконтролера
в нашем случаи мы выставляем во fuces clkdiv8 что обеспечит нам частоту 9,6Мhz/8=1,2Mhz значит
скорость работы таймера будет 1,2Mhz/1024=1,17Khz что увеличивает счет значения. Чем меньше
частота тем большее время срабатывания до прерывания*/
ldi R16, (1<<CS02)|(0<<CS01)|(1<<CS00);
out TCCR0B, R16;
ret; //возврат из подпрограммы TIMER:
//Определяем начальные параметры микроконтролера.
START:
CLI; команда запрещает глобальные прерывания.
//инициализация стэка.(установка максимально размера ОЗУ);
ldi R17, RAMEND;
out SPL, R17;
ldi ZERO, 0x00; //Присваеваем значение 0 переменной zero;
//Отключаем аналогово-цифровой преобразователь
CBI ADCSRA, ADEN;
//Подключаем компаратор для сравнения сигналов
////Команда CBI устанавливает значение в 0 регистра ACSR ячейки ASD что включает компаратор - по умолчанию он и так включен;
CBI ACSR, ACD;
//Команда SBI устанавливает значение в 1 регистра ACSR ячейки ACIE которая включает разрешения прерывания от компаратора.
SBI ACSR, ACIE;
//Устанавливаем условие генерации прерывания выставляем изменения сосотояния от 0 до 1;
sbi ACSR, ACIS1;
sbi ACSR, ACIS0;
//инициализация портов ввода вывод
//Устанавливаем работу портов на вход и выход.
//Устанавливаем выходы DDB1 и DDB0 работу на вход для компаратора
//Если порт DDB установлен в 1 то данный порт является выходам,
//а если в 0 то входам.
ldi R16,(0<<DDB5)|(1<<DDB4)|(0<<DDB3)|(0<<DDB2)|(0<<DDB1)|(0<<DDB0);
out DDRB, R16;
//Разрешаем глобальные прерывания
sei;
//Переходим к основному циклу проверки
rjmp START1;
START1:
nop;
rjmp START1;
Желательно отключать цифровые входы от лап АС
// Команда для переименования регистров.
.def ZERO=R22;
.def XXX=R23;
.list; // Отоброжения листинга исполнения команды.
.cseg; работаем с програмной памятью а не озу или eeprom
.org 0; устанавливаем начальную позицию строки
rjmp START; Reset Handler
rjmp START; IRQ0 Handler
rjmp START;; PCINT0Z Handler
rjmp START; Timer0 Overflow Handler
rjmp START; EEPROM Ready Handler
rjmp Comparator; Analog Comparator Handler
rjmp ObrobotkaTIM0_COMPA; TIM0_COMPA CompareA Handler
rjmp START; Timer0 CompareB Handler
rjmp START; Watchdog Interrupt Handler
rjmp START; ADC Conversion Handler
//Оброботка прерывания от компаратора
Comparator:
CLI; команда запрещает глобальные прерывания.
sbi PORTB,4; - Подкючаем подтягивающий резистор для включения лампы
sei; - команда разрешает глобальные прерывания
reti; - Выход с под программы прерывания
//оброботка прерывания порта INT0, по высокому сигналу.
//Прерывания при совапдении таймера
ObrobotkaTIM0_COMPA:
inc XXX;
reti;
/*Код установки таймера счетчика*/
TIMER:
/*
TIFR0 - регистр индикации флагов прерывания
TOV0 - флаг индикации по переполнению таймера
OCF0A,OCF0B - флаг индикации по совпадению.
OCR0A,OCR0B - регистр установки значения для совпадения.
TCCR0A - регистр управления A;
TCCR0B - регистр управления B;
*TIMSK0 - Регистр выбора режима срабатывания прерывания
TOIE0 - по переполнению, OCIE0A - по совпадению со значанием в регистре А,
OCIE0B - по совпадению со значанием в регистре B.
*/
ldi R16, (1<<OCIE0A);Установка режима по совпадению с А;
out TIMSK0, R16;
ldi R16, 0xFF; Устанавливаем значение при совпадении с А
out OCR0A, R16;
ldi R16, 0x00;// Сбрасываем все флаги таймера
out TIFR0, R16;
/*Скорость работы таймера выбираем СК/1024 - где СК - частота работы микроконтролера
в нашем случаи мы выставляем во fuces clkdiv8 что обеспечит нам частоту 9,6Мhz/8=1,2Mhz значит
скорость работы таймера будет 1,2Mhz/1024=1,17Khz что увеличивает счет значения. Чем меньше
частота тем большее время срабатывания до прерывания*/
ldi R16, (1<<CS02)|(0<<CS01)|(1<<CS00);
out TCCR0B, R16;
ret; //возврат из подпрограммы TIMER:
//Определяем начальные параметры микроконтролера.
START:
CLI; команда запрещает глобальные прерывания.
//инициализация стэка.(установка максимально размера ОЗУ);
ldi R17, RAMEND;
out SPL, R17;
ldi ZERO, 0x00; //Присваеваем значение 0 переменной zero;
//Отключаем аналогово-цифровой преобразователь
CBI ADCSRA, ADEN;
//Подключаем компаратор для сравнения сигналов
LDI R22,1<<ACIS1|1<<ACIS0|1<<ACIE;
OUT ACSR,R22;
LDI R22,1<<AIN1D|1<<AIN0D;//Если какой-либо из входов ADC3-0 используется как аналоговый,
OUT DIDR0,R22;//то в соответствующий бит ADC3D-ADC0D нужно устанавливать логическую единицу.
//Устанавливаем работу портов на вход и выход.
//Устанавливаем выходы DDB1 и DDB0 работу на вход для компаратора
//Если порт DDB установлен в 1 то данный порт является выходам,
//а если в 0 то входам.
ldi R16,(0<<DDB5)|(1<<DDB4)|(0<<DDB3)|(0<<DDB2)|(0<<DDB1)|(0<<DDB0);
out DDRB, R16;
//Разрешаем глобальные прерывания
sei;
//Переходим к основному циклу проверки
rjmp START1;
START1:
nop;
rjmp START1;
Чт окт 26, 2017 15:45:29
Чт окт 26, 2017 20:42:46
Пт окт 27, 2017 07:32:57
восстановитьAlexeyslav писал(а):а перед выходом - освободить
Пт окт 27, 2017 07:57:36
/ Команда для переименования регистров.
.def ZERO=R22;
.def XXX=R23;
.list; // Отоброжения листинга исполнения команды.
.cseg; работаем с програмной памятью а не озу или eeprom
.org 0; устанавливаем начальную позицию строки
rjmp START; Reset Handler
rjmp START; IRQ0 Handler
rjmp START;; PCINT0Z Handler
rjmp START; Timer0 Overflow Handler
rjmp START; EEPROM Ready Handler
rjmp Comparator; Analog Comparator Handler
rjmp START; TIM0_COMPA CompareA Handler
rjmp START; Timer0 CompareB Handler
rjmp START; Watchdog Interrupt Handler
rjmp START; ADC Conversion Handler
//Оброботка прерывания от компаратора
Comparator:
sbi PORTB,4; - Подкючаем подтягивающий резистор для включения лампы
reti; - Выход с под программы прерывания
//оброботка прерывания порта INT0, по высокому сигналу.
//Определяем начальные параметры микроконтролера.
START:
//инициализация стэка.(установка максимально размера ОЗУ);
ldi R17, RAMEND;
out SPL, R17;
ldi ZERO, 0x00; //Присваеваем значение 0 переменной zero;
//Отключаем аналогово-цифровой преобразователь
CBI ADCSRA, ADEN;
//Подключаем компаратор для сравнения сигналов
LDI R22,1<<ACIS1|1<<ACIS0|1<<ACIE;
OUT ACSR,R22;
LDI R24,1<<AIN1D|1<<AIN0D;//Если какой-либо из входов ADC3-0 используется как аналоговый,
OUT DIDR0,R24;//то в соответствующий бит ADC3D-ADC0D нужно устанавливать логическую единицу.
//Устанавливаем работу портов на вход и выход.
//Устанавливаем выходы DDB1 и DDB0 работу на вход для компаратора
//Если порт DDB установлен в 1 то данный порт является выходам,
//а если в 0 то входам.
ldi R16,(0<<DDB5)|(1<<DDB4)|(0<<DDB3)|(0<<DDB2)|(0<<DDB1)|(0<<DDB0);
out DDRB, R16;
//Разрешаем глобальные прерывания
sei;
//Переходим к основному циклу проверки
rjmp START1;
START1:
nop;
rjmp START1;
Пт окт 27, 2017 08:13:08
Вот рабочий пример в протеусе.strengerst писал(а):И все равно нет прерывания по компаратору, спасибо всем за советы учту.
Переделанный код согласно замечанием: Может кто свой небольшой пример на асемблере скинет, что бы компаратор уходил в прерывания.
Пт окт 27, 2017 08:16:49
Адаптировал программу и проверил в железе на tiny2313, благо распиновка и поддержка такая же как tiny13. Работает!strengerst писал(а):Жаль но прерывания все равно нет.
.INCLUDE "tn2313def.inc"
// Команда для переименования регистров.
.def ZERO=R22;
.def XXX=R23;
.list; // Отоброжения листинга исполнения команды.
.cseg; работаем с програмной памятью а не озу или eeprom
.org 0; устанавливаем начальную позицию строки
rjmp START; Reset Handler
.org $0A
rjmp Comparator; Analog Comparator Handler
.org $0D
ObrobotkaTIM0_COMPA:
inc XXX;
reti;
//Оброботка прерывания от компаратора
Comparator:
sbi PINB,4; - Подкючаем подтягивающий резистор для включения лампы
reti; - Выход с под программы прерывания
//Определяем начальные параметры микроконтролера.
START:
//инициализация стэка.(установка максимально размера ОЗУ);
;Initial Value10011111, т.е. для tiny13 две следующие команды не нужны
ldi R17, RAMEND;
out SPL, R17;
ldi ZERO, 0x00; //Присваеваем значение 0 переменной zero;
//инициализация портов ввода вывод
//Устанавливаем работу портов на вход и выход.
//Устанавливаем выходы DDB1 и DDB0 работу на вход для компаратора
//Если порт DDB установлен в 1 то данный порт является выходам,
//а если в 0 то входам.
SBI DDRB,4
; ldi R16,1<<DDB4
; out DDRB, R16;
//Подключаем компаратор для сравнения сигналов
LDI R22,1<<ACIE;1<< ACIS1|1<<ACIS0|1<<ACIE
OUT ACSR,R22
LDI R22,1<< AIN1D|1<<AIN0D
OUT DIDR,R22; отключение цифровых входов от аналоговой части
; OUT DIDR0,R22; отключение цифровых входов от аналоговой части
SBI ACSR,ACI; очистка флага AC
;Alternatively, ACI is cleared by writing a logic one to the flag
; RCALL TIMER
//Разрешаем глобальные прерывания
sei;
START1:
;nop;
rjmp START1;
.EXIT
.INCLUDE "tn13def.inc"
// Команда для переименования регистров.
.def ZERO=R22;
.def XXX=R23;
.list; // Отоброжения листинга исполнения команды.
.cseg; работаем с програмной памятью а не озу или eeprom
.org 0; устанавливаем начальную позицию строки
rjmp START; Reset Handler
.org 5
rjmp Comparator; Analog Comparator Handler
.org 6
ObrobotkaTIM0_COMPA:
inc XXX;
reti;
//Оброботка прерывания от компаратора
Comparator:
;sbi PORTB,4; - Подкючаем подтягивающий резистор для включения лампы
sbi PINB,4; - Подкючаем подтягивающий резистор для включения лампы
reti; - Выход с под программы прерывания
//Определяем начальные параметры микроконтролера.
START:
//инициализация стэка.(установка максимально размера ОЗУ);
;Initial Value10011111, т.е. для tiny13 две следующие команды не нужны
; ldi R17, RAMEND;
; out SPL, R17;
ldi ZERO, 0x00; //Присваеваем значение 0 переменной zero;
//инициализация портов ввода вывод
//Устанавливаем работу портов на вход и выход.
//Устанавливаем выходы DDB1 и DDB0 работу на вход для компаратора
//Если порт DDB установлен в 1 то данный порт является выходам,
//а если в 0 то входам.
SBI DDRB,4
; ldi R16,1<<DDB4
; out DDRB, R16;
//Подключаем компаратор для сравнения сигналов
LDI R22,1<< ACIS1|1<<ACIS0|1<<ACIE
OUT ACSR,R22
LDI R22,1<< AIN1D|1<<AIN0D
OUT DIDR0,R22; отключение цифровых входов от аналоговой части
SBI ACSR,ACI; очистка флага AC
;Alternatively, ACI is cleared by writing a logic one to the flag
; RCALL TIMER
//Разрешаем глобальные прерывания
sei;
START1:
;nop;
rjmp START1;
.EXIT