Программирование STM8

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Pjatruha@mail.ru
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 10, 2014 19:40:03

Re: Программирование STM8

Сообщение Pjatruha@mail.ru »

Спасибо за наводку.
Саму книгу скачать не удалось, но нашел где ее можно почитать. Правда для этого пришлось зарегистрироваться. Попутно нашел еще и лабораторный практикум того же автора.
Реклама
Pjatruha@mail.ru
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 10, 2014 19:40:03

Re: Программирование STM8

Сообщение Pjatruha@mail.ru »

Подскажите, пожалуйста, а как избавиться от дребезга контактов программно? Знаю, что можно задержку добавить после опроса кнопки, но это не лучшее решение, вроде. А как же тогда борются с этим явлением? В электронике для этого используют триггер. Наверное что-то подобное можно программно реализовать?
Реклама
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Программирование STM8

Сообщение Martian »

Задержка. Только не глобальная, которая останавливает всю программу, а задержка на реакцию следующего события кнопки. Реализации могут быть всякие, с таймерами и без, для работы по прерываниям или нет...
Pjatruha@mail.ru
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 10, 2014 19:40:03

Re: Программирование STM8

Сообщение Pjatruha@mail.ru »

Написал я вот такую програмку

Код: Выделить всё

#include "IOSTM8S103F3.h"
 
int main (void) 
{ 
    
   PD_DDR_bit.DDR3 = 0; // Активируем порт PD3 в качестве "входа"
   PD_CR1_bit.C13 = 0; //  переключаем порт в качестве Дифф. входа 
   PD_CR2_bit.C23 = 0; // Прерывания запрещены
   
   PB_DDR_bit.DDR5 = 1; // Настраиваем PB5 в качестве "вывода".
   PB_CR1_bit.C15 = 1; // Переключение порта в режим push-pull. 
   PB_CR2_bit.C25 = 1; // Скорость переключения до 2 МГц
   
   int n = 2;
  while(1)
  {
    if (PD_IDR_bit.IDR3!=1) // Проверка нажатия кнопки. Кнопка NO замыкает PD3 на землю. PD3 через резистор подтянут к плюсу.
    {
      for  (unsigned long i=0;  i<20000;  i++);
      if (PD_IDR_bit.IDR3!=1)
      {
        n++;
      }
    }
    switch(n)
    {
      case 1:
        PB_ODR_bit.ODR5 = 0; // Включение светодиода. 
        break;			
      case 2:
        PB_ODR_bit.ODR5 = 1; // Отключение светодиода.
        break;			
      default:
        n=1;
         }
  }
   
}
Задержка на нажатие кнопки в этой программе глобальная, правильно? А как будет выглядеть локальная задержка?
Не нравится мне как работает кнопка. Переключения не очень четкие. Оно конечно гораздо лучше чем без задержки, но все равно не то. Подскажите, в какую сторону копать?
Реклама
Эиком - электронные компоненты и радиодетали
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Программирование STM8

Сообщение Martian »

Код: Выделить всё

 
int main (void)
{
   i = 0;
   ....
  while(1)
  {
     if (i > 0) 
     {
        i--;
     }

     if (PD_IDR_bit.IDR3!=1) // Проверка нажатия кнопки. Кнопка NO замыкает PD3 на землю. PD3 через резистор подтянут к плюсу.
     {
       if (i == 0)
       { 
         i = 20000;
         n++;
       }
     }

   .....
  }// while
}
фактически, это тоже самое, только теперь i меняется в глобальном цикле, не препятствуя выполнению основной программы. При первом нажатии происходит обработка (n++;) и инициализируется счётчик (i = 20000;). И пока i не станет равным нулю, последующие состояния кнопки игнорируются. Минус такого решения: в зависимости от ветвления основной программы длительность игнорирования может сильно отличаться. Использование таймера позволит сделать более точное время антидребезга.

И ещё: кнопка может генерировать три события: KeyUp, KeyDown и Click. Вариант подобного кода их не различает, то есть, как только счетчик обнулится и кнопка при этом не отпустится, она снова обработается.
Последний раз редактировалось Martian Ср авг 30, 2023 02:53:28, всего редактировалось 1 раз.
Реклама
Pjatruha@mail.ru
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 10, 2014 19:40:03

Re: Программирование STM8

Сообщение Pjatruha@mail.ru »

[uquote="Martian",url="/forum/viewtopic.php?p=4470112#p4470112"]только теперь i меняется в глобальном цикле, не препятствуя выполнению основной программы.[/uquote]
Ах вот как это делается... А я всю голову себе сломал... Все оказывается лежит на поверхности. :)
[uquote="Martian",url="/forum/viewtopic.php?p=4470112#p4470112"]И ещё: кнопка может генерировать три события: KeyUp, KeyDown и Click.[/uquote]
Навереное KeyUp/KeyDown будет выглядеть вот так, с учетом ваших рекомендаций:

Код: Выделить всё

int main (void)
{
   i = 0;
   ....
  while(PD_IDR_bit.IDR3!=1) // KeyUp - 0, KeyDown - 1
  {
     if (i > 0)
     {
        i--;
     }   
       if (i == 0)
       {
         i = 20000;
         n++;
       }
     
   .....
  }// while
}
А Click будет выглядеть вот так:

Код: Выделить всё

int main (void)
{
   i = 0;
   ....
  while(1)
  {
     if (i > 0)
     {
        i--;
     }

     if (PD_IDR_bit.IDR3!=1) 
     {
       if (i == 0)
       {
         if (PD_IDR_bit.IDR3!=0)
          {
            i = 20000;
            n++;
          }
       }
     }

   .....
  }// while
}
Реклама
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Программирование STM8

Сообщение Martian »

во втором случае проверка на отжатие сработает в момент дребезга и сделает ложный клик. Отжатие в свою очередь тоже вызывает дребезг, поэтому надо немного больше заморочиться.
Pjatruha@mail.ru
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 10, 2014 19:40:03

Re: Программирование STM8

Сообщение Pjatruha@mail.ru »

[uquote="Martian",url="/forum/viewtopic.php?p=4470141#p4470141"]поэтому надо немного больше заморочиться.[/uquote]
Тогда Click будет выглядеть так:

Код: Выделить всё

int main (void)
{
   i = 0;
   j = 0;
     ....
  while(1)
  {
     if (i > 0)
     {
        i--;
     }
     if (PD_IDR_bit.IDR3!=1 & i == 0)
     {
       if (j == 0 )
       {
         j = 1;
       }
     }
     if (PD_IDR_bit.IDR3!=0 & j == 1)
       {
           if (i == 0)
            {
              i = 20000;
              j = 0;
              n++;
            }
       }
   .....
  }// while
}
Дополнение
Нет, не будет это работать. Надо еще подумать...

Все, придумал. Проверил. Четкие переключения без ложных срабатываний. Теперь мне нравится работа кнопки.

Код: Выделить всё

int n = 2, i=0, j=0;
  while(1)
  {
    if (i > 0)
     {
        i--;
     }

     if (PD_IDR_bit.IDR3!=1 & i == 0)
     {
       if (j == 0 )
       {
         j = 1;
         i = 2000;
       }
     }
     if (PD_IDR_bit.IDR3!=0 & j == 1)
       {
           if (i == 0)
            {
              i = 2000;
              j = 0;
              n++;
            }
       }
}
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Программирование STM8

Сообщение Martian »

Ну, надо просто нарисовать алгоритм, примерно так:
произошло событие кнопки, например, замыкание, которое мы отловили и теперь должны переждать дребезг.
пока идет дребезг, мы не реагируем ни на что.
дребезг закончился, смотрим состояние кнопки, если она всё ещё нажата - запускаем/инкрементируем счётчик, как долго нажата кнопка, если хотим отловить удержание, для, например, входа в меню, если не хотим - продолжаем игнорировать.
если не нажата - считаем, что кнопка была отпущена, надо снова переждать дребезг.
пока идет дребезг, мы не реагируем ни на что.

То есть, у нас видится как одинаковое что-то, так и разное что-то. Одинаковое - это пережидание дребезга, изменение состояния кнопки (неважно, на какое) и отсутствие реакции:

Код: Выделить всё

int main (void)
{
   drebezg_count = 0;
   button_status = 0; // 0 - не нажата, 1 - нажата
     ....
  while(1)
  {
     if (drebezg_count > 0)
     {
       drebezg_count--;  // пережидаем дребезг
     }
     else
     { 
// а здесь пишем обработку кнопок
        if ((PD_IDR_bit.IDR3 == button_status) // кнопка изменила состояние
        {
           drebezg_count = 20000;
           button_status != button_status; //меняем статус кнопки
          // здесь можно вызвать функцию обработки события кнопки или написать код
     }

// продолжение программы
  }
}
Я не проверял строго, писал прям здесь, но вот как-то так, попроще (чем проще - тем меньше риск ошибок). Мы теперь можем ловить изменение любого состояния кнопки, минуя оба дребезга и строить дальше уже логику исходя из какое именно изменение (по фронту или спаду) кнопки произошло
Последний раз редактировалось Martian Чт авг 31, 2023 19:56:59, всего редактировалось 1 раз.
Pjatruha@mail.ru
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 10, 2014 19:40:03

Re: Программирование STM8

Сообщение Pjatruha@mail.ru »

Суть вашей идеи я уловил, как мне кажется, но отдельные моменты мне остались не понятны.
[uquote="Martian",url="/forum/viewtopic.php?p=4470548#p4470548"]// а здесь пишем обработку кнопок[/uquote]
Поясните этот момент. Не понял, что за обработка.



А тут вы хотели сделать инверсию?
[uquote="Martian",url="/forum/viewtopic.php?p=4470548#p4470548"]button_status ^= button_status;[/uquote]
Если да, то 0^0=1, но и 1^1=1. Может вот так: button_status = !button_status ? Или так нельзя?
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Программирование STM8

Сообщение Martian »

Да, блин, ошибся, думал и об бите, и о буле ) спасибо за замечание.

Обработка кнопок - здесь это часть программы, которая опрашивает кнопки и что-то изменяет от действий кнопки, у Вас, например, n++
Pjatruha@mail.ru
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 10, 2014 19:40:03

Re: Программирование STM8

Сообщение Pjatruha@mail.ru »

Тогда что вы имели ввиду тут?
[uquote="Martian",url="/forum/viewtopic.php?p=4470548#p4470548"]// здесь можно вызвать функцию обработки события кнопки или написать код[/uquote]
Честно говоря, в этих двух строчках я и запутался. :)
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Программирование STM8

Сообщение Martian »

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

Код: Выделить всё

void KeyChange(unsigned char btn_status);
...

int main (void)
{
   drebezg_count = 0;
   button_status = 0; // 0 - не нажата, 1 - нажата
     ....
  while(1)
  {
     if (drebezg_count > 0)
     {
       drebezg_count--;  // пережидаем дребезг
     }
     else
     {
// а здесь пишем обработку кнопок
        if ((PD_IDR_bit.IDR3 == button_status) // кнопка изменила состояние
        {
           drebezg_count = 20000;
           button_status != button_status; //меняем статус кнопки
          KeyChange(button_status);
        }
     }

// продолжение программы
  }
}

void KeyChange(unsigned char btn_status)
{
   if (btn_status == 1) // проверка, что произошло событие отпускания кнопки
   {
      n++;
   }
}

Конечно, ради одного условия и инкремента нет смысла и сожрет больше ресурсов на вызов, если оптимизатор не соптимизирует, но зато удобно и минимизирует ошибки: если антидребезг и опрос портов отлажены, то там уже ничего не трогается, работаем только с KeyChange
Последний раз редактировалось Martian Чт авг 31, 2023 23:45:05, всего редактировалось 1 раз.
Pjatruha@mail.ru
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 10, 2014 19:40:03

Re: Программирование STM8

Сообщение Pjatruha@mail.ru »

[uquote="Martian",url="/forum/viewtopic.php?p=4470993#p4470993"]если антидребезг и опрос портов отлажены, то там уже ничего не трогается, работаем только с KeyChange[/uquote]
Сразу видно, что не один десяток программ написали :) Мыслите глобально с заделом на будущее. Я пока так не умею, но буду к этому стремиться.
Аватара пользователя
valentinovich
Электрический кот
Сообщения: 1003
Зарегистрирован: Ср окт 04, 2017 20:47:40

Re: Программирование STM8

Сообщение valentinovich »

Pjatruha@mail.ru писал(а):Я пока так не умею, но буду к этому стремиться.
Ничего, ничего, как говорят "лиха беда начало". :)
Стремиться к чему-то - это хорошо и нужно.
Но главное всё же во всём этом уловить, что основное есть выбор правильного алгоритма для решения задуманного вами процесса!
И только второе - это его та или иная (но желательно всё же оптимальная :roll: ) реализация на выбранном вами языке.
Удачи в освоении программирования. :beer:
Pjatruha@mail.ru
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 10, 2014 19:40:03

Re: Программирование STM8

Сообщение Pjatruha@mail.ru »

[uquote="valentinovich",url="/forum/viewtopic.php?p=4471080#p4471080"]Но главное всё же во всём этом уловить, что основное есть выбор правильного алгоритма для решения задуманного вами процесса![/uquote]
Да, полностью с вами согласен. Это я еще со школьной скамьи знаю. :lol:(давно это было...) Мы тогда паскаль изучали. Сам язык и не помню, но алгоритмы составлять нас научили(я так думаю :) ).

Добавлено after 9 hours 30 minutes 46 seconds:
Подскажите, пожалуйста, а как мне посчитать частоту моргания светодиода в этой программе:

Код: Выделить всё

#include "IOSTM8S103F3.h"

int main( void )
{
  int k=0;
   PB_DDR_bit.DDR5 = 1; //
   PB_CR1_bit.C15 = 1; //
   PB_CR2_bit.C25 = 1; //
   while(1)
  {
   if ( k > 0)
  {
    k++;
  }
  if (k == 0)
        {
     PB_ODR_bit.ODR5 = 0;
     k++;
        }
  if (k == 200)
  {
     PB_ODR_bit.ODR5 = 1;
  }
  if (k == 400)
  {
    k=0;
  }
  } 
}
Частота работы процессора по умолчанию 2МГц. Нужно 2000кГц/400? Что-то у меня другую частоту осциллограф показывает...
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Программирование STM8

Сообщение Martian »

Упростим до:

Код: Выделить всё

#include "IOSTM8S103F3.h"

int main( void )
{
   unsigned char k=0;
   PB_DDR_bit.DDR5 = 1; //
   PB_CR1_bit.C15 = 1; //
   PB_CR2_bit.C25 = 1; //
   while(1)
   {
     if (++k == 200)
     {
       PB_ODR_bit.ODR5 ^= 1; 
       k = 0;
     }
   }
}
теперь смотрим листинг ассемблера, как компилятор скомпилировал:

Изображение

Теперь надо сосчитать количество тактов процессора, которые потребуются для выполнения всех этих команд. И вот на это число и надо делить частоту работы процессора, а не на 400.

Наверное, пришло время изучить таймеры ;)
Pjatruha@mail.ru
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 10, 2014 19:40:03

Re: Программирование STM8

Сообщение Pjatruha@mail.ru »

[uquote="Martian",url="/forum/viewtopic.php?p=4471482#p4471482"]теперь смотрим листинг ассемблера, как компилятор скомпилировал:[/uquote]
Большое спасибо за пояснение.

[uquote="Martian",url="/forum/viewtopic.php?p=4471482#p4471482"]Наверное, пришло время изучить таймеры ;)[/uquote]
Опять вы зрите в корень. :lol:
Уже начал изучать. А параллельно и прерывания. Пару дней уже не могу понять вот это

Код: Выделить всё

Обработчики прерываний определяются следующим образом: 
#pragma vector=<номер прерывания> (табл. 3.1) 
__interrupt void <имя прерывания>, 
<номер прерывания> – номер прерывания в hex формате. Берется 
значение  из  технической  документации  микроконтроллера  и  к  нему 
прибавляется 2. 
<имя  прерывания> –  имя,  которое  будет  именем  подпрограммы 
обработчика прерывания (определяется пользователем). 
__interrupt void Это функция, которая будет исполнятся при наступлении условия прерывания(вектора прерывания)?
Как указать значение вектора прерывания? Точнее сказать, какое значение должно стоять, например, для TIM1 захват/сравнение? Не могу разобраться как значение из таблицы перевести в шестнадцатеричный формат.
Martian
Друг Кота
Сообщения: 12867
Зарегистрирован: Сб дек 18, 2021 19:25:32
Контактная информация:

Re: Программирование STM8

Сообщение Martian »

Полагаю, проще прочитать здесь: https://we.easyelectronics.ru/STM8/8l-k ... -exti.html
а то писать очень много :)

Добавлено after 1 minute 34 seconds:
И обязательно читать учебник, прилагающийся к каждой среде разработки, так как есть различия.
Pjatruha@mail.ru
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 10, 2014 19:40:03

Re: Программирование STM8

Сообщение Pjatruha@mail.ru »

Большое спасибо за статью. Мне очень понравилось. Написано простыми словами. Очень легко читать. Пожалуй прочитаю весь цикл статей этого автора по теме STM8. Но тут ответ на мой вопрос все же не полный. По сути можно не заморачиваться и пользоваться готовой таблицей из заголовочного файла IOSTM8S103F3.h(ведь не зря же он подключен :) ) , но мне все же хотелось бы разобраться до конца. Как получилась эта таблица в заголовочном файле?
Вот таблица из DataSheet
Изображение
Нужно брать номер вектора прерывания из первого столбца таблицы, прибавлять к нему 2, а затем переводить в шестнадцатеричный формат? Т.е. для TIM2 capture/compare это значение будет 14+2=16(dec)=10(hex),верно?
Ответить

Вернуться в «Разные вопросы по МК»