Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: опять USART на 16 меге
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
*SERG
Регистры настроил так:

UCSRA=0x00;
UCSRB=0B11011000;
UCSRC=0B10000110;
UBRRH=0x00;
UBRRL=0x65;

подпрограммы прерывания

interrupt [USART_RXC] void usart_rx_isr(void)
{

prinat_ussap=UDR;
est_dannie=1;
zapis_end=0;

}


// USART Transmitter interrupt service routine
interrupt [USART_TXC] void usart_tx_isr(void)
{
#asm
nop;
#endasm
}

Пишу в CVAVR.

Проблемма в том, что когда приходит первый байт, прерывание не происходит, а вот когда уже второй байт пришёл, то происходит прерывание, переменной "prinat_ussap" присваивается значение первого байта blink.gif
А теоретически при приходе первого байта доложно происходить прерывание. Регистр UCSRB, больше не трогаю, все прерывания разрешаю в самом начале, больше не запрещаю.
Где собака порылась??? smile.gif
beer_warrior
1. Что за делитель 0x65, какой кварц?
2. На какой скорости работает передатчик?
3. Разрешен ли бит I (sei), до начала приема?
4. Посмотреть листинг на предмет правильности компиляции.
5. Воспользоваться примерами из даташита.

PS советую пользоваться конструкциями типа:
Код
UCSRB= (1 << TXEN )|(1 << RXEN )|(1 << TXIE )|(1 << RXIE );

очень облегчают жизнь кодочитателям.
*SERG
1. Кварц встроенный, 16МГц
2. 9600
3. все прерывания разрешаю в самом начале, больше не запрещаю.
т.е. бит установлен
4. посмотрю
5. в даташите вроде пример не по прерываниям а всё время проверяется бит (может ошибаюсь)

Да и проблемма то не в этом, прием и передача идёт чётко.
Не понятно почему при приходе первого байта не возникает прерывания???

Да я б сам не против такой конструкции, только CVAVR не хочет так понимать
Dominikanez
Цитата(*SERG @ Jan 30 2006, 08:54) *
1. Кварц встроенный, 16МГц
2. 9600

0x67 - вот более близкое значение UBBR для 9600 @ 16Mhz

Цитата(*SERG @ Jan 30 2006, 08:54) *
3. все прерывания разрешаю в самом начале, больше не запрещаю.
т.е. бит установлен

перед разрешением прерываний попробуй очистить флаг RXC в регистре UCSRA,
это можно сделать записав в этот бит единицу:
UCSRA|=(1<<RXC); или UCSRA|=0x80;
если не поможет, то также, перед разрешением прерывания, попробуй прочитать содержимое UDR:

unsigned char temp;
temp=UDR;
*SERG
ок. попробую
Spider
А что если у меня при следующем коде программы постоянно с проца приходит символ?

Код
/*********************************************
* Chip type           : ATmega16
* Clock frequency     : 16,000000 MHz
*********************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include <inttypes.h>
#include <avr/iom16.h>

#define F_OSC 16000000                   /* oscillator-frequency in Hz */
#define UART_BAUD_RATE 9600
#define UART_BAUD_CALC(UART_BAUD_RATE,F_OSC) ((F_OSC)/((UART_BAUD_RATE)*16l)-1)

void delay_ms(unsigned short ms) {
    unsigned short outer1, outer2;
    outer1 = 200;
    while (outer1) {
        outer2 = 1000;
        while (outer2) {
            while ( ms ) ms--;
            outer2--;
        }
        outer1--;
    }
}

void usart_putc(unsigned char c) {
   // wait until UDR ready
    while(!(UCSRA & (1 << UDRE)));
    UDR = c;    // send character
}

void uart_puts (char *s) {
    //  loop until *s != NULL
    while (*s) {
        usart_putc(*s);
        s++;
    }
}

