; ПРОБНАЯ 2 .include "m2560def.inc" .list .def loop1=R0 ;счетчик 0.1сек .def loop2=R1 ;счетчик 1.0сек .def temp1=R16 .def temp2=R20 .def t1=R17 ;кол-во секунд T1 .def t2=R18 ;кол-во секунд T2 ; ИНИЦИАЛИЗАЦИЯ .cseg .org 0 start: rjmp RESET ; СБРОС #1 rjmp STOP ; внешнее прерывание 0 команда STOP #2 reti ; внешнее прерывание 1 #3 reti ; внешнее прерывание 2 #4 reti ; внешнее прерывание 3 #5 reti ; внешнее прерывание 4 #6 reti ; внешнее прерывание 5 #7 reti ; внешнее прерывание 6 #8 reti ; внешнее прерывание 7 #9 rjmp GO ; внешнее прерывание PCINT0 команда START #10 reti ; внешнее прерывание PCINT1 #11 reti ; внешнее прерывание PCIIN2 #12 reti ; WDT #13 reti ; TIMER2 COMPA #14 reti ; TIMER2 COMPB #15 reti ; TIMER2 OVF #16 reti ; TIMER1 CAPT #17 rjmp TIMER ; TIMER1 COMPA #18 reti ; TIMER1 COMPB #19 reti ; TIMER1 COMPC #20 reti ; TIMER1 OVF #21 reti ; TIMER0 COMPA #22 reti ; TIMER0 COMPB #23 reti ; TIMER0 OVF #24 reti ; SPI, STC #25 reti ; USART0 RX #26 reti ; USART0 UDRE #27 reti ; USART0 TX #28 reti ; ANALOG COMP #29 reti ; ADC #30 reti ; EE READY #31 reti ; TIMER3 CAPT #32 reti ; TIMER3 COMPA #33 reti ; TIMER3 COMPB #34 reti ; TIMER3 COMPC #35 reti ; TIMER3 OVF #36 reti ; USART1 RX #37 reti ; USART1 UDRE #38 reti ; USART1 TX #39 reti ; TWI #40 reti ; SPM READY #41 reti ; TIMER4 CAPT #42 reti ; TIMER4 COMPA #43 reti ; TIMER4 COMPB #44 reti ; TIMER4 COMPC #45 reti ; TIMER4 OVF #46 reti ; TIMER5 CAPT #47 reti ; TIMER5 COMPA #48 reti ; TIMER5 COMPB #49 reti ; TIMER5 COMPC #50 reti ; TIMER5 OVF #51 reti ; USART2 RX #52 reti ; USART2 UDRE #53 reti ; USART2 TX #54 reti ; USART2 RX #55 reti ; USART2 UDRE #56 reti ; USART2 TX #57 ; КОНЕЦ ТАБЛИЦЫ ПРЕРЫВАНИЙ ; ВЕКТОР СБРОСА RESET: LDI R16, HIGH(RAMEND) ;УСТАНОВКА УКАЗАТЕЛЯ СТЕКА SP OUT SPH,R16 LDI R16, LOW(RAMEND) OUT SPL,R16 ; УСТАНОВКА СЧЕТЧИКА ЗАДЕРЖКИ TC1 LDI TEMP1,0x05 LDI TEMP2,0 STS TCCR1B,TEMP1 ; НАСТРОЙКА ПРЕДДЕЛИТЕЛЯ НА 1024 STS TCCR1A,TEMP2 ; ОТКЛЮЧЕНИЕ COM1A,COM1B,COM1C,ШИМ LDI t1,3 ; ЗАДАЕМ ДЛИТЕЛЬНОСТЬ РАБОТЫ СЧЕТЧИКА 3СЕК MOV loop2,t1 ; ЗАНОСИМ КОЛ-ВО СЕКУНД В СЧЕТЧИК LOOP2 LDI TEMP1,0b00000001 OUT EIMSK,TEMP1 ; РАЗРЕШАЕМ ПРЕРЫВАНИЕ INT0 LDI TEMP1,2 STS TIMSK1,TEMP1 ; НАСТРАИВАЕМ ТС1 НА ПРЕРЫВАНИЕ ПО СОВПАДЕНИЮ А SEI ; разрешение прерываний ; НАСТРОЙКА PG НА ВЫХОД LDI TEMP1,15 ;ГРУЗИМ 0b11111 В РАБ РЕГИСТР OUT DDRG,TEMP1 ;НАСТРАИВАЕМ ПОРТ НА ВЫВОД OUT PORTG,TEMP1 ;ВЫВОДИМ В ПОРТ ЕДИНИЦЫ (ОТКЛЮЧАЕМ СВЕТОДИОДЫ) ; НАСТРОЙКА PB5 НА ВЫХОД, ОСТАЛЬНЫЕ БИТЫ ПОРТА НА ВХОД LDI temp1,32 LDI temp2,32 out DDRB,temp1 ; НАСТРОЙКА ПОРТА OUTPUT: out PORTB,temp2 ; ВЫВОД В ПОРТ nop nop nop INPUT: in temp2,PINB ; ЧТЕНИЕ ПОРТА Б ANDI temp2,1 ; маска для чтения 1го бита по флагу Z BRNE SET1 ; ЕСЛИ НЕ НОЛЬ,ТО ЧИТАТЬ ПОРТ LDI temp2,0 ; ноль занесем в порт (зажгем светодиод) JMP OUTPUT ; ВЫВОД НУЛЯ В ПОРТ SET1: out PORTB,temp1 ; ВЫКЛЮЧАЕМ СВЕТИК,ЕСЛИ КНОПКА НЕ НАЖАТА jmp INPUT ; ПЕРЕХОДИМ НА СЧИТЫВАНИЕ ПОРТА STOP: PUSH TEMP1 PUSH TEMP2 LDI TEMP1,62 ; OUT PORTG,TEMP1 ; ВКЛЮЧАЕМ СИД НА PG0 LDI TEMP1,0xF LDI TEMP2,0x42 STS OCR1AH,TEMP1 ; УСТАНАВЛИВАЕМ В РЕГИСТРЫ СОВПАДЕНИЯ ПОСТОЯННУЮ ЗАДЕРЖКИ 1 СЕК STS OCR1AL,TEMP2 LDI TEMP1,0 LDI TEMP2,2 STS TCNT1H,TEMP1 ; ОБНУЛЯЕМ СОДЕРЖИМОЕ СЧЕТНЫХ РЕГИСТРОВ ТС1 STS TCNT1L,TEMP1 ; STS TIMSK1,TEMP2 ; ВКЛЮЧАЕМ ПЕРЕРЫВАНИЕ С ТС1 ПО СОВПАДЕНИЮ POP TEMP2 POP TEMP1 reti GO: reti TIMER: PUSH TEMP1 PUSH TEMP2 CLI TST LOOP2 ; ПРОВЕРЯЕМ,ЕСЛИ 0,ТО УСТАНАВЛИВАЕТСЯ ФЛАГ Z BREQ TIM ; ПЕРЕХОД,ЕСЛИ В LOOP2 НОЛЬ DEC LOOP2 ; УМЕНЬШАЕМ НА 1 LOOP2 LDI TEMP1,0 ; STS TCNT1H,TEMP1 ; ОБНУЛЯЕМ СОДЕРЖИМОЕ СЧЕТНЫХ РЕГИСТРОВ ТС1 STS TCNT1L,TEMP1 TIMEND: POP TEMP2 POP TEMP1 SEI reti TIM: LDI TEMP1,62 OUT PORTG,TEMP1 ; ГАСИМ СВЕТОДИОД MOV loop2,t1 ; ВОССТАНАВЛИВАЕМ СОДЕРЖИМОЕ СЧЕТЧИКА СЕКУНД CLR TEMP1 STS TIMSK1,TEMP1 ; ОТКЛЮЧАЕМ ПРЕРЫВАНИЕ ОТ ТС1 JMP TIMEND
Вот такой маленький код. Жмем на кнопку на PB0, программно на РВ5 зажигаем светодиод (это из первого пробного проекта), кроме того, жмем на кнопку на PD0 (INT0), зажигаем светодиод на PG0, должен запуститься таймер ТС1 и по истечении 3сек после отпускания кнопки потушить светодиод на PG0. Все просто. Системаня частота 4МГц от встроенного RC генератора, предделитель 1024. Насчет таблицы прерываний,вижу косяк,что каждый вектор в памяти занимает 2 байта,потому мое прерывание по INT0 перескакивает джампер на STOP и запускает следующий,расположенный по адресу 0х4 в памяти. Отрезок таблицы векторов из даташита:
Здесь вектора расположены по конкретным адресам в памяти. Но как внести команды конкретно в эти ячейки? Как правильно написать таблицу в AVRStudio? Блин,кажись доперло! Нужно вместо rjmp и reti писать jmp т.к. команда jmp имеет размер 32 бита, а не 16 как две предыдущие. Но прерывания от ТС1 все равно не работают... P.S. извините за то,что все слитно-форматирование текста никак не могу понять здесь
Последний раз редактировалось Gudd-Head Ср окт 23, 2013 13:00:23, всего редактировалось 1 раз.
Для начала, вставляете текст программы -> выделяете его -> нажимаете тег CODE -> если код длинный дополнительно выделяете с предыдущим тегом и нажимаете тег spoiler. Спойлер
Код:
; ПРОБНАЯ 2 .include "m2560def.inc" .list .def loop1=R0 ;счетчик 0.1сек .def loop2=R1 ;счетчик 1.0сек .def temp1=R16 .def temp2=R20 .def t1=R17 ;кол-во секунд T1 .def t2=R18 ;кол-во секунд T2 ; ИНИЦИАЛИЗАЦИЯ .cseg .org 0 start: JMP RESET ; СБРОС #1 jmp STOP ; внешнее прерывание 0 команда STOP #2 ;reti ; внешнее прерывание 1 #3 ;reti ; внешнее прерывание 2 #4 ;reti ; внешнее прерывание 3 #5 ;reti ; внешнее прерывание 4 #6 ;reti ; внешнее прерывание 5 #7 ;reti ; внешнее прерывание 6 #8 ;reti ; внешнее прерывание 7 #9 .org $0012 jmp GO ; внешнее прерывание PCINT0 команда START #10 ;reti ; внешнее прерывание PCINT1 #11 ;reti ; внешнее прерывание PCIIN2 #12 ;reti ; WDT #13 ;reti ; TIMER2 COMPA #14 ;reti ; TIMER2 COMPB #15 ;reti ; TIMER2 OVF #16 ;reti ; TIMER1 CAPT #17 .org $0022 jmp TIMER ; TIMER1 COMPA #18 reti ; TIMER1 COMPB #19 reti ; TIMER1 COMPC #20 reti ; TIMER1 OVF #21 reti ; TIMER0 COMPA #22 reti ; TIMER0 COMPB #23 reti ; TIMER0 OVF #24 reti ; SPI, STC #25 reti ; USART0 RX #26 reti ; USART0 UDRE #27 reti ; USART0 TX #28 reti ; ANALOG COMP #29 reti ; ADC #30 reti ; EE READY #31 reti ; TIMER3 CAPT #32 reti ; TIMER3 COMPA #33 reti ; TIMER3 COMPB #34 reti ; TIMER3 COMPC #35 reti ; TIMER3 OVF #36 reti ; USART1 RX #37 reti ; USART1 UDRE #38 reti ; USART1 TX #39 reti ; TWI #40 reti ; SPM READY #41 reti ; TIMER4 CAPT #42 reti ; TIMER4 COMPA #43 reti ; TIMER4 COMPB #44 reti ; TIMER4 COMPC #45 reti ; TIMER4 OVF #46 reti ; TIMER5 CAPT #47 reti ; TIMER5 COMPA #48 reti ; TIMER5 COMPB #49 reti ; TIMER5 COMPC #50 reti ; TIMER5 OVF #51 reti ; USART2 RX #52 reti ; USART2 UDRE #53 reti ; USART2 TX #54 reti ; USART2 RX #55 reti ; USART2 UDRE #56 reti ; USART2 TX #57 ; КОНЕЦ ТАБЛИЦЫ ПРЕРЫВАНИЙ ; ВЕКТОР СБРОСА RESET: LDI R16, HIGH(RAMEND) ;УСТАНОВКА УКАЗАТЕЛЯ СТЕКА SP OUT SPH,R16 LDI R16, LOW(RAMEND) OUT SPL,R16 ; УСТАНОВКА СЧЕТЧИКА ЗАДЕРЖКИ TC1 LDI TEMP1,0x05 LDI TEMP2,0 STS TCCR1B,TEMP1 ; НАСТРОЙКА ПРЕДДЕЛИТЕЛЯ НА 1024 STS TCCR1A,TEMP2 ; ОТКЛЮЧЕНИЕ COM1A,COM1B,COM1C,ШИМ LDI t1,3 ; ЗАДАЕМ ДЛИТЕЛЬНОСТЬ РАБОТЫ СЧЕТЧИКА 3СЕК MOV loop2,t1 ; ЗАНОСИМ КОЛ-ВО СЕКУНД В СЧЕТЧИК LOOP2 LDI TEMP1,0b00000001 OUT EIMSK,TEMP1 ; РАЗРЕШАЕМ ПРЕРЫВАНИЕ INT0 LDI TEMP1,2 STS TIMSK1,TEMP1 ; НАСТРАИВАЕМ ТС1 НА ПРЕРЫВАНИЕ ПО СОВПАДЕНИЮ А SEI ; разрешение прерываний ; НАСТРОЙКА PG НА ВЫХОД LDI TEMP1,15 ;ГРУЗИМ 0b11111 В РАБ РЕГИСТР OUT DDRG,TEMP1 ;НАСТРАИВАЕМ ПОРТ НА ВЫВОД OUT PORTG,TEMP1 ;ВЫВОДИМ В ПОРТ ЕДИНИЦЫ (ОТКЛЮЧАЕМ СВЕТОДИОДЫ) ; НАСТРОЙКА PB5 НА ВЫХОД, ОСТАЛЬНЫЕ БИТЫ ПОРТА НА ВХОД LDI temp1,32 LDI temp2,32 out DDRB,temp1 ; НАСТРОЙКА ПОРТА OUTPUT: out PORTB,temp2 ; ВЫВОД В ПОРТ nop nop nop INPUT: in temp2,PINB ; ЧТЕНИЕ ПОРТА Б ANDI temp2,1 ; маска для чтения 1го бита по флагу Z BRNE SET1 ; ЕСЛИ НЕ НОЛЬ,ТО ЧИТАТЬ ПОРТ LDI temp2,0 ; ноль занесем в порт (зажгем светодиод) JMP OUTPUT ; ВЫВОД НУЛЯ В ПОРТ SET1: out PORTB,temp1 ; ВЫКЛЮЧАЕМ СВЕТИК,ЕСЛИ КНОПКА НЕ НАЖАТА jmp INPUT ; ПЕРЕХОДИМ НА СЧИТЫВАНИЕ ПОРТА STOP: PUSH TEMP1 PUSH TEMP2 LDI TEMP1,62 ; OUT PORTG,TEMP1 ; ВКЛЮЧАЕМ СИД НА PG0 LDI TEMP1,0xF LDI TEMP2,0x42 STS OCR1AH,TEMP1 ; УСТАНАВЛИВАЕМ В РЕГИСТРЫ СОВПАДЕНИЯ ПОСТОЯННУЮ ЗАДЕРЖКИ 1 СЕК STS OCR1AL,TEMP2 LDI TEMP1,0 LDI TEMP2,2 STS TCNT1H,TEMP1 ; ОБНУЛЯЕМ СОДЕРЖИМОЕ СЧЕТНЫХ РЕГИСТРОВ ТС1 STS TCNT1L,TEMP1 ; STS TIMSK1,TEMP2 ; ВКЛЮЧАЕМ ПЕРЕРЫВАНИЕ С ТС1 ПО СОВПАДЕНИЮ POP TEMP2 POP TEMP1 reti GO: reti TIMER: PUSH TEMP1 PUSH TEMP2 CLI TST LOOP2 ; ПРОВЕРЯЕМ,ЕСЛИ 0,ТО УСТАНАВЛИВАЕТСЯ ФЛАГ Z BREQ TIM ; ПЕРЕХОД,ЕСЛИ В LOOP2 НОЛЬ DEC LOOP2 ; УМЕНЬШАЕМ НА 1 LOOP2 LDI TEMP1,0 ; STS TCNT1H,TEMP1 ; ОБНУЛЯЕМ СОДЕРЖИМОЕ СЧЕТНЫХ РЕГИСТРОВ ТС1 STS TCNT1L,TEMP1 TIMEND: POP TEMP2 POP TEMP1 SEI reti TIM: LDI TEMP1,62 OUT PORTG,TEMP1 ; ГАСИМ СВЕТОДИОД MOV loop2,t1 ; ВОССТАНАВЛИВАЕМ СОДЕРЖИМОЕ СЧЕТЧИКА СЕКУНД CLR TEMP1 STS TIMSK1,TEMP1 ; ОТКЛЮЧАЕМ ПРЕРЫВАНИЕ ОТ ТС1 JMP TIMEND
Использование модульных источников питания открытого типа широко распространено в современных устройствах. Присущие им компактность, гибкость в интеграции и высокая эффективность делают их отличным решением для систем промышленной автоматизации, телекоммуникационного оборудования, медицинской техники, устройств «умного дома» и прочих приложений. Рассмотрим подробнее характеристики и особенности трех самых популярных вариантов AC/DC-преобразователей MW открытого типа, подходящих для применения в промышленных устройствах - серий EPS, EPP и RPS представленных на Meanwell.market.
LDI t1,3 ; ЗАДАЕМ ДЛИТЕЛЬНОСТЬ РАБОТЫ СЧЕТЧИКА 3СЕК MOV loop2,t1 ; ЗАНОСИМ КОЛ-ВО СЕКУНД В СЧЕТЧИК LOOP2 LDI TEMP1,0b00000001 OUT EIMSK,TEMP1 ; РАЗРЕШАЕМ ПРЕРЫВАНИЕ INT0 LDI TEMP1,2 STS TIMSK1,TEMP1 ; НАСТРАИВАЕМ ТС1 НА ПРЕРЫВАНИЕ ПО СОВПАДЕНИЮ А ;************************************************* SER R22 OUT TIFR1,R22 ;************************************************* ;SEI ; разрешение прерываний ; НАСТРОЙКА PG НА ВЫХОД LDI TEMP1,15 ;ГРУЗИМ 0b11111 В РАБ РЕГИСТР OUT DDRG,TEMP1 ;НАСТРАИВАЕМ ПОРТ НА ВЫВОД OUT PORTG,TEMP1 ;ВЫВОДИМ В ПОРТ ЕДИНИЦЫ (ОТКЛЮЧАЕМ СВЕТОДИОДЫ) ; НАСТРОЙКА PB5 НА ВЫХОД, ОСТАЛЬНЫЕ БИТЫ ПОРТА НА ВХОД LDI temp1,32 LDI temp2,32 out DDRB,temp1 ; НАСТРОЙКА ПОРТА OUTPUT: out PORTB,temp2 ; ВЫВОД В ПОРТ nop nop nop SEI
INPUT: in temp2,PINB ; ЧТЕНИЕ ПОРТА Б ANDI temp2,1 ; маска для чтения 1го бита по флагу Z BRNE SET1 ; ЕСЛИ НЕ НОЛЬ,ТО ЧИТАТЬ ПОРТ LDI temp2,0 ; ноль занесем в порт (зажгем светодиод) JMP OUTPUT ; ВЫВОД НУЛЯ В ПОРТ SET1: out PORTB,temp1 ; ВЫКЛЮЧАЕМ СВЕТИК,ЕСЛИ КНОПКА НЕ НАЖАТА Rjmp INPUT ; ПЕРЕХОДИМ НА СЧИТЫВАНИЕ ПОРТА
STOP: PUSH TEMP1 PUSH TEMP2 LDI TEMP1,62 ; OUT PORTG,TEMP1 ; ВКЛЮЧАЕМ СИД НА PG0 LDI TEMP1,0xF LDI TEMP2,0x42 STS OCR1AH,TEMP1 ; УСТАНАВЛИВАЕМ В РЕГИСТРЫ СОВПАДЕНИЯ ПОСТОЯННУЮ ЗАДЕРЖКИ 1 СЕК STS OCR1AL,TEMP2 LDI TEMP1,0 LDI TEMP2,2 STS TCNT1H,TEMP1 ; ОБНУЛЯЕМ СОДЕРЖИМОЕ СЧЕТНЫХ РЕГИСТРОВ ТС1 STS TCNT1L,TEMP1 ; STS TIMSK1,TEMP2 ; ВКЛЮЧАЕМ ПЕРЕРЫВАНИЕ С ТС1 ПО СОВПАДЕНИЮ POP TEMP2 POP TEMP1 reti GO: reti TIMER: PUSH TEMP1 PUSH TEMP2 ;CLI TST LOOP2 ; ПРОВЕРЯЕМ,ЕСЛИ 0,ТО УСТАНАВЛИВАЕТСЯ ФЛАГ Z BREQ TIM ; ПЕРЕХОД,ЕСЛИ В LOOP2 НОЛЬ DEC LOOP2 ; УМЕНЬШАЕМ НА 1 LOOP2 LDI TEMP1,0 ; STS TCNT1H,TEMP1 ; ОБНУЛЯЕМ СОДЕРЖИМОЕ СЧЕТНЫХ РЕГИСТРОВ ТС1 STS TCNT1L,TEMP1 TIMEND: POP TEMP2 POP TEMP1 ;SEI reti TIM: LDI TEMP1,62 OUT PORTG,TEMP1 ; ГАСИМ СВЕТОДИОД MOV loop2,t1 ; ВОССТАНАВЛИВАЕМ СОДЕРЖИМОЕ СЧЕТЧИКА СЕКУНД CLR TEMP1 STS TIMSK1,TEMP1 ; ОТКЛЮЧАЕМ ПРЕРЫВАНИЕ ОТ ТС1 JMP TIMEND
В подробности не вдавался; переделал без комментариев. INT0 работает по низкому уровню????? T1 лучше перевести в режим CTC. Исчезаю.
На сайте есть статья http://radiokot.ru/circuit/power/supply/19/ Хочу осилить программу для этого блока самостоятельно. Вроде всё получается, но не понятно следующее. Я задействовал два таймера Т1 и Т2,настроил их на шим режим, соответственно выходы у меня ОС1А и ОС2. А тут вижу что выход на задание напряжения и тока берётся с выводов ОС1А и ОС1В. Но ведь это выходы только с одного таймера Т1. Как можно одним таймером рулить двумя заданиями.
Ну так у ШИМ период постоянный, только заполнение разное. У таймера 2 регистра сравнения, и каждый рулит своим выходом. Просто задаете в регистры OCR1A и OCR1B разные значения, и все дела. Таймер будет считать сам по себе от 0 до MAX, а на выходах будет 0 или 1 в зависимости от того что больше: значение в соответствующем регистре сравнения или значение счетчика. Так можно хоть 2 (как тут), хоть 100 (не видел таких, но программно можно) каналов сделать с одним таймером/счетчиком.
Зарегистрирован: Сб май 25, 2013 11:52:14 Сообщений: 364
Рейтинг сообщения:0
Пытаюсь добиться на тиньке13 максимальной и нулевой скважности. С fast PWM не выходит. Вроде как Phase Correct PWM должно получиться. Но никак в толк не возьму, какие биты установить в TCCR0A. Помогите, а
Пытаюсь добиться на тиньке13 максимальной и нулевой скважности. С fast PWM не выходит. Вроде как Phase Correct PWM должно получиться. Но никак в толк не возьму, какие биты установить в TCCR0A. Помогите, а
Мяу коты. Голова кипит, а дело на месте стоит не могу разобраться с таймером на тини 13 ТС0. мне нужно во время выполнения программы запустить таймер и по мере счета проверять какое значение он уже насчитал (это без его остановки) затем остановить считать значения. и заново. можете объяснить в какие биты что писать. по возможности с комментариями.
Парни, нужна консультация по асинхронному режиму работы Timer/Counter2 в ATMega8. Суть в том, что не срабатывает прерывание TIM2_OVF (проверял работу в ISIS v.7.7 SP2), хотя рассчитывал на прерывание в 1 сек.
Ниже код проги (ассемблер, набирал в Atmel Studio v6.0.1996 SP2). В прерывании RESET прописаны строки инициализации асинхронного режима T/C2: Спойлер
Код:
.def Temp=R18
.CSEG .ORG 0
rjmp RESET
TIM2_OVF:
;Включить светодиод, подключенный к PC0 ldi Temp, 0b00000001 out PortC, Temp
;Включить светодиод, подключенный к PC1 ldi Temp, 0b00000010 out PortC, Temp
reti
RESET: cli ; Clear the interrupt bit in the status register, disable interrupt execution
;Инициализация стека ldi r16,high(RAMEND); Main program start. RAMEND is the highest 16-bit address in SRAM out SPH,r16 ; Set Stack Pointer to top of RAM ldi r16,low(RAMEND) out SPL,r16
;Настройка порта C на вывод. ldi Temp,0b11111111 out ddrc,Temp
;НАСТРОЙКА TIMER/COUNTER2 В АСИНХРОННЫЙ РЕЖИМ ;1. Disable the Timer/Counter2 interrupts by clearing OCIE2 and TOIE2. ;Запрепить прерывания, сбросив биты OCIE2 and TOIE2 в регистре TIMSK, биты 7 и 6 in Temp, TIMSK cbr Temp, 0b11000000 out TIMSK, Temp
;2. Select clock source by setting AS2 as appropriate ;Установить бит AS2 = 1 в регистре ASSR, бит 3 in Temp, ASSR sbr Temp, 0b00001000 out ASSR, Temp
;3. Write new values to TCNT2, OCR2, and TCCR2. ;Записать новые значения в TCNT2 (хранит значение), ;OCR2 (вых. рег-р сравнения), and TCCR2 (рег-р управл-я, вкл. предделителями) ldi Temp, 0 out TCNT2, Temp out OCR2, Temp ;В программе не используется ;Устанавливаем предделитель = 128 ;32,768 кГц / 128 / 256 => переполнение раз в 1 сек. in Temp, TCCR2 sbr Temp, 0b00000101 out TCCR2, Temp
;4. To switch to asynchronous operation: ;Wait for TCN2UB, OCR2UB, and TCR2UB - биты 2, 1, 0 в ASSR ;В ASSR д.б. значение 0b00001000, проверяем его. Wait_For_Switch_ASSR: in Temp, ASSR andi Temp, 0b00000111 brbc 1, Wait_For_Switch_ASSR ;BRBC - Branch if Bit in SREG is Cleared ;<END Wait_For_Switch_ASSR>
;5. Clear the Timer/Counter2 Interrupt Flags. ;Сбросить флаги прерываний OCF2 и TOV2 (биты 7 и 6 в TIFR), записав в них "1", т.к.: ;Alternatively, OCF2 is cleared by writing a logic one to the flag ;Alternatively, TOV2 is cleared by writing a logic one to the flag. in Temp, TIFR sbr Temp, 0b11000000 out TIFR, Temp
;6. Enable interrupts, if needed. ;Разрешаем прерывания по переполнению в Timer/Counter2 ;Записать TOIE2 = 1 (бит 6 в TIMSK) in Temp, TIMSK sbr Temp, 0b01000000 out TIMSK, Temp ;<END НАСТРОЙКА TIMER/COUNTER2 В АСИНХРОННЫЙ РЕЖИМ>
sei ; Enable interrupts
;<END RESET>
Main:
Ldi Temp, 0b00000100 ;Включить светодиод, подключенный к PC2 out PortC, Temp
rjmp Main
Схема в ISIS ниже. Светится только жёлтый светодиод, подключенный к PC2. Хотя, по идее, через секунду после запуска программы должны засветиться светодиоды, подключенные к PC1 и PC0. На 4-х разрядный индикатор и кнопки не обращайте внимания (от другой проги остались).
Последний раз редактировалось Black_Wolf Вс окт 27, 2013 21:58:36, всего редактировалось 1 раз.
Но, если немного изменить код программы, добавив функционала (что требует добавить в обработчик прерывания RESET новые переменные и их начальные значения), то прерывание TIM2_OVF снова перестаёт работать.
Касаемо директивы .ORG нашел:
Цитата:
.ORG address означет примерно следующее «копать отсюда и до обеда», т.е. до конца памяти. Данный оператор указывает с какого адреса пойдет собственно программа. Обычно используется для создания таблицы прерываний.
Тем не менее, не понятно почему "4" в строке ".ORG 4". Поясните это, пож-та.
В предыдущих софто-испытательных наработках я использовал прерывания TIM0_OVF и TIM1_OVF - всё работало, но такая "шляпа" получилась с TIM2_OVF асинхронного Timer/Counter2....
....кажется разобрался... ".ORG 4" - это адрес вектора прерываний для ATmega8A. Из тех.документации: Спойлер
Изменил в своей проге блок RESET следующим образом: 1. Инициализация стека 2. НАСТРОЙКА TIMER/COUNTER2 В АСИНХРОННЫЙ РЕЖИМ 3. Присвоение нач.значений переменным 4. Настройка порта С на вывод Было - 1, 3, 2, 4. Но в чём разница (один вариант работает, другой нет), пока не понятно. Спойлер
cpi Seconds,0 brbs 1, TurnON_VD2 ;BRBS - Branch if Bit in SREG is Set TurnON_VD1: out PortC, SetOnVD1 inc Seconds rjmp TIM2_OVF_Exit
TurnON_VD2: out PortC, SetOnVD2 dec Seconds
TIM2_OVF_Exit:
reti
RESET: cli ; Clear the interrupt bit in the status register, disable interrupt execution
;Инициализация стека ldi r16,high(RAMEND); Main program start. RAMEND is the highest 16-bit address in SRAM out SPH,r16 ; Set Stack Pointer to top of RAM ldi r16,low(RAMEND) out SPL,r16
;НАСТРОЙКА TIMER/COUNTER2 В АСИНХРОННЫЙ РЕЖИМ ;1. Disable the Timer/Counter2 interrupts by clearing OCIE2 and TOIE2. ;Запрепить прерывания, сбросив биты OCIE2 and TOIE2 в регистре TIMSK, биты 7 и 6 in Temp, TIMSK cbr Temp, 0b11000000 out TIMSK, Temp
;2. Select clock source by setting AS2 as appropriate ;Установить бит AS2 = 1 в регистре ASSR, бит 3 in Temp, ASSR sbr Temp, 0b00001000 out ASSR, Temp
;3. Write new values to TCNT2, OCR2, and TCCR2. ;Записать новые значения в TCNT2 (хранит значение), ;OCR2 (вых. рег-р сравнения), and TCCR2 (рег-р управл-я, вкл. предделителями) ldi Temp, 0 out TCNT2, Temp out OCR2, Temp ;В программе не используется ;Устанавливаем предделитель = 128 ;32,768 кГц / 128 / 256 => переполнение раз в 1 сек. in Temp, TCCR2 sbr Temp, 0b00000101 out TCCR2, Temp
;4. To switch to asynchronous operation: ;Wait for TCN2UB, OCR2UB, and TCR2UB - биты 2, 1, 0 в ASSR ;В ASSR д.б. значение 0b00001000, проверяем его. Wait_For_Switch_ASSR: in Temp, ASSR andi Temp, 0b00000111 brbc 1, Wait_For_Switch_ASSR ;BRBC - Branch if Bit in SREG is Cleared ;<END Wait_For_Switch_ASSR>
;5. Clear the Timer/Counter2 Interrupt Flags. ;Сбросить флаги прерываний OCF2 и TOV2 (биты 7 и 6 в TIFR), записав в них "1", т.к.: ;Alternatively, OCF2 is cleared by writing a logic one to the flag ;Alternatively, TOV2 is cleared by writing a logic one to the flag. in Temp, TIFR sbr Temp, 0b11000000 out TIFR, Temp
;6. Enable interrupts, if needed. ;Разрешаем прерывания по переполнению в Timer/Counter2 ;Записать TOIE2 = 1 (бит 6 в TIMSK) in Temp, TIMSK sbr Temp, 0b01000000 out TIMSK, Temp ;<END НАСТРОЙКА TIMER/COUNTER2 В АСИНХРОННЫЙ РЕЖИМ>
Вроде, должна работать, только светики на PC0, PC1 будут загораться на 8 тактов ядра в секунду. На столько же светик PC2 будет гаснуть. Попробуйте так Спойлер
cpi Seconds,0 BREQ TurnON_VD2 ; brbs 1, TurnON_VD2 ;BRBS - Branch if Bit in SREG is Set TurnON_VD1: EOR SetOnVD1,R22 out PortC, SetOnVD1 inc Seconds rjmp TIM2_OVF_Exit
TurnON_VD2: EOR SetOnVD2,R22 out PortC, SetOnVD2 dec Seconds
TIM2_OVF_Exit:
reti
RESET: cli ; Clear the interrupt bit in the status register, disable interrupt execution
;Инициализация стека ldi r16,high(RAMEND); Main program start. RAMEND is the highest 16-bit address in SRAM out SPH,r16 ; Set Stack Pointer to top of RAM ldi r16,low(RAMEND) out SPL,r16
;НАСТРОЙКА TIMER/COUNTER2 В АСИНХРОННЫЙ РЕЖИМ ;1. Disable the Timer/Counter2 interrupts by clearing OCIE2 and TOIE2. ;Запрепить прерывания, сбросив биты OCIE2 and TOIE2 в регистре TIMSK, биты 7 и 6 in Temp, TIMSK cbr Temp, 0b11000000 out TIMSK, Temp
;2. Select clock source by setting AS2 as appropriate ;Установить бит AS2 = 1 в регистре ASSR, бит 3 in Temp, ASSR sbr Temp, 0b00001000 out ASSR, Temp
;3. Write new values to TCNT2, OCR2, and TCCR2. ;Записать новые значения в TCNT2 (хранит значение), ;OCR2 (вых. рег-р сравнения), and TCCR2 (рег-р управл-я, вкл. предделителями) ldi Temp, 0 out TCNT2, Temp out OCR2, Temp ;В программе не используется ;Устанавливаем предделитель = 128 ;32,768 кГц / 128 / 256 => переполнение раз в 1 сек. in Temp, TCCR2 sbr Temp, 0b00000101 out TCCR2, Temp
;4. To switch to asynchronous operation: ;Wait for TCN2UB, OCR2UB, and TCR2UB - биты 2, 1, 0 в ASSR ;В ASSR д.б. значение 0b00001000, проверяем его. Wait_For_Switch_ASSR: in Temp, ASSR andi Temp, 0b00000111 brbc 1, Wait_For_Switch_ASSR ;BRBC - Branch if Bit in SREG is Cleared ;<END Wait_For_Switch_ASSR>
;5. Clear the Timer/Counter2 Interrupt Flags. ;Сбросить флаги прерываний OCF2 и TOV2 (биты 7 и 6 в TIFR), записав в них "1", т.к.: ;Alternatively, OCF2 is cleared by writing a logic one to the flag ;Alternatively, TOV2 is cleared by writing a logic one to the flag. in Temp, TIFR sbr Temp, 0b11000000 out TIFR, Temp
;6. Enable interrupts, if needed. ;Разрешаем прерывания по переполнению в Timer/Counter2 ;Записать TOIE2 = 1 (бит 6 в TIMSK) in Temp, TIMSK sbr Temp, 0b01000000 out TIMSK, Temp ;<END НАСТРОЙКА TIMER/COUNTER2 В АСИНХРОННЫЙ РЕЖИМ>
Предполагаю, что Atmel Studio 6.0.1996 SP2 косячит. Сегодня скачаю новый релиз Atmel Studio 6.1 update 2.0 (build 2730), попробую его. Потом отпишусь...
Сейчас этот форум просматривают: tanhamon и гости: 11
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения