Написать про процесс отладки, хотел давно, но не было удачного примера. Наконец, благодаря тов. FreshMan, у меня появилась возможность как объяснить, зачем это нужно.Во первых, нужно сразу сказать о том, что это за зверь такой отладчик (Debugger). По сути, отладчик это программа, которая показывает нам ход выполнения программы микроконтроллера. Например, известный нам Proteus, позволяет наблюдать за ходом процесса.
На мой взгляд, протеус не всегда удобен. Бытует мнение, что ему нельзя доверять. Однако, рассуждать на тему насколько хорош протеус, нет смысла. Со своей задачей он справляется достаточно хорошо.
Есть круг задач, которые лично мне, проще посмотреть при помощи отладчика фирмы atmel — Avr Studio. Той самой, которая выпускает микроконтроллеры AVR. Не доверять их отладчику нет смысла, кому как не производителю не знать свой микроконтроллер. Я использую Avr Studio 4.19.
Перейдем к поставленной задаче: есть кусочек кода, который непонятно что делает:
OCR1AH = (char)(Bit>>8); //записываем текущую ноту в OCR1A
OCR1AL = (char)Bit;
Чтобы не перебирать тонны кода, создадим новый проект для atmega8. Другие настройки можно не выставлять. Код сразу вычищаем до следующего вида:
#include <mega8.h> void main(void) { while (1) { int Bit=15288; OCR1AH = (char)(Bit>>8); //записываем текущую ноту в OCR1A OCR1AL = (char)Bit; }; } |
Компилируем проект и заходим в меню Tools — Debugger. Запустится Avr Studio Нажимаем Open. Ищем папку со своим проектом, в нем открываем файл с расширением «.cof». Студия задаст вопрос пересохранить проект, соглашаемся. Появится окно с выбором средства отладки выбираем AVR Simulator, используемый микроконтроллер ATmega8. Нажимаем finish.
Появится основное рабочее окно.
Сразу запускаем процесс отладки Debug-Start Debugging. В окошке слева видно Frequency, это рабочая частота микроконтроллера, изменить ее можно в меню Debug-Avr Simulator Options.
Процесс подготовки окончен. Теперь вернемся к нашему вопросу — что делает строчка
OCR1AH = (char)(Bit>>8);
OCR1AL = (char)Bit;
В окошке слева ищем интересующий нас таймер1
Попробуем прошагать по коду при помощи отладчика, кнопкой F11 или Step into, после каждого шага желтая стрелочка смещается к следующей строчке кода. Итак после выполнения строчки
OCR1AH = (char)(Bit>>8);
в регистр OCR1AH записалось число 3B
OCR1AL = (char)Bit;
после выполнения данной строчки в OCR1AL стал равным В8. Откуда же взялись эти строчки?
Представим переменную Bit в разных системах счисления:
в десятичной системе Bit=15288,
в шестнадцатеричной системе Bit=3BB8,
в двоичной системе Bit = 11 1011 1011 1000
Уже кое что начинает проясняться, что за магические 3B и B8, но чтобы до конца понять нужно разобраться с OCR1AH = (char)(Bit>>8);
Операция >> называется логический сдвиг вправо, т.е. нужно переменную Bit сдвинуть на 8 бит в право. Удобно это проводить в двоичной системе.
После сдвига на 1 бит вправо Bit = 0001 1101 1101 1100
После сдвига на 2 бита вправо Bit = 0000 1110 1110 1110
После сдвига на 3 бита вправо Bit = 0000 0111 0111 0111
После сдвига на 8 бит вправо Bit = 0000 0000 0011 1011
Получившееся число 111011 в шестнадцатеричной 3B. Таким образом операция Bit>>8 позволила получить нам старший байт числа 15288.
Причина в том, что в OCR1AL и OCR1AН не может хранить в себе больше одного байта, а число 15288 содержит 2 байта. Поэтому его разбивают на части. Так же становится понятен смысл строчки OCR1AL = (char)Bit;, при такой записи старший байт отбрасывается, т.е. из числа Bit = 11 1011 1011 1000 будет записано только 1011 1000 — те самые В8.
Надеюсь хоть что то стало понятнее)))
OCR1AH = (char)(Bit>>8); со сдвигом понятно и после сдвига присвоению это значения OCR1AH но зачем нужен (char) ???
Bit 16 битное число, чтобы преобразовать его в 8 битное, производится преобразование к char
Не обязательно, можно и так:
{
int Bit=15288;
OCR1AH = Bit >> 8;
OCR1AL = Bit & 0xFF;
}
Уважаемый admin, написал небольшую программу в CVAVR, HEX файл «записал» в контроллер Proteus, но при симуляции получил импульсы PWM только малой ширины.
Решил «программировать» этот МК в Proteus файлом «.asm», получаемым в CVAVR при компиляции. При симуляции получаю сообщение об ошибке : «invalid opcode 0xFFFF at
PC= 0x0602». Что такое opcode? Связано это с неправильно установленными фьюзами?
И как их правильно выставить для Мега 8 и внутренний генератор 8мГц?
Протеус распознает либо hex либо coff. Когда дважды щелкаешь по модели мк, то там можно выбрать int.rc.8mhz
Здравствуйте.Я решил не устанавливать 4 студию тк у меня установлена 6.И тут понял…. что я нихрена не понял)) можно ли писать программы на С в аврстудио 6)под мегу)в начале создания проекта там выбор из 4:
GCC C Executable Project И GCC C Static Library Project Вроде проекты на си)(хотя если честн о я даже не понимаю в чем различие)) тыкнул)на 2 появилось
int function(void)
{
//TODO:: Please write your application code
return 0;
тыкнул на 1
int main(void)
{
while(1)
{
//TODO:: Please write your application code
}
}
я к чему все это.. Я не слишком умный)) XDDD просто в код вижн хоть понятно интуитивно что такое и где таймер помощник с генерируемым пустым кодом. А тут вообще ничерта) Просто на чем основаны программы в авр студио .Если можно коротко))
проект нужно выбирать GCC C Executable Project, а код можно писать тот же самый, можно перетаскивать код туда и обратно, только учитывать некоторые «особенности». И да в студии нет библиотек которые есть в cavr, так что придется или самому писать или искать в инете
А как увидеть обработку прерывания. Проект с таймером Т1 — студия крутится внутри while(1), а в обработчик никак не переходит, а в нём функция из подключенной библиотеки, оно-то должно после переполнения таймера ещё и туда заглянуть. В чём может быть дело?
может прерывания не включены, делается просто — ставится точка останова внутри функции прерывания
А как промониторить прерывание, а ещё лучше, выполнение функции в прерывании, которая описана во внешней библиотеке? Не могу врубиться в чём проблема.
выставить бит в регистре руками, хотя на этот счет мне больше нравится протеус
Просто у меня в прерывании функция динамического отображения на трёх семисегментниках, сама функция описана во внешнем файле, и если инт нормально отображается, то с риалом пока не срослось, а без отладки я не умею. Вобщем пока идея только всунуть всю ф-цию в файл программы, отлаживать, а затем снова выкидывать во внешний файл. Может ещё какие приёмы есть?
Не понял что именно не получилось, но есть еще вариант выводить в UART на комп отладочную информацию. Ну и конечно же протеус)
«На мой взгляд, протеус не всегда удобен. Бытует мнение, что ему нельзя доверять.»
Последняя фраза относится к аналоговому моделированию, в смысле невысокой точности. А что касается цифровой части, в особенности МК, то протеусу почти нет равных. К тому же можно навесить предполагаемую обвязку в схеме, что затруднительно учесть при симуляции в AvrStudio.
Лично мое мнение. Проще собрать отладочную плату со сменными контроллерами и тестировать все в живу.
И дополнить софтовые проблемы железными)))
Зато отладка будет идеальной. Хотя из железных проблем были только умирающие флеш. Но это вылезло за 6 лет перезаливок программ. А вот когда в протеусе работает, а в железе нет, вот тут точно бубен нужен))) Самый веселый глюк у меня был когда я в протеусе проверял работу таймера. В протеусе вместо секунды было около одной десятой, а в железе нормально. С частотами не промахивался. Но в любом случае это как религия, каждый выбирает своё.
Админ, подскажите пожалуйста. У меня когда step доходит до строки с инициализацией i2c — debuger виснет и не желает дальше идти жму кнопку песни ( в дебугере) и снова могу дойти до того-же места. Это по причине того что дебугер уходит в код библиотеки и я просто не вижу шагов или дебугер вообще не может работать с библиотекой?
у вас опрашивается флаг, поэтому и виснет. на железе надо проверять
Спасибо. На железе я всегда проверяю. Тут надо проверить что в переменных творится…