Easyelectronics.ru

Электроника для всех
Текущее время: 21 ноя 2019, 04:09

Часовой пояс: UTC + 5 часов



JLCPCB – Прототипы печатных плат за $2/10pcs (Любой цвет!)
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 6 ] 
Автор Сообщение
 Заголовок сообщения: PIC18F25K22. USART. Прерывание по передаче данных
СообщениеДобавлено: 29 янв 2019, 14:46 
Только пришел

Зарегистрирован: 29 май 2018, 16:33
Сообщения: 10
Добрый день. Есть контроллер серии PIC18. Возникла сейчас необходимость производить передачу по USART в прерывании. Раньше для этого я использовал функцию, и работало все без прерываний:
Код:
void usart_Tx(void* buf,BYTE size)
{
    BYTE i,j;
    UINT16 k;
    char* ptr = (char*)buf;
    TRAN; // установить признак передачи для переключения переходника TTL-RS485
    PIE1bits.RCIE = 0; // запретить прерывание от приемника USART
    for(i = 0; i < size; i++)
    {
        TXREG1 = ptr[i]; // запись байта в буфер передатчика USART
        while(!PIR1bits.TXIF); // ожидание опустошения буфера
        for(j = 0; j < 255; j++) // временная выдержка для достижения скорости передачи
            k++;
    }
    REC; // установить признак приема для переключения переходника TTL-RS485
    PIE1bits.RCIE = 1;   // разрешить прерывание от приемника USART
}


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

Все, что придумал, это
Код:
char* ptr = (char*)usart_rx_buf;

// количество данных для передачи
void tx_str(BYTE cnt)
{
   
    PIE1bits.TXIE = 1;                       
    TRAN; // установить признак передачи для переключения переходника TTL-RS485
    PIE1bits.RCIE = 0; // запретить прерывание от приемника USART
   
    totalElementstoSend = cnt;
    sendPointer = 0;
   
    REC; // установить признак приема для переключения переходника TTL-RS485
    PIE1bits.RCIE = 1;   // разрешить прерывание от приемника USART
}

void usart_Tx_Int(void)
{
    BYTE i,j;
    UINT16 k;

    TXREG = ptr[sendPointer];
    while(!PIR1bits.TXIF); // ожидание опустошения буфера
        for(j = 0; j < 255; j++) // временная выдержка для достижения скорости передачи
            k++;
    sendPointer++;
    if (sendPointer >= totalElementstoSend)
        PIE1bits.TXIE = 0;
    PIR1bits.TXIF = 0;
}


Вроде все передается, но все равно как будто не то. Подскажите, пожалуйста, как это сделать лучше? Или может у кого небольшой фрагментик готового кода завалялся :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: PIC18F25K22. USART. Прерывание по передаче данных
СообщениеДобавлено: 29 янв 2019, 16:17 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1030
Давно я пиками не занимался, но зачем ты в обработчике прерывания цикл ожидания добавил? В итоге после этого цикла байт уже ушел и TXIF снова в 1, писать в него 0 бессмысленно, т.к. он Read Only. Сразу после выхода из обработчика в него заходит снова, никакой экономии времени нет, наоборот, его должно тратится еще больше, чем в первоначальном варианте где вся отправка в цикле.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: PIC18F25K22. USART. Прерывание по передаче данных
СообщениеДобавлено: 29 янв 2019, 17:04 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2014, 13:25
Сообщения: 766
Откуда: Earth
У вас неправильное понимание принципа работы с прерываниями. Внитри прерываний никаких "ожидание опустошения буфера" и "временная выдержка для достижения скорости передачи". Сунули байт, проверили флажок, и сразу на выход.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: PIC18F25K22. USART. Прерывание по передаче данных
СообщениеДобавлено: 29 янв 2019, 17:17 
Только пришел

Зарегистрирован: 29 май 2018, 16:33
Сообщения: 10
Gnusmas писал(а):
Сунули байт, проверили флажок, и сразу на выход.

