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

 
 
> RFM50 (Si1000) + SmaRTClock + ISR, нужна помощь
pepelats
сообщение Apr 29 2012, 11:41
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 20-01-10
Из: Томск
Пользователь №: 54 958



Здравствуйте

Решил обратиться сюда, т.к. сам уже все перепробовал и особого результата не добился.
Проблема такая:

Есть радиомодуль от HopeRF, который построен на базе Si1000. В этом Si1000 есть так называемый SmaRTClock для реализации часов реального времени.
Необходимо в заданный интервал (пускай будет раз в секунду) отправлять пакет с данными. Настраиваю обработчик прерывания INTERRUPT_RTC0ALARM и в нем делаю инкремент переменной и моргание светодиодом

Код
...
U8 __xdata Pktcnt;
...
INTERRUPT (RTC0ALARM_ISR, INTERRUPT_RTC0ALARM)
{
    LEDTX = !LEDTX;
    Pktcnt = (Pktcnt == 255 ) ? 0 : Pktcnt + 1;
    RTC_Alarm = 1;
}


в основном теле программы я по событию отправляю некий пакет в котором передаю значение переменной Pktcnt

Код
...
U8 __xdata RxBuffer[64];
U8 __xdata TxBuffer[64];
...

void main (void)
{

    while (1) {
        PCON |= 0x01;                    // Enter Idle mode
        PCON = PCON;                   // Safety dummy instruction
      
        if(RTC_Alarm) {
            RTC_Alarm = 0;                
            TxBuffer[0] = Pktcnt;
            TxBuffer[1] = 0;
            TxBuffer[2] = 0;
            TxBuffer[3] = 0;
            TxBuffer[4] = 0;
            rtPhyTx( 5, TxBuffer );
        }
   }
}


по идее я должен на приемной стороне каждую секунду получать пакеты где значение Pktcnt каждый раз увеличивается на 1. Но ну тут то было. Светодиод моргает как положено раз в секунду. Пакеты тоже приходят раз в секунду, но значение поля меняется нифига не на 1. Изменяться оно может на 6 на 7. По разному бывает. Т.е. получаю в пакете 1, потом 7, потом 13 и т.д.
Мой мозг отказывается это понимать smile3046.gif

Помогите пожалуйста разобраться в этих "чудесах" . help.gif
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
barabek
сообщение May 1 2012, 22:02
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 540
Регистрация: 16-08-07
Из: Владивосток
Пользователь №: 29 831



Цитата(pepelats @ Apr 29 2012, 21:41) *
Есть радиомодуль от HopeRF, который построен на базе Si1000. В этом Si1000 есть так называемый SmaRTClock для реализации часов реального времени.
Изменяться оно может на 6 на 7. По разному бывает. Т.е. получаю в пакете 1, потом 7, потом 13 и т.д.
Мой мозг отказывается это понимать smile3046.gif

Помогите пожалуйста разобраться в этих "чудесах" . help.gif


Предупреждаю, ни с HopeRF ни с si1000 не работал. И не пойму каким компилятором Вы пользовались и все остальное. Но, как мне видится, Вы в обработчике прерываний дожны убрать какой-то аппаратный флаг. А раз Вы этого не делаете, то несколько раз подряд это прерывание вызывается до того как заснуть. Не угадал? Либо нужно переводить будильник на секунду вперед. Но у Вас я вообще не вижу никаких переводов и манипуляций с модулем SmaRTCclock в прерывании. Видимо эти действия выполняет какая-то ОС?


Go to the top of the page
 
+Quote Post
pepelats
сообщение May 2 2012, 05:19
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 20-01-10
Из: Томск
Пользователь №: 54 958



Цитата(barabek @ May 2 2012, 05:02) *
Предупреждаю, ни с HopeRF ни с si1000 не работал. И не пойму каким компилятором Вы пользовались и все остальное. Но, как мне видится, Вы в обработчике прерываний дожны убрать какой-то аппаратный флаг. А раз Вы этого не делаете, то несколько раз подряд это прерывание вызывается до того как заснуть. Не угадал? Либо нужно переводить будильник на секунду вперед. Но у Вас я вообще не вижу никаких переводов и манипуляций с модулем SmaRTCclock в прерывании. Видимо эти действия выполняет какая-то ОС?


