Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Только начинаю
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > MCS51, AVR, PIC, STM8, 8bit
anaconda
Добрый вечер!
Только начинаю пользоваться IAR v5.30 для AVR. Сделал простенькую программку для вывода байта в USART0(контроллер Atmega162). Проверяю в Proteus и вижу, что в USART выводится не то, что должно. Частота кварца 7,372800 MHz baud rate=9600, 8data,1stop,no parity. В чем может быть ошибка?
SergeyTT
А что,если повыбрасывать все обработчики прерываний и переписать tx_uart0() наподобие примера со стр. 172 из даташита на контроллер?
Сергей Борщ
Цитата(anaconda @ Jan 18 2010, 22:13) *
В чем может быть ошибка?
1)Озаглавливайте тему осмысленно. Темы с неинформативными названиями в большинстве случаев попросту игнорируются многими участниками ("идут в сад сразу").
2) переменные, которые изменяются в прерываниях и используются в программе обязательно должны объявляться с квалификатором volatile. Поищите по форуму - это наиболее часто встречаемая ошибка начинающих не обошла и вас.
3) Не используйте "магические числа" в инициализации периферии. То, что у вас рядом написан комментарий не исключает ошибки в процессе перевода битов в число, т.е. комментарий может элементарно не соответствовать коду. У вас в руках мощный инструмент препроцессора и компилятора, используйте его:
Код
#define F_OSC  7372800UL
#define  RS485_BAUDRATE   115200

    UBRR0H = ((unsigned)(F_CPU/(8.0 * RS485_BAUDRATE)-0.5)>>8)&0x0F;
    UBRR0L = ((unsigned)(F_CPU/(8.0 * RS485_BAUDRATE)-0.5))&0xFF;
    UCSR0A = (1<<U2X0);
    UCSR0B = (0<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0)|(1<<RXEN0)|(1<<TXEN0)|(0<<UCSZ02);
    UCSR0C = (1<<UMSEL01)|(0<<UMSEL00)|(0<<UPM01)|(0<<UPM00)|(1<<USBS0)|(1<<UCSZ01)|(1<<UCSZ00);
Такой код элементарно читается даже без комментариев. Ну в крайнем случае заглянуть в даташит на предмет "что же означает эта комбинация битов UCSZ", но не тратить время на перевод обратно из 16-ричного числа в комбинацию битов. По этой причине не проверял правильность ваших магических чисел.
4) ваш код будет работать неэффективно - между байтами будет пауза. Используйте прерывание UDR. Вот совсем свежая дискуссия на тему прерываний UDR и TXC.
Mark71
Слово volatile в переводе означает "изменчивый, непостоянный". В Си к описанию переменной следует добавлять слово volatile, если ее значение может изменяться не в результате выполнения программы, а из-за каких-либо внешних событий. Например, переменная может измениться при выполнении программы-обработчика аппаратного прерывания (см. раздел 2.5). Другой причиной "внезапного" изменения значения переменной может быть переключение между нитями при параллельном программировании (см. 2.6.2) и модификация переменной в параллельной нити.

Необходимо обязательно сообщать компилятору о таких изменчивых переменных. Дело в том, что процессор выполняет все действия с регистрами, а не с элементами памяти. Оптимизирующий компилятор держит значения большинства переменных в регистрах, сводя к минимуму обращения к памяти. Непостоянная переменная может изменить свое значение в памяти, но программа будет по-прежнему использовать значение в регистре, которое осталось прежним. Из-за этого выполнение программы нарушится. Модификатор volatile запрещает даже временно помещать переменную в регистр процессора.

Пример описания переменной:
volatile int inputPort;

Здесь мы описываем целочисленную переменную inputPort и сообщаем компилятору, что ее значение может внезапно меняться в результате каких-либо внешних событий. Этим мы запрещаем компилятору помещать переменную в регистр процессора в целях оптимизации программы.
rezident
Цитата(Mark71 @ Jan 21 2010, 14:46) *
Модификатор volatile запрещает даже временно помещать переменную в регистр процессора.
Не совсем так. Это зависит от особенностей компилятора и архитектуры МК. Есть архитектуры, которые не позволяют производить некоторые операции напрямую с содержимым памяти. Или, например, volatile-переменная имеет разрядность выше, чем нативная разрядность микроконтроллера. В этих случаях volatile-переменная может быть считана в регистры, но копирование ее значения будет предварять каждую операцию с ней.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.