ATMega16 Fast PWM (15) пропуски OCR1A

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
vvchik
Родился
Сообщения: 11
Зарегистрирован: Вс фев 20, 2011 21:37:29

ATMega16 Fast PWM (15) пропуски OCR1A

Сообщение vvchik »

Есть код, который должен генерировать звуковой сигнал переменной частоты.
Использую 16 битный таймер в режиме Fast PWM (15)

Код: Выделить всё

		//generate sound (turning on timer1)
		TCCR1A = 0x43; //COM1A0,WGM11,WGM10 - Toggle OCnA/OCnB/OCnC on compare match + FAST PWM mode15
		TCCR1B = 0x19; // CS10,WGM13,WGM12 
OCR1A обновляется в основном цикле.
по идее он имеет двойной буфер, и должен обновляться только при наступлении прерывания, но у меня регулярно вылазят пропуски, и таймер считает до конца.

Подскажите куда смотреть? явно где-то ошибся.
Обновлять OCR1A в ручную в прерывании не очень хочется.
Реклама
Мастер Ломастер
Поставщик валерьянки для Кота
Сообщения: 1995
Зарегистрирован: Ср май 11, 2011 21:37:45
Откуда: Цветочный город
Контактная информация:

Re: ATMega16 Fast PWM (15) пропуски OCR1A

Сообщение Мастер Ломастер »

вы уверены что не успеваете больше одного раза за период ШИМ обновить OCR1A?
битва с дураками проиграна, победители торжествуют. слава победителям!
Реклама
vvchik
Родился
Сообщения: 11
Зарегистрирован: Вс фев 20, 2011 21:37:29

Re: ATMega16 Fast PWM (15) пропуски OCR1A

Сообщение vvchik »

По идее не успеваю, в коде задержка в 20 мс между обновлениями, но даже если обновлял бы чаще, то там меняется значение в первом буфере пусть хоть 10 раз, а заносится в нужный регистр в момент прерывания, то что в этот буфер попало последним. Если я правильно понимаю даташит.
vvchik
Родился
Сообщения: 11
Зарегистрирован: Вс фев 20, 2011 21:37:29

Re: ATMega16 Fast PWM (15) пропуски OCR1A

Сообщение vvchik »

Я могу весь код выложить, если надо. Просто может, кто сталкивался уже.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: ATMega16 Fast PWM (15) пропуски OCR1A

Сообщение Engineer_Keen »

OCR1AH пишется первым? Запись OCR1A не может прерываться другими операциями записи/чтения 16 битных регистров (которые используют общий регистр TEMP)?
Реклама
vvchik
Родился
Сообщения: 11
Зарегистрирован: Вс фев 20, 2011 21:37:29

Re: ATMega16 Fast PWM (15) пропуски OCR1A

Сообщение vvchik »

Код на си.
я просто заношу десятичное (гы) значение в OCR1A, компилятор сам раскладывает на верхний и нижний регистры.
Но! в коде есть прерывание по второму таймеру, в котором тоже заносятся данные в двойные регистры.

Если прерывание наступило пока данные занесены только в часть 16 битного регистра. А потом мы меняем значение какого-то 16 битного регистра в прерывании, оно что одну переменную использует??
Реклама
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18657
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: ATMega16 Fast PWM (15) пропуски OCR1A

Сообщение ARV »

vvchik писал(а):Если прерывание наступило пока данные занесены только в часть 16 битного регистра. А потом мы меняем значение какого-то 16 битного регистра в прерывании, оно что одну переменную использует??
ДА!!! работа со всеми НЕ ОДНОБАЙТНЫМИ переменными (регистры AVR - тоже переменные с точки зрения Си) происходит НЕ АТОМАРНО! если вы начали менять OCR1A и после записи в OCR1AH произошло прерывание, внутри котрого вы ИЗМЕНЯЕТЕ содержимое той переменной, из которой пишите в регистр - в OCR1AL запишется уже кусочек ОБНОВЛЕННОЙ переменной!!!

если у вас есть такие "узкие" места в программе, используйте util/atomic.h и макрос ATOMIC_BLOCK:

Код: Выделить всё

ATOMIC_BLOCK(ATOMIC_RESTORE_STATE){
   OCR1A = var; // обновление OCR1A гарантированно не будет прервано прерыванием!!!
}
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
vvchik
Родился
Сообщения: 11
Зарегистрирован: Вс фев 20, 2011 21:37:29

Re: ATMega16 Fast PWM (15) пропуски OCR1A

Сообщение vvchik »

Да не меняю я значение ЭТОЙ переменной в прерывании.
Engineer_Keen написал, что при обновлении всех двухбайтных регистров используется некий общий регистр TEMP.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18657
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: ATMega16 Fast PWM (15) пропуски OCR1A

Сообщение ARV »

vvchik писал(а):Да не меняю я значение ЭТОЙ переменной в прерывании.
Engineer_Keen написал, что при обновлении всех двухбайтных регистров используется некий общий регистр TEMP.
ах, вон вы о чем! смотрите, например, главу Output Compare Units в даташите на любой МК 16-битным с таймером - там нарисована диаграмма работы его регистров.
Последний раз редактировалось ARV Пт июн 17, 2011 15:19:00, всего редактировалось 1 раз.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
GP1
Поставщик валерьянки для Кота
Сообщения: 2401
Зарегистрирован: Пт май 23, 2008 19:32:22
Откуда: Россия, Волгоград
Контактная информация:

Re: ATMega16 Fast PWM (15) пропуски OCR1A

Сообщение GP1 »

Дело в том, что в режиме 15, обновление OCR1A происходит при достижении предыдушего значения записанного в OCR1A, теперь допустим что между записью OCR1AH и OCR1AL произошло прерывание, а у вас записан только OCR1AH, что при этом произойдет?
Чем дальше, тем больше становлюсь занудой...
Изображение
Аватара пользователя
Engineer_Keen
Друг Кота
Сообщения: 3872
Зарегистрирован: Пт янв 29, 2010 10:27:40
Откуда: Москва

Re: ATMega16 Fast PWM (15) пропуски OCR1A

Сообщение Engineer_Keen »

Вот что я имел ввиду. Если перевести даташит, получается:
"Регистры OCR - 16 разрядные. Для уверенности в том, что старший и младший байты записываются в эти регистры одновременно, доступ выполняется с использованием временного регистра для старшего байта (TEMP). Этот временный регистр общий для всех 16-битных регистров."
То есть если в коде типа:

Код: Выделить всё

1) пишем в OCR1AH
2) пишем в OCR1AL 
между шагами 1 и 2 возникает прерывание, в котором есть команда типа "пишем что-то в OCR1BH", то после возврата к второй строке кода в регистр OCR1A по команде запишется не тот старший байт, хотя код вроде бы верный. Это только теоретически, сам вроде не сталкивался.

Ага, опередили, долго писал :)))
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»