ATtiny45 Arduino IDE

ATtiny45 — низкопотребляющий 8 битный КМОП микроконтроллер с AVR RISC архитектурой. Выполняя команды за один цикл, ATtiny45 достигает производительности 1 MIPS при частоте задающего генератора 1 МГц, что позволяет разработчику оптимизировать отношение потребления к производительности.

Характеристики:

  • Высокопроизводительный, экономичный 8-разр. AVR-микроконтроллер
  • Усовершенствованная RISC-архитектура
    — Обширный набор из 120 инструкций большинство которых выполняются за один цикл
    — 32 x 8 универсальных регистров общего назначения
    — Полностью статическая работа
  • Энергонезависимые памяти программ и данных
    — Внутрисистемно программируемая флэш-память программ размером 4 кбайт с износостойкостью 10 тыс. циклов запись/стирание
    — 256 байт внутрисистемно-программируемого ЭСППЗУ с износостойкостью 100 тыс. циклов записи/стирания
    — 256 байт внутреннего статического ОЗУ
    — Программируемые биты защиты флэш-памяти и ЭСППЗУ
  • Отличительные особенности периферийных устройств
    — 8-разр. таймер-счетчик с предделителем и двумя каналами ШИМ
    — 8-разр. высокоскоростной таймер-счетчик с отдельным предварительным делителем 2 высокочастотных выхода ШИМ с отдельными регистрами задания порога сравнения
  • Программируемый генератор паузы
    — Универсальный последовательный интерфейс с отдельным детектором условия старт
    — 10-разр. АЦП
  • 4 несимметричных канала
  • 2 дифференциальных канала с программируемым усилением (1x, 20x)
    — Программируемый сторожевой таймер с отдельным встроенным генератором
    — Встроенный аналоговый компаратор
  • Специальные функции микроконтроллера
    — Встроенная отладочная система debugWIRE
    — Внутрисистемное программирование через порт SPI
    — Внешние и внутренние источники прерываний
    — Экономичные режимы: холостой ход (Idle), уменьшение шумов АЦП (ADC Noise Reduction) и пониженная мощность (Power-down)
    — Усовершенствованная схема сброса при подаче питания
    — Программируемая схема контроля напряжения питания
    — Встроенный калиброванный генератор
  • Ввод-вывод и корпуса
    — Шесть программируемых линий ввода-вывода
    — 8-выв. корпус PDIP и 8-выв. SOIC
  • Рабочее напряжение
    — 1.8 — 5.5В для ATtiny45V
    — 2.7 — 5.5В для ATtiny45
  • Градации по быстродействию
    — ATtiny45V: 0 — 4 МГц при 1.8 — 5.5В, 0 — 10 МГц при 2.7 — 5.5В
    — ATtiny45: 0 — 10 МГц при 2.7 — 5.5В, 0 — 20 МГц при 4.5 — 5.5В
  • Малый потребляемый ток
    — Активный режим: 1 МГц, 1.8В: 450 мкА
    — Режим пониженной мощности: 0.1 мкА при 1.8В

Микроконтроллер ATtiny45 отлично подходит для маленьких и дешевых проектов, а поддержка средой программирования Arduino IDE заметно упрощает работу с микроконтроллером.

Для поддержки ATtiny45 в Arduino IDE необходимо выполнить несколько простых операций:

  • Добавление поддержки платы

Откройте в Arduino IDE вкладку Файл > Настройки и добавьте ссылку для менеджера плат

https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json

Далее перейдите во вкладку Инструменты > Плата > Менеджер плат

Выберите и установите пакет новых плат ATtiny45, ATtiny85, ATtiny44, ATtiny84

Далее в Инструменты > Плата выберите плату ATtiny45.

Установите параметры платы как показано на скриншоте:

  • Для прошивки скетча  Вам понадобится программатор USBAsp

Схема подключения

Распиновка программатора USBAsp

Для удобства использования и прошивки микроконтроллера ATtiny45 можно воспользоваться отладочной платой HW-260.

В настройках платы нужно выбрать поддержку Attiny45 и установить частоту  8 MHz internal, остальные параметры менять не нужно. Далее необходимо выставить нужные фьюзы для микроконтроллера, чтобы он всегда работал на выбранной Вами частоте. Для этого в настройках Arduino IDE выберите программатор USBasb и нажмите Инструменты > Записать загрузчик. Эту операцию необходимо проводить всего один и снова повторить если Вы будете менять частоту работы микроконтроллера.

Для загрузки скетча в настройках Arduino IDE выберите программатор USBasb и во вкладке Скетч нажмите на Загрузить через программатор (или просто нажать кнопку — Загрузить)

Для примера, можно загрузить простой скетч мигания светодиода, к выводу 3 (PB4) контроллера подключите светодиод через резистор 200 Ом.

void setup() {
  pinMode(4, OUTPUT);
}
 
void loop() {
  digitalWrite(4, HIGH);  
  delay(1000);                     
  digitalWrite(4, LOW);   
  delay(1000);                    
}

После загрузки скетча, светодиод начнет мигать.

Для нормальной работы микроконтроллера необходимо подать напряжение VCC через резистор 10 кОм на вход RST микроконтроллера.


Примеры использования 

 

LCD1602_I2C (Программный I2C)

#define ADDR    0x27
#define SDA 3 // PB3
#define SCL 4 // PB4
#define RS      0
#define E       2
#define LED     3
 
byte led_b,h[8];
 
void setup() {
    i2c_write(led_b |= (1<<LED));// включаем подсветку
    lcdInit();
}
 
void loop() {
   lcdCurs(0,3);
   lcdString("ATtiny_45");
   lcdCurs(1,3);
   lcdLong(1234567890);  
}
 
void lcdSend(bool rs, byte data) {
    if(rs==0){led_b |= (1<<RS);} else {led_b &= ~(1<<RS);}//RS
 
    del();
    if(((data >> 7) & 1) ==1){i2c_write(led_b |= (1<<7));} else {i2c_write(led_b &= ~(1<<7));}
    if(((data >> 6) & 1) ==1){i2c_write(led_b |= (1<<6));} else {i2c_write(led_b &= ~(1<<6));}
    if(((data >> 5) & 1) ==1){i2c_write(led_b |= (1<<5));} else {i2c_write(led_b &= ~(1<<5));}
    if(((data >> 4) & 1) ==1){i2c_write(led_b |= (1<<4));} else {i2c_write(led_b &= ~(1<<4));}
    e_pin();
    if(((data >> 3) & 1) ==1){i2c_write(led_b |= (1<<7));} else {i2c_write(led_b &= ~(1<<7));}
    if(((data >> 2) & 1) ==1){i2c_write(led_b |= (1<<6));} else {i2c_write(led_b &= ~(1<<6));}
    if(((data >> 1) & 1) ==1){i2c_write(led_b |= (1<<5));} else {i2c_write(led_b &= ~(1<<5));}
    if(((data >> 0) & 1) ==1){i2c_write(led_b |= (1<<4));} else {i2c_write(led_b &= ~(1<<4));}
    e_pin();
}
 
void lcdInit(){ 
    del();
    lcd(0x03);delayMicroseconds(4500);
    lcd(0x03);delayMicroseconds(4500);
    lcd(0x03);delayMicroseconds(200);
 
    lcd(0b00000010);del();
    lcd(0b00001100);del();
    lcdClear();
  } 
 
void lcdClear(){lcd(0b00000001);} 
void lcd(uint8_t cmd) {lcdSend(true, cmd);}
void lcdChar(const char chr) {lcdSend(false, (uint8_t)chr);}
void lcdString(const char* str) {while(*str != '\0') {del();lcdChar(*str);str++;}}
void del(){delayMicroseconds(1000);}
void e_pin(){i2c_write(led_b |= (1<<E));del();i2c_write(led_b &= ~(1<<E));}
 
 
void lcdCurs(byte str, byte mesto){
  if(str==0){lcd(0b10000000+mesto);}
  if(str==1){lcd(0b11000000+mesto);}
  }  
 
void lcdLong(long int_x){
   byte h[8];
   long int_y=int_x;
   int i,i_kol;
  if(int_x<0){int_x=abs(int_x);lcdChar('-');}    // если минус
  for(i_kol=0;int_x>0;i_kol++){int_x=int_x/10;}  // определяем кол-во цифр в long
  for(i=0;i<i_kol;i++){h[i]=int_y%10; int_y=int_y/10;}// разбиваем число на отдельные цифры
  for(i=i_kol-1;i>=0;i--){lcdChar(h[i] +'0');} // преобразуем числа в char
  if(i_kol==0){lcdChar('0');} // если long = 0, то выводить ноль
  }  
 
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(); 
}
 
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);             
}
 
void i2c_write(byte lcd){
     i2c_start();
     i2c_write_byte(ADDR<<1);
     i2c_write_byte(lcd);
     i2c_stop();
  }

Скетч использует 1040 байт (25%) памяти устройства. Всего доступно 4096 байт.
Глобальные переменные используют 20 байт (7%) динамической памяти, оставляя 236 байт для локальных переменных. Максимум: 256 байт.

 

ЧАСЫ ATTINY45+DS3231 С КНОПКАМИ КОРРЕКЦИИ ВРЕМЕНИ

#define ADDR    0x27
#define ADDR_T  0x68
#define SDA 3 // PB3
#define SCL 4 // PB4
#define SET 0 // PB0
#define UP  1 // PB1
#define DW  2 // PB2
#define RS      0
#define E       2
#define LED     3
 
byte led_b,init_t;
int seting,tic;
int hh,mm,ss,dd,mon,yy;
 
 
 
void setup() {
    lcdInit();
    i2c_write(led_b |= (1<<LED));// включаем подсветку
    /// set_time(22,3,9,4,9,54,0);// год 00-99, ДН 1-7 (1=ВС), месяц 1-12, дата 1-31, час 0-23, минуты 0-59, секунды 0-59
    PORTB |= (1 << UP) | (1 << DW) | (1 << SET);
    delay(500);
}
 
void loop() {
   byte sec =  (ds_read(0) & 0x0F) + (((ds_read(0) & 0x70) >> 4) * 10);
   byte min =  (ds_read(1) & 0x0F) + (((ds_read(1) & 0x70) >> 4) * 10);
   byte hour = ((ds_read(2) & 0x0F) + ((ds_read(2) & 0x70) >> 4) * 10);
   byte datat = ((ds_read(4) & 0x0F) + ((ds_read(4) & 0x70) >> 4) * 10);
   byte mont = ((ds_read(5) & 0x0F) + ((ds_read(5) & 0x70) >> 4) * 10);
   byte year = ((ds_read(6) & 0x0F) + ((ds_read(6) & 0x70) >> 4) * 10);
   hh=hour;mm=min;ss=sec;dd=datat;mon=mont;yy=year;
   if(((PINB >> SET) & 1) == 0){seting++;if(seting>6){seting=0;}}   
 
   if(seting>0){tic++;if(tic>1){tic=0;}}
 
   if(seting>0){
    if(((PINB >> UP) & 1) == 0){
     switch(seting){
      case 1:  hh++;if(hh>23){hh=23;}break;
      case 2:  mm++;if(mm>59){mm=59;}break;
      case 3:  ss=0;break;
      case 4:  dd++;if(dd>31){dd=31;}break;
      case 5:  mon++;if(mon>12){mon=12;}break;
      case 6:  yy++;if(yy>50){yy=50;}break;
      }
    set_time(yy,0,mon,dd,hh,mm,ss);  
    }
    if(((PINB >> DW) & 1) == 0){
     switch(seting){
      case 1:  hh--;if(hh<0){hh=0;}break;
      case 2:  mm--;if(mm<0){mm=0;}break;
      case 3:  ss=0;break;
      case 4:  dd--;if(dd<1){dd=1;}break;
      case 5:  mon--;if(mon<1){mon=1;}break;
      case 6:  yy--;if(yy<22){yy=22;}break;
      }
    set_time(yy,0,mon,dd,hh,mm,ss);  
    }  
    }
 
   lcdCurs(0,4);
   lcdChar(hour/10+'0');lcdChar(hour%10+'0');
   if(seting==1&&tic==1){lcdCurs(0,4);lcdChar(160);lcdChar(160);}lcdChar(58);
   lcdChar(min/10+'0');lcdChar(min%10+'0');
   if(seting==2&&tic==1){lcdCurs(0,7);lcdChar(160);lcdChar(160);}lcdChar(58);
   lcdChar(sec/10+'0');lcdChar(sec%10+'0');
   if(seting==3&&tic==1){lcdCurs(0,10);lcdChar(160);lcdChar(160);}
   lcdCurs(1,4); 
   lcdChar(datat/10+'0');lcdChar(datat%10+'0');
   if(seting==4&&tic==1){lcdCurs(1,4);lcdChar(160);lcdChar(160);}lcdChar(45);
   lcdChar(mont/10+'0');lcdChar(mont%10+'0');
   if(seting==5&&tic==1){lcdCurs(1,7);lcdChar(160);lcdChar(160);}lcdChar(45);
   lcdChar(year/10+'0');lcdChar(year%10+'0');
   if(seting==6&&tic==1){lcdCurs(1,10);lcdChar(160);lcdChar(160);}
   delay(200);
}
 
