Программирование STM8
-
Pjatruha@mail.ru
- Грызет канифоль
- Сообщения: 259
- Зарегистрирован: Пн фев 10, 2014 19:40:03
Re: Программирование STM8
Спасибо за наводку.
Саму книгу скачать не удалось, но нашел где ее можно почитать. Правда для этого пришлось зарегистрироваться. Попутно нашел еще и лабораторный практикум того же автора.
Саму книгу скачать не удалось, но нашел где ее можно почитать. Правда для этого пришлось зарегистрироваться. Попутно нашел еще и лабораторный практикум того же автора.
- Реклама
-
Pjatruha@mail.ru
- Грызет канифоль
- Сообщения: 259
- Зарегистрирован: Пн фев 10, 2014 19:40:03
Re: Программирование STM8
Подскажите, пожалуйста, а как избавиться от дребезга контактов программно? Знаю, что можно задержку добавить после опроса кнопки, но это не лучшее решение, вроде. А как же тогда борются с этим явлением? В электронике для этого используют триггер. Наверное что-то подобное можно программно реализовать?
Re: Программирование STM8
Задержка. Только не глобальная, которая останавливает всю программу, а задержка на реакцию следующего события кнопки. Реализации могут быть всякие, с таймерами и без, для работы по прерываниям или нет...
-
Pjatruha@mail.ru
- Грызет канифоль
- Сообщения: 259
- Зарегистрирован: Пн фев 10, 2014 19:40:03
Re: Программирование STM8
Написал я вот такую програмку
Задержка на нажатие кнопки в этой программе глобальная, правильно? А как будет выглядеть локальная задержка?
Не нравится мне как работает кнопка. Переключения не очень четкие. Оно конечно гораздо лучше чем без задержки, но все равно не то. Подскажите, в какую сторону копать?
Код: Выделить всё
#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;
}
}
}
Не нравится мне как работает кнопка. Переключения не очень четкие. Оно конечно гораздо лучше чем без задержки, но все равно не то. Подскажите, в какую сторону копать?
Re: Программирование STM8
Код: Выделить всё
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
}И ещё: кнопка может генерировать три события: KeyUp, KeyDown и Click. Вариант подобного кода их не различает, то есть, как только счетчик обнулится и кнопка при этом не отпустится, она снова обработается.
Последний раз редактировалось Martian Ср авг 30, 2023 02:53:28, всего редактировалось 1 раз.
- Реклама
-
Pjatruha@mail.ru
- Грызет канифоль
- Сообщения: 259
- Зарегистрирован: Пн фев 10, 2014 19:40:03
Re: Программирование STM8
[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 будет выглядеть вот так, с учетом ваших рекомендаций:
А Click будет выглядеть вот так:
Ах вот как это делается... А я всю голову себе сломал... Все оказывается лежит на поверхности.
[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
}
Код: Выделить всё
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
}
Re: Программирование STM8
во втором случае проверка на отжатие сработает в момент дребезга и сделает ложный клик. Отжатие в свою очередь тоже вызывает дребезг, поэтому надо немного больше заморочиться.
-
Pjatruha@mail.ru
- Грызет канифоль
- Сообщения: 259
- Зарегистрирован: Пн фев 10, 2014 19:40:03
Re: Программирование STM8
[uquote="Martian",url="/forum/viewtopic.php?p=4470141#p4470141"]поэтому надо немного больше заморочиться.[/uquote]
Тогда Click будет выглядеть так:
Дополнение
Нет, не будет это работать. Надо еще подумать...
Все, придумал. Проверил. Четкие переключения без ложных срабатываний. Теперь мне нравится работа кнопки.
Тогда 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++;
}
}
}
Re: Программирование STM8
Ну, надо просто нарисовать алгоритм, примерно так:
произошло событие кнопки, например, замыкание, которое мы отловили и теперь должны переждать дребезг.
пока идет дребезг, мы не реагируем ни на что.
дребезг закончился, смотрим состояние кнопки, если она всё ещё нажата - запускаем/инкрементируем счётчик, как долго нажата кнопка, если хотим отловить удержание, для, например, входа в меню, если не хотим - продолжаем игнорировать.
если не нажата - считаем, что кнопка была отпущена, надо снова переждать дребезг.
пока идет дребезг, мы не реагируем ни на что.
То есть, у нас видится как одинаковое что-то, так и разное что-то. Одинаковое - это пережидание дребезга, изменение состояния кнопки (неважно, на какое) и отсутствие реакции:
Я не проверял строго, писал прям здесь, но вот как-то так, попроще (чем проще - тем меньше риск ошибок). Мы теперь можем ловить изменение любого состояния кнопки, минуя оба дребезга и строить дальше уже логику исходя из какое именно изменение (по фронту или спаду) кнопки произошло
произошло событие кнопки, например, замыкание, которое мы отловили и теперь должны переждать дребезг.
пока идет дребезг, мы не реагируем ни на что.
дребезг закончился, смотрим состояние кнопки, если она всё ещё нажата - запускаем/инкрементируем счётчик, как долго нажата кнопка, если хотим отловить удержание, для, например, входа в меню, если не хотим - продолжаем игнорировать.
если не нажата - считаем, что кнопка была отпущена, надо снова переждать дребезг.
пока идет дребезг, мы не реагируем ни на что.
То есть, у нас видится как одинаковое что-то, так и разное что-то. Одинаковое - это пережидание дребезга, изменение состояния кнопки (неважно, на какое) и отсутствие реакции:
Код: Выделить всё
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
Суть вашей идеи я уловил, как мне кажется, но отдельные моменты мне остались не понятны.
[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 ? Или так нельзя?
[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 ? Или так нельзя?
Re: Программирование STM8
Да, блин, ошибся, думал и об бите, и о буле ) спасибо за замечание.
Обработка кнопок - здесь это часть программы, которая опрашивает кнопки и что-то изменяет от действий кнопки, у Вас, например, n++
Обработка кнопок - здесь это часть программы, которая опрашивает кнопки и что-то изменяет от действий кнопки, у Вас, например, n++
-
Pjatruha@mail.ru
- Грызет канифоль
- Сообщения: 259
- Зарегистрирован: Пн фев 10, 2014 19:40:03
Re: Программирование STM8
Тогда что вы имели ввиду тут?
[uquote="Martian",url="/forum/viewtopic.php?p=4470548#p4470548"]// здесь можно вызвать функцию обработки события кнопки или написать код[/uquote]
Честно говоря, в этих двух строчках я и запутался.
[uquote="Martian",url="/forum/viewtopic.php?p=4470548#p4470548"]// здесь можно вызвать функцию обработки события кнопки или написать код[/uquote]
Честно говоря, в этих двух строчках я и запутался.
Re: Программирование STM8
Просто я как-то неверно выразил мысль.
Она была как-то так - обработка кнопок - это то, что касается опроса состояния портов, где подключены кнопки и то, что меняет что-то в программе в зависимости от результата опроса портов. Вызов функции обработки события кнопки - это как раз последняя часть, то самое инкрементирование n++. Просто работа с кнопками может быть гораздо большей, чем просто инкрементирование, раздувать главный цикл неудобно, поэтому, я бы написал так:
Конечно, ради одного условия и инкремента нет смысла и сожрет больше ресурсов на вызов, если оптимизатор не соптимизирует, но зато удобно и минимизирует ошибки: если антидребезг и опрос портов отлажены, то там уже ничего не трогается, работаем только с KeyChange
Она была как-то так - обработка кнопок - это то, что касается опроса состояния портов, где подключены кнопки и то, что меняет что-то в программе в зависимости от результата опроса портов. Вызов функции обработки события кнопки - это как раз последняя часть, то самое инкрементирование 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
[uquote="Martian",url="/forum/viewtopic.php?p=4470993#p4470993"]если антидребезг и опрос портов отлажены, то там уже ничего не трогается, работаем только с KeyChange[/uquote]
Сразу видно, что не один десяток программ написали
Мыслите глобально с заделом на будущее. Я пока так не умею, но буду к этому стремиться.
Сразу видно, что не один десяток программ написали
- valentinovich
- Электрический кот
- Сообщения: 1003
- Зарегистрирован: Ср окт 04, 2017 20:47:40
Re: Программирование STM8
Ничего, ничего, как говорят "лиха беда начало".Pjatruha@mail.ru писал(а):Я пока так не умею, но буду к этому стремиться.
Стремиться к чему-то - это хорошо и нужно.
Но главное всё же во всём этом уловить, что основное есть выбор правильного алгоритма для решения задуманного вами процесса!
И только второе - это его та или иная (но желательно всё же оптимальная
Удачи в освоении программирования.
-
Pjatruha@mail.ru
- Грызет канифоль
- Сообщения: 259
- Зарегистрирован: Пн фев 10, 2014 19:40:03
Re: Программирование STM8
[uquote="valentinovich",url="/forum/viewtopic.php?p=4471080#p4471080"]Но главное всё же во всём этом уловить, что основное есть выбор правильного алгоритма для решения задуманного вами процесса![/uquote]
Да, полностью с вами согласен. Это я еще со школьной скамьи знаю.
(давно это было...) Мы тогда паскаль изучали. Сам язык и не помню, но алгоритмы составлять нас научили(я так думаю
).
Добавлено after 9 hours 30 minutes 46 seconds:
Подскажите, пожалуйста, а как мне посчитать частоту моргания светодиода в этой программе:
Частота работы процессора по умолчанию 2МГц. Нужно 2000кГц/400? Что-то у меня другую частоту осциллограф показывает...
Да, полностью с вами согласен. Это я еще со школьной скамьи знаю.
Добавлено 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;
}
}
}
Re: Программирование STM8
Упростим до:
теперь смотрим листинг ассемблера, как компилятор скомпилировал:

Теперь надо сосчитать количество тактов процессора, которые потребуются для выполнения всех этих команд. И вот на это число и надо делить частоту работы процессора, а не на 400.
Наверное, пришло время изучить таймеры
Код: Выделить всё
#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
[uquote="Martian",url="/forum/viewtopic.php?p=4471482#p4471482"]теперь смотрим листинг ассемблера, как компилятор скомпилировал:[/uquote]
Большое спасибо за пояснение.
[uquote="Martian",url="/forum/viewtopic.php?p=4471482#p4471482"]Наверное, пришло время изучить таймеры
[/uquote]
Опять вы зрите в корень.
Уже начал изучать. А параллельно и прерывания. Пару дней уже не могу понять вот это
__interrupt void Это функция, которая будет исполнятся при наступлении условия прерывания(вектора прерывания)?
Как указать значение вектора прерывания? Точнее сказать, какое значение должно стоять, например, для TIM1 захват/сравнение? Не могу разобраться как значение из таблицы перевести в шестнадцатеричный формат.
Большое спасибо за пояснение.
[uquote="Martian",url="/forum/viewtopic.php?p=4471482#p4471482"]Наверное, пришло время изучить таймеры
Опять вы зрите в корень.
Уже начал изучать. А параллельно и прерывания. Пару дней уже не могу понять вот это
Код: Выделить всё
Обработчики прерываний определяются следующим образом:
#pragma vector=<номер прерывания> (табл. 3.1)
__interrupt void <имя прерывания>,
<номер прерывания> – номер прерывания в hex формате. Берется
значение из технической документации микроконтроллера и к нему
прибавляется 2.
<имя прерывания> – имя, которое будет именем подпрограммы
обработчика прерывания (определяется пользователем).
Как указать значение вектора прерывания? Точнее сказать, какое значение должно стоять, например, для TIM1 захват/сравнение? Не могу разобраться как значение из таблицы перевести в шестнадцатеричный формат.
Re: Программирование STM8
Полагаю, проще прочитать здесь: https://we.easyelectronics.ru/STM8/8l-k ... -exti.html
а то писать очень много
Добавлено after 1 minute 34 seconds:
И обязательно читать учебник, прилагающийся к каждой среде разработки, так как есть различия.
а то писать очень много
Добавлено after 1 minute 34 seconds:
И обязательно читать учебник, прилагающийся к каждой среде разработки, так как есть различия.
-
Pjatruha@mail.ru
- Грызет канифоль
- Сообщения: 259
- Зарегистрирован: Пн фев 10, 2014 19:40:03
Re: Программирование STM8
Большое спасибо за статью. Мне очень понравилось. Написано простыми словами. Очень легко читать. Пожалуй прочитаю весь цикл статей этого автора по теме STM8. Но тут ответ на мой вопрос все же не полный. По сути можно не заморачиваться и пользоваться готовой таблицей из заголовочного файла IOSTM8S103F3.h(ведь не зря же он подключен
) , но мне все же хотелось бы разобраться до конца. Как получилась эта таблица в заголовочном файле?
Вот таблица из DataSheet

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


