Djumper 0 9 октября, 2010 Опубликовано 9 октября, 2010 · Жалоба Очень заинтересовался программированием микроконтроллеров. Сейчас изучаю Keil и язык C. Имеется железка на микроконтроллере ADuC842. Начал с малого. Решил написать программу, которая просто заставляет загореться два светодиода из четырёх. Написал. Получилось, работает. Сейчас решил написать программу, суть которой заключается в том, что надо нажать на кнопку и светодиод загорится, если ещё раз нажать на кнопку, то светодиод тухнет. Бился целый день, но не получается. Согласно схеме: на светодиод надо подать 0, чтобы он загорелся, на кнопку надо тоже подать 0, чтобы она сработала и заставила загореться светодиод. Порты прописывал следующим образом: sbit P1_1=0x11 (например светодиод) и P2_1=0x22 (например кнопка). Адреса портов 0x00 условные, т.е. по спецификации я знаю правильный адрес, это для примера привел. Подскажите, расскажите, объясните. Выслушаю всех, очень хочу научиться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 9 октября, 2010 Опубликовано 9 октября, 2010 · Жалоба Не нужно подавать на пин, к которому подключена кнопка лог."0", а нужно опрашивать состояние этого пина и включать светодиод, если состояние кнопки изменилось. Соответственно на пине к которому подключена кнопка нужен pull-up резистор, либо используйте внутренний pull-up (если он есть в этом МК). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Djumper 0 10 октября, 2010 Опубликовано 10 октября, 2010 · Жалоба Не нужно подавать на пин, к которому подключена кнопка лог."0", а нужно опрашивать состояние этого пина и включать светодиод, если состояние кнопки изменилось. Соответственно на пине к которому подключена кнопка нужен pull-up резистор, либо используйте внутренний pull-up (если он есть в этом МК). а можете пример привести. На счёт резистора не знаю, сейчас буду смотреть спецификацию. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 10 октября, 2010 Опубликовано 10 октября, 2010 (изменено) · Жалоба Периферию вашего контроллера я не знаю, а изучать ее специально нет особого желания. Примерно вот так #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; //обновим состояние кнопки Изменено 10 октября, 2010 пользователем rezident Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Djumper 0 10 октября, 2010 Опубликовано 10 октября, 2010 · Жалоба rezident спасибо, а что такое P3? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 10 октября, 2010 Опубликовано 10 октября, 2010 · Жалоба rezident спасибо, а что такое P3?Порт P3, к которому якобы подключены кнопка и светодиод. Я еще раз повторяю, что не знаю ни вашего МК, ни его периферии, ни обозначений его портов в Keil. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Djumper 0 10 октября, 2010 Опубликовано 10 октября, 2010 (изменено) · Жалоба Порт P3, к которому якобы подключены кнопка и светодиод. Я еще раз повторяю, что не знаю ни вашего МК, ни его периферии, ни обозначений его портов в Keil. Кнопка и светодиод к разным портам подключены. sbit P3_6=0xB6; - диод sbit P1_2=0x92; - кнопка Изменено 10 октября, 2010 пользователем Djumper Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 10 октября, 2010 Опубликовано 10 октября, 2010 · Жалоба Ну дык замените в дефайнах номера битов и далее по тексту чтение из порта 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) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Djumper 0 12 октября, 2010 Опубликовано 12 октября, 2010 (изменено) · Жалоба Дребезг и т.д. это слишком сложно для меня, на сколько я помню программа состоит из нескольких строк, жаль что я не записал её когда было время. По сути дела должно быть так??? 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) Изменено 12 октября, 2010 пользователем Djumper Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
rezident 0 12 октября, 2010 Опубликовано 12 октября, 2010 · Жалоба Но не работает. Может где-то ошибку допустил. Помогите исправить и объяснить.Для того чтобы понять причину, представьте себя на месте исполнителя вашей программы и попытайтесь по шагам мысленно исполнить ее ;) Для того, чтобы загорелся светодиод должны выполниться инструкция PIN_LED = 0x00; Но для того чтобы выполнилась эта инструкция условие if (key == KEY_SET) должно быть истинным, т.е. в переменной key должно быть значение KEY_SET. А откуда там возьмется это значение, если ни вы и никто другой его туда не записал? В сообщении #4 я привел практически готовую программу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
firstvald 24 12 октября, 2010 Опубликовано 12 октября, 2010 · Жалоба Вы фактически реализуете счетный триггер, но при этом на входе у вас при каждом нажатии целая серия импульсов. Обычно у кнопки переходный процесс длиться до 20 миллисекунд, когда ее контакт то замкнут то разомкнут. Да и после переходного процесса могут быть "шуршавчики" в замкнутом состоянии. Поэтому упростите свою задачу до безобразия для начала - нажали кнопку - загорелся светодиод. Отпустили - погас. Потом будем дальше усложнять. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Djumper 0 12 октября, 2010 Опубликовано 12 октября, 2010 (изменено) · Жалоба Вы фактически реализуете счетный триггер, но при этом на входе у вас при каждом нажатии целая серия импульсов. Обычно у кнопки переходный процесс длиться до 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; } } Изменено 12 октября, 2010 пользователем Djumper Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
firstvald 24 12 октября, 2010 Опубликовано 12 октября, 2010 · Жалоба Давайте еще проще: void main (void) { P1=0xff;//иначе может оказаться случайным P3=0xff;// while(1){ if (P1&0x04 ==0 )//нажали {P3=P3&(~0x08);}//зажгли else {P3=P3|0x08;}//погасили } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Djumper 0 12 октября, 2010 Опубликовано 12 октября, 2010 · Жалоба Давайте еще проще: 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;} } } Не хочет работать программа. Железка проверенная, должна работать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
firstvald 24 12 октября, 2010 Опубликовано 12 октября, 2010 · Жалоба Нет. Я специально написал безо всяких битовых операций - именно работаем с портом как с байтом, целиком. Вы уже на глупость переправили. Попробуем просто зажечь а потом просто погасить sfr P1 = 0x90; //проверьте есть ли такие строчки в начале программы или в подключаемом заголовочном файле sfr P3 = 0xB0; // void main (void) { P1=0xff;//иначе может оказаться случайным P3=0xff;// while(1){ P3=P3&(~0x08);//зажгли } } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться