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
Измеряемое напряжение подается на вход А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