// Alexander Brevig tərəfindən düymələr kitabxanası // Quraşdırma LED Matrisi // pin 12 displeydəki DataIn-ə qoşulur // pin 11 displeydəki CLK-ya qoşulur // pin 10 displeydə LOAD-a qoşulur LedControl lc = LedControl(6, 5, 4, 4); //3 pinləri 12, 11 və 10 olaraq təyin edir və sonra 4 displey təyin edir (maksimum 8 displeydir) //qlobal dəyişənlər bayt intensivliyi = 7; // Defolt intensivlik/parlaqlıq (0-15) bayt saat_rejimi = 0; // Standart saat rejimi. Defolt = 0 (əsas_rejim) bool təsadüfi_rejim = 0; // Təsadüfi rejimi müəyyənləşdirin - ekran tipini bir neçə saatdan bir dəyişir. Defolt = 0 (off) bayt köhnə_rejim = saat_rejimi; // Əvvəlki saat rejimini saxlayır, ona görə də tarixə getsək və ya nə olursa olsun, sonra hansı rejimə qayıtmağı bilirik. bool ampm = 0; // 12 və ya 24 saat vaxt təyin edin. 0 = 24 saat. 1 = 12 saat bayt dəyişdirmə_rejimi_zamanı = 0; // Təsadüfi rejimdə olduqda saat rejiminin növbəti dəyişəcəyi saatı saxlayır. imzalanmamış uzun gecikmə = 500; // Biz həmişə displey int rtc yeniləmələri arasında bir az gözləyirik; // Real vaxt saatı çıxışını saxlayır char günləri = ( "Günəş", "Bazar ertəsi", "Çərşənbə axşamı", "Çərşənbə", "Cümə", "Cümə", "Şənbə" ); //gün massivi - slayd, əsas_rejim və qarışıq rejimlərdə istifadə olunur (DS1307 həftənin günü üçün 1-7 dəyər verir) char daysfull = ( "Bazar", "Bazar ertəsi", "Çərşənbə axşamı", "Çərşənbə", "Cümə axşamı" ", "Cümə", "Şənbə" ); char şəkilçisi = ("st", "nd", "rd", "th" ); //tarix şəkilçisi massivi, slayd, əsas_rejim və qarışıq rejimlərdə istifadə olunur. məsələn, 1-ci 2-ci ... //sabitləri təyin edin #NUM_DISPLAY_MODES-i təyin edin 3 // Nömrəni göstərmə rejimləri (birinci rejim olaraq sıfırı təyin edin) #NUM_SETTINGS_MODES-i təyin edin 4 // Nömrə parametrləri rejimləri = 6 (birinci rejim olaraq sıfıra nəzarət) # SLIDE_DELAY 20 müəyyən et // Slayd rejimində hər simvol üçün slayd effekti üçün millisaniyələrlə vaxt. Daha yavaş effekt üçün bunu yüksək edin #define cls clear_display // Clear display RTC_DS1307 ds1307; // RTC obyekti yarat Button buttonA = Button(2, BUTTON_PULLUP); // Quraşdırma düyməsi A (düymə kitabxanasından istifadə etməklə) Düymə düyməsiB = Düymə (3, BUTTON_PULLUP); // Quraşdırma düyməsi B (düymə kitabxanasından istifadə etməklə) quraşdırmanı ləğv edin () ( digitalWrite(2, YÜKSEK); // 2-ci pindəki düymə üçün pullup rezistorunu yandırın digitalWrite(3, HIGH); // pin üzərindəki düymə üçün çəkmə rezistorunu yandırın 3 digitalWrite(4, HIGH); // 4-cü pin üzərindəki düymə üçün pullup rezistorunu yandırın Serial.begin(9600); //serialı başladın //4 matris panelini işə salın //biz yaradanda artıq cihazların sayını təyin etmişik. LedControl int cihazları = lc.getDeviceCount(); //biz (int ünvanı = 0; ünvan) üçün dövrədə bütün cihazları işə salmalıyıq.< devices; address++) {
/*The MAX72XX is in power-saving mode on startup*/
lc.shutdown(3-address, false);
/* Set the brightness to a medium values */
lc.setIntensity(3-address, intensity);
/* and clear the display */
lc.clearDisplay(3-address);
}
//Setup DS1307 RTC
#ifdef AVR
Wire.begin();
#else
Wire1.begin(); // Shield I2C pins connect to alt I2C bus on Arduino
#endif
ds1307.begin(); //start RTC Clock
if (! ds1307.isrunning()) {
Serial.println("RTC is NOT running!");
ds1307.adjust(DateTime(__DATE__, __TIME__)); // sets the RTC to the date & time this sketch was compiled
}
//Show software version & hello message
printver();
//enable red led
digitalWrite(13, HIGH);
}
void loop() {
//run the clock with whatever mode is set by clock_mode - the default is set at top of code.
switch (clock_mode){
case 0:
basic_mode();
break;
case 1:
small_mode();
break;
case 2:
slide();
break;
case 3:
word_clock();
break;
case 4:
setup_menu();
break;
}
}
//plot a point on the display
void plot (byte x, byte y, byte val) {
//select which matrix depending on the x coord
byte address;
if (x >= 0 && x<= 7) {
address = 3;
}
if (x >= 8 && x<= 15) {
address = 2;
x = x - 8;
}
if (x >= 16 && x<= 23) {
address = 1;
x = x - 16;
}
if (x >= 24 && x<= 31) {
address = 0;
x = x - 24;
}
if (val == 1) {
lc.setLed(address, y, x, true);
} else {
lc.setLed(address, y, x, false);
}
}
//clear screen
void clear_display() {
for (byte address = 0; address < 4; address++) {
lc.clearDisplay(address);
}
}
//fade screen down
void fade_down() {
//fade from global intensity to 1
for (byte i = intensity; i >0; i--) ( üçün (bayt ünvanı = 0; ünvan< 4; address++) {
lc.setIntensity(address, i);
}
delay(30); //change this to change fade down speed
}
clear_display(); //clear display completely (off)
//reset intentsity to global val
for (byte address = 0; address < 4; address++) {
lc.setIntensity(address, intensity);
}
}
//power up led test & display software version number
void printver() {
byte i = 0;
char ver_a = "MADE";
char ver_b = "IN";
char ver_c = "RUSSIA";
//test all leds.
for (byte x = 0; x <= 32; x++) {
for (byte y = 0; y <= 7; y++) {
plot(x, y, 1);
}
}
delay(300);
fade_down();
while (ver_a[i]) {
puttinychar((i * 4), 1, ver_a[i]);
delay(35);
i++;
}
delay(500);
fade_down();
i = 0;
while (ver_b[i]) {
puttinychar((i * 4), 1, ver_b[i]);
delay(35);
i++;
}
delay(500);
fade_down();
i = 0;
while (ver_c[i]) {
puttinychar((i * 4), 1, ver_c[i]);
delay(35);
i++;
}
delay(500);
fade_down();
}
// puttinychar
// Copy a 3x5 character glyph from the myfont data structure to display memory, with its upper left at the given coordinate
// This is unoptimized and simply uses plot() to draw each dot.
void puttinychar(byte x, byte y, char c)
{
byte dots;
if (c >= "A" && c<= "Z" || (c >= "a" && c<= "z")) {
c &= 0x1F; // A-Z maps to 1-26
}
else if (c >= "0" && c<= "9") {
c = (c - "0") + 32;
}
else if (c == " ") {
c = 0; // space
}
else if (c == ".") {
c = 27; // full stop
}
else if (c == ":") {
c = 28; // colon
}
else if (c == "\"") {
c = 29; // single quote mark
}
else if (c == "!") {
c = 30; // single quote mark
}
else if (c == "?") {
c = 31; // single quote mark
}
for (byte col = 0; col < 3; col++) {
dots = pgm_read_byte_near(&mytinyfont[c]);
for (char row = 0; row < 5; row++) {
if (dots & (16 >> sıra)) süjet(x + col, y + sətir, 1); başqa süjet(x + col, y + sıra, 0); ) ) ) void putnormalchar(bayt x, bayt y, char c) ( bayt nöqtələri; // əgər (c >= "A" && c)<= "Z" || (c >= "a" && c<= "z")) {
// c &= 0x1F; // A-Z maps to 1-26
// }
if (c >= "A" && c<= "Z") {
c &= 0x1F; // A-Z maps to 1-26
}
else if (c >= "a" && c<= "z") {
c = (c - "a") + 41; // A-Z maps to 41-67
}
else if (c >= "0" && c<= "9") {
c = (c - "0") + 31;
}
else if (c == " ") {
c = 0; // space
}
else if (c == ".") {
c = 27; // full stop
}
else if (c == "\"") {
c = 28; // single quote mark
}
else if (c == ":") {
c = 29; // clock_mode selector arrow
}
else if (c == ">") ( c = 30; // saat_rejimi seçici oxu ) əgər (c >= -80 && c)<= -67) {
c *= -1;
}
for (char col = 0; col < 5; col++) {
dots = pgm_read_byte_near(&myfont[c]);
for (char row = 0; row < 7; row++) {
//check coords are on screen before trying to plot
//if ((x >= 0) && (x<= 31) && (y >= 0) && (y<= 7)){
if (dots & (64 >> sətir)) ( // yalnız 7 sıra. plot(x + col, y + row, 1); ) else ( plot(x + col, y + row, 0); ) //) ) ) ) //kiçik_rejim //saniyələrlə vaxtı kiçik 3x5 simvolda göstərin void small_mode() ( char textchar; // displeydəki 16 simvol bayt mins = 100; //dəqiqə bayt saniyə = rtc; //saniyə bayt old_san = saniyə; / /köhnə saniyə dəyərini saxlayır - son saniyələrin yeniləndiyi vaxtdan və ya displeydə - saniyələrin dəyişib-dəyişmədiyini yoxlamaq üçün istifadə olunur cls(); // run_mode true isə (run_mode()) ( get_time(); / /düyməni yoxlayın, əgər (buttonA.uniquePress()) ( switch_mode(); return; ) əgər (buttonB.uniquePress()) ( display_date(); return; ) //saniyələr dəyişibsə, onları displeydə yeniləyin saniyələr = rtc; if (san != old_secs) ( //san char bufer; itoa(san, bufer, 10); //düzelt - əks halda, əgər nömrənin başlanğıc sıfırı varsa, məsələn, "03" saniyə, itoa bunu boşluqlu simvolları əhatə edir "3" əgər (san< 10) {
buffer = buffer;
buffer = "0";
}
puttinychar(20, 1, ":"); //seconds colon
puttinychar(24, 1, buffer); //seconds
puttinychar(28, 1, buffer); //seconds
old_secs = secs;
}
//if minute changes change time
if (mins != rtc) {
//reset these for comparison next time
mins = rtc;
byte hours = rtc;
if (hours > < 1) {
hours = hours + ampm * 12;
}
//byte dow = rtc; // the DS1307 outputs 0 - 6 where 0 = Sunday0 - 6 where 0 = Sunday.
//byte date = rtc;
//set characters
char buffer;
itoa(hours, buffer, 10);
//fix - as otherwise if num has leading zero, e.g. "03" hours, itoa coverts this to chars with space "3 ".
if (hours < 10) {
buffer = buffer;
//if we are in 12 hour mode blank the leading zero.
if (ampm) {
buffer = " ";
}
else {
buffer = "0";
}
}
//set hours chars
textchar = buffer;
textchar = buffer;
textchar = ":";
itoa (mins, buffer, 10);
if (mins < 10) {
buffer = buffer;
buffer = "0";
}
//set mins characters
textchar = buffer;
textchar = buffer;
//do seconds
textchar = ":";
buffer;
secs = rtc;
itoa(secs, buffer, 10);
//fix - as otherwise if num has leading zero, e.g. "03" secs, itoa coverts this to chars with space "3 ".
if (secs < 10) {
buffer = buffer;
buffer = "0";
}
//set seconds
textchar = buffer;
textchar = buffer;
byte x = 0;
byte y = 0;
//print each char
for (byte x = 0; x < 6 ; x++) {
puttinychar(x * 4, 1, textchar[x]);
}
}
delay(50);
}
fade_down();
}
// basic_mode()
// show the time in 5x7 characters
void basic_mode()
{
cls();
char buffer; //for int to char conversion to turn rtc values into chars we can print on screen
byte offset = 0; //used to offset the x postition of the digits and centre the display when we are in 12 hour mode and the clock shows only 3 digits. e.g. 3:21
byte x, y; //used to draw a clear box over the left hand "1" of the display when we roll from 12:59 ->12 saat rejimində saat 1:00. //amper 1 bayt saata təyin olunarsa, 12/24 saat çevrilmə edin = rtc; əgər (saat > 12) (saat = saat - ampm * 12; ) əgər (saat)< 1) {
hours = hours + ampm * 12;
}
//do offset conversion
if (ampm && hours < 10) {
offset = 2;
}
//set the next minute we show the date at
//set_next_date();
// initially set mins to value 100 - so it wll never equal rtc on the first loop of the clock, meaning we draw the clock display when we enter the function
byte secs = 100;
byte mins = 100;
int count = 0;
//run clock main loop as long as run_mode returns true
while (run_mode()) {
//get the time from the clock chip
get_time();
//check for button press
if (buttonA.uniquePress()) {
switch_mode();
return;
}
if (buttonB.uniquePress()) {
display_date();
return;
}
//check whether it"s time to automatically display the date
//check_show_date();
//draw the flashing: as on if the secs have changed.
if (secs != rtc) {
//update secs with new value
secs = rtc;
//draw:
plot (15 - offset, 2, 1); //top point
plot (15 - offset, 5, 1); //bottom point
count = 400;
}
//if count has run out, turn off the:
if (count == 0) {
plot (15 - offset, 2, 0); //top point
plot (15 - offset, 5, 0); //bottom point
}
else {
count--;
}
//re draw the display if button pressed or if mins != rtc i.e. if the time has changed from what we had stored in mins, (also trigggered on first entering function when mins is 100)
if (mins != rtc) {
//update mins and hours with the new values
mins = rtc;
hours = rtc;
//adjust hours of ampm set to 12 hour mode
if (hours >12) (saat = saat - ampm * 12; ) əgər (saat< 1) {
hours = hours + ampm * 12;
}
itoa(hours, buffer, 10);
//if hours < 10 the num e.g. "3" hours, itoa coverts this to chars with space "3 " which we dont want
if (hours < 10) {
buffer = buffer;
buffer = "0";
}
//print hours
//if we in 12 hour mode and hours < 10, then don"t print the leading zero, and set the offset so we centre the display with 3 digits.
if (ampm && hours < 10) {
offset = 2;
//if the time is 1:00am clear the entire display as the offset changes at this time and we need to blank out the old 12:59
if ((hours == 1 && mins == 0)) {
cls();
}
}
else {
//else no offset and print hours tens digit
offset = 0;
//if the time is 10:00am clear the entire display as the offset changes at this time and we need to blank out the old 9:59
if (hours == 10 && mins == 0) {
cls();
}
putnormalchar(1, 0, buffer);
}
//print hours ones digit
putnormalchar(7 - offset, 0, buffer);
//print mins
//add leading zero if mins < 10
itoa (mins, buffer, 10);
if (mins < 10) {
buffer = buffer;
buffer = "0";
}
//print mins tens and ones digits
putnormalchar(19 - offset, 0, buffer);
putnormalchar(25 - offset, 0, buffer);
}
}
fade_down();
}
//like basic_mode but with slide effect
void slide() {
byte digits_old = {99, 99, 99, 99}; //old values we store time in. Set to somthing that will never match the time initially so all digits get drawn wnen the mode starts
byte digits_new; //new digits time will slide to reveal
byte digits_x_pos = {25, 19, 7, 1}; //x pos for which to draw each digit at
char old_char; //used when we use itoa to transpose the current digit (type byte) into a char to pass to the animation function
char new_char; //used when we use itoa to transpose the new digit (type byte) into a char to pass to the animation function
//old_chars - stores the 5 day and date suffix chars on the display. e.g. "mon" and "st". We feed these into the slide animation as the current char when these chars are updated.
//We sent them as A initially, which are used when the clocl enters the mode and no last chars are stored.
//char old_chars = "AAAAA";
//plot the clock colon on the display
cls();
putnormalchar(13, 0, ":");
byte old_secs = rtc; //store seconds in old_secs. We compare secs and old secs. WHen they are different we redraw the display
//run clock main loop as long as run_mode returns true
while (run_mode()) {
get_time();
//check for button press
if (buttonA.uniquePress()) {
switch_mode();
return;
}
if (buttonB.uniquePress()) {
display_date();
return;
}
//if secs have changed then update the display
if (rtc != old_secs) {
old_secs = rtc;
//do 12/24 hour conversion if ampm set to 1
byte hours = rtc;
if (hours >12) (saat = saat - ampm * 12; ) əgər (saat< 1) {
hours = hours + ampm * 12;
}
//split all date and time into individual digits - stick in digits_new array
//rtc = secs //array pos and digit stored
//digits_new = (rtc%10); //0 - secs ones
//digits_new = ((rtc/10)%10); //1 - secs tens
//rtc = mins
digits_new = (rtc % 10); //2 - mins ones
digits_new = ((rtc / 10) % 10); //3 - mins tens
//rtc = hours
digits_new = (hours % 10); //4 - hour ones
digits_new = ((hours / 10) % 10); //5 - hour tens
//rtc = date
//digits_new = (rtc%10); //6 - date ones
//digits_new = ((rtc/10)%10); //7 - date tens
//draw initial screen of all chars. After this we just draw the changes.
//compare digits 0 to 3 (mins and hours)
for (byte i = 0; i <= 3; i++) {
//see if digit has changed...
if (digits_old[i] != digits_new[i]) {
//run 9 step animation sequence for each in turn
for (byte seq = 0; seq <= 8 ; seq++) {
//convert digit to string
itoa(digits_old[i], old_char, 10);
itoa(digits_new[i], new_char, 10);
//if set to 12 hour mode and we"re on digit 2 (hours tens mode) then check to see if this is a zero. If it is, blank it instead so we get 2.00pm not 02.00pm
if (ampm && i == 3) {
if (digits_new == 0) {
new_char = " ";
}
if (digits_old == 0) {
old_char = " ";
}
}
//draw the animation frame for each digit
slideanim(digits_x_pos[i], 0, seq, old_char, new_char);
delay(SLIDE_DELAY);
}
}
}
/*
//compare date digit 6 (ones) and (7) tens - if either of these change we need to update the date line. We compare date tens as say from Jan 31 ->01 fevral onda birlərin rəqəmi dəyişmir, əgər ((rəqəmlər_köhnə != rəqəmlər_yeni) || (rəqəmlər_köhnə != rəqəmlər_yeni)) ( //göstərilən günü dəyişdirin. Aşağıdakı dövrə növbə ilə 3 simvolun hər birindən keçir, məsələn, "MON" üçün (bayt day_char = 0; day_char<=2 ; day_char++){
//run the anim sequence for each char
for (byte seq = 0; seq <=8 ; seq++){
//the day (0 - 6) Read this number into the days char array. the seconds number in the array 0-2 gets the 3 chars of the day name, e.g. m o n
slideanim(6*day_char,8,seq,old_chars,days); //6 x day_char gives us the x pos for the char
delay(SLIDE_DELAY);
}
//save the old day chars into the old_chars array at array pos 0-2. We use this next time we change the day and feed it to the animation as the current char. The updated char is fed in as the new char.
old_chars = days;
}
//change the date tens digit (if needed) and ones digit. (the date ones digit wil alwaus change, but putting this in the "if" loop makes it a bit neater code wise.)
for (byte i = 7; i >= 6; i--)( əgər (rəqəmlər_köhnə[i] != rəqəmlər_yeni[i]) ( üçün (bayt ardıcıllığı = 0; ardıcıl)<=8 ; seq++){
itoa(digits_old[i],old_char,10);
itoa(digits_new[i],new_char,10);
slideanim(digits_x_pos[i],8,seq,old_char,new_char);
delay(SLIDE_DELAY);
}
}
}
//print the day suffix "nd" "rd" "th" etc. First work out date 2 letter suffix - eg st, nd, rd, th
byte s = 3; //the pos to read our suffix array from.
byte date = rtc;
if(date == 1 || date == 21 || date == 31) {
s = 0;
}
else if (date == 2 || date == 22) {
s = 1;
}
else if (date == 3 || date == 23) {
s = 2;
}
for (byte suffix_char = 0; suffix_char <=1 ; suffix_char++){
for (byte seq = 0; seq <=8 ; seq++){
slideanim((suffix_char*6)+36,8,seq,old_chars,suffix[s]); // we pass in the old_char array char as the current char and the suffix array as the new char
delay(SLIDE_DELAY);
}
//save the suffic char in the old chars array at array pos 3 and 5. We use these chars next time we change the suffix and feed it to the animation as the current char. The updated char is fed in as the new char.
old_chars = suffix[s];
}
}//end do date line
*/
//save digita array tol old for comparison next loop
for (byte i = 0; i <= 3; i++) {
digits_old[i] = digits_new[i];
}
}//secs/oldsecs
}//while loop
fade_down();
}
//called by slide
//this draws the animation of one char sliding on and the other sliding off. There are 8 steps in the animation, we call the function to draw one of the steps from 0-7
//inputs are are char x and y, animation frame sequence (0-7) and the current and new chars being drawn.
void slideanim(byte x, byte y, byte sequence, char current_c, char new_c) {
// To slide one char off and another on we need 9 steps or frames in sequence...
// seq# 0123456 <-rows of the display
// | |||||||
// seq0 0123456 START - all rows of the display 0-6 show the current characters rows 0-6
// seq1 012345 current char moves down one row on the display. We only see it"s rows 0-5. There are at display positions 1-6 There is a blank row inserted at the top
// seq2 6 01234 current char moves down 2 rows. we now only see rows 0-4 at display rows 2-6 on the display. Row 1 of the display is blank. Row 0 shows row 6 of the new char
// seq3 56 0123
// seq4 456 012 half old / half new char
// seq5 3456 01
// seq6 23456 0
// seq7 123456
// seq8 0123456 END - all rows show the new char
//from above we can see...
//currentchar runs 0-6 then 0-5 then 0-4 all the way to 0. starting Y position increases by 1 row each time.
//new char runs 6 then 5-6 then 4-6 then 3-6. starting Y position increases by 1 row each time.
//if sequence number is below 7, we need to draw the current char
if (sequence < 7) {
byte dots;
// if (current_c >= "A" && || (cari_c >= "a" && cari_c<= "z")) {
// current_c &= 0x1F; // A-Z maps to 1-26
// }
if (current_c >= "A" && cari_c<= "Z") {
current_c &= 0x1F; // A-Z maps to 1-26
}
else if (current_c >= "a" && cari_c<= "z") {
current_c = (current_c - "a") + 41; // A-Z maps to 41-67
}
else if (current_c >= "0" && cari_c<= "9") {
current_c = (current_c - "0") + 31;
}
else if (current_c == " ") {
current_c = 0; // space
}
else if (current_c == ".") {
current_c = 27; // full stop
}
else if (current_c == "\"") {
current_c = 28; // single quote mark
}
else if (current_c == ":") {
current_c = 29; //colon
}
else if (current_c == ">") ( cari_c = 30; // saat_rejimi seçici oxu ) bayt curr_char_row_max = 7 - ardıcıllıq; //çəkiləcək sətirlərin maksimum sayı 6-dır - sıra nömrəsi bayt start_y = ardıcıllıq; //başlamaq üçün y mövqeyi - eynidir ardıcıllıq nömrəsi. Biz bunu hər bir döngəyə daxil edirik // (bayt curr_char_row = 0; curr_char_row) üçün hər cərgəni maksimum sıraya qədər (ardıcıllıq nömrəsindən hesablanır) tərtib edirik<= curr_char_row_max; curr_char_row++) {
for (byte col = 0; col < 5; col++) {
dots = pgm_read_byte_near(&myfont);
if (dots & (64 >> curr_char_row)) süjet(x + col, y + start_y, 1); //plot led on else plot(x + col, y + start_y, 0); //else plot led off ) start_y++;//y-ə bir əlavə edək ki, növbəti cərgə birini aşağı çəkək ) ) //ardıcıllıq 1 ilə 7 arasındadırsa simvollar arasında boş sətir çəkin. Bunu etməsək, əldə edirik. cari simvolların qalıqları ekranda qalan son mövqe əgər (ardıcıllıq >= 1 && ardıcıllığı<= 8) {
for (byte col = 0; col < 5; col++) {
plot(x + col, y + (sequence - 1), 0); //the y position to draw the line is equivalent to the sequence number - 1
}
}
//if sequence is above 2, we also need to start drawing the new char
if (sequence >= 2) ( //xarakter bayt nöqtələrini işləyin; //əgər (new_c >= "A" && new_c<= "Z" || (new_c >= "a" && yeni_c<= "z")) {
// new_c &= 0x1F; // A-Z maps to 1-26
//}
if (new_c >= "A" && yeni_c<= "Z") {
new_c &= 0x1F; // A-Z maps to 1-26
}
else if (new_c >= "a" && yeni_c<= "z") {
new_c = (new_c - "a") + 41; // A-Z maps to 41-67
}
else if (new_c >= "0" && yeni_c<= "9") {
new_c = (new_c - "0") + 31;
}
else if (new_c == " ") {
new_c = 0; // space
}
else if (new_c == ".") {
new_c = 27; // full stop
}
else if (new_c == "\"") {
new_c = 28; // single quote mark
}
else if (new_c == ":") {
new_c = 29; // clock_mode selector arrow
}
else if (new_c == ">") ( new_c = 30; // saat_rejimi seçici oxu ) bayt newcharrowmin = 6 - (ardıcıllıq - 2); //yeni simvol üçün çəkmək üçün minimum sətir nömrəsi - bu, 2-8 sıra nömrələri verildikdə 6-dan 0-a qədər nəticə yaradır . Bu, yeni simvol baytı üçün çəkiləcək minimum cərgədir start_y = 0; //y mövqeyindən başlamaq üçün - sıra nömrəsi ilə eynidir. biz onu hər cərgə daxil edirik //hər cərgəni minimum sətirdən yuxarı çəkirik (ardıcıllıq nömrəsi ilə hesablanır) ) üçün 6-ya qədər (bayt newcharrow = newcharrowmin; newcharrow<= 6; newcharrow++) {
for (byte col = 0; col < 5; col++) {
dots = pgm_read_byte_near(&myfont);
if (dots & (64 >> newcharrow)) süjet(x + col, y + start_y, 1); //plot led on else plot(x + col, y + start_y, 0); //else plot led off ) start_y++;//y-ə bir əlavə edin ki, növbəti cərgə bir aşağı çəkək ) ) ) //rəqəmlərdən çox sözlərdən istifadə edərək saatı çap edin void word_clock() ( cls(); char numbers = ( "bir" ", "iki", "üç", "dörd", "beş", "altı", "yeddi", "səkkiz", "doqquz", "on", "on bir", "on iki", "on üç", "on dörd", "on beş", "on altı", "on yeddi", "on səkkiz", "on doqquz" ); simvol nömrələri = ( "on", "iyirmi", "otuz", "qırx", "əlli" ); //potensial olaraq 3 sətir char str_a; char str_b; char str_c; //bayt saat_y, mins_y; //saat və dəqiqələr və saatlar və dəqiqələr üçün mövqelər bayt saat = rtc; əgər (saat > 12) (saat = saat - ampm * 12; ) əgər (saat< 1) {
hours = hours + ampm * 12;
}
get_time(); //get the time from the clock chip
byte old_mins = 100; //store mins in old_mins. We compare mins and old mins & when they are different we redraw the display. Set this to 100 initially so display is drawn when mode starts.
byte mins;
//run clock main loop as long as run_mode returns true
while (run_mode()) {
//check for button press
if (buttonA.uniquePress()) {
switch_mode();
return;
}
if (buttonB.uniquePress()) {
display_date();
}
get_time(); //get the time from the clock chip
mins = rtc; //get mins
//if mins is different from old_mins - redraw display
if (mins != old_mins) {
//update old_mins with current mins value
old_mins = mins;
//reset these for comparison next time
mins = rtc;
hours = rtc;
//make hours into 12 hour format
if (hours >12) ( saat = saat - 12; ) if (saat == 0) (saat = 12; ) //mins dəyərini iki ayrı rəqəmə bölmək int minsdigit = rtc % 10; bayt minsdigitten = (rtc / 10) % 10; //əgər dəqiqə<= 10 , then top line has to read "minsdigti past" and bottom line reads hours
if (mins < 10) {
strcpy (str_a, numbers);
strcpy (str_b, "PAST");
strcpy (str_c, numbers);
}
//if mins = 10, cant use minsdigit as above, so soecial case to print 10 past /n hour.
if (mins == 10) {
strcpy (str_a, numbers);
strcpy (str_b, " PAST");
strcpy (str_c, numbers);
}
//if time is not on the hour - i.e. both mins digits are not zero,
//then make first line read "hours" and 2 & 3rd lines read "minstens" "mins" e.g. "three /n twenty /n one"
else if (minsdigitten != 0 && minsdigit != 0) {
strcpy (str_a, numbers);
//if mins is in the teens, use teens from the numbers array for the 2nd line, e.g. "fifteen"
//if (mins >= 11 && dəq<= 19) {
if (mins <= 19) {
strcpy (str_b, numbers);
}
else {
strcpy (str_b, numberstens);
strcpy (str_c, numbers);
}
}
// if mins digit is zero, don"t print it. read read "hours" "minstens" e.g. "three /n twenty"
else if (minsdigitten != 0 && minsdigit == 0) {
strcpy (str_a, numbers);
strcpy (str_b, numberstens);
strcpy (str_c, "");
}
//if both mins are zero, i.e. it is on the hour, the top line reads "hours" and bottom line reads "o"clock"
else if (minsdigitten == 0 && minsdigit == 0) {
strcpy (str_a, numbers);
strcpy (str_b, "O"CLOCK");
strcpy (str_c, "");
}
}//end worknig out time
//run in a loop
//print line a "twelve"
byte len = 0;
while (str_a) {
len++;
}; //get length of message
byte offset_top = (31 - ((len - 1) * 4)) / 2; //
//plot hours line
byte i = 0;
while (str_a[i]) {
puttinychar((i * 4) + offset_top, 1, str_a[i]);
i++;
}
//hold display but check for button presses
int counter = 1000;
while (counter >0)( //düymənin basılıb-baxılmadığını yoxlayın if (buttonA.uniquePress()) ( switch_mode(); return; ) if (buttonB.uniquePress()) ( display_date(); ) gecikmə(1); counter--; ) fade_down (); //çap xətti b len = 0; while (str_b) (len++; ); //mesajın uzunluğunu alın ofset_top = (31 - ((len - 1) * 4)) / 2; i = 0; while (str_b[i]) ( puttinychar((i * 4) + ofset_top, 1, str_b[i]); i++; ) //ekranı saxlayın, lakin düymələrin basıldığını yoxlayın counter = 1000; isə (counter > 0)( if (buttonA.uniquePress()) ( switch_mode(); return; ) if (buttonB.uniquePress()) ( display_date(); ) delay(1); counter--; ) fade_down() ; //varsa c sətrini çap edin. len = 0; while (str_c) (len++; ); //mesajın uzunluğunu alın ofset_top = (31 - ((len - 1) * 4)) / 2; i = 0; while (str_c[i]) ( puttinychar((i * 4) + ofset_top, 1, str_c[i]); i++; ) counter = 1000; isə (sayğac > 0)( //düyməni basıb yoxlayın if (buttonA.uniquePress()) ( switch_mode(); return; ) if (buttonB.uniquePress()) ( display_date(); ) gecikmə(1); counter- -; ) fade_down(); // ekranı boş saxlayın, lakin yenidən başlamazdan əvvəl düymələrin basılıb-baxılmadığını yoxlayın. sayğac = 1000; isə (sayğac > 0)( //düyməni basıb yoxlayın if (buttonA.uniquePress()) ( switch_mode(); return; ) if (buttonB.uniquePress()) ( display_date(); ) gecikmə(1); counter- -; ) ) fade_down(); ) /// sürüşdürmə mesajı - hazırda istifadə edilmir - çox yavaş. void scroll() ( char message = ("Salam"); cls(); bayt p = 6; //sətirdəki cari mövqe bayt chara = (0, 1, 2, 3, 4, 5); // simvollar sətirdən int x = (0, 6, 12, 18, 24, 30); //hər bayt üçün xpos y = 0; //y pos // clear_buffer(); while (message[p] != "\ 0") ( //bütün 6 simvolu çəkin (bayt c = 0; c< 6; c++) {
putnormalchar(x[c],y,message[ chara[c] ]);
//draw a line of pixels turned off after each char,otherwise the gaps between the chars have pixels left in them from the previous char
for (byte yy = 0 ; yy < 8; yy ++) {
plot(x[c] + 5, yy, 0);
}
//take one off each chars position
x[c] = x[c] - 1;
}
//reset a char if it"s gone off screen
for (byte i = 0; i <= 5; i++) {
if (x[i] < -5) {
x[i] = 31;
chara[i] = p;
p++;
}
}
}
}
//display_date - print the day of week, date and month with a flashing cursor effect
void display_date()
{
cls();
//read the date from the DS1307
byte dow = rtc; // day of week 0 = Sunday
byte date = rtc;
byte month = rtc - 1;
//array of month names to print on the display. Some are shortened as we only have 8 characters across to play with
char monthnames = {
"January", "February", "March", "April", "May", "June", "July", "August", "Sept", "October", "November", "December"
};
//print the day name
//get length of text in pixels, that way we can centre it on the display by divindin the remaining pixels b2 and using that as an offset
byte len = 0;
while(daysfull) {
len++;
};
byte offset = (31 - ((len-1)*4)) / 2; //our offset to centre up the text
//print the name
int i = 0;
while(daysfull[i])
{
puttinychar((i*4) + offset , 1, daysfull[i]);
i++;
}
delay(1000);
fade_down();
cls();
// print date numerals
char buffer;
itoa(date,buffer,10);
offset = 10; //offset to centre text if 3 chars - e.g. 3rd
// first work out date 2 letter suffix - eg st, nd, rd, th etc
// char suffix={"st", "nd", "rd", "th" }; is defined at top of code
byte s = 3;
if(date == 1 || date == 21 || date == 31) {
s = 0;
}
else if (date == 2 || date == 22) {
s = 1;
}
else if (date == 3 || date == 23) {
s = 2;
}
//print the 1st date number
puttinychar(0+offset, 1, buffer);
//if date is under 10 - then we only have 1 digit so set positions of sufix etc one character nearer
byte suffixposx = 4;
//if date over 9 then print second number and set xpos of suffix to be 1 char further away
if (date >9)( suffixposx = 8; puttinychar(4+ofset, 1, bufer); ofset = 8; //4 simvol olduqda mətnin mərkəzinə ofset ) //2 şəkilçi simvolu çap edin puttinychar(suffixposx+offset, 1, şəkilçi[s) ]); puttinychar(suffixposx+4+ofset, 1, şəkilçi[s]); gecikmə (1000); solğun_aşağı(); //ayın adını çap edin //mətnin uzunluğunu piksellə əldə edin, beləliklə, qalan pikselləri b2 bölməklə və onu ofset olaraq istifadə etməklə onu ekranda mərkəzləşdirə bilərik len = 0; while(ay adları) ( len++; ); ofset = (31 - ((len-1)*4)) / 2; //mətni mərkəzləşdirmək üçün ofsetimiz i = 0; while(ay adları[i]) ( puttinychar((i*4) +ofset, 1, ay adları[i]); i++; ) gecikmə(1000); solğun_aşağı(); ) //saat rejimini dəyişmək üçün dislpay menyusu void switch_mode() ( //bizim olduğumuz rejimi yadda saxla. Parametrlər rejiminə keçdiyimiz zaman bu dəyərdən istifadə edirik, ona görə də biz parametrlər rejimindən (6) istənilən rejimə qayıda bilərik. köhnə_rejim = saat_rejimi; char* rejimləri = ( "Əsas", "Kiçik", "Slayd", "Sözlər", "Quraşdırma"); bayt növbəti_saat_rejimi; bayt ilk iş = 1; //döyməni gözləyən dövrə (35-dən sonra vaxt aşımı) X rejiminə qayıtmaq üçün döngələr) for (int count = 0; count< 35 ; count++) {
//if user hits button, change the clock_mode
if (buttonA.uniquePress() || firstrun == 1) {
count = 0;
cls();
if (firstrun == 0) {
clock_mode++;
}
if (clock_mode >NUM_DISPLAY_MODES + 1) ( clock_mode = 0; ) //birinci sətirdə oxu və cari saat_rejimi adını çap edin və ikinci sətirdə növbəti saat_rejiminin adını çap edin char str_top; //strcpy (str_top, "-"); strcpy (str_top, rejimlər); növbəti_saat_rejimi = saat_rejimi + 1; əgər (next_clock_rejimi > NUM_DISPLAY_MODES + 1) ( next_clock_rejimi = 0; ) bayt i = 0; while (str_top[i]) ( putnormalchar(i * 6, 0, str_top[i]); i++; ) firstrun = 0; ) gecikmə(50); ) ) //run_mode əsl baytı qaytardığı müddətcə saatın əsas dövrəsini işlədin run_mode() ( //təsadüfi rejim aktivdirsə... rejimi dəyişdiyimiz zaman saatı yoxlayın. if (təsadüfi_rejim) ( //əgər saat dəyərini dəyişmə rejimində vaxt = saat. sonra false = yəni çıxış rejiminə qayıt. if (change_mode_time == rtc) ( //növbəti təsadüfi saat rejimini və onu dəyişdirmək üçün vaxtı təyin edin set_next_random(); //cari rejimdən çıxın. 0; ) ) / /else return 1 - bu rejimdə işləməyə davam edin qaytarın 1; ) //təsadüfi rejim boş olduqda saat rejimi dəyişəcək növbəti saatı təyin edin set_next_random() ( //saat rejiminin dəyişəcəyi növbəti saatı təyin edin - cari vaxt plus 1 - 4 saat get_time(); change_mode_time = rtc + təsadüfi (1, 5); //dəyişiklik_rejimi_zamanı indi 23-dən çox olarsa, onu səhər saat 1 ilə 3 arasında təyin edin, əgər (dəyişiklik_rejimi_zamanı > 23) (dəyişiklik_rejimi_zamanı = təsadüfi (1) , 4); ) //yeni saat rejimini təyin edin clock_mode = random(0, NUM_DISPLAY_MODES + 1); //yeni təsadüfi saat rejimi seçin ) //saat parametrlərini dəyişmək üçün dislpay menyusu void setup_menu() ( char* set_modes = () "Rndom", "24 Hr", "Set", "Brght", "Exit"); əgər (ampm == 0) ( set_rejimləri = ("12 Hr"); ) bayt ayarı_rejimi = 0; bayt sonrakı_setting_rejimi; bayt ilk iş = 1; // düyməni gözləyən dövrə (X rejiminə qayıtmaq üçün 35 döngədən sonra fasilə) for(int count=0; count< 35 ; count++) {
//if user hits button, change the clock_mode
if(buttonA.uniquePress() || firstrun == 1){
count = 0;
cls();
if (firstrun == 0) {
setting_mode++;
}
if (setting_mode >NUM_SETTINGS_MODES) ( settings_mode = 0; ) //birinci sətirdə oxu və cari saat_rejimi adını çap edin və ikinci sətirdə növbəti saat_rejiminin adını çap edin char str_top; strcpy (str_top, set_rejimləri); sonrakı_setting_rejimi = quraşdırma_rejimi + 1; əgər (next_setting_rejimi > NUM_SETTINGS_MODES) ( next_setting_rejim = 0; ) bayt i = 0; while(str_top[i]) ( putnormalchar(i*6, 0, str_top[i]); i++; ) firstrun = 0; ) gecikmə(50); ) //rejim keçidini seçin(setting_rejim)( hal 0: set_random(); fasilə; hal 1: set_ampm(); fasilə; hal 2: set_time(); fasilə; hal 3: set_intensity(); fasilə; hal 4: //menyunun fasiləsindən çıxmaq; ) //saatı 6-cı rejimdən (parametrlər) clock_mode=old_mode-dan əvvəlki vəziyyətə dəyişdirin; ) //təsadüfi rejimi dəyişdirin - bir neçə saatdan bir fərqli saat rejimi seçin void set_random())( cls(); char text_a = "Off"; char text_b = "On"; bayt i = 0; //təsadüfi rejimdirsə yandırın, onu söndürün, əgər (təsadüfi_rejim)( //təsadüfi rejimi söndürün random_mode = 0; //ekranda mesajı çap edin while(text_a[i]) ( putnormalchar((i*6), 0, text_a[i] ) ; i++; ) ) else ( //təsadüfi rejimi yandırın. random_mode = 1; //saat rejimini təyin edin set_next_random(); //ekranda mesajı çap edin while(text_b[i]) ( putnormalchar((i) * 6), 0, text_b[i]); i++; ) ) gecikmə (1500); //mesajı bir saniyə yuxarı buraxın ) //12 və ya 24 saatlıq saat boşluğunu təyin edin set_ampm() ( // AM/ PM və ya 24 saatlıq saat rejimi - biti çevirin (ampm rejimi üçün 0-ı 1-ə və ya 1-i 0-a çevirir) ampm = (ampm ^ 1); cls(); ) //ekran intensivliyini dəyişdirin void set_intensity() ( cls() ; bayt i = 0; char mətn = "Parlaq"; while(text[i]) ( puttinychar((i*4)+4, 0, text[i]); i++; ) // düymənin daxil edilməsini gözləyin ( ! buttonA.uniquePress()) ( səviyyə çubuğu (0.6,(intensivlik*2)+2.2); //intensivlik səviyyəsini bar kimi göstərərkən (buttonB.isPressed()) ( if(intensity == 15) ( intensity = 0; cls (); ) else ( intensity++; ) //yeni dəyəri çap edin i = 0; while(text[i]) ( puttinychar((i*4)+4, 0, text[i]); i++; ) //intensivlik səviyyəsini bar səviyyə çubuğu kimi göstərin (0,6,(intensivlik*2)+ 2,2); // üçün displeylərdə parlaqlıq parametrlərini dəyişdirin (bayt ünvanı = 0; ünvan< 4; address++) {
lc.setIntensity(address, intensity);
}
delay(150);
}
}
}
// display a horizontal bar on the screen at offset xposr by ypos with height and width of xbar, ybar
void levelbar (byte xpos, byte ypos, byte xbar, byte ybar) {
for (byte x = 0; x < xbar; x++) {
for (byte y = 0; y <= ybar; y++) {
plot(x+xpos, y+ypos, 1);
}
}
}
//set time and date routine
void set_time() {
cls();
//fill settings with current clock values read from clock
get_time();
byte set_min = rtc;
byte set_hr = rtc;
byte set_date = rtc;
byte set_mnth = rtc;
int set_yr = rtc;
//Set function - we pass in: which "set" message to show at top, current value, reset value, and rollover limit.
set_date = set_value(2, set_date, 1, 31);
set_mnth = set_value(3, set_mnth, 1, 12);
set_yr = set_value(4, set_yr, 2013, 2099);
set_hr = set_value(1, set_hr, 0, 23);
set_min = set_value(0, set_min, 0, 59);
ds1307.adjust(DateTime(set_yr, set_mnth, set_date, set_hr, set_min));
cls();
}
//used to set min, hr, date, month, year values. pass
//message = which "set" message to print,
//current value = current value of property we are setting
//reset_value = what to reset value to if to rolls over. E.g. mins roll from 60 to 0, months from 12 to 1
//rollover limit = when value rolls over
int set_value(byte message, int current_value, int reset_value, int rollover_limit){
cls();
char messages = {
"Set Mins", "Set Hour", "Set Day", "Set Mnth", "Set Year"};
//Print "set xyz" top line
byte i = 0;
while(messages[i])
{
puttinychar(i*4 , 1, messages[i]);
i++;
}
delay(2000);
cls();
//print digits bottom line
char buffer = " ";
itoa(current_value,buffer,10);
puttinychar(0 , 1, buffer);
puttinychar(4 , 1, buffer);
puttinychar(8 , 1, buffer);
puttinychar(12, 1, buffer);
delay(300);
//wait for button input
while (!buttonA.uniquePress()) {
while (buttonB.isPressed()){
if(current_value < rollover_limit) {
current_value++;
}
else {
current_value = reset_value;
}
//print the new value
itoa(current_value, buffer ,10);
puttinychar(0 , 1, buffer);
puttinychar(4 , 1, buffer);
puttinychar(8 , 1, buffer);
puttinychar(12, 1, buffer);
delay(150);
}
}
return current_value;
}
void get_time()
{
//get time
DateTime now = ds1307.now();
//save time to array
rtc = now.year();
rtc = now.month();
rtc = now.day();
rtc = now.dayOfWeek(); //returns 0-6 where 0 = Sunday
rtc = now.hour();
rtc = now.minute();
rtc = now.second();
//flash arduino led on pin 13 every second
//if ((rtc % 2) == 0) {
// digitalWrite(13, HIGH);
//}
//else {
// digitalWrite(13, LOW);
//}
//print the time to the serial port - useful for debuging RTC issues
/*
Serial.print(rtc);
Serial.print(":");
Serial.print(rtc);
Serial.print(":");
Serial.println(rtc);
*/
}
İndi cihazda işi başa çatdırmaq üçün yalnız bir sıra sadə əməliyyatları yerinə yetirməlisiniz:
Proqram kodunu tərtib etmək və daha sonra mikrokontrolörün yaddaşına yükləmək bir az vaxt aparacaq, adətən bir dəqiqədən çox deyil. Əməliyyatın uğurla başa çatması barədə Arduino IDE konsolunda məlumat veriləcək. Bundan sonra cihazdakı Reset düyməsini istifadə edərək Arduino-nu yenidən başlatmaq qalır - LED matrislərində sadə bir saat hazırdır!
Arduino-da hazır saat
Saat iki düymədən istifadə etməklə qurulur. Cihaz 12 və 24 saatlıq vaxt formatlarını dəstəkləyir, həftənin tarixini və gününü göstərir və vaxtı saniyələrlə və ya saniyəsiz göstərir. LED-lərin parlaqlığını dəyişdirmək də mümkündür.
Yəqin ki, gələcəkdə daha çox funksiya əlavə etmək istəyəcəksiniz (məsələn, termometr) və ya cihazı öz dizaynınız olan bir gövdəyə quraşdırmaq - lazer kəsmə maşınlarında istehsal etməklə yaxşı nəticələr əldə etmək olar. Ancaq indi əminliklə deyə bilərsiniz ki, öz əllərinizlə tam hüquqlu bir elektron saat yığmısınız!
Bir müddət əvvəl evdə saatın olmasına ehtiyac yarandı, ancaq elektron saat, çünki saatları sevmirəm, çünki onlar işarələnir. Lehimləmə və aşındırma sxemlərində kifayət qədər təcrübəm var. İnterneti araşdırdıqdan və bəzi ədəbiyyat oxuduqdan sonra ən sadə sxemi seçmək qərarına gəldim, çünki zəngli saata ehtiyacım yoxdur.
Asan olduğu üçün bu sxemi seçdim öz saatınızı düzəldin
Başlayaq, bəs öz əlimizlə saat düzəltmək üçün bizə nə lazımdır? Əlbətdə ki, əllər, dövrə diaqramlarını oxumaq, lehimləmə dəmiri və hissələri bacarıq (hətta böyük deyil). İstifadə etdiklərimin tam siyahısı budur:
10 MHz kvars – 1 əd., ATtiny 2313 mikrokontroller, 100 Ohm rezistorlar – 8 əd., 3 əd. 10 kOhm, 22 pF-lik 2 kondansatör, 4 tranzistor, 2 düymə, LED göstərici 4 bitlik KEM-5641-ASR (RL-F5610SBAW/D15). Quraşdırmanı birtərəfli PCB-də həyata keçirdim.
Ancaq bu sxemdə bir qüsur var: boşalmalara nəzarət etmək üçün cavabdeh olan mikrokontrolörün (bundan sonra MK adlandırılacaq) sancaqları kifayət qədər layiqli bir yük alır. Ümumi cərəyan maksimum port cərəyanından çox yüksəkdir, lakin dinamik göstərici ilə MK-nın həddindən artıq istiləşmə vaxtı yoxdur. MK-nın işləməməsinin qarşısını almaq üçün, boşalma dövrələrinə 100 Ohm rezistorlar əlavə edirik.
Bu sxemdə göstərici dinamik göstərici prinsipinə uyğun olaraq idarə olunur, buna görə göstərici seqmentləri MK-nın müvafiq çıxışlarından gələn siqnallarla idarə olunur. Bu siqnalların təkrarlanma tezliyi 25 Hz-dən çoxdur və buna görə də göstərici nömrələrinin parıltısı davamlı görünür.
Elektron saatlar yuxarıdakı sxemə uyğun olaraq hazırlanmışdır yalnız vaxtı (saat və dəqiqə) göstərə bilər və saniyələr seqmentlər arasında nöqtə ilə göstərilir, yanıb-sönür. Saatın iş rejiminə nəzarət etmək üçün onun strukturunda saatların və dəqiqələrin tənzimlənməsinə nəzarət edən düymələr var. Bu dövrə 5V enerji təchizatı ilə təchiz edilmişdir. Çap dövrə lövhəsinin istehsalı zamanı dövrəyə 5V zener diodu daxil edilmişdir.
5V enerji təchizatına malik olduğum üçün zener diodunu dövrədən xaric etdim.
Lövhəni hazırlamaq üçün bir dəmir istifadə edərək dövrə tətbiq edildi. Yəni, çap sxemi parlaq kağızdan istifadə edərək inkjet printerdə çap edilmişdir, müasir parlaq jurnallardan götürülə bilər. Daha sonra tələb olunan ölçüdə tekstolit kəsilib. Mənim ölçüsüm 36*26 mm oldu. Belə kiçik ölçü, bütün hissələrin SMD paketində seçildiyinə görədir.
Lövhə dəmir xlorid (FeCl 3) ilə işlənmişdir. Lövhə ilə vanna kamin üzərində olduğu üçün aşındırma təxminən bir saat çəkdi; aşındırma müddətinə yüksək temperatur təsir göstərir, lövhədə mis istifadə edilməmişdir. Ancaq temperaturu aşmayın.
Oxunma prosesi davam edərkən beynimi sındırmamaq və saatın işləməsi üçün proqram təminatı yazmamaq üçün İnternetə girdim və bu sxem üçün proqram təminatı tapdım. MK-ni necə yandırmaq olar İnternetdə də tapıla bilər. Mən yalnız ATMEGA MK-ləri yandıran bir proqramçı istifadə etdim.
Və nəhayət, lövhəmiz hazırdır və biz saatlarımızı lehimləməyə başlaya bilərik. Lehimləmə üçün MK və digər hissələri yandırmamaq üçün nazik bir ucu olan 25 Vt gücündə bir lehimləmə dəmirinə ehtiyacınız var. Lehimləməni diqqətlə həyata keçiririk və tercihen ilk dəfə MK-nın bütün ayaqlarını lehimləyirik, ancaq ayrıca. Bilməyənlər üçün, SMD paketində hazırlanmış hissələrin sürətli lehimləmə üçün terminallarında qalay olduğunu bilin.
Və lövhənin lehimlənmiş hissələri ilə belə görünür.
Yadımdadır... Otuz il əvvəl altı göstərici kiçik bir xəzinə idi. Daha sonra belə göstəricilərlə TTL məntiqindən istifadə edərək saat düzəldə bilən hər kəs öz sahəsində mükəmməl mütəxəssis hesab olunurdu.
Qaz-boşaltma göstəricilərinin parıltısı daha isti görünürdü. Bir neçə dəqiqədən sonra bu köhnə lampaların işləyə biləcəyini düşündüm və onlarla nəsə etmək istədim. İndi belə bir saat düzəltmək çox asandır. Sizə lazım olan tək şey mikrokontrollerdir...
Eyni zamanda yüksək səviyyəli dillərdə mikrokontrollerlərin proqramlaşdırılması ilə maraqlandığım üçün bir az oynamağa qərar verdim. Rəqəmsal qaz boşalma göstəricilərindən istifadə edərək sadə bir saat qurmağa çalışdım.
Dizaynın məqsədi
Qərara gəldim ki, saat altı rəqəmdən ibarət olmalıdır və vaxt minimum sayda düymə ilə təyin olunmalıdır. Bundan əlavə, müxtəlif istehsalçıların ən çox yayılmış mikrokontroller ailələrindən bir neçəsini istifadə etməyə çalışmaq istədim. Proqramı C dilində yazmaq niyyətində idim.
Qaz boşaltma göstəriciləri işləmək üçün yüksək gərginlik tələb edir. Amma mən təhlükəli şəbəkə gərginliyi ilə məşğul olmaq istəmədim. Saatın zərərsiz 12 V gərginliyi ilə işləməsi nəzərdə tutulurdu.
Əsas məqsədim oyun olduğu üçün burada mexaniki dizaynın və ya bədən təsvirlərinin heç bir təsvirini tapa bilməzsiniz. İstəyirsinizsə, zövqünüzə və təcrübənizə uyğun olaraq saatı özünüz dəyişə bilərsiniz.
Əldə etdiyim budur:
- Vaxt göstəricisi: HH MM SS
- Siqnal göstəricisi: HH MM --
- Vaxt göstərmə rejimi: 24 saat
- Dəqiqlik gündə ±1 saniyə (kvars kristalından asılı olaraq)
- Təchizat gərginliyi: 12 V
- Cari istehlak: 100 mA
Saat diaqramı
Altı rəqəmli rəqəmsal displeyi olan bir cihaz üçün multipleks rejimi təbii bir həll idi.
Blok diaqramının əksər elementlərinin məqsədi (Şəkil 1) şərhsiz aydındır. Müəyyən dərəcədə qeyri-standart vəzifə TTL səviyyələrinin yüksək gərginlikli göstərici idarəetmə siqnallarına çevrilməsinin yaradılması idi. Anod sürücüləri yüksək gərginlikli NPN və PNP tranzistorlarından istifadə etməklə hazırlanır. Diaqram Stefan Knellerdən götürülmüşdür (http://www.stefankneller.de).
74141 TTL çipində hər bir rəqəm üçün BCD dekoderi və yüksək gərginlikli sürücü var. Bir çip sifariş etmək çətin ola bilər. (Baxmayaraq ki, artıq onları kimsə düzəldirmi bilmirəm). Ancaq qaz boşalma göstəricilərini tapsanız, 74141 yaxın bir yerdə ola bilər :-). TTL məntiqi dövründə 74141 çipinə praktiki olaraq alternativ yox idi. Buna görə bir yerdə tapmağa çalışın.
Göstəricilər təxminən 170 V gərginlik tələb edir. Gərginlik çeviricisi üçün xüsusi bir dövrə hazırlamaq mənasızdır, çünki çox sayda gücləndirici çevirici çip var. Mən ucuz və geniş yayılmış IC34063-ü seçdim. Konverter sxemi demək olar ki, tamamilə MC34063 məlumat vərəqindən kopyalanır. T13 güc açarı ona yeni əlavə edilib. Daxili keçid belə yüksək gərginlik üçün uyğun deyil. Konvertor üçün endüktans kimi boğucu istifadə etdim. Şəkil 2-də göstərilmişdir; diametri 8 mm, uzunluğu 10 mm-dir.
Konvertorun səmərəliliyi olduqca yaxşıdır və çıxış gərginliyi nisbətən təhlükəsizdir. 5 mA yük cərəyanı ilə çıxış gərginliyi 60 V-ə düşür. R32 cərəyanı hiss edən rezistor kimi çıxış edir.
Məntiqi gücləndirmək üçün xətti tənzimləyici U4 istifadə olunur. Dövrə və lövhədə ehtiyat batareya üçün yer var. (3,6 V - NiMH və ya NiCd). D7 və D8 Schottky diodlarıdır və R37 rezistoru batareyanın xüsusiyyətlərinə görə şarj cərəyanını məhdudlaşdırmaq üçün nəzərdə tutulmuşdur. Yalnız əylənmək üçün saatlar tikirsinizsə, D7, D8 və R37 batareyasına ehtiyacınız olmayacaq.
Son dövrə Şəkil 3-də göstərilmişdir.
Vaxt təyini düymələri diodlar vasitəsilə birləşdirilir. Düymələrin vəziyyəti müvafiq çıxışda məntiqi “1” təyin edilməklə yoxlanılır. Bonus xüsusiyyəti olaraq, mikrokontrolörün çıxışına bir piezo emitter qoşulur. Bu murdar cığıltını söndürmək üçün kiçik açardan istifadə edin. Bir çəkic bunun üçün olduqca uyğun olardı, amma bu son çarədir :-).
Dövrə komponentlərinin siyahısı, PCB rəsmi və layout diaqramı "Yükləmələr" bölməsində tapıla bilər.
CPU
Minimum tələb olunan sayı Cədvəl 1-də göstərilən kifayət qədər sayda sancaqlı demək olar ki, hər hansı bir mikrokontroller bu sadə cihazı idarə edə bilər.
Cədvəl 1.
|
Funksiya
|
nəticələr
|
Qidalanma |
2
|
Kvars rezonatoru |
2
|
Anod idarəetmə |
6
|
Sürücü 74141 |
4
|
Düymə girişi |
1
|
Piezo emitent |
1
|
Ümumi |
16
|
|
Hər bir istehsalçı öz ailələrini və mikrokontroller növlərini inkişaf etdirir. Sancaqların yeri hər bir növ üçün fərdi. Bir neçə növ mikrokontroller üçün universal lövhə hazırlamağa çalışdım. Lövhədə 20 pinli rozetka var. Bir neçə keçid naqili ilə onu müxtəlif mikro nəzarətçilərə uyğunlaşdıra bilərsiniz.
Bu dövrədə sınaqdan keçirilmiş mikrokontrollerlər aşağıda verilmişdir. Digər növlərlə təcrübə edə bilərsiniz. Sxemin üstünlüyü müxtəlif prosessorlardan istifadə etmək imkanıdır. Radio həvəskarları, bir qayda olaraq, bir mikrokontroller ailəsindən istifadə edirlər və müvafiq proqramçı və proqram vasitələrinə malikdirlər. Digər istehsalçıların mikrokontrolörlərində problemlər ola bilər, ona görə də sizə sevimli ailənizdən bir prosessor seçmək imkanı verdim.
Müxtəlif mikrokontrollerlərin işə salınmasının bütün xüsusiyyətləri Cədvəl 2...5 və Şəkil 4...7-də öz əksini tapmışdır.
Cədvəl 2.
|
Sərbəst miqyas
|
|
Növ |
MC68HC908QY1 |
Kvars rezonatoru |
12 MHz |
Kondansatörler C1, C2 |
22 pF |
Proqram |
freescale.zip ("Yükləmələr" bölməsinə baxın) |
Parametrlər |
—
|
|
Qeyd: Kvars rezonatoru ilə paralel olaraq 10 MΩ rezistor birləşdirilir.
Cədvəl 3.
|
Mikroçip
|
|
Növ |
PIC16F628A |
Kvars rezonatoru |
32,768 kHz |
Kondansatörler C1, C2 |
22 pF |
Proqram |
pic628.zip ("Yükləmələr" bölməsinə baxın) |
Parametrlər |
Int. 4 MHz generator - I/O RA6, MCLR OFF, WDT OFF, LVP OFF, BROUT OFF, CP OFF, PWRUP OFF |
|
Qeyd: Mikrosxem rozetkada 180° döndərilməlidir.
Cədvəl 4.
|
Atmel
|
|
Növ |
ATtiny2313 |
Kvars rezonatoru |
12 MHz |
Kondansatörler C1, C2 |
15 pF |
Proqram |
attiny.zip ("Yükləmələr" bölməsinə baxın) |
Parametrlər |
kv. 8 MHz osilator, RESET ON |
|
Qeyd: RESET pininə (10 kΩ və 100 nF) SMD komponentləri R və C əlavə edin.
Cədvəl 5.
|
Atmel
|
|
Növ |
AT89C2051 |
Kvars rezonatoru |
12 MHz |
Kondansatörler C1, C2 |
22 pF |
Proqram |
at2051.zip ("Yükləmələr" bölməsinə baxın) |
Parametrlər |
--
|
|
Qeyd: SMD komponentləri R və C RESET pininə əlavə edin (10 kΩ və 100 nF); ulduzlarla işarələnmiş sancaqları 3,3 kOhm SMD rezistorları vasitəsilə +Ub enerji avtobusuna birləşdirin.
Müxtəlif mikrokontrollerlər üçün kodları müqayisə etdikdə, onların çox oxşar olduğunu görəcəksiniz. Limanlara giriş və kəsmə funksiyalarının tərifində, eləcə də aparat komponentlərindən asılı olanda fərqlər var.
Mənbə kodu iki bölmədən ibarətdir. Funksiya əsas() portları konfiqurasiya edir və kəsmə siqnallarını yaradan taymeri işə salır. Bundan sonra proqram basılan düymələri skan edir və müvafiq vaxt və həyəcan dəyərlərini təyin edir. Orada əsas döngədə cari vaxt zəngli saatla müqayisə edilir və piezo emitent işə salınır.
İkinci hissə taymer kəsmələrini idarə etmək üçün alt proqramdır. Hər millisaniyədə çağırılan alt proqram (taymerin imkanlarından asılı olaraq) vaxt dəyişənlərini artırır və ekran rəqəmlərinə nəzarət edir. Bundan əlavə, düymələrin vəziyyəti yoxlanılır.
Dövrəni işə salmaq
Komponentləri quraşdırarkən və quraşdırarkən enerji mənbəyindən başlayın. U4 tənzimləyicisini və ətrafdakı komponentləri lehimləyin. U2 üçün 5 V, U1 üçün 4,6 V gərginliyi yoxlayın. Növbəti addım yüksək gərginlikli çeviricinin yığılmasıdır. Gərginliyi 170 V-a təyin etmək üçün R36 kəsmə rezistorundan istifadə edin. Tənzimləmə diapazonu kifayət deyilsə, R33 rezistorunun müqavimətini bir qədər dəyişdirin. İndi U2 çipini, anod və rəqəmsal sürücü dövrəsinin tranzistorlarını və rezistorlarını quraşdırın. U2 girişlərini GND avtobusuna qoşun və R25 - R30 rezistorlarından birini ardıcıl olaraq +Ub enerji avtobusuna qoşun. Göstərici nömrələri müvafiq mövqelərdə yanmalıdır. Dövrənin yoxlanılmasının son mərhələsində U1 mikrosxeminin 19-cu pinini yerə qoşun - piezo emitter səs verməlidir.
Mənbə kodları və tərtib edilmiş proqramları “Yükləmələr” bölməsində müvafiq ZIP faylında tapa bilərsiniz. Proqramı mikrokontrollerə yandırdıqdan sonra U1 mövqeyində olan hər bir pinini diqqətlə yoxlayın və lazımi tel və lehim keçidlərini quraşdırın. Yuxarıdakı mikrokontroller şəkillərinə baxın. Mikrokontroller proqramlaşdırılıbsa və düzgün qoşulubsa, onun generatoru işə başlamalıdır. Siz vaxt və həyəcanı təyin edə bilərsiniz. Diqqət! Lövhədə daha bir düymə üçün yer var - bu gələcək genişləndirmələr üçün ehtiyat düymədir :-).
Generator tezliyinin düzgünlüyünü yoxlayın. Gözlənilən diapazonda deyilsə, C1 və C2 kondansatörlərinin dəyərlərini bir az dəyişdirin. (Kiçik kondensatorları paralel olaraq lehimləyin və ya başqaları ilə əvəz edin). Saatın dəqiqliyi yaxşılaşmalıdır.
Nəticə
Kiçik 8 bitlik prosessorlar yüksək səviyyəli dillər üçün olduqca uyğundur. C əvvəlcə kiçik mikrokontrollerlər üçün nəzərdə tutulmamışdı, lakin sadə proqramlar üçün ondan yaxşı istifadə edə bilərsiniz. Assembly dili kritik vaxtlar və ya maksimum CPU yükü tələb edən mürəkkəb tapşırıqlar üçün daha uyğundur. Əksər radio həvəskarları üçün C kompilyatorunun həm pulsuz, həm də shareware məhdud versiyaları uyğun gəlir.
C proqramlaşdırması bütün mikrokontrollerlər üçün eynidir. Siz seçilmiş mikrokontroller növünün aparat funksiyalarını (registrlər və periferiyalar) bilməlisiniz. Bit əməliyyatları ilə diqqətli olun - ATtiny üçün orijinalın nümunəsində göründüyü kimi, C dili fərdi bitləri manipulyasiya etmək üçün uyğun deyil.
Bitirdiniz? Sonra vakuum borularını nəzərdən keçirin və baxın...
...köhnə günlər qayıtdı... :-)
Redaktorun qeydi
SN74141-in tam analoqu Minsk Integral proqramı tərəfindən istehsal olunan K155ID1 mikrosxemdir.
Mikrosxem İnternetdə asanlıqla tapıla bilər.
Böyük rəqəmlərlə saat anlayışı
Struktur olaraq, cihaz iki lövhədən ibarət olacaq - biri digərinin üstündə. Birinci lövhə saat və dəqiqələri təşkil edən LED-lərin matrisidir, ikincisi güc hissəsidir (LED nəzarəti), məntiq və enerji təchizatı. Bu dizayn saatı daha yığcam edəcək (korpussuz, təxminən 22 sm x 9 sm, qalınlığı 4-5 santimetr) + bir şey səhv olarsa, matrisi başqa bir layihəyə vidalamağa imkan verəcəkdir.
Güc hissəsi UL2003 sürücüsü və tranzistor açarları əsasında qurulacaq. Məntiqi - Atmega8 və DS1307-də. Enerji təchizatı: 220V - transformator; lojik 5V (7805 vasitəsilə), güc hissəsi - 12V (LM2576ADJ vasitəsilə). Real vaxt saatının avtonom enerji təchizatı üçün 3V batareya üçün ayrıca bölmə olacaq - DS1307.
Mən Atmega8 və DS1307-dən istifadə etməyi düşünürəm (saatı tavandan asmağı planlaşdırıram, belə ki, elektrik kəsildiyi zaman hər dəfə parametrləri axtarmağa məcbur olmayacağam), lakin lövhənin tərtibatı cihazı DS1307 olmadan idarə etmək imkanı (ilk dəfə və bəlkə də əbədi - necə işləyəcək).
Beləliklə, konfiqurasiyadan asılı olaraq, saat proqramının iş alqoritmi aşağıdakı kimi olacaqdır:
Atmega8- taymer ilə vaxt sayğacı. Fasiləsiz bir dövrədə işləyin: klaviaturada səsvermə, vaxtı tənzimləmək (lazım olduqda), 4 rəqəm və ayırıcı göstərmək.
Atmega8+DS1307. Fasiləsiz bir dövrədə işləyin: klaviaturada səsvermə, DS1307 vaxtını tənzimləmək (lazım olduqda), DS1307-dən vaxtı oxumaq, 4 rəqəm və ayırıcı göstərmək. Və ya başqa bir seçim - DS1307-dən bir taymerdə oxumaq, qalanı bir döngədə (hələ ən yaxşısını bilmirəm).
Seqment ardıcıl olaraq birləşdirilmiş 4 qırmızı LED-dən ibarətdir. Bir rəqəm - ümumi anodlu 7 seqment. Adi göstəricilərdə olduğu kimi, səkkiz rəqəmindən istifadə edərək seqmentləri ayırmağı planlaşdırmıram.
Saatın güc hissəsi
Saatın güc hissəsi UL2003 sürücüsü və VT1 və VT2 tranzistor açarları üzərində qurulub.
UL2003 göstərici seqmentlərinə, düymələr isə rəqəmlərə nəzarət etmək üçün cavabdehdir.
Saat və dəqiqə ayırıcısı ayrıca idarə olunur (siqnal K8).
Seqmentlər, bitlər və separator K1-K8, Z1-Z4-ə müsbət potensial tətbiq etməklə (yəni +5V tətbiq etməklə) mikrokontroller tərəfindən idarə olunur.
İnformasiyanın dinamik çıxışını (saat və dəqiqə) təmin etmək üçün seqmentlərə və bitlərə siqnallar sinxron və müəyyən tezliklə verilməlidir.
Transistor BCP52 tranzistor VT1 (BCP53) kimi istifadə edilə bilər.
Böyük rəqəmlərlə saatın güc hissəsinin sxemi
Böyük nömrələri olan bir saat üçün yeddi seqmentli göstəricinin çap dövrə lövhəsi
Daha əvvəl dediyim kimi, saat iki çaplı elektron lövhədən ibarət olacaq - göstərici lövhəsi + məntiq və güc hissəsi.
Göstərici dövrə lövhəsinin dizaynı və istehsalı ilə başlayaq.
Böyük rəqəmləri olan saat üçün yeddi seqmentli göstərici üçün çap dövrə lövhəsinin hazırlanması
"Lay" formatında böyük nömrələri olan saat üçün yeddi seqmentli göstəricinin çap dövrə lövhəsi məqalənin sonunda, əlavə edilmiş fayllarda yerləşir. LUT metodundan istifadə edərək çap dövrə lövhələrinin istehsalı texnologiyası haqqında oxuya bilərsiniz.
Hər şeyi düzgün etmisinizsə, bitmiş PCB bu kimi görünəcək.
Böyük nömrələri olan bir saat üçün yeddi seqmentli göstəricinin bitmiş çap dövrə lövhəsi
Yeddi seqmentli göstəricinin yığılması
Göstərici lövhəsi iki tərəfli olduğundan, ediləcək ilk şey interlayer keçidləri etməkdir. Mən bunu lazımsız hissələrin ayaqlarından istifadə edərək edirəm - onları deliklərdən keçirib hər iki tərəfdən lehimləyirəm. Bütün keçidlər başa çatdıqda, onları düz, incə bir fayl ilə təmizləyirəm - çox səliqəli və gözəl çıxır.
Göstərici lövhəsində interlayer flakonlar
Növbəti addım, əslində, göstəricinin yığılmasıdır. Niyə bir paket qırmızı (yaşıl, ağ, mavi) LEDlərə ehtiyacımız var? Məsələn, mən bunları götürdüm.
Göstəricini yığmağa hazırlaşır
Diyotları quraşdırarkən, ümumi bir anod ilə bir göstərici hazırladığımızı unutmayın - yəni. "+" diodları bir-birinə birləşdirilməlidir. PCB-də ümumi anodlar böyük mis parçalarıdır. Bölmə nöqtəsi anoduna diqqət yetirdiyinizə əmin olun.
Göstərici çaplı elektron lövhədə anodların yeri
Nəticədə, 2 saatlıq əziyyətli işdən sonra bunu əldə etməlisiniz:
Yeddi seqment göstəricisi
Saatın rəqəmsal hissəsi
Aşağıdakı sxemə uyğun olaraq böyük nömrələrlə saatın rəqəmsal hissəsini yığacağıq:
Böyük rəqəmlərlə saat diaqramı
Saat dövrəsi olduqca şəffafdır, ona görə də onun necə işlədiyini izah etməkdə heç bir məna görmürəm. *.lay formatında çap edilmiş elektron lövhəni məqalənin sonunda yükləmək olar. Qeyd edək ki, çap dövrə lövhəsi əsasən səthə quraşdırılan hissələr üçün nəzərdə tutulub.
Beləliklə, istifadə etdiyim element bazası:
1. Diod körpüsü DFA028 (yerüstü montaj üçün hər hansı bir kompakt olacaq);
2. D2PAK korpusunda LM2576ADJ gərginlik tənzimləyiciləri, HSOP3-P-2.30A korpusunda 78M05;
3. Transistor açarları BCP53 (SOT223 korpusu) və BC847 (SOT23 korpusu);
4. Atmega8 mikro nəzarət cihazı (TQFP);
5. Real vaxt saatı DS1307 (SO8);
6. Bəzi köhnə cihazdan 14V 1.2A enerji təchizatı;
7. Qalan hissələr istənilən tipdir, çap elektron platada quraşdırmaq üçün uyğun ölçülüdür.
Əlbəttə ki, digər hissə paketlərindən istifadə etmək istəyirsinizsə, PCB-də bəzi dəyişikliklər etməlisiniz.
R3 və R4 müqavimət dəyərlərinə diqqət yetirin - onlar diaqramda göstərildiyi kimi olmalıdır - nə çox, nə də az. Bu, LM2576ADJ gərginlik tənzimləyicisinin çıxışında tam olaraq 12V təmin etmək üçün edilir. Əgər hələ də belə rezistor dəyərlərini tapa bilmirsinizsə, R4 müqavimətinin dəyəri düsturla hesablana bilər:
R4=R3(12/1.23-1) və ya R4=8.76R3
Rəqəmsal hissənin yığılması. Versiya 1, DS1307 olmadan
Saat üçün çap dövrə lövhəsi hazırlayarkən burada göstərilən tövsiyələrə əməl etmisinizsə, o zaman sizə xatırlatmağa ehtiyac yoxdur ki, montajdan əvvəl çap dövrə lövhəsi qazılmalı, üzərindəki bütün görünən qısa qapanmalar aradan qaldırılmalıdır və lövhə maye rozin ilə örtülməlidir? Sonra saatı yığmağa başlayırıq.
Enerji təchizatının yığılması ilə başlamağı və yalnız bundan sonra rəqəmsal hissəni quraşdırmağı məsləhət görürəm. Bu, cihazların öz-özünə yığılması üçün ümumi bir tövsiyədir. Niyə? Sadəcə ona görə ki, enerji təchizatı xəta ilə yığılıbsa, bu enerji təchizatı ilə təchiz edilməli olan bütün aşağı gərginlikli elektronikanı yandıra bilərsiniz.
Hər şey düzgün aparılırsa, enerji təchizatı dərhal işləməlidir. Enerji təchizatının yığılmasını yoxlayırıq - sınaq nöqtələrində gərginliyi ölçün.
Şəkil, təchizatı gərginliyinin yoxlanılmalı olduğu sınaq nöqtələrini göstərir. Gərginlik elan edilənə uyğundursa, saatın rəqəmsal hissəsini yığmağa başlaya bilərsiniz. Əks təqdirdə, enerji təchizatı elementlərinin quraşdırılmasını və funksionallığını yoxlayırıq.
Saat enerji təchizatı üçün sınaq nöqtələri və gərginlik dəyərləri
Enerji təchizatını yoxladıqdan sonra saatın rəqəmsal hissəsini yığmağa davam edirik - bütün digər elementləri çap dövrə lövhəsinə quraşdırırıq. Xüsusilə Atmega mikro nəzarət cihazının və UL2003 sürücüsünün ayaqlarında qısa qapanma olub olmadığını yoxlayırıq.
Saatın rəqəmsal hissəsinin quraşdırılması
Nəzərə alın ki, biz saatı DS1307 real vaxt saatını quraşdırmadan yığırıq, lakin bu çipin bütün naqilləri tamamlanmalıdır. Gələcəkdə, ehtiyac yaranarsa, bu, DS1307-də ayrıca, müstəqil real vaxt saatının hələ də istifadə olunacağı ikinci versiya üçün saatı dəyişdirmək üçün vaxtımıza qənaət edəcəkdir.
ATMEGA8 mikro nəzarətçisinin ilkin sınağı
Mikrokontrolörün düzgünlüyünü və funksionallığını yoxlamaq üçün bizə lazımdır:
1. Proqramçı, məsələn.
2. mikrokontrollerin sxemdaxili proqramlaşdırılması üçün.
3. AVRDUDESHELL proqramı.
Saat lövhəsini məlumat kabelinə bağlayırıq. Məlumat kabelini proqramçıya bağlayırıq. AVRDUDESHELL proqramının quraşdırıldığı kompüter üçün proqramçı. Saat lövhəsi 220V enerji təchizatına qoşulmamalıdır.
AVRDUDESHELL proqramı tərəfindən mikrokontrollerdən verilənlərin müvəffəqiyyətlə oxunması
Qoruyucuları oxuyarkən problemlər yaranarsa, quraşdırmanı yoxlayın - bir yerdə qısa qapanma və ya "itkin əlaqə" ola bilər. Başqa bir ipucu - bəlkə də mikro nəzarətçi aşağı sürətli proqramlaşdırma rejimindədir, onda proqramçını bu rejimə keçirin (