Миландр

Ключевым подразделением нашей компании является Центр Проектирования интегральных микросхем
Текущее время: 2017-ноя-18 11:38

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




Начать новую тему Ответить на тему  [ Сообщений: 7 ] 
Автор Сообщение
СообщениеДобавлено: 2011-ноя-11 10:05 
Не в сети

Зарегистрирован: 2011-май-11 07:35
Сообщения: 25
Здравствуйте все!!!! Подскажите пожалуйста, как грамотно организовать доступ к массивам из iServer?
Реализовано чтение с АЦП с нескольких каналов поочерёдно и по условиям задачи нужно реализовать чтение периодических сигналов в массивы для обработки (уфф.. надеюсь понятно объяснил :) ). К сожалению при компиляции выводится ошибки:
... FSR0 not saved/restored during interrupt 'iServer'
... PRODL not saved/restored during interrupt 'iServer'
... PRODH not saved/restored during interrupt 'iServer'


Привожу часть кода..
Объявлено глобально:
Код:
bank1 struct _TAB
{
    uns16 Ur;
    uns16 Ui;
    uns16 Uf;
    uns16 Uc;
    uns16 Ic;
}TAB[D1UU551_SIZE_TAB];

bank1 struct _ADC
{
    uns8 CHANAL; // номер канала АЦП;
    uns8 QUANTUM; // номер кванта импульса
}ADC;

bank1 struct _STATUS // глобальная переменная текущего состояния
{
...
}CURRSTATUS;

находится в interrupt iServer(void)
Код:
/* обрабодка прерывания от АЦП */
    if(ADCIF)
   {
            ...
           
            if(ADC.QUANTUM > D1UU551_SIZE_TAB) goto ADC_channel_reset;

            TEMP16 = ADRESH;
            TEMP16 = TEMP16 << 8;
            switch (ADC.CHANAL)
            {
            case D1UU551_AD0: // Ток катода
                CURRSTATUS.Ic = ADRESL;
                CURRSTATUS.Ic |= TEMP16;
                TAB[ADC.QUANTUM].Ic = CURRSTATUS.Ic;
                ADC.CHANAL = D1UU551_AD1;
                break;
            case D1UU551_AD1: // Нарпяжение (мощность) отраженное
                CURRSTATUS.Ur = ADRESL;
                CURRSTATUS.Ur |= TEMP16;
                TAB[ADC.QUANTUM].Ur = CURRSTATUS.Ur;
                ADC.CHANAL = D1UU551_AD2;
                break;
            case D1UU551_AD2: // Нарпяжение (мощность) падающая
                CURRSTATUS.Ui = ADRESL;
                CURRSTATUS.Ui |= TEMP16;
                TAB[ADC.QUANTUM].Ui = CURRSTATUS.Ui;
                ADC.CHANAL = D1UU551_AD3;
                break;
            case D1UU551_AD3: // Напряжение катода
                CURRSTATUS.Uc = ADRESL;
                CURRSTATUS.Uc |= TEMP16;
                TAB[ADC.QUANTUM].Uc = CURRSTATUS.Uc;
                ADC.CHANAL = D1UU551_AD7;
                break;
            case D1UU551_AD7: // Напряжение накала
                CURRSTATUS.Uf = ADRESL;
                CURRSTATUS.Uf |= TEMP16;
                TAB[ADC.QUANTUM].Uf = CURRSTATUS.Uf;
                ADC.CHANAL = D1UU551_AD0;

                ADC.QUANTUM++;
                break;
            }
        }
ADC_channel_reset:  /* переключение канала ADC */
        TEMP8 = ADC.CHANAL;
        TEMP8 = (TEMP8 & 0x0f) << 4;
        ADCON0 = 0b00000101; // ADC on, AD0
        ADCON0 |= TEMP8;
       
        ADCIF = 0; // сбрасываем флаг прерывания от АЦП
        GO_DONE = 1; // включение выполнения преобразования АЦП
    }


компилятор ругается на
Код:
TAB[ADC.QUANTUM].Ic = CURRSTATUS.Ic;
...
TAB[ADC.QUANTUM].Ur = CURRSTATUS.Ur;
...
TAB[ADC.QUANTUM].Ui = CURRSTATUS.Ui;
...
TAB[ADC.QUANTUM].Uc = CURRSTATUS.Uc;
...
TAB[ADC.QUANTUM].Uf = CURRSTATUS.Uf;


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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2011-ноя-11 11:32 
Не в сети

