BOOM
17.Март.2024 18:53:59
22
Вот перед сном что-то захотелось “по ковыряться”.
Застрял на метке goto (понятия не имею что не так, о goto вообще ничего не знаю и никогда не использовал):
пшик
/*
timer pshik
made slav0n
Chip type : ATtiny13
9.6 MHz / 8 = 1.2
фузы заводские
;Hfuse FF
;Lfuse 6A
****************************************************/
#include <avr/io.h>
#include <avr/eeprom.h>
#include <avr/wdt.h>
#include <util/delay.h>
//#include “m8_128.h”
#define LED_pl PB1
#define LED_mn PB0
#define GATE PB2
#define BUTTON_PSHIK PB4
#define adr_set_hrs 1
#define adr_binary adr_set_hrs + 1
#define adr_unary adr_binary + 1
typedef uint8_t u8;
typedef uint32_t u32;
//============================================================
int main(void) {
WDTCR = (1 << WDE) | //выпускаем сторожевую собаку
// (0<<WDP3)|(0<<WDP2)|(0<<WDP1)|(1<<WDP0); //32mc
// (0<<WDP3)|(0<<WDP2)|(1<<WDP1)|(0<<WDP0); //64mc
// (0<<WDP3)|(0<<WDP2)|(1<<WDP1)|(1<<WDP0); //0.125c
// (0<<WDP3)|(1<<WDP2)|(0<<WDP1)|(1<<WDP0); //0.5c
// (0<<WDP3)|(1<<WDP2)|(1<<WDP1)|(0<<WDP0); //1c
// (0<<WDP3)|(1<<WDP2)|(1<<WDP1)|(1<<WDP0); //2c
(1 << WDP3) | (0 << WDP2) | (0 << WDP1) | (0 << WDP0); //4c
// (1<<WDP3)|(0<<WDP2)|(0<<WDP1)|(1<<WDP0); //8c
PORTB |= (1 << LED_pl) | (1 << BUTTON_PSHIK);
_delay_us(100);
while (bit_is_clear(PINB, LED_mn)) {
wdt_reset();
u8 set_hrs = eeprom_read_byte((const uint8_t*)adr_set_hrs) + 1;
if (set_hrs >= 5) set_hrs = 0;
u8 i = set_hrs;
do {
DDRB |= (1 << LED_pl); //зажигаем светодиод от кнопки
_delay_ms(200);
wdt_reset();
DDRB &= ~(1 << LED_pl); //тушим светодиод
_delay_ms(200);
wdt_reset();
} while (i--);
_delay_ms(400);
wdt_reset();
_delay_ms(400);
wdt_reset();
// eeprom_update_byte(adr_set_hrs, set_hrs);
eeprom_write_byte((uint8_t*)adr_set_hrs, set_hrs);
eeprom_write_byte((uint8_t*)adr_binary, 0); // сбрасываем бинарный счетчик
}
if (bit_is_clear(PINB, BUTTON_PSHIK)) goto M_PSHIK; //пшикаем и сбрасываем таймер
DDRB |= (1 << LED_pl) | (1 << LED_mn); //зажигаем светодиод
_delay_ms(10);
u8 p_ctr[4];
u8 p_old[4];
eeprom_read_block(p_ctr, (const void*)adr_unary, 4); // читаем унарный счетчик
memcpy(p_old, p_ctr, 4);
// u8 *ctr_unary = p_ctr;
u32 *ctr_unary = (u32*)p_ctr;
*ctr_unary <<= 1; //инкремент унарный счетчик
if (*ctr_unary == 0)
{
*ctr_unary = 0xffffffff;
// *ctr_unary = 0xff;
/* */
int ct_binary = eeprom_read_byte((const uint8_t*)adr_binary); // читаем бинарный счетчик
ct_binary++;
//здесь можем сравнить бинарный счетчик с чем-либо
int set_hrs = eeprom_read_byte((const uint8_t*)adr_set_hrs);
if (set_hrs >= 5)set_hrs = 0;
if (ct_binary == (set_hrs + 1) * 24)
// if(ct_binary == (set_hrs+1))
{
M_PSHIK:
ct_binary = 0; // сбрасываем бинарный счетчик
DDRB |= (1 << GATE);
PORTB |= (1 << GATE);
wdt_reset();
_delay_ms(500);
wdt_reset();
_delay_ms(500);
wdt_reset();
PORTB &= ~(1 << GATE);
DDRB &= ~(1 << GATE);
}
eeprom_write_byte((const uint8_t*)adr_binary, ct_binary);
}
/* */
//------- пишем 4 байта унарного счетчика в EEPROM ----------------------
for (u8 i = 0; i < 4; i++)
{
if (p_old[i] != p_ctr[i]) //пишем только если байт измнился
{
while (EECR & (1 << EEPE)); // Wait for completion of previous write
// Set Programming mode
// EECR = (0<<EEPM1)|(0>>EEPM0); //Erase-Write
if (p_ctr[i] == 0xff)EECR = (0 << EEPM1) | (1 >> EEPM0); //Erase Only
else EECR = (1 << EEPM1) | (0 >> EEPM0); //Write Only
EEARL = adr_unary + i; //ucAddress;
EEDR = p_ctr[i]; //ucData;
EECR |= (1 << EEMPE); // Write logical one to EEMWE
EECR |= (1 << EEPE); // Start eeprom write by setting EEWE
}
}
//-------------------------------------------------------------------------
DDRB &= ~((1 << LED_pl) | (1 << LED_mn)); //тушим светодиод
PORTB &= ~((1 << LED_pl) | (1 << LED_mn));
MCUCR |= (1 << SE) | (1 << SM1) | (0 << SM0); //power down
asm("sleep");
}
Окромя варнингов от такое:
sketch_mar17a:106:1: error: jump to label ‘M_PSHIK’ [-fpermissive]
M_PSHIK:
BOOM
17.Март.2024 19:13:36
24
Без изменений.
Ладно, лошадь никуда не денется ))
ua6em
17.Март.2024 19:39:06
25
это жеж линейное программирование, а ты внутрь условия лезешь, я бы тебе показал кусок когда, где без goto НУ ОЧЕНЬ СЛОЖНО! если найду, приведу пример
Всё правильно написал было @xDriver , ругается, что между goto и меткой есть инициализация
M_PSHIK:
^~~~~~~
…/main.ino:75:46: note: from here
if (bit_is_clear(PINB, BUTTON_PSHIK)) goto M_PSHIK; //пшикаем и сбрасываем таймер
^~~~~~~
…/main.ino:99:9: note: crosses initialization of ‘int set_hrs’
int set_hrs = eeprom_read_byte((const uint8_t*)adr_set_hrs);
^~~~~~~
…/main.ino:95:9: note: crosses initialization of ‘int ct_binary’
int ct_binary = eeprom_read_byte((const uint8_t*)adr_binary); // читаем бинарный счетчик
^~~~~~~~~
…/main.ino:87:8: note: crosses initialization of ‘u32* ctr_unary’
u32 ctr_unary = (u32 )p_ctr;
я решения не нашел, точнее нашел, как мне показалось, но не прокатило)
вот и потер.
xDriver:
решения не нашел,
По мне так просто объявить, уже не ругается, а там пусть BOOM дальше думает))
int main(void) {
u32 *ctr_unary;
int set_hrs;
int ct_binary;
Не ну это я конечно сделал, правда красных дипломов у нас не имеется))
Спойлер
/*
timer pshik
made slav0n
Chip type : ATtiny13
9.6 MHz / 8 = 1.2
фузы заводские
;Hfuse FF
;Lfuse 6A
****************************************************/
#include <avr/eeprom.h>
#include <avr/io.h>
#include <avr/wdt.h>
#include <util/delay.h>
//#include “m8_128.h”
#define LED_pl PB1
#define LED_mn PB0
#define GATE PB2
#define BUTTON_PSHIK PB4
#define adr_set_hrs 1
#define adr_binary (adr_set_hrs + 1)
#define adr_unary (adr_binary + 1)
typedef uint8_t u8;
typedef uint32_t u32;
//============================================================
int main(void)
{
WDTCR = (1 << WDE) | //выпускаем сторожевую собаку
// (0<<WDP3)|(0<<WDP2)|(0<<WDP1)|(1<<WDP0); //32mc
// (0<<WDP3)|(0<<WDP2)|(1<<WDP1)|(0<<WDP0); //64mc
// (0<<WDP3)|(0<<WDP2)|(1<<WDP1)|(1<<WDP0); //0.125c
// (0<<WDP3)|(1<<WDP2)|(0<<WDP1)|(1<<WDP0); //0.5c
// (0<<WDP3)|(1<<WDP2)|(1<<WDP1)|(0<<WDP0); //1c
// (0<<WDP3)|(1<<WDP2)|(1<<WDP1)|(1<<WDP0); //2c
(1 << WDP3) | (0 << WDP2) | (0 << WDP1) | (0 << WDP0); // 4c
// (1<<WDP3)|(0<<WDP2)|(0<<WDP1)|(1<<WDP0); //8c
PORTB |= (1 << LED_pl) | (1 << BUTTON_PSHIK);
_delay_us(100);
while (bit_is_clear(PINB, LED_mn))
{
wdt_reset();
u8 set_hrs = eeprom_read_byte((const uint8_t *)adr_set_hrs) + 1;
if (set_hrs >= 5)
set_hrs = 0;
u8 i = set_hrs;
do
{
DDRB |= (1 << LED_pl); //зажигаем светодиод от кнопки
_delay_ms(200);
wdt_reset();
DDRB &= ~(1 << LED_pl); //тушим светодиод
_delay_ms(200);
wdt_reset();
} while (i--);
_delay_ms(400);
wdt_reset();
_delay_ms(400);
wdt_reset();
// eeprom_update_byte(adr_set_hrs, set_hrs);
eeprom_write_byte((uint8_t *)adr_set_hrs, set_hrs);
eeprom_write_byte((uint8_t *)adr_binary, 0); // сбрасываем бинарный счетчик
}
u8 p_ctr[4];
u8 p_old[4];
u32 *ctr_unary;
int ct_binary;
int set_hrs;
if (bit_is_clear(PINB, BUTTON_PSHIK))
goto M_PSHIK; //пшикаем и сбрасываем таймер
DDRB |= (1 << LED_pl) | (1 << LED_mn); //зажигаем светодиод
_delay_ms(10);
eeprom_read_block(p_ctr, (const void *)adr_unary,
4); // читаем унарный счетчик
memcpy(p_old, p_ctr, 4);
// u8 *ctr_unary = p_ctr;
ctr_unary = (u32 *)p_ctr;
*ctr_unary <<= 1; //инкремент унарный счетчик
if (*ctr_unary == 0)
{
*ctr_unary = 0xffffffff;
// *ctr_unary = 0xff;
/* */
ct_binary = eeprom_read_byte(
(const uint8_t *)adr_binary); // читаем бинарный счетчик
ct_binary++;
//здесь можем сравнить бинарный счетчик с чем-либо
set_hrs = eeprom_read_byte((const uint8_t *)adr_set_hrs);
if (set_hrs >= 5)
set_hrs = 0;
if (ct_binary == (set_hrs + 1) * 24)
// if(ct_binary == (set_hrs+1))
{
M_PSHIK:
ct_binary = 0; // сбрасываем бинарный счетчик
DDRB |= (1 << GATE);
PORTB |= (1 << GATE);
wdt_reset();
_delay_ms(500);
wdt_reset();
_delay_ms(500);
wdt_reset();
PORTB &= ~(1 << GATE);
DDRB &= ~(1 << GATE);
}
eeprom_write_byte((uint8_t *)adr_binary, ct_binary);
}
/* */
//------- пишем 4 байта унарного счетчика в EEPROM ----------------------
for (u8 i = 0; i < 4; i++)
{
if (p_old[i] != p_ctr[i]) //пишем только если байт измнился
{
while (EECR & (1 << EEPE))
; // Wait for completion of previous write
// Set Programming mode
// EECR = (0<<EEPM1)|(0>>EEPM0); //Erase-Write
if (p_ctr[i] == 0xff)
EECR = (0 << EEPM1) | (1 >> EEPM0); // Erase Only
else
EECR = (1 << EEPM1) | (0 >> EEPM0); // Write Only
EEARL = adr_unary + i; // ucAddress;
EEDR = p_ctr[i]; // ucData;
EECR |= (1 << EEMPE); // Write logical one to EEMWE
EECR |= (1 << EEPE); // Start eeprom write by setting EEWE
}
}
//-------------------------------------------------------------------------
DDRB &= ~((1 << LED_pl) | (1 << LED_mn)); //тушим светодиод
PORTB &= ~((1 << LED_pl) | (1 << LED_mn));
MCUCR |= (1 << SE) | (1 << SM1) | (0 << SM0); // power down
asm("sleep");
}
ну и варнинги поправил, а там да, пусть BOOM дальше думает))
1 лайк
vk007
17.Март.2024 21:32:42
32
Почти как у классиков же, пятница начинается в понедельник.
1 лайк
ага)
сижу репу чешу, вот почему ругается?
#include <avr/io.h>
int main(void)
{
for (byte r = 0; r < 255; r++)
{
for (byte g = 255; g > 0; g--)
{
for (byte b = 0; b < 255; b++)
{
if (analogRead(A0) > 250)
{
goto bailout;
}
// еще код
}
}
}
bailout:
}
а так нет
#include <avr/io.h>
int main(void)
{
for (byte r = 0; r < 255; r++)
{
for (byte g = 255; g > 0; g--)
{
for (byte b = 0; b < 255; b++)
{
if (analogRead(A0) > 250)
{
goto bailout;
}
// еще код
}
}
}
bailout: ;
}
я вижу Евгений не спит))
а тут как , ну не знаю #pragma какая нибудь поможет?
#include <Arduino.h>
void setup()
{
if (analogRead(A0) > 250)
{
goto bailout;
}
// еще код
int a = 0;
bailout: ;
}
void loop(){};
D:\1\Blink\Blink.ino: In function 'void setup()':
D:\1\Blink\Blink.ino:12:1: error: jump to label 'bailout' [-fpermissive]
bailout: ;
^~~~~~~
D:\1\Blink\Blink.ino:7:10: note: from here
goto bailout;
^~~~~~~
D:\1\Blink\Blink.ino:10:7: note: crosses initialization of 'int a'
int a = 0;
^
D:\1\Blink\Blink.ino:10:7: warning: unused variable 'a' [-Wunused-variable]
exit status 1
Compilation error: jump to label 'bailout' [-fpermissive]
xDriver:
вот почему ругается?
В языке нет меток как таковых. Есть помеченные операторы (labeled statements). Ругается, когда после метки не идёт никакой оператор. А если есть (пускай и пустой) то всё нормально.
Допускается несколько меток на один оператор. Например, вот так - нормально:
void setup(void)
{
for (byte r = 0; r < 255; r++)
{
for (byte g = 255; g > 0; g--)
{
for (byte b = 0; b < 255; b++)
{
if (analogRead(A0) > 250)
{
goto bailout1;
} else goto bailout2;
// еще код
}
}
}
bailout1:
bailout2:
;
}
void loop(void) {}
2 лайка
vk007
17.Март.2024 22:11:59
37
Это предупреждение, ведь переменная объявляется (инициализируется) между goto и меткой, поэтому может возникнуть ситуация, что программа перейдёт по goto, и объявление переменной окажется за бортом, т.е. возникает неоднозначность. Поэтому лучше вынести её объявление в другое место (раньше goto).
да это все понятно, не понятно почему старый добрый С тапк не думает, и почему С++ перестает так думать, стоит только “обрамить”
#include <Arduino.h>
void setup()
{
if (analogRead(A0) > 250)
{
goto bailout;
}
// еще код
{
int a = 0;
}
bailout:;
}
void loop(){};
vk007
17.Март.2024 22:24:57
39
После обрамления область видимости становится другой. Переменная уничтожится ещё до метки, поэтому повода для беспокойства компилятор не видит.
1 лайк
все, въехал, спасибо!
некогда просто не имел дело с goto, позновательно.
А с чего ему так думать, если в нём переменные объявляются всегда в начале функции/блока?
Может, потому, что никакая a в районе метки просто не существует?
vk007
17.Март.2024 22:38:51
42
xDriver:
не имел дело с goto
Это, наверное, потому что бейсик и фортран не приходилось учить
Я уже из того почти ничего не помню, но то что там без goto никуда - это факт.
1 лайк