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

 
 
> AT90CAN128, Проблема с USART
--Ivan--
сообщение Sep 1 2007, 21:43
Сообщение #1





Группа: Новичок
Сообщений: 8
Регистрация: 1-09-07
Пользователь №: 30 221



Есть AT90CAN128, у которого используется USART1. При написании программы в CV AVR всё отлично пашет. Контроллер посылает данные в порт, гипертерминал их получает и выводит на экран. Т.е. железо в порядке. Но когда я попытался написать аналогичную программу в IAR, ком-порт работать перестал. При этом остальное не пострадало. Ниже приведены функции настройки и передачи данных.
Код
// Инициализация USART
void USART_Init( void )
{
  // Включить приемник и передатчик
    UCSR1B = ( 1 << RXEN1 ) | ( 1 << TXEN1 );
  // 8 data, no parity, 1 stop  
    UCSR1C = ( 1 << UCSZ11 ) | ( 1 << UCSZ10 );
  // 9600 bps при 16 MHz  
    UBRR1 = 103;

}

// Передача данных по USART
void USART1_Transmit( unsigned char data )
{
  // Запись в буфер
    UDR1 = data;
  // Ожидание завершения передачи
    while ( ! ( UCSR1A & ( 1 << TXC1 ) ) );
}

На ATmega8 данные функции работают после незначительной переделки ( только один USART, против двух у at90can128 ). В чем же дело?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
=GM=
сообщение Sep 2 2007, 16:03
Сообщение #2


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(--Ivan-- @ Sep 1 2007, 21:43) *
Есть AT90CAN128, у которого используется USART1. При написании программы в CV AVR всё отлично пашет. Контроллер посылает данные в порт, гипертерминал их получает и выводит на экран. Т.е. железо в порядке. Но когда я попытался написать аналогичную программу в IAR, ком-порт работать перестал. При этом остальное не пострадало. Ниже приведены функции настройки и передачи данных.

На ATmega8 данные функции работают после незначительной переделки ( только один USART, против двух у at90can128 ). В чем же дело?

Дело в том, что для AT90CAN128 адреса регистров компорта находятся в расширенной зоне адресов ввода-вывода (выше 0х60), а для ATmega8 - в обычной (ниже 0х60). Поменяйте файл с определениями регистров и будет вам щастье.

И ещё, при инициализации лучше сначала инициализировать регистры порта, потом разрешать приёмник и передатчик, а не наоборот.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
--Ivan--
сообщение Sep 3 2007, 09:51
Сообщение #3





Группа: Новичок
Сообщений: 8
Регистрация: 1-09-07
Пользователь №: 30 221



Файл "iocan128.h", в котором определяются регистры, на первый взгляд без ошибок. Адреса связанных с компортом регистров специально сверил с документацией и не нашел отличий.

Цитата(=GM= @ Sep 2 2007, 20:03) *
И ещё, при инициализации лучше сначала инициализировать регистры порта, потом разрешать приёмник и передатчик, а не наоборот.


Пробовал и так, и этак - никакой разницы.
Go to the top of the page
 
+Quote Post
=GM=
сообщение Sep 3 2007, 11:59
Сообщение #4


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(--Ivan-- @ Sep 3 2007, 08:51) *
Файл "iocan128.h", в котором определяются регистры, на первый взгляд без ошибок. Адреса связанных с компортом регистров специально сверил с документацией и не нашел отличий.
Пробовал и так, и этак - никакой разницы.

Попробуйте в режиме теста вывести данные не по прерыванию, а по ожиданию готовности TXC.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
--Ivan--
сообщение Sep 3 2007, 16:26
Сообщение #5





Группа: Новичок
Сообщений: 8
Регистрация: 1-09-07
Пользователь №: 30 221



Цитата(=GM= @ Sep 3 2007, 15:59) *
Попробуйте в режиме теста вывести данные не по прерыванию, а по ожиданию готовности TXC.