Зарегистрирован: 2009-май-25 15:07
Сообщения: 158
Откуда: АО "ПКК Миландр"
Для доступа к структурам данных компилятор обычно использует FSR0 и FSR1.
Вы должны сохранять и восстанавливать их в обработчике прерываний.
Читаем в примере обработчика прерываний:
Код:
// save on demand: PRODL,PRODH,TBLPTRH,TBLPTRL,FSR0,FSR1
Однако регистры PRODH и PRODL в наших контроллерах доступны только для чтения, поэтому не рекомендуется использовать операторы умножения в прерывании (возможно, компилятор их неявно использует из-за сложных структур данных). И непонятно, зачем Вам такого крокодила вешать на прерывание. Вынесите " if(ADCIF)" в main.
WBR.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2011-ноя-11 13:06 
Не в сети

Зарегистрирован: 2011-май-11 07:35
Сообщения: 25
Lew, Вы предлагаете не использовать прерывания для АЦП?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2011-ноя-11 14:11 
Не в сети

Зарегистрирован: 2009-май-25 15:07
Сообщения: 158
Откуда: АО "ПКК Миландр"
Ecclesiastes писал(а):
Lew, Вы предлагаете не использовать прерывания для АЦП?
По моему мнению, прерывания надо использовать, когда время реакции на событие должно быть минимальным. Вам действительно нужна максимальная скорость преобразования АЦП? Может, разумнее запускать АЦП по таймеру?
В любом случае обработчик прерывания не должен выполнять вычисления и заполнять сложные структуры данных, пусть этим занимается основная программа.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2011-ноя-11 14:19 
Не в сети

Зарегистрирован: 2011-май-11 07:35
Сообщения: 25
Lew писал(а):
По моему мнению, прерывания надо использовать, когда время реакции на событие должно быть минимальным. Вам действительно нужна максимальная скорость преобразования АЦП? Может, разумнее запускать АЦП по таймеру?

Да.. мне нужна скорость.. т.к. нужно обработать несколько параметров при импульсе длиной в 0.1 секунды.

А по таймеру запускать ацп, это как?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2011-ноя-11 14:55 
Не в сети

Зарегистрирован: 2009-май-25 15:07
Сообщения: 158
Откуда: АО "ПКК Миландр"
Тогда, действительно, зачем нужны прерывания?
Код:
while(GO_DONE);
так быстрее всего.
WBR.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: 2014-окт-24 12:42 
Не в сети

Зарегистрирован: 2014-окт-16 07:19
Сообщения: 3
Нужно сохранит FSR0 и остальные если требуется.

Вот для FSR0. см. в INT17XXX.H
Код:
#define  multi_interrupt_entry_and_save \
    shrBank char sBSR, sALUSTA; \
    bank0 char sWREG, sPCLATH, THP; \
        \
   #asm \
    ; ADDRESS 0x08 \
    MOVFP BSR,sBSR           ; unbanked \
    MOVFP ALUSTA, sALUSTA    ; unbanked \
    CLRF BSR \
    MOVPF PCLATH, sPCLATH    ; bank 0 \
    MOVWF sWREG              ; bank 0 \
      MOVPF FSR0, THP  \
    CLRF PCLATH \
    GOTO INT_service \
    NOP \
         \
    ; ADDRESS 0x10 \
    MOVFP BSR,sBSR           ; unbanked \
    MOVFP ALUSTA, sALUSTA    ; unbanked \
    CLRF BSR \
    MOVPF PCLATH, sPCLATH    ; bank 0 \
    MOVWF sWREG              ; bank 0 \
    CLRF PCLATH \
    GOTO TMR0_service \
    NOP \
        \
    ; ADDRESS 0x18 \
    MOVFP BSR,sBSR           ; unbanked \
    MOVFP ALUSTA, sALUSTA    ; unbanked \
    CLRF BSR \
    MOVPF PCLATH, sPCLATH    ; bank 0 \
    MOVWF sWREG              ; bank 0 \
    CLRF PCLATH \
    GOTO T0CKI_service \
    NOP \
        \
    ; ADDRESS 0x20 \
    MOVFP BSR,sBSR           ; unbanked \
    MOVFP ALUSTA, sALUSTA    ; unbanked \
    CLRF BSR \
    MOVPF PCLATH, sPCLATH    ; bank 0 \
    MOVWF sWREG              ; bank 0 \
    CLRF PCLATH \
   #endasm \
    goto PERIPHERAL_service; \


Код:
#define interrupt_exit_and_restore \
   #asm \
      MOVFP THP, FSR0 \
    MOVFP sWREG,W            \
    MOVFP sPCLATH, PCLATH    \
    MOVFP sALUSTA, ALUSTA    \
    MOVFP sBSR, BSR          \
    RETFIE \
   #endasm \


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

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


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

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


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

Найти:
Перейти:  
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB