Временное отключение таймера Атмега

Обсуждаем контроллеры компании Atmel.
Ответить
Поставщик валерьянки для Кота
Сообщения: 1957
Зарегистрирован: Пт окт 31, 2008 09:38:55
Откуда: Одесса

Сообщение clawham »

Есть атмега 324, на ней заведен таймер 1 (16 битный) на 1 мегагерце, fast pwm icr top.

считаю до 10000.
задействован один аппаратный выход - OCR1B как неинвертированный.

на нем висит сервопривод в которого нужно посылать импульсы 900-2200 наносекунд...но сервопривод крутит кран и он сопротивляется вращению только в момент передвижения... а если серву долбить постоянно одинаковыми импульсами - она рыскает дергается и греет мотор, кушает энергию и т.д.

потому обновляю я положение раз в десять секунд - ставлю TCCR1A = 0x22 и ШИМ пошел на выход, модифицирую требуемое положение OCR1B и жду секунду....потом хочу заглушить генерацию! Глушу TCCR1A = 0x02? регистр сравнения не трогаю.
Но получаю иногда глитчи с странными периодами в 2000 3000 наносек и серва рвется в край до упору...мощная сильно :)

уже три часа ловлю эти глюки...надоело...как правильно этот самый ШИМ глушить....надо бы дождаться конца цикла...и по идее регистры и обновляются в конце цикла чтоб глюков не допустить....но...дергается...обидно...
Что нас не убило сделало нас осторожней
Не доверяйте русским лужам - это может быть вход в метро.
Контактная информация:
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

Сообщение blackx »

Не совсем понял какого характера глюки вы наблюдаете, но таймер всегда можно легко и надежно приостановить выставляя биты CS10:2 регистра TCCR1B в 0 (отключая частоту).
Изображение only pure true norwegian blackx Изображение
Реклама
Поставщик валерьянки для Кота
Сообщения: 1957
Зарегистрирован: Пт окт 31, 2008 09:38:55
Откуда: Одесса

Сообщение clawham »

приостановка может прийтись на вывод единички в ноге...результат - улетевшая в упор серва!

ну допустим выводил я 1500 в серву
она встала на 45 градусов....через секунду в момент снятия сигнала она может на микрон дернуться не туда....или в упор улететь..инерцию никто не отменял ибо без управляющего сигнала её электроника не управляет двигателем - он обесточен...но он получил толчек...

нужно именно отработать последнюю длительность в 1500 и всё...больше в единицу вывод подниматься не должен а он иногда в момент отключения дрынькает...
Что нас не убило сделало нас осторожней
Не доверяйте русским лужам - это может быть вход в метро.
Контактная информация:
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

Сообщение blackx »

Ну, а если просто регистры сравнения в 0 выставить?
Изображение only pure true norwegian blackx Изображение
Реклама
Эиком - электронные компоненты и радиодетали
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

Можно еще СОМы на ноль сбросить, вывести в порт "0" и остановить таймер.
Реклама
Поставщик валерьянки для Кота
Сообщения: 1957
Зарегистрирован: Пт окт 31, 2008 09:38:55
Откуда: Одесса

Сообщение clawham »

в общем вчера в 2 часа ночи пришло озарение :)

1) написал функцию загрузки инта в два регистра....оказалось работать через указатели не катит!!! компилятор оптимизирует это дело и иногда старшую часть поменять невозможно!!!!! она остаётся неизменной не смотря на явное её присвоение...смотрел отладчиком в железе!!!!!

2) выставил прерывание по сравнению регистра А и поставил его за 100 тактов до топа.
3) В прерывании торможу таймер, отключаю режим PWM и ПОРТ=0 ДДР=1....в таком режиме за 20 минут наблюдения ни разу не было замечено дергания ни в начале подачи импульсов ни в конце при отключении!

оказалось что в 324 меге нет промежуточного буфера для всего 16-тиразрядного регистра сравнения....только 8 битная защелка....и вот она-то и не обновляет свои данные с реальным регистром если не та последовательность записи!

такая запись -

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

OCR1BH=0x01;
OCR1BL=0x02; 
всё правильно запишет
а вот

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

OCR1BL=0x02; 
OCR1BH=0x01;
оставит старшую часть (0х01) незаписанной...там будет предыдущее значение от правильной записи!!!

У себя я пытался сделать так же как и всегда в атмегах -

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

#define OCR1B (*(unsigned int *) 0x8a) 
и потом просто OCR1B = 2000;

вот иногда оно проканывает а иногда оптимизатор какие-то другие функции вызывает и получается не тот порядок!
один рас скомпилировал - нормально работает, одну строку поменял и хоп...уже туфта!

Не понятно почему но в атмеге8 на том же компиляторе я спокойно так мож пользоваться присвоением...а в 324 - вот такие вот глюки !

Вот пример записи инта в регистр сравнения тиньки 2313

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

; 0000 00ED             OCR0B = Inp_B;
	LDS  R30,_Inp_B
	OUT  0x3C,R30
; 0000 00EE       }

а вот во что превратился код записи инта в 324 меге

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

; 0000 00A4       {
; 0000 00A5       // Place your code here
; 0000 00A6       unsigned int a=0;
; 0000 00A7 
; 0000 00A8       OCR1B=a;
	SBIW R28,2
	LDI  R30,LOW(0)
	ST   Y,R30
	STD  Y+1,R30
;	a -> Y+0
	LD   R30,Y
	LDD  R31,Y+1
	STS  138,R30
	STS  138+1,R31
; 0000 00A9       a++;
	ADIW R30,1
	ST   Y,R30
	STD  Y+1,R31
; 0000 00AA 
; 0000 00AB       }

Все дело оказалось в том что адрес регистра в тиньке находится в пределах действия команды OUT
а в 324 меге это уже память оперативная
Последний раз редактировалось clawham Вт ноя 19, 2013 13:52:04, всего редактировалось 1 раз.
Что нас не убило сделало нас осторожней
Не доверяйте русским лужам - это может быть вход в метро.
Контактная информация:
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1518
Зарегистрирован: Пт дек 28, 2012 21:56:46
Откуда: St. Petersburg

Сообщение blackx »

:facepalm: :))) ох уж эти приколы avr-gcc
Изображение only pure true norwegian blackx Изображение
Поставщик валерьянки для Кота
Сообщения: 1957
Зарегистрирован: Пт окт 31, 2008 09:38:55
Откуда: Одесса

Сообщение clawham »

Дак всё бы ладно ну... блин...примите вы правило писать сначала старший байт а потом младший или наоборот..оно бы хоть тогда или вообще не работало или я бы не знал этой проблемы :) а то блин....вначале проги пишеш OCR1B = 1200; и оно срабатывает а в теле цикла пишеш
unsigned int a=1200;
OCR1B=a;

а тебе уже кукиш...сначала младшую часть писануло потом старшую....пипец млин...
Что нас не убило сделало нас осторожней
Не доверяйте русским лужам - это может быть вход в метро.
Контактная информация:
Вымогатель припоя
Сообщения: 630
Зарегистрирован: Пн июн 14, 2010 13:07:29
Откуда: Жуковский

Сообщение a_skr »

Как Вы такое получили, чтобы сначала младший байт записывался???
Сколько работаю в WinAVR - никогда не сталкивался с подобным.

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

int main(void)
{
  94:	df 93       	push	r29
  96:	cf 93       	push	r28
  98:	00 d0       	rcall	.+0      	; 0x9a <main+0x6>
  9a:	cd b7       	in	r28, 0x3d	; 61
  9c:	de b7       	in	r29, 0x3e	; 62
while(1)
{
volatile unsigned int a=1200;
  9e:	20 eb       	ldi	r18, 0xB0	; 176
  a0:	34 e0       	ldi	r19, 0x04	; 4
  a2:	3a 83       	std	Y+2, r19	; 0x02
  a4:	29 83       	std	Y+1, r18	; 0x01
OCR1B = a;
  a6:	89 81       	ldd	r24, Y+1	; 0x01
  a8:	9a 81       	ldd	r25, Y+2	; 0x02
  aa:	90 93 8b 00 	sts	0x008B, r25 --- старший
  ae:	80 93 8a 00 	sts	0x008A, r24 --- младший
a++;
  b2:	89 81       	ldd	r24, Y+1	; 0x01
  b4:	9a 81       	ldd	r25, Y+2	; 0x02
  b6:	01 96       	adiw	r24, 0x01	; 1
  b8:	9a 83       	std	Y+2, r25	; 0x02
  ba:	89 83       	std	Y+1, r24	; 0x01
  bc:	f2 cf       	rjmp	.-28     	; 0xa2 <main+0xe>
Ответить

Вернуться в «AVR»