в общем вчера в 2 часа ночи пришло озарение
1) написал функцию загрузки инта в два регистра....оказалось работать через указатели не катит!!! компилятор оптимизирует это дело и иногда старшую часть поменять невозможно!!!!! она остаётся неизменной не смотря на явное её присвоение...смотрел отладчиком в железе!!!!!
2) выставил прерывание по сравнению регистра А и поставил его за 100 тактов до топа.
3) В прерывании торможу таймер, отключаю режим PWM и ПОРТ=0 ДДР=1....в таком режиме за 20 минут наблюдения ни разу не было замечено дергания ни в начале подачи импульсов ни в конце при отключении!
оказалось что в 324 меге нет промежуточного буфера для всего 16-тиразрядного регистра сравнения....только 8 битная защелка....и вот она-то и не обновляет свои данные с реальным регистром если не та последовательность записи!
такая запись -
всё правильно запишет
а вот
оставит старшую часть (0х01) незаписанной...там будет предыдущее значение от правильной записи!!!
У себя я пытался сделать так же как и всегда в атмегах -
и потом просто 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 меге это уже память оперативная