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

 
 
 
Reply to this topicStart new topic
Зураб
сообщение Aug 15 2010, 19:41
Сообщение #1





Группа: Участник
Сообщений: 10
Регистрация: 11-11-07
Пользователь №: 32 244



Снова здравствуйте!
Сразу по сути. Имеется ножка P1.0, сконфигурированная как вход и включен внутренний резистор pullup на ней. На эту ногу поступает сигнал с другого девайса, который выдает при включении лог.0. Необходимо произвести прерывание при перепаде на P1.0 из лог.1 в лог.0, при выполнении которого (для примера) выставляет на ноге P2.0 лог.1, при этом P2.0 сконфигурирован как выход со значением лог.0 при включении. Проблема в том, что при включении P2.0 выдаёт лог.1. Видимо сразу при включении срабатывает прерывание от порта P1. Как этого избежать? Может я что-то не так конфигурирую? Код ниже:
Код
void main(void){
  WDTCTL = WDTPW+WDTHOLD; //отключение watchdog
  P1DIR = 0xFE;
  P1OUT = 0x00;
  P1REN = 0x01;
  P2DIR = 0x03;                            
  P2OUT = 0x02;
  P2REN = 0x20;
  IE1 |= OFIE + WDTIE;  // разрешить прерывание от детектора ошибки резонатора
  IFG1 |= OFIFG;
  uart_init();
  P1IES = 0x01;
  P1IE = 0x01;
  P1IFG = 0;  
  __bis_SR_register(GIE);
  while(1){
  .................
}
}

#pragma vector=PORT1_VECTOR
__interrupt void DISCONNECTED(void)
{
  P1IFG=0;
  P2OUT|=BIT0;
}
Go to the top of the page
 
+Quote Post
_3m
сообщение Aug 16 2010, 06:58
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 745
Регистрация: 28-12-06
Пользователь №: 23 960



Цитата(Зураб @ Aug 15 2010, 23:41) *
Снова здравствуйте!
Сразу по сути. Имеется ножка P1.0, сконфигурированная как вход и включен внутренний резистор pullup на ней. На эту ногу поступает сигнал с другого девайса, который выдает при включении лог.0. Необходимо произвести прерывание при перепаде на P1.0 из лог.1 в лог.0, при выполнении которого (для примера) выставляет на ноге P2.0 лог.1, при этом P2.0 сконфигурирован как выход со значением лог.0 при включении. Проблема в том, что при включении P2.0 выдаёт лог.1. Видимо сразу при включении срабатывает прерывание от порта P1. Как этого избежать? Может я что-то не так конфигурирую? Код ниже:

Мне кажется так будет лучше:
Код
void main(void){
  WDTCTL = WDTPW+WDTHOLD; //отключение watchdog
  P1DIR = 0xFE;
  P1REN = 0x01;
  P1OUT = 0x01;
/*
If the pin’s pull up/down resistor is enabled, the corresponding bit in the
PxOUT register selects pull-up or pull-down.
Bit = 0: The pin is pulled down
Bit = 1: The pin is pulled up
*/
  P2DIR = 0x03;                            
  P2OUT = 0x02;
  P2REN = 0x20;
  IE1 |= OFIE + WDTIE;  // разрешить прерывание от детектора ошибки резонатора
  IFG1 |= OFIFG;
  uart_init();
  P1IES = 0x01;
  P1IE = 0x01;

  // делаем задержку для нарастания напряжения на p1
  for (unsigned char delay=255; delay!=0; delay--)
     __no_operation();
  // если после старта непрерывно ноль - инициируем прерывание  
  P1IFG = ~(P1IN & 0x01);
  __bis_SR_register(GIE);

  while(1){
  .................
}
}
Go to the top of the page
 
+Quote Post
Ko4egap
сообщение Aug 16 2010, 07:11
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 63
Регистрация: 17-09-09
Пользователь №: 52 434



Во первых, в прерывании непомешает проверить действительно ли на нужной ноге нужный уровень.
Во вторых, скорее всего вам нет смысла использовать здесь прерывания, я думаю достаточно банального опроса. Прерывание нужно чтобы вернуть из энергосберегающего режима, или когда нужна быстрая реакция.
Соглашусь с _3m, задержка здесь нужна

Сообщение отредактировал Ko4egap - Aug 16 2010, 07:12
Go to the top of the page
 
+Quote Post
Зураб
сообщение Aug 16 2010, 11:25
Сообщение #4





Группа: Участник
Сообщений: 10
Регистрация: 11-11-07
Пользователь №: 32 244



_3m, Ko4egap, спасибо за помощь! Я подумывал о задержке, попробую.
Цитата
скорее всего вам нет смысла использовать здесь прерывания, я думаю достаточно банального опроса

А как в этом случае организовать срабатывание по перепаду из лог.1 в лог.0? Можно, конечно, ввести дополнительную переменную, но не хочется.
Go to the top of the page
 
+Quote Post
Ko4egap
сообщение Aug 17 2010, 11:53
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 63
Регистрация: 17-09-09
Пользователь №: 52 434



Цитата(Зураб @ Aug 16 2010, 15:25) *
А как в этом случае организовать срабатывание по перепаду из лог.1 в лог.0? Можно, конечно, ввести дополнительную переменную, но не хочется.

Такие вещи делаются с помощью конечных автоматов (машина состояний). Выглядит примерно так:
Код
static int state = 0;

switch(state)
{
    case(0):
        if(state1_cond)
        {
            state=1;
            /* Kакие-либо действия, корторые необходимо выполнять при переходе
             * из нулевого состояния в первое
             */
        }
        break;
    case(1):
        if(state0_cond)
        {
            state=0;
        }
        break;
    default:
        /* Что-то пошло не так, надо сбросить всю машину */
        state=0;
        break;
}

И вообще нечего жалеть память. Чем меньше кода, тем меньше мест где могут появиться ошибки. Чем проще решение тем меньше вероятность ошибиться в его реализации, и меньше сил затрачивается на отладку и дальнейшее сопровождение, и стабильнее результирующий продукт.

Машины состояний вообще мощный инструмент, рекомендую ознакомиться c этим

Сообщение отредактировал Ko4egap - Aug 17 2010, 11:58
Go to the top of the page
 
+Quote Post

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

 


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


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