Добрых времен всем. Други, помогите с проблемой - пытаюсь накропать класс для АТТИНИ 2313 кнопки на два нажатия в течение определенного времени (определяется подсчетом прерываний предварительно настроенного счетчика-таймера 0
ISR(TIMER0_COMPA_vect) {
if (kn_1.counting) kn_1.count_Plus();
}
метод count_Plus() стр. 23-32 ), метод опроса кнопки butt_Read()(стр. 34-56) постоянно вызывается из loop(); После второго нажатия кнопки вызывается внешняя функция target_Funct_, прекращается (вернее должен прекращаться) подсчет прерываний обнуляются(должны обнуляться) переменные counting, sec, sec_time, этого не происходит т.е. строки 51-53 тупо не выполняются (смотрю в протеусе и на зашитой микрухе),target_Funct_ выполняется, хотя в методе count_Plus() все срабатывает при достижении макс. значения счета. Подскажите пож. чего я не понимаю, где ошибка? Заранее благодарю.
class _Butt_ : public noga {
public:
void (*funct_)(); //функция выключения счетчика
void (*target_Funct_)(); //выполняемая функция кнопки
//noga _Noga;
bool dbg = 0;
bool sec = 0;
bool released = false;
bool counting = 0;
uint8_t dbg_time = 0;
uint8_t sec_time = 0;
void butt_Read();
void count_Plus();
// void tst_prnt(bool inp);
_Butt_(uint8_t pin, void(*_funct), void(*t_Funct))
: noga(pin),
funct_(_funct), target_Funct_(t_Funct) {
pin_Set(true, false);
}
};
void _Butt_::count_Plus() {
//target_Funct_();
if (counting!=0) sec_time ++;
if (sec_time >= 7 && dbg) dbg = false;
if (sec_time >= 62 && sec) {
sec_time = 0;
counting = false;
sec = false;
}
}
void _Butt_::butt_Read()
{
if (!dbg && sec && !released) {
if (pin_read()) released = true;
}
if (!pin_read()) {
if (!dbg && !sec) {
dbg = true;
sec = true;
counting = true;
OCR0A = 254;
TIMSK = 0b00000001;
}
else if (sec && !dbg && released) {
TIMSK &=~1;
funct_();
target_Funct_();
sec=0;
released = false;
counting = 0;
}
}
}
Нормального, целого компилируемого кода нет, поэтому и ответов нет. Разве предположения строить.
В 48 строке, вместо TIMSK &=~1;
попробовать cli();
, а в 45 sei()
И, памяти, после компиляции, сколько свободной остаётся?
1 лайк
Меня тоже удивило, вроде ТС тут не первый день. Я вот всегда запускаю глючный код и смотрю, мне так гораздо удобнее. А без запуска можно только самые простые вещи заметить.
1 лайк
Вот сам скейч(с), сделанный исключительно проверить класс
_Butt_ kn_1(14, timer_, target_1);
_Butt_ kn_2(15, timer_, target_2);
noga tst_pin(2);
noga tst_out(3);
noga ts_dbg(4);
noga _Sec(5);
noga prs(6);
noga _counting(9);
bool ir_flag = false;
bool flg_BT = false;
bool sleep_m = false;
bool counting = false;
bool dbg = false;
bool _sec = false;
uint8_t cntr = 0;
void timer_() {
if(!kn_1.counting && !kn_2.counting ) TIMSK = 0x0; //выключаем маску прерывания таймера TIMER0_COMPA
kn_1.sec = 0;
kn_1.released = false;
kn_1.counting = 0;
}
ISR(TIMER0_COMPA_vect) {
if (kn_1.counting) kn_1.count_Plus();
if (kn_2.counting) kn_2.count_Plus();
}
void target_1() {
tst_out.pin_Write(!tst_out.pin_read());
}
void target_2() {
tst_pin.pin_Write(!tst_pin.pin_read());
}
void setup() {
kn_1.pull_Up();
kn_2.pull_Up();
tst_pin.pin_Set(false);
_counting.pin_Set(false);
ts_dbg.pin_Set(false);
tst_out.pin_Set(false);
_Sec.pin_Set(false);
//установка счетчика____________
TCCR0B = 0b00000101;
TCCR0A = 0b00000010;
OCR0A = 15;
}
void loop() {
static bool press;
prs.pin_Write(press);
_counting.pin_Write(counting);
ts_dbg.pin_Write(dbg);
_Sec.pin_Write(_sec);
kn_1.butt_Read();
kn_2.butt_Read();
}
сам класс
#pragma once
#include <Arduino.h>
#include "define_s2313.h"
void timer_(); //ппрототип функции
void target_1(); //ппрототипы целевых функций для кнопок
void target_2();
class noga {
private:
uint8_t mask = 0;
public:
uint8_t _noga_;
uint8_t getMask(uint8_t);
bool pin_read();
bool pin_Write(bool dta);
void pin_Set(bool r_w, bool p_up);
void pull_Up();
noga(uint8_t noga_)
: _noga_(noga_) {
mask = g_mask(noga_);
// Serial.print("pin=");Serial.print(noga_);Serial.print(", mask=");Serial.println(mask);
}
};
bool noga::pin_Write(bool dta) {
(dta) ? _V_U_(g_PORT(_noga_)) |= (1 << mask) : _V_U_(g_PORT(_noga_)) &= ~(1 << mask);
}
bool noga::pin_read() {
return _V_U_(g_PIN(_noga_)) & (1 << mask);
}
void noga::pin_Set(bool r_w, bool p_up = 0) //r_w==true на чтение
{
(!r_w) ? *(volatile uint16_t*)(g_DDR(_noga_)) |= (1 << mask) : *(volatile uint16_t*)(g_DDR(_noga_)) &= ~(1 << mask);
if (p_up && r_w) *(volatile uint16_t*)(g_PORT(_noga_)) |= (1 << mask);
}
void noga::pull_Up() {
if (!(_V_U_(g_DDR(_noga_)) & (1 << mask))) _V_U_(g_PORT(_noga_)) |= (1 << mask);
}
// класс кнопки----------------------->>>>>
class _Butt_ : public noga {
public:
void (*funct_)(); //функция выключения счетчика
void (*target_Funct_)(); //выполняемая функция кнопки
//noga _Noga;
bool dbg = 0;
bool sec = 0;
bool released = false;
bool counting = 0;
uint8_t dbg_time = 0;
uint8_t sec_time = 0;
void stp();
void butt_Read();
void count_Plus();
// void tst_prnt(bool inp);
_Butt_(uint8_t pin, void(*_funct), void(*t_Funct))
: noga(pin),
funct_(_funct), target_Funct_(t_Funct) {
pin_Set(true, false);
}
};
void _Butt_::stp() {
sec = 0;
released = false;
counting = 0;
}
void _Butt_::count_Plus() {
//target_Funct_();
if (counting!=0) sec_time ++;
if (sec_time >= 7 && dbg) dbg = false;
if (sec_time >= 62 && sec) {
sec_time = 0;
counting = false;
sec = false;
//timer_();
//TIMSK &=~1;
// funct_();
}
}
// void _Butt_::count_Plus() {
// if (counting) sec_time++;
// if ((sec_time > 7) && dbg) {
// dbg = false;
// }
// if (sec_time > 62) {
// sec = false;
// sec_time = 0;
// //released = false;
// funct_(); //функция выключения счетчика
// }
// }
void _Butt_::butt_Read()
{
//static bool press;
if (!dbg && sec && !released) {
if (pin_read()) released = true;
}
if (!pin_read()) {
if (!dbg && !sec) {
dbg = true;
sec = true;
counting = true;
// funct_();
OCR0A = 254;
TIMSK = 0b00000001;
}
else if (sec && !dbg && released) {
cli();
//
TIMSK &=~1;
// _sec =!_sec ;
stp();
funct_();
target_Funct_();
sec=0;
released = false;
counting = 0;
sei();
return;
}
}
}
define_s2313.h:
#define g_DDR(x) (x==1||x==4||x==5)?&DDRA:(x>=12 && x<=19)?&DDRB:(x==2||x==3||x==6||x==7||x==8||x==9||x==11)?&DDRD:0
#define g_PORT(x) (x==1||x==4||x==5)?&PORTA:(x>=12 && x<=19)?&PORTB:(x==2||x==3||x==6||x==7||x==8||x==9||x==11)?&PORTD:0
#define g_PIN(x) (x==1||x==4||x==5)?&PINA:(x>=12 && x<=19)?&PINB:(x==2||x==3||x==6||x==7||x==8||x==9||x==11)?&PIND:0
#define g_mask(y) (y==2||y==5||y==12)?0:(y==4||y==3||y==13)?1:(y==1||y==14||y==6)?2:(y==7||y==15)?3:(y==8||y==16)?4:(y==9||y==17)?5:(y==11||y==18)?6:(y==19)?7:0
#define _V_U_(x) *(volatile uint8_t*)(x)
Извините, много мусора, как всегда
Kakmyc
15.Сентябрь.2023 10:50:21
5
Угу, типа того, что в прерывании пытаются менять значение переменной, которая не объявлена как volatile.
1 лайк
Ну что, помог volatile? А то чегой-то у меня код не компилируется
Ни разу не помог, сижу втыкаю ничего не пойму в трех соснах такая фигня
Alexey_Rem:
Вот сам скейч(с)
Ну, нельзя же так. Я скопировал скетч, чтобы попытаться Вам помочь, и обнаружил, что он не компилируется! Как Вы его проверяли?
В строке №56 скетча класса неправильно описаны параметры. Надо писать вот так:
_Butt_(*uint8_t* pin, void(*_funct)(void), void(*t_Funct)(void))
Далее, в строках 25-27 того же файла у Вас функция объявлена как bool
, но ничего не возвращает. Вы забыли return
? Или функция должна быть void
?
После этих исправлений код скомпилировался. Внесите их у себя, проверьте на месте ли проблема и попробуйте её как-то более внятно описать. Для начала нарисуйте схему что куда подключено, чтобы я мог это воспроизвести. А потом опишите что я должен сделать, чтобы увидеть проблему и в чём она (проблема) выражается.
ЕвгенийП:
он не компилируется!
У меня тоже не компилировался, но вот получилось от имени администратора )))) (Недавно тема была). Правда с предупреждениями. Аддон ATTinyCore…
Что-то новое, раньше вроде такого не было, может обновление…
Ну, я просто в микрочип-студии компилировал. После тех исправлений, что я описал предупреждения исчезли. Всё компилируется безо всяких бубнов.
Осталось от ТС дождаться схемы и описания проблемы, тогда можно будет запустить и хоть посмотреть, что ему там не нравится.
Блин, вот почему сразу это всё не выкладывать? Ему вообще нужно решить проблему или так, потрындеть зашёл? Вот говорит, что исправил volatile
- не помогло. А показать как исправил? Или он так уверен, что сделал это правильно?
Спасибо всем на сегодня все, завтра займусь
Butt (uint8_t pin, void(*_funct)(void), void(*t_Funct)(void))
за это отдельное спасибо
Нет не уверен, все до завтра, еще раз спасибо
ua6em
15.Сентябрь.2023 17:47:57
13
ЕвгенийП:
что ему там не нравится
всегда так…всему посёлку невеста нравится, а жениху нет )))
Возможно , проблема с логикой кнопок.
Вот, сделал заплатку(если конечно, я правильно понял замысел)
void _Butt_::butt_Read()
{
if (!dbg && !sec && !released ) {
if (pin_read()){ on = false;dbg = false;}
}
if (!dbg && sec && !released ) {
if (pin_read()) released = true;
}
if (!pin_read()) {
if (!dbg && !sec && !on) {
dbg = true;
on = true;
sec = true;
counting = true;
// funct_();
OCR0A = 254;
TIMSK = 0b00000001;
}
else if (sec && !dbg && released && on) {
TIMSK &=~1;
stp();
funct_();
target_Funct_();
printByte(counting);
return;
}
}
}
И здесь убрать лишнее
void _Butt_::count_Plus() {
//target_Funct_();
if (counting!=0) sec_time ++;
if (sec_time >= 7 && dbg) dbg = false;
if (sec_time >= 62 && sec) {
sec_time = 0;
}
}
Объявить
bool on = false;
Спасибо всем кто откликнулся! Таки с логикой перемудрил, переписал сейчас все работает. Всем спасибо еще раз за помощь
мусорный скейч(с) с новой логикой кому интересно
Спойлер
#pragma once
#include <Arduino.h>
//#include "define_s.h"
//#include "define_s2560.h"
#include "define_s2313.h"
void timer_(); //ппрототип функции
void target_1(); //ппрототипы целевых функций для кнопок
void target_2();
class noga {
private:
uint8_t mask = 0;
public:
uint8_t _noga_;
uint8_t getMask(uint8_t);
bool pin_read();
bool pin_Write(bool dta);
void pin_Set(bool r_w, bool p_up);
void pull_Up();
noga(uint8_t noga_)
: _noga_(noga_) {
mask = g_mask(noga_);
}
};
bool noga::pin_Write(bool dta) {
(dta) ? _V_U_(g_PORT(_noga_)) |= (1 << mask) : _V_U_(g_PORT(_noga_)) &= ~(1 << mask);
}
bool noga::pin_read() {
return _V_U_(g_PIN(_noga_)) & (1 << mask);
}
void noga::pin_Set(bool r_w, bool p_up = 0) //r_w==true на чтение
{
(!r_w) ? *(volatile uint16_t*)(g_DDR(_noga_)) |= (1 << mask) : *(volatile uint16_t*)(g_DDR(_noga_)) &= ~(1 << mask);
if (p_up && r_w) *(volatile uint16_t*)(g_PORT(_noga_)) |= (1 << mask);
}
void noga::pull_Up() {
if (!(_V_U_(g_DDR(_noga_)) & (1 << mask))) _V_U_(g_PORT(_noga_)) |= (1 << mask);
}
// класс кнопки----------------------->>>>>
class _Butt_ : public noga {
public:
void (*funct_)(); //функция выключения счетчика
void (*target_Funct_)(); //выполняемая функция кнопки
//noga _Noga;
volatile bool dbg = 0;
volatile bool sec = 0;
volatile bool released = false;
volatile bool counting = false;
uint8_t dbg_time = 0;
bool pr1=0;
bool pr2=0;
bool key = 0;
volatile byte sec_time = 0;
bool tst_press=0;
uint8_t prs_cnt=0;
void stp();
void butt_Read();
void count_Plus();
// void tst_prnt(bool inp);
_Butt_(uint8_t pin, void (*_funct)(void), void (*t_Funct)(void))
: noga(pin),
funct_(_funct), target_Funct_(t_Funct) {
pin_Set(true, false);
}
};
void _Butt_::stp() {
sec = 0;
released = false;
counting = 0;
}
void _Butt_::count_Plus() {
if(counting || pr2) sec_time++;
if (sec_time >= 2 && dbg) dbg = false;
if (sec_time >= 31) {
sec_time = 0;
counting = false;
sec = false;
pr1=false;
pr2=false;
released=false;
}
}
void _Butt_::butt_Read() {
if(!dbg && pr1){if(pin_read() && !released)released=true; }
if(!pin_read()){
if(!pr1){
dbg=true;
pr1=true;
counting=true;
return;
}
if(pr1 && !dbg)
{
if(!pr2 && released){
pr2=true;
counting=false;
target_Funct_();
// sec_time=0;
}
}
}
}
Уж очень сложная запись, куча флагов, легко запутаться. Как по мне, проще создать массив всех возможных состояний кнопок , и привязывать его к текущей позиции ИМХО
Но, как говорится , “на вкус и цвет…”))
“…он играет как умеет”, а умеет не очень хорошо, только сейчас поонимаю как не хватает именно системных знаний, поэтому позволю себе дать совет учитесь всегда, и желательно на чужих ошибках😀
1 лайк