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

 
 
> опять USART на 16 меге, прерывание по приёму
*SERG
сообщение Jan 29 2006, 08:11
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 274
Регистрация: 10-08-05
Из: Екатеринбург
Пользователь №: 7 517



Регистры настроил так:

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
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 11)
beer_warrior
сообщение Jan 29 2006, 19:54
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



1. Что за делитель 0x65, какой кварц?
2. На какой скорости работает передатчик?
3. Разрешен ли бит I (sei), до начала приема?
4. Посмотреть листинг на предмет правильности компиляции.
5. Воспользоваться примерами из даташита.

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

очень облегчают жизнь кодочитателям.


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post
*SERG
сообщение Jan 30 2006, 02:54
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 274
Регистрация: 10-08-05
Из: Екатеринбург
Пользователь №: 7 517



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

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

Да я б сам не против такой конструкции, только CVAVR не хочет так понимать
Go to the top of the page
 
+Quote Post
Dominikanez
сообщение Jan 30 2006, 06:42
Сообщение #4





Группа: Участник
Сообщений: 12
Регистрация: 24-06-05
Пользователь №: 6 276



Цитата(*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;
Go to the top of the page
 
+Quote Post
*SERG
сообщение Jan 30 2006, 08:15
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 274
Регистрация: 10-08-05
Из: Екатеринбург
Пользователь №: 7 517



ок. попробую
Go to the top of the page
 
+Quote Post
Spider
сообщение Feb 1 2006, 08:50
Сообщение #6


В поисках истины
***

Группа: Свой
Сообщений: 431
Регистрация: 7-01-06
Из: Россия
Пользователь №: 12 923



А что если у меня при следующем коде программы постоянно с проца приходит символ?

Код
/*********************************************
* 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
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Feb 1 2006, 10:13
Сообщение #7


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



Alexey Belyaev, похоже на сбой (переполнение) стека.
Попробуйте отследить это в AVR Studio.
Go to the top of the page
 
+Quote Post
kuk
сообщение Feb 1 2006, 11:02
Сообщение #8


Участник
*

Группа: Новичок
Сообщений: 21
Регистрация: 14-12-05
Пользователь №: 12 189



Я в меге 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;
Прерывание как на прием так и на передачу все пашет
Go to the top of the page
 
+Quote Post
ALexx
сообщение Feb 1 2006, 14:22
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 243
Регистрация: 22-09-04
Из: Burbach, Germany
Пользователь №: 704



Инициализируюсь следующими функциями:

#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")

Все работает уже давно и много ;-))
Go to the top of the page
 
+Quote Post
freux
сообщение Feb 1 2006, 15:47
Сообщение #10


Участник
*

Группа: Новичок
Сообщений: 41
Регистрация: 7-02-05
Пользователь №: 2 473



Alexey, дурацкое предположение:
uart_puts("Test\n\r\0");
Go to the top of the page
 
+Quote Post
IgorKossak
сообщение Feb 1 2006, 16:10
Сообщение #11


Шаман
******

Группа: Модераторы
Сообщений: 3 064
Регистрация: 30-06-04
Из: Киев, Украина
Пользователь №: 221



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

Стринги завершаются нулём по умолчанию, по крайней мере стандарт на этом настаивает.
Кроме того, печатается именно 't', а не '\r', как следовало бы предположить.
Go to the top of the page
 
+Quote Post
beer_warrior
сообщение Feb 1 2006, 20:18
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 065
Регистрация: 8-10-05
Из: Kiev, UA
Пользователь №: 9 380



Поубирать все лищнее, скорее всего проц влазит в какое-то левое
преывание и шарашит символ оставшийся в буфере.


--------------------
Вони шукають те, чого нема,
Щоб довести, що його не існує.
Go to the top of the page
 
+Quote Post

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

 


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


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