paskal 1 16 июня, 2015 Опубликовано 16 июня, 2015 · Жалоба Микроконтроллер ATMEGA128A, отправляет серию команд с заданным интервалом, для чего использую таймер 1, режим - сброс при совпадении. Прерыванием не пользуюсь. Просто опрашиваю флаг OCF1A в TIFR. Сбрасываю его программно командой TIFR&=~(1<<OCF1A); Не сбрасывается! И что существенно, программу я пишу не с нуля, а перевожу старый полностью рабочий проект с ассемблера на си. В старой программе было: waittick1: in r16,TIFR sbrs r16,OCF1A rjmp waittick1 cbr r16,OCF1A out TIFR,r16 Это работает. В новой программе: while((TIFR&(1<<OCF1A))==0); TIFR&=~(1<<OCF1A); Это почему то не работает! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vladivolt 0 16 июня, 2015 Опубликовано 16 июня, 2015 · Жалоба Alternatively, OCF1A can be cleared by writing a logic one to its bit location Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
АлександрК 0 17 июня, 2015 Опубликовано 17 июня, 2015 (изменено) · Жалоба Alternatively, OCF1A can be cleared by writing a logic one to its bit location Правильно, все флаги (другого не помню) сбрасываются записью единицы в этот разряд. В старой программе было: waittick1: in r16,TIFR sbrs r16,OCF1A rjmp waittick1 cbr r16,OCF1A out TIFR,r16 Это работает. А как у Вас работало в старой программе? В программе команда "cbr r16,OCF1A" записана неверно. Должно быть "cbr r16,(1<<OCF1A)" . Команда CBR делает сброс разрядов регистров в соотвестствии с маской, т.е. если в Вашем случае OCF1A это 6-й разряд (к примеру, не смотрел для Вашего МК), то маска будет выглядеть как 0b00000110 и сброс будет произведен для 1-го и 2-го разряда, а Ваш 6-й останется несброшенным. К тому же флаги брасываются установкой единицы. Сбрасывать прямым сбросом не пробовал. Зачем отступать от Datasheet? Может в первой редакции программы все удачно сложилось и Вы не заметили неточности при написании программы? Изменено 17 июня, 2015 пользователем Александр1 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 120 17 июня, 2015 Опубликовано 17 июня, 2015 · Жалоба Сбрасываю его программно командой TIFR&=~(1<<OCF1A); Не сбрасывается!Во-первых, как уже написали, этот флаг сбрасывается записью в него единицы (читайте документацию). Во-вторых, запись TIFR |= 1<<OCF1A; тоже будет неправильной, потому что будет сбрасывать все выставленные флаги в этом регистре. Правильной будет запись TIFR = 1<<OCF1A. Насчет спользования инструкции SBI в этом случае не помню, делает ли она чтение-модификацию-запись или нет - надо читать документацию. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
paskal 1 18 июня, 2015 Опубликовано 18 июня, 2015 · Жалоба Может в первой редакции программы все удачно сложилось и Вы не заметили неточности при написании программы? Ну да, теперь выяснил. Прогнал в отладчике. OCF1A это разряд 4. Ассемблерная инструкция "cbr r16,OCF1A" транслируется в команду "andi r16,0xFB". Нужный бит, OCF1A остается = 1 и сбрасывается (а с ним и не нужные биты тоже). Выходит, бывает полезно переводить на другой язык - вылазят малозаметные ошибки. :) Насчет спользования инструкции SBI в этом случае не помню, делает ли она чтение-модификацию-запись или нет - надо читать документацию. Ну на си это уже и не актуально - компилятор сам решит какой инструкцией пользоваться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться