реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Только начинаю
anaconda
сообщение Jan 18 2010, 20:13
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 20
Регистрация: 18-11-07
Пользователь №: 32 418



Добрый вечер!
Только начинаю пользоваться IAR v5.30 для AVR. Сделал простенькую программку для вывода байта в USART0(контроллер Atmega162). Проверяю в Proteus и вижу, что в USART выводится не то, что должно. Частота кварца 7,372800 MHz baud rate=9600, 8data,1stop,no parity. В чем может быть ошибка?
Прикрепленные файлы
Прикрепленный файл  Test.rar ( 10.49 килобайт ) Кол-во скачиваний: 24
 
Go to the top of the page
 
+Quote Post
SergeyTT
сообщение Jan 18 2010, 22:09
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 53
Регистрация: 3-07-06
Из: Харьков
Пользователь №: 18 533



А что,если повыбрасывать все обработчики прерываний и переписать tx_uart0() наподобие примера со стр. 172 из даташита на контроллер?

Сообщение отредактировал rezident - Jan 19 2010, 01:08
Причина редактирования: Ненужное цитирование.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 18 2010, 22:20
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(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.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Mark71
сообщение Jan 21 2010, 09:46
Сообщение #4





Группа: Участник
Сообщений: 9
Регистрация: 31-03-08
Пользователь №: 36 358



Слово volatile в переводе означает "изменчивый, непостоянный". В Си к описанию переменной следует добавлять слово volatile, если ее значение может изменяться не в результате выполнения программы, а из-за каких-либо внешних событий. Например, переменная может измениться при выполнении программы-обработчика аппаратного прерывания (см. раздел 2.5). Другой причиной "внезапного" изменения значения переменной может быть переключение между нитями при параллельном программировании (см. 2.6.2) и модификация переменной в параллельной нити.

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

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

Здесь мы описываем целочисленную переменную inputPort и сообщаем компилятору, что ее значение может внезапно меняться в результате каких-либо внешних событий. Этим мы запрещаем компилятору помещать переменную в регистр процессора в целях оптимизации программы.
Go to the top of the page
 
+Quote Post
rezident
сообщение Jan 21 2010, 11:07
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Mark71 @ Jan 21 2010, 14:46) *
Модификатор volatile запрещает даже временно помещать переменную в регистр процессора.
Не совсем так. Это зависит от особенностей компилятора и архитектуры МК. Есть архитектуры, которые не позволяют производить некоторые операции напрямую с содержимым памяти. Или, например, volatile-переменная имеет разрядность выше, чем нативная разрядность микроконтроллера. В этих случаях volatile-переменная может быть считана в регистры, но копирование ее значения будет предварять каждую операцию с ней.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 09:42
Рейтинг@Mail.ru


Страница сгенерированна за 0.01391 секунд с 7
ELECTRONIX ©2004-2016