Digitālais pulkstenis ar termometra funkciju


Ikvienam lietotājam patīk, ja ierīces ir ērtas un ar vairākām funkcijām, tāpēc šoreiz autors izveidojis elektrisko principiālo shēmu pārnēsājamam digitālajam pulkstenim, kuram paredzēta arī istabas temperatūras attēlošanas uz displeja funkcija. Elektrobarošanai paredzēts izmantot divas baterijas: 3,3 un 9 V, taču 9 V baterijas vietā var izmantot arī citu līdzsprieguma avotu, kurš atbilst LM7805 sērijas lineārā sprieguma stabilizatora ieejas parametriem.




1.1.att. Digitālais pulkstenis ar termometra funkciju



Elektriskās principiālās shēmas darbības princips ir balstīts uz ATMEGA328P sērijas mikrokontrollera un DS1307 sērijas reālā laika pulksteņa jeb integrālās shēmas, kura atgriež reālā laika vērtību, kuru tālāk apstrādā mikrokontrolleris un izvada uz šķidro kristālu displeja, izmantojot datu pārsūtīšanu četru bitu režīmā.

DS1307 sērijas reālā laika pulkstenis datus saņem un nosūta, izmantojot I2C saskarni, kas nozīmē, ka nepieciešami tikai divi mikrokontrollera izvadi, kur viens no tiem ir datiem, bet otrs ir paredzēts takts signālam. Abas līnijas (SCL un SDA) nepieciešams piesaistīt pie augsta signāla līmeņa.

Temperatūras mērīšanu nodrošina LM35 sērijas termosensors, kura izejas signāla nestabilitātes novēršanai tiek izmantota RC ķēde, kuru veido R8 rezistors un C2 kondensators. 

R9 rezistors paredzēts C2 kondensatora izlādei.

5 V nodrošināšanai tiek izmantots LM7805 sērijas lineārais sprieguma stabilizators.

Tā kā reālā laika pulkstenim jābūt neatkarīgam no kopējās elektrobarošanas, tad shēmā paredzēts izmantot 3,3 V bateriju. Tā darbībai arī nepieciešams ārējais 32,76 kHz takts avots (X1).

5 V elektrobarošanas indikācijai paredzēta D1 gaismas diode, kuras aizsardzībai paredzēts R7 rezistors, kurš ierobežo strāvu caur to.

Izmantojot 3 spiedpogas, lietotājs var iestatīt sākotnējo laiku, kurš tālāk tiek nosūtīts reālā laika pulkstenim, kurš tālāk uzsāk laika atskaiti no sākotnēji iestatītās vērtības.

R1-R6 rezistori paredzēti augsta signāla līmeņa piesaistei.

Ar RV1 potenciometra palīdzību ir iespējams pieskaņot šķidro kristālu displeja kontrastu.

C1 un C3 keramiskie kondensatori paredzēti parazītiskās induktivitātes mazināšanai, bet C4 un C5 elektrolītiskie kondensatori paredzēti elektrobarošanas sprieguma pulsāciju "gludināšanai". C5 kondensators nepieciešams, ja elektrobarošanai netiek izmantota baterija.

D2 taisngriežu diode paredzēta aizsardzībai pret nepareizu baterijas polaritāti.

SW1 slēdzis paredzēts elektriskās principiālās shēmas ieslēgšanai un izslēgšanai.






#ifndef F_CPU

#define F_CPU 8000000UL

#endif

 

#include <avr/io.h>

#include <stdio.h>

#include <inttypes.h>

#include <util/delay.h>

#include "lcd.h"

#include <string.h>

 

#define RTC_write_ADDRESS 0xD0

#define RTC_read_ADDRESS  0xD1

#define DS1307_SEC 0x00                                                              

 

 

typedef struct{                                                                       

            int sec;

            int min;

            int hour;

}rtc_time;

 

                                                                                   

void I2C_init();

void I2C_stop();

char I2C_read();

char I2C_read_NACK();

void I2C_write(char data);

void I2C_start();

void RTC_get_time(rtc_time *rtc);

void RTC_set_time(rtc_time *rtc);

void Time_set();

unsigned int Read_ADC();

void Init_ADC();

 

rtc_time rtc;                                                                

 

int main(){

           

                                                                                   

            DDRD = 0xFF;                                                          

            DDRB = 0x00;

           

            Init_ADC();

            InitLCD(0);                                                    

            Time_set();

            LCDClear();

            int prev_min=0, temperatura=0;

           

            while(1){

                       

                        _delay_ms(350);

                        LCDClear();

                        RTC_get_time(&rtc);

                                                                                                                                                                                   

                        rtc.hour = (rtc.hour>> 4) * 10 + (rtc.hour & 0x0F);

                        rtc.min = (rtc.min>> 4) * 10 + (rtc.min & 0x0F);

                        rtc.sec = (rtc.sec>>4) * 10 + (rtc.sec & 0x0F);

                        temperatura = Read_ADC()/2.05;

                       

                        if(rtc.min!=prev_min){

                                   

                                    if(prev_min>=59){

                                                prev_min=0;

                                    }

                                    else{

                                                prev_min=rtc.min;

                                    }

                                               

                                    LCDClear();

                                    LCDWriteStringXY(2,0,"TEMPERATURA");

                                    LCDWriteIntXY(5,1,temperatura,2);

                                    LCDWriteStringXY(8,1,"oC");

                                    _delay_ms(1000);      

                        }

                       

                       

                        LCDWriteStringXY(1,0,"PAREIZS  LAIKS");

                        LCDWriteIntXY(4,1,rtc.hour,2);

                        LCDWriteStringXY(6,1,":");

                        LCDWriteIntXY(7,1,rtc.min,2);

                        LCDWriteStringXY(9,1,":");

                        LCDWriteIntXY(10,1,rtc.sec,2);

 

            }

            return 0;

}

 

//===================== I2C ====================//

 

                                                                                    //Initializing i2c Communication

void I2C_init(){

                                                                                    //set status register to zero

  TWSR = 0x00;                                                                      //set presca1er bits to zero

  TWBR = 0x47;                                                                     //SCL frequency is 50K for 16Mhz

  TWCR = 0x04;                                                                     //enab1e TWI module

 

}

 

                                                                                    //Starting I2C communication

void I2C_start(){

           

  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);

  while((TWCR &(1<<TWINT))== 0);

 

}

 

                                                                                    //Writing through I2C

void I2C_write(char data){

           

  TWDR = data;

  TWCR = (1<<TWINT)|(1<<TWEN);

  while((TWCR &(1<<TWINT))==0);

 

 }

 

                                                                                    //Read through I2C

char I2C_read(){

           

  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);

  while(!(TWCR &(1<<TWINT)));

  return TWDR;

 

}         

 

 

 

char I2C_read_NACK(){

           

            TWCR = (1<<TWINT)|(1<<TWEN);

            while(!(TWCR &(1<<TWINT)));

            return TWDR;

 

}

 

           

                                                                                    //Stopping I2C communication

void I2C_stop(){

           

  TWCR = ((1<<TWINT)|(1<<TWSTO)|(1<<TWEN));

 

}

 

void RTC_init(){

           

            I2C_init();                                                                   // Initialize the I2C

    I2C_start();                                                                                     // Start I2C communication

    I2C_write(RTC_read_ADDRESS);                                               // Connect to DS1307 by sending its ID on I2c Bus

    I2C_write(RTC_write_ADDRESS);                                             // Select the Ds1307 ControlRegister to configure Ds1307

    I2C_write(0x00);                                                                 // Write 0x00 to Control register to disable SQW-Out

    I2C_stop();                                                                                      // Stop I2C communication after initializing

    _delay_ms(5);        

}

 

 

 

 

void RTC_set_time(rtc_time *rtc){

           

     I2C_init();                                                                                        // I2C init

    I2C_start();                                                                                       // Start I2C communication

    I2C_write(RTC_write_ADDRESS);                                             // connect to DS1307 by sending its ID on I2c Bus

    I2C_write(DS1307_SEC);                                                              // 0x00

    I2C_write(rtc->sec);                                                                       // Write sec from RAM address 00H

    I2C_write(rtc->min);                                                                    // Write min from RAM address 01H

    I2C_write(rtc->hour);                                                                 // Write hour from RAM address 02H

    I2C_stop();                                                                                   // Stop I2C communication after Setting the hours

            _delay_ms(5);

}

 

 

void RTC_get_time(rtc_time *rtc){

    

    I2C_start();                                                                                     // Start I2C communication

    I2C_write(RTC_write_ADDRESS);                                            // connect to DS1307 by sending its ID on I2c Bus

    I2C_write(DS1307_SEC);                                                             // Request sec RAM address at 00H

    I2C_stop();                                                                                      // Stop I2C communication after selecting Sec Register

    _delay_ms(5);                                            

    I2C_start();                                                                                     // Start I2C communication

    I2C_write(RTC_read_ADDRESS);                                               // connect to DS1307(Read mode) by sending its ID

    rtc->sec = I2C_read();                                                        // read second and return Positive ACK

    rtc->min =  I2C_read();                                                      // read minute and return Positive ACK

    rtc->hour = I2C_read_NACK();                                        

    I2C_stop();                                                                          // Stop I2C communication after reading the Date

 _delay_ms(5);                                                           

}

 

void Time_set(){

 

            int seconds=0, minutes=0, hours=0;

            int set_val=0, cnt=1;                                                   

            int temp_PINB = PINB;                                            

           

           

            while(1){

                       

                                   

                                    LCDWriteStringXY(2,0,"IEVADI LAIKU");

                                    _delay_ms(1000);

                                    LCDClear();

 

                                                while(1){

           

                                                            if(set_val==0){                                                                                                                                                          


                                                                                         LCDWriteStringXY(4,0,"SET TIME");        

                                                                        LCDWriteStringXY(1,1,"DEC/SELECT/INC");                                                                                                     

                                                            }

 

                                                            temp_PINB = PINB;                                                                                                                                                                                                                                                                                     

                                                            while((PINB & 0b00000111) == (temp_PINB & 0b00000111));                                                    

                                                            if(!(PINB & (1<<PINB1)) && (temp_PINB & (1<<PB1))){                                                                                                                                                                                                                                                                                                                                                                                                                                   cnt++;                                                                                                                                                 

if(cnt==4){

                                                                                    cnt = 0;

                                                                        }

                                                                        else{

                                                                                    cnt = cnt;

                                                                        }

                                                            }                         

                         

                                                            if(!(PINB & (1<<PINB2)) && (temp_PINB & (1<<PB2))){                                                                                              

                                                                        if(cnt == 1){                                                                                                                                                                                                                                                                                                               

                                                                                    seconds++;

                                                                                    if(seconds == 60){

                                                                                                seconds = 0;

                                                                                    }

                                                                        }

                                                                       

                                                                        else if (cnt == 2){                                                                                                                   

                                               

                                                                                    minutes++;

                                                                                    if(minutes == 60){

                                                                                                minutes = 0;

                                                                                    }         

                                                                        }

                                                                       

                                                                        else if (cnt == 3){                                                                                                                                                                   

                                                                                    hours++;

                                                                                    if(hours == 24){

                                                                                                hours = 0;

                                                                                    }         

                                                                        }

                                                                       

                                                                        else{

                                                                                                                                                                                                                       

                                                                                    break;

                                                                        }         

                                                            }

 

                                                            if(!(PINB & (1<<PINB0)) && (temp_PINB & (1<<PB0))){                                  

                                                                                                                                                                                                                       

                                                                        if(cnt == 1){

                                                                                                                                                                                   

                                                                                    seconds--;

                                                                                    if(seconds == -1){

                                                                                                seconds = 59;

                                                                                    }

                                                                        }

                                                                       

                                                                        else if (cnt == 2){

                                               

                                                                                    minutes--;

                                                                                    if(minutes == -1){

                                                                                                minutes = 59;

                                                                                    }         

                                               

                                                                        }

                                                                       

                                                                        else if (cnt == 3){

                                               

                                                                                    hours--;

                                                                                    if(hours == -1){

                                                                                                hours = 23;

                                                                                    }         

                                               

                                                                        }

                                                                       

                                                                        else{

                                                                                                                                                                                                                       

                                                                                    break;

                                                                        }

                                                            }

                         

                                                                                                                                                                                                                       

                                                            set_val=1;

                                                            LCDClear();

                                                            LCDWriteStringXY(0,0,"IEVADITAIS LAIKS");

                                                            LCDWriteIntXY(4,1,hours,2);

                                                            LCDWriteStringXY(6,1," ");

                                                            LCDWriteIntXY(7,1,minutes,2);

                                                            LCDWriteStringXY(9,1," ");

                                                            LCDWriteIntXY(10,1,seconds,2);

                       

                                                                                                                                                                                                                       

                                                            if(cnt == 3){

                                                                        LCDWriteStringXY(3,1,"^");

                                                            }

                                                           

                                                            else if(cnt == 2){

                                                                        LCDWriteStringXY(6,1,"^");

                                                            }

                                                           

                                                            else if(cnt == 1){

                                                                        LCDWriteStringXY(9,1,"^");

                                                            }

                                                           

                                                            else{                                       

                                                                        LCDWriteStringXY(0,1,">");

                                                            }

 

                       

                                                }                                             

                                               

                                                rtc.hour =((hours/10) << 4) + (hours%10);

                                                rtc.min = ((minutes/10) << 4) + (minutes%10);

                                                rtc.sec = ((seconds/10) << 4) + (seconds%10);

                                                RTC_set_time(&rtc);

                                                break;

                       

                        }

                       

}

 

 

 

void Init_ADC(){ 

 

ADMUX=(1<<REFS0);                                                                                               

ADCSRA=(1<<ADEN)|(1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0);            

                                                                                                                                                                                                                       

unsigned int Read_ADC(){   

            ADMUX |= 0x00;      

            ADCSRA |= (1<<ADSC);

            while(ADCSRA & (1<<ADSC));

            return (ADC);

                                                                                                                                                           

}

UZ SĀKUMU