Прерывания я не использовал.
Код
// Передача данных по USART
void USART1_Transmit( unsigned char data )
{
  // Запись в буфер
    UDR1 = data;
  // Ожидание завершения передачи
    while ( ! ( UCSR1A & ( 1 << TXC1 ) ) );
}

В основной программе просто циклично вызывается данная функция.
Код
void main( void )
{
    asm("cli");
    PWM_Init();  
    USART_Init();
    asm("sei");

    int i=0, c=1;
    DDRC = 0xFF;
    PORTC = 0xFF;
    while (1)      
    {
        
        USART1_Transmit( 'b' );
        i += c;
        if ( i > 165 ) c = -1;
        if ( i < -165 ) c = 1;
        PWM_Set( i, i );
    }
}

Судя по тому, что остальной код выполняется правильно, зацикливание из-за TXC1 не происходит. Вообще 90кан128 - довольно большой мк, может есть какие-нибудь хитрости именно с инициализацией.
Цитата
Так что вам мешает написать простенькую тестовую программу вывода в цикле буквы 'A' и сравнить листинги? Чудес ведь не бывает.

Программка у меня примерно того же уровня сложности smile.gif
Go to the top of the page
 
+Quote Post
=GM=
сообщение Sep 3 2007, 20:50
Сообщение #6


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(--Ivan-- @ Sep 3 2007, 16:26) *
Судя по тому, что остальной код выполняется правильно, зацикливание из-за TXC1 не происходит. Вообще 90кан128 - довольно большой мк, может есть какие-нибудь хитрости именно с инициализацией

Ну, чудес не бывает, давайте посмотрим, что там яровский компилер натворил в асмовом коде.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
--Ivan--
сообщение Sep 4 2007, 18:55
Сообщение #7





Группа: Новичок
Сообщений: 8
Регистрация: 1-09-07
Пользователь №: 30 221



Цитата(=GM= @ Sep 4 2007, 00:50) *
Ну, чудес не бывает, давайте посмотрим, что там яровский компилер натворил в асмовом коде.

Знать бы ещё как этот код достать... unsure.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 5 2007, 11:52
Сообщение #8


Гуру
******

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



Цитата(--Ivan-- @ Sep 4 2007, 21:55) *
Знать бы ещё как этот код достать... unsure.gif
Project->options->C/C++ compiler->вкладка List->Output list file, assembler mnemonics. Листинги искать в папке, указанной в Project->options->General Options->Output


--------------------
На любой вопрос даю любой ответ
"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
--Ivan--
сообщение Sep 5 2007, 17:32
Сообщение #9





Группа: Новичок
Сообщений: 8
Регистрация: 1-09-07
Пользователь №: 30 221



Код
   \                                 In  segment CODE, align 2, keep-with-next
   \   __nearfunc __version_3 void USART_Init()
   \                     USART_Init:
   \   00000000   E108               LDI     R16, 24
   \   00000002   930000C9           STS     201, R16
   \   00000006   E006               LDI     R16, 6
   \   00000008   930000CA           STS     202, R16
   \   0000000C   E607               LDI     R16, 103
   \   0000000E   E010               LDI     R17, 0
   \   00000010   931000CD           STS     205, R17
   \   00000014   930000CC           STS     204, R16
   \   00000018   9508               RET
   \   0000001A                      REQUIRE _A_UBRR1
   \   0000001A                      REQUIRE _A_UCSR1C
   \   0000001A                      REQUIRE _A_UCSR1B

   \                                 In  segment CODE, align 2, keep-with-next
   \   __nearfunc __version_3 void USART1_Transmit(unsigned char)
   \                     USART1_Transmit:
   \   00000000   930000CE           STS     206, R16
   \                     ??USART1_Transmit_0:
   \   00000004   910000C8           LDS     R16, 200
   \   00000008   FF06               SBRS    R16, 6
   \   0000000A   CFFC               RJMP    ??USART1_Transmit_0
   \   0000000C   9508               RET
   \   0000000E                      REQUIRE _A_UDR1
   \   0000000E                      REQUIRE _A_UCSR1A
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 6 2007, 04:33
Сообщение #10


