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

 
 
> 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
 
Start new topic
Ответов
NikitoS-86
сообщение Dec 10 2008, 09:07
Сообщение #2


Участник
*

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



Значится так...
1) Всем спасибо, поскольку полезной инфы для себя ещё подчерпнул...
2) Правы оказались товарищи Палыч и man with no name, сегодня первым делом прочитал, что было написано в ветке и за место 20 Мгц поставил 2,5 Мгц (как деление на 8) - всё заработало... Для меня если честно стало сюрпризом... Поясню почему - когда прошивал фьюзы - был абсолютно уверен, что если выбрать в закладке фьюзов в последней строке что-то типа внешнего тактового источника и нажать програм, то всё будет как надо... Как видно я ошибался... Разве это не так? К тому же теперь я не доберусь до фьюзов никак, поскольку у меня на руках mk2, то теперь он мне не даст без СТК500 добраться до фьюзов... Или я опять ошибаюсь?

3) Теперь по поводу моего кода... Да, прерывание по передаче, возможно и лишнее, как и цикл, но тогда у меня встаёт вопрос - а как обойтись без цикла (ну который у меня под вайлом идёт)? Просто когда мне надо переслать 1 байт - всё замечательно, он ушёл и бог с ним... А если целый пакет? Не получится ли так, что просто в цикле будет так, что следующий пакет будет наступать на пятки предыдущему? Или может тут как раз стоит подумать о прерывании по окончании передачи?

4) И ещё вопрос... Ситуация - надо отослать массив данных, например, short (2 байта)... Мне достаточно написать:
UDDR0=Mass[i]
и он сам поймёт, что надо просто тупо запихать сначала первый байт инта, потом второй? Или же надо самостоятельно ему поочереди запихнуть сначала первый байт, потом второй?

Спасибо.

Сообщение отредактировал NikitoS-86 - Dec 10 2008, 09:15
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 10 2008, 09:53
Сообщение #3


Гуру
******

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



Цитата(NikitoS-86 @ Dec 10 2008, 11:07) *
когда прошивал фьюзы - был абсолютно уверен, что если выбрать в закладке фьюзов в последней строке что-то типа внешнего тактового источника и нажать програм, то всё будет как надо...
Вот-вот... тоже попался на удочку визардов. Пользуюсь AVReal. Читаю описание всех фузов, пишу .bat с командной строкой, абсолютно уверен, что "оно само" ничего лишнего не сделает.
Цитата(NikitoS-86 @ Dec 10 2008, 11:07) *
Просто когда мне надо переслать 1 байт - всё замечательно, он ушёл и бог с ним... А если целый пакет?
В данном случае целый пакет вы не получите, потому что уже сидите в прерывании приема. Если надо переслать несколько байт, то используют промежуточный буфер в озу и прерывание по освобождению UDR, а не по окончанию передачи. Примерно вот так (код для меги8, но идея понятна):
CODE
#define TX_BUFFER_SIZE 8
uint8_t volatile TxHead;
uint8_t volatile TxTail;
uint8_t TxPool[TX_BUFFER_SIZE];


void send_byte(unsigned char byte)
{
uint8_t Tmp = TxHead;
while((uint8_t)(Tmp - TxTail) >= (uint8_t) TX_BUFFER_SIZE)
; // buffer full, wait

TxBuffer[ Tmp ] = Byte;
Tmp = (Tmp + 1) & (TX_BUFFER_SIZE - 1);
TxHead = Tmp;
UCSRB |= (1<<UDRIE);
}

void send_str(PGM_P string)
{
char c;
while( (c = pgm_read_byte(string++)) != '\x0' )
{
send_byte( c );
}
}
void send_str_P(char * string)
{
char c;
while( (c = *string++) != '\x0' )
{
send_byte( c );
}
}


