Ср янв 19, 2022 12:54:08
Ср янв 19, 2022 13:15:57
Ср янв 19, 2022 13:33:18
Ср янв 19, 2022 13:44:55
Ср янв 19, 2022 13:47:56
switch(e){
case EVT_NONE: // just pressed
case EVT_RELEASE:
if((k->counter += d) > PRESSTHRESHOLD)
k->event = EVT_PRESS;
break;
case EVT_PRESS: // hold
if((k->counter += d)> HOLDTHRESHOLD)
k->event = EVT_HOLD;
break;
default:
break;
}
Ср янв 19, 2022 17:03:09
Ни знаю в чем проблема, и не ужели для каких-то кнопок применять конечный автомат?AlanDrakes писал(а):или хотя бы обрабатывать кнопки в функции
#include <stdbool.h>
bool flag_IDR5;
bool flag_IDR4;
bool flag_IDR8;
#define BTN_TIME 50
void ScanButtons(void) {
static uint8_t ButtonFilter[3] = {0};
flag_IDR5=0; flag_IDR4=0; flag_IDR8=0;
if (GPIOB->IDR & GPIO_IDR_IDR5) {
// Отпущена, висит в воздухе, подтяжка к VCC
if (ButtonFilter[0]) { ButtonFilter[0] = 0; }
} else {
// Нажата (притянуто к 0)
if (ButtonFilter[0] == BTN_TIME) {
ButtonFilter[0] = (BTN_TIME+1);
flag_IDR5 = 1;
} else if (ButtonFilter[0] < BTN_TIME) {
ButtonFilter[0]++;
}
}
if (GPIOB->IDR & GPIO_IDR_IDR4) {
if (ButtonFilter[1]) { ButtonFilter[1] = 0; }
} else {
if (ButtonFilter[1] == BTN_TIME) {
ButtonFilter[1] = (BTN_TIME+1);
flag_IDR4 = 1;
} else if (ButtonFilter[1] < BTN_TIME) {
ButtonFilter[1]++;
}
}
if (GPIOB->IDR & GPIO_IDR_IDR8) {
if (ButtonFilter[2]) { ButtonFilter[2] = 0; }
} else {
if (ButtonFilter[2] == BTN_TIME) {
ButtonFilter[2] = (BTN_TIME+1);
flag_IDR8 = 1;
} else if (ButtonFilter[2] < BTN_TIME) {
ButtonFilter[2]++;
}
}
}
ScanButtons();
switch (nastroyki.menu_btn) {
case 0:
break;
case 1:
if (flag_IDR4) {
if (danie.a < 4095) danie.a++;
}
if (flag_IDR8) {
if (danie.a) danie.a--;
}
break;
#define BTN_TIME(port,pin,b_time,flag) do{ flag=0; if(port&(pin)) { if(b_time)b_time=0; } else { if(b_time == BTN_LOCK_TIME) { b_time = (BTN_LOCK_TIME+1); flag=1; } else if(b_time<BTN_LOCK_TIME) b_time++; } }while(0)
void ScanButtons(void) {
static uint8_t ButtonFilter[3] = {0};
BTN_TIME(GPIOB->IDR, GPIO_IDR_IDR5, ButtonFilter[0], flag_IDR5);
BTN_TIME(GPIOB->IDR, GPIO_IDR_IDR4, ButtonFilter[1], flag_IDR4);
BTN_TIME(GPIOB->IDR, GPIO_IDR_IDR8, ButtonFilter[2], flag_IDR8);
}
Ср янв 19, 2022 20:12:04
Ни знаю в чем проблема, и не ужели для каких-то кнопок применять конечный автомат?AlanDrakes писал(а):или хотя бы обрабатывать кнопки в функции
#include <stdbool.h>
bool flag_IDR5;
bool flag_IDR4;
bool flag_IDR8;
#define BTN_TIME 50
void ScanButtons(void) {
static uint8_t ButtonFilter[3] = {0};
flag_IDR5=0; flag_IDR4=0; flag_IDR8=0;
if (GPIOB->IDR & GPIO_IDR_IDR5) {
// Отпущена, висит в воздухе, подтяжка к VCC
if (ButtonFilter[0]) { ButtonFilter[0] = 0; }
} else {
// Нажата (притянуто к 0)
if (ButtonFilter[0] == BTN_TIME) {
ButtonFilter[0] = (BTN_TIME+1);
flag_IDR5 = 1;
} else if (ButtonFilter[0] < BTN_TIME) {
ButtonFilter[0]++;
}
}
if (GPIOB->IDR & GPIO_IDR_IDR4) {
if (ButtonFilter[1]) { ButtonFilter[1] = 0; }
} else {
if (ButtonFilter[1] == BTN_TIME) {
ButtonFilter[1] = (BTN_TIME+1);
flag_IDR4 = 1;
} else if (ButtonFilter[1] < BTN_TIME) {
ButtonFilter[1]++;
}
}
if (GPIOB->IDR & GPIO_IDR_IDR8) {
if (ButtonFilter[2]) { ButtonFilter[2] = 0; }
} else {
if (ButtonFilter[2] == BTN_TIME) {
ButtonFilter[2] = (BTN_TIME+1);
flag_IDR8 = 1;
} else if (ButtonFilter[2] < BTN_TIME) {
ButtonFilter[2]++;
}
}
}
ScanButtons();
switch (nastroyki.menu_btn) {
case 0:
break;
case 1:
if (flag_IDR4) {
if (danie.a < 4095) danie.a++;
}
if (flag_IDR8) {
if (danie.a) danie.a--;
}
break;
#define BTN_TIME(port,pin,b_time,flag) do{ flag=0; if(port&(pin)) { if(b_time)b_time=0; } else { if(b_time == BTN_LOCK_TIME) { b_time = (BTN_LOCK_TIME+1); flag=1; } else if(b_time<BTN_LOCK_TIME) b_time++; } }while(0)
void ScanButtons(void) {
static uint8_t ButtonFilter[3] = {0};
BTN_TIME(GPIOB->IDR, GPIO_IDR_IDR5, ButtonFilter[0], flag_IDR5);
BTN_TIME(GPIOB->IDR, GPIO_IDR_IDR4, ButtonFilter[1], flag_IDR4);
BTN_TIME(GPIOB->IDR, GPIO_IDR_IDR8, ButtonFilter[2], flag_IDR8);
}
Ср янв 19, 2022 21:05:34
nastroyki.menu_btn
nastroyki.menu_lcd
while (1) {
ScanButtons();
if (flag_IDR5) {
if(++nastroyki.menu_btn > 4) nastroyki.menu_btn = 0;
}
switch (nastroyki.menu_btn) {
case 0:
LCD_SetPos(0, 0);
LCD_String("Bobr_stm32");
break;
case 1:
if(flag_IDR4) if(danie.a < 4095) danie.a++;
if(flag_IDR8) if(danie.a) danie.a--;
sprintf(nastroyki.buf, "a=%2d ", danie.a);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf);
break;
case 2:
if(flag_IDR4) if(danie.b < 4095) danie.b++;
if(flag_IDR8) if(danie.b) danie.b--;
sprintf(nastroyki.buf2, "b=%2d ", danie.b);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf2);
break;
case 3:
if(flag_IDR4) if(danie.c < 4095) danie.c++;
if(flag_IDR8) if(danie.c) danie.c--;
sprintf(nastroyki.buf4, "c=%2d ", danie.c);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf4);
break;
case 4:
if(flag_IDR4) if(danie.d < 1023) danie.d++;
if(flag_IDR8) if(danie.d) danie.d--;
sprintf(nastroyki.buf6, "d=%2d ", danie.d);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf6);
break;
default: break;
}
}
Ср янв 19, 2022 21:57:10
Ср янв 19, 2022 22:35:38
nastroyki.menu_btn
nastroyki.menu_lcd
while (1) {
ScanButtons();
if (flag_IDR5) {
if(++nastroyki.menu_btn > 4) nastroyki.menu_btn = 0;
}
switch (nastroyki.menu_btn) {
case 0:
LCD_SetPos(0, 0);
LCD_String("Bobr_stm32");
break;
case 1:
if(flag_IDR4) if(danie.a < 4095) danie.a++;
if(flag_IDR8) if(danie.a) danie.a--;
sprintf(nastroyki.buf, "a=%2d ", danie.a);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf);
break;
case 2:
if(flag_IDR4) if(danie.b < 4095) danie.b++;
if(flag_IDR8) if(danie.b) danie.b--;
sprintf(nastroyki.buf2, "b=%2d ", danie.b);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf2);
break;
case 3:
if(flag_IDR4) if(danie.c < 4095) danie.c++;
if(flag_IDR8) if(danie.c) danie.c--;
sprintf(nastroyki.buf4, "c=%2d ", danie.c);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf4);
break;
case 4:
if(flag_IDR4) if(danie.d < 1023) danie.d++;
if(flag_IDR8) if(danie.d) danie.d--;
sprintf(nastroyki.buf6, "d=%2d ", danie.d);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf6);
break;
default: break;
}
}
Чт янв 20, 2022 05:44:06
Чт янв 20, 2022 07:37:07
Не знаю в чем проблема, и неужели для каких-то кнопок применять конечный автомат?AlanDrakes писал(а):или хотя бы обрабатывать кнопки в функции
#define BTN_TIME(port,pin,b_time,flag) do{ flag=0; if(port&(pin)) { if(b_time)b_time=0; } else { if(b_time == BTN_LOCK_TIME) { b_time = (BTN_LOCK_TIME+1); flag=1; } else if(b_time<BTN_LOCK_TIME) b_time++; } }while(0)
void ScanButtons(void) {
static uint8_t ButtonFilter[3] = {0};
BTN_TIME(GPIOB->IDR, GPIO_IDR_IDR5, ButtonFilter[0], flag_IDR5);
BTN_TIME(GPIOB->IDR, GPIO_IDR_IDR4, ButtonFilter[1], flag_IDR4);
BTN_TIME(GPIOB->IDR, GPIO_IDR_IDR8, ButtonFilter[2], flag_IDR8);
}
Чт янв 20, 2022 07:44:46
я тебе даю свой рабочий проект, а ты из него делаешь КА, вот тогда и поговорим о размере кода.Eddy_Em писал(а):Ну так сравни объем одного и того же кода без КА и с ними!
Eddy_Em писал(а):С КА воткнуть новое состояние намного проще, чем без оного!
while (1) {
ScanButtons();
новое_состояние();
под каждую задачу вы будете рисовать свой автомат, а потом его кодировать.tonyk писал(а):Заметьте, сначала рисуем автомат, а потом его кодируем.
tonyk писал(а):Учитесь рисовать и работать с КА, ибо это очень эффективный способ создания ПО!
КА++
switch (KA){
case 0 : опрос_кнопок(); break;
case 1 : действие(); break;
case 2 : вывод_лсд(); break;
default : КА=-1
}
while(1){
опрос_кнопок();
действие();
вывод_лсд();
}
пример в студию, с КА и без КА.tonyk писал(а):когда у вас при анализе получается 100500 if-then-else, а в самой глубине goto.
Чт янв 20, 2022 08:07:13
nastroyki.menu_btn
nastroyki.menu_lcd
while (1) {
ScanButtons();
if (flag_IDR5) {
if(++nastroyki.menu_btn > 4) nastroyki.menu_btn = 0;
}
switch (nastroyki.menu_btn) {
case 0:
LCD_SetPos(0, 0);
LCD_String("Bobr_stm32");
break;
case 1:
if(flag_IDR4) if(danie.a < 4095) danie.a++;
if(flag_IDR8) if(danie.a) danie.a--;
sprintf(nastroyki.buf, "a=%2d ", danie.a);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf);
break;
case 2:
if(flag_IDR4) if(danie.b < 4095) danie.b++;
if(flag_IDR8) if(danie.b) danie.b--;
sprintf(nastroyki.buf2, "b=%2d ", danie.b);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf2);
break;
case 3:
if(flag_IDR4) if(danie.c < 4095) danie.c++;
if(flag_IDR8) if(danie.c) danie.c--;
sprintf(nastroyki.buf4, "c=%2d ", danie.c);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf4);
break;
case 4:
if(flag_IDR4) if(danie.d < 1023) danie.d++;
if(flag_IDR8) if(danie.d) danie.d--;
sprintf(nastroyki.buf6, "d=%2d ", danie.d);
LCD_SetPos(0, 0);
LCD_String(nastroyki.buf6);
break;
default: break;
}
}
Чт янв 20, 2022 08:28:49
ivan dimir писал(а):И меня заинтерисовала функция ScanButtons()?
что и требовалось.AlanDrakes писал(а):или хотя бы обрабатывать кнопки в функции
здесь мне не понятно было, а переспрашивать не стал, в качестве демонстрации.ivan dimir писал(а):что переход на ноль при ++ и переход с нуля на 1023 при --
опять не понятно, что значит замедление?ivan dimir писал(а):И замедление показаний.
#define BTN_TIME 50
Чт янв 20, 2022 11:48:50
КА++
switch (KA){
case 0 : опрос_кнопок(); break;
case 1 : действие(); break;
case 2 : вывод_лсд(); break;
default : КА=-1
}
Чт янв 20, 2022 14:28:42
KA = 0;
while (1) {
switch (KA) {
case 0: инит_всего(); KA = 1; break;
case 1: опрос_кнопок(); KA = 2; break;
case 2: действие(); KA = 3; break;
case 3: вывод_лсд(); KA = 1; break;
default: в пиииии.....();
}
}
Чт янв 20, 2022 15:04:13
Чт янв 20, 2022 15:44:56
//==================
#ifndef SOFT_TIMERS_H
#define SOFT_TIMERS_H
#include "soft_timers.h"
#include "main.h"
#define SwTimerCount 8 //Количество программных таймеров
/*Режимы работы таймеров*/
typedef enum
{
SWTIMER_MODE_EMPTY,
SWTIMER_MODE_WAIT_ON,
SWTIMER_MODE_WAIT_OFF,
SWTIMER_MODE_CYCLE,
SWTIMER_MODE_SINGLE
} SwTimerMode;
/*Стурктура программного таймера*/
typedef struct
{
unsigned LocalCount:32; //Переменная для отсчета таймера
unsigned Count:24; //Переменная для хранения задержки
unsigned Mode:3; //Режим работы
unsigned On:1; //Разрешиющий бит
unsigned Reset:1; //Сброс счета таймера без его выключения
unsigned Off:1; //Останавливающий бит
unsigned Out:1; //Выход таймера
unsigned Status:1; //Состояние таймера
}SW_TIMER;
#if (SwTimerCount>0)
volatile SW_TIMER TIM[SwTimerCount]; //Объявление софтовых таймеров
#endif
void SwTimerWork(volatile SW_TIMER* TIM, unsigned char Count); //Сама функция для обработки таймеров
void OnSwTimer(volatile SW_TIMER* TIM, SwTimerMode Mode, unsigned int SwCount); //Подготовливает выбранный из массива таймер
unsigned char GetStatusSwTimer(volatile SW_TIMER* TIM); //Считывание статуса таймера
#endif
//==================
//---------- Пример использования ----------
// set_soft_timer (ST_LED_2_BLINK, 50, 50); // Установка таймера.
// if (handle_soft_timer (ST_LED_2_BLINK)) // Проверка таймера.
//==================
//==================
#include "soft_timers.h"
//==================
//Подпрограмма программных таймеров
void SwTimerWork(volatile SW_TIMER* TIM, unsigned char Count){
unsigned short i=0;
for (i=0; i<Count; i++){
if (TIM->Mode==SWTIMER_MODE_EMPTY){
TIM++;
continue;
}
if (TIM->Mode==SWTIMER_MODE_WAIT_ON){ //Если таймер на задержку включения
if (TIM->On){
if (TIM->LocalCount>0) TIM->LocalCount--;
else {
TIM->Out=1;
TIM->Status=1;
}
}
else {
TIM->Out=0;
TIM->LocalCount=TIM->Count-1;
}
}
if (TIM->Mode==SWTIMER_MODE_WAIT_OFF){ //Если таймер на задержку выключения
if (TIM->On){
TIM->Out=1;
TIM->Status=1;
TIM->LocalCount=TIM->Count-1;
}
else {
if (TIM->LocalCount>0) TIM->LocalCount--;
else TIM->Out=0;
}
}
if (TIM->Mode==SWTIMER_MODE_CYCLE){
if (TIM->Off){
if (TIM->On){
TIM->Off=0;
if (TIM->LocalCount>0) TIM->LocalCount--;
}
}
else{
if (TIM->LocalCount>0) {
TIM->LocalCount--;
TIM->Out=0;
}
else {
TIM->Out=1;
TIM->Status=1;
TIM->LocalCount=TIM->Count-1;
}
}
if (TIM->Reset){
TIM->LocalCount=TIM->Count-1;
TIM->Out=0;
TIM->Status=0;
}
}
if (TIM->Mode==SWTIMER_MODE_SINGLE){
if (TIM->Off){
if (TIM->On){
TIM->Off=0;
if (TIM->LocalCount>0) TIM->LocalCount--;
}
}
else{
if (TIM->LocalCount>0) {
TIM->LocalCount--;
TIM->Out=0;
}
else {
TIM->Out=1;
TIM->Status=1;
TIM->LocalCount=TIM->Count-1;
TIM->Off=1;
TIM->On=0;
}
}
if (TIM->Reset){
TIM->LocalCount=TIM->Count-1;
TIM->Out=0;
TIM->Status=0;
}
}
TIM++;
}
}
void OnSwTimer(volatile SW_TIMER* TIM, SwTimerMode Mode, unsigned int SwCount){
TIM->Mode=Mode;
if (SwCount){
TIM->Count=SwCount;
TIM->LocalCount=SwCount-1;
}
if (TIM->Mode==SWTIMER_MODE_CYCLE || TIM->Mode==SWTIMER_MODE_SINGLE){
TIM->Off=1;
}
}
unsigned char GetStatusSwTimer(volatile SW_TIMER* TIM){
unsigned char status=0;
if (TIM->Mode==SWTIMER_MODE_EMPTY) return -1;
if (TIM->Status){
TIM->Status=0;
status=1;
}
else {
status=0;
}
return status;
}
volatile uint32_t currentMillis = 0;
void SysTick_Handler(void)
{ static uint8_t count=0;
currentMillis++;
}
uint32_t millis (void)
{
return currentMillis;
}
if((millis() - previousMillis) > 500){
previousMillis = millis();
blink = !blink;
}
LCDI2C_setCursor (10,0);
if (blink) LCDI2C_write(0x22); else LCDI2C_write(0x20);
LCDI2C_setCursor (11, 0);
sprintf (string_out,"%02dV",(uint8_t)table_u);
LCDI2C_write_String (string_out);
LCDI2C_setCursor (15,0);
if (blink) LCDI2C_write(0x22); else LCDI2C_write(0x20);
Чт янв 20, 2022 16:41:48