Перейти к содержанию
    

Помогите найти ошибку в коде. UART, ATMega32U4

main.c

void main (void) {

    InitDevice ();

    while (1) {
        Delay_mSeconds(20);
        UARTTransmitByte(0x55);
    }
}

 

UART.c

#include "global.h"
/*
********************************************************************************
*                             #DEFINE CONSTANTS
******************************************************************************** 
*/
#define UART_RX_BUFFER_SIZE 8
#define UART_RX_BUFFER_MASK ( UART_RX_BUFFER_SIZE - 1 )
#define UART_TX_BUFFER_SIZE 8
#define UART_TX_BUFFER_MASK ( UART_TX_BUFFER_SIZE - 1 )

#if ( UART_RX_BUFFER_SIZE & UART_RX_BUFFER_MASK )
#error RX buffer size is not a power of 2
#endif


/*
********************************************************************************
*                             GLOBAL FUNCTION
******************************************************************************** 
*/

INT08U UART_RxBuf[UART_RX_BUFFER_SIZE];
volatile INT08U UART_RxHead;
volatile INT08U UART_RxTail;

INT08U UART_TxBuf[UART_TX_BUFFER_SIZE];
volatile INT08U UART_TxHead;
volatile INT08U UART_TxTail;

INT08U UARTDataInReceiveBuffer (void) {    
   INT08U temp1 = UART_RxHead, temp2 = UART_RxTail;
   return (temp1 != temp2);    
}

INT08U UARTReceiveByte (void) {
    INT08U temp1=UART_RxHead, temp2=UART_RxTail;
    INT08U tmptail;


    while (temp1 == temp2) {
    };
    tmptail = ( UART_RxTail + 1 ) & UART_RX_BUFFER_MASK;
    UART_RxTail = tmptail; 
    return UART_RxBuf[tmptail]; 
}

void UARTTransmitByte (INT08U data ) {
    INT08U tmphead;


    tmphead = ( UART_TxHead + 1 ) & UART_TX_BUFFER_MASK; 
    while ( tmphead == UART_TxTail );
    UART_TxBuf[tmphead] = data;
    UART_TxHead = tmphead;
    UCSR1B |= (1<<UDRIE1);
}
/*
********************************************************************************
*                              LOCAL FUNCTION
******************************************************************************** 
*/


#pragma vector=USART1_RX_vect
__interrupt void USART_Rx_isr(void) {
    INT08U data;
    INT08U tmphead;

    data = UDR1;
    tmphead = ( UART_RxHead + 1 ) & UART_RX_BUFFER_MASK;
    UART_RxHead = tmphead;  
    if (tmphead == UART_RxTail) {        }
    UART_RxBuf[tmphead] = data;
}


#pragma vector=USART1_TX_vect
__interrupt void USART0_Tx_interrupt( void ) {
    INT08U temp1 = UART_TxHead, temp2 = UART_TxTail; 
    INT08U tmptail;

    if (temp1 != temp2) {
        tmptail = ( UART_TxTail + 1 ) & UART_TX_BUFFER_MASK;
        UART_TxTail = tmptail; 
        UDR1=UART_TxBuf[tmptail]; 
    }
    else {
        UCSR1B &= ~(1<<UDRIE1); 
    }
}

 

UART.h

/*
********************************************************************************
*                             GLOBAL VARIABLE
******************************************************************************** 
*/
extern INT08U UART_RxBuf[];
extern volatile INT08U UART_RxHead;
extern volatile INT08U UART_RxTail;

extern INT08U UART_TxBuf[];
extern volatile INT08U UART_TxHead;
extern volatile INT08U UART_TxTail;


/*
********************************************************************************
*                        GLOBAL FUNCTION PROTOTYPES
******************************************************************************** 
*/
INT08U UARTDataInReceiveBuffer (void);
INT08U UARTReceiveByte (void);
void UARTTransmitByte (INT08U);

init.c