Компилятор я использую SDCC, хотя пробовал на Keil и "чудес" там было не меньше.
По идее Вы правы в начале обработчика надо бы выключать это прерывание с помощью
Код
EIE1 &= ~0x02;

в на выходе включать
Код
EIE1 |= 0x02;


но я так делал, и проблемы это не решало.
Выяснил тут, что действительно как то обработчик похоже несколько раз вызывается. Щас добавил флаг, чтобы значение устанавливалось только один раз и больше не менялось пока не считаю его. Помогло, но это тоже не выход. Почему возникает такой "дребезг" в ISR не понимаю. Обработчик делал по примеру от Silabs.
Go to the top of the page
 
+Quote Post
barabek
сообщение May 2 2012, 05:28
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 540
Регистрация: 16-08-07
Из: Владивосток
Пользователь №: 29 831



Цитата(pepelats @ May 2 2012, 15:19) *
Код
EIE1 &= ~0x02;

в на выходе включать
Код
EIE1 |= 0x02;

нет, я имел ввиду другое. Нужно не сбрасывать флаг разрешения прерывания, а хардверный флаг, тот что выставляет железо. Как флаги TI и RI для UART. Например, у меня в f410 для сброса прерывания от RTC был такой код:

Код
void RTCinter(void)interrupt 8 using 1
    {
    unsigned char contr;
    while(RTC0ADR & 0x80);
    RTC0ADR=RTC0CN;
    RTC0ADR|=0x80;
    while(RTC0ADR & 0x80);
    contr=RTC0DAT;
if(contr&0x20)            //OSCFAIL=1,сбой генератора часов
        {
    //!!! перезапускаем.
        contr&=~0x20;
        while(RTC0ADR & 0x80);
        RTC0ADR=RTC0CN;
        RTC0DAT=contr;

        while(RTC0ADR & 0x80);
        RTC0ADR=RTC0CN;
        RTC0DAT=0;

        while(RTC0ADR & 0x80);
        RTC0ADR=RTC0XCN;
        RTC0DAT=0x60;

        while(RTC0ADR & 0x80);
        RTC0ADR=RTC0CN;
        RTC0DAT=0x90;
    }
if(contr&0x04)            //ALRM=1,сработал будильник, переставляем на секунду
    {//
    contr&=~0x0c;        //сбрасываем ALRM и RTC0AEN-разрешение аларма
        while(RTC0ADR & 0x80);
        RTC0ADR=RTC0CN;
        RTC0DAT=contr;
        sec_tick=1;
        }
    }


Go to the top of the page
 
+Quote Post
pepelats
сообщение May 2 2012, 06:52
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 56
Регистрация: 20-01-10
Из: Томск
Пользователь №: 54 958



Цитата(barabek @ May 2 2012, 12:28) *
нет, я имел ввиду другое. Нужно не сбрасывать флаг разрешения прерывания, а хардверный флаг, тот что выставляет железо. Как флаги TI и RI для UART. Например, у меня в f410 для сброса прерывания от RTC был такой код:

Код
void RTCinter(void)interrupt 8 using 1
    {
    unsigned char contr;

if(contr&0x04)            //ALRM=1,сработал будильник, переставляем на секунду
    {//
    contr&=~0x0c;        //сбрасываем ALRM и RTC0AEN-разрешение аларма
        while(RTC0ADR & 0x80);
        RTC0ADR=RTC0CN;
        RTC0DAT=contr;
        sec_tick=1;
        }
    }


Блин, похоже так и есть. Вечером попробую и отпишусь. В примерах от Silabs они только флаг разрешения прерывания сбрасывали, вот я и сделал так же.
Go to the top of the page
 
+Quote Post



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

 


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


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