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

 
 
> Правильно отключить прерывания, на время передачи по UART
athlon64
сообщение Jun 11 2010, 12:43
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 156
Регистрация: 10-03-10
Из: Уфа
Пользователь №: 55 882



Портирую прошивку с AVR на ARM SAM7X512. В прошивке для AVR во время вывода в порты UART0, UART1 глобально запрещались и разрешались прерывания командами CLI и SEI.
В проекте для SAM7 добавил одноимённые функции:
Код
unsigned char SREG;
////unsigned long int IMR;
/*===============================================
  Процедуры CLI и SEI заменяют соответствующие АВР-овские,
  выключают и включают все прерывания
  ===============================================
*/
void CLI(){                                        //// Отключает все прерывания
AT91C_BASE_AIC->AIC_IDCR=0xFFFFFFFF;
SREG=0x00;
}

void SEI(){                                        //// Включает все прерывания
AT91C_BASE_AIC->AIC_IDCR=0;
SREG=0x80;
}


Процедура отправки очередного байта в ком-порт выглядит так:
Код
void Out2COM(){
char i;

if (AT91C_BASE_US0->US_CSR & AT91C_US_TXEMPTY){             //// регистр к передаче готов
        CLI();
        if(OutBufCOMIdxWR==OutBufCOMIdxRD){                   // буфер пуст
            OutBufCOMIdxWR=OutBufCOMIdxRD=0;
            
            if (AT91C_BASE_US0->US_CSR & AT91C_US_ENDTX){   //// Если передача закончена // Разрешаем прием по COM
                USART_ReadBuffer(AT91C_BASE_US0, &i, 1);
                COM_mode &= ~0x83;      // нет пилотов и нет принятых пакетов и нет Tx
                AT91C_BASE_US0->US_IER = AT91C_US_RXBUFF;   //// разрешаем прерывания приема СОМ
            }
        }
        else{
            AT91C_BASE_US0->US_THR = OutBufCOM[OutBufCOMIdxRD++]; //// выдали в порт
        }

        COMWaitCnt=0;
        SEI();
    }
    else if(COMWaitCnt++>5000){LedErrorOn(); while(1);}  // по WatchDog'у должны сброситься
}


В итоге МК пытаясь при инициализации отправить свой адрес в порт (адрес приходит нормально и МК не виснет, крутится в главном цикле main), в обработчик PIT он так и не попадает. Если убрать из процедуры отправки байта вызов CLI, то PIT работает, но вместо посылки (адреса устройства приходит байт 0x0D), видимо передачу прерывает PIT


--------------------
Руслан
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 10)
aaarrr
сообщение Jun 11 2010, 12:50
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



В IDCR писать нули совершенно бесполезно, для разрешения прерываний существует регистр IECR.
Глобально запрещать прерывания гораздо удобнее установкой бита I регистра CPSR ядра.
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jun 11 2010, 12:52
Сообщение #3


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(athlon64 @ Jun 11 2010, 16:43) *
В прошивке для AVR во время вывода в порты UART0, UART1 глобально запрещались и разрешались прерывания командами CLI и SEI.

Зачем?!!


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jun 12 2010, 10:53
Сообщение #4


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



И правда зачем?


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
athlon64
сообщение Jun 15 2010, 05:07
Сообщение #5


Частый гость
**

Группа: Свой
Сообщений: 156
Регистрация: 10-03-10
Из: Уфа
Пользователь №: 55 882



Цитата(aaarrr @ Jun 11 2010, 18:50) *
В IDCR писать нули совершенно бесполезно, для разрешения прерываний существует регистр IECR.
Глобально запрещать прерывания гораздо удобнее установкой бита I регистра CPSR ядра.

Как менять биты регистра CPSR в IAR я так и не понял. В at91sam7x512.h этот регистр не объявлен
Дальше разбираюсь, возможно проблема не в запрещении/разрешении прерываний. Как выясню, отпишу smile.gif

Цитата(MrYuran @ Jun 11 2010, 18:52) *
Зачем?!!

Цитата(demiurg_spb @ Jun 12 2010, 16:53) *
И правда зачем?

Ну как зачем. Как иначе исключить возможность прерывания передачи периодическим таймером или ещё чем то?


--------------------
Руслан
Go to the top of the page
 
+Quote Post
igorenja
сообщение Jun 15 2010, 05:26
Сообщение #6


Частый гость
**

Группа: Свой
Сообщений: 130
Регистрация: 8-08-08
Из: Новосибирск
Пользователь №: 39 488



Цитата(athlon64 @ Jun 15 2010, 12:07) *
Как менять биты регистра CPSR в IAR я так и не понял. В at91sam7x512.h этот регистр не объявлен
Дальше разбираюсь, возможно проблема не в запрещении/разрешении прерываний. Как выясню, отпишу smile.gif


В 4ом IARе было так:
CODE
#include "intrinsics.h"

....
__disable_interrupt();
....
__enable_interrupt();
...


как в 5ом не разбирался
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jun 15 2010, 06:11
Сообщение #7


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(athlon64 @ Jun 15 2010, 09:07) *
Ну как зачем. Как иначе исключить возможность прерывания передачи периодическим таймером или ещё чем то?

А как таймер может прервать передачу? Не понимаю...
Как раз наоборот, прерывания по опустошению передающего буфера очень облегчают жизнь.
Достаточно указать на буфер сообщения и выдать первый байт, и остальные выскочат совершенно без никакого участия со стороны основной программы. А в это время можно заниматься полезными делами (вместо того чтобы тупо караулить тормозной УАРТ)


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
athlon64
сообщение Jun 15 2010, 10:08
Сообщение #8


Частый гость
**

Группа: Свой
Сообщений: 156
Регистрация: 10-03-10
Из: Уфа
Пользователь №: 55 882



Начал отключать прерывания по одному, выяснилось что если выключить прерывание от PIT - посылка по USART проходит без проблем.
В обработчике прерывания PIT сделал мигалку светодиода и посмотрел осциллографом что происходит на ножке. Независимо от задаваемого периода PIT, в обработчик PIT попадаю раз в 5мкс.
Инициализация PIT:
Код
    PIT_Init(1000, 48); // period 1ms

    // Configure interrupt on PIT
    IRQ_DisableIT(AT91C_ID_SYS);
    IRQ_ConfigureIT(AT91C_ID_SYS, AT91C_AIC_PRIOR_LOWEST, IRQ_PIT);
    IRQ_EnableIT(AT91C_ID_SYS);
    PIT_EnableIT();

    // Enable the pit
    PIT_Enable();

Обработчик PIT:
Код
void IRQ_PIT(){ //1 msek
unsigned int status;

status = PIT_GetStatus() & AT91C_PITC_PITS;
if (status != 0) {
        Led_blink2();
}


PS: пробовал читать PIT_PIVR в обработчике прерывания, тогда ножка МК вообще перестаёт дрыгаться

Сообщение отредактировал athlon64 - Jun 15 2010, 10:18


--------------------
Руслан
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Jun 15 2010, 10:16
Сообщение #9


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(athlon64 @ Jun 15 2010, 14:08) *
Независимо от задаваемого периода PIT, в обработчик PIT попадаю раз в 5мкс.

Не знаю, что такое PIT sad.gif
но жизненный опыт подсказывает, что наверняка в обработчике прерывания надо какой-то флажок загасить


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 15 2010, 10:24
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(athlon64 @ Jun 15 2010, 14:08) *
PS: пробовал читать PIT_PIVR в обработчике прерывания, тогда ножка МК вообще перестаёт дрыгаться

PIVR читать необходимо, иначе прерывание не будет сброшено. Если выполнить это чтение до чтения статуса, то PITS, естественно, будет сброшен, и ничего мигать не будет.
Go to the top of the page
 
+Quote Post
athlon64
сообщение Jun 15 2010, 10:42
Сообщение #11


Частый гость
**

Группа: Свой
Сообщений: 156
Регистрация: 10-03-10
Из: Уфа
Пользователь №: 55 882



Заработала отправка в USART и периодический 1мс таймер smile.gif Спасибо
В последнем случае проблема была в том что я на время отсылки в ком-порт отключал прерывания от PIT, в это время PIT переполнялся но прерывание сгенерить не мог.


--------------------
Руслан
Go to the top of the page
 
+Quote Post

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

 


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


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