ISR(USART_UDRE_vect)
{
UCSRB &= ~(1<<UDRIE);
sei();
{
uint8_t Tmp = TxTail;
UDR = TxBuffer[ Tmp ];
Tmp = (Tmp + 1) & (TX_BUFFER_SIZE - 1)
TxTail = Tmp;
if(Tmp != TxHead) // more data pending in buffer
{
UCSRB |= (1<<UDRIE);
}
}
}
или, в простейшем случае, без прерываний:
Код
void send_byte(uint8_t Byte)
{
    while(!(UCSRA & (1<<UDRE)));
    UDR = Byte;
}
В любом случае ожидание должно происходить вне обработчика прерывания.
Цитата(NikitoS-86 @ Dec 10 2008, 11:07) *
Не получится ли так, что просто в цикле будет так, что следующий пакет будет наступать на пятки предыдущему? Или может тут как раз стоит подумать о прерывании по окончании передачи?
В случае "эха" - не получится. И прерывание по освобождению UDR. Прерывание об окончании передачи используется для другого - например, для отключения передатчика в RS485.
Цитата(NikitoS-86 @ Dec 10 2008, 11:07) *
4) И ещё вопрос... Ситуация - надо отослать массив данных, например, short (2 байта)... Мне достаточно написать:
UDDR0=Mass[i]
и он сам поймёт, что надо просто тупо запихать сначала первый байт инта, потом второй? Или же надо самостоятельно ему поочереди запихнуть сначала первый байт, потом второй?
Конечно самостоятельно. В вашей строке он запихнет только i-тый элемент массива. Можно написать универсальную функцию:
Код
void send_block(void const *ptr, uint8_t size)
{
    while(size--)
    {
        send_byte(*ptr++);
    }
}

void test()
{
   unsigned char Mass[2];
   unsigned short Short;

   send_block(Mass, sizeof(Mass));
   send_block(&Short, sizeof(Short));
}


--------------------
На любой вопрос даю любой ответ
"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

Сообщений в этой теме
- NikitoS-86   USART на АTmega48   Dec 9 2008, 16:27
- - Палыч   Вы уверены что вот это будет подсчитано правильно ...   Dec 9 2008, 16:36
|- - NikitoS-86   Цитата(Палыч @ Dec 9 2008, 19:36) Вы увер...   Dec 9 2008, 16:43
|- - Палыч   Цитата(NikitoS-86 @ Dec 9 2008, 19:4...   Dec 9 2008, 16:49
|- - NikitoS-86   Цитата(Палыч @ Dec 9 2008, 19:49) Ну, поч...   Dec 9 2008, 16:53
- - Сергей Борщ   Цитата(NikitoS-86 @ Dec 9 2008, 18:2...   Dec 9 2008, 16:54
|- - Палыч   Может fuse CKDIV8 остался запрограммирован? С заво...   Dec 9 2008, 17:01
|- - Палыч   Цитата(Сергей Борщ @ Dec 9 2008, 19:54) С...   Dec 9 2008, 17:07
|- - NikitoS-86   Цитата(Сергей Борщ @ Dec 9 2008, 19:54) С...   Dec 9 2008, 17:10
||- - Сергей Борщ   Цитата(NikitoS-86 @ Dec 9 2008, 19:1...   Dec 9 2008, 17:44
|- - gormih   Цитата(Сергей Борщ @ Dec 9 2008, 19:54) А...   Dec 9 2008, 17:37
|- - Сергей Борщ   Цитата(gormih @ Dec 9 2008, 19:37) А если...   Dec 9 2008, 17:49
|- - gormih   Цитата(Сергей Борщ @ Dec 9 2008, 20:49) И...   Dec 9 2008, 18:13
- - man with no name   попробуйте uart включать после окончательной иници...   Dec 9 2008, 17:04
- - gormih   AVR CALCULATOR Хватит уже п**у мучать, товарищи...   Dec 9 2008, 17:46
- - =GM=   Цитата(NikitoS-86 @ Dec 9 2008, 16:2...   Dec 9 2008, 19:01
- - NikitoS-86   Цитата(Сергей Борщ @ Dec 10 2008, 12:53) ...   Dec 10 2008, 13:11
- - Сергей Борщ   Цитата(NikitoS-86 @ Dec 10 2008, 15...   Dec 10 2008, 13:22


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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 06:55
Рейтинг@Mail.ru


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