void lcdSend(bool rs, byte data) {
    if(rs==0){led_b |= (1<<RS);} else {led_b &= ~(1<<RS);}//RS
 
    delay(1);
    if(((data >> 7) & 1) ==1){i2c_write(led_b |= (1<<7));} else {i2c_write(led_b &= ~(1<<7));}
    if(((data >> 6) & 1) ==1){i2c_write(led_b |= (1<<6));} else {i2c_write(led_b &= ~(1<<6));}
    if(((data >> 5) & 1) ==1){i2c_write(led_b |= (1<<5));} else {i2c_write(led_b &= ~(1<<5));}
    if(((data >> 4) & 1) ==1){i2c_write(led_b |= (1<<4));} else {i2c_write(led_b &= ~(1<<4));}
    e_pin();
    if(((data >> 3) & 1) ==1){i2c_write(led_b |= (1<<7));} else {i2c_write(led_b &= ~(1<<7));}
    if(((data >> 2) & 1) ==1){i2c_write(led_b |= (1<<6));} else {i2c_write(led_b &= ~(1<<6));}
    if(((data >> 1) & 1) ==1){i2c_write(led_b |= (1<<5));} else {i2c_write(led_b &= ~(1<<5));}
    if(((data >> 0) & 1) ==1){i2c_write(led_b |= (1<<4));} else {i2c_write(led_b &= ~(1<<4));}
    e_pin();
}
 
void lcdInit(){ 
    lcd(0x03);delay(5);
    lcd(0x03);delay(5);
    lcd(0x03);delayMicroseconds(200);
    lcd(0b00000010);delay(5);
    lcd(0b00001100);delay(5);
    lcdClear();
  } 
 
void lcdClear(){lcd(0b00000001);} 
void lcd(uint8_t sett) {lcdSend(true, sett);}
void lcdChar(const char chr) {lcdSend(false, (uint8_t)chr);}
void e_pin(){i2c_write(led_b |= (1<<E));delay(1);i2c_write(led_b &= ~(1<<E));}
 
 
void lcdCurs(byte str, byte mesto){
  if(str==0){lcd(0b10000000+mesto);}
  if(str==1){lcd(0b11000000+mesto);}
  }  
 
 
///// i2c /////////////
 
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(){
     DDRB &= ~(1 << SDA); DDRB &= ~(1 << SCL);
     DDRB |= (1 << SDA);  PORTB &= ~(1 << SDA);
     DDRB |= (1 << SCL);  PORTB &= ~(1 << SCL);
}
 
void i2c_stop()  {
     DDRB |= (1 << SDA);           
     DDRB &= ~(1 << SCL);            
     DDRB &= ~(1 << SDA);           
}
 
void i2c_write(byte lcd){
     i2c_start();
     i2c_write_byte(ADDR<<1);
     i2c_write_byte(lcd);
     i2c_stop();
  }   
 
void ds_write(byte reg, byte data){
     i2c_start();
     i2c_write_byte(ADDR_T<<1);
     i2c_write_byte(reg);
     i2c_write_byte(data);
     i2c_stop();
  }  
 
byte ds_read(byte reg){
     byte dat=0;
     i2c_start();
     i2c_write_byte(ADDR_T<<1);
     i2c_write_byte(reg);
     i2c_start(); 
     i2c_write_byte((ADDR_T<<1)|1); 
     dat = i2c_read_byte(0);
     i2c_stop();
     return dat;
  }
 
void set_time(byte years, byte days, byte monts, byte datas, byte hours ,byte minute, byte second){
  if(second>=0){ds_write(0x00,(second/10<<4)+second%10);}
  if(minute>=0){ds_write(0x01,(minute/10<<4)+minute%10);}
  if(hours>=0){ds_write(0x02,(hours/10<<4)+hours%10);}
  if(days>=0){ds_write(0x03,days);}
  if(datas>=0){ds_write(0x04,(datas/10<<4)+datas%10);}
  if(monts>=0){ds_write(0x05,(monts/10<<4)+monts%10);}
  if(years>=0){ds_write(0x06,(years/10<<4)+years%10);}
  }

 

ПРОСТОЕ РЕЛЕ ВРЕМЕНИ 0…99 МИН

Кнопками (+/-) можно задавать время от 1 до 99 минут, при установки времени таймера сразу же активируется реле, при обнулении таймера реле отключает нагрузку.

#define CLK  PB1 // TM1637
#define DIO  PB0 // TM1637
#define UP   PB3 // BUTTON +++
#define DOWN PB4 // BUTTON ---
#define OUT  PB2 // RELAY
 
char i,tic;
bool w,w1=0,cl;
unsigned long times;
 
void setup(){
  DDRB |= (1 << OUT);
  PORTB &= ~(1 << OUT);
  PORTB |= (1 << UP) | (1 << DOWN);
}
 
void loop(){
   cl=0;
   if(((PINB >> UP) & 1) == 0){i++;if(i>99){i=99;}cl=1;}
   if(((PINB >> DOWN) & 1) == 0){i--;if(i<0){i=0;tic=0;}cl=1;}
 
   if(i>0 || (i==0 && tic>0)){PORTB |= (1 << OUT);w=1;w1=1;}
    else{PORTB &= ~(1 << OUT);w=0;w1=0;}
 
   if(w==1&&cl==0){
    if(millis()-times>999){times=millis();tic--;}
     if(tic<0){tic=59;i--;}
    }  
   tm_print(i*100+tic,w1,5);      
}// end loop
 
void tm_dec(byte dig){
       for(byte 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 tm_print(int t, bool pd_t, byte br){
        tm_start();tm_dec(0b10001000 + br);
        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
        }
        if(n == 0){data0 = data;}
        if(n == 1){data1 = data;}
        if(n == 2){data2 = data;}
        if(n == 3){data3 = data;}
        }
      if(pd_t==1){data1 = data1+0b10000000;}
      tm_dec(0xC0);tm_dec(data0);tm_dec(data1);tm_dec(data2);tm_dec(data3);tm_stop();
}  
 
void del(){delay(1);}

 

DHT11 ДАТЧИК ТЕМПЕРАТУРЫ И ВЛАЖНОСТИ

byte data_dht[5];
 
void setup(){}  
 
void loop() {
  dht_read(); 
  delay(3000);
  print_time(data_dht[2],0,7,1);
  delay(3000);
  print_time(data_dht[0],0,7,0);
}
 
void tm_dec(byte dig){
       for(byte 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);}
 
int dht_read(){
        byte i = 0,i1 = 0;  
        for(i = 0;i < 5;i++){data_dht[i] = 0;}                  
        DDRB |=(1 << DHT); 
        PORTB &= ~(1 << DHT); 
        delay(18); 
        PORTB |= (1 << DHT);
        delayMicroseconds(40); 
        DDRB &= ~(1 << DHT); 
        delayMicroseconds(80); 
    while(PINB & (1 << DHT));
      for (i = 0; i < 5; i++){
        data_dht[i]=0;
      for (i1=0; i1<8; i1++){
    while(!(PINB & (1 << DHT)));  
        delayMicroseconds(30);
      if (PINB & (1 << DHT)){data_dht[i] |= 1 << (7-i1);}
    while(PINB & (1 << DHT));  
}}return 1;}

 

ВОЛЬТМЕТР 0…5 В

3.3 V

1.8 V

0.0 V

Измеряемое напряжение подается на вход А3, в течении 1 секунды производится 10 измерений напряжения с интервалом 100 мс и среднее значение измеренного напряжения выводится на дисплей.

#define VCC 5000.00 // mB
// TM1637
#define DIO PB1
#define CLK PB0
 
byte data_dht[5];
int u;
 
void setup(){
  pinMode(A3,INPUT);
  }  
 
void loop() {
  u=0;
  for(int n=0;n<10;n++){u += analogRead(A3);delay(100);}
  u=u/10;
  print_time(VCC/1023.00/10*u,2,7);
}
 
void tm_dec(byte dig){
       for(byte 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 = 11;
        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 = 0b00111110;break;     // u
        }
 
        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);}

 

ЧАСЫ С БОЛЬШИМИ ЦИФРАМИ И ДАТЧИКОМ ТЕМПЕРАТУРЫ ATTINY45+LCD1602_I2C+DS18B20+DS3231

Скетч — http://forum.rcl-radio.ru/viewtopic.php?pid=6884#p6884

 

Добавить комментарий

Войти с помощью: