Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Atmega128 проблемы с USART
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Nekromant
Доброго времени суток!
help.gif Суть проблемы в том, что впервые пытаюсь запустить USART (ранее опыта работы не было). провел инициализацию и просто пытаюсь по прерыванию вывести на дисплей бессмысленную строчку. Дело в том, что на дисплее я эту строку ни разу так и не увидел(попытка помигать светодиодами приводи к тому же самому результату). help.gif
вот код инициализации и прерываний:
oid TDebugUSART::InitUSART(uint32_t baudrate)
{
/* Enable receiver, transmitter and interrupts */
UCSR1B = (1 << RXEN1) | (1 << TXEN1) | (1 << RXCIE1);

/* 8 bit data */


UCSR1C = (1 << UCSZ11) | (1 << UCSZ10);

/* high byte of UART speed */
UBRR1H = (F_CPU /(baudrate * 8L) - 1) >> 8;
/* low byte of UART speed */
UBRR1L = (uint8_t)(F_CPU / (baudrate * 8L)-1);

}
//-----------------------------
ISR(USART1_RX_vect)
{

Lcd.WriteInt(987654321);


}

ISR(USART1_UDRE_vect)
{
Lcd.WriteInt(123456789);


}
Сами функции Lcd.WriteInt точно рабочие, они взяты из библиотеки моих же предыдущих проектов и еще не подводили.
Заранее благодарен...
Qwertty
А у Вас фьюз "М103С" случайно не установлен?
Laptop
А putchar у Вас где? Фунции низкого уровня надо самим написать.
putchar, getchar желательно сделать буферизованными.
Насчет прерываний не помню, они вроде как в первый раз сами и не сработают если ничего в порт не отправить.

Компилятор то хоть какой?
Nekromant
1)фьюз м103 не установлен-я сним много шишек набил прежде чем понял его работу.
2)putchar и getchar в данном случае просто не использую пока, нужно для начала вообще хоть какую то реакцию увидеть и научить реагировать.
3)Компилятор использую который идет с WinAVR-20071221.
Laptop
Цитата(Nekromant @ Nov 18 2008, 20:09) *
1)фьюз м103 не установлен-я сним много шишек набил прежде чем понял его работу.
2)putchar и getchar в данном случае просто не использую пока, нужно для начала вообще хоть какую то реакцию увидеть и научить реагировать.
3)Компилятор использую который идет с WinAVR-20071221.

Ну хоть 1 символ в УАРТ запиши и при этом не забудь еще прерывания разрешить.
AHTOXA
А Lcd.WriteInt(123456789); - там случайно не используется какая-нибудь таймерная задержка со счётчиком на прерываниях?
smac
Цитата(Nekromant @ Nov 18 2008, 18:04) *
...
}
//-----------------------------
ISR(USART1_RX_vect)
{

Lcd.WriteInt(987654321);
}
....
Сами функции Lcd.WriteInt точно рабочие, они взяты из библиотеки моих же предыдущих проектов и еще не подводили.
Заранее благодарен...

При приеме байта надо UDR вычитывать, чтобы флаг прерывания сбросился, хотя может быть компилятор сам это делает, я не в курсе.
Nekromant
Цитата(AHTOXA @ Nov 18 2008, 20:57) *
А Lcd.WriteInt(123456789); - там случайно не используется какая-нибудь таймерная задержка со счётчиком на прерываниях?

нет никакой таймерной задержки, только что еще раз просмотрел, да и дело всего скорее не в этой функции, так как попытка просто мигнуть диодом в прерывании тоже ничем не увенчалась.
Принимая во внимания все советы, постараюсь сегодня организовать запись в порт и получившийся код выложу.
Сергей Борщ
Цитата(Nekromant @ Nov 18 2008, 17:04) *
вот код инициализации и прерываний:
А сами прерывания глобально разрешены? Программа в main() живет?
Nekromant
Цитата(Сергей Борщ @ Nov 19 2008, 12:11) *
А сами прерывания глобально разрешены? Программа в main() живет?

Да,сами прерывания разрешены. чтоб проверить работоспосбность инициализации порта попытался с контроллера отправить букву в бесконечном цикле-вполне посылается, зато если пытаюсь в цикле послать массив:
for(i = 0; i < sizeof(InitLcd); i++)
{
while(!(UCSR1A & (1 << UDRE1)));
UDR1 = maker1[i];
}
то получаю совершенную несуразицу.
зато если просто вернуть размер массива и просто опять же посылать букву:
for(i = 0; i < sizeof(InitLcd); i++)
{
while(!(UCSR1A & (1 << UDRE1)));
UDR1 = 'X';
}
то опять все получаю вполне нормально. 05.gif
aesok
Пожалуйста замените идеоматические выражения "вполне посылается", "совершенную несуразицу" и "вполне нормально" четкими описанием того что вы наблюдаете. Это технический форум а не литературный, или эфирная среда общества экстрасенсов.

Анатолий.

Как определено InitLcd?
Qwertty
Цитата(Nekromant @ Nov 18 2008, 18:04) *
/* high byte of UART speed */
UBRR1H = (F_CPU /(baudrate * 8L) - 1) >> 8;
/* low byte of UART speed */
UBRR1L = (uint8_t)(F_CPU / (baudrate * 8L)-1);

Вот еще вопрос - откуда 8L взялась? Вы в каком формате baudrate передаете функции инициализации?
И зачем в функции ВЫЧИСЛЯТЬ значение регистров UBRR1x?
Я использую в хидере -
#define BAUD9600 (uint16_t)((F_CPU/(16*9600UL))-1)
Потом просто передаю это значение в функцию. Обратите внимание на расчет. Вы используете константу 8UL, которая нужна для Double Speed. А судя по неустанавливаемому биту U2X в UCSR1A используете обычный режим.
Nekromant
Цитата(aesok @ Nov 19 2008, 13:50) *
Пожалуйста замените идеоматические выражения "вполне посылается", "совершенную несуразицу" и "вполне нормально" четкими описанием того что вы наблюдаете. Это технический форум а не литературный, или эфирная среда общества экстрасенсов.

Анатолий.

Как определено InitLcd?

Извиняюсь если непонятно выразился
1) посылается означало: что отправили с контроллера то и получили на компьютере
2) несуразица выглядела различными символами ни коим образом не похожих на те символы, которые должны были быть отправлены МК на ПК.

3)prog_char InitLcd[]="initialization...";//инициализация


Цитата(Qwertty @ Nov 19 2008, 16:34) *
Вот еще вопрос - откуда 8L взялась? Вы в каком формате baudrate передаете функции инициализации?
И зачем в функции ВЫЧИСЛЯТЬ значение регистров UBRR1x?
Я использую в хидере -
#define BAUD9600 (uint16_t)((F_CPU/(16*9600UL))-1)
Потом просто передаю это значение в функцию. Обратите внимание на расчет. Вы используете константу 8UL, которая нужна для Double Speed. А судя по неустанавливаемому биту U2X в UCSR1A используете обычный режим.

Извиняюсь, когда правил чтоб выложить случайно удалил эту строчку
void TDebugUSART::InitUSART(uint32_t baudrate)
{

/* Enable double speed */
UCSR1A = (1 << U2X1);

/* Enable receiver, transmitter and interrupts */
UCSR1B = (1 << RXEN1) | (1 << TXEN1) | (1 << RXCIE1);

/* 8 bit data */



UCSR1C = (1 << UCSZ11) | (1 << UCSZ10);

/* high byte of UART speed */
UBRR1H = (F_CPU /(baudrate * 8L) - 1) >> 8;
/* low byte of UART speed */
UBRR1L = (uint8_t)(F_CPU / (baudrate * 8L)-1);

}
Сергей Борщ
Цитата(Nekromant @ Nov 19 2008, 16:28) *
3)prog_char InitLcd[]="initialization...";//инициализация
Размер считаете по этой строчке, а отправляете что-то совсем другое из массива marker.
aesok
Цитата(Nekromant @ Nov 19 2008, 17:28) *
3)prog_char InitLcd[]="initialization...";//инициализация


Как вы корпируете строку из InitLcd в maker1?

Анатолий.
Nekromant
добрый день, извиняюсь за долгий ответ.
1) строка maker1 длиннее строки InitLcd и объявлена она так же как InitLcd-написал так, потому что начал грешить на индивидуальную непереносимость именно константы InitLcd, пытался проверить пошлет ли мне он такое же количество правильных символов как определился размер(на случай если нужно послать невесь массив а его часть).результат был тот же.
2) строку maker1 никак не копирую в InitLcd это тестовый вариант и мне по сути надо просто получить вменяемую передачу массива с МК на ПК, для начала можно любоого массива, а затем уж этопойдет в нормальную програму.
aesok
Цитата(Nekromant @ Nov 21 2008, 04:31) *
добрый день, извиняюсь за долгий ответ.
1) строка maker1 длиннее строки InitLcd и объявлена она так же как InitLcd...


maker1 обьявленна так?
prog_char maker1[]="initialization...";
Nekromant
Добрый день, проблема решена, теперь контроллер выдает то что я его прошу и когда я его прошу, мешал цикл абсолютно не относящийся к USART, пока еще не выяснил почему, но в будущем надеюсь прояснить. Всех благодярю за ответы-они мне очень помогли с решением проблемы
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.