Подскажите, о каком флаге идет речь? Что-то под конец дня голова уже не работает :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: PIC18F25K22. USART. Прерывание по передаче данных
СообщениеДобавлено: 29 янв 2019, 18:17 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2014, 13:25
Сообщения: 766
Откуда: Earth
Auratos писал(а):
Подскажите, о каком флаге идет речь? Что-то под конец дня голова уже не работает :)

Ну например в передатчике в роли "флажка" у вас выступает "if (sendPointer >= totalElementstoSend)" - есть ли данные для передачи, и на его основе вы делаете запрет прерываний, если все передалось, так что тут все норм. Осталось избавиться от ненужных задержек.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: PIC18F25K22. USART. Прерывание по передаче данных
СообщениеДобавлено: 30 янв 2019, 00:24 
Заглядывает иногда

Зарегистрирован: 28 апр 2010, 00:17
Сообщения: 124
Откуда: picping.lg.ua
Как все запущено...

Код:
/**
  Section: Macro Declarations
*/
#define EUSART1_TX_BUFFER_SIZE 8

/**
  Section: Global Variables
*/
// TX
volatile uint8_t eusart1TxHead = 0;
volatile uint8_t eusart1TxTail = 0;
volatile uint8_t eusart1TxBuffer[EUSART1_TX_BUFFER_SIZE];
volatile uint8_t eusart1TxBufferRemaining;


//  Section: EUSART1 APIs

void EUSART1_Initialize(void)
{
    // disable interrupts before changing states
    PIE1bits.RC1IE = 0;
    PIE1bits.TX1IE = 0;
    // Set the EUSART1 mod
    // Set the EUSART1 module to the options selected in the user interface.

    // ABDOVF no_overflow; CKTXP async_noninverted_sync_fallingedge; BRG16 16bit_generator; WUE disabled; ABDEN disabled; DTRXP not_inverted;
    BAUDCON1 = 0x08;

    // SPEN enabled; RX9 8-bit; CREN enabled; ADDEN disabled; SREN disabled;
    RCSTA1 = 0x90;

    // TX9 8-bit; TX9D 0; SENDB sync_break_complete; TXEN enabled; SYNC asynchronous; BRGH hi_speed; CSRC slave_mode;
    TXSTA1 = 0x24;
    // 115200
    SPBRG1 = 0x8A;
    SPBRGH1 = 0x00;

    // initializing the driver state
    eusart1TxHead = 0;
    eusart1TxTail = 0;
    eusart1TxBufferRemaining = sizeof(eusart1TxBuffer);

    // enable receive interrupt
    PIE1bits.RC1IE = 1;
}

void EUSART1_Write(uint8_t txData)
{
    while(0 == eusart1TxBufferRemaining)
    {
    }
   
    if(0 == PIE1bits.TX1IE)
    {
        TXREG1 = txData;
    }
    else
    {
        PIE1bits.TX1IE = 0;
        eusart1TxBuffer[eusart1TxHead++] = txData;
        if(sizeof(eusart1TxBuffer) <= eusart1TxHead)
        {
            eusart1TxHead = 0;
        }
        eusart1TxBufferRemaining--;
    }
    PIE1bits.TX1IE = 1;
}

void EUSART1_Transmit_ISR(void)
{
    if(sizeof(eusart1TxBuffer) > eusart1TxBufferRemaining)
    {
        TXREG1 = eusart1TxBuffer[eusart1TxTail++];
        if(sizeof(eusart1TxBuffer) <= eusart1TxTail)
        {
            eusart1TxTail = 0;
        }
        eusart1TxBufferRemaining++;
    }
    else
    {
        PIE1bits.TX1IE = 0;
    }
}

void EUSART1_Receive_ISR(void)
{
    uint8_t a ;
    a = RCREG1;
    // user code

}


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 6 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB