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

Обсуждаем контроллеры компании Atmel.
Ответить
Встал на лапы
Аватара пользователя
Сообщения: 120
Зарегистрирован: Сб апр 20, 2013 16:38:32
Откуда: Страна Чудес

Сообщение 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")
Последний раз редактировалось ATMEL86 Пн июл 04, 2016 10:42:32, всего редактировалось 1 раз.
Реклама
Это не хвост, это антенна
Аватара пользователя
Сообщения: 1368
Зарегистрирован: Вс мар 28, 2010 12:52:22
Откуда: Беларусь

Сообщение dr.doc »

А разве
interrupt [USART_TXC]
не выходит в прерывание по завершению передачи байта?
«Еще я хотел бы, чтобы наши ученые изобрели какой-то новый источник энергии, чтобы мы на коленях не ползали даже перед нашими братьями, умоляя их и выпрашивая тонну нефти или кубометр газа», — рассказал белорусский президент.
Реклама
Встал на лапы
Аватара пользователя
Сообщения: 120
Зарегистрирован: Сб апр 20, 2013 16:38:32
Откуда: Страна Чудес

Сообщение ATMEL86 »

Добрый вечер dr.doc! В том то и дело, что не выходит! :shock: потому я и ломаю голову который день...
Поставщик валерьянки для Кота
Сообщения: 2222
Зарегистрирован: Вт ноя 27, 2007 11:32:06
Откуда: Tashkent

Сообщение uk8amk »

Это не весь код.
Где запускается передача данных?
Реклама
Эиком - электронные компоненты и радиодетали
Встал на лапы
Аватара пользователя
Сообщения: 120
Зарегистрирован: Сб апр 20, 2013 16:38:32
Откуда: Страна Чудес

Сообщение ATMEL86 »

Это и есть весь код . Запуск передачи данных если в PORTB.4 приходит лог."1"
Реклама
Говорящий с текстолитом
Аватара пользователя
Сообщения: 1525
Зарегистрирован: Чт июн 10, 2010 20:11:19

Сообщение COKPOWEHEU »

Если я правильно помню, для передачи нескольких байт используется прерывание UDRE, а не RXC. Ну и пока не приведете полный код сложно что-то более конкретное порекомендовать.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Странная у вас какая-то терминология, "не выходит в прерывание". Тогда из прерывания должно входить? :)
ATMEL86 писал(а):Это и есть весь код
Тогда чего он работать то будет? После выполнения последней строчки основной программы UBRRL=0x2F; МК пойдет выполнять пустую область памяти? Где код, который изменяет значение регистра PORT или его значение меняется каким-то магическим образом? Где разрешение всех прерываний? Одно сплошное где.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Держит паяльник хвостом
Сообщения: 933
Зарегистрирован: Ср апр 13, 2011 11:09:20
Откуда: Екатеринбург

Сообщение Alkul »

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

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

А вообще, сама идеология программы у Вас неправильная. Какой Вы вообще результат хотите получить?
Встал на лапы
Аватара пользователя
Сообщения: 120
Зарегистрирован: Сб апр 20, 2013 16:38:32
Откуда: Страна Чудес

Сообщение 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){ //вечный цикл
     
     }
     
  };
ARV
Ум, честь и совесть. И скромность.
Аватара пользователя
Сообщения: 18783
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск

Сообщение 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;   //выключается светодиод
      
     } 
     };
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Контактная информация:
Держит паяльник хвостом
Сообщения: 933
Зарегистрирован: Ср апр 13, 2011 11:09:20
Откуда: Екатеринбург

Сообщение Alkul »

Автор, если передаете только один байт, прерывание TXC можете вообще не использовать, ARV Вам правильно написал.
Прерывание TXC используется, если, к примеру, в ответ на байт 0x05 Вам надо передать несколько байт.
В этом случае первый из этих нескольких следует передать так, как показал ARV, а вот передача (занесение в регистр UDR) остальных делается в прерывании TXC. Конечно, тут нужно будет счетчик переданных байт организовать, а сам передаваемый пакет предварительно сформировать в ОЗУ. Тогда счетчик переданных байт будет смещением, которое надо прибавить к адресу первого байта пакета для получения адреса текущего передаваемого байта.
Встал на лапы
Аватара пользователя
Сообщения: 120
Зарегистрирован: Сб апр 20, 2013 16:38:32
Откуда: Страна Чудес

Сообщение ATMEL86 »

Да :)) работает!!! Спасибо вам, за то что поддерживаете !!! :beer:
Ответить

Вернуться в «AVR»