Страница 1 из 1

Проблема UART передача байта через прерывания!!!

Добавлено: Вс июл 03, 2016 20:10:34
ATMEL86
Привет всем! Не могу понять в чём проблема, не передаётся значение "0х15" через прерывание. 2 дня голову ломаю :shock:
скажите пожалуйста где я на тупил... :(

char data;

// USART Transmitter interrupt service routine
interrupt [USART_TXC] void usart_tx_isr(void)
{

UDR=data; //передаём данные
if (PORTB.4==1) { //если в порте появится лог "1"
data=0x15; // отсылаем

}

};



// USART initialization
// Communication Parameters: 8 Data, 1 Stop, No Parity
// USART Receiver: On
// USART Transmitter: On
// USART Mode: Asynchronous
// USART Baud Rate: 9600
UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<U2X) | (0<<MPCM);
UCSRB=(1<<RXCIE) | (1<<TXCIE) | (0<<UDRIE) | (1<<RXEN) | (1<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
UCSRC=(0<<UMSEL) | (0<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
UBRRH=0x00;
UBRRL=0x2F;


#asm("sei")

Re: ПРОБЛЕМА UART передача байта через прерывания!!!

Добавлено: Вс июл 03, 2016 21:29:19
dr.doc
А разве
interrupt [USART_TXC]
не выходит в прерывание по завершению передачи байта?

Re: ПРОБЛЕМА UART передача байта через прерывания!!!

Добавлено: Вс июл 03, 2016 22:00:24
ATMEL86
Добрый вечер dr.doc! В том то и дело, что не выходит! :shock: потому я и ломаю голову который день...

Re: ПРОБЛЕМА UART передача байта через прерывания!!!

Добавлено: Вс июл 03, 2016 22:44:19
uk8amk
Это не весь код.
Где запускается передача данных?

Re: ПРОБЛЕМА UART передача байта через прерывания!!!

Добавлено: Пн июл 04, 2016 06:14:11
ATMEL86
Это и есть весь код . Запуск передачи данных если в PORTB.4 приходит лог."1"

Re: ПРОБЛЕМА UART передача байта через прерывания!!!

Добавлено: Пн июл 04, 2016 06:46:40
COKPOWEHEU
Если я правильно помню, для передачи нескольких байт используется прерывание UDRE, а не RXC. Ну и пока не приведете полный код сложно что-то более конкретное порекомендовать.

Re: ПРОБЛЕМА UART передача байта через прерывания!!!

Добавлено: Пн июл 04, 2016 06:58:04
Z_h_e
Странная у вас какая-то терминология, "не выходит в прерывание". Тогда из прерывания должно входить? :)
ATMEL86 писал(а):Это и есть весь код
Тогда чего он работать то будет? После выполнения последней строчки основной программы UBRRL=0x2F; МК пойдет выполнять пустую область памяти? Где код, который изменяет значение регистра PORT или его значение меняется каким-то магическим образом? Где разрешение всех прерываний? Одно сплошное где.

Re: ПРОБЛЕМА UART передача байта через прерывания!!!

Добавлено: Пн июл 04, 2016 19:11:25
Alkul
COKPOWEHEU писал(а):для передачи нескольких байт используется прерывание UDRE, а не RXC
Для передачи нескольких байт можно использовать хоть UDRE, хоть TXC, не суть важно.

Мне странно, автор что-то ожидает получить запуск прерывания от изменения состояния на выводе 4 порта B?
С какой стати?
Автор, для начала - Ваша программа прочитает состояние порта, если войдет в обработчик прерывания TXC. Для того, чтобы это случилось, надо, чтобы по UART передался какой-то байт, пока этого нет, можете "дергать" этот пин хоть до посинения, ничего не будет. Это раз.
Если Вы хотите прочитать состояние пина, надо читать регистр PINB, а не PORTB (для порта B, разумеется). То есть, регистр PIN, а не PORT, регистр PORT - это регистр-защелка, в нем хранится то, что Вы выводите из порта, если порт сконфигурирован как выход. А если как вход, то регистр PORT отвечет за включение/отключение внутренних pull-up резисторов. Это два.
Ну и в треитьх - если хотите работать с портами, их для начала надо инициализировать.

А вообще, сама идеология программы у Вас неправильная. Какой Вы вообще результат хотите получить?

Re: Проблема UART передача байта через прерывания!!!

Добавлено: Пн июл 04, 2016 20:14:56
ATMEL86
суть программы заключается: если приняли на пример значение 0х05, то мы должны отправить значение 0х15 (приём - передача должно выполнятся в прерываниях)

Код: Выделить всё

#include <tiny2313.h>
#include <stdio.h>

char priem;   // переменная "priem" тип данных Char (0...255)

// USART Receiver interrupt service routine
    interrupt [USART_RXC] void usart_rx_isr(void)
    {
       priem=UDR;  //читаем из регистра 
       
      if (priem==0x05) { //если приняли значение 0х05 то
      PORTB.4=1;      //включается светодиод
     }
          
      if (priem==0x09) {  //если приняли значение 0х09 то
      PORTB.4=0;   //выключается светодиод
      
     } 
     };
     


// USART Transmitter interrupt service routine
   interrupt [USART_TXC] void usart_tx_isr(void)
    { 
         
     UDR=data; //записуем в регистр
     
     if (PINB.4==1) { 
     data=0x15;  // отсылаем
     }
     };
     
     
     
     
     
     
     
     
       void main(void)
  { 
  
  
      // Crystal Oscillator division factor: 1
    #pragma optsize-
    CLKPR=(1<<CLKPCE);
    CLKPR=(0<<CLKPCE) | (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
    #ifdef _OPTIMIZE_SIZE_
    #pragma optsize+
     #endif

    DDRB=0b00010000;//Выходы 
    PORTB=0b00000000; //Входы
    
    
    // USART initialization
    // Communication Parameters: 8 Data, 1 Stop, No Parity
    // USART Receiver: On
    // USART Transmitter: On
    // USART Mode: Asynchronous
    // USART Baud Rate: 9600
       UCSRA=(0<<RXC) | (0<<TXC) | (0<<UDRE) | (0<<FE) | (0<<DOR) | (0<<UPE) | (0<<U2X) | (0<<MPCM);
       UCSRB=(1<<RXCIE) | (1<<TXCIE) | (0<<UDRIE) | (1<<RXEN) | (1<<TXEN) | (0<<UCSZ2) | (0<<RXB8) | (0<<TXB8);
       UCSRC=(0<<UMSEL) | (0<<UPM1) | (0<<UPM0) | (0<<USBS) | (1<<UCSZ1) | (1<<UCSZ0) | (0<<UCPOL);
       UBRRH=0x00;
       UBRRL=0x2F;
  
     
     #asm("sei") //Разрешено глобальное прерывание
     
     
     while (1){ //вечный цикл
     
     }
     
  };

Re: Проблема UART передача байта через прерывания!!!

Добавлено: Пн июл 04, 2016 20:45:05
ARV
Чтобы передать 0x15 в случае приема 0х05, надо в обработчике прерывания ПО ПРИЕМУ сделать UDR = 0x15:

Код: Выделить всё

// USART Receiver interrupt service routine
    interrupt [USART_RXC] void usart_rx_isr(void)
    {
       priem=UDR;  //читаем из регистра 
       
      if (priem==0x05) { //если приняли значение 0х05 то
      PORTB.4=1;      //включается светодиод
      UDR = 0x15; // и передаем число
     }
          
      if (priem==0x09) {  //если приняли значение 0х09 то
      PORTB.4=0;   //выключается светодиод
      
     } 
     };

Re: Проблема UART передача байта через прерывания!!!

Добавлено: Пн июл 04, 2016 21:07:27
Alkul
Автор, если передаете только один байт, прерывание TXC можете вообще не использовать, ARV Вам правильно написал.
Прерывание TXC используется, если, к примеру, в ответ на байт 0x05 Вам надо передать несколько байт.
В этом случае первый из этих нескольких следует передать так, как показал ARV, а вот передача (занесение в регистр UDR) остальных делается в прерывании TXC. Конечно, тут нужно будет счетчик переданных байт организовать, а сам передаваемый пакет предварительно сформировать в ОЗУ. Тогда счетчик переданных байт будет смещением, которое надо прибавить к адресу первого байта пакета для получения адреса текущего передаваемого байта.

Re: Проблема UART передача байта через прерывания!!!

Добавлено: Пн июл 04, 2016 22:37:40
ATMEL86
Да :)) работает!!! Спасибо вам, за то что поддерживаете !!! :beer: