Карма: 67
Рейтинг сообщений: 1060
Зарегистрирован: Чт сен 18, 2008 12:27:21 Сообщений: 19745 Откуда: Столица Мира Санкт-Петербург
Рейтинг сообщения:0 Медали: 1
Black_Wolf писал(а):
На мой взгляд разницы быть не должно.
А метка Ресет-то где?
_________________ [ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ] Измерить нннада?
EXT_INT0: ret ; IRQ0 Handler EXT_INT1: ret ; IRQ1 Handler TIM2_COMP: ret ; Timer2 Compare Handler ;TIM2_OVF: ret ; Timer2 Overflow Handler TIM1_CAPT: ret ; Timer1 Capture Handler TIM1_COMPA: ret ; Timer1 CompareA Handler TIM1_COMPB: ret ; Timer1 CompareB Handler TIM1_OVF: ret ; Timer1 Overflow Handler TIM0_OVF: ret ; Timer0 Overflow Handler SPI_STC: ret ; SPI Transfer Complete Handler USART_RXC: ret ; USART RX Complete Handler USART_UDRE: ret ; UDR Empty Handler USART_TXC: ret ; USART TX Complete Handler ADC_IRQ: ret ; ADC Conversion Complete Handler EE_RDY: ret ; EEPROM Ready Handler ANA_COMP: ret ; Analog Comparator Handler TWSI: ret ; Two-wire Serial Interface Handler SPM_RDY: ret ; Store Program Memory Ready Handler
TIM2_OVF: ;Timer2 Overflow Handler ;nop ;nop ;nop
cpi Seconds,0 brbs 1, TurnON_VD2 ;BRBS - Branch if Bit in SREG is Set
TurnON_VD1: out PortD, SetOnVD1 inc Seconds rjmp TIM2_OVF_Exit
TurnON_VD2: out PortD, 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 clr Temp cbr Temp, (1<<OCIE2)|(1<<TOIE2) out TIMSK, Temp
;2. Select clock source by setting AS2 as appropriate ;Установить бит AS2 = 1 в регистре ASSR, бит 3 clr Temp sbr Temp, (1<<AS2) out ASSR, Temp
;3. Write new values to TCNT2, OCR2, and TCCR2. ;Записать новые значения в TCNT2 (хранит значение), ;OCR2 (вых. рег-р сравнения), and TCCR2 (рег-р управл-я, вкл. предделителями) clr Temp out TCNT2, Temp out OCR2, Temp ;В программе не используется ;Устанавливаем предделитель = 128 ;32,768 кГц / 128 / 256 => переполнение раз в 1 сек. clr Temp sbr Temp, (1<<CS22)|(0<<CS21)|(1<<CS20) 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, (0<<AS2)|(1<<TCN2UB)|(1<<OCR2UB)|(1<<TCR2UB) brbc SREG_Z, 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. clr Temp sbr Temp, (1<<OCF2)|(1<<TOV2) out TIFR, Temp
;6. Enable interrupts, if needed. ;Разрешаем прерывания по переполнению в Timer/Counter2 ;Записать TOIE2 = 1 (бит 6 в TIMSK) clr Temp sbr Temp, (1<<TOIE2) out TIMSK, Temp ;<END НАСТРОЙКА TIMER/COUNTER2 В АСИНХРОННЫЙ РЕЖИМ>
;Настройка порта C и D на вывод. ldi Temp,0b11111111 out ddrc,Temp out ddrb,Temp clr Temp out PortC, Temp
sei ; Enable interrupts
;<END RESET>
Main:
Ldi Temp, 0b00000001 out PortD, Temp
rjmp Main
Единственно, нужны два hex-файла: 1. Как в коде выше, 2. В прерывании TIM2_OVF есть закомментированные три строки "nop". Раскомментируйте их и скомпилируйте 2-й hex-файл. Поможете?
Кстати, поставил AtmelStudio 6.1, но проблемы с обработчиком прерывания TIM2_OVF теже: если в вышеуказанном коде раскомментировать три строки "nop" (сразу за меткой TIM2_OVF:), то обработчик TIM2_OVF уже не работает в ISIS. :-/
Правда, не понятно что Вы хотите увидеть от этой проги. Вроде, в прерывании идет вывод на порт D, но оный на вывод не настроен. Или настроенный на вывод порт B это ошибка? Также в ступор меня ввела команда
Код:
brbc SREG_Z, Wait_For_Switch_ASSR ;BRBC - Branch if Bit in SREG is Cleared
akl, Испытал в ISIS файлы "TEST1.hex" и "TEST2.hex". Первый работает, второй - нет. Получается, что Atmel Studio v.6.1 у меня работает. Кстати, обратил внимание, что программа "TEST1.hex" каждые 8 - 10 секунд работы замирает на пару секунд.... Почему так получается, пока мне не понятно...впечатление, что что-то с адресом прерывания "TIM2_OVF".
akl писал(а):
Правда, не понятно что Вы хотите увидеть от этой проги. Вроде, в прерывании идет вывод на порт D, но оный на вывод не настроен. Или настроенный на вывод порт B это ошибка?
Цель этой проги - оттестировать прерывание "TIM2_OVF", когда Timer/Counter2 работает в асинхронном режиме. Сегменты, которые загораются на индикаторе, должны моргать раз в 1 сек.
Оба порта C и D настроены на вывод:
Код:
;Настройка порта C и D на вывод. ldi Temp,0b11111111 out ddrc,Temp out ddrb,Temp
К порту С подключены катоды индикаторов, а к порту D - аноды сегментов индикатора (на кнопки не смотрите, к этой проге не относятся):
Также в ступор меня ввела командаКод: brbc SREG_Z, Wait_For_Switch_ASSR ;BRBC - Branch if Bit in SREG is Cleared и, хотя, студия даже не пискнула я её не понимаю.
SREG_Z - это флаг Z в статусном регистре SREG. Из файла "m8def.inc": Спойлер
Цитата:
; SREG - Status Register .equ SREG_C = 0 ; Carry Flag .equ SREG_Z = 1 ; Zero Flag .equ SREG_N = 2 ; Negative Flag .equ SREG_V = 3 ; Two's Complement Overflow Flag .equ SREG_S = 4 ; Sign Bit .equ SREG_H = 5 ; Half Carry Flag .equ SREG_T = 6 ; Bit Copy Storage .equ SREG_I = 7 ; Global Interrupt Enable
"Wait_For_Switch_ASSR" - это цикл "Ждать_Переключения_Регистра_ASSR": Спойлер
Код:
;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, (0<<AS2)|(1<<TCN2UB)|(1<<OCR2UB)|(1<<TCR2UB) brbc SREG_Z, Wait_For_Switch_ASSR ;BRBC - Branch if Bit in SREG is Cleared ;<END Wait_For_Switch_ASSR>
Пока результат ANDI не будет равен нулю, цикл "Wait_For_Switch_ASSR" будет выполняться.
Ух, промахнулся я с одной буквой, правильно так "out ddrd,Temp".
akl писал(а):
Правда, не понятно что Вы хотите увидеть от этой проги. Вроде, в прерывании идет вывод на порт D, но оный на вывод не настроен. Или настроенный на вывод порт B это ошибка?
Да, опечатка.
Из-за опечатки теперь понял, почему "как бы рабочая" программа не работала на реальном железе (думал порты у МК сгорели), но совсем не понятно, почему "как бы рабочая" программа работала в ISIS...
Дополнено: Переписал я прогу. Из обработчика прерывания TIM2_OVF убрал весь функциональный код (перенёс его в основное тело программы), оставил только переменную-флаг. Всё заработало как надо. Для себя пока сделал вывод, что в обработчике прерывания не следует применять инструкции ветвления RJMP. Конечная версия кода (проверено в ISIS и на ATmega8): Спойлер
EXT_INT0: ret ; IRQ0 Handler EXT_INT1: ret ; IRQ1 Handler TIM2_COMP: ret ; Timer2 Compare Handler ;TIM2_OVF: ret ; Timer2 Overflow Handler TIM1_CAPT: ret ; Timer1 Capture Handler TIM1_COMPA: ret ; Timer1 CompareA Handler TIM1_COMPB: ret ; Timer1 CompareB Handler TIM1_OVF: ret ; Timer1 Overflow Handler TIM0_OVF: ret ; Timer0 Overflow Handler SPI_STC: ret ; SPI Transfer Complete Handler USART_RXC: ret ; USART RX Complete Handler USART_UDRE: ret ; UDR Empty Handler USART_TXC: ret ; USART TX Complete Handler ADC_IRQ: ret ; ADC Conversion Complete Handler EE_RDY: ret ; EEPROM Ready Handler ANA_COMP: ret ; Analog Comparator Handler TWSI: ret ; Two-wire Serial Interface Handler SPM_RDY: ret ; Store Program Memory Ready Handler
TIM2_OVF: ;Timer2 Overflow Handler
push Temp in Temp, SREG push Temp
inc Seconds
pop Temp out SREG, Temp pop 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
;НАСТРОЙКА TIMER/COUNTER2 В АСИНХРОННЫЙ РЕЖИМ ;1. Disable the Timer/Counter2 interrupts by clearing OCIE2 and TOIE2. ;Запрепить прерывания, сбросив биты OCIE2 and TOIE2 в регистре TIMSK, биты 7 и 6 clr Temp cbr Temp, (1<<OCIE2)|(1<<TOIE2) out TIMSK, Temp
;2. Select clock source by setting AS2 as appropriate ;Установить бит AS2 = 1 в регистре ASSR, бит 3 clr Temp sbr Temp, (1<<AS2) out ASSR, Temp
;3. Write new values to TCNT2, OCR2, and TCCR2. ;Записать новые значения в TCNT2 (хранит значение), ;OCR2 (вых. рег-р сравнения), and TCCR2 (рег-р управл-я, вкл. предделителями) clr Temp out TCNT2, Temp out OCR2, Temp ;В программе не используется ;Устанавливаем предделитель = 128 ;32,768 кГц / 128 / 256 => переполнение раз в 1 сек. clr Temp sbr Temp, (1<<CS22)|(0<<CS21)|(1<<CS20) 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, (0<<AS2)|(1<<TCN2UB)|(1<<OCR2UB)|(1<<TCR2UB) brbc SREG_Z, 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. clr Temp sbr Temp, (1<<OCF2)|(1<<TOV2) out TIFR, Temp
;6. Enable interrupts, if needed. ;Разрешаем прерывания по переполнению в Timer/Counter2 ;Записать TOIE2 = 1 (бит 6 в TIMSK) clr Temp sbr Temp, (1<<TOIE2) out TIMSK, Temp ;<END НАСТРОЙКА TIMER/COUNTER2 В АСИНХРОННЫЙ РЕЖИМ>
;Вспомогательные переменные ldi Seconds, 0
;Настройка порта C и D на вывод ldi Temp,0b11111111 out ddrc,Temp out ddrd,Temp clr Temp out PortC, Temp
;Включить один сегмент на индикаторе Ldi Temp, 0b00000001 out PortD, Temp
sei ; Enable interrupts
;<END RESET>
Main:
ldi Temp, 0b11100000 sbrc Seconds, 0 ;SBRC - Skip if Bit in Register is Cleared ldi Temp, 0b00011110
ori Temp, 0b00000001 out PortD, Temp
rjmp Main
Также есть вопрос. При прогоне программы регистр TCNT2 не меняет своего значения (ниже прикрепил скрин). Как в Atmel Studio запускать прерывания в режиме отладки? Сначала я попробовал установить бит TOV2 во флаговом регистре прерываний TIFR, но безрезультатно - в прерывание не прыгнул. Появилась ещё мысль - программно увеличивать содержимое TCNT2 и при его переполнении прога должна прыгнуть в обработчик TIM2_OVF. Что скажете?
При прогоне программы регистр TCNT2 не меняет своего значения (ниже прикрепил скрин). Как в Atmel Studio запускать прерывания в режиме отладки?
Ничего для этого не надо делать. Разве что снять предделитель /128 на время отладки. Желательно также назначить тактовую (3.276800МГц), чтобы увидеть правильность формирования интервала. Спойлер
Карма: 9
Рейтинг сообщений: 19
Зарегистрирован: Ср мар 10, 2010 22:28:34 Сообщений: 1287 Откуда: Запад Беларуси
Рейтинг сообщения:0
Можно ли, используя возможности tiny45(85), управлять цветом RGB светодиода? Подключить его к 3 разным выводам микросхемы и управлять цветом. Или нужно искать контроллер с тремя ШИМ?
Подскажите как мне собрать два регистра данных 16-разрядного счетчика в единую переменную на Си? Есть 2 восьмиразрядных регистра TCNT1L и TCNT1H. Мне их нужно слить в одну 16-разр. переменную unsigned int. Как это правильно сделать?
Пробую повторить код программы по этому уроку на atmel studio 6.1. Микроконтроллер atmega16 [youtube]http://www.youtube.com/watch?v=fxfvNA_guF4[/youtube] В симуляторе флаги устанавливаются, а вектор не уходит. Подскажите в чем проблема может быть? Вроде код правильно скопировал, проверял несколько раз. Спойлер
регистр TCNT0. По описанию, он должен считать от 0 до 255. Инкрементируя свое значение при каждом тике процессора...и вызывая прерывание по переполнению при переходе от 0xFF -> 0x00
я хочу его использовать в
Код:
main () { ... unsigned char counter=0; while() {
[b]counter++[/b] } ... }
вместо переменной counter
Но как завести таймер? что бы он только тупо считал.
Код:
TIMSK0 = TIMSK0|(1<<TOIE0); //разрешение таймера как счетчика? TCCR0A = TCCR0A|(1<<WGM00)|(0<<WGM01); //управление модулем таймера/счетчика? режим PWM Phase correct
кажется что это не те настройки регистров...
Что хочу сделать:
Код:
int ShowInPortB(unsigned Char AnyWarible) { PORTB=AnyVarible; }
int main() { ... while(1) { ShowInPortB(TCNT0); } ... }
я считаю, что данный код будет делать следующее: на порту Б у меня при каждом тике будет выводиться значение по нарастающей, по кругу 0-255.
Только как правильно настроить таймер? подскажите пожалуйста
TIMSK0 и TCCR0A настраивать не надо, просто запускается счетчик TCNT0 в регистре TCCR0B и все. Однако, если его запустить с прескалером 1:1, тогда вы не увидите плавного нарастания счета, т.к. счетчик будет увеличиваться с каждым машинным тактом, а цикл программы проходит не за один такт.
Сейчас этот форум просматривают: Google [Bot] и гости: 9
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения