Подскажите новичку что сделал не так при прошивке Тиньки13

да нет, конечно сам goto я использовал, уж в Басике то точно, как Си начал изучать, постулат не прикасаться к goto, засел с самого начала :smile:

2 лайка

“вам не нравятся кошки…да вы их готовить не умеете”

Благодарю всех!
Вынес объявления переменных, которые были между goto METKA и самой МЕТКОЙ и “заколосилось” )))

Пшик
/*
  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) {

  int ct_binary;
  int set_hrs;
  u32 *ctr_unary;
  u8 p_ctr[4];
  u8 p_old[4];

  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);

  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");
}

Скетч использует 596 байт (58%) памяти устройства. Всего доступно 1024 байт.
Глобальные переменные используют 0 байт (0%) динамической памяти, оставляя 64 байт для локальных переменных. Максимум: 64 байт.

MicroCore

Может быть еще Warnings потом победю:

Warnings

\test1.ino: In function ‘int main()’:
\test1.ino:26:32: warning: pointer of type 'void ’ used in arithmetic [-Wpointer-arith]
#define adr_binary adr_set_hrs + 1
\test1.ino:27:19: note: in expansion of macro ‘adr_binary’
#define adr_unary adr_binary + 1
^~~~~~~~~~
\test1.ino:86:41: note: in expansion of macro ‘adr_unary’
eeprom_read_block(p_ctr, (const void
)adr_unary, 4); // читаем унарный счетчик
^~~~~~~~~
\test1.ino:27:30: warning: pointer of type 'void ’ used in arithmetic [-Wpointer-arith]
#define adr_unary adr_binary + 1
\test1.ino:86:41: note: in expansion of macro ‘adr_unary’
eeprom_read_block(p_ctr, (const void
)adr_unary, 4); // читаем унарный счетчик

В фортране-то? Да, ладно, тоже мне факт!

Без goto там всё пишется легко и непринуждённо. Арифметический if покрывает функциональность goto “как бык овцу”

А это не шуточные предупреждения. Смотря что там у Вас означают эти adr_binary и др. При некоторых условиях это может быть тяжёлой ошибкой.

1 лайк

я жешь в #30 написал, что все для тебя сделал))

О как )))
Я как-то пропустил… ((

Ну и всё, считай спустя два года всё для ТС сделали ))))

Обновил ядро MicroCore для Attiny13 до версии 2.3.0.
Все скетчи стали компилироваться по занимаемому месту на 16 байт меньше.
Не знаю что там автор “подкрутил”, но если кто использует MicroCore - рекомендую обновиться.

Не прошло и года…
MicroCore v2.3.0 Apr 13, 2023

Так я же не разработчик в “Корпорации ЗЛА” ))))
Понадобилось - обновился. ))

1 лайк

в теме про тиньку 13 было и другое ядро, под ним скетч компилировался по размеру в два раза меньше

Вопрос давно назрел, всё забывал спросить.
Автор вот так “управляет лапами”:

Но то, что я вижу в комментарии не соответствует тому что написано в коде. Он просто меняет направление порта ввода-выводаю Правильнее ведь вот так:

PORTB |= (1 << LED_pl); //зажигаем светодиод от кнопки
//...
PORTB &= ~(1 << LED_pl); //тушим светодиод

Или я чего-то не понимаю? о_0

Отчего же не соответствует?

  • Светодиод зажигается?
  • Зажигается,
  • Гаснет?
  • Гаснет.

Значит, комментарии вполне соответствуют тому, что происходит.
Просто зажечь или погасить светодиод можно более чем одним способом.

Соберем полную коллекцию,?

и даже так
PINB |= (1 << LED_pl);

:smiley:

Вопрос снят.

А зря. Тут есть много интересных нюансов.
Например, в AVR напрямую отсутствует режим работы выхода “с открытым коллектором”, а переключение пина на вход позволяет эмулировать такое поведение.

Тащить из тебя клещами мне не хочется, а сам ты, видимо, рассказывать не хочешь.

че там рассказывать)
пин с внешней подтяжкой к плюсу логики, например для работы с логикой 1.8 или 3.3 вольт.
делаешь его выходом и записываешь 0 - соответствует низкому уровню на линии.
делаешь его входом - соответствует высокому уровню на линии.
вот и вся эмуляция OpenDrain

я не знаю, че там еще выдумать можно.

1 лайк

Спасибо!