Гуру
******

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



Цитата(--Ivan-- @ Sep 5 2007, 20:32) *
Код
   \                                 In  segment CODE, align 2, keep-with-next
Отлично. А теперь, чтобы не ломать голову приведите листинг второй программы:
Цитата(--Ivan-- @ Sep 2 2007, 00:43) *
При написании программы в CV AVR всё отлично пашет. Контроллер посылает данные в порт, гипертерминал их получает и выводит на экран.


--------------------
На любой вопрос даю любой ответ
"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
--Ivan--
сообщение Sep 6 2007, 16:01
Сообщение #11





Группа: Новичок
Сообщений: 8
Регистрация: 1-09-07
Пользователь №: 30 221



Из-за кодвизарда в коде много лишнего. Выкладываю основное
Код
;     280 // USART1 initialization
;     281 // Communication Parameters: 8 Data, 1 Stop, No Parity
;     282 // USART1 Receiver: On
;     283 // USART1 Transmitter: On
;     284 // USART1 Mode: Asynchronous
;     285 // USART1 Baud rate: 9600
;     286 UCSR1A=0x00;
    STS  0xC8,R30
;     287 UCSR1B=0xD8;
    LDI  R30,LOW(216)
    STS  0xC9,R30
;     288 UCSR1C=0x06;
    LDI  R30,LOW(6)
    STS  0xCA,R30
;     289 UBRR1H=0x00;
    LDI  R30,LOW(0)
    STS  0xCD,R30
;     290 UBRR1L=0x67;
    LDI  R30,LOW(103)
    STS  0xCC,R30

Код
;     328         putchar1('a');
    LDI  R30,LOW(97)
    ST   -Y,R30
    RCALL _putchar1

Код
;      96 // USART1 Transmitter interrupt service routine
;      97 interrupt [USART1_TXC] void usart1_tx_isr(void)
;      98 {

    .CSEG
_usart1_tx_isr:
    ST   -Y,R30
    ST   -Y,R31
    IN   R30,SREG
    ST   -Y,R30
;      99 if (tx_counter1)
    TST  R7
    BREQ _0xA
;     100    {
;     101    --tx_counter1;
    DEC  R7
;     102    UDR1=tx_buffer1[tx_rd_index1];
    MOV  R30,R6
    LDI  R31,0
    SUBI R30,LOW(-_tx_buffer1)
    SBCI R31,HIGH(-_tx_buffer1)
    LD   R30,Z
    STS  0xCE,R30
;     103    if (++tx_rd_index1 == TX_BUFFER_SIZE1) tx_rd_index1=0;
    INC  R6
    LDI  R30,LOW(8)
    CP   R30,R6
    BRNE _0xB
    CLR  R6
;     104    };
_0xB:
_0xA:
;     105 }
    LD   R30,Y+
    OUT  SREG,R30
    LD   R31,Y+
    LD   R30,Y+
    RETI
;     106
;     107 // Write a character to the USART1 Transmitter buffer
;     108 #pragma used+
;     109 void putchar1(char c)
;     110 {
_putchar1:
;     111 while (tx_counter1 == TX_BUFFER_SIZE1);
_0xC:
    LDI  R30,LOW(8)
    CP   R30,R7
    BREQ _0xC
;     112 #asm("cli")
    cli
;     113 if (tx_counter1 || ((UCSR1A & DATA_REGISTER_EMPTY)==0))
    TST  R7
    BRNE _0x10
    LDS  R30,200
    ANDI R30,LOW(0x20)
    BRNE _0xF
_0x10:
;     114    {
;     115    tx_buffer1[tx_wr_index1]=c;
    MOV  R30,R5
    LDI  R31,0
    SUBI R30,LOW(-_tx_buffer1)
    SBCI R31,HIGH(-_tx_buffer1)
    LD   R26,Y
    STD  Z+0,R26
;     116    if (++tx_wr_index1 == TX_BUFFER_SIZE1) tx_wr_index1=0;
    INC  R5
    LDI  R30,LOW(8)
    CP   R30,R5
    BRNE _0x12
    CLR  R5
;     117    ++tx_counter1;
_0x12:
    INC  R7
;     118    }
;     119 else
    RJMP _0x13
_0xF:
;     120    UDR1=c;
    LD   R30,Y
    STS  0xCE,R30
;     121 #asm("sei")
_0x13:
    sei
;     122 }
    ADIW R28,1
    RET
;     123 #pragma used-
;     124
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 6 2007, 16:14
Сообщение #12


Гуру
******

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



Цитата(--Ivan-- @ Sep 6 2007, 19:01) *
Из-за кодвизарда в коде много лишнего. Выкладываю основное
Ну тогда бы сразу и сказали, кто из отвечавших должен сравнить эти листинги и найти в них отличия из-за которых не работает 1111493779.gif


--------------------
На любой вопрос даю любой ответ
"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
=GM=
сообщение Sep 6 2007, 16:39
Сообщение #13


Ambidexter
*****

Группа: Свой
Сообщений: 1 589
Регистрация: 22-06-06
Из: Oxford, UK
Пользователь №: 18 282



Цитата(Сергей Борщ @ Sep 6 2007, 15:14) *
Ну тогда бы сразу и сказали, кто из отвечавших должен сравнить эти листинги и найти в них отличия из-за которых не работает 1111493779.gif

Похоже, товарисч сам не знает, чего хочет. Привёл кусок программы с прерыванием, а ранее - кусок программы без прерывания, думайте мол сами.

То --Ivan--. Я ж вам сказал, где у вас ошибка, чего проще, поставить сброс ТХС и проверить. А команда RETI сбрасывает ТХС! Что ж вы нас путаете?


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
--Ivan--
сообщение Sep 7 2007, 16:18
Сообщение #14





Группа: Новичок
Сообщений: 8
Регистрация: 1-09-07
Пользователь №: 30 221



Цитата(=GM= @ Sep 6 2007, 20:39) *
То --Ivan--. Я ж вам сказал, где у вас ошибка, чего проще, поставить сброс ТХС и проверить. А команда RETI сбрасывает ТХС! Что ж вы нас путаете?

To =GM=. Извините за поздний ответ, написал перед тем как проверить.
Сейчас добавил одну строку в функцию передачи, теперь она выглядит так:
Код
void USART1_Transmit( unsigned char data )
{
    UDR1 = data;
    while ( ! ( UCSR1A & ( 1 << TXC1 ) ) );
    UCSR1A = ( 1 << TXC1 );
}

Появился небольшой прогресс, но правильно данные все равно не передаются. Если перебирать все значения от 1 до 250 и посылать их в компорт, то в окне терминала иногда добавляется буква "А", и никаких других символов нет. До того как стал сбрасывать флаг терминал вообще не реагировал.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- --Ivan--   AT90CAN128   Sep 1 2007, 21:43
- - =GM=   Цитата(--Ivan-- @ Sep 1 2...   Sep 2 2007, 16:03
|- - =GM=   Цитата(--Ivan-- @ Sep 3 2...   Sep 3 2007, 11:59
|- - =GM=   Цитата(--Ivan-- @ Sep 3 2...   Sep 3 2007, 20:50
|- - =GM=   Цитата(--Ivan-- @ Sep 5 2...   Sep 5 2007, 22:21
|- - =GM=   Цитата(--Ivan-- @ Sep 7 2...   Sep 7 2007, 21:51
|- - --Ivan--   Как раз в случае 0х55 и возникает та самая буква ...   Sep 8 2007, 14:47
|- - =GM=   Цитата(--Ivan-- @ Sep 8 2...   Sep 10 2007, 10:47
- - Сергей Борщ   Цитата(--Ivan-- @ Sep 2 2...   Sep 3 2007, 13:18


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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 11:41
Рейтинг@Mail.ru


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