Пятница, 29.03.2024, 09:16
Микроконтроллерная техника AVR
Главная Регистрация Вход
Приветствую Вас, Гость · RSS
Меню сайта
Помоги сайту
Поддержи наш сайт
Через WebMoney
U222865683087
R391933670808
Z877043628365
E649133782052

или пополни нашу SMS копилку
SMS.копилка

Ссылки

 Каталог статей
Главная » Статьи » Учимся работать с AVR

Учимся использовать таймер. :) часть 2
Я предлагаю на практике освоить работу с основными возможностями таймера. Итак, начнем!
Давайте сделаем таймер в которого максимальное значение было 24 часа 59 мин. 59 сек :) Возьмем наш таймер и просто будем не инкрементировать(++) переменную, а декрементировать (--), для того чтобы таймер считал время назад. А в конце когда будет 00-00-00 на определенный порт выводилась лог. 1, в данном случае я использую светодиод.

Сделаем кнопки установки времени, START, STOP и RESET. Но RESET здесь необычный, он не выставляет все на 0 ибо при 00-00-00 срабатывает светодиод, так что RESET устанавливает время 00-00-03. Параметр сек., можно установить в строке unsigned char sek=3; где вместо 3 ставим любое другое значение. 

Главные регистры которые мы ипользовали:

TCCR1B&=0b11111000; // останавливаем таймер

 TCCR1B|=0b00000101; // запускаем таймер

Итак предлагаю схему: 


А вот и сам код.

#include <mega8.h>

// Alphanumeric LCD Module functions
#asm
  .equ __lcd_port=0x12 ;PORTD
#endasm
#include <lcd.h>
#include <delay.h> // подключаем библиотеку задержки
 
 unsigned char sek=3; // переменная сек. задаем стандартно 3 чтобы не зажечь светодиод сразу.
 unsigned char min; // пересенная мин.
 unsigned char hour; // переменная часов
// Timer 1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void) // таймер выставлен на частоту 1 Гц
{
// Place your code here
  TCNT1H=0;
  TCNT1L=0;
  sek--; // декрементируем переменную sek
   
}

// Declare your global variables here

void main(void)
{
PORTD=0x00; // порт как выход
DDRD=0xFF;

PORTB=0xFF; // порт как выход
DDRB=0x00;

PORTC=0xFF; // выставляем порт С на все кнопки.
DDRC=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 7,813 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x05;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x1E;
OCR1AL=0x85;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x10;

// LCD module initialization
lcd_init(16);

// Global enable interrupts
#asm("sei")
TCCR1B&=0b11111000; // останавливаем таймер
while (1)
  { 
   
  // роботаем с кнопками
  if (PINB.0==0) // если нажата первая кнопка
  {
  delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
  min++; // к значению минуты добавляем еденицу 
  }
  if (PINB.1==0) // если нажата вторая кнопка
  {
  delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
  min--; // от значения минуты вычитаем еденицу
  }
  if (PINB.2==0) // если нажата третья кнопка
  {
  delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
  hour++; // к значению час добавляем еденицу 
  }
  if (PINB.3==0) // если нажата четвертая кнопка
  {
  delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
  hour--; // от значения часов вычитаем еденицу
  }
   
  // главное условие 
  // мы его используем для того чтобы не можно было ввести 99 часов или 99 мин и 99 сек. :) по необходимости это можно убрать.  
  if (hour==25)
  hour=0;
  if (min==59)
  min=0;
  if (sek==59)
  sek=0;  
   
   
  if (PINB.4==0) // если нажата пятая кнопка
  {
  TCCR1B|=0b00000101; // запускаем таймер
  }
  if (PINC.0==0)  
  {
  TCCR1B&=0b11111000; // останавливаем таймер по необходимости
  }
  if (PINC.1==0) // если нажата шестая кнопка
  {
  delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
  sek++; // sek +1
  }
  if (PINC.2==0)  
  {
  delay_ms(250); // задержка 1/4 сек. (для удобства) выбора
  sek--; // sek -1
  }
  if (PINC.3==0)  
  {
  min=0;  
  hour=0;
  sek=1; // устанавливаем 1 секунду, для того чтобы порт не "зажегся"
  TCCR1B&=0b11111000; // останавливаем таймер
  PORTD.3=0;
  }
   
  ///// Условия таймера.
  if(sek==255) // сравнение переменной sek, почему 255 - потомучто переменная char когда у него значение 0 и мы вычитаем еще 1  
  { // то пулучаем 255.
  min--;
  sek=59;
  }
  if(min== 255) // сравнение переменной min
  {
  min=0;  
  sek=59;  
  hour--;  
  }
  if(hour== 0) //
  {
 min=59; // зануляем переменную "hour"
  }  
  if ( min==0 && sek==0 && hour==0) // если таймер срабатывает
  {
  PORTD.3=1; // включаем светодиод
  TCCR1B&=0b11111000; // останавливаем таймер
  }

  // выводим переменные
  lcd_gotoxy(4,0); // выводим посередине, если хотите вывести в начале дисплея тогда нужно выставить lcd_gotoxy(0,0);  
  lcd_putchar(hour/10+0x30);
  lcd_putchar(hour%10+0x30);
  lcd_putchar(':');
  lcd_putchar(min/10+0x30);
  lcd_putchar(min%10+0x30);  
  lcd_putchar(':');
  lcd_putchar(sek/10+0x30);
  lcd_putchar(sek%10+0x30);
   
  };
}

Прошивка и схема в Proteus, находиться в разделе файлы. Все вопросы на форум:)  

Проект не доделан, есть ошибки.


Категория: Учимся работать с AVR | Добавил: my-avr (18.01.2009)
Просмотров: 15408 | Комментарии: 4 | Рейтинг: 5.0/2 |
Всего комментариев: 4
4 Aleksey  
0
уменя не получается программно поменять время я хотелчтобы после отсчёта секунд в регистры сравнения вносились другие числа и делал вот так:

unsigned char time1=0x1E,time2=0x85;
void main (void)
{
........
........
........
OCR1AH=0x1E; //вместо OCR1AH=0x1E я писал OCR1AH=time1
OCR1AL=0x85; //вместо OCR1AL=0x1E я писал OCR1AL=time2
if(sek==255)
{
time1=1F; //это пример
time2=FF; //это пример
min--;
sek=59;
}
а он всё равно не меняет частоты wacko %)


3 Tigr_7  
0
Да, статья действительно хорошая. Доступная.
У мну вопрос: как я могу посчитать в таймер количество импульсов на входе за период времени, скажем, за 1 сек.? хочу замутить свой тахометр. Сильно не пинайте, если не так выразился - я тока учусь! )))

2 asm  
0
Да жаль что не доделан. Таймер не воспринимает часы минуты на каждом разряде считает только секунды. максимум данного таймера 00:00:59 секунд 00:59:59 будет тоже самое, и так тоже 23:59:59 В итоге просчитает только 59 секунд. Статья хорошая ! полёт идей и мыслей безграничен. Спасибо

1 Hoosim  
0
Блин, самая полезная штука недоделана. Абыдно, да.

Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Copyright My-AVR © 2024
Наша кнопка
У нас появилась кнопка, код кнопки:

Лаборатория самоделок на микроконтроллерах AVR

Форма входа
Наш опрос
Как вам материалы на сайте
Всего ответов: 863
Статистика/Друзья
CY-PR.com



Онлайн всего: 1
Гостей: 1
Пользователей: 0

РадиоКОТ - популярно об электронике. Авторские схемы, новые разработки. Обучение по электронике, микроконтроллерам, ПЛИС. Форум Сайт по радиоэлектронике. У нас все просто и интересно… ARV Reserch: Электроника — просто, полезно, увлекательно. Электронные устройства и программные средства для радиолюбителей и профессионалов, только авторские разработки, плагиата нет! Разработки на заказ. AVR projects Создание электронных роботов своими руками Схемы и программы на AVR http://ur5yfv.ucoz.ua/BANNER.gif Блог начинающего эмбеддера. Дай волю паяльнику! Самоделки на all-make.ru Принципиальные схемы Модулі автозапуску бензогенератора та системи АВР, електромонтажні роботи
Хостинг от uCoz