void init(void) {
    // set baud rate
    UBRRH = (uint8_t)(UART_BAUD_CALC(UART_BAUD_RATE,F_OSC)>>8);
    UBRRL = (uint8_t)UART_BAUD_CALC(UART_BAUD_RATE,F_OSC);

    // Enable receiver and transmitter; enable RX interrupt
    UCSRB = (1 << RXEN) | (1 << TXEN) | (1 << RXCIE);

    //asynchronous 8N1
    UCSRC = (1 << URSEL) | (3 << UCSZ0);
}

// INTERRUPT can be interrupted
// SIGNAL can't be interrupted
SIGNAL (SIG_UART_RECV) { // USART RX interrupt
    unsigned char c;
    c = UDR;
    usart_putc(c);
}

int main(void) {
    init(); // init USART

    // send initial character
    while(!(UCSRA & (1 << UDRE)));
    UDR = 0x43; // "C"
    while(!(UCSRA & (1 << UDRE)));
    UDR = 0x0d;

    uart_puts("Test\n\r");

    sei();  // enable interrupts

    // enable  PD5 as output
    DDRD |= (1<<PD5);
    while (1) {
        // PIN5 PORTD clear -> LED off
        PORTD &= ~(1 << PD5);
        delay_ms(500);
        // PIN5 PORTD set -> LED on
        PORTD |= (1 << PD5);
        delay_ms(500);    
    }
    return 0;
}


До мерцания диода даже не доходит. В терминалке на компе вижу:
Цитата
Test
tttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttttt
t....

и так бесконечно.
help.gif
IgorKossak
Alexey Belyaev, похоже на сбой (переполнение) стека.
Попробуйте отследить это в AVR Studio.
kuk
Я в меге 16 УАСПП конфигурировал так
void USART_Init(void){
DDRD_Bit0=0;
DDRD_Bit1=0;

UBRRH =0;
UBRRL = 103;


RXCIE=1;
RXEN=1;
TXEN=1;
UCSRC = 0x86;
num_byte_comand=0;
num_byte_data = 0;
}
Скорость 9600 кварц 16МГц и I=1;
Прерывание как на прием так и на передачу все пашет
ALexx
Инициализируюсь следующими функциями:

#define AsyncNormalBaud(f) (_MCU_CLOCK_FREQUENCY_/(16*f))-1

/*******************************************************************************
* Function Name : USART_AsyncInit
* Description : Configure USART as UART
*******************************************************************************/
void USART_AsyncInit(unsigned char UCSRA_Mode, unsigned char UCSRB_Mode){
UCSRA=UCSRA_Mode;
UCSRB=UCSRB_Mode;
}

/*******************************************************************************
* Function Name : USART_AsyncOpen
* Description : Open UART for transmission
*******************************************************************************/
void USART_AsyncOpen( unsigned long Baud, Usart_CharSize Size,
Usart_StopBits StopBits, Usart_Parity Parity){

UCSRC=0x00; //Access to UBRRH
// Set the baud rate
if(UCSRA & U2X) Baud=AsyncDoubleBaud(Baud); // Turbo
else Baud=AsyncNormalBaud(Baud);
UBRRH=(unsigned char)Baud>>8;
UBRRL=(unsigned char)Baud;
// Set frame format
UCSRC=USCRC_ACCESS | Size | StopBits | Parity;
// Enabling port
UCSRB|=(TXEN | RXEN);
// Clear buffers
RxIndex=0; TxIndex=0;
RxFlag=0; TxFlag=0;
}


Инициализация выглядит так:

USART_AsyncInit(0,TXCIE | RXCIE);
USART_AsyncOpen(9600,CharLen_8,OneStop,NoParity);
.
.
.
asm("SEI")

Все работает уже давно и много ;-))
freux
Alexey, дурацкое предположение:
uart_puts("Test\n\r\0");
IgorKossak
Цитата(freux @ Feb 1 2006, 17:47) *
Alexey, дурацкое предположение:
uart_puts("Test\n\r\0");

Стринги завершаются нулём по умолчанию, по крайней мере стандарт на этом настаивает.
Кроме того, печатается именно 't', а не '\r', как следовало бы предположить.
beer_warrior
Поубирать все лищнее, скорее всего проц влазит в какое-то левое
преывание и шарашит символ оставшийся в буфере.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.