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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> USART на АTmega48, не работает
NikitoS-86
сообщение Dec 9 2008, 16:27
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 28
Регистрация: 22-09-08
Пользователь №: 40 380



Доброго времени суток. Значит так, собрал платку на 48 Атмеге, работает, необходимо отправлять данные на ПК... Как топорный вариант выбрал COM-порт. Для этого была взята схемка MAX232, ну вобщем всё по книжке... Однако, не получается даже сделать простешего зеркала=/. При этом ситуация следующая:
- Атмега работает от внешнего кварца в 20 МГц;
- скорость - не важно, пробовал на многих, ни на одной не работает...
- МАХ рабочий, тупо закорачивал ноги - сигнал возвращался тут же...
- если оциллографом смотреть на ногах самой Атмеги, то приходит всегда то, что нужно, а в ответ уходит какая-то ересь... (в моём случае это 0x80)

Ну вот собственно код:
Код
#include <avr/io.h>
#include <avr/interrupt.h>

#define FOSC 20000000 // Clock Speed
#define BAUD 2400
#define MYUBRR FOSC/16/BAUD-1

void USART_Init (unsigned int);

volatile unsigned char buff;

ISR (USART_RX_vect, ISR_BLOCK)
{
    buff=UDR0;
    while ( !( UCSR0A & (1<<UDRE0)) );
    
    UDR0 = buff;    
}

ISR (USART_TX_vect, ISR_BLOCK)
{
    buff=0;
}



void main( void )
{
    sei();
    USART_Init(MYUBRR);
    for(;;);
}

void USART_Init(unsigned int ubrr)
{
UBRR0H = (unsigned char)(ubrr>>8);            
UBRR0L = (unsigned char)ubrr;

UCSR0B |= (1<<RXCIE0);            
UCSR0B |= (1<<TXCIE0);

UCSR0B |= (1<<RXEN0)|(1<<TXEN0);            

UCSR0C = (1<<USBS0)|(3<<UCSZ00);            
}



Может быть кварц слишком быстрый? Но по даташиту ограничения нету на его частоту никаких...
Спасибо.

Сообщение отредактировал NikitoS-86 - Dec 9 2008, 16:29
Go to the top of the page
 
+Quote Post
Палыч
сообщение Dec 9 2008, 16:36
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Вы уверены что вот это будет подсчитано правильно

#define MYUBRR FOSC/16/BAUD-1

Я - не уверен. Посчитайте на калькуляторе и запишите результат:

#define MYUBRR 520 // Как-то так

Кстати, при F=20МГц целые делители для стандартных скоростей не получить...
Go to the top of the page
 
+Quote Post
NikitoS-86
сообщение Dec 9 2008, 16:43
Сообщение #3


Участник
*

Группа: Новичок
Сообщений: 28
Регистрация: 22-09-08
Пользователь №: 40 380



Цитата(Палыч @ Dec 9 2008, 19:36) *
Вы уверены что вот это будет подсчитано правильно

#define MYUBRR FOSC/16/BAUD-1

Я - не уверен. Посчитайте на калькуляторе и запишите результат:

#define MYUBRR 520 // Как-то так

Кстати, при F=20МГц целые делители для стандартных скоростей не получить...

Без разницы, уже пробовал=/ И при этом не только на этой скорости... Пробовал прям ставить цифры даже для интересующей меня (например 115200, т.е. 10) - всёравно на выходе не то... А данная формула - это кусок из даташита... В принципе совершенно естественно, что точно не посчитается... Но не должно же быть так, что вообще другое число...
Go to the top of the page
 
+Quote Post
Палыч
сообщение Dec 9 2008, 16:49
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(NikitoS-86 @ Dec 9 2008, 19:43) *
Но не должно же быть так, что вообще другое число...
Ну, почему же не должно? С какой разрядностью производиятся вычисления? Число 20 000 000 в целое (16 бит) не помещается... Да и деления вовсе не обязаны выполняться в том порядке, в котором записаны...
Go to the top of the page
 
+Quote Post
NikitoS-86
сообщение Dec 9 2008, 16:53
Сообщение #5


Участник
*

Группа: Новичок
Сообщений: 28
Регистрация: 22-09-08
Пользователь №: 40 380



Цитата(Палыч @ Dec 9 2008, 19:49) *
Ну, почему же не должно? С какой разрядностью производиятся вычисления? Число 20 000 000 в целое (16 бит) не помещается... Да и деления вовсе не обязаны выполняться в том порядке, в котором записаны...

Даже когда ставлю туда интересующее меня число, всёравно на выход левое значение выходит...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 9 2008, 16:54
Сообщение #6


Гуру
******

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



Цитата(NikitoS-86 @ Dec 9 2008, 18:27) *
- если оциллографом смотреть на ногах самой Атмеги, то приходит всегда то, что нужно, а в ответ уходит какая-то ересь... (в моём случае это 0x80)
Странно. Уходить не должно вообще. Прерывания приема не разрешены, значит до записи в UDR дело не доходит. Зачем вы используете прерывания, если внутри обработчика все равно ждете в цикле?

Код
UCSR0B |= (1<<RXCIE0);            
UCSR0B |= (1<<TXCIE0);

UCSR0B |= (1<<RXEN0)|(1<<TXEN0);
Каков глубокий смысл этих манипуляций? Почему не написать сразу UCSR0B = (1<<RXCIE0)| (1<<TXCIE0)| (1<<RXEN0)|(1<<TXEN0); и не забыть | (1<<RXСIE0)
Цитата(NikitoS-86 @ Dec 9 2008, 18:27) *
Может быть кварц слишком быстрый? Но по даташиту ограничения нету на его частоту никаких...
Ограничения есть в зависимости от напряжения питания. Красивые графики №131 и 132.
Цитата(Палыч @ Dec 9 2008, 18:36) *
Я - не уверен. Посчитайте на калькуляторе и запишите результат:
Абсолютно глупый совет. А если завтра кварц другой поставят? Снова калькулятор в зубы? А если скорость другая потребуется? А как не забыть все места, в которых надо подправить такие "магические" числа? Или вы думаете, что калькулятор в компиляторе может ошибаться? Тогда надежнее всего писать прямо в кодах - мало ли, ассемблер ошибется и не тот код команды подставит. Чтобы компилятор посчитал правильно, надо ему правильно написать: #define FOSC 20000000ULL Все, дальше вычисления идут в длинных целых. Порядок действий компилятор изменить может лишь в том случае, если это не повлияет на результат.


--------------------
На любой вопрос даю любой ответ
"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
Палыч
сообщение Dec 9 2008, 17:01
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Может fuse CKDIV8 остался запрограммирован? С завода он таким приходит - нужно сбросить в 1
Go to the top of the page
 
+Quote Post
man with no name
сообщение Dec 9 2008, 17:04
Сообщение #8


Частый гость
**

Группа: Свой
Сообщений: 158
Регистрация: 6-08-07
Из: Moscow
Пользователь №: 29 586



попробуйте uart включать после окончательной инициализации (строчку UCSR0B |= (1<<RXEN0)|(1<<TXEN0); поставить после установки параметров uart)

В #define FOSC 20000000 я бы добавил ul (#define FOSC 20000000ul) - не хочется гадать какой тип по умолчанию использует препроцессор.

Ну и убедитесь, что проц работает от внешнего кварца - проверьте fuse-биты. "Вобще другое число" получается, возможно, при работе от внутреннего RC-генератора на 1МГц, либо от 20МГц/8, если бит деления частоты на 8 (CLKDIV8 вроде) оставили сброшенным, как по умолчанию.
Go to the top of the page
 
+Quote Post
Палыч
сообщение Dec 9 2008, 17:07
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(Сергей Борщ @ Dec 9 2008, 19:54) *
Странно. Уходить не должно вообще. Прерывания приема не разрешены, значит до записи в UDR дело не доходит.
Так вот же - разрешены:
Код
UCSR0B |= (1<<RXCIE0);
Go to the top of the page
 
+Quote Post
NikitoS-86
сообщение Dec 9 2008, 17:10
Сообщение #10


Участник
*

Группа: Новичок
Сообщений: 28
Регистрация: 22-09-08
Пользователь №: 40 380



Цитата(Сергей Борщ @ Dec 9 2008, 19:54) *
Странно. Уходить не должно вообще. Прерывания приема не разрешены, значит до записи в UDR дело не доходит. Зачем вы используете прерывания, если внутри обработчика все равно ждете в цикле?


Цитата
Код
UCSR0B |= (1<<RXCIE0);            
UCSR0B |= (1<<TXCIE0);

UCSR0B |= (1<<RXEN0)|(1<<TXEN0);
Каков глубокий смысл этих манипуляций? Почему не написать сразу UCSR0B = (1<<RXCIE0)| (1<<TXCIE0)| (1<<RXEN0)|(1<<TXEN0); и не забыть | (1<<RXСIE0)

Это как это не разрешены? Помоему как раз строчка
UCSR0B |= (1<<RXCIE0);
отвечает за их разрешение, в связи с чем, просто не совсем понятно "и не забыть | (1<<RXСIE0)"...

Цитата
Ограничения есть в зависимости от напряжения питания. Красивые графики №131 и 132.

А это где такая нумерация? Если в даташите, то там все графики в формате "номер главы"-"номер рисунка"
Цитата
...Чтобы компилятор посчитал правильно, надо ему правильно написать: #define FOSC 20000000ULL Все, дальше вычисления идут в длинных целых. Порядок действий компилятор изменить может лишь в том случае, если это не повлияет на результат.

А вот этого не знал - спасибо...

PS: Если где туплю - тыкайте носом=) Целый день перед монитором - уже буквы на мониторе пляшут))

Сообщение отредактировал NikitoS-86 - Dec 9 2008, 17:11
Go to the top of the page
 
+Quote Post
gormih
сообщение Dec 9 2008, 17:37
Сообщение #11


nofb
***

Группа: Свой
Сообщений: 430
Регистрация: 18-05-06
Из: Москва, Зеленоград
Пользователь №: 17 218



Цитата(Сергей Борщ @ Dec 9 2008, 19:54) *
А если завтра кварц другой поставят? Снова калькулятор в зубы? А если скорость другая потребуется? А как не забыть все места, в которых надо подправить такие "магические" числа? Или вы думаете, что калькулятор в компиляторе может ошибаться?

А если поставят кварц, когда ошибка разсинхронизации выйдет за грани допустимой при любых прескалерах - не думали? Именно для исключения подобных неурядиц пользуются так называемыми Code Wizard или Uart calculator. Например в Code Vision это очень хорошо сделано, да и для IAR вроде уже есть плагины.


--------------------
Это не то что вы подумали ...

Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 9 2008, 17:44
Сообщение #12


Гуру
******

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



Цитата(NikitoS-86 @ Dec 9 2008, 19:10) *
Это как это не разрешены? Помоему как раз строчка
UCSR0B |= (1<<RXCIE0);
отвечает за их разрешение, в связи с чем, просто не совсем понятно "и не забыть | (1<<RXСIE0)"...
Это назывется "между глаз лежало". Но цикл в прерывании лишний. Напишите там просто UDR = UDR; В чем смысл прерывания по окончанию передачи тоже не понятно. Хоть ногой там махните smile.gif
Цитата(NikitoS-86 @ Dec 9 2008, 19:10) *
А это где такая нумерация? Если в даташите, то там все графики в формате "номер главы"-"номер рисунка"
Ну, может у меня даташит и старый, 2545D–AVR–07/04, но подобные параметры обычно расположены в разделе про электрические характеристики. Да, скачал свежий - картинки 28.1 и 28.2


--------------------
На любой вопрос даю любой ответ
"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
gormih
сообщение Dec 9 2008, 17:46
Сообщение #13


nofb
***

Группа: Свой
Сообщений: 430
Регистрация: 18-05-06
Из: Москва, Зеленоград
Пользователь №: 17 218



AVR CALCULATOR
Хватит уже п**у мучать, товарищи...
Прикрепленные файлы
Прикрепленный файл  AvrCalc.zip ( 21.27 килобайт ) Кол-во скачиваний: 27
 


--------------------
Это не то что вы подумали ...

Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 9 2008, 17:49
Сообщение #14


Гуру
******

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



Цитата(gormih @ Dec 9 2008, 19:37) *
А если поставят кварц, когда ошибка разсинхронизации выйдет за грани допустимой при любых прескалерах - не думали?
И что будет? В худшем случае на первом же тестовом устройстве связи не будет. Причем сразу ясно, где копать. В лучшем - стоит проверка, вычисляющая получившуюся ошибку и дающая #error или #warning прямо на этапе компиляции. А если вы изменили кварц и из пяти таких "магических" цифр вспомнили поменять только четыре - приятной отладки.


--------------------
На любой вопрос даю любой ответ
"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
gormih
сообщение Dec 9 2008, 18:13
Сообщение #15


nofb
***

Группа: Свой
Сообщений: 430
Регистрация: 18-05-06
Из: Москва, Зеленоград
Пользователь №: 17 218



Цитата(Сергей Борщ @ Dec 9 2008, 20:49) *
И что будет? В худшем случае на первом же тестовом устройстве связи не будет. Причем сразу ясно, где копать. В лучшем - стоит проверка, вычисляющая получившуюся ошибку и дающая #error или #warning прямо на этапе компиляции. А если вы изменили кварц и из пяти таких "магических" цифр вспомнили поменять только четыре - приятной отладки.

Будет именно то, что написал товарищ. А на скорости 2400 при кварце 20 Гц нет таких прескалеров, которые сделали бы уарт работоспособным. Именно поэтому и рекомендую пользовать вышеуказанный софт beer.gif

Хотя, извиняюсь... калькулятор кривоват оказался.
В Code Vision все ок..
А на счет #warning и #error поддреживаю, вопрос только в том - зачем делать то, что уже сделано другими (это кстати к вопросу - может на асме наченм программировать? :-) )


--------------------
Это не то что вы подумали ...

Go to the top of the page
 
+Quote Post

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

 


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


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