...
void Init_UART (void) {
    UBRR1L = 0x0C;                                             
    UBRR1H = 0x00;                                           
    UCSR1B = (1<<RXEN1)|(1<<TXEN1)|(1<<TXCIE1)|(1<<RXCIE1)|(1<<UDRIE1);    
    UCSR1C = (1<<USBS1)|(3<<UCSZ10);                           
}
...

 

Вроде как не первый раз использую этот код, но что-то не едут лыжи:(

Выполняется несколько итераций (по количеству байт в буфере передатчика), при этом на выводе Тх ничего нет, потом все умирает совсем.

Шо делать? :)

Изменено пользователем Буратино

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Уж не знаю как в m32u4 (нет под рукой DS), но в m32 регистры UCSRC и UBRRH - совмещены (различаются битом URSEL). Может и в Вашем Мк так?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Уж не знаю как в m32u4 (нет под рукой DS), но в m32 регистры UCSRC и UBRRH - совмещены (различаются битом URSEL). Может и в Вашем Мк так?

 

в даташите вот таким образом инициализируется UART

 

void USART_Init( unsigned int baud )
{
/* Set baud rate */
UBRRHn = (unsigned char)(baud>>8);
UBRRLn = (unsigned char)baud;
/* Enable receiver and transmitter */
UCSRnB = (1<<RXENn)|(1<<TXENn);
/* Set frame format: 8data, 2stop bit */
UCSRnC = (1<<USBSn)|(3<<UCSZn0);
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

/* Set baud rate */
UBRRHn = (unsigned char)(baud>>8);
UBRRLn = (unsigned char)baud;

Обратите внимание на порядок

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Обратите внимание на порядок

 

Изменил порядок, но к сож. не пашет:(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все ,разрулил. сейчас расскажу

 

#pragma vector=USART1_TX_vect заменил на

#pragma vector=USART1_UDRE_vect :rolleyes:

 

Всем спасибо!, така краса.. :)))0

Изменено пользователем Буратино

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

INT08U UARTReceiveByte (void) {
    INT08U temp1=UART_RxHead, temp2=UART_RxTail;

    while (temp1 == temp2) {
    };

Иззюмительный кусок кода! :1111493779: Повесить МК можно и гораздо проще!

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Иззюмительный кусок кода! :1111493779: Повесить МК можно и гораздо проще!

 

нормально все там, а если че то можно через некоторое время выпрыгивать из этого ожидания. Посмотрите, там даже место оставлено для этих целей:)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

нормально все там, а если че то можно через некоторое время выпрыгивать из этого ожидания. Посмотрите, там даже место оставлено для этих целей:)
Да ну? С чего это оно 'выпрыгнет' из while цикла? У вас же там сравниваются локальные копии volatile переменных (из temp1 и temp2). Если они окажутся равными на входе в цикл, то цикл никогда не кончится

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да ну? С чего это оно 'выпрыгнет' из while цикла? У вас же там сравниваются локальные копии volatile переменных (из temp1 и temp2). Если они окажутся равными на входе в цикл, то цикл никогда не кончится

 

хм, а и правда нехорошо. Я так сделал ибо компилятор ругался на сравнение volatile переменных.

Ну и че делать? Может быть внутри операторного блока цикла ,переменным temp1, temp2 присваивать значения volatile переменных?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я так сделал ибо компилятор ругался на сравнение volatile переменных.
Это он не прав :biggrin:

Ну и че делать? Может быть внутри операторного блока цикла ,переменным temp1, temp2 присваивать значения volatile переменных?

Достаточно одной временной переменной

INT08U temp1=UART_RxHead;

    while (temp1 == UART_RxTail) {
    
     temp1=UART_RxHead;
    };

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

хм, а и правда нехорошо. Я так сделал ибо компилятор ругался на сравнение volatile переменных.

Именно ругался, а не предупреждал о том, что ничего не знает об их поведении?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...