Atmega8 Timer0+Timer1 одновременно не пашут.. :(
-
Cassegrain
- Первый раз сказал Мяу!
- Сообщения: 32
- Зарегистрирован: Ср мар 03, 2010 16:35:42
- Откуда: Tallinn
Atmega8 Timer0+Timer1 одновременно не пашут.. :(
Дано:
Тестер для кабелей. Логика на базе Атмега8.
16-битный Таймер1 работает с предделителем 1/1024 и считает 10 секунд - время испытаний кабеля.
Есть светодиод статуса - горит, значит "Готов к тесту", моргает когда тест производится, то есть в течение 10 секунд, отсчитываемых Таймером0.
Идея такова:при начале теста запускаю 16-битный таймер с предделителем 1/1024 и тут же запускаю 8-битный Таймер0 с предделителем 1/1024 и на переполнениях последнего инвертирую состояние порта, куда включен светодиод статуса - так он моргает.
На словах всё красиво, на деле не пашет. Таймер1 отсчитывает задержку, всё как положено, а Таймер0 не работает. Выдернул код, которым запускал Таймер0, вкатил в чистый проект, скомпилировал и прошлил в Мегу - всё пашет. Как совмещаю два таймера в кучу - не пашет. Где я туплю? Помогите, други!
Тестер для кабелей. Логика на базе Атмега8.
16-битный Таймер1 работает с предделителем 1/1024 и считает 10 секунд - время испытаний кабеля.
Есть светодиод статуса - горит, значит "Готов к тесту", моргает когда тест производится, то есть в течение 10 секунд, отсчитываемых Таймером0.
Идея такова:при начале теста запускаю 16-битный таймер с предделителем 1/1024 и тут же запускаю 8-битный Таймер0 с предделителем 1/1024 и на переполнениях последнего инвертирую состояние порта, куда включен светодиод статуса - так он моргает.
На словах всё красиво, на деле не пашет. Таймер1 отсчитывает задержку, всё как положено, а Таймер0 не работает. Выдернул код, которым запускал Таймер0, вкатил в чистый проект, скомпилировал и прошлил в Мегу - всё пашет. Как совмещаю два таймера в кучу - не пашет. Где я туплю? Помогите, други!
- Реклама
Re: Atmega8 Timer0+Timer1 одновременно не пашут.. :(
Вы действительно тупите! Код-то где? Могу Вас заверить, что таймеры работают вместе без каких-либо проблем, ошибка точно в Вашем коде.Cassegrain писал(а):Дано:
Где я туплю? Помогите, други!
-
Cassegrain
- Первый раз сказал Мяу!
- Сообщения: 32
- Зарегистрирован: Ср мар 03, 2010 16:35:42
- Откуда: Tallinn
Первые два бита TIMSК разрешают прерывание по таймерам О и 1 соответственно.Smirnov писал(а):наверника в начале разрешил прерывание для таймера 0
timsk=0x01; //например, точно биты не знаю
а потом разрешил прерывание для таймера 1
timsk=0x80; //например, точно биты не знаю
в итоге слетела инициализация для таймера 0
![]()
пожалуйста проверь все строки с инициализацией
1)Устанавливаю первые два бита ТИМСК
2)Гружу начальные значения в счётные регистры таймеров
3)Запускаю 16-битный Таймер1, предделитель 1/1024
4)Запускаю 8-битный Таймер0,предделитель 1/1024
Щас, я напишу код снова и скину сюда.
- Реклама
-
Cassegrain
- Первый раз сказал Мяу!
- Сообщения: 32
- Зарегистрирован: Ср мар 03, 2010 16:35:42
- Откуда: Tallinn
Идея: на портах В и С записаны числа 10101010, на нулевой ножке каждого порта светодиод. Порт В подключен к обработчику прерываний Таймера0, порт С - к обработчику прерываний Таймера1.Cassegrain писал(а):Smirnov писал(а): Щас, я напишу код снова и скину сюда.
Обработчики одинаковые - сдвиг вправо даёт то горящий, то погасший светодиод. Теоретически. Практически не пашет почему-то. АВР Студио симулирует работу, при срабатывании обработчика Таймера0 вместо того чтоб сместить 10101010 направо и дать мне 01010101, я получаю на выходе 00001100 и в дальнейшем по прерыванию от Таймера0 ничего с портом В не происходит.
Код:
Код: Выделить всё
.include "m8def.inc"
.MACRO outi
LDI R16,@1 ; This macro copies specific integer to R16
OUT @0,R16 ; and copies R16 content to specific register
.ENDMACRO
.CSEG
.ORG 0x0000 ; CPU starts from 0x0000, but there are
RJMP Reset ; interrupt vectors, so we jump to
; beginning of our program - Reset marker
;INTERRUPT VECTORS
;definitions are copied from m8def.inc and therefore corresponding
; .EQU changed to .ORG and RETI added if no action is needed for
;specific interrupt
.ORG INT0addr ; External Interrupt Request 0
RETI
.ORG INT1addr ; External Interrupt Request 1
RETI
.ORG OC2addr ; Timer/Counter2 Compare Match
RETI
.ORG OVF2addr ; Timer/Counter2 Overflow
RETI
.ORG ICP1addr ; Timer/Counter1 Capture Event
RETI
.ORG OC1Aaddr ; Timer/Counter1 Compare Match A
RETI
.ORG OC1Baddr ; Timer/Counter1 Compare Match B
RETI
.ORG OVF1addr ; Timer/Counter1 Overflow
RJMP Timer1OV ;Move to Timer1OV marker code
.ORG OVF0addr ; Timer/Counter0 Overflow
RJMP Timer0OV
.ORG SPIaddr ; Serial Transfer Complete
RETI
.ORG URXCaddr ; USART, Rx Complete
RETI
.ORG UDREaddr ; USART Data Register Empty
RETI
.ORG UTXCaddr ; USART, Tx Complete
RETI
.ORG ADCCaddr ; ADC Conversion Complete
RETI
.ORG ERDYaddr ; EEPROM Ready
RETI
.ORG ACIaddr ; Analog Comparator
RETI
.ORG TWIaddr ; 2-wire Serial Interface
RETI
.ORG SPMRaddr ; Store Program Memory Ready
RETI
.ORG INT_VECTORS_SIZE ; END OF INTERRUPT VECTORS TABLE
;The Program begins here
Reset: OUTI SPL,low(RAMEND) ; Initialize Stack
OUTI SPH,High(RAMEND)
OUTI DDRB,255 ;port B initialization
OUTI DDRC,255 ;port C initialization
OUTI PORTB,0b10101010
OUTI PORTC,0b10101010
LDI R16,(1<<TOIE0)+(1<<TOIE1) ;Timer1,Timer0 Overflow Interrupt Enable set bit and load to R16
OUT TIMSK, R16 ;Load R16 to TIMSK register
;global interrupts disabled before 16-bit operations
LDI R16, High(65535-100) ; Here loading initial state of count registers
OUT TCNT1H, R16 ; High byte
LDI R16, Low(65535-100) ;
OUT TCNT1L, R16 ; And low byte
SEI ; Global Interrupt enable
LDI R16,1 ; Start Timer1 (without prescaler - 0000 0001 (1Dec)
OUT TCCR1B,R16 ; or with 1024 prescaler - 0000 0101 (5Dec))
OUT TCCR0,R16 ; Start Timer0
Main:
NOP ;Wait for counter overflow, no operation
RJMP Main
Timer1OV:
LDI R17,PORTB ;shift PORTB right - toggle LED
ROR R17
OUT PORTB,R17
RETI ;return
Timer0OV:
LDI R18,PORTC ;shift PORTC right - toggle LED
ROR R18
OUT PORTC,R18
RETI ;return
- Engineer_Keen
- Друг Кота
- Сообщения: 3872
- Зарегистрирован: Пт янв 29, 2010 10:27:40
- Откуда: Москва
Что-то меня смущают строчки "LDI rX,portX"...
Это вроде получается загрузить в rX константу=адресу порта, а не значение самого порта
Разве надо не "IN rX,portX" ?
А второй таймер в AVR Studio вообще не работает, сам недавно мучался, пока тут не сказали
Это вроде получается загрузить в rX константу=адресу порта, а не значение самого порта
Разве надо не "IN rX,portX" ?
А второй таймер в AVR Studio вообще не работает, сам недавно мучался, пока тут не сказали
Последний раз редактировалось Engineer_Keen Ср мар 10, 2010 14:26:48, всего редактировалось 1 раз.
- GP1
- Поставщик валерьянки для Кота
- Сообщения: 2401
- Зарегистрирован: Пт май 23, 2008 19:32:22
- Откуда: Россия, Волгоград
- Контактная информация:
На первый взгляд, то что бросилось в глаза:
1.
в R17 получишь адрес порта $18, а никак не его значение, и соответственно после команды ROR получишь свои 0b00001100.
2.
для чего этот код? если для начальной установки таймер, то она будет выполнена только однажды.
1.
Код: Выделить всё
LDI R17,PORTB ;shift PORTB right - toggle LED2.
Код: Выделить всё
LDI R16, High(65535-100) ; Here loading initial state of count registers
OUT TCNT1H, R16 ; High byte
LDI R16, Low(65535-100) ;
OUT TCNT1L, R16 ; And low byte
-
Cassegrain
- Первый раз сказал Мяу!
- Сообщения: 32
- Зарегистрирован: Ср мар 03, 2010 16:35:42
- Откуда: Tallinn
1. IN вместо LDI?GP1 писал(а):На первый взгляд, то что бросилось в глаза:
1.в R17 получишь адрес порта $18, а никак не его значение, и соответственно после команды ROR получишь свои 0b00001100.Код: Выделить всё
LDI R17,PORTB ;shift PORTB right - toggle LED
2.для чего этот код? если для начальной установки таймер, то она будет выполнена только однажды.Код: Выделить всё
LDI R16, High(65535-100) ; Here loading initial state of count registers OUT TCNT1H, R16 ; High byte LDI R16, Low(65535-100) ; OUT TCNT1L, R16 ; And low byte
2. Это из другого кода выдрано, там надо было так, я так и поместил как было - мне не важна сейчас точность задержки, важно отладить работу таймеров вообще.
- Engineer_Keen
- Друг Кота
- Сообщения: 3872
- Зарегистрирован: Пт янв 29, 2010 10:27:40
- Откуда: Москва
- Pooher
- Мучитель микросхем
- Сообщения: 491
- Зарегистрирован: Вс янв 07, 2007 01:45:48
- Откуда: Российская Федерация, будь она неладна...
LDI - Load immediate (на память)
IN - Load I/O Location
Понятно объясняю?
Portb - константа из .inc файла, посмотрите её значение, и удивитесь: О! Чудо! гдето я её видел, не в значении ли порта?
ЗЫ: АСМ очень коварный, не любит невнимательности.
IN - Load I/O Location
Понятно объясняю?
Portb - константа из .inc файла, посмотрите её значение, и удивитесь: О! Чудо! гдето я её видел, не в значении ли порта?
ЗЫ: АСМ очень коварный, не любит невнимательности.
Научить нельзя, можно научиться. Пифагор.
Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
Вставь недостающие буквы в слово *у*ня. Если у тебя получилось слово кухня, значит ты интеллигентный человек.
-
Cassegrain
- Первый раз сказал Мяу!
- Сообщения: 32
- Зарегистрирован: Ср мар 03, 2010 16:35:42
- Откуда: Tallinn
Спасибо! Всё заработало!Pooher писал(а):LDI - Load immediate (на память)
IN - Load I/O Location
Понятно объясняю?
Portb - константа из .inc файла, посмотрите её значение, и удивитесь: О! Чудо! гдето я её видел, не в значении ли порта?![]()
ЗЫ: АСМ очень коварный, не любит невнимательности.
Стало быть LDI позволяет работать с регистрами, кроме тех, что касаются непосредственно ввода-вывода, т.е PortA-D.
Вот внмательности мне на раздаче в роддоме немного не хватило, так что приходится частенько лбом биться.
-
Cassegrain
- Первый раз сказал Мяу!
- Сообщения: 32
- Зарегистрирован: Ср мар 03, 2010 16:35:42
- Откуда: Tallinn
Прекрасно работают оба таймера. Я думаю не вопрос и третий Таймер2 подключить.Engineer_Keen писал(а):Что-то меня смущают строчки "LDI rX,portX"...
Это вроде получается загрузить в rX константу=адресу порта, а не значение самого порта![]()
Разве надо не "IN rX,portX" ?
А второй таймер в AVR Studio вообще не работает, сам недавно мучался, пока тут не сказали
Просто для того чтобы посмотреть как они работают в АВР Студио надо сначала запустить их без предделителя и включив программу исполняться обратить внимание на счётные регистры TCNT(номер таймера). Если значения меняются, то счётчики пашут. У меня было такое, что не пахал счётчик, но я смотрел в него долго и потом он наконец тикнул. Тогда я посмотрел на счётчик циклов процессора и стало ясно, что он не тикал сразу из за установленного мною же предделителя на 1024. То есть пока 1024 цикла не прошло,он не тикал, а я думал, что он не работает, перепроверял процесс инициализации несколько раз, злился даже, пока наконец не допетрило. О как!
- Engineer_Keen
- Друг Кота
- Сообщения: 3872
- Зарегистрирован: Пт янв 29, 2010 10:27:40
- Откуда: Москва



