Электросхемы в помощниках.
Приветствую Вас, Гость · RSS Среда, 13.11.2024, 01:42











Главная » Файлы » AVR » AVR

Электронные "шахматные" часы.
13.05.2011, 08:54

Источник материала сайт http://c2.at.ua. 

Как ни велик интернет, однако простых и интересных схем не так уж просто и найти.

Вот, например часы типа шахматных, погуглил и мне не встретилась подобная схема, а ведь сделать самому такую схему на МК, это несложно.

Определение: «Часы для шахмат» называют часы с двумя устройствами индикации времени, соединенными друг с другом таким образом, что только одно из них может работать в одно и то же время.  

Приведу Вам простой пример таких шахматных часов (вообще-то это прототип в виде секундомера , а не таймера обратного отсчета, да еще и упрощенной версии без дополнительных функций, но это дело поправимо :))  исходник прилагается). 

Схема:

 

Функции: Управление происходит просто, при нажатой кнопке Кн-1 идет счет 1-го секундомера, при нажатой кнопке Кн-3 идет счет 2-го секундомера, кнопкой Кн-2 (сброс) обнуляем показания счета.

Если в управлении включения секундомеров использовать переключатель П2К или обыкновенный перекидной, это и будет примерно соответствовать нужной функциональности схемы.

 

В данном проекте основное, это  использование двух секундомеров, при желании их число можно увеличить, что может оказаться полезно и для других схем,  на примере этого проекта создаем его начало в CodeVisionAVR.

Сначала выберем МК и частоту. 


подключим LCD к   PORTB



а порт  PORTD  делаем  управление кнопок на вход с подтяжкой внутренними резисторами к +.




Самое интересное это сконфигурировать таймер на точный счет секунд.

Как это делается, мне очень доходчиво в свое время, помогла информация с сайта my-avr.at.uа.

В параметрах таймера выберем Timer 1, Clock Value 7,813 kHz, Interrupt on: Compare A Match, Comp. A = 1e85 (это чисто обозначает что он будет тактироваться с частотой в 1 секунду)
clock value - частота счета
Interrupt on Compare A match - прерывание по совпадению с регистром А



Здесь мы немного остановимся. Что это за число 1е85? Почему решили взять именно это число?

Итак, чтобы правильно посчитать какова частота работы таймера нужно открыть инженерный калькулятор. Число 1e85 (оно в 16-чной системе счисления) =7813 в 10ситичной с/ч. С этого следует что 7813(частота прерывания = 1 Гц)*5(сек)=39065 и перевести это в 16чную с/ч тогда мы получим 9899, вот это число вставляем в Comp. A и наш таймер будет работать с частотой 0,2 Гц то есть 1раз в 5секунд.
Генерируем код и сохраняем.

В коде таймера: (TIM1_COMPA)
Нужно вставить в середину следующие строки кода:
TCNT1H=0;
TCNT1L=0;
Для корректной работы таймера этим регистрам присваивается  0.
Вот исходный код получился в итоге.


Code

/*****************************************************
CodeWizardAVR V2.04.4a Advanced
Project : Shahmaty
Version : 1
Date : 13.05.2012
Company : http://c2.at.ua
Chip type : ATtiny2313
AVR Core Clock frequency: 8,000000 MHz
*****************************************************/
#include <tiny2313.h>
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>
#include <delay.h>
unsigned char sek_B, min_B, hour_B;
unsigned char sek_A, min_A, hour_A;

    interrupt [TIM1_COMPA] void timer1_compa_isr(void)
   {
   TCNT1H=0;
   TCNT1L=0;  
   if (PIND.2==0) { // Секундомер №1 разрешено
   sek_A ++ ; // инкрементирруем
   };
   if (PIND.4==0) { // Секундомер №2 разрешено
   sek_B ++ ; // инкрементирруем
   };  
  }

