Рис. 7. Схема печатной платы устройства
Разработка программы для микроконтроллера
Разработка блок схемы программы
По сбросу программа стартует с адреса 0000h.
Далее происходит следующее:
Происходит настройка портов ввода-вывода.
Включаются встроенные подтягивающие резисторы
Выводится приветствие
Начинается индикация текущего времени и даты.
После инициализации программа работает циклически. Постоянно опрашивается состояние кнопок, обслуживается дисплей, проверяется не подавать ли звонок, после чего цикл повторяется.
Код программы автомат звонок микроконтроллер
/** Программа для автомата подачи звонков в учебном учреждении
Разработчики: Гудков Владислав, Соленов Андрей
МОГК 2012 Группа 4АСУ/09 */
#include <avr/io.h>
#include <util/delay.h>
#include "lcd.h"
#include "ds1307.h"
#define MENU (PINC&(1 << PC2))==0 && PINC&(1 << PC0) && PINC&(1 << PC1) && PINC&(1 << PC3)
#define OK (PINC&(1 << PC3))==0 && PINC&(1 << PC0) && PINC&(1 << PC1) && PINC&(1 << PC2)
#define HOUR (PINC&(1 << PC0))==0 && PINC&(1 << PC1) && PINC&(1 << PC2) && PINC&(1 << PC3)
#define MIN (PINC&(1 << PC1))==0 && PINC&(1 << PC0) && PINC&(1 << PC2) && PINC&(1 << PC3)
int main(void)
{
// Инициализация портов
_delay_ms(100);
DDRC = 0x00;= 0xFF;|=(1 << PB2);|=(0 << PB2);_init(); // Инициализация LCD
I2CInit(); // Инициализация шины I2C
// Запускаем ход часов
uint8_t temp;Read(0x00,&temp);&= ~(1 << 7); // обнуляем 7 битWrite(0x00,temp);
// Инициализация и объявление переменныхchar hour_za, minute_za, second_start, second_stop;char hour_zb, minute_zb;char hour_zc, minute_zc;char hour_zd, minute_zd;char hour_ze, minute_ze;char hour_zf, minute_zf;char hour_zj, minute_zj;char hour_zh, minute_zh;char hour_zi, minute_zi;char hour_zg, minute_zg;char hour_zk, minute_zk;char hour_zl, minute_zl;char hour_zm, minute_zm;char hour_zn, minute_zn;char hour_zo, minute_zo;char hour_zp, minute_zp;char v, i, menu, ok, k, a, c, e, zvon_vkl, f;=0;=0;=0;=0;=0;=0;=1;=1;_vkl=1;=1;_start = 0;_stop = 3;_za = 8;_za = 15;_zb = 9;_zb = 00;_zc = 9;_zc = 5;_zd = 9;_zd = 50;_ze = 10;_ze = 5;_zf = 10;_zf = 50;_zj = 10;_zj = 55;_zh = 11;_zh = 40;_zi = 12;_zi = 15;_zg = 13;_zg = 0;_zk = 13;_zk = 5;_zl = 13;_zl = 50;_zm = 14;_zm = 00;_zn = 14;_zn = 45;_zo = 14;_zo = 50;_zp = 15;_zp = 35;
// Ввывод приветствия(i=0; i<1; i++)
{_com(0x01);
_delay_ms(100);_string(0x85, "SolGud");
_delay_ms(1500);_com(0x01);
_delay_ms(100);_string(0x86, "2012");
_delay_ms(1500);_com(0x01);
_delay_ms(100);_string(0x86, "MOЎK");
_delay_ms(1500);_com(0x01);
_delay_ms(100);
}(1)
{ char hour, minute, second, day, date, month, years, temp;
// Читаем данные и преобразуем из BCD в двоичную системуRead(0x00,&temp); // Чтение регистра секунд
second = (((temp & 0xF0) >> 4)*10)+(temp & 0x0F);
DS1307Read(0x01,&temp); // Чтение регистра минут
minute = (((temp & 0xF0) >> 4)*10)+(temp & 0x0F);
DS1307Read(0x02,&temp); // Чтение регистра часов
hour = (((temp & 0xF0) >> 4)*10)+(temp & 0x0F);
DS1307Read(0x03,&temp); // Чтение регистра дней
day = (temp & 0x0F);Read(0x04,&temp); // Чтение регистра даты= (((temp & 0xF0) >> 4)*10)+(temp & 0x0F);
DS1307Read(0x05,&temp); // Чтение регистра месяца
month = (((temp & 0xF0) >> 4)*10)+(temp & 0x0F);
DS1307Read(0x06,&temp); // Чтение регистра года
years = (((temp & 0xF0) >>
4)*10)+(temp & 0x0F);
if(v==1)
{_com(0x08); // полное выключение дисплея_com(0x01); // очистка дисплея
_delay_us(100);_com(0x06); // сдвиг курсора вправо_com(0x0C); // включение дисплея, курсор не видим=0;
}
// Вывод часов и календаря_string(0xC1, " - -20 / "); // дата_com(0xC1); (date, 2); // Выводим на экран дату
if(month == 1) lcd_string(0xC4, "ЗЅі");if (month == 2) lcd_string(0xC4, "дeі"); if (month == 3) lcd_string(0xC4, "јap"); if (month == 4) lcd_string(0xC4, "aѕp"); if (month == 5) lcd_string(0xC4, "јa№"); if (month == 6) lcd_string(0xC4, "ёЖЅ"); if (month == 7) lcd_string(0xC4, "ёЖ»"); if (month == 8) lcd_string(0xC4, "aіґ"); if (month == 9) lcd_string(0xC4, "ceЅ"); if (month == 10) lcd_string(0xC4, "oєї"); if (month == 11) lcd_string(0xC4, "ЅoЗ");
else lcd_string(0xC4, "гeє"); // Выводим на экран месяц_com(0xCA); (years, 2); // Выводим на экран год
if(day == 1) lcd_string(0xCD, "BC");if (day == 2) lcd_string(0xCD, "ЁH"); if (day == 3) lcd_string(0xCD, "BT"); if (day == 4) lcd_string(0xCD, "CP"); if (day == 5) lcd_string(0xCD, "«T"); if (day == 6) lcd_string(0xCD, "ЁT");
else lcd_string(0xCD, "C "); // Выводим на экран день недели
lcd_string(0x84, " : : ");_com(0x84);
LCDWriteInt(hour, 2); // Выводим на экран часы_com(0x87); (minute, 2); // Выводим на экран минуты_com(0x8A); (second, 2); // Выводим на экран секунды_com(0x8E);(zvon_vkl == 1) lcd_data(0xED); // Выводим на экран индикатор включения/выключения звонка(MENU) // если кнопка "меню" нажата
{((PINC & (1 << PC2))==0){}=1;
}
// Вход в меню(menu)
{1: // Настройка времени(1)
{((v==0)||(k==0)||(a==1))
{_com(0x08); // полное выключение дисплея_com(0x01); // очистка дисплея
_delay_us(100);_com(0x06); // сдвиг курсора вправо_com(0x0C); // включение дисплея, курсор не видим
v=1;=1;=0;
}_string(0x86, "MEH°");_string(0xC1, "Hacїp. Аacoі >");
if(OK) // Если кнопка "ок" нажата
{((PINC & (1 << PC3))==0){}=1;
}(MIN) // Если нажата кнопка "Минуты+"
{((PINC & (1 << PC1))==0){} // Ждем отпускания кнопки
menu=2;;
}(ok==1)
{(k==1)
{_com(0x08); // полное выключение дисплея_com(0x01); // очистка дисплея
_delay_us(100);_com(0x06); // сдвиг курсора вправо_com(0x0C); // включение дисплея, курсор не видим
k=0;
}_string(0x81, "HACTPO¦KA «ACOB");_string(0xC5, " : ");_com(0xC5);
LCDWriteInt(hour, 2); // Выводим на экран часы_com(0xC8); (minute, 2); // Выводим на экран минуты(HOUR) // Если нажата кнопка "Часы+"
{((PINC & (1 << PC0))==0){} // Ждем отпускания кнопки++; // Увеличиваем часы на 1(hour > 23) hour = 0;
// Преобразуем из двоичной системы в BCD и записываем в DS1307
uint8_t temp;= ((hour/10) << 4)|(hour%10);Write(0x02, temp);
_delay_ms(100);
}(MIN) // Если нажата кнопка "Минуты+"
{((PINC & (1 << PC1))==0){} // Ждем отпускания кнопки++; // Увеличиваем минуты на 1(minute > 59) minute = 0;
// Преобразуем из двоичной системы в BCD и записываем в DS1307
uint8_t temp;= ((minute/10) << 4)|(minute%10);Write(0x01, temp);
_delay_ms(100);
}
/**Выход из настроек часов **/(OK) // Если кнопка "ок" нажата, то выход
{((PINC & (1 << PC3))==0){}=0;=1;
}(ok==0)
{break;}
}
/** Выход из меню **/(MENU) // если кнопка "меню" нажата
{((PINC & (1 << PC2))==0){}=0;;
}(menu=0){break;}
};2://Настройка даты(1)
{((a==0)||(v==0))
{_com(0x08); // полное выключение дисплея
lcd_com(0x01); // очистка дисплея
_delay_us(100);
lcd_com(0x06); // сдвиг курсора вправо_com(0x0C); // включение дисплея, курсор не видим
v=1;=1;
}_string(0x86, "MEH°");_string(0xC1, "< Hacїp. гaїГ >");
if(HOUR) // Если нажата кнопка "Часы+"
{((PINC & (1 << PC0))==0){} // Ждем отпускания кнопки=1;;
}(MIN) // Если нажата кнопка "Минуты+"
{((PINC & (1 << PC1))==0){} // Ждем отпускания кнопки=3;;
}(OK) // Если кнопка "ок" нажата
{((PINC & (1 << PC3))==0){}=1;
}(ok==1)
{(a==1)
{_com(0x08); // полное выключение дисплея_com(0x01); // очистка дисплея
_delay_us(100);_com(0x06); // сдвиг курсора вправо_com(0x0C); // включение дисплея, курсор не видим
a=0;
}_string(0x80, "Hacїpo№єa Аёc»a");_string(0xC4, " / / ");_com(0xC4);
LCDWriteInt(date, 2); // Выводим на экран дату
if(month == 1) lcd_string(0xC7, "ЗЅі");if (month == 2) lcd_string(0xC7, "дeі"); if (month == 3) lcd_string(0xC7, "јap"); if (month == 4) lcd_string(0xC7, "aѕp"); if (month == 5) lcd_string(0xC7, "јa№"); if (month == 6) lcd_string(0xC7, "ёЖЅ"); if (month == 7) lcd_string(0xC7, "ёЖ»"); if (month == 8) lcd_string(0xC7, "aіґ"); if (month == 9) lcd_string(0xC7, "ceЅ"); if (month == 10) lcd_string(0xC7, "oєї"); if (month == 11) lcd_string(0xC7, "ЅoЗ");
else lcd_string(0xC7, "гeє"); // Выводим на экран день месяц_com(0xCB); (years, 2); // Выводим на экран год
//настройка даты(MENU) // если кнопка "меню" нажата
{((PINC & (1 << PC2))==0){}++;(date > 31) date=1;_t temp;= ((date/10) << 4)|(date%10);Write(0x04, temp);
_delay_ms(100);
}(HOUR) // Если нажата кнопка "Часы+"
{((PINC & (1 << PC0))==0){} // Ждем отпускания кнопки++; // Увеличиваем часы на 1(month > 12) month = 1;
// Преобразуем из двоичной системы в BCD и записываем в DS1307
uint8_t temp;= ((month/10) << 4)|(month%10);Write(0x05, temp);
_delay_ms(100);
}
(MIN) // Если нажата кнопка "Минуты+"
{((PINC & (1 << PC1))==0){} // Ждем отпускания кнопки++; // Увеличиваем минуты на 1(years > 99) years = 0;
// Преобразуем из двоичной системы в BCD и записываем в DS1307
uint8_t temp;= ((years/10) << 4)|(years%10);Write(0x06, temp);
_delay_ms(100);
}
/**Переход в настройку дня недели **/(OK) // Если кнопка "ок" нажата, то выход
{((PINC & (1 << PC3))==0){}=2;
}(ok==2)
{break;}
}(ok==2)
{(v==1)
{_com(0x08); // полное выключение дисплея_com(0x01); // очистка дисплея
_delay_us(100);_com(0x06); // сдвиг курсора вправо_com(0x0C); // включение дисплея, курсор не видим
v=0;
}_string(0x82, "аeЅД Ѕeгe»ё");(day == 1) lcd_string(0xC7, "BC");if (day == 2) lcd_string(0xC7, "ЁH"); if (day == 3) lcd_string(0xC7, "BT"); if (day == 4) lcd_string(0xC7, "CP"); if (day == 5) lcd_string(0xC7, "«T"); if (day == 6) lcd_string(0xC7, "ЁT");
else lcd_string(0xC7, "C "); // Выводим на экран день недели(HOUR) // Если нажата кнопка "Часы+"
{((PINC & (1 << PC0))==0){} // Ждем отпускания кнопки++; // Увеличиваем день на 1(day > 7) day = 1;
// Преобразуем из двоичной системы в BCD и записываем в DS1307
uint8_t temp;= (day%10);Write(0x03, temp);
_delay_ms(100);
}
/**выход из настроек даты и дня недели**/(OK) // Если кнопка "ок" нажата, то выход
{((PINC & (1 << PC3))==0){}=0;
}(ok==0)
{break;}
}
/** Выход из меню **/(MENU) // если кнопка "меню" нажата
{((PINC & (1 << PC2))==0){}=0;;
}
};3: // Настройка вкл/выкл звонков
while(1)
{((c==1)||(e==0)||(v==0))
{_com(0x08); // полное выключение дисплея_com(0x01); // очистка дисплея
_delay_us(100);_com(0x06); // сдвиг курсора вправо_com(0x0C); // включение дисплея, курсор не видим
c=0;=1;=1;
}_string(0x86, "MEH°");_string(0xC0, "< Bє». ·іoЅєoі >");
if(MENU) // если кнопка "меню" нажата
{((PINC & (1 << PC2))==0){}=0;;
}
(HOUR) // Если нажата кнопка "Часы+"
{((PINC & (1 << PC0))==0){} // Ждем отпускания кнопки=2;;
}(MIN) // Если нажата кнопка "Минуты+"
{((PINC & (1 << PC1))==0){} // Ждем отпускания кнопки=4;;
}(OK) //Если кнопка "ок" нажата
{((PINC & (1 << PC3))==0){}=1;
}
(ok==1)
{(e==1)
{_com(0x08); // полное выключение дисплея_com(0x01); // очистка дисплея
_delay_us(100);_com(0x06); // сдвиг курсора вправо_com(0x0C); // включение дисплея, курсор не видим
e=0;=1;
}_string(0x82, "Bє». ·іoЅєoі");(zvon_vkl == 1) lcd_string(0xC2, "< Bє»ЖАeЅГ >");if (zvon_vkl == 0) lcd_string(0xC2, "< BГє»ЖАeЅГ >");
if(HOUR) // Если нажата кнопка "Часы+"
{((PINC & (1 << PC0))==0){} // Ждем отпускания кнопки_vkl++; // Увеличиваем часы на 1
if(zvon_vkl > 1) zvon_vkl = 0;
_delay_ms(100);
}(OK) //Если кнопка "ок" нажата
{((PINC & (1 << PC3))==0){}=0;
}(ok==0)
{break;}
}
/** Выход из меню **/(MENU) // если кнопка "меню" нажата
{((PINC & (1 << PC2))==0){}=0;;
}
};4: // Информация о разработчиках(1)
{((a==0)||(f==1)||(e==1))
{_com(0x08); // полное выключение дисплея_com(0x01); // очистка дисплея
_delay_us(100);_com(0x06); // сдвиг курсора вправо_com(0x0C); // включение дисплея, курсор не видим
a=1;=0;=0;=1;
}_string(0x86, "MEH°");_string(0xC1, "< Pa·paІoїАёєё");
if(MENU) // если кнопка "меню" нажата
{((PINC & (1 << PC2))==0){}=0;;
}(HOUR) // Если нажата кнопка "Часы+"
{((PINC & (1 << PC0))==0){} // Ждем отпускания кнопки=3;;
}(OK) //Если кнопка "ок" нажата
{((PINC & (1 << PC3))==0){}=1;
}(ok==1)
{(f==0)
{_com(0x08); // полное выключение дисплея_com(0x01); // очистка дисплея
_delay_us(100);_com(0x06); // сдвиг курсора вправо_com(0x0C); // включение дисплея, курсор не видим
f=1;
}_string(0x84, "4 AC©/09");_string(0xC1, "Ўyгєoі Co»µЅoі");
if(OK) // если кнопка "ок" нажата
{((PINC & (1 << PC3))==0){}=0;
}(ok==0)
{break;}
}
/** Выход из меню **/(MENU) // если кнопка "меню" нажата
{((PINC & (1 << PC2))==0){}=0;;
}
};: ;
}
// Проверка когда звонить
// 1 урок((hour==hour_za) && (minute==minute_za) && (second == second_start) && (day!=1) && (day!=7) && (zvon_vkl==1))
{|= _BV(PB2);
}((hour==hour_za) && (minute==minute_za) && (second == second_stop) && (day!=1) && (day!=7) && (zvon_vkl==1))
{&= ~_BV(PB2);
}
// 5 минут((hour==hour_zb) && (minute==minute_zb) && (second == second_start) && (day!=1) && (day!=7) && (zvon_vkl==1))
{|= _BV(PB2);
}((hour==hour_zb) && (minute==minute_zb) && (second == second_stop) && (day!=1) && (day!=7) && (zvon_vkl==1))
{&= ~_BV(PB2);
}
// 2 урок((hour==hour_zc) && (minute==minute_zc) && (second == second_start) && (day!=1) && (day!=7) && (zvon_vkl==1))
{|= _BV(PB2);
}((hour==hour_zc) && (minute==minute_zc) && (second == second_stop) && (day!=1) && (day!=7) && (zvon_vkl==1))
{&= ~_BV(PB2);
// перемена((hour==hour_zd) && (minute==minute_zd) && (second == second_start) && (day!=1) && (day!=7) && (zvon_vkl==1))
{|= _BV(PB2);
}((hour==hour_zd) && (minute==minute_zd) && (second == second_stop) && (day!=1) && (day!=7) && (zvon_vkl==1))
{&= ~_BV(PB2);
}
// 3 урок((hour==hour_ze) && (minute==minute_ze) && (second == second_start) && (day!=1) && (day!=7) && (zvon_vkl==1))
{|= _BV(PB2);
}((hour==hour_ze) && (minute==minute_ze) && (second == second_stop) && (day!=1) && (day!=7) && (zvon_vkl==1))
{&= ~_BV(PB2);
}
//5 минут((hour==hour_zf) && (minute==minute_zf) && (second == second_start) && (day!=1) && (day!=7) && (zvon_vkl==1))
{|= _BV(PB2);
}((hour==hour_zf) && (minute==minute_zf) && (second == second_stop) && (day!=1) && (day!=7) && (zvon_vkl==1))
{&= ~_BV(PB2);
}
// 4 урок((hour==hour_zj) && (minute==minute_zj) && (second == second_start) && (day!=1) && (day!=7) && (zvon_vkl==1))
{|= _BV(PB2);
}((hour==hour_zj) && (minute==minute_zj) && (second == second_stop) && (day!=1) && (day!=7) && (zvon_vkl==1))
{&= ~_BV(PB2);
}
// перемена((hour==hour_zh) && (minute==minute_zh) && (second == second_start) && (day!=1) && (day!=7) && (zvon_vkl==1))
{|= _BV(PB2);
}((hour==hour_zh) && (minute==minute_zh) && (second == second_stop) && (day!=1) && (day!=7) && (zvon_vkl==1))
{&= ~_BV(PB2);
}
// 5 урок((hour==hour_zi) && (minute==minute_zi) && (second == second_start) && (day!=1) && (day!=7) && (zvon_vkl==1))
{|= _BV(PB2);
}((hour==hour_zi) && (minute==minute_zi) && (second == second_stop) && (day!=1) && (day!=7) && (zvon_vkl==1))
{&= ~_BV(PB2);
}
// 5 минут((hour==hour_zg) && (minute==minute_zg) && (second == second_start) && (day!=1) && (day!=7) && (zvon_vkl==1))
{|= _BV(PB2);
}((hour==hour_zg) && (minute==minute_zg) && (second == second_stop) && (day!=1) && (day!=7) && (zvon_vkl==1))
{&= ~_BV(PB2);
}
// 6 урок((hour==hour_zk) && (minute==minute_zk) && (second == second_start) && (day!=1) && (day!=7) && (zvon_vkl==1))
{|= _BV(PB2);
}((hour==hour_zk) && (minute==minute_zk) && (second == second_stop) && (day!=1) && (day!=7) && (zvon_vkl==1))
{&= ~_BV(PB2);
}
// перемена((hour==hour_zl) && (minute==minute_zl) && (second == second_start) && (day!=1) && (day!=7) && (zvon_vkl==1))
{|= _BV(PB2);
}((hour==hour_zl) && (minute==minute_zl) && (second == second_stop) && (day!=1) && (day!=7) && (zvon_vkl==1))
{&= ~_BV(PB2);
}
// 7 урок((hour==hour_zm) && (minute==minute_zm) && (second == second_start) && (day!=1) && (day!=7) && (zvon_vkl==1))
{|= _BV(PB2);
}((hour==hour_zm) && (minute==minute_zm) && (second == second_stop) && (day!=1) && (day!=7) && (zvon_vkl==1))
{&= ~_BV(PB2);
}
//5 минут((hour==hour_zn) && (minute==minute_zn) && (second == second_start) && (day!=1) && (day!=7) && (zvon_vkl==1))
{|= _BV(PB2);
}((hour==hour_zn) && (minute==minute_zn) && (second == second_stop) && (day!=1) && (day!=7) && (zvon_vkl==1))
{&= ~_BV(PB2);
}
// 8 урок((hour==hour_zo) && (minute==minute_zo) && (second == second_start) && (day!=1) && (day!=7) && (zvon_vkl==1))
{|= _BV(PB2);
}((hour==hour_zo) && (minute==minute_zo) && (second == second_stop) && (day!=1) && (day!=7) && (zvon_vkl==1))
{&= ~_BV(PB2);
}
// окончание((hour==hour_zp) && (minute==minute_zp) && (second == second_start) && (day!=1) && (day!=7) && (zvon_vkl==1))
{|= _BV(PB2);
}((hour==hour_zp) && (minute==minute_zp) && (second == second_stop) && (day!=1) && (day!=7) && (zvon_vkl==1))
{&= ~_BV(PB2);
}
}
}
Заключение
Результаты, достигнутые при выполнении курсовой работы:
Проанализирована радиотехническая литература.
На основе структурной схемы спроектирована принципиальная электрическая схема автомата, разработана и изготовлена печатная плата устройства.
Разработана и написана программа на языке программирования Си для автомата подачи звонков.
При испытании автомата были выявлены некоторые недостатки, которые были устранены.
Цель курсовой работы была достигнута: разработан и создан автомат подачи звонков. Он будет использоваться в учебных заведениях. Также он может использоваться в других целях, т.е. там, где нужно подавать напряжение на различные источники питания в соответствии со временем, но при этом нужно будет задавать соответствующее время подачи сигнала.
Данный автомат подачи звонков может программно
дорабатываться и совершенствоваться.
Список информационных источников
Синдеев Ю.Г. Электротехника с основами электроники. Ростов-на Дону. 2010.
Шмаков С.Б. Энциклопедия радиолюбителя. Санкт-Петербург. 2010.
Подбельский В.В., Фомин С.С. Курс программирования на языке СИ. Москва. 2012
Керниган
Б., Ритчи Д. Язык программирования СИ. Москва. 2012
Приложение А
Микросхемы часов реального времени (RTC)