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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Подскажите начинающему, Keil
Djumper
сообщение Oct 9 2010, 18:09
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 9-10-10
Пользователь №: 60 027



Очень заинтересовался программированием микроконтроллеров.
Сейчас изучаю Keil и язык C.
Имеется железка на микроконтроллере ADuC842.
Начал с малого. Решил написать программу, которая просто заставляет загореться два светодиода из четырёх. Написал. Получилось, работает.
Сейчас решил написать программу, суть которой заключается в том, что надо нажать на кнопку и светодиод загорится, если ещё раз нажать на кнопку, то светодиод тухнет. Бился целый день, но не получается.

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

Подскажите, расскажите, объясните. Выслушаю всех, очень хочу научиться.
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 9 2010, 19:02
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Не нужно подавать на пин, к которому подключена кнопка лог."0", а нужно опрашивать состояние этого пина и включать светодиод, если состояние кнопки изменилось. Соответственно на пине к которому подключена кнопка нужен pull-up резистор, либо используйте внутренний pull-up (если он есть в этом МК).
Go to the top of the page
 
+Quote Post
Djumper
сообщение Oct 10 2010, 07:07
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 9-10-10
Пользователь №: 60 027



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

а можете пример привести. На счёт резистора не знаю, сейчас буду смотреть спецификацию.
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 10 2010, 08:01
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Периферию вашего контроллера я не знаю, а изучать ее специально нет особого желания. Примерно вот так
Код
#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 - Oct 10 2010, 08:16
Go to the top of the page
 
+Quote Post
Djumper
сообщение Oct 10 2010, 10:48
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 9-10-10
Пользователь №: 60 027



rezident спасибо, а что такое P3?
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 10 2010, 11:05
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Djumper @ Oct 10 2010, 16:48) *
rezident спасибо, а что такое P3?
Порт P3, к которому якобы подключены кнопка и светодиод. Я еще раз повторяю, что не знаю ни вашего МК, ни его периферии, ни обозначений его портов в Keil.
Go to the top of the page
 
+Quote Post
Djumper
сообщение Oct 10 2010, 11:12
Сообщение #7


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 9-10-10
Пользователь №: 60 027



Цитата(rezident @ Oct 10 2010, 18:05) *
Порт P3, к которому якобы подключены кнопка и светодиод. Я еще раз повторяю, что не знаю ни вашего МК, ни его периферии, ни обозначений его портов в Keil.

Кнопка и светодиод к разным портам подключены.
sbit P3_6=0xB6; - диод
sbit P1_2=0x92; - кнопка

Сообщение отредактировал Djumper - Oct 10 2010, 11:12
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 10 2010, 11:52
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Ну дык замените в дефайнах номера битов и далее по тексту чтение из порта 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)
Go to the top of the page
 
+Quote Post
Djumper
сообщение Oct 12 2010, 15:00
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 9-10-10
Пользователь №: 60 027



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

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)

Сообщение отредактировал Djumper - Oct 12 2010, 15:05
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 12 2010, 16:09
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Цитата(Djumper @ Oct 12 2010, 21:00) *
Но не работает. Может где-то ошибку допустил. Помогите исправить и объяснить.
Для того чтобы понять причину, представьте себя на месте исполнителя вашей программы и попытайтесь по шагам мысленно исполнить ее wink.gif
Для того, чтобы загорелся светодиод должны выполниться инструкция PIN_LED = 0x00;
Но для того чтобы выполнилась эта инструкция условие if (key == KEY_SET) должно быть истинным, т.е. в переменной key должно быть значение KEY_SET. А откуда там возьмется это значение, если ни вы и никто другой его туда не записал?
В сообщении #4 я привел практически готовую программу.
Go to the top of the page
 
+Quote Post
firstvald
сообщение Oct 12 2010, 16:35
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 580
Регистрация: 3-06-08
Пользователь №: 38 041



Вы фактически реализуете счетный триггер, но при этом на входе у вас при каждом нажатии целая серия импульсов. Обычно у кнопки переходный процесс длиться до 20 миллисекунд, когда ее контакт то замкнут то разомкнут. Да и после переходного процесса могут быть "шуршавчики" в замкнутом состоянии. Поэтому упростите свою задачу до безобразия для начала - нажали кнопку - загорелся светодиод. Отпустили - погас. Потом будем дальше усложнять.
Go to the top of the page
 
+Quote Post
Djumper
сообщение Oct 12 2010, 16:54
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 9-10-10
Пользователь №: 60 027



Цитата(firstvald @ Oct 12 2010, 23:35) *
Вы фактически реализуете счетный триггер, но при этом на входе у вас при каждом нажатии целая серия импульсов. Обычно у кнопки переходный процесс длиться до 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 - Oct 12 2010, 16:55
Go to the top of the page
 
+Quote Post
firstvald
сообщение Oct 12 2010, 17:18
Сообщение #13


Знающий
****

Группа: Свой
Сообщений: 580
Регистрация: 3-06-08
Пользователь №: 38 041



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

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

while(1){
if (P1&0x04 ==0 )//нажали
{P3=P3&(~0x08);}//зажгли
else
{P3=P3|0x08;}//погасили
}
}
Go to the top of the page
 
+Quote Post
Djumper
сообщение Oct 12 2010, 17:40
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 18
Регистрация: 9-10-10
Пользователь №: 60 027



Цитата(firstvald @ Oct 13 2010, 00:18) *
Давайте еще проще:

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;}
}
}
Не хочет работать программа. Железка проверенная, должна работать.
Go to the top of the page
 
+Quote Post
firstvald
сообщение Oct 12 2010, 17:51
Сообщение #15


Знающий
****

Группа: Свой
Сообщений: 580
Регистрация: 3-06-08
Пользователь №: 38 041



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

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

sfr P1 = 0x90; //проверьте есть ли такие строчки в начале программы или в подключаемом заголовочном файле
sfr P3 = 0xB0; //
void main (void)
{
P1=0xff;//иначе может оказаться случайным
P3=0xff;//

while(1){
P3=P3&(~0x08);//зажгли
}
}
Go to the top of the page
 
+Quote Post

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

 


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


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