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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Не работает прибавление 1 к переменной при нажатии на кнопку
loghir
сообщение May 9 2011, 06:05
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 63
Регистрация: 13-03-11
Пользователь №: 63 577



Доброго времени суток!
Всех с Днем Победы! Желаю чтобы агрессивные политики воевали только в парламентах по мордам друг друга!

биты конфигурации задаю вручную, RA0 сидит на +5В через резистор 4к7, кнопка на "массу", МК - pic16f72.
Срабатывание кнопки гарантировано доходит до RA0 (мерял на выводе). При "ручной" записи в порт через переменную индикация работает нормально.

Код
#include <pic.h>

#define knopka_start RA0
#define all_1 RC4
unsigned char time1 = 0;

void podgot (void)
{
ADCON1 = 0x07;
TRISA = 0b111111;
TRISB = 0b00000000;
TRISC = 0b00000000;
RBPU = 0;
PORTA = 0;
PORTB = 0b11111111;
PORTC = 0b11111111;
}

const unsigned char arr_seg [10] =
{
/* начало массива
0bABCDEFGH <– расположение сегментов по битам */
0b00000011, // «0» !
0b10011111, // «1» !
0b00100101, // «2» !
0b00001101, // «3» !
0b10011001, // «4» !
0b01001001, // «5» !
0b01000001, // «6» !
0b00011111, // «7» !
0b00000001, // «8» !
0b11110111, // «9» !
};

void main (void)
{
podgot();
all_1 = 0;
PORTB = arr_seg [time1];
if (knopka_start == 0);
{
time1 = time1 + 1;
}
}


Сообщение отредактировал loghir - May 9 2011, 06:05
Go to the top of the page
 
+Quote Post
V_G
сообщение May 9 2011, 07:21
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



А вы когда-нибудь программы для микроконтроллеров-то писали?
Где бесконечный цикл (у вас - ожидания нажатия кнопки)?
Где антидребезг?
Где отработка нажатия и отжатия кнопки?

Ваша программа запускается, 1 раз опрашивает порт, после чего уходит в никуда. Если за те микросекунды, что пройдут до первого (и единственного) опроса порта, вы не успеете нажать кнопку, то переменная time не проинкрементируется

Сообщение отредактировал V_G - May 9 2011, 07:22
Go to the top of the page
 
+Quote Post
loghir
сообщение May 9 2011, 09:55
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 63
Регистрация: 13-03-11
Пользователь №: 63 577



Цитата
Где бесконечный цикл (у вас - ожидания нажатия кнопки)?

Спасибо, добавил while(1)
Цитата
Где антидребезг?

не все сразу - дребезг экспериментам не помеха.
Цитата
Где отработка нажатия и отжатия кнопки?

отработку нажатия попытался реализовать так:
Код
if (knopka_start == 0);

а отжатие зачем как-то отрабатывать?

Код
void main (void)
{
podgot();
while(1)
{
time1 = 1;
all_1 = 0;
PORTB = arr_seg [time1];
if (knopka_start = 0);
{
time1 = time1 + 1;
}
}
}
Go to the top of the page
 
+Quote Post
xemul
сообщение May 9 2011, 12:18
Сообщение #4



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(loghir @ May 9 2011, 13:55) *
не все сразу - дребезг экспериментам не помеха.

Если не помешает правильно интерпретировать результаты экспериментов.
Цитата
отработку нажатия попытался реализовать так:
Код
if (knopka_start == 0)

Вам нужно распознать не состояние кнопки, а изменение состояния. Вероятно, нужно сравнивать текущее состояние кнопки с предыдущим. А отсюда и до анти-дребезга совсем рядом.
Цитата
а отжатие зачем как-то отрабатывать?

Дык разные бывают задачи. Иногда интересует момент нажатия, иногда наоборот, иногда оба.
Цитата
Код
...
PORTB = arr_seg [time1]; // и что получится при time1 >= 10 ?
if (knopka_start = 0); // '=' - оператор присваивания, '==' - оператор сравнения, ';' после ')' ну очень лишний
// результат '(knopka_start = 0)' - всегда false, а '(knopka_start = 123)' - всегда true.
...
Go to the top of the page
 
+Quote Post
V_G
сообщение May 9 2011, 12:19
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Отжатие совместно с антидребезгом надо отрабатывать для того, чтобы отработать последующие нажатия. В вашем варианте переменная проинкрементируется насколько тысяч (а не один) раз, пока будет нажата кнопка.
И как вы узнаёте состояние time1, у вас отладчик?
Go to the top of the page
 
+Quote Post
loghir
сообщение May 9 2011, 14:08
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 63
Регистрация: 13-03-11
Пользователь №: 63 577



Цитата
Если не помешает правильно интерпретировать результаты экспериментов.

Если будет не "0" - значит, реакция на кнопку есть.
Цитата
Вам нужно распознать не состояние кнопки, а изменение состояния. Вероятно, нужно сравнивать текущее состояние кнопки с предыдущим.

А как? Так?
Код
if (!knopka_start)

забавно: если убираю ";" после if, на индикаторе нет даже "1".
Цитата
Иногда интересует момент нажатия, иногда наоборот, иногда оба.

да мне бай Боже добиться, чтобы МК реагировал на нажатие.
Цитата
И как вы узнаёте состояние time1, у вас отладчик?

у меня к порту В подключен семисегментный индикатор.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение May 9 2011, 14:25
Сообщение #7


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(loghir @ May 9 2011, 18:08) *
забавно: если убираю ";" после if, на индикаторе нет даже "1".


Вся ваша программа - полное отсутствие понимания, чего вы хотите и что вы делаете. Может профессию поменять, пока не поздно?
Go to the top of the page
 
+Quote Post
loghir
сообщение May 9 2011, 15:10
Сообщение #8


Участник
*

Группа: Участник
Сообщений: 63
Регистрация: 13-03-11
Пользователь №: 63 577



Цитата
Вся ваша программа - полное отсутствие понимания, чего вы хотите и что вы делаете. Может профессию поменять, пока не поздно?

Чтобы абстрактно критиковать и отсылать в даташиты, достаточно найти на форуме вопрос. Для этого действительно ненадо много понимания.
Go to the top of the page
 
+Quote Post
xemul
сообщение May 9 2011, 15:30
Сообщение #9



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(loghir @ May 9 2011, 18:08) *
Если будет не "0" - значит, реакция на кнопку есть.

Я думал, Вам нужен осмысленный результат, а не генератор случайных чисел.
Цитата
А как? Так?
Код
if (!knopka_start)

Не помню, поддерживает ли писс8.05 тип bit, но как-то так:
Код
bit knopka_prev; // переменная для запоминания состояния кнопки
// переменная, объявленная здесь, является глобальной
// поэтому здесь "unsigned char time1 = 0;" == "unsigned char time1;"

void main(void)
{
...
   time1 = 1;
   PORTB = arr_seg [time1];
   knopka_prev = knopka_start; // присваиваем текущее значение

   for(;;) // или while(1), если оно Вам симпатичнее
   {
      if(knopka_prev != knopka_start) // если сохранённое состояние кнопки отличается от текущего
      {
         knopka_prev ^= 1; // изменим сохранённое состояние (так будет короче и корректнее, чем knopka_prev = knopka_start;)
         if(!knopka_prev) // в Вашей схеме 0 == кнопка нажата; при таком условии будет отрабатываться нажатие
//         if(knopka_prev) // а при таком - отпускание
         {
            time1++;
            PORTB = arr_seg [time1];  // ГСЧ готов
         }
      }
   }
}

Цитата
забавно: если убираю ";" после if, на индикаторе нет даже "1".

';' в С - не просто закорючка. Сомневаюсь, что у кого-нить здесь хватит здоровья пересказывать Вам букварь по С.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение May 9 2011, 16:02
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(loghir @ May 9 2011, 19:10) *
Чтобы абстрактно критиковать и отсылать в даташиты, достаточно найти на форуме вопрос. Для этого действительно ненадо много понимания.


Я вас куда подальше (в даташиты) не посылал. Хотите конкретную критику, пожалуйста. Парочку, на вскидку.
Индекс массива в С начинается с 0. Посему начальное значение time1 = 0;

Чтобы из массива arr_seg по индексу читать что-то осмысленное, надо проверять, не вышел ли индекс за границы массива. Например:

Код
        {
            time1++;
            if (time >= sizeof(arr_seg)/sizeof(arr_seg[0]))
                time1 = 0;
            PORTB = arr_seg [time1];  // ГСЧ готов
         }
Go to the top of the page
 
+Quote Post
loghir
сообщение May 9 2011, 16:45
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 63
Регистрация: 13-03-11
Пользователь №: 63 577



Цитата
';' в С - не просто закорючка. Сомневаюсь, что у кого-нить здесь хватит здоровья пересказывать Вам букварь по С.

Спасибо, чего-чего, а "букварей" у меня хватает:
Цитата
Пустой оператор это специальный случай, состоящий только из точки с запятой (wink.gif. Пустой оператор ничего не делает, однако полезен в ситуациях, когда синтаксис mikroC требует наличия оператора, а программе в этом месте ничего делать не требуется. Например, пустой оператор обычно используется в ”холостых” циклах:

Цитата
Не помню, поддерживает ли писс8.05 тип bit

по мануалу, вроде да. Но я нарывался на несоответствующий версии проги мануал.
Цитата
HI-TECH PICCsupports bit integral types which can hold the values 0 or 1. Single bit variables
may be declared using the keyword bit. bit objects declared within a function, for example:
static bit init_flag;
will be allocated in the bit-addressable psect rbit, and will be visible only in that function. When
the following declaration is used outside any function:
bit init_flag;
init_flag will be globally visible, but located within the same psect.

Попробовал - компилятор не подавился кодом
Код
bit knopka_prev;

Спасибо, буду пробовать остальное.
Цитата
Чтобы из массива arr_seg по индексу читать что-то осмысленное, надо проверять, не вышел ли индекс за границы массива.

Да мне бы заставить МК реагировать на нажатие кнопки! (о чем в названии топика и говорилось)
А в пределах массива удержать просто:
Код
if (time1 > 9)
{
time1 = 0;
time2 = time2++;
}

ну и так далее на все 4 разряда.

Сообщение отредактировал loghir - May 9 2011, 16:53
Go to the top of the page
 
+Quote Post
sergeeff
сообщение May 9 2011, 17:05
Сообщение #12


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(loghir @ May 9 2011, 20:45) *
Спасибо, чего-чего, а "букварей" у меня хватает:


по мануалу, вроде да. Но я нарывался на несоответствующий версии проги мануал.

Попробовал - компилятор не подавился кодом
Код
bit knopka_prev;

Спасибо, буду пробовать остальное.

Да мне бы заставить МК реагировать на нажатие кнопки! (о чем в названии топика и говорилось)
А в пределах массива удержать просто:
Код
if (time1 > 9)
{
time1 = 0;
time2 = time2++;
}

ну и так далее на все 4 разряда.


Простой вопрос. Вы уверены, что можете заставить свой процессор прочитать значение на входе пина?

При ненажатой кнопке вы читаете "1", а при нажатой "0"? Вы можете адекватно это зафиксировать?
Go to the top of the page
 
+Quote Post
xemul
сообщение May 9 2011, 19:09
Сообщение #13



*****

Группа: Свой
Сообщений: 1 928
Регистрация: 11-07-06
Пользователь №: 18 731



Цитата(loghir @ May 9 2011, 20:45) *
Спасибо, чего-чего, а "букварей" у меня хватает:

Тогда угадайте, в чём разница между
Код
if();
{};
// и
if()
{};

Цитата
Код
time2 = time2++;

Компилятор это, конечно, поправит, но смотрится некошерно.

В (мелких) пиках в силу архитектурных особенностей комбинация
Код
const unsigned char arr_seg [10] ...
// и
foo = arr_seg [x3];

при выходе индекса массива за ... приводит к гораздо более чудесатым результатам.
Go to the top of the page
 
+Quote Post
V_G
сообщение May 9 2011, 23:19
Сообщение #14


Профессионал
*****

Группа: Свой
Сообщений: 1 818
Регистрация: 15-10-09
Из: Владивосток
Пользователь №: 52 955



Цитата(xemul @ May 10 2011, 06:09) *
Тогда угадайте, в чём разница между
Код
if();
{};
// и
if()
{};


Присоединяюсь к вопросу к ТС. Лучше самому догадаться, хотя бы с помощью букварей, чем мы вам тут все разжуем и в рот положим, а вы и не поймете, что съели, и съели ли.
Go to the top of the page
 
+Quote Post
loghir
сообщение May 10 2011, 13:23
Сообщение #15


Участник
*

Группа: Участник
Сообщений: 63
Регистрация: 13-03-11
Пользователь №: 63 577



Тут не гадать, а пробовать надо: в другом "букваре" нашел другое толкование для ";":
Цитата
Точка с запятой ";" - это ограничитель оператора. Любое допустимое в Си выражение (включая пустое) завершенное точкой с запятой интепретируется как оператор, называемый еще оператором выражения. Выражение вычисляется и его значение пропадает. Если выражение не имеет побочных эффектов, mikroC может игнорировать его.

Ничего нового: зачем-то пишут книги с ошибками (или, в лучшем случае, с недосказанностями), народ за них платит
неслабые деньги, и, эквигенитально, ничего не работает в программе.
if(); - в примерах кода ";" после "if()" не встречается.
А про
Код
if()
{};

прямо написано, что так писать код нельзя.

Теперь о практике:
Код
time2 = time2++;

Ну, я на знание кашрута не претендую. Рано! Обычно пишу
Код
time2 = time2 + 1;

мне так понятнее.

И строку
Код
knopka_prev ^= 1; // изменим сохранённое состояние
               // (так будет короче и корректнее, чем knopka_prev = knopka_start;)

мне понятнее написать как
Код
knopka_prev = knopka_prev ^ 1; // если knopka_prev = 1, возвращает 0; если knopka_prev = 0, возвращает 1.


Сообщение отредактировал loghir - May 10 2011, 13:24
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 Текстовая версия Сейчас: 21st July 2025 - 12:30
Рейтинг@Mail.ru


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