1

Тема: attiny13

Основная статья - http://rcl-radio.ru/?p=98729

ЧАСЫ DS1307 + TM1637

http://forum.rcl-radio.ru/uploads/images/2021/04/c0a2d40655bbe6f337b25c737e2cae61.jpg

http://forum.rcl-radio.ru/uploads/images/2021/04/2dd754d39eb1fdb5401086fc5a2151eb.jpg


#define SDA 3 // PB3
#define SCL 4 // PB4
#define CLK 0 // PB0
#define DIO 1 // PB1


void setup() {
  //set_time(13,45,0);//  час 0-23, минуты 0-59, секунды 0-59
}
 

void loop() {
  byte min =  (ds_read(1) & 0x0F) + (((ds_read(1) & 0x70) >> 4) * 10);
  byte hour = (ds_read(2) & 0x0F) + (((ds_read(2) & 0x70) >> 4) * 10);
  
   print_time(hour *100 + min,0,7);
   delay(500);
   print_time(hour *100 + min,2,7);
   delay(500);           
}


void tm_dec(byte dig){
       for(int i = 0; i < 8; i++) {
         DDRB |= (1 << CLK);del();
       if (dig & 0x01)
         DDRB &= ~(1 << DIO);
       else
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         dig = dig >> 1;
  }
         DDRB |= (1 << CLK);
         DDRB &= ~(1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
 
       if (((PINB >> DIO) & 1) == 0)
         DDRB |= (1 << DIO);del();
         DDRB |= (1 << CLK);del();
  }  
 
void tm_stop(){
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         DDRB &= ~(1 << DIO);del();
  }  
 
void tm_start(){
         DDRB |= (1 << DIO);del();
  }
 
void print_time(int t, byte pd_t, int br){
        tm_start();tm_dec(0b10001000 + br);//tm_stop();tm_start();
        tm_dec(0x40);tm_stop();tm_start();
 
        int data0 = t / 1000;
        int data1 = t / 100 % 10;
        int data2 = t / 10 % 10;
        int data3 = t % 10;
 
      for(byte n = 0; n < 4; n++){
        int data;
      switch(n){
        case 0: data = data0;break;
        case 1: data = data1;break;
        case 2: data = data2;break;
        case 3: data = data3;break;
        }
 
      switch(data){    // XGFEDCBA
        case 0:  data = 0b00111111;break;     // 0
        case 1:  data = 0b00000110;break;     // 1
        case 2:  data = 0b01011011;break;     // 2
        case 3:  data = 0b01001111;break;     // 3
        case 4:  data = 0b01100110;break;     // 4
        case 5:  data = 0b01101101;break;     // 5
        case 6:  data = 0b01111101;break;     // 6
        case 7:  data = 0b00000111;break;     // 7
        case 8:  data = 0b01111111;break;     // 8
        case 9:  data = 0b01101111;break;     // 9
        case 10: data = 0b00000000;break;     // пусто
        case 11: data = 0b01000000;break;     // -
        }
 
        if(n == 0){data0 = data;}
        if(n == 1){data1 = data;}
        if(n == 2){data2 = data;}
        if(n == 3){data3 = data;}
        }
      if(pd_t==2){data1 = data1+0b10000000;}
      tm_dec(0xC0);tm_dec(data0);tm_dec(data1);tm_dec(data2);tm_dec(data3);tm_stop();
}  
 
void del(){delayMicroseconds(200);}

bool i2c_read_bit() {
    bool i2c_bit = 1;        
    DDRB &= ~(1 << SDA);            
    delayMicroseconds(10); 
    DDRB &= ~(1 << SCL);                
    if((PINB >> SDA) & 1) i2c_bit=0;                            
    delayMicroseconds(10);  
    DDRB |= (1 << SCL);              
    return i2c_bit;  
}
 
byte i2c_write_byte(byte data){
    for (byte i=0; i<8; i++){i2c_write_bit((data&0x80)==0);data<<=1;}    
    return i2c_read_bit(); 
}
 
byte i2c_read_byte(byte a){
    byte i, data=0;                
    for(i=0; i<8; i++){if (!i2c_read_bit()) data++;if(i!=7) data<<=1;}        
    i2c_write_bit(a);return data;  
}
 
void i2c_write_bit(byte b){
    delayMicroseconds(5);
    if(b){DDRB |= (1 << SDA);}else{DDRB &= ~(1 << SDA);}
    delayMicroseconds(5);
    DDRB &= ~(1 << SCL);       
    delayMicroseconds(10);
    DDRB |= (1 << SCL);
}
 
void i2c_start(){
     delayMicroseconds(10);  
     DDRB &= ~(1 << SDA); DDRB &= ~(1 << SCL); 
     delayMicroseconds(10); 
     DDRB |= (1 << SDA);  PORTB &= ~(1 << SDA);
     delayMicroseconds(10); 
     DDRB |= (1 << SCL);  PORTB &= ~(1 << SCL);   
     delayMicroseconds(10);
}
 
void i2c_stop()  {
     DDRB |= (1 << SDA);            
     delayMicroseconds(10);
     DDRB &= ~(1 << SCL);               
     delayMicroseconds(10); 
     DDRB &= ~(1 << SDA);             
}
 
byte ds_read(byte reg){
     byte data = 0;
     i2c_start();
     i2c_write_byte(0b11010000);
     i2c_write_byte(reg);
     i2c_start(); 
     i2c_write_byte(0b11010001); 
     data = i2c_read_byte(0);
     i2c_stop();
     return data;
  }
 
void ds_write(byte reg, byte data){
     i2c_start();
     i2c_write_byte(0b11010000);
     i2c_write_byte(reg);
     i2c_write_byte(data);
     i2c_stop();
  }  
 
void set_time(byte hours ,byte minute, byte second){
    ds_write(0x00,(second/10<<4)+second%10);
    ds_write(0x01,(minute/10<<4)+minute%10);
    ds_write(0x02,(hours/10<<4)+hours%10);

  }

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

2

Re: attiny13

ВОЛЬТМЕТР 5В

http://forum.rcl-radio.ru/uploads/images/2021/04/31a51c78e7f034e8a3c27c4b4c7cd16c.jpg


#define CLK 0 // PB0
#define DIO 1 // PB1
unsigned int u;

void setup() {
   ADMUX |= (1<<MUX1);// ADC2 (PB4) input
   ADCSRA |= (1<<ADEN) | (1<<ADSC) | (1<<ADATE) | (1<<ADIF);
   ADCSRA |= (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);// Division Factor 128
}
 

void loop() {
  while((ADCSRA & (1 << ADIF)) == 0);
   u = (ADCL|ADCH << 8);
   print_time(u*51/102,2,7);// 51=VCC 5.1V | 102 = 1023
   delay(500);           
}


void tm_dec(byte dig){
       for(int i = 0; i < 8; i++) {
         DDRB |= (1 << CLK);del();
       if (dig & 0x01)
         DDRB &= ~(1 << DIO);
       else
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         dig = dig >> 1;
  }
         DDRB |= (1 << CLK);
         DDRB &= ~(1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
 
       if (((PINB >> DIO) & 1) == 0)
         DDRB |= (1 << DIO);del();
         DDRB |= (1 << CLK);del();
  }  
 
void tm_stop(){
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         DDRB &= ~(1 << DIO);del();
  }  
 
void tm_start(){
         DDRB |= (1 << DIO);del();
  }
 
void print_time(int t, byte pd_t, int br){
        tm_start();tm_dec(0b10001000 + br);//tm_stop();tm_start();
        tm_dec(0x40);tm_stop();tm_start();
 
        int data0 = 10;
        int data1 = t / 100 % 10;
        int data2 = t / 10 % 10;
        int data3 = t % 10;
 
      for(byte n = 0; n < 4; n++){
        int data;
      switch(n){
        case 0: data = data0;break;
        case 1: data = data1;break;
        case 2: data = data2;break;
        case 3: data = data3;break;
        }
 
      switch(data){    // XGFEDCBA
        case 0:  data = 0b00111111;break;     // 0
        case 1:  data = 0b00000110;break;     // 1
        case 2:  data = 0b01011011;break;     // 2
        case 3:  data = 0b01001111;break;     // 3
        case 4:  data = 0b01100110;break;     // 4
        case 5:  data = 0b01101101;break;     // 5
        case 6:  data = 0b01111101;break;     // 6
        case 7:  data = 0b00000111;break;     // 7
        case 8:  data = 0b01111111;break;     // 8
        case 9:  data = 0b01101111;break;     // 9
        case 10: data = 0b00000000;break;     // пусто
        case 11: data = 0b01000000;break;     // -
        }
 
        if(n == 0){data0 = data;}
        if(n == 1){data1 = data;}
        if(n == 2){data2 = data;}
        if(n == 3){data3 = data;}
        }
      switch(pd_t){
        case 1 : data2 = data2+0b10000000;break;
        case 2 : data1 = data1+0b10000000;break;
        case 3 : data0 = data0+0b10000000;break;
        }
      tm_dec(0xC0);tm_dec(data0);tm_dec(data1);tm_dec(data2);tm_dec(data3);tm_stop();
}  
 
void del(){delayMicroseconds(200);}

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

ТОЖЕ САМОЕ

#define CLK 0 // PB0
#define DIO 1 // PB1
unsigned int u;

void setup() {
  
}
 

void loop() {
   u = analogRead(A2);
   print_time(u*51/102,2,7);// 51=VCC 5.1V | 102 = 1023
   delay(500);           
}


void tm_dec(byte dig){
       for(int i = 0; i < 8; i++) {
         DDRB |= (1 << CLK);del();
       if (dig & 0x01)
         DDRB &= ~(1 << DIO);
       else
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         dig = dig >> 1;
  }
         DDRB |= (1 << CLK);
         DDRB &= ~(1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
 
       if (((PINB >> DIO) & 1) == 0)
         DDRB |= (1 << DIO);del();
         DDRB |= (1 << CLK);del();
  }  
 
void tm_stop(){
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         DDRB &= ~(1 << DIO);del();
  }  
 
void tm_start(){
         DDRB |= (1 << DIO);del();
  }
 
void print_time(int t, byte pd_t, int br){
        tm_start();tm_dec(0b10001000 + br);//tm_stop();tm_start();
        tm_dec(0x40);tm_stop();tm_start();
 
        int data0 = 10;
        int data1 = t / 100 % 10;
        int data2 = t / 10 % 10;
        int data3 = t % 10;
 
      for(byte n = 0; n < 4; n++){
        int data;
      switch(n){
        case 0: data = data0;break;
        case 1: data = data1;break;
        case 2: data = data2;break;
        case 3: data = data3;break;
        }
 
      switch(data){    // XGFEDCBA
        case 0:  data = 0b00111111;break;     // 0
        case 1:  data = 0b00000110;break;     // 1
        case 2:  data = 0b01011011;break;     // 2
        case 3:  data = 0b01001111;break;     // 3
        case 4:  data = 0b01100110;break;     // 4
        case 5:  data = 0b01101101;break;     // 5
        case 6:  data = 0b01111101;break;     // 6
        case 7:  data = 0b00000111;break;     // 7
        case 8:  data = 0b01111111;break;     // 8
        case 9:  data = 0b01101111;break;     // 9
        case 10: data = 0b00000000;break;     // пусто
        case 11: data = 0b01000000;break;     // -
        }
 
        if(n == 0){data0 = data;}
        if(n == 1){data1 = data;}
        if(n == 2){data2 = data;}
        if(n == 3){data3 = data;}
        }
      switch(pd_t){
        case 1 : data2 = data2+0b10000000;break;
        case 2 : data1 = data1+0b10000000;break;
        case 3 : data0 = data0+0b10000000;break;
        }
      tm_dec(0xC0);tm_dec(data0);tm_dec(data1);tm_dec(data2);tm_dec(data3);tm_stop();
}  
 
void del(){delayMicroseconds(200);}

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

3

Re: attiny13

ИЗМЕРЕНИЕ НАПРЯЖЕНИЕ (ВНУТРЕННИЙ ОПОРНЫЙ ИСТОЧНИК 1.1 В)

#define CLK 0 // PB0
#define DIO 1 // PB1
unsigned int u;

void setup() {
   ADMUX |= (1<<MUX1) | (1<<REFS0);// Internal Voltage Reference ADC2 (PB4) input
   ADCSRA |= (1<<ADEN) | (1<<ADSC) | (1<<ADATE) | (1<<ADIF);
   ADCSRA |= (1<<ADPS2) | (1<<ADPS1) | (1<<ADPS0);// Division Factor 128
}
 

void loop() {
  while((ADCSRA & (1 << ADIF)) == 0);
   u = (ADCL|ADCH << 8);
   print_time(u*11/102,2,7);// 11=VCC 1.1V | 102 = 1023
   delay(500);           
}


void tm_dec(byte dig){
       for(int i = 0; i < 8; i++) {
         DDRB |= (1 << CLK);del();
       if (dig & 0x01)
         DDRB &= ~(1 << DIO);
       else
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         dig = dig >> 1;
  }
         DDRB |= (1 << CLK);
         DDRB &= ~(1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
 
       if (((PINB >> DIO) & 1) == 0)
         DDRB |= (1 << DIO);del();
         DDRB |= (1 << CLK);del();
  }  
 
void tm_stop(){
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         DDRB &= ~(1 << DIO);del();
  }  
 
void tm_start(){
         DDRB |= (1 << DIO);del();
  }
 
void print_time(int t, byte pd_t, int br){
        tm_start();tm_dec(0b10001000 + br);//tm_stop();tm_start();
        tm_dec(0x40);tm_stop();tm_start();
 
        int data0 = 10;
        int data1 = t / 100 % 10;
        int data2 = t / 10 % 10;
        int data3 = t % 10;
 
      for(byte n = 0; n < 4; n++){
        int data;
      switch(n){
        case 0: data = data0;break;
        case 1: data = data1;break;
        case 2: data = data2;break;
        case 3: data = data3;break;
        }
 
      switch(data){    // XGFEDCBA
        case 0:  data = 0b00111111;break;     // 0
        case 1:  data = 0b00000110;break;     // 1
        case 2:  data = 0b01011011;break;     // 2
        case 3:  data = 0b01001111;break;     // 3
        case 4:  data = 0b01100110;break;     // 4
        case 5:  data = 0b01101101;break;     // 5
        case 6:  data = 0b01111101;break;     // 6
        case 7:  data = 0b00000111;break;     // 7
        case 8:  data = 0b01111111;break;     // 8
        case 9:  data = 0b01101111;break;     // 9
        case 10: data = 0b00000000;break;     // пусто
        case 11: data = 0b01000000;break;     // -
        }
 
        if(n == 0){data0 = data;}
        if(n == 1){data1 = data;}
        if(n == 2){data2 = data;}
        if(n == 3){data3 = data;}
        }
      switch(pd_t){
        case 1 : data2 = data2+0b10000000;break;
        case 2 : data1 = data1+0b10000000;break;
        case 3 : data0 = data0+0b10000000;break;
        }
      tm_dec(0xC0);tm_dec(data0);tm_dec(data1);tm_dec(data2);tm_dec(data3);tm_stop();
}  
 
void del(){delayMicroseconds(200);}

4

Re: attiny13

ЦИФРОВОЙ ТЕРМОМЕТР DS18B20 + TM1637

http://forum.rcl-radio.ru/uploads/images/2021/04/96a82077df82db68dfdca4efef794b0d.jpg

#define CLK 0 // PB0
#define DIO 1 // PB1
#define OUT 4 // PB4


void setup() {

}
 

void loop() {
  if(read_temp()<0){print_time(abs(read_temp()),1,7,1);}
  else{print_time(read_temp(),1,7,0);}
  delay(500);           
}


void tm_dec(byte dig){
       for(int i = 0; i < 8; i++) {
         DDRB |= (1 << CLK);del();
       if (dig & 0x01)
         DDRB &= ~(1 << DIO);
       else
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         dig = dig >> 1;
  }
         DDRB |= (1 << CLK);
         DDRB &= ~(1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
 
       if (((PINB >> DIO) & 1) == 0)
         DDRB |= (1 << DIO);del();
         DDRB |= (1 << CLK);del();
  }  
 
void tm_stop(){
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         DDRB &= ~(1 << DIO);del();
  }  
 
void tm_start(){
         DDRB |= (1 << DIO);del();
  }
 
void print_time(int t, byte pd_t, int br,bool mn){
        tm_start();tm_dec(0b10001000 + br);//tm_stop();tm_start();
        tm_dec(0x40);tm_stop();tm_start();
 
        int data0;
        if(mn==1){data0 = 11;}
        else{data0 = 10;}
        int data1 = t / 100 % 10;
        int data2 = t / 10 % 10;
        int data3 = t % 10;
 
      for(byte n = 0; n < 4; n++){
        int data;
      switch(n){
        case 0: data = data0;break;
        case 1: data = data1;break;
        case 2: data = data2;break;
        case 3: data = data3;break;
        }
 
      switch(data){    // XGFEDCBA
        case 0:  data = 0b00111111;break;     // 0
        case 1:  data = 0b00000110;break;     // 1
        case 2:  data = 0b01011011;break;     // 2
        case 3:  data = 0b01001111;break;     // 3
        case 4:  data = 0b01100110;break;     // 4
        case 5:  data = 0b01101101;break;     // 5
        case 6:  data = 0b01111101;break;     // 6
        case 7:  data = 0b00000111;break;     // 7
        case 8:  data = 0b01111111;break;     // 8
        case 9:  data = 0b01101111;break;     // 9
        case 10: data = 0b00000000;break;     // пусто
        case 11: data = 0b01000000;break;     // -
        }
 
        if(n == 0){data0 = data;}
        if(n == 1){data1 = data;}
        if(n == 2){data2 = data;}
        if(n == 3){data3 = data;}
        }
      switch(pd_t){
        case 1 : data2 = data2+0b10000000;break;
        case 2 : data1 = data1+0b10000000;break;
        case 3 : data0 = data0+0b10000000;break;
        }
      tm_dec(0xC0);tm_dec(data0);tm_dec(data1);tm_dec(data2);tm_dec(data3);tm_stop();
}  
 
void del(){delayMicroseconds(200);}

/////////////////////

// reset
uint8_t therm_reset(){
    uint8_t i;
    PORTB &= ~(1 << OUT);
    DDRB |= (1 << OUT);
    delayMicroseconds(480);  
    DDRB &= ~(1 << OUT);
    delayMicroseconds(60);
    i=((PINB >> OUT) & 1);
    delayMicroseconds(420);
    return i;
}
// write bit
void therm_write_bit(uint8_t bit){
    PORTB &= ~(1 << OUT);
    DDRB |= (1 << OUT);
    delayMicroseconds(1);
    if(bit) DDRB &= ~(1 << OUT);
    delayMicroseconds(60);
    DDRB &= ~(1 << OUT);
}
// read bit
uint8_t therm_read_bit(void){
    uint8_t bit=0;
    PORTB &= ~(1 << OUT);
    DDRB |= (1 << OUT);
    delayMicroseconds(1);
    DDRB &= ~(1 << OUT);
    delayMicroseconds(14);
    if(PINB & (1 << OUT)) bit=1;
    delayMicroseconds(45);
    return bit;
}
 
// read byte
uint8_t therm_read_byte(void){
    uint8_t i=8, n=0;
    while(i--){n>>=1;n|=(therm_read_bit()<<7);}
    return n;
}
 
// write byte
void therm_write_byte(uint8_t byte){
    uint8_t i=8;
    while(i--){therm_write_bit(byte&1);byte >>= 1;
    }
}
// read temp
int read_temp(){
    uint8_t temperature[2];
    float temper;
    therm_reset();
    therm_write_byte(0xCC);
    therm_write_byte(0x44);
    while(!therm_read_bit());
    therm_reset();
    therm_write_byte(0xCC);
    therm_write_byte(0xBE);
    temperature[0]=therm_read_byte();
    temperature[1]=therm_read_byte();
    therm_reset();
    temper = (temperature[1] << 8 | temperature[0])*10/16;
    return (int)temper;
}

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

5

Re: attiny13

Добрый день !
liman324,не могли бы Вы выложить схему, по которой собирали ЧАСЫ DS1307 + TM1637.

6

Re: attiny13

http://forum.rcl-radio.ru/uploads/images/2022/10/a4d54af24d871704843881912b6294ba.png

7 (2022-10-29 08:34:35 отредактировано korsar)

Re: attiny13

liman324, в скетче соответствие портов противоположное.

#define SDA 3 // PB3
#define SCL 4 // PB4
#define CLK 0 // PB0
#define DIO 1 // PB1


void setup() {
  //set_time(13,45,0);//  час 0-23, минуты 0-59, секунды 0-59
}

Где ошибка?

P.S. В данном проекте не предусмотрена настройка времен  с кнопок.
Возможно ли это реализовать ?

8

Re: attiny13

Я поправил схему.

P.S. В данном проекте не предусмотрена настройка времен  с кнопок.
Возможно ли это реализовать ?

Свободен PB2 это аналоговый вход ADC1, можно повесить делитель напряжения и подключить две кнопки - часы и минуты.

http://forum.rcl-radio.ru/uploads/images/2022/10/60b5d6496dd2eed1478105c1d5c830a5.png

9

Re: attiny13

Ok!
Если честно, в написании скетчей я профан!
Не подскажите, какие нужны изменения в программе, чтоб заработали кнопки?

10

Re: attiny13

Не получается запихнуть код кнопок, места не хватает.

11 (2023-02-28 16:35:13 отредактировано klause)

Re: attiny13

korsar пишет:

Ok!
Если честно, в написании скетчей я профан!
Не подскажите, какие нужны изменения в программе, чтоб заработали кнопки?

На мой взгляд можно подключить одну кнопку. Лучше поменять  DS1307 на ds3231.
я попробывал так сделать. вот кусочек кода.
#define SDA 3 // PB3
#define SCL 4 // PB4
#define CLK 0 // PB0
#define DIO 1 // PB1
#define BUT 2 // PB2
void setup() {
// set_time(13,45,0);//  час 0-23, минуты 0-59, секунды 0-59
  PORTB |= (1 << BUT);

}


void loop() {
  byte min =  (ds_read(1) & 0x0F) + (((ds_read(1) & 0x70) >> 4) * 10);
  byte hour = (ds_read(2) & 0x0F) + (((ds_read(2) & 0x70) >> 4) * 10);
 
   print_time(hour *100 + min,0,7);
   delay(500);
   print_time(hour *100 + min,2,7);
   delay(500);
   
if(((PINB >> BUT) & 1) == 0){
   set_time(12,0,0);
}

}

Настроить часы в 12.00 или в то время, которое самому удобное,изменив значение.
Скорректировать секунды тоже можно в это же время, если часы "убежали".

12 (2023-11-08 16:42:27 отредактировано klause)

Re: attiny13

Интересно, хватить ли места для кнопок? Немного уменьшил скетч.

#define SDA 3 // PB3
#define SCL 4 // PB4
#define CLK 1 // PB0
#define DIO 0 // PB1
#define BUT 2 // PB2
byte min;
byte hour;
byte tochka;// разделительная точка часов и минут

void setup() {
  //set_time(13,45,0);//  час 0-23, минуты 0-59, секунды 0-59
   
}
 

void loop() {
  min =  (ds_read(1) & 0x0F) + (((ds_read(1) & 0x70) >> 4) * 10);
  hour = (ds_read(2) & 0x0F) + (((ds_read(2) & 0x70) >> 4) * 10);
   tochka=0x80;
   print_time();
   delay(500);
   tochka=0x00;
   print_time();
   delay(500);
       
}


void tm_dec(byte dig){
       for(int i = 0; i < 8; i++) {
         DDRB |= (1 << CLK);del();
       if (dig & 0x01)
         DDRB &= ~(1 << DIO);
       else
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         dig = dig >> 1;
  }
         DDRB |= (1 << CLK);
         DDRB &= ~(1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
 
       if (((PINB >> DIO) & 1) == 0)
         DDRB |= (1 << DIO);del();
         DDRB |= (1 << CLK);del();
  }  
 
void tm_stop(){
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         DDRB &= ~(1 << DIO);del();
  }  
 
void tm_start(){
         DDRB |= (1 << DIO);del();
  }
 
void print_time(){
        tm_start();tm_dec(0b10001000 + 7);//tm_stop();tm_start();
        tm_dec(0x40);tm_stop();tm_start();
 
     int  data0 = (hour / 10) % 10;
     int  data1 = hour % 10;
     int  data2 = (min / 10) % 10;
     int  data3 = min % 10;
     if(data0 == 0)data0=10;//гашение нуля.
 
      for(byte n = 0; n < 4; n++){
        int data;
      switch(n){
        case 0: data = data0;break;
        case 1: data = data1;break;
        case 2: data = data2;break;
        case 3: data = data3;break;
        }
 
      switch(data){    // XGFEDCBA
        case 0:  data = 0b00111111;break;     // 0
        case 1:  data = 0b00000110;break;     // 1
        case 2:  data = 0b01011011;break;     // 2
        case 3:  data = 0b01001111;break;     // 3
        case 4:  data = 0b01100110;break;     // 4
        case 5:  data = 0b01101101;break;     // 5
        case 6:  data = 0b01111101;break;     // 6
        case 7:  data = 0b00000111;break;     // 7
        case 8:  data = 0b01111111;break;     // 8
        case 9:  data = 0b01101111;break;     // 9
        case 10: data = 0b00000000;break;     // пусто
        
        }
 
        if(n == 0){data0 = data;}
        if(n == 1){data1 = data;}
        if(n == 2){data2 = data;}
        if(n == 3){data3 = data;}
        }
     
      tm_dec(0xC0);tm_dec(data0);tm_dec(data1+tochka);tm_dec(data2);tm_dec(data3);tm_stop();
}  
 
void del(){delayMicroseconds(200);}

bool i2c_read_bit() {
    bool i2c_bit = 1;        
    DDRB &= ~(1 << SDA);            
    delayMicroseconds(10); 
    DDRB &= ~(1 << SCL);                
    if((PINB >> SDA) & 1) i2c_bit=0;                            
    delayMicroseconds(10);  
    DDRB |= (1 << SCL);              
    return i2c_bit;  
}
 
byte i2c_write_byte(byte data){
    for (byte i=0; i<8; i++){i2c_write_bit((data&0x80)==0);data<<=1;}    
    return i2c_read_bit(); 
}
 
byte i2c_read_byte(byte a){
    byte i, data=0;                
    for(i=0; i<8; i++){if (!i2c_read_bit()) data++;if(i!=7) data<<=1;}        
    i2c_write_bit(a);return data;  
}
 
void i2c_write_bit(byte b){
    delayMicroseconds(5);
    if(b){DDRB |= (1 << SDA);}else{DDRB &= ~(1 << SDA);}
    delayMicroseconds(5);
    DDRB &= ~(1 << SCL);       
    delayMicroseconds(10);
    DDRB |= (1 << SCL);
}
 
void i2c_start(){
     delayMicroseconds(10);  
     DDRB &= ~(1 << SDA); DDRB &= ~(1 << SCL); 
     delayMicroseconds(10); 
     DDRB |= (1 << SDA);  PORTB &= ~(1 << SDA);
     delayMicroseconds(10); 
     DDRB |= (1 << SCL);  PORTB &= ~(1 << SCL);   
     delayMicroseconds(10);
}
 
void i2c_stop()  {
     DDRB |= (1 << SDA);            
     delayMicroseconds(10);
     DDRB &= ~(1 << SCL);               
     delayMicroseconds(10); 
     DDRB &= ~(1 << SDA);             
}
 
byte ds_read(byte reg){
     byte data = 0;
     i2c_start();
     i2c_write_byte(0b11010000);
     i2c_write_byte(reg);
     i2c_start(); 
     i2c_write_byte(0b11010001); 
     data = i2c_read_byte(0);
     i2c_stop();
     return data;
  }
 
void ds_write(byte reg, byte data){
     i2c_start();
     i2c_write_byte(0b11010000);
     i2c_write_byte(reg);
     i2c_write_byte(data);
     i2c_stop();
  }  
 
void set_time(byte hours ,byte minute, byte second){
    ds_write(0x00,(second/10<<4)+second%10);
    ds_write(0x01,(minute/10<<4)+minute%10);
    ds_write(0x02,(hours/10<<4)+hours%10);

  }

У меня скетч занимает 82%. Внимание. MicroCore v.2.2.1. В версии 2.3.0 скетч не вмещается!!!.

13

Re: attiny13

Кнопку надо переделать
Примерно так
http://forum.rcl-radio.ru/uploads/images/2023/10/19c59b935ba22fc15796b706fad2d2a5.png

Сопротивления надо высчитывать

Коррекция часов условие > значение ADC больше 300 но меньше 600
Коррекция минут условие > значение ADC больше 600
При условии, что 5 В на входе равно 1023

В железе не тестировал

#define SDA 3 // PB3
#define SCL 4 // PB4
#define CLK 1 // PB0
#define DIO 0 // PB1

byte min;
byte hour;
byte tochka;// разделительная точка часов и минут
int u;

void setup() {
  //set_time(13,45,0);//  час 0-23, минуты 0-59, секунды 0-59
    ADCSRA = 0b10000100; 
}
 

void loop() {
  ADMUX = 0b00000001; // input A1 (PB2)
  do{ADCSRA |= (1 << ADSC);}
   while ((ADCSRA & (1 << ADIF)) == 0);
    u = (ADCL|ADCH << 8);

  if(u>300 || u < 600){set_time(hour++,min,0);}
  if(u>600){set_time(hour,min++,0);}  
  
  min =  (ds_read(1) & 0x0F) + (((ds_read(1) & 0x70) >> 4) * 10);
  hour = (ds_read(2) & 0x0F) + (((ds_read(2) & 0x70) >> 4) * 10);
 
   tochka=0x80;
   print_time();
   delay(500);
   tochka=0x00;
   print_time();
   delay(500);
       
}


void tm_dec(byte dig){
       for(int i = 0; i < 8; i++) {
         DDRB |= (1 << CLK);del();
       if (dig & 0x01)
         DDRB &= ~(1 << DIO);
       else
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         dig = dig >> 1;
  }
         DDRB |= (1 << CLK);
         DDRB &= ~(1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
 
       if (((PINB >> DIO) & 1) == 0)
         DDRB |= (1 << DIO);del();
         DDRB |= (1 << CLK);del();
  }  
 
void tm_stop(){
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         DDRB &= ~(1 << DIO);del();
  }  
 
void tm_start(){
         DDRB |= (1 << DIO);del();
  }
 
void print_time(){
        tm_start();tm_dec(0b10001000 + 7);//tm_stop();tm_start();
        tm_dec(0x40);tm_stop();tm_start();
 
     int  data0 = (hour / 10) % 10;
     int  data1 = hour % 10;
     int  data2 = (min / 10) % 10;
     int  data3 = min % 10;
     if(data0 == 0)data0=10;//гашение нуля.
 
      for(byte n = 0; n < 4; n++){
        int data;
      switch(n){
        case 0: data = data0;break;
        case 1: data = data1;break;
        case 2: data = data2;break;
        case 3: data = data3;break;
        }
 
      switch(data){    // XGFEDCBA
        case 0:  data = 0b00111111;break;     // 0
        case 1:  data = 0b00000110;break;     // 1
        case 2:  data = 0b01011011;break;     // 2
        case 3:  data = 0b01001111;break;     // 3
        case 4:  data = 0b01100110;break;     // 4
        case 5:  data = 0b01101101;break;     // 5
        case 6:  data = 0b01111101;break;     // 6
        case 7:  data = 0b00000111;break;     // 7
        case 8:  data = 0b01111111;break;     // 8
        case 9:  data = 0b01101111;break;     // 9
        case 10: data = 0b00000000;break;     // пусто
        
        }
 
        if(n == 0){data0 = data;}
        if(n == 1){data1 = data;}
        if(n == 2){data2 = data;}
        if(n == 3){data3 = data;}
        }
     
      tm_dec(0xC0);tm_dec(data0);tm_dec(data1+tochka);tm_dec(data2);tm_dec(data3);tm_stop();
}  
 
void del(){delayMicroseconds(200);}

bool i2c_read_bit() {
    bool i2c_bit = 1;        
    DDRB &= ~(1 << SDA);            
    delayMicroseconds(10); 
    DDRB &= ~(1 << SCL);                
    if((PINB >> SDA) & 1) i2c_bit=0;                            
    delayMicroseconds(10);  
    DDRB |= (1 << SCL);              
    return i2c_bit;  
}
 
byte i2c_write_byte(byte data){
    for (byte i=0; i<8; i++){i2c_write_bit((data&0x80)==0);data<<=1;}    
    return i2c_read_bit(); 
}
 
byte i2c_read_byte(byte a){
    byte i, data=0;                
    for(i=0; i<8; i++){if (!i2c_read_bit()) data++;if(i!=7) data<<=1;}        
    i2c_write_bit(a);return data;  
}
 
void i2c_write_bit(byte b){
    delayMicroseconds(5);
    if(b){DDRB |= (1 << SDA);}else{DDRB &= ~(1 << SDA);}
    delayMicroseconds(5);
    DDRB &= ~(1 << SCL);       
    delayMicroseconds(10);
    DDRB |= (1 << SCL);
}
 
void i2c_start(){
     delayMicroseconds(10);  
     DDRB &= ~(1 << SDA); DDRB &= ~(1 << SCL); 
     delayMicroseconds(10); 
     DDRB |= (1 << SDA);  PORTB &= ~(1 << SDA);
     delayMicroseconds(10); 
     DDRB |= (1 << SCL);  PORTB &= ~(1 << SCL);   
     delayMicroseconds(10);
}
 
void i2c_stop()  {
     DDRB |= (1 << SDA);            
     delayMicroseconds(10);
     DDRB &= ~(1 << SCL);               
     delayMicroseconds(10); 
     DDRB &= ~(1 << SDA);             
}
 
byte ds_read(byte reg){
     byte data = 0;
     i2c_start();
     i2c_write_byte(0b11010000);
     i2c_write_byte(reg);
     i2c_start(); 
     i2c_write_byte(0b11010001); 
     data = i2c_read_byte(0);
     i2c_stop();
     return data;
  }
 
void ds_write(byte reg, byte data){
     i2c_start();
     i2c_write_byte(0b11010000);
     i2c_write_byte(reg);
     i2c_write_byte(data);
     i2c_stop();
  }  
 
void set_time(byte hours ,byte minute, byte second){
    ds_write(0x00,(second/10<<4)+second%10);
    ds_write(0x01,(minute/10<<4)+minute%10);
    ds_write(0x02,(hours/10<<4)+hours%10);
  }

14 (2023-10-24 20:34:32 отредактировано Karl2233)

Re: attiny13

Коррекция часов условие > значение ADC больше 300 но меньше 600
Коррекция минут условие > значение ADC больше 600
При условии, что 5 В на входе равно 1023

>600 = 4,7к...5,6к
300...<600 = 8,2к

15 (2023-11-27 15:03:10 отредактировано klause)

Re: attiny13

Спасибо за помощь. 3 варианта подключения кнопок.

  #define SDA 3 // PB3
 #define SCL 4 // PB4
  #define TM1637_DIO_HIGH() (PORTB |= _BV(TM1637_DIO_PIN))
  #define TM1637_DIO_LOW() (PORTB &= ~_BV(TM1637_DIO_PIN))
  #define TM1637_DIO_OUTPUT() (DDRB |= _BV(TM1637_DIO_PIN))
  #define TM1637_DIO_INPUT() (DDRB &= ~_BV(TM1637_DIO_PIN))
  #define TM1637_DIO_READ() (((PINB & _BV(TM1637_DIO_PIN)) > 0) ? 1 : 0)
  #define TM1637_CLK_HIGH() (PORTB |= _BV(TM1637_CLK_PIN))
  #define TM1637_CLK_LOW() (PORTB &= ~_BV(TM1637_CLK_PIN))  
  #define TM1637_DIO_PIN  PB0
  #define TM1637_CLK_PIN  PB1 
  byte _config = 0x08 | 7;
  byte _segments = 0xff;
 byte min;
 byte hour;
// byte second;
 int u;
  PROGMEM const byte _digit2segments[] =
  {
  0x3F, // 0
  0x06, // 1
  0x5B, // 2
  0x4F, // 3
  0x66, // 4
  0x6D, // 5
  0x7D, // 6
  0x07, // 7
  0x7F, // 8
  0x6F // 9
  };
  
  void setup() { 
 
} 
  void loop() {
 u = analogRead(A1);
 
 if (u>690&&u<700){ //подгон минут
    min++;
    if(min>=60)min=0;
    ds_write(0x01,(min/10<<4)+min%10);
     }
           
  if(u>605&&u<615){ // подгон часов
    hour++;
    if(hour>23)hour=0;
    ds_write(0x02,(hour/10<<4)+hour%10);    
    }
    
  //  if(u>565&&u<575){ // обнуление секунд
   //  second=0;
  // ds_write(0x00,(second/10<<4)+second%10); }
       
  min =  (ds_read(1) & 0x0F) + (((ds_read(1) & 0x70) >> 4) * 10);
  hour = (ds_read(2) & 0x0F) + (((ds_read(2) & 0x70) >> 4) * 10);
  TM1637_init(1/*включить*/, 7/*яркость*/);
  TM1637_display_digit(3, min %10);
  TM1637_display_digit(2, min /10);
  TM1637_display_digit(1, hour %10);
  if(hour<10)TM1637_display_segments(0,0);// гашение нуля
  else TM1637_display_digit(0, hour/10);
  TM1637_display_colon(1);
    //delay(200);
  TM1637_display_colon(0);
    //delay(200);
  
  }

  bool i2c_read_bit() {
    bool i2c_bit = 1;        
    DDRB &= ~(1 << SDA);            
    delayMicroseconds(10); 
    DDRB &= ~(1 << SCL);                
    if((PINB >> SDA) & 1) i2c_bit=0;                            
    delayMicroseconds(10);  
    DDRB |= (1 << SCL);              
    return i2c_bit;  
}
 
byte i2c_write_byte(byte data){
    for (byte i=0; i<8; i++){i2c_write_bit((data&0x80)==0);data<<=1;}    
    return i2c_read_bit(); 
}
 
byte i2c_read_byte(byte a){
    byte i, data=0;                
    for(i=0; i<8; i++){if (!i2c_read_bit()) data++;if(i!=7) data<<=1;}        
    i2c_write_bit(a);return data;  
}
 
void i2c_write_bit(byte b){
    delayMicroseconds(5);
    if(b){DDRB |= (1 << SDA);}else{DDRB &= ~(1 << SDA);}
    delayMicroseconds(5);
    DDRB &= ~(1 << SCL);       
    delayMicroseconds(10);
    DDRB |= (1 << SCL);
}
 
void i2c_start(){
     delayMicroseconds(10);  
     DDRB &= ~(1 << SDA); DDRB &= ~(1 << SCL); 
     delayMicroseconds(10); 
     DDRB |= (1 << SDA);  PORTB &= ~(1 << SDA);
     delayMicroseconds(10); 
     DDRB |= (1 << SCL);  PORTB &= ~(1 << SCL);   
     delayMicroseconds(10);
}
 
void i2c_stop()  {
     DDRB |= (1 << SDA);            
     delayMicroseconds(10);
     DDRB &= ~(1 << SCL);               
     delayMicroseconds(10); 
     DDRB &= ~(1 << SDA);             
}
 
byte ds_read(byte reg){
     byte data = 0;
     i2c_start();
     i2c_write_byte(0b11010000);
     i2c_write_byte(reg);
     i2c_start(); 
     i2c_write_byte(0b11010001); 
     data = i2c_read_byte(0);
     i2c_stop();
     return data;
  }
 
void ds_write(byte reg, byte data){
     i2c_start();
     i2c_write_byte(0b11010000);
     i2c_write_byte(reg);
     i2c_write_byte(data);
     i2c_stop();
  }  
/* 
void set_time(byte hours ,byte minute, byte second){
    ds_write(0x00,(second/10<<4)+second%10);
    ds_write(0x01,(minute/10<<4)+minute%10);
    ds_write(0x02,(hours/10<<4)+hours%10);
 }
 */
// библиотека tm1637
 void delay1sec(void)
   {    
  asm volatile (
    "    ldi  r18, 6"  "\n"
    "    ldi  r19, 19"  "\n"
    "    ldi  r20, 174" "\n"
    "1:  dec  r20"  "\n"
    "    brne 1b" "\n"
    "    dec  r19"  "\n"
    "    brne 1b" "\n"
    "    dec  r18"  "\n"
    "    brne 1b" "\n"
    "    rjmp 1f" "\n"
    "1:"  "\n"
       );
}
  // Инициализация дисплея
  void TM1637_init(byte enable, byte brightness)
  { 
  DDRB |= (_BV(TM1637_DIO_PIN)|_BV(TM1637_CLK_PIN));
  PORTB &= ~(_BV(TM1637_DIO_PIN)|_BV(TM1637_CLK_PIN));
  TM1637_send_config(enable, brightness);
  }
  // включение дисплея
  void TM1637_enable(byte value) {
    TM1637_send_config(value, _config & 7);
  }
  // яркость от 0 до 7
  void TM1637_set_brightness(byte value){
  TM1637_send_config(_config & 0x08, value & 7);
  }
  // По сегментамБ например,'H', segments=0b01110110
  void TM1637_display_segments(byte position,byte segments){  
  TM1637_send_command(0x40 | 0x04);
  TM1637_start();
  TM1637_write_byte(0xC0 | (position & 3));
  TM1637_write_byte(segments);
  TM1637_stop();
  }
  // По цифрам от 0 до 9
  void TM1637_display_digit(byte position, byte digit){
  uint8_t segments = (digit < 10 ? pgm_read_byte_near((byte *)&_digit2segments + digit) : 0x00);
   if (position == 0x01) {
  segments = segments | (_segments & 0x80);
  _segments = segments;
  }
   TM1637_display_segments(position, segments);
  }
  // Разделительные точки  1 - on, 0 - off
  void TM1637_display_colon(byte value){
  if (value) {
  _segments |= 0x80;
  } else {
  _segments &= ~0x80;
  }
  TM1637_display_segments(0x01, _segments);
  }
 
  void TM1637_send_config(byte enable,byte brightness)
  { 
  _config = (enable ? 0x08 : 0x00) |
  (brightness > 7 ? 7 : brightness); 
  TM1637_send_command(0x80 | _config);
  }
  
  void TM1637_send_command(byte value){
  TM1637_start();
  TM1637_write_byte(value);
  TM1637_stop();
  }
  
  void TM1637_start() { 
  TM1637_DIO_HIGH();
  TM1637_CLK_HIGH();
   // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm"  "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  TM1637_DIO_LOW();
  }
  
  void TM1637_stop() { 
  TM1637_CLK_LOW();
     // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm"  "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  TM1637_DIO_LOW();
     // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm"  "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  TM1637_CLK_HIGH();
    // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm" "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  TM1637_DIO_HIGH();
  }
  
  byte TM1637_write_byte(byte value) {
  byte i, ack;  
  for (i = 0; i < 8; ++i, value >>= 1) {
  TM1637_CLK_LOW();
     // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm"  "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  if (value & 0x01) {
  TM1637_DIO_HIGH();
  } else {
  TM1637_DIO_LOW();
  } 
  TM1637_CLK_HIGH(); 
     // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm"  "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  }
  
  TM1637_CLK_LOW();
  TM1637_DIO_INPUT();
  TM1637_DIO_HIGH(); 
   // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm"  "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  ack = TM1637_DIO_READ();
  if (ack) {
  TM1637_DIO_OUTPUT();
  TM1637_DIO_LOW();
  }
    // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm" "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  TM1637_CLK_HIGH();
    // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm" "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  TM1637_CLK_LOW();
   // Delay 5 cycles, 5us at 1 MHz
        asm volatile (
            "    lpm"  "\n"
            "    rjmp 1f" "\n"
            "1:"  "\n"
         );
  TM1637_DIO_OUTPUT();
  return ack;
  } 

http://forum.rcl-radio.ru/uploads/images/2023/11/a16b53c03b3a21c8db62d47d822c9bee.bmp
Очень медленно корректируется время. Лучше взять кнопки с фиксацией в этом варианте.
2 вариант.
http://forum.rcl-radio.ru/uploads/images/2023/11/5f922c17974d89ac6143fd964aaf52db.bmp
3 вариант. В железе не опробовано. Pin reset установлен как пин входа-выхода.
http://forum.rcl-radio.ru/uploads/images/2023/11/079b812c402ccfaf7dff6ef8e37f06f8.bmp
Файлы + исходник Attiny13 TM1637 от польского товарища.
Данный контент доступен только зарегистрированным пользователям. Данный контент доступен только зарегистрированным пользователям. Данный контент доступен только зарегистрированным пользователям. Данный контент доступен только зарегистрированным пользователям.

16 (2023-11-13 15:53:10 отредактировано klause)

Re: attiny13

термометр dht11&tm1637. Код опроса датчика был взят из и-нета.

#define CLK 1 // PB0
#define DIO 0 // PB1
#define DHT PB4 // +подключить внешнюю подтяжку.
byte _hum, _temp;// переменные для влажности и температуры
void setup() {  

}

void loop() {
dht_read(&_hum, &_temp);// опроса датчика
 delay(3000);
  print_time(_hum,0,7,0);
  delay(3000);
  print_time(_temp,0,7,1);
 
}

// общая функция опроса датчика
  byte dht_read(byte *hum, byte* temp) {
  byte data[5];// массив под данные датчика
  byte error=dht_start();// стартуем и получаем код ошибки в переменную

  if (error) return error; // если есть ошибки выходим с кодом ошибки
  
  // получаем 5 байт от датчика
  for (byte i=0; i<5; i++)
  {
    data[i]=dht_byte();
  }
  
  if (data[0]+data[1]+data[2]+data[3]!=data[4]) return 1; // если контрольная сумма не сошлась вернем ошибку 
  
  *hum=data[0];// пишем данные влажности 
  *temp=data[2];// пишем данные температуры 
  return 0;// вернем 0 - ошибок нет.
}
// функция передачи условия "старт" на линию и проверка ответов от датчика.
 byte  dht_start(){
  DDRB|=(1<<DHT);// притянули линию к земле - 0
  _delay_ms(20);// пауза 20 мс 
  DDRB&=~(1<<DHT);// отпустили линию - 1
  _delay_us(40);// ждем 40 мкс чтобы попасть в середину низкого сигнала
  if (PINB&(1<<DHT)) return 1; // если на линии 1 ошибка - "датчик не ответил"
  _delay_us(80); // ждем 80 мкс чтобы попасть в середину высокого сигнала
  if (!(PINB&(1<<DHT))) return 1; // если на линии 0 ошибка - "датчик не готов "
  while(PINB&(1<<DHT));// ждем пока датчик не притянет линию к земле.
  return 0;// ошибок нет
}
// получение байта от датчика
byte dht_byte(){
  byte i=8, byte=0;// переменная для цикла и под байт
  while(i--){
    while(!(PINB&(1<<DHT)));// ждем пока линия не поднимится в 1
    _delay_us(40);// отступаем 40 мкс
    if (PINB&(1<<DHT)) {// если на линии 1 = приняли 1
      byte|=(1<<i);// поднимаем итый бит в 1
      while(PINB&(1<<DHT));// ждем пока линия упадет в 0
    }
  }
  return byte;// возвращаем полученный байт
}
void tm_dec(byte dig){
       for(int i = 0; i < 8; i++) {
         DDRB |= (1 << CLK);del();
       if (dig & 0x01)
         DDRB &= ~(1 << DIO);
       else
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         dig = dig >> 1;
  }
         DDRB |= (1 << CLK);
         DDRB &= ~(1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
 
       if (((PINB >> DIO) & 1) == 0)
         DDRB |= (1 << DIO);del();
         DDRB |= (1 << CLK);del();
  }  
 
void tm_stop(){
         DDRB |= (1 << DIO);del();
         DDRB &= ~(1 << CLK);del();
         DDRB &= ~(1 << DIO);del();
  }  
 
void tm_start(){
         DDRB |= (1 << DIO);del();
  }
 
void print_time(int t, byte pd_t, int br, bool mn){
        tm_start();tm_dec(0b10001000 + br); tm_stop();tm_start();
        tm_dec(0x40);tm_stop();tm_start();
 
     int data0;
        if(mn == 1){data0 = 11;}else{data0 = 12;}
        int data1 = 10;
        int data2 = t / 10 % 10;
        int data3 = t % 10;
 
      for(byte n = 0; n < 4; n++){
        int data;
      switch(n){
        case 0: data = data0;break;
        case 1: data = data1;break;
        case 2: data = data2;break;
        case 3: data = data3;break;
        }
 
      switch(data){    // XGFEDCBA
        case 0:  data = 0b00111111;break;     // 0
        case 1:  data = 0b00000110;break;     // 1
        case 2:  data = 0b01011011;break;     // 2
        case 3:  data = 0b01001111;break;     // 3
        case 4:  data = 0b01100110;break;     // 4
        case 5:  data = 0b01101101;break;     // 5
        case 6:  data = 0b01111101;break;     // 6
        case 7:  data = 0b00000111;break;     // 7
        case 8:  data = 0b01111111;break;     // 8
        case 9:  data = 0b01101111;break;     // 9
        case 10: data = 0b00000000;break;     // пусто
        case 11: data = 0b01111000;break;     // t
        case 12: data = 0b01110110;break;     // H
        }
 
        if(n == 0){data0 = data;}
        if(n == 1){data1 = data;}
        if(n == 2){data2 = data;}
        if(n == 3){data3 = data;}
        }
      switch(pd_t){
        case 1 : data2 = data2+0b10000000;break;
        case 2 : data1 = data1+0b10000000;break;
        case 3 : data0 = data0+0b10000000;break;
        }
      tm_dec(0xC0);tm_dec(data0);tm_dec(data1);tm_dec(data2);tm_dec(data3);tm_stop();
}  
 
void del(){delayMicroseconds(200);}

Интересно,что скетч в версии 2.3.0. занимает 97%. В версии 2.2.1 занимает 73%.
Похожий проект. Частота чипа 1.2Мгц.Данный контент доступен только зарегистрированным пользователям.

17

Re: attiny13

Термометр dht11 + max7219.

#define MAX7219_DIN PB2 // нога1
#define MAX7219_CS  PB1 // нога12
#define MAX7219_CLK PB0 // нога13
#include <SimpleDHT.h>
int pinDHT11 = PB4; // датчик
SimpleDHT11 dh11;
byte DisplayNumtoSeg[] = {126,48, 109, 121, 51, 91, 95, 112, 127, 123};
void setup() {
digitalWrite(MAX7219_CS, HIGH);
 pinMode(MAX7219_DIN, OUTPUT);
 pinMode(MAX7219_CS, OUTPUT);
 pinMode(MAX7219_CLK, OUTPUT);
  output(0x0f, 0x00); //тест выкл
  output(0x0c, 0x01); // спящий режим
  output(0x0b, 0x04); // количествов знакомест
  output(0x0a, 0x0f); //яркость
  output(0x09, 0x00); // включен режим декодирования
  
}

void loop() {
 byte temperature = 0;
  byte humidity = 0;
 if (dh11.read(pinDHT11, &temperature, &humidity, NULL)) {   
    return; }  
  byte data0 = DisplayNumtoSeg[temperature / 10 % 10];
  byte data1= DisplayNumtoSeg[temperature % 10];
  byte data2 = DisplayNumtoSeg[humidity / 10 % 10];
  byte data3 = DisplayNumtoSeg[humidity % 10];
  output(0x01,data0);
  output(0x02,data1);
  output(0x03,0b01100011);
  output(0x04,0b01001110);
  delay(3000);
  output(0x01,data2);
  output(0x02,data3); 
  output(0x03,0b00110111);
  output(0x04,0b00011100);
  delay(3000);
}

 void output(byte address, byte data)
{
 digitalWrite(MAX7219_CS, LOW);
 shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, address);
 shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, data);
 digitalWrite(MAX7219_CS, HIGH);
}
 

Данный контент доступен только зарегистрированным пользователям.
Программа декодирования MAX7219
Данный контент доступен только зарегистрированным пользователям.

18 (2023-12-04 17:40:13 отредактировано klause)

Re: attiny13

Попробывал подсоединить dht22. MAX7219 индикатор самодельный.

#define MAX7219_DIN PB0 // нога1
#define MAX7219_CS  PB1 // нога12
#define MAX7219_CLK PB2 // нога13
#define DHT22_PIN PB4
byte c=0,temperature_hi, temperature_lo, humidity_hi, humidity_lo, dig1,dig2,dig3,dig4,dig5,dig6,temporary, check_sum;
int temperature_result, humidity_result;
byte DisplayNumtoSeg[] = {126,48, 109, 121, 51, 91, 95, 112, 127, 123};
void setup() {
 digitalWrite(MAX7219_CS, HIGH);
 pinMode(MAX7219_DIN, OUTPUT);
 pinMode(MAX7219_CS, OUTPUT);
 pinMode(MAX7219_CLK, OUTPUT);
  output(0x0f, 0x00); //тест выкл
  output(0x0c, 0x01); // спящий режим
  output(0x0b, 0x07); // количествов знакомест
  output(0x0a, 0x0f); //яркость
  output(0x09, 0x00); // включен режим декодирования
  for(byte i=0;i<9;i++){  
  output(i, 0); } 
  for(byte i=0;i<9;i++){  
  output(i, 1);
   delay(500);}
   delay(2000); 
   
}

void loop() {
request();    /* стартовый импульс */
response();
humidity_lo=receive_data(); /* целое число влажности */
humidity_hi=receive_data();  /* дробное число влажности */
temperature_lo=receive_data(); /* целое число температуры */
temperature_hi=receive_data();  /* дробное число температуры */
check_sum=receive_data(); /* контрольная сумма */
humidity_result = (humidity_lo * 256 + humidity_hi );
if(temperature_lo > 127){ //
 temperature_result = (temperature_lo-128)* 256+ temperature_hi;
output(0x01,1);
if((temperature_result / 100)>0){ // если ниже -10 гр
dig1 = DisplayNumtoSeg [temperature_result / 100];  
temporary = temperature_result % 100;   
dig2 = DisplayNumtoSeg[temporary / 10]|128;
dig3 = DisplayNumtoSeg[temporary % 10];
output(0x02,dig1);
output(0x03,dig2);
output(0x04,dig3);}
else{
temporary = temperature_result % 100; // между 0 и -10гр.         
dig2 = DisplayNumtoSeg[temporary / 10]|128;
dig3 = DisplayNumtoSeg[temporary % 10];
output(0x02,dig2);
output(0x03,dig3);
output(0x04,99);}  
dig1 = DisplayNumtoSeg [temperature_result / 100];
temporary = temperature_result % 100;           
dig2 = DisplayNumtoSeg[temporary / 10]|128;
dig3 = DisplayNumtoSeg[temporary % 10];
output(0x02,dig2);
output(0x03,dig3);
output(0x04,99);}  
else{
temperature_result = (temperature_lo * 256 + temperature_hi ); // выше 0          
  if (temperature_result / 100==0)dig1=0;
 else{dig1 = DisplayNumtoSeg [temperature_result / 100];};         
 temporary = temperature_result % 100; 
 dig2 = DisplayNumtoSeg[temporary / 10]|128;
 dig3 = DisplayNumtoSeg[temporary % 10];  
  output(0x01,dig1);
  output(0x02,dig2);
  output(0x03,dig3);
  output(0x04,99);}   
      
dig4 =DisplayNumtoSeg [humidity_result / 100];
temporary = humidity_result % 100; 
dig5 =DisplayNumtoSeg[ temporary / 10]|128;
dig6 =DisplayNumtoSeg[ temporary % 10];  
  output(0x05,dig4);
  output(0x06,dig5);
  output(0x07,dig6);
  output(0x08,55);
  delay(2000);  
}

void output(byte address, byte data)
{
 digitalWrite(MAX7219_CS, LOW);
 shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, address);
 shiftOut(MAX7219_DIN, MAX7219_CLK, MSBFIRST, data);
 digitalWrite(MAX7219_CS, HIGH);
}
void request()  {
  
  DDRB |= (1<<DHT22_PIN);
  PORTB &= ~(1<<DHT22_PIN);    /* set to low pin */
  delay(20);            /* wait for 20ms */
  PORTB |= (1<<DHT22_PIN); /* set to high pin */

}

void response() {
  
  DDRB &= ~(1<<DHT22_PIN);
  while(PINB & (1<<DHT22_PIN));
  while((PINB & (1<<DHT22_PIN))==0);
  while(PINB & (1<<DHT22_PIN));
}

uint8_t receive_data() {  
  int q;
  for (q=0; q<8; q++) {
    while((PINB & (1<<DHT22_PIN)) == 0);  /* check received bit 0 or 1 */
    delayMicroseconds(30);
    if(PINB & (1<<DHT22_PIN))/* if high pulse is greater than 30ms */
    c = (c<<1)|(0x01);  /* then its logic HIGH */
    else      /* otherwise its logic LOW */
    c = (c<<1);
    while(PINB & (1<<DHT22_PIN));
  }
  return c;
}
//int get_checksum() {  
//  return humidity_lo + humidity_hi + temperature_lo +  temperature_hi;}

http://forum.rcl-radio.ru/uploads/images/2023/12/3c335ef57b54f2c94a10dbe762f2bbc0.jpg http://forum.rcl-radio.ru/uploads/images/2023/12/ae3bd9c7bea732294b66d9abf376dd91.jpg http://forum.rcl-radio.ru/uploads/images/2023/12/2e52f74463e42b1ea2ca26edab0b131f.jpg http://forum.rcl-radio.ru/uploads/images/2023/12/6e6b225ddcd3a93d5c52f739b5fd20b6.jpg http://forum.rcl-radio.ru/uploads/images/2023/12/d5caef0c53166063931e9f78dc426f1d.jpg

19 (2023-12-02 14:44:45 отредактировано Karl2233)

Re: attiny13

http://forum.rcl-radio.ru/uploads/images/2023/12/da9511c40712b26a467393ec6e3027a8.jpg
Вопрос по устройству на. Attiny13.
Нужен вот такой функционал:
1. Вкл-выкл с кнопки и с пульта(с возможностью прописать кнопку пульта).
2. Режим MUTE с пульта(с возможностью прописать код кнопки).
3. Переключение двух входов с одной кнопки пульта (с возможностью прописать код кнопки).

Схему накидал.

Уважаемый liman324, есть возможность помочь с таким?

20

Re: attiny13

Вот код для ардуино:

bool data[96],st,st1,raz;
uint32_t cod;
byte i1,i2,s;
 
void setup() {
  Serial.begin(9600);
  DDRB &= ~(1 << 0);
   cli(); 
  TCCR1A = 0;   
  TCCR1B = 0;   
  OCR1A = 9000; // 562.5 mks
  TCCR1B |= (1 << WGM12); 
  TCCR1B |= (1 << CS10);  
  TIMSK1 |= (1 << OCIE1A);  
   sei(); 
}
 
void loop() {
if(raz==1){  Serial.println(IR(),HEX);}
delay(200);
}
 
uint32_t IR(){
 delay(150);
 cod=0;i2=0;
 for(int a=0;a<96;a++){
   if(data[a] + data[a+2] == 2){cod += ((uint32_t)0 << 31-i2);i2++;a=a+1;}
   if(data[a] + data[a+2] == 1){cod += ((uint32_t)1 << 31-i2);i2++;a=a+3;}}
 raz=0;
 TCCR1B |= (1 << CS10);OCR1A = 3200;//5000 Hz
 if(cod==1||cod>0x7FFFFFFF){cod=0xFFFFFFFF;}
 return cod;}
 
ISR(TIMER1_COMPA_vect){
     if(((PINB >> 0) & 1)==0&&st==0&&raz==0){st=1;OCR1A = 9000;}
     if(st==1){s++;}
     if(s>20&&((PINB >> 0) & 1)==0){st1=1;}   
     if(st1==1){data[i1]=((PINB >> 0) & 1);i1++;} 
     if(i1>96){i1=0;s=0;st=0;raz=1;st1=0;TCCR1B &= ~(1 << CS10); }
     }

Вывод кода в монитор порта

http://forum.rcl-radio.ru/uploads/images/2023/12/8ad3161ef9c53bc9b8a047be85944266.png

21

Re: attiny13

Но все это не будет работать на attny13, не хватит места, нужно как то уменьшить код, например считывать пакет кода не расшифровывая его.

22 (2023-12-02 16:59:31 отредактировано Karl2233)

Re: attiny13

liman324 пишет:

Но все это не будет работать на attny13, не хватит места, нужно как то уменьшить код, например считывать пакет кода не расшифровывая его.

Ардуину жалко на это.
Правильно ли я понимаю: если считать код кнопок и потом вписать в скетч, тогда возможно этот функционал в Ат13 впихнуть?
Или убрать переключение входов?

23

Re: attiny13

Для ардуино код упростил как мог, если поправить под Attiny13 должно получится.

http://forum.rcl-radio.ru/uploads/images/2023/12/d303cdee5e7fd4a28b141c833fdee985.png


Считывает только 2 последних байта кода кнопок ,без обработки, они как раз на пульте всегда разные.

Загрузите, посмотрите в мониторе порта коды кнопок Вашего пульта, если все работает, то можно адаптировать под attiny13

bool st,st1,raz,dat;
uint32_t cod;
unsigned long data;
byte i1,i2,s,n;
 
void setup() {
  Serial.begin(9600);
  DDRB &= ~(1 << 0);
   cli(); 
  TCCR1A = 0;   
  TCCR1B = 0;   
  OCR1A = 9000; // 562.5 mks
  TCCR1B |= (1 << WGM12); 
  TCCR1B |= (1 << CS10);  
  TIMSK1 |= (1 << OCIE1A);  
   sei(); 
}
 
void loop() {
if(raz==1){Serial.println(IR(),HEX);}
// тут пишем условие, если IR()=0x7755, то сделать что то.
delay(200);
}
 
uint32_t IR(){
 delay(150);
 cod=0;i2=0;
 raz=0;
 TCCR1B |= (1 << CS10);OCR1A = 3200;//5000 Hz
 cod=data & 0xFFFF;data=0;
 return cod;}
 
ISR(TIMER1_COMPA_vect){
     if(((PINB >> 0) & 1)==0&&st==0&&raz==0){st=1;OCR1A = 9000;}
     if(st==1){s++;}
     if(s>20&&((PINB >> 0) & 1)==0){st1=1;}   
     if(st1==1){ dat = ((PINB >> 0) & 1);  if(i1>64){data+=(dat<<n);n++;}i1++;} 
     if(i1>96){i1=0;n=0;s=0;st=0;raz=1;st1=0;TCCR1B &= ~(1 << CS10);}
     }

24

Re: attiny13

Предварительно без настройки таймера attiny13

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

bool st,st1,raz,dat;
uint32_t cod;
unsigned long data;
byte i1,i2,s,n;
 
void setup() {
  
  DDRB &= ~(1 << 0);
   cli(); 
  TCCR0A = 0;   
  TCCR0B = 0;   
  OCR0A = 9000; // 562.5 mks
  TCCR0B |= (1 << WGM02); 
  TCCR0B |= (1 << CS00);  
  TIMSK0 |= (1 << OCIE0A);  
   sei(); 
}
 
void loop() {
if(raz==1){IR();}
// тут пишем условие, если IR()=0x7755, то сделать что то.
delay(200);
}
 
uint32_t IR(){
 delay(150);
 cod=0;i2=0;
 raz=0;
 TCCR0B |= (1 << CS00);OCR0A = 3200;//5000 Hz
 cod=data & 0xFFFF;data=0;
 return cod;}
 
ISR(TIMER1_COMPA_vect){
     if(((PINB >> 0) & 1)==0&&st==0&&raz==0){st=1;OCR0A = 9000;}
     if(st==1){s++;}
     if(s>20&&((PINB >> 0) & 1)==0){st1=1;}   
     if(st1==1){ dat = ((PINB >> 0) & 1);  if(i1>64){data+=(dat<<n);n++;}i1++;} 
     if(i1>96){i1=0;n=0;s=0;st=0;raz=1;st1=0;TCCR0B &= ~(1 << CS00);}
     }

25

Re: attiny13

Правильно ли я понял: надо скетч из сообщения 23 загрузить в Ардуино? И надо проверить что в монитр порта попадает при использовании пульта?
Верно?
А на какой пин цеплять IR датчик?