Перейти к содержанию
    

Подскажите начинающему

Очень заинтересовался программированием микроконтроллеров.

Сейчас изучаю Keil и язык C.

Имеется железка на микроконтроллере ADuC842.

Начал с малого. Решил написать программу, которая просто заставляет загореться два светодиода из четырёх. Написал. Получилось, работает.

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

 

Согласно схеме: на светодиод надо подать 0, чтобы он загорелся, на кнопку надо тоже подать 0, чтобы она сработала и заставила загореться светодиод.

Порты прописывал следующим образом: sbit P1_1=0x11 (например светодиод) и P2_1=0x22 (например кнопка). Адреса портов 0x00 условные, т.е. по спецификации я знаю правильный адрес, это для примера привел.

 

Подскажите, расскажите, объясните. Выслушаю всех, очень хочу научиться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не нужно подавать на пин, к которому подключена кнопка лог."0", а нужно опрашивать состояние этого пина и включать светодиод, если состояние кнопки изменилось. Соответственно на пине к которому подключена кнопка нужен pull-up резистор, либо используйте внутренний pull-up (если он есть в этом МК).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не нужно подавать на пин, к которому подключена кнопка лог."0", а нужно опрашивать состояние этого пина и включать светодиод, если состояние кнопки изменилось. Соответственно на пине к которому подключена кнопка нужен pull-up резистор, либо используйте внутренний pull-up (если он есть в этом МК).

а можете пример привести. На счёт резистора не знаю, сейчас буду смотреть спецификацию.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

#define PIN_KEY     (1<<2) //кнопка подключена к P3.2 и к DGND, к P3.2 подключен pull-up резистор
#define PIN_LED     (1<<1) //светодиод катодом подключен к P3.1, анодом через балластный резистор к +DVDD

#define MAXCOMP     15U
#define MAXCNTR     1000U
#define KEY_NULL    0x00
#define KEY_SET     0x01

unsigned int cntr, comp;
unsigned char key;

void main (void)
{
/* тут секция для начальной инициализации периферии */

/* конец секции начальной инициализации периферии */
  P3 &=  PIN_LED^0xFF;
  key = KEY_NULL;
  for(;;)
  { if ((P3&PIN_KEY) == 0)    //засекли нажатие кнопки?
    { comp = 0;
      cntr = 0;
      do                      //устраняем дребезг
      { if ((P3&PIN_KEY) == 0)
          comp++;
        else
          comp = 0;
        if (comp >= MAXCOMP)  //состояние устойчивое?
        { key = KEY_SET;
          break;
        }
        cntr++;
      } while (cntr < MAXCNTR);
      if (cntr >= MAXCNTR)    //дребезг устранить не удалось?
        key = KEY_NULL;
    }
    if (key == KEY_SET)       //кнопка нажата?
      P3 &= PIN_LED^0xFF;     //включим LED
    else
      P3 |= PIN_LED;          //иначе выключим LED
  }
}

Времена устранения дребезга можно изменить значениями дефайнов.

Если нужен триггерный эффект, то замените простую проверку кода кнопки на смену ее состояния.

Добавим еще одну переменную

unsigned char lastkey = KEY_NULL;

Изменим способ проверки факта нажатия и переключение светодиода

if ( (key == KEY_SET) &&     //кнопка нажата? И
     (lastkey == KEY_NULL) ) // до этого она была не нажата?
  P3 ^= PIN_LED;             //переключим состояние LED
lastkey = key;               //обновим состояние кнопки

Изменено пользователем rezident

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

rezident спасибо, а что такое P3?
Порт P3, к которому якобы подключены кнопка и светодиод. Я еще раз повторяю, что не знаю ни вашего МК, ни его периферии, ни обозначений его портов в Keil.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Порт P3, к которому якобы подключены кнопка и светодиод. Я еще раз повторяю, что не знаю ни вашего МК, ни его периферии, ни обозначений его портов в Keil.

Кнопка и светодиод к разным портам подключены.

sbit P3_6=0xB6; - диод

sbit P1_2=0x92; - кнопка

Изменено пользователем Djumper

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну дык замените в дефайнах номера битов и далее по тексту чтение из порта P3 на чтение из порта P1.

#define PIN_KEY     (1<<2) //кнопка подключена к P1.2 и к DGND, к P1.2 подключен pull-up резистор
#define PIN_LED     (1<<6) //светодиод катодом подключен к P3.6, анодом через балластный резистор к +DVDD

if ((P1&PIN_KEY) == 0)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Дребезг и т.д. это слишком сложно для меня, на сколько я помню программа состоит из нескольких строк, жаль что я не записал её когда было время.

По сути дела должно быть так???

 

sbit PIN_LED = 0xB6;

sbit PIN_KEY = 0x92;

 

#define KEY_NULL 0x00

#define KEY_SET 0x01

 

unsigned int key;

 

void main (void)

{

 

for(;;)

{

 

if (key == KEY_SET)

PIN_LED = 0x00;

else

PIN_LED = 0x01;

}

}

 

Но не работает. Может где-то ошибку допустил. Помогите исправить и объяснить.

Кнопка S2 (P1.2; 0x92), светодиод любой из четырёх (P3.4, Р3.5, Р3.6, Р3.7; 0xB4, 0xB5, 0xB6, 0xB7)

post-60027-1286895644_thumb.png

Изменено пользователем Djumper

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но не работает. Может где-то ошибку допустил. Помогите исправить и объяснить.
Для того чтобы понять причину, представьте себя на месте исполнителя вашей программы и попытайтесь по шагам мысленно исполнить ее ;)

Для того, чтобы загорелся светодиод должны выполниться инструкция PIN_LED = 0x00;

Но для того чтобы выполнилась эта инструкция условие if (key == KEY_SET) должно быть истинным, т.е. в переменной key должно быть значение KEY_SET. А откуда там возьмется это значение, если ни вы и никто другой его туда не записал?

В сообщении #4 я привел практически готовую программу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы фактически реализуете счетный триггер, но при этом на входе у вас при каждом нажатии целая серия импульсов. Обычно у кнопки переходный процесс длиться до 20 миллисекунд, когда ее контакт то замкнут то разомкнут. Да и после переходного процесса могут быть "шуршавчики" в замкнутом состоянии. Поэтому упростите свою задачу до безобразия для начала - нажали кнопку - загорелся светодиод. Отпустили - погас. Потом будем дальше усложнять.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы фактически реализуете счетный триггер, но при этом на входе у вас при каждом нажатии целая серия импульсов. Обычно у кнопки переходный процесс длиться до 20 миллисекунд, когда ее контакт то замкнут то разомкнут. Да и после переходного процесса могут быть "шуршавчики" в замкнутом состоянии. Поэтому упростите свою задачу до безобразия для начала - нажали кнопку - загорелся светодиод. Отпустили - погас. Потом будем дальше усложнять.

Например так?

 

sbit PIN_LED = 0xB6;

sbit PIN_KEY = 0x92;

 

unsigned int KEY_NULL1=0;

unsigned int PIN_LED1=0;

unsigned int PIN_LED2=1;

 

void main (void)

{

 

for(;;)

{

 

if (PIN_KEY == KEY_NULL1)

PIN_LED = PIN_LED1;

else

PIN_LED = PIN_LED2;

}

}

Изменено пользователем Djumper

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Давайте еще проще:

 

void main (void)

{

P1=0xff;//иначе может оказаться случайным

P3=0xff;//

 

while(1){

if (P1&0x04 ==0 )//нажали

{P3=P3&(~0x08);}//зажгли

else

{P3=P3|0x08;}//погасили

}

}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Давайте еще проще:

 

void main (void)

{

P1=0xff;//иначе может оказаться случайным

P3=0xff;//

 

while(1){

if (P1&0x04 ==0 )//нажали

{P3=P3&(~0x08);}//зажгли

else

{P3=P3|0x08;}//погасили

}

}

P1_2=0x92;

P3_6=0xB6;

 

void main (void)

{

 

while(1){

if (P1_2&0x04 ==0 )

{P3_6=P3_6&(~0x08);}

else

{P3_6=P3_6|0x08;}

}

}

Не хочет работать программа. Железка проверенная, должна работать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет. Я специально написал безо всяких битовых операций - именно работаем с портом как с байтом, целиком. Вы уже на глупость переправили.

 

Попробуем просто зажечь а потом просто погасить

 

sfr P1 = 0x90; //проверьте есть ли такие строчки в начале программы или в подключаемом заголовочном файле

sfr P3 = 0xB0; //

void main (void)

{

P1=0xff;//иначе может оказаться случайным

P3=0xff;//

 

while(1){

P3=P3&(~0x08);//зажгли

}

}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...