Тема: ATTINY45
https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json
Вы не вошли. Пожалуйста, войдите или зарегистрируйтесь.
forum.rcl-radio.ru → Разное → ATTINY45
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
https://raw.githubusercontent.com/damellis/attiny/ide-1.6.x-boards-manager/package_damellis_attiny_index.json
BLINK
void setup() {
pinMode(4, OUTPUT);
}
void loop() {
digitalWrite(4, HIGH);
delay(1000);
digitalWrite(4, LOW);
delay(1000);
}
LCD1602
#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 ДАТЧИК ТЕМПЕРАТУРЫ И ВЛАЖНОСТИ
// DHT11
#define DHT PB2
// TM1637
#define DIO PB1
#define CLK PB0
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В
0V
1.8V
3.3V
#define VCC 5090.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);}
#define I2C_SDA PB3
#define I2C_SCL PB4
#define OLED_ADDR 0x78 // OLED write address
#include <avr/io.h>
#include <util/delay.h>
const char Message1[] PROGMEM = "RCL-RADIO.RU";
const char Message2[] PROGMEM = "OLED 0.96";
const char Message3[] PROGMEM = "SSD1306";
const char Message4[] PROGMEM = "LINE ";
const char Message5[] PROGMEM = "---------------------";
int n;
int main(void) {
_delay_ms(200);
OLED_init();
OLED_clear();
while(1) {
// OLED_clear();
OLED_cursor(0, 0);
OLED_printP(Message1);
OLED_cursor(0, 1);
OLED_printP(Message2);
OLED_cursor(0, 2);
OLED_printP(Message3);
OLED_cursor(0, 3);
OLED_printP(Message5);
OLED_cursor(0, 4);
OLED_printP(Message4);OLED_num(5);
OLED_cursor(0, 5);
OLED_printP(Message4);OLED_num(6);
OLED_cursor(0, 6);
OLED_printP(Message4);OLED_num(7);
OLED_cursor(0, 7);
OLED_printP(Message4);OLED_num(8);
n++;
if(n>50){n=0;}
OLED_cursor(70, 7);
OLED_num(n/10);OLED_num(n%10);
_delay_ms(100);
}
}
#define I2C_SDA_HIGH() DDRB &= ~(1<<I2C_SDA)
#define I2C_SDA_LOW() DDRB |= (1<<I2C_SDA)
#define I2C_SCL_HIGH() DDRB &= ~(1<<I2C_SCL)
#define I2C_SCL_LOW() DDRB |= (1<<I2C_SCL)
#define OLED_CMD_MODE 0x00
#define OLED_DAT_MODE 0x40
const uint8_t OLED_INIT_CMD[] PROGMEM = {0xA8, 0x3F, 0x8D, 0x14, 0xAF, 0xA1, 0xC8};
void I2C_init(void) {
DDRB &= ~((1<<I2C_SDA)|(1<<I2C_SCL));
PORTB &= ~((1<<I2C_SDA)|(1<<I2C_SCL));
}
void I2C_write(uint8_t data) {
for(uint8_t i = 8; i; i--) {
I2C_SDA_LOW();
if (data & 0x80) I2C_SDA_HIGH();
I2C_SCL_HIGH();
data<<=1;
I2C_SCL_LOW();
}
I2C_SDA_HIGH();
I2C_SCL_HIGH();
asm("nop");
I2C_SCL_LOW();
}
// I2C start transmission
void I2C_start(uint8_t addr) {
I2C_SDA_LOW(); // start condition: SDA goes LOW first
I2C_SCL_LOW(); // start condition: SCL goes LOW second
I2C_write(addr); // send slave address
}
// I2C stop transmission
void I2C_stop(void) {
I2C_SDA_LOW(); // prepare SDA for LOW to HIGH transition
I2C_SCL_HIGH(); // stop condition: SCL goes HIGH first
I2C_SDA_HIGH(); // stop condition: SDA goes HIGH second
}
// Standard ASCII 5x8 font (adapted from Neven Boyanov and Stephen Denne)
const uint8_t OLED_FONT[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, // 0
0x00, 0x00, 0x2f, 0x00, 0x00, // ! 1
0x00, 0x07, 0x00, 0x07, 0x00, // " 2
0x14, 0x7f, 0x14, 0x7f, 0x14, // # 3
0x24, 0x2a, 0x7f, 0x2a, 0x12, // $ 4
0x62, 0x64, 0x08, 0x13, 0x23, // % 5
0x36, 0x49, 0x55, 0x22, 0x50, // & 6
0x00, 0x05, 0x03, 0x00, 0x00, // ' 7
0x00, 0x1c, 0x22, 0x41, 0x00, // ( 8
0x00, 0x41, 0x22, 0x1c, 0x00, // ) 9
0x14, 0x08, 0x3E, 0x08, 0x14, // * 10
0x08, 0x08, 0x3E, 0x08, 0x08, // + 11
0x00, 0x00, 0xA0, 0x60, 0x00, // , 12
0x08, 0x08, 0x08, 0x08, 0x08, // - 13
0x00, 0x60, 0x60, 0x00, 0x00, // . 14
0x20, 0x10, 0x08, 0x04, 0x02, // / 15
0x3E, 0x51, 0x49, 0x45, 0x3E, // 0 16
0x00, 0x42, 0x7F, 0x40, 0x00, // 1 17
0x42, 0x61, 0x51, 0x49, 0x46, // 2 18
0x21, 0x41, 0x45, 0x4B, 0x31, // 3 19
0x18, 0x14, 0x12, 0x7F, 0x10, // 4 20
0x27, 0x45, 0x45, 0x45, 0x39, // 5 21
0x3C, 0x4A, 0x49, 0x49, 0x30, // 6 22
0x01, 0x71, 0x09, 0x05, 0x03, // 7 23
0x36, 0x49, 0x49, 0x49, 0x36, // 8 24
0x06, 0x49, 0x49, 0x29, 0x1E, // 9 25
0x00, 0x36, 0x36, 0x00, 0x00, // : 26
0x00, 0x56, 0x36, 0x00, 0x00, // ; 27
0x08, 0x14, 0x22, 0x41, 0x00, // < 28
0x14, 0x14, 0x14, 0x14, 0x14, // = 29
0x00, 0x41, 0x22, 0x14, 0x08, // > 30
0x02, 0x01, 0x51, 0x09, 0x06, // ? 31
0x32, 0x49, 0x59, 0x51, 0x3E, // @ 32
0x7C, 0x12, 0x11, 0x12, 0x7C, // A 33
0x7F, 0x49, 0x49, 0x49, 0x36, // B 34
0x3E, 0x41, 0x41, 0x41, 0x22, // C 35
0x7F, 0x41, 0x41, 0x22, 0x1C, // D 36
0x7F, 0x49, 0x49, 0x49, 0x41, // E 37
0x7F, 0x09, 0x09, 0x09, 0x01, // F 38
0x3E, 0x41, 0x49, 0x49, 0x7A, // G 39
0x7F, 0x08, 0x08, 0x08, 0x7F, // H 40
0x00, 0x41, 0x7F, 0x41, 0x00, // I 41
0x20, 0x40, 0x41, 0x3F, 0x01, // J 42
0x7F, 0x08, 0x14, 0x22, 0x41, // K 43
0x7F, 0x40, 0x40, 0x40, 0x40, // L 44
0x7F, 0x02, 0x0C, 0x02, 0x7F, // M 45
0x7F, 0x04, 0x08, 0x10, 0x7F, // N 46
0x3E, 0x41, 0x41, 0x41, 0x3E, // O 47
0x7F, 0x09, 0x09, 0x09, 0x06, // P 48
0x3E, 0x41, 0x51, 0x21, 0x5E, // Q 49
0x7F, 0x09, 0x19, 0x29, 0x46, // R 50
0x46, 0x49, 0x49, 0x49, 0x31, // S 51
0x01, 0x01, 0x7F, 0x01, 0x01, // T 52
0x3F, 0x40, 0x40, 0x40, 0x3F, // U 53
0x1F, 0x20, 0x40, 0x20, 0x1F, // V 54
0x3F, 0x40, 0x38, 0x40, 0x3F, // W 55
0x63, 0x14, 0x08, 0x14, 0x63, // X 56
0x07, 0x08, 0x70, 0x08, 0x07, // Y 57
0x61, 0x51, 0x49, 0x45, 0x43, // Z 58
0x00, 0x7F, 0x41, 0x41, 0x00, // [ 59
0x02, 0x04, 0x08, 0x10, 0x20, // \ 60
0x00, 0x41, 0x41, 0x7F, 0x00, // ] 61
0x04, 0x02, 0x01, 0x02, 0x04, // ^ 62
0x40, 0x40, 0x40, 0x40, 0x40 // _ 63
};
void OLED_init(void) {
I2C_init();
I2C_start(OLED_ADDR);
I2C_write(OLED_CMD_MODE);
for (uint8_t i = 0; i < 7; i++) I2C_write(pgm_read_byte(&OLED_INIT_CMD[i]));
I2C_stop();
}
void OLED_printC(char ch) {
uint16_t offset = ch - 32;
offset += offset << 2;
I2C_write(0x00);
for(uint8_t i=5; i; i--) I2C_write(pgm_read_byte(&OLED_FONT[offset++]));
}
void OLED_printP(const char* p) {
I2C_start(OLED_ADDR);
I2C_write(OLED_DAT_MODE);
char ch = pgm_read_byte(p);
while (ch != 0){OLED_printC(ch);ch = pgm_read_byte(++p);}
I2C_stop();
}
void OLED_num(byte num){
I2C_start(OLED_ADDR);
I2C_write(OLED_DAT_MODE);
OLED_printC(num+48);
I2C_stop();
}
void OLED_cursor(uint8_t xpos, uint8_t ypos) {
I2C_start(OLED_ADDR);
I2C_write(OLED_CMD_MODE);
I2C_write(xpos & 0x0F);
I2C_write(0x10 | (xpos >> 4));
I2C_write(0xB0 | (ypos & 0x07));
I2C_stop();
}
void OLED_clear(void) {
for (uint8_t i = 0; i < 8; i++) { // clear screen line by line
OLED_cursor(0, i);
I2C_start(OLED_ADDR); // start transmission to OLED
I2C_write(OLED_DAT_MODE); // set data mode
for(uint8_t i=128; i; i--) I2C_write(0x00);
I2C_stop(); // stop transmission
}
}
#include <avr/io.h>
#include <util/delay.h>
// Project Files (Github): https://github.com/wagiminator/ATtiny13-TinyOLEDdemo
// License: http://creativecommons.org/licenses/by-sa/3.0/
#define I2C_SDA PB3
#define I2C_SCL PB4
#define I2C_SDA_HIGH() DDRB &= ~(1<<I2C_SDA)
#define I2C_SDA_LOW() DDRB |= (1<<I2C_SDA)
#define I2C_SCL_HIGH() DDRB &= ~(1<<I2C_SCL)
#define I2C_SCL_LOW() DDRB |= (1<<I2C_SCL)
const char Message1[] PROGMEM = "RCL-RADIO.RU";
const char Message2[] PROGMEM = "OLED 0.91 / 128x32";
const char Message3[] PROGMEM = "SSD1306";
const char Message4[] PROGMEM = "Line 4";
int n;
int main(void) {
OLED_init();
OLED_brig(150);// 0...255
OLED_inver(0); // invers
OLED_clear();
while(1) {
OLED_cursor(0, 0);
OLED_printP(Message1);
OLED_cursor(0, 1);
OLED_printP(Message2);
OLED_cursor(0, 2);
OLED_printP(Message3);
OLED_cursor(0, 3);
OLED_printP(Message4);
n++;
if(n>50){n=0;}
OLED_cursor(70, 3);
OLED_num(n/10);OLED_num(n%10);
_delay_ms(100);
}}
///// I2C ///////////////////////////////////////////////////////
void I2C_init(void) {DDRB &= ~((1<<I2C_SDA)|(1<<I2C_SCL)); PORTB &= ~((1<<I2C_SDA)|(1<<I2C_SCL));}
void I2C_write(uint8_t data) {
for(uint8_t i = 8; i; i--) {I2C_SDA_LOW();
if (data & 0x80) I2C_SDA_HIGH();I2C_SCL_HIGH();data<<=1;I2C_SCL_LOW();}
I2C_SDA_HIGH();I2C_SCL_HIGH();asm("nop");I2C_SCL_LOW();
}
void I2C_start(uint8_t addr) {I2C_SDA_LOW();I2C_SCL_LOW();I2C_write(addr);}
void I2C_stop(void) {I2C_SDA_LOW();I2C_SCL_HIGH();I2C_SDA_HIGH();}
///// OLED ///////////////////////////////////
#define OLED_ADDR 0x78
#define OLED_CMD_MODE 0x00
#define OLED_DAT_MODE 0x40
#define OLED_INIT_LEN 12
const uint8_t OLED_INIT_CMD[] PROGMEM = {0xA8,0x1F,0x22,0x00,0x03,0x20,0x00,0xDA,0x02,0x8D,0x14,0xAF,0xA1,0xC8};
const uint8_t OLED_FONT[] PROGMEM = {
0x00, 0x00, 0x00, 0x00, 0x00, // sp
0x00, 0x00, 0x5F, 0x00, 0x00, // !
0x00, 0x03, 0x00, 0x03, 0x00, // "
0x14, 0x3E, 0x14, 0x3E, 0x14, // #
0x24, 0x2A, 0x7F, 0x2A, 0x12, // $
0x43, 0x33, 0x08, 0x66, 0x61, // %
0x36, 0x49, 0x55, 0x22, 0x50, // &
0x00, 0x05, 0x03, 0x00, 0x00, // '
0x00, 0x1C, 0x22, 0x41, 0x00, // (
0x00, 0x41, 0x22, 0x1C, 0x00, // )
0x14, 0x08, 0x3E, 0x08, 0x14, // *
0x08, 0x08, 0x3E, 0x08, 0x08, // +
0x00, 0x50, 0x30, 0x00, 0x00, // ,
0x08, 0x08, 0x08, 0x08, 0x08, // -
0x00, 0x60, 0x60, 0x00, 0x00, // .
0x20, 0x10, 0x08, 0x04, 0x02, // /
0x3E, 0x51, 0x49, 0x45, 0x3E, // 0
0x00, 0x04, 0x02, 0x7F, 0x00, // 1
0x42, 0x61, 0x51, 0x49, 0x46, // 2
0x22, 0x41, 0x49, 0x49, 0x36, // 3
0x18, 0x14, 0x12, 0x7F, 0x10, // 4
0x27, 0x45, 0x45, 0x45, 0x39, // 5
0x3E, 0x49, 0x49, 0x49, 0x32, // 6
0x01, 0x01, 0x71, 0x09, 0x07, // 7
0x36, 0x49, 0x49, 0x49, 0x36, // 8
0x26, 0x49, 0x49, 0x49, 0x3E, // 9
0x00, 0x36, 0x36, 0x00, 0x00, // :
0x00, 0x56, 0x36, 0x00, 0x00, // ;
0x08, 0x14, 0x22, 0x41, 0x00, // <
0x14, 0x14, 0x14, 0x14, 0x14, // =
0x00, 0x41, 0x22, 0x14, 0x08, // >
0x02, 0x01, 0x51, 0x09, 0x06, // ?
0x3E, 0x41, 0x59, 0x55, 0x5E, // @
0x7E, 0x09, 0x09, 0x09, 0x7E, // A
0x7F, 0x49, 0x49, 0x49, 0x36, // B
0x3E, 0x41, 0x41, 0x41, 0x22, // C
0x7F, 0x41, 0x41, 0x41, 0x3E, // D
0x7F, 0x49, 0x49, 0x49, 0x41, // E
0x7F, 0x09, 0x09, 0x09, 0x01, // F
0x3E, 0x41, 0x41, 0x49, 0x3A, // G
0x7F, 0x08, 0x08, 0x08, 0x7F, // H
0x00, 0x41, 0x7F, 0x41, 0x00, // I
0x30, 0x40, 0x40, 0x40, 0x3F, // J
0x7F, 0x08, 0x14, 0x22, 0x41, // K
0x7F, 0x40, 0x40, 0x40, 0x40, // L
0x7F, 0x02, 0x0C, 0x02, 0x7F, // M
0x7F, 0x02, 0x04, 0x08, 0x7F, // N
0x3E, 0x41, 0x41, 0x41, 0x3E, // O
0x7F, 0x09, 0x09, 0x09, 0x06, // P
0x1E, 0x21, 0x21, 0x21, 0x5E, // Q
0x7F, 0x09, 0x09, 0x09, 0x76, // R
0x26, 0x49, 0x49, 0x49, 0x32, // S
0x01, 0x01, 0x7F, 0x01, 0x01, // T
0x3F, 0x40, 0x40, 0x40, 0x3F, // U
0x1F, 0x20, 0x40, 0x20, 0x1F, // V
0x7F, 0x20, 0x10, 0x20, 0x7F, // W
0x41, 0x22, 0x1C, 0x22, 0x41, // X
0x07, 0x08, 0x70, 0x08, 0x07, // Y
0x61, 0x51, 0x49, 0x45, 0x43, // Z
0x00, 0x7F, 0x41, 0x00, 0x00, // [
0x02, 0x04, 0x08, 0x10, 0x20, // "/"
0x00, 0x00, 0x41, 0x7F, 0x00, // ]
0x04, 0x02, 0x01, 0x02, 0x04, // ^
0x40, 0x40, 0x40, 0x40, 0x40, // _
0x00, 0x01, 0x02, 0x04, 0x00, // `
0x20, 0x54, 0x54, 0x54, 0x78, // a
0x7F, 0x44, 0x44, 0x44, 0x38, // b
0x38, 0x44, 0x44, 0x44, 0x44, // c
0x38, 0x44, 0x44, 0x44, 0x7F, // d
0x38, 0x54, 0x54, 0x54, 0x18, // e
0x04, 0x04, 0x7E, 0x05, 0x05, // f
0x08, 0x54, 0x54, 0x54, 0x3C, // g
0x7F, 0x08, 0x04, 0x04, 0x78, // h
0x00, 0x44, 0x7D, 0x40, 0x00, // i
0x20, 0x40, 0x44, 0x3D, 0x00, // j
0x7F, 0x10, 0x28, 0x44, 0x00, // k
0x00, 0x41, 0x7F, 0x40, 0x00, // l
0x7C, 0x04, 0x78, 0x04, 0x78, // m
0x7C, 0x08, 0x04, 0x04, 0x78, // n
0x38, 0x44, 0x44, 0x44, 0x38, // o
0x7C, 0x14, 0x14, 0x14, 0x08, // p
0x08, 0x14, 0x14, 0x14, 0x7C, // q
0x00, 0x7C, 0x08, 0x04, 0x04, // r
0x48, 0x54, 0x54, 0x54, 0x20, // s
0x04, 0x04, 0x3F, 0x44, 0x44, // t
0x3C, 0x40, 0x40, 0x20, 0x7C, // u
0x1C, 0x20, 0x40, 0x20, 0x1C, // v
0x3C, 0x40, 0x30, 0x40, 0x3C, // w
0x44, 0x28, 0x10, 0x28, 0x44, // x
0x0C, 0x50, 0x50, 0x50, 0x3C, // y
0x44, 0x64, 0x54, 0x4C, 0x44, // z
0x00, 0x08, 0x36, 0x41, 0x41, // {
0x00, 0x00, 0x7F, 0x00, 0x00, // |
0x41, 0x41, 0x36, 0x08, 0x00, // }
0x02, 0x01, 0x02, 0x04, 0x02, // ~
};
void OLED_init(void) {
I2C_init();
I2C_start(OLED_ADDR);
I2C_write(OLED_CMD_MODE);
for (uint8_t i = 0; i < OLED_INIT_LEN; i++) I2C_write(pgm_read_byte(&OLED_INIT_CMD[i]));
I2C_stop();
}
void OLED_printC(char ch) {
uint16_t offset = ch - 32;
offset += offset << 2;
I2C_write(0x00);
for(uint8_t i=5; i; i--) I2C_write(pgm_read_byte(&OLED_FONT[offset++]));
}
void OLED_printP(const char* p) {
I2C_start(OLED_ADDR);
I2C_write(OLED_DAT_MODE);
char ch = pgm_read_byte(p);
while (ch != 0){OLED_printC(ch);ch = pgm_read_byte(++p);}
I2C_stop();
}
void OLED_cursor(uint8_t xpos, uint8_t ypos) {
I2C_start(OLED_ADDR);
I2C_write(OLED_CMD_MODE);
I2C_write(xpos & 0x0F);
I2C_write(0x10 | (xpos >> 4));
I2C_write(0xB0 | (ypos & 0x07));
I2C_stop();
}
void OLED_clear(void) {
OLED_cursor(0, 0);
I2C_start(OLED_ADDR);
I2C_write(OLED_DAT_MODE);
for(uint16_t i=512; i; i--) I2C_write(0x00);
I2C_stop();
}
void OLED_num(byte num){
I2C_start(OLED_ADDR);
I2C_write(OLED_DAT_MODE);
OLED_printC(num+48);
I2C_stop();
}
void OLED_brig(byte br){
I2C_start(OLED_ADDR);
I2C_write(OLED_CMD_MODE);
I2C_write(0x81);
I2C_write(br);
I2C_stop();
}
void OLED_inver(bool inv){
int inv_data;
if(inv==0) inv_data=0xA6; else inv_data=0xA7;
I2C_start(OLED_ADDR);
I2C_write(OLED_CMD_MODE);
I2C_write(inv_data);
I2C_stop();
}
ЧАСЫ С БОЛЬШИМИ ЦИФРАМИ И ДАТЧИКОМ ТЕМПЕРАТУРЫ ATTINY45+LCD1602_I2C+DS18B20+DS3231
#include <avr/io.h>
#include <util/delay.h>
#define ADDR_DS3231 0b1101000
#define ADDR_1602 0x27
#define SDA PB4
#define SCL PB3
#define TERM PB2
#define HH PB0
#define MM PB1
#define RS 0
#define E 2
#define LED 3
byte led_b,init_t;
byte d1,d2,d3,d4,d5,d6,e1,e2,e3;
int a[6],x;
int t_dig;
byte sec,min,hour;
int hh,mm;
int w;
bool k=1;
int main(){
PORTB |=(1 << HH)|(1 << MM);
// set_time(22,2,10,24,13,20,0);// год 00-99, ДН 1-7 (1=ВС), месяц 1-12, дата 1-31, час 0-23, минуты 0-59, секунды 0-59
lcdInit();
i2c_write(led_b |= (1<<LED)); // включаем подсветку
lcdWrite(0, 0x07,0x07,0x07,0x07,0x07,0x07,0x07,0x07);
lcdWrite(8, 0x07,0x07,0x00,0x00,0x00,0x00,0x00,0x00);
lcdWrite(16,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x1F);
lcdWrite(24,0x1F,0x1F,0x00,0x00,0x00,0x00,0x1F,0x1F);
lcdWrite(32,0x1C,0x1C,0x00,0x00,0x00,0x00,0x1C,0x1C);
lcdWrite(40,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C,0x1C);
lcdWrite(48,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x07);
lcdWrite(56,0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00);
while (1) {
sec = (ds_read(0) & 0x0F) + (((ds_read(0) & 0x70) >> 4) * 10);
min = (ds_read(1) & 0x0F) + (((ds_read(1) & 0x70) >> 4) * 10);
hour = ((ds_read(2) & 0x0F) + ((ds_read(2) & 0x70) >> 4) * 10);
hh=hour;mm=min;
if(((PINB >> HH) & 1) == 0){hh++;if(hh>23){hh=0;}set_time(22,2,10,24,hh,mm,0);_delay_ms(200);}
if(((PINB >> MM) & 1) == 0){mm++;if(mm>59){mm=0;}set_time(22,2,10,24,hh,mm,0);_delay_ms(200);}
if(sec>=35&&sec<=40||sec>=55){
if(w==0){ lcdClear();t_dig = read_temp();}w++;
a[0]=t_dig/100;
a[1]=t_dig/10%10;
a[2]=t_dig%10;
for(x=0;x<3;x++){
switch(x){
case 0: e1=2;e2=3,e3=4;break;
case 1: e1=5,e2=6,e3=7;break;
case 2: e1=9,e2=10,e3=11;break;
}digit();
lcdCurs(1,8);lcdChar(0x2e);lcdCurs(1,12);lcdChar(0xdf);lcdChar(0x43);}
}
else{
w=0;
a[0]=hour/10;
a[1]=hour%10;
a[2]=min/10;
a[3]=min%10;
for(x=0;x<4;x++){
switch(x){
case 0: e1=0;e2=1,e3=2;break;
case 1: e1=3,e2=4,e3=5;break;
case 2: e1=7,e2=8,e3=9;break;
case 3: e1=10,e2=11,e3=12;break;
}digit();
lcdCurs(0,6);lcdChar(0x2e);lcdCurs(1,6);lcdChar(0x2e);lcdCurs(1,13);lcdChar(20);lcdCurs(1,14);lcdChar(sec/10+'0');lcdChar(sec%10+'0');}
}
}}// END
void digit(){
switch(a[x]){
case 0: d1=0,d2=7,d3=5,d4=0,d5=2,d6=5;break;
case 1: d1=32,d2=1,d3=5,d4=32,d5=32,d6=5;break;
case 2: d1=1,d2=7,d3=5,d4=0,d5=3,d6=4;break;
case 3: d1=1,d2=3,d3=5,d4=6,d5=2,d6=5;break;
case 4: d1=0,d2=2,d3=5,d4=32,d5=32,d6=5;break;
case 5: d1=0,d2=3,d3=4,d4=6,d5=2,d6=5;break;
case 6: d1=0,d2=3,d3=4,d4=0,d5=2,d6=5;break;
case 7: d1=0,d2=7,d3=5,d4=32,d5=32,d6=5;break;
case 8: d1=0,d2=3,d3=5,d4=0,d5=2,d6=5;break;
case 9: d1=0,d2=3,d3=5,d4=6,d5=2,d6=5;break;
case 10:d1=150,d2=150,d3=150,d4=150,d5=150,d6=150;break;}
lcdCurs(0,e1);lcdChar(d1);
lcdCurs(0,e2);lcdChar(d2);
lcdCurs(0,e3);lcdChar(d3);
lcdCurs(1,e1);lcdChar(d4);
lcdCurs(1,e2);lcdChar(d5);
lcdCurs(1,e3);lcdChar(d6);
}
void lcdSend(bool rs, byte data) {
cli();
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();
sei();
}
void lcdInit(){
lcd(0x03);_delay_us(4500);
lcd(0x03);_delay_us(4500);
lcd(0x03);_delay_us(200);
lcd(0b00000010);_delay_ms(5);
lcd(0b00001100);_delay_ms(5);
lcdClear();
}
void lcdClear(){lcd(0b00000001);}
void lcdString(const char* str) {while(*str != '\0') {del();lcdChar(*str);str++;}}
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));del();i2c_write(led_b &= ~(1<<E));}
void lcdWrite(byte addr_w, byte wr1,byte wr2,byte wr3,byte wr4,byte wr5,byte wr6,byte wr7,byte wr8){
lcd(0b01000000|addr_w);lcdChar(wr1);lcdChar(wr2);lcdChar(wr3);lcdChar(wr4);lcdChar(wr5);lcdChar(wr6);lcdChar(wr7);lcdChar(wr8);}
void del(){_delay_us(500);}
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);
_delay_us(5);
DDRB &= ~(1 << SCL);
if((PINB >> SDA) & 1) i2c_bit=0;
_delay_us(5);
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){
_delay_us(1);
if(b){DDRB |= (1 << SDA);}else{DDRB &= ~(1 << SDA);}
_delay_us(1);
DDRB &= ~(1 << SCL);
_delay_us(1);
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_1602<<1);
i2c_write_byte(lcd);
i2c_stop();
}
void ds_write(byte reg, byte data){
i2c_start();
i2c_write_byte(ADDR_DS3231<<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_DS3231<<1);
i2c_write_byte(reg);
i2c_start();
i2c_write_byte((ADDR_DS3231<<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){
ds_write(0x00,(second/10<<4)+second%10);
ds_write(0x01,(minute/10<<4)+minute%10);
ds_write(0x02,(hours/10<<4)+hours%10);
ds_write(0x03,days);
ds_write(0x04,(datas/10<<4)+datas%10);
ds_write(0x05,(monts/10<<4)+monts%10);
ds_write(0x06,(years/10<<4)+years%10);
}
// reset
uint8_t therm_reset(){
uint8_t i;
PORTB &= ~(1 << TERM);
DDRB |= (1 << TERM);
_delay_us(480);
DDRB &= ~(1 << TERM);
_delay_us(60);
i=((PINB >> TERM) & 1);
_delay_us(420);
return i;
}
// write bit
void therm_write_bit(uint8_t bit){
PORTB &= ~(1 << TERM);
DDRB |= (1 << TERM);
_delay_us(1);
if(bit) DDRB &= ~(1 << TERM);
_delay_us(60);
DDRB &= ~(1 << TERM);
}
// read bit
uint8_t therm_read_bit(void){
uint8_t bit=0;
PORTB &= ~(1 << TERM);
DDRB |= (1 << TERM);
_delay_us(1);
DDRB &= ~(1 << TERM);
_delay_us(14);
if(PINB & (1 << TERM)) bit=1;
_delay_us(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])/1.60;
return (int)temper;
}
"Черновой" вариант Dht22_max7219.
#define MAX7219_DIN PB0 // нога1
#define MAX7219_CS PB1 // нога12
#define MAX7219_CLK PB2 // нога13
#define DHT_PIN PB4 // датчик dht22
#include "DHT.h"
#define DHTPIN PB4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
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); // включен режим декодирования
dht.begin();
}
void loop() {
float h = dht.readHumidity()*100;
float t = dht.readTemperature()*100;
byte data0 = DisplayNumtoSeg[(int)t / 1000];
byte data1= DisplayNumtoSeg[((int)t /100)% 10]|128;
byte data2 =DisplayNumtoSeg[((int)t /10)% 10];
// byte data3 = (int)t % 10;
output(0x01,data0);
output(0x02,data1);
output(0x03,data2);
output(0x04,0b01100011);
delay(2000);
data0 = DisplayNumtoSeg[ (int)h / 1000];
data1= DisplayNumtoSeg[((int)h /100)% 10]|128;
data2 = DisplayNumtoSeg[((int)h /10)% 10];
// data3 = (int)h % 10;
output(0x01,data0);
output(0x02,data1);
output(0x03,data2);
output(0x04,0b00110111);
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);
}
Данный контент доступен только зарегистрированным пользователям.
Данный контент доступен только зарегистрированным пользователям.
Можно код и библиотеку оптимизировать, заменив команды ардуино битовыми операциями.
Датчик BMP180_TM1637. Показывает поочерёдно атмосферное давление и температуру.
#include <TinyWireM.h>
#include <tinyBMP085.h>
tinyBMP085 bmp;
#define CLK PB3 // TM1637
#define DIO PB4 // TM1637
//SDA pin 5 PB0
//SCL pin 7 PB2
void setup() {
bmp.begin();
}
void loop() {
int pres = bmp.readPressure()/10; //kилопаскалях
pres = pres/1.333224,2;// мм ртутного столба
int temp = bmp.readTemperature10C();
// int alt = bmp.readAltitude();
// int altMM = bmp.readAltitudemm();
// int altSTDdm = bmp.readAltitudeSTDdm();
tm_print(temp,1,7);
delay(3000);
tm_print(pres,1,7);
delay(3000);
}
//// tm1637////////////////////////////////////
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, byte pd_t, int br){
tm_start();tm_dec(0b10001000 + br);//tm_stop();tm_start();
tm_dec(0x40);tm_stop();tm_start();
int data0;
if(t<1000){data0=10;}else{ 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;}
}
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(){delay(1);}
Библиотеки
Данный контент доступен только зарегистрированным пользователям.
Данный контент доступен только зарегистрированным пользователям.
Добавил датчик DHT11
#include <TinyWireM.h>
#include <tinyBMP085.h>
tinyBMP085 bmp;
#define CLK PB3 // TM1637
#define DIO PB4 // TM1637
//SDA pin 5 PB0
//SCL pin 7 PB2
#define DHT PB1 // +подключить внешнюю подтяжку.
byte _hum, _temp;// переменные для влажности и температуры
void setup() {
bmp.begin();
}
void loop() {
int pres = bmp.readPressure()/10; //kилопаскалях
pres = pres/1.333224,2;// мм ртутного столба
int temp = bmp.readTemperature10C();
dht_read(&_hum, &_temp);// опроса датчика
tm_print(temp,1,7);
delay(3000);
tm_print(pres,1,7);
delay(3000);
tm_print(_hum*10,1,7);
delay(3000);
}
//// tm1637////////////////////////////////////
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, byte pd_t, int br){
tm_start();tm_dec(0b10001000 + br);//tm_stop();tm_start();
tm_dec(0x40);tm_stop();tm_start();
int data0;
if(t<1000){data0=10;}else{ 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;}
}
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(){delay(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 3; // если контрольная сумма не сошлась вернем ошибку 3
*hum=data[0];// пишем данные влажности
*temp=data[2];// пишем данные температуры
return 0;// вернем 0 - ошибок нет.
}
// функция передачи условия "старт" на линию и проверка ответов от датчика.
byte dht_start(){
DDRB|=(1<<DHT);// притянули линию к земле - 0
delay(20);// пауза 20 мс
DDRB&=~(1<<DHT);// отпустили линию - 1
delayMicroseconds(40);// ждем 40 мкс чтобы попасть в середину низкого сигнала
if (PINB&(1<<DHT)) return 1; // если на линии 1 ошибка - "датчик не ответил"
delayMicroseconds(80); // ждем 80 мкс чтобы попасть в середину высокого сигнала
if (!(PINB&(1<<DHT))) return 2; // если на линии 0 ошибка - "датчик не готов "
while(PINB&(1<<DHT));// ждем пока датчик не притянет линию к земле.
return 0;// ошибок нет
}
// получение байта от датчика
byte dht_byte(){
byte i=8, byte=0;// переменная для цикла и под байт
while(i--){
while(!(PINB&(1<<DHT)));// ждем пока линия не поднимится в 1
delayMicroseconds(40);// отступаем 40 мкс
if (PINB&(1<<DHT)) {// если на линии 1 = приняли 1
byte|=(1<<i);// поднимаем итый бит в 1
while(PINB&(1<<DHT));// ждем пока линия упадет в 0
}
}
return byte;// возвращаем полученный байт
}
Второй вариант
#include <TinyWireM.h>
#include <tinyBMP085.h>
tinyBMP085 bmp;
//SDA pin 5 PB0
//SCL pin 7 PB2
#define DHT PB1 // +подключить внешнюю подтяжку.
byte _hum, _temp;// переменные для влажности и температуры
// TM1637 Macros
#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))
// TM1637 Main Settings
#define TM1637_DIO_PIN PB4
#define TM1637_CLK_PIN PB3
#define TM1637_BRIGHTNESS_MAX (7)
#define TM1637_POSITION_MAX (4)
// TM1637 commands
#define TM1637_CMD_SET_DATA 0x40
#define TM1637_CMD_SET_ADDR 0xC0
#define TM1637_CMD_SET_DSIPLAY 0x80
// TM1637 data settings (use bitwise OR to contruct complete command)
#define TM1637_SET_DATA_WRITE 0x00 // write data to the display register
#define TM1637_SET_DATA_READ 0x02 // read the key scan data
#define TM1637_SET_DATA_A_ADDR 0x00 // automatic address increment
#define TM1637_SET_DATA_F_ADDR 0x04 // fixed address
#define TM1637_SET_DATA_M_NORM 0x00 // normal mode
#define TM1637_SET_DATA_M_TEST 0x10 // test mode
// TM1637 display control command set (use bitwise OR to consruct complete command)
#define TM1637_SET_DISPLAY_OFF 0x00 // off
#define TM1637_SET_DISPLAY_ON 0x08 // on
static uint8_t _config = TM1637_SET_DISPLAY_ON | TM1637_BRIGHTNESS_MAX;
static uint8_t _segments = 0xff;
PROGMEM const uint8_t _digit2segments[] =
{
0x3F, // 0
0x06, // 1
0x5B, // 2
0x4F, // 3
0x66, // 4
0x6D, // 5
0x7D, // 6
0x07, // 7
0x7F, // 8
0x6F // 9
};
void setup() {
bmp.begin();
TM1637_init(1/*включение*/, 7/*яркость*/);
}
void loop() {
int pres = bmp.readPressure()/10; //kилопаскалях
pres = pres/1.333224,2;// мм ртутного столба
int temp = bmp.readTemperature10C();
dht_read(&_hum, &_temp);// опроса датчика
TM1637_display_digit(0, pres/1000);
TM1637_display_digit(1, pres / 100 % 10);
TM1637_display_digit(2, pres/ 10 % 10);
TM1637_display_segments(3, 115);
delay(3000);
TM1637_display_digit(0, temp / 100 % 10);
TM1637_display_digit(1 ,temp/ 10 % 10 );
TM1637_display_digit(2, temp % 10);
TM1637_display_segments(3, 99);
TM1637_display_colon(1);
delay(3000);
TM1637_display_digit(0,_hum/ 10 % 10 );
TM1637_display_digit(1, _hum % 10);
TM1637_display_segments(2, 118);
TM1637_display_segments(3, 28);
delay(3000);
}
// общая функция опроса датчика
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 3; // если контрольная сумма не сошлась вернем ошибку 3
*hum=data[0];// пишем данные влажности
*temp=data[2];// пишем данные температуры
return 0;// вернем 0 - ошибок нет.
}
// функция передачи условия "старт" на линию и проверка ответов от датчика.
byte dht_start(){
DDRB|=(1<<DHT);// притянули линию к земле - 0
delay(20);// пауза 20 мс
DDRB&=~(1<<DHT);// отпустили линию - 1
delayMicroseconds(40);// ждем 40 мкс чтобы попасть в середину низкого сигнала
if (PINB&(1<<DHT)) return 1; // если на линии 1 ошибка - "датчик не ответил"
delayMicroseconds(80); // ждем 80 мкс чтобы попасть в середину высокого сигнала
if (!(PINB&(1<<DHT))) return 2; // если на линии 0 ошибка - "датчик не готов "
while(PINB&(1<<DHT));// ждем пока датчик не притянет линию к земле.
return 0;// ошибок нет
}
// получение байта от датчика
byte dht_byte(){
byte i=8, byte=0;// переменная для цикла и под байт
while(i--){
while(!(PINB&(1<<DHT)));// ждем пока линия не поднимится в 1
delayMicroseconds(40);// отступаем 40 мкс
if (PINB&(1<<DHT)) {// если на линии 1 = приняли 1
byte|=(1<<i);// поднимаем итый бит в 1
while(PINB&(1<<DHT));// ждем пока линия упадет в 0
}
}
return byte;// возвращаем полученный байт
}
//// tm1637////////////////////////////////////
asm volatile (
" ldi r18, 26" "\n"
" ldi r19, 249" "\n"
"1: dec r19" "\n"
" brne 1b" "\n"
" dec r18" "\n"
" brne 1b" "\n"
);
void
TM1637_init(const uint8_t enable, const uint8_t 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(const uint8_t value)
{
TM1637_send_config(value, _config & TM1637_BRIGHTNESS_MAX);
}
void
TM1637_set_brightness(const uint8_t value)
{
TM1637_send_config(_config & TM1637_SET_DISPLAY_ON,
value & TM1637_BRIGHTNESS_MAX);
}
void
TM1637_display_segments(const uint8_t position, const uint8_t segments)
{
TM1637_send_command(TM1637_CMD_SET_DATA | TM1637_SET_DATA_F_ADDR);
TM1637_start();
TM1637_write_byte(TM1637_CMD_SET_ADDR | (position & (TM1637_POSITION_MAX - 1)));
TM1637_write_byte(segments);
TM1637_stop();
}
void
TM1637_display_digit(const uint8_t position, const uint8_t digit)
{
uint8_t segments = (digit < 10 ? pgm_read_byte_near((uint8_t *)&_digit2segments + digit) : 0x00);
if (position == 0x01) {
segments = segments | (_segments & 0x00);//tochka 0x80
_segments = segments;
}
TM1637_display_segments(position, segments);
}
void
TM1637_display_colon(const uint8_t value)
{
if (value) {
_segments |= 0x80;
} else {
_segments &= ~0x80;
}
TM1637_display_segments(0x01, _segments);
}
void
TM1637_clear(void)
{
uint8_t i;
for (i = 0; i < TM1637_POSITION_MAX; ++i) {
TM1637_display_segments(i, 0x00);
}
}
void
TM1637_send_config(const uint8_t enable, const uint8_t brightness)
{
_config = (enable ? TM1637_SET_DISPLAY_ON : TM1637_SET_DISPLAY_OFF) |
(brightness > TM1637_BRIGHTNESS_MAX ? TM1637_BRIGHTNESS_MAX : brightness);
TM1637_send_command(TM1637_CMD_SET_DSIPLAY | _config);
}
void
TM1637_send_command(const uint8_t value)
{
TM1637_start();
TM1637_write_byte(value);
TM1637_stop();
}
void
TM1637_start(void)
{
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(void)
{
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();
}
uint8_t
TM1637_write_byte(uint8_t value)
{
uint8_t 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;
}
Страницы 1
Чтобы отправить ответ, вы должны войти или зарегистрироваться
forum.rcl-radio.ru → Разное → ATTINY45
Форум работает на PunBB, при поддержке Informer Technologies, Inc
|