1

Тема: lcd1602+I2C + DS3231 + 18b20

http://forum.rcl-radio.ru/uploads/images/2021/12/3c339a0191dd6861b2aacbefcc0b03a9.png
http://forum.rcl-radio.ru/uploads/images/2021/12/a8537a836f7fd66826c678b222bab15f.png

d10 - вход 18b20

#include <avr/io.h>
#include <util/delay.h>

#define ADDR_DS3231    0b1101000
#define ADDR_1602      0x27

#define CPU_F   16000000 // Clock Speed 
#define SCL_F   100000 // // I2C Speed
/// uart init /////
#define BAUD 9600 // USART Speed
#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,datat,mont,year,day;
 unsigned long i,times,times0;
 bool w;


int main(){
   TWBR = (((CPU_F)/(SCL_F)-16 )/2) ;
   TWSR = 0;
   USART_Init(CPU_F/16/BAUD-1); 
  // set_time(21,1,12,26,18,45,0);// год 00-99, ДН 1-7 (1=ВС), месяц 1-12, дата 1-31, час 0-23, минуты 0-59, секунды 0-59
   lcdInit();
   i2c_write_1bit(ADDR_1602,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);
   cli();
   TCCR1A = 0;
   TCCR1B = 0;
   TCNT1 = 0;
   OCR1A = 6249;
   TCCR1B |= (1 << WGM12);
   TCCR1B |= (1 << CS12);
   TIMSK1 |= (1 << OCIE1A);
   sei();
   
   while (1) { 

   sec =  (i2c_read_1bit(ADDR_DS3231,0) & 0x0F) + (((i2c_read_1bit(ADDR_DS3231,0) & 0x70) >> 4) * 10);
   min =  (i2c_read_1bit(ADDR_DS3231,1) & 0x0F) + (((i2c_read_1bit(ADDR_DS3231,1) & 0x70) >> 4) * 10);
   hour = ((i2c_read_1bit(ADDR_DS3231,2) & 0x0F) + ((i2c_read_1bit(ADDR_DS3231,2) & 0x70) >> 4) * 10);
   day =  (i2c_read_1bit(ADDR_DS3231,3) & 0x0F);
   datat = ((i2c_read_1bit(ADDR_DS3231,4) & 0x0F) + ((i2c_read_1bit(ADDR_DS3231,4) & 0x70) >> 4) * 10);
   mont = ((i2c_read_1bit(ADDR_DS3231,5) & 0x0F) + ((i2c_read_1bit(ADDR_DS3231,5) & 0x70) >> 4) * 10);
   year = ((i2c_read_1bit(ADDR_DS3231,6) & 0x0F) + ((i2c_read_1bit(ADDR_DS3231,6) & 0x70) >> 4) * 10);
// temper = (i2c_read_1bit(ADDR_DS3231,0x11)*100 + ((i2c_read_1bit(ADDR_DS3231,0x12) & 0b11000000) >> 6)*25) ;

  
  USART_int(hour);USART_String(":");
  USART_int(min);USART_String(":");
  USART_int(sec);USART_String(" ");
  USART_int(datat);USART_String("-");
  USART_int(mont);USART_String("-");
  USART_int(year);USART_String(" ");
  USART_int(day);USART_String(" ");
  USART_String("\n");
  
  if(i-times>30){t_dig = read_temp();times=i;}
  if(i-times0<30){
     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);}
  }
 if(i-times0>=30&&i-times0<100){
     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');}
 }
 if(i-times0>=100){times0=i; lcdClear();}
  

    
}}// END

ISR(TIMER1_COMPA_vect){i++;}

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
 
    _delay_us(1);
    if(((data >> 7) & 1) ==1){i2c_write_1bit(ADDR_1602,led_b |= (1<<7));} else {i2c_write_1bit(ADDR_1602,led_b &= ~(1<<7));}
    if(((data >> 6) & 1) ==1){i2c_write_1bit(ADDR_1602,led_b |= (1<<6));} else {i2c_write_1bit(ADDR_1602,led_b &= ~(1<<6));}
    if(((data >> 5) & 1) ==1){i2c_write_1bit(ADDR_1602,led_b |= (1<<5));} else {i2c_write_1bit(ADDR_1602,led_b &= ~(1<<5));}
    if(((data >> 4) & 1) ==1){i2c_write_1bit(ADDR_1602,led_b |= (1<<4));} else {i2c_write_1bit(ADDR_1602,led_b &= ~(1<<4));}
    e_pin();
    if(((data >> 3) & 1) ==1){i2c_write_1bit(ADDR_1602,led_b |= (1<<7));} else {i2c_write_1bit(ADDR_1602,led_b &= ~(1<<7));}
    if(((data >> 2) & 1) ==1){i2c_write_1bit(ADDR_1602,led_b |= (1<<6));} else {i2c_write_1bit(ADDR_1602,led_b &= ~(1<<6));}
    if(((data >> 1) & 1) ==1){i2c_write_1bit(ADDR_1602,led_b |= (1<<5));} else {i2c_write_1bit(ADDR_1602,led_b &= ~(1<<5));}
    if(((data >> 0) & 1) ==1){i2c_write_1bit(ADDR_1602,led_b |= (1<<4));} else {i2c_write_1bit(ADDR_1602,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') {_delay_us(1);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_1bit(ADDR_1602,led_b |= (1<<E));_delay_us(1);i2c_write_1bit(ADDR_1602,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 lcdCurs(byte str, byte mesto){
  if(str==0){lcd(0b10000000+mesto);}
  if(str==1){lcd(0b11000000+mesto);}
  }  


int i2c_read_i2c_2bit(byte i2c_addr, byte i2c_reg){
   TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);  // START
  while (!(TWCR & (1<<TWINT)));
   TWDR = i2c_addr << 1;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
   TWDR = i2c_reg;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
 
   TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);  // START
  while (!(TWCR & (1<<TWINT))); 
   TWDR = (i2c_addr << 1) | 1;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
 
   TWCR=(1<<TWINT)|(1<<TWEN)|(1<<TWEA); 
  while(~TWCR&(1<<TWINT));
   int i2c_data0 = TWDR; 
 
   TWCR = (1<<TWINT) | (1<<TWEN);
  while(~TWCR&(1<<TWINT));
  int i2c_data1 = TWDR; 
 
   TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // СТОП
  int i2c_data = (i2c_data0<<8)+i2c_data1;
  return i2c_data;
  }  

int i2c_read_1bit(byte i2c_addr, byte i2c_reg){
   TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);  // START
  while (!(TWCR & (1<<TWINT)));
   TWDR = i2c_addr << 1;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
   TWDR = i2c_reg;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
 
   TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);  // START
  while (!(TWCR & (1<<TWINT))); 
   TWDR = (i2c_addr << 1) | 1;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
 
   TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA); 
  while(~TWCR&(1<<TWINT));
    byte i2c_data = TWDR; 
  TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
 
   TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // СТОП
  return i2c_data;
  }   

 void i2c_write(byte i2c_addr, byte i2c_reg, byte i2c_dat){
   TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);  // START
  while (!(TWCR & (1<<TWINT)));
   TWDR = i2c_addr << 1;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
   TWDR = i2c_reg;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
   TWDR = i2c_dat;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
   TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // СТОП
  } 

 void i2c_write_1bit(byte i2c_addr, byte i2c_reg){
   TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);  // START
  while (!(TWCR & (1<<TWINT)));
   TWDR = i2c_addr << 1;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
   TWDR = i2c_reg;
   TWCR = (1<<TWINT) | (1<<TWEN);
  while (!(TWCR & (1<<TWINT)));
   TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO); // СТОП
  }   

void set_time(byte years, byte days, byte monts, byte datas, byte hours ,byte minute, byte second){
    if(second < 255){i2c_write(ADDR_DS3231,0x00,(second/10<<4)+second%10);}
    if(minute < 255){i2c_write(ADDR_DS3231,0x01,(minute/10<<4)+minute%10);} 
    if(hours < 255){i2c_write(ADDR_DS3231,0x02,(hours/10<<4)+hours%10);}
    if(days < 255){i2c_write(ADDR_DS3231,0x03,days);}
    if(datas < 255){i2c_write(ADDR_DS3231,0x04,(datas/10<<4)+datas%10);}
    if(monts < 255){i2c_write(ADDR_DS3231,0x05,(monts/10<<4)+monts%10);}
    if(years < 255){i2c_write(ADDR_DS3231,0x06,(years/10<<4)+years%10);}
  }    

void USART_Init( unsigned int ubrr ){
  UBRR0H = (unsigned char)(ubrr>>8);
  UBRR0L = (unsigned char)ubrr;
  UCSR0B = (1<<RXEN0)|(1<<TXEN0);
  UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}  

void USART_String(char *data){
  for(int i=0;i<strlen(data);i++){
  while(!( UCSR0A & (1 << UDRE0 )));
  UDR0 = data[i];}
}

void USART_int(int to_int){
  String stringVar = String(to_int, DEC);
  char charVar[sizeof(stringVar)];
  stringVar.toCharArray(charVar, sizeof(charVar));
  USART_String(charVar);} 

// reset
uint8_t therm_reset(){
    uint8_t i;
    PORTB &= ~(1 << PB2);
    DDRB |= (1 << PB2);
    _delay_us(480);  
    DDRB &= ~(1 << PB2);
    _delay_us(60);
    i=((PINB >> PB2) & 1);
    _delay_us(420);
    return i;
}
// write bit
void therm_write_bit(uint8_t bit){
    PORTB &= ~(1 << PB2);
    DDRB |= (1 << PB2);
    _delay_us(1);
    if(bit) DDRB &= ~(1 << PB2);
    _delay_us(60);
    DDRB &= ~(1 << PB2);
}
// read bit
uint8_t therm_read_bit(void){
    uint8_t bit=0;
    PORTB &= ~(1 << PB2);
    DDRB |= (1 << PB2);
    _delay_us(1);
    DDRB &= ~(1 << PB2);
    _delay_us(14);
    if(PINB & (1 << PB2)) 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;
}