Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Mega1280 vs UART's
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
Starick
всем привет. Вопрос собствено вот в чем. Вроде все просто. Нужно мне юзать 4 юарта. Взял для этих целей м1280 и был бы счастлив, еслиб все они заработали. Но работают только 0 и 1 юарт, 2 и 3 нивкакую. Что я не так делаю? Для проверки даже на асме быстро прогу наваял. Прерывания от 0 и 1 срабатывают, а вот от 2 - нет. 07.gif Спецы, подскажите заблудившему в поиске истины.

.include "m1280def.inc"

.org 0
rjmp init

.org URXC0addr
rjmp Handler_USART0

.org URXC1addr
rjmp Handler_USART1

.org URXC2addr
rjmp Handler_USART2

init:

; UCSR0B = 0x00; //disable while setting baud rate

CLR R2
STS 0xC1,R2
//UCSR0A = 1<<U2X;
; UBRR0L = 0xBF; //set baud rate lo
LDI R24,0xBF
STS 0xC4,R24
; UBRR0H = 0x00; //set baud rate hi
STS 0xC5,R2

; UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);
LDI R24,6
STS 0xC2,R24
; UCSR0B = ((1<<RXCIE0)|(1<<RXEN0)|(1<<TXEN0));
LDI R24,0x98
STS 0xC1,R24

;UCSR1B = 0x00; //disable while setting baud rate

CLR R2
STS 0xC9,R2
; UBRR1L = 0x2F; //set baud rate lo
LDI R24,0x2F
STS 0xCC,R24
; UBRR1H = 0x00; //set baud rate hi
STS 0xCD,R2
;UCSR1C = (1<<UCSZ11)|(1<<UCSZ10);
LDI R24,6
STS 0xCA,R24
; UCSR1B = ((1<<RXCIE1)|(1<<RXEN1)|(1<<TXEN1));
LDI R24,0x98
STS 0xC9,R24


CLR R2
STS 0xD1,R2

;UBRR2L = 0x0F; //set baud rate lo
LDI R24,0xF
STS 0xD4,R24
; UBRR2H = 0x00; //set baud rate hi
STS 0xD5,R2
; UCSR2C = (1<<UCSZ21)|(1<<UCSZ20);
LDI R24,6
STS 0xD2,R24
;UCSR2B = ((1<<RXCIE2)|(1<<RXEN2)|(1<<TXEN2));
LDI R24,0x98
STS 0xD1,R24
sei

idle:
rjmp idle


Handler_USART0:
nop
nop
nop
reti

Handler_USART1:
nop
nop
nop
reti

Handler_USART2:
nop
nop
nop
reti
XsanyaX
Советую проинициализоровать все порты сразу и поочереди посылать в них данные и ловит прерывание по приёму....

Может проблема не в процессоре, а в плате.....
SasaVitebsk
А в студии по шагам прогнать?
IgorKossak
Раз уж Вы подключаете m1280def.inc, то неплохо бы пользоваться символическими именами регистров и битов вместо конкретных адресов и значений.
Иначе Ваш текст не очень то хочется анализировать на тему правильности адресов и масок.
Прогон в Студии с одновременной инспекцией записи в нужные регистры обычно помогает.
firework
Цитата(Starick @ Oct 12 2007, 09:48) *
всем привет. Вопрос собствено вот в чем. Вроде все просто. Нужно мне юзать 4 юарта. Взял для этих целей м1280 и был бы счастлив, еслиб все они заработали. Но работают только 0 и 1 юарт, 2 и 3 нивкакую. Что я не так делаю? Для проверки даже на асме быстро прогу наваял. Прерывания от 0 и 1 срабатывают, а вот от 2 - нет. 07.gif Спецы, подскажите заблудившему в поиске истины.
В CodeVisionAVR заработали сразу все 4 порта. Инициализация и обработчики на С совершенно одинаковые для всех четырех UART.
Инициализация:

// USART0 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART0 Receiver: On
// USART0 Transmitter: On
// USART0 Mode: Asynchronous
// USART0 Baud Rate: 115200 (Double Speed Mode)
UCSR0A=0x02;
UCSR0B=0xD8;
UCSR0C=0x06;
UBRR0H=0x00;
UBRR0L=0x07;

// USART2 initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART2 Receiver: On
// USART2 Transmitter: On
// USART2 Mode: Asynchronous
// USART2 Baud Rate: 115200 (Double Speed Mode)
UCSR2A=0x02;
UCSR2B=0xD8;
UCSR2C=0x06;
UBRR2H=0x00;
UBRR2L=0x07;

Обработчики:
//***********************************
// USART0 Receiver interrupt service routine
interrupt [USART0_RXC] void usart0_rx_isr(void)
{
unsigned char status,data;
status=UCSR0A;
data=UDR0;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
// код

}
}


//***************************************************
// USART2 Receiver interrupt service routine
interrupt [USART2_RXC] void usart2_rx_isr(void)
{
unsigned char status,data;
status=UCSR2A;
data=UDR2;
if ((status & (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0)
{
// код

}
}
swisst
Можно ли установить бит TXC0 программно ? Точнее сказать, можно ли программно вызвать прерывание по определенному вектору (определенный вектор - USART0_TX_vect)?
Палыч
В AVR сделано так, что флаги программно установить нельзя. Можно просто тупо вызвать обработчик прерываний, если это нужно.

Из примера выше:
.......
usart2_rx_isr();
.......
Но, это не совсем прерывание, вернее, совсем не прерывание
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.