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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> 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
=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
Сергей Борщ
сообщение Sep 3 2007, 13:18
Сообщение #5


Гуру
******

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



Цитата(--Ivan-- @ Sep 2 2007, 00:43) *
При написании программы в CV AVR всё отлично пашет.
Но когда я попытался написать аналогичную программу в IAR, ком-порт работать перестал.
Так что вам мешает написать простенькую тестовую программу вывода в цикле буквы 'A' и сравнить листинги? Чудес ведь не бывает.


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





Группа: Новичок
Сообщений: 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
Сообщение #7


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
Сообщение #8





Группа: Новичок
Сообщений: 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
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 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
Сообщение #10





Группа: Новичок
Сообщений: 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
=GM=
сообщение Sep 5 2007, 22:21
Сообщение #11


Ambidexter
*****

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



Цитата(--Ivan-- @ Sep 5 2007, 17:32) *
Код
   \   __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

Здесь у вас логическая ошибка. После завершения передачи (после появления флага ТХС1=1), вам надо его очистить вручную, записав туда единицу. Флаг очищается автоматически только при обработке прерывания. См. с.195 документа 7682а.

Если не очищать флаг, то произойдёт следующее. Вы запустили передачу, дождались ТХС, не сбросили его, проделали некоторые операции и вернулись к передаче символа, пустили символ на передачу, стали ждать окончания, но не дождались, поскольку ТХС не сброшен, быстренько сделали некоторые операции и перешли опять к передаче символа. Но передача предыдущего символа еще не закончилась, запись нового байта перебила передачу текущего, в итоге получилась каша. Как-то так.


--------------------
Делай сразу хорошо, плохо само получится
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 6 2007, 04:33
Сообщение #12


Гуру
******

Группа: Модераторы
Сообщений: 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
Сообщение #13





Группа: Новичок
Сообщений: 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
Сообщение #14


Гуру
******

Группа: Модераторы
Сообщений: 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
Сообщение #15


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

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

 


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


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