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

 
 
> вопросы по pic24, помогите новичку)
yliya
сообщение Nov 24 2012, 11:09
Сообщение #1





Группа: Новичок
Сообщений: 7
Регистрация: 22-11-12
Из: Украина
Пользователь №: 74 519



Здраствуйте!!!
помогите, пожалуйста...

Измерить временной интервал. Входные сигналы являются сигналами логического уровня ТТЛ. 2 входных сигнала (от двух фотодатчиков).
Использую микроконтроллер PIC24F16KA102 (28 ножек), семисегментную индикацию (5 индикаторов), интерфейс SPI.

по-быстрячку накидала алгоритм (прикрепила), начала писатьт прогу, застряла...
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
yliya
сообщение Dec 11 2012, 17:44
Сообщение #2





Группа: Новичок
Сообщений: 7
Регистрация: 22-11-12
Из: Украина
Пользователь №: 74 519



Спасибо огромное за ценные замечания) Обязательно учту.

volodya, вы поняли меня правильно и я хотела так и делать, но сложность моей задачи состоит в том, что где появится первый сигнал неизвестно (либо на INT0, либо на INT1)...

сделала бы так (если бы точно знала что сигнал появится на первом входе INT0) и пользовалась бы одним таймером:

/* Обработчик прерывания 1 (INT0) (пошел в магаз) */

void __attribute__ ((__interrupt__, no_auto_psv)) _INT0Interrupt(void)
{
_RB8=1; // засветили светодиод 1 (ушел)
_RB9=0; // погасили светодиод 2

IFS0bits.INT0IF =0; // обнуляем флаг INT0IF в регистре IFS0
IEC0bits.INT0IE=0; // запрещаем прерывания INT0
TMR1=0; // обнуляем таймер 1
tmr1Res = 0; // обнуляем переменную, в кот. накапливается кол-во времени от таймера
T1CONbits.TON=1; // старт таймера 1

}


/* Обработчик прерывания 2 (INT1) (вернулся домой) */

void __attribute__ ((__interrupt__, no_auto_psv)) _INT1Interrupt(void)
{

_RB8=0; // погасили светодиод 1
_RB9=1; // засветили светодиод 2 (вернулся домой)

IEC0bits.INT0IE=1; // разрешаем прерывания INT0
IFS1bits.INT1IF =0; // обнуляем флаг INT1IF в регистре IFS1
T1CONbits.TON=0; // cтоп таймера 1
tmrRes=TMR1;
}

но ... если сигнал появится на INT1? что делать в этом случае? поэтому чуть изменила мысль...

я получаю из таймера двоичное значение, мне нужно перевести в десятичное... Примерно так :

tmrRes=tmr1h
T=T+tmr1l
tmrRes=((tmr1H<<8)+tmr1L) ???

tmr1h, tmr1l - можно unsigned char?

Мало пока понимаю, но все же...

Спасибо огромное за помощь!

Сообщение отредактировал yliya - Dec 11 2012, 17:46
Go to the top of the page
 
+Quote Post
volodya
сообщение Dec 12 2012, 07:33
Сообщение #3


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

Группа: Свой
Сообщений: 194
Регистрация: 14-02-07
Из: УКРАИНА
Пользователь №: 25 344



Цитата(yliya @ Dec 11 2012, 19:44) *
но ... если сигнал появится на INT1? что делать в этом случае?

я получаю из таймера двоичное значение, мне нужно перевести в десятичное...


Если неизвестно который из сигналов приходит первый , но время необходимо измерить между двумя сигналами можно поступить следующим образом -
1 - установить прерывания на ожидание события.
2 - по свершившемуся событию (на любом из прерываний) проверить флаг (счетчик событий)
2.1 - если флаг сброшен (счетчик событий = 0) и запустить таймер.
2.2 - если флаг установлен (счетчик событий = 1) остановить таймер и получить время между событиями, установить признак готовности времени для основной программы.


Код
#define _INT0_PULSE 1
#define _INT1_PULSE 2

char countPulse = 0;
char timeOk = 0;
unsigned int timeResult = 0;

void __attribute__ ((__interrupt__, no_auto_psv)) _INT0Interrupt(void)
{
  ...... /* очистить флаг прерываний -  */

  controlPulse(_INT0_PULSE);

}

void __attribute__ ((__interrupt__, no_auto_psv)) _INT1Interrupt(void)
{
  ...... /* очистить флаг прерываний -  */

  controlPulse(_INT1_PULSE);

}

void controlPulse(char pulse)
{
  if( ! countPulse )
  {
    /*запустить таймер на отсчет времени*/
    countPulse = pulse;
    WriteTimerX(0);
    TXCONbits.TON=1;
  }
  else
  {
    if(p[u]u[/u]lse != countPulse)/*ожидать второго пульса*/ /*очепятку исправил */
    {
      /*остановить таймер, зафиксировать резыльтат*/
      countPulse = 0; /*сбросить флаг для следующего замера*/
      timeResult = ReadTimerX();
      timeOk = 1;
    }
    else
    {
      /* тот-же пульс - либо просто ожидать другого пульса,
          либо перезапустить отсчет времени
     */
    }    
  }
}
/* WriteTimerX(), ReadTimerX() - функция записи, чтения таймера X*/


Дополнительно контролируя pulse в controlPulse можно фиксировать какое событие было первым и принимать какое-то решение - зависит от постановки задачи.

В основной программе :
Код
while( ! timeOk )
{
  /*ожидание результата*/
}
......
/*получен результат , приступить к его обработке*/


По поводу доступа к регистрам таймера на этапе ознакомления рекомендую использовать библиотеку Timers Peripheral Module Library из 16-bit Compiler Peripheral Libraries (MPLAB - C30 XC16 , в других компиляторах может называться иначе, но обычно присутсвует ) - это позволит сконцентрироваться на решении главной задачи , а особенности обращения к аппаратным регистрам изучать по ходу ознакомления с программированием , или при возникновении необходимости глубокой оптимизации исполняемого кода.

для преобразования в двоично-десятичный результат
Код
unsigned int Bin; /* двоичное  */
unsigned char bcdResult[5] = {0,0,0,0,0}; /*двоично-десятичный результат */
char i = 0;

for(i = 0; i<5; i++)
{
  bcdResult[i] = (unsigned char)(Bin % 10)
  Bin = Bin / 10;
}


Как-то так. Но можно и иначе.


--------------------
"Для того чтобы избежать критики, надо ничего не делать, ничего не говорить и никем не быть"
"Каждый из нас бывает дураком по крайней мере пять минут в день; мудрость заключается в том, чтобы не превысить лимит." Элберт Хаббард
Go to the top of the page
 
+Quote Post
evc
сообщение Dec 12 2012, 08:50
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 206
Регистрация: 17-03-07
Из: Москва
Пользователь №: 26 266



Цитата(volodya @ Dec 12 2012, 11:33) *
Если неизвестно который из сигналов приходит первый , но время необходимо измерить между двумя сигналами можно поступить следующим образом -
1 - установить прерывания на ожидание события.
2 - по свершившемуся событию (на любом из прерываний) проверить флаг (счетчик событий)
2.1 - если флаг сброшен (счетчик событий = 0) и запустить таймер.
2.2 - если флаг установлен (счетчик событий = 1) остановить таймер и получить время между событиями, установить признак готовности времени для основной программы.


А можно и еще проще - сделать два одинаковых обработчика прерываний INT0 и INT1.
Еще на входе делать поверку - работает ли Таймер1 или нет (бит 15 в регистре T1CON - "1" или "0"?).
Если работает, записать результат и остановить Таймер1. Если не работает, обнулить и запустить Таймер1.
Но это не отменяет необходимость обработчика прерываний от Таймера1.
Потому что, если Таймер1 переполнится, результат будет искажен.

Цитата(volodya @ Dec 12 2012, 11:33) *
else
{
if(pilse != countPulse)/*ожидать второго пульса*/
{
/*остановить таймер, зафиксировать резыльтат*/
countPulse = 0; /*сбросить флаг для следующего замера*/

Наверное опечатка. Должно быть "u".


--------------------
УЭР
Go to the top of the page
 
+Quote Post
volodya
сообщение Dec 12 2012, 12:06
Сообщение #5


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

Группа: Свой
Сообщений: 194
Регистрация: 14-02-07
Из: УКРАИНА
Пользователь №: 25 344



Цитата(evc @ Dec 12 2012, 10:50) *


Опечатку исправил - спасибо за подсказку.

Согласен - контроль переполнения таймера необходим (особенно если события разделяют большие промежутки времени) и в общем достоверность результата повысится.



--------------------
"Для того чтобы избежать критики, надо ничего не делать, ничего не говорить и никем не быть"
"Каждый из нас бывает дураком по крайней мере пять минут в день; мудрость заключается в том, чтобы не превысить лимит." Элберт Хаббард
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- yliya   вопросы по pic24   Nov 24 2012, 11:09
- - Ruslan1   0. К сожалению, ничего не прикрепилось. 1. С чем и...   Nov 24 2012, 21:05
- - yliya   Индикацию так реализовала: // Таблица изображения...   Nov 28 2012, 18:04
|- - volodya   Цитата(yliya @ Nov 28 2012, 20:04) Как из...   Nov 29 2012, 06:26
|- - evc   Юля, дополню volodya: Цитата(yliya @ Nov 28 ...   Nov 29 2012, 11:49
|- - volodya   Цитата(evc @ Nov 29 2012, 13:49) int data...   Nov 29 2012, 12:59
- - yliya   Спасибо большое!!!) Буду дальше продви...   Nov 29 2012, 18:05
|- - evc   Цитата(yliya @ Nov 29 2012, 22:05) Написа...   Nov 30 2012, 09:06
- - yliya   Я хочу научиться, а не просто "передрать и сд...   Dec 2 2012, 18:09
|- - evc   Цитата(yliya @ Dec 2 2012, 22:09) Я хочу ...   Dec 2 2012, 19:02
- - yliya   )))) Сделала так, чуть по другому. Мне надо знать ...   Dec 5 2012, 17:06
|- - volodya   Цитата(yliya @ Dec 5 2012, 19:06) Сделала...   Dec 6 2012, 06:34
|- - evc   В правильном направлении двигаетесь, Юля. Если я х...   Dec 6 2012, 08:11
|- - evc   Цитата(volodya @ Dec 12 2012, 16:06) Опеч...   Dec 12 2012, 13:01
- - yliya   .   Dec 11 2012, 17:44


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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 08:32
Рейтинг@Mail.ru


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