void main(void)
{
// Declare your local variables here

// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
PORTA=0x00;
DDRA=0x00;
PORTB=0x00;
DDRB=0x00;
PORTD=0x1C;
DDRD=0x00;

TCCR1A=0x00;
TCCR1B=0x05;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x1E;
OCR1AL=0x85;
OCR1BH=0x00;
OCR1BL=0x00;
TIMSK=0x40;
USICR=0x00;
ACSR=0x80;
lcd_init(16);
#asm("sei")

while (1)
{
lcd_gotoxy(0,0); // Место на дисплее
lcd_putchar(hour_A/10+0x30);
lcd_putchar(hour_A%10+0x30);
lcd_putchar(':');
lcd_putchar(min_A/10+0x30);
lcd_putchar(min_A%10+0x30);
lcd_putchar(':');
lcd_putchar(sek_A/10+0x30);
lcd_putchar(sek_A%10+0x30);
if (PIND.2==0) // на экране состояние 1-го секундомера
lcd_putsf(" <start1");
else
{
lcd_putsf(" < payza");
};
lcd_gotoxy(0,1); // Место на дисплее
if (PIND.4==0) // на экране состояние 2-го секундомера
lcd_putsf("start2> ");
else
{
lcd_putsf("payza > ");
};
lcd_putchar(hour_B/10+0x30);
lcd_putchar(hour_B%10+0x30);
lcd_putchar(':');
lcd_putchar(min_B/10+0x30);
lcd_putchar(min_B%10+0x30);
lcd_putchar(':');
lcd_putchar(sek_B/10+0x30);
lcd_putchar(sek_B%10+0x30);

if (sek_A==60) { min_A++, sek_A=0; }; // Условие работы секунд
if (min_A==60) { hour_A++, min_A=0; }; // Условие работы минут
if (hour_A==96) { hour_A=0; } ; // Условие работы часов в формате 4х суток

if (sek_B==60) { min_B++, sek_B=0; }; // Условие работы секунд
if (min_B==60) { hour_B++, min_B=0; }; // Условие работы минут
if (hour_B==96) { hour_B=0; } ; // Условие работы часов в формате 4х суток

if (PIND.3==0) { //общий сброс
hour_A=0;
min_A=0;
sek_A=0;
hour_B=0;
min_B=0;
sek_B=0;
};
};
}

 

Фьюзы для работы схемы с внешним кварцем нужно выставить так:

Проект в протеусе

Архив проекта 16х2; исходник, протеус, (прошивка, в папке проекта ЕХЕ.).


Это конечно интересно, но это просто два секундомера с накоплением отсчитанного времени, дальше все можно делать гораздо функциональней, вся фантазия в этой схеме может быть затруднена, только тем, как вывести на экран в 16 символов все функции и всю информацию, и что бы она там , была логически понятна, любому пользователю....

В общем arbeiten (продолжаем работать:)))) Пока на факт с количеством символов не обращаем внимание берем "пожирнее" индикатор, и добавляем в программу учет текущего времени.

Теперь схема становится гораздо интересней, так как,  мы видим на экране для каждого секундомера не только накопленное время , но и текущий отрезок времени , от начала нажатия кнопки пуск.

Код теперь имеет такой вид: 

Code
/*****************************************************
CodeWizardAVR V2.04.4a Advanced
Project : Shahmaty
Version : 1
Date : 13.05.2012
Author : C@at
Company : http://c2.at.ua
Chip type : ATtiny2313
AVR Core Clock frequency: 8,000000 MHz
*****************************************************/
#include <tiny2313.h>
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>
#include <delay.h>
unsigned char sek_A, min_A, hour_A;
unsigned char sek_AA, min_AA, hour_AA;
unsigned char sek_B, min_B, hour_B;
unsigned char sek_BB, min_BB, hour_BB;

interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{
TCNT1H=0;
TCNT1L=0;
if (PIND.2==0) { // Секундомер №1 разрешено
sek_A ++ ; // инкрементирруем
sek_AA ++ ; //
};
if (PIND.4==0) { // Секундомер №2 разрешено
sek_B ++ ; // инкрементирруем
sek_BB ++ ; //
};
}

void main(void)
{

#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
PORTA=0x00;
DDRA=0x00;
PORTB=0x00;
DDRB=0x00;
PORTD=0x1C;
DDRD=0x00;

TCCR1A=0x00;
TCCR1B=0x05;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x1E;
OCR1AL=0x85;
OCR1BH=0x00;
OCR1BL=0x00;
TIMSK=0x40;
USICR=0x00;
ACSR=0x80;
lcd_init(16);
#asm("sei")

while (1)
{
lcd_gotoxy(0,0); // Место на дисплее
lcd_putchar(hour_A/10+0x30);
lcd_putchar(hour_A%10+0x30);
lcd_putchar(':');
lcd_putchar(min_A/10+0x30);
lcd_putchar(min_A%10+0x30);
lcd_putchar(':');
lcd_putchar(sek_A/10+0x30);
lcd_putchar(sek_A%10+0x30);
if (PIND.2==0) // на экране состояние 1-го секундомера
lcd_putsf(" <start1");
else
{
lcd_putsf(" < payza");
hour_AA=0, min_AA=0, sek_AA=0; // сброс текущего времени
};
lcd_gotoxy(0,1); //
lcd_putchar(hour_AA/10+0x30);
lcd_putchar(hour_AA%10+0x30);
lcd_putchar(':');
lcd_putchar(min_AA/10+0x30);
lcd_putchar(min_AA%10+0x30);
lcd_putchar(':');
lcd_putchar(sek_AA/10+0x30);
lcd_putchar(sek_AA%10+0x30);

lcd_gotoxy(0,2); //
if (PIND.4==0) // на экране состояние 2-го секундомера
lcd_putsf("start2> ");
else
{
lcd_putsf("payza > ");
hour_BB=0, min_BB=0, sek_BB=0; // сброс текущего времени
};
lcd_putchar(hour_B/10+0x30);
lcd_putchar(hour_B%10+0x30);
lcd_putchar(':');
lcd_putchar(min_B/10+0x30);
lcd_putchar(min_B%10+0x30);
lcd_putchar(':');
lcd_putchar(sek_B/10+0x30);
lcd_putchar(sek_B%10+0x30);

lcd_gotoxy(8,3); //текущее время
lcd_putchar(hour_BB/10+0x30);
lcd_putchar(hour_BB%10+0x30);
lcd_putchar(':');
lcd_putchar(min_BB/10+0x30);
lcd_putchar(min_BB%10+0x30);
lcd_putchar(':');
lcd_putchar(sek_BB/10+0x30);
lcd_putchar(sek_BB%10+0x30);

if (PIND.3==0) { //общий сброс
hour_A=0, min_A=0, sek_A=0; // сброс времени
hour_AA=0, min_AA=0, sek_AA=0; // сброс текущего
hour_B=0, min_B=0, sek_B=0; // сброс времени
hour_BB=0, min_BB=0, sek_BB=0; // сброс текущего
};

if (sek_A==60) { min_A++, sek_A=0; }; // Условие работы секунд
if (min_A==60) { hour_A++, min_A=0; }; // Условие работы минут
if (hour_A==96) { hour_A=0; } ; // Условие работы часов в формате 4х суток

if (sek_AA==60) { min_AA++, sek_AA=0; }; // Условие работы секунд
if (min_AA==60) { hour_AA++, min_AA=0; }; // Условие работы минут
if (hour_AA==24) { hour_AA=0; } ; // Условие работы часов

if (sek_B==60) { min_B++, sek_B=0; }; // Условие работы секунд
if (min_B==60) { hour_B++, min_B=0; }; // Условие работы минут
if (hour_B==96) { hour_B=0; } ; // Условие работы часов в формате 4х суток

if (sek_BB==60) { min_BB++, sek_BB=0; }; // Условие работы секунд
if (min_BB==60) { hour_BB++, min_BB=0; }; // Условие работы минут
if (hour_BB==24) { hour_BB=0; } ; // Условие работы часов
};
}

 Кстати при  компиляции он занимает в МК  58,1%  FLASHа, и здесь  остаеется еще полно места для дальнейшего творчества в этом устройстве:)))))

 Архив проекта 16х4; исходник, протеус, прошивка


Еще  небольшие примеры, для интересующихся программированием на любительском уровне....






Категория: AVR | Добавил: c2
Просмотров: 6253
Всего комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Конструктор сайтов - uCoz
Copyright MyCorp © 2024