Суббота, 20.04.2024, 00:11
Микроконтроллерная техника AVR
Главная Регистрация Вход
Приветствую Вас, Гость · RSS
[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 1
  • 1
Форум » Микроконтроллеры » Вопросы по статьям » Таймер (помогите разобраться...)
Таймер
vit701-Дата: Воскресенье, 07.02.2010, 01:03 | Сообщение # 1
Рядовой
Группа: Пользователи
Сообщений: 11
Репутация: 1
Статус: Offline
В общем не пойму как запустить таймер, чтобы он считал миллисекунды...

Решил сделать задачку такого типа.

Есть любой свободный порт на Atmega8. На него раз в 250-1000 ms подается логическая единица. Как единица пришла нужно записать время в переменную и перезапустить таймер. Статьи про таймер не помогли.

Хотелось бы увидеть более подробно и понятного объяснения как cделать, чтобы инкрементировалась переменная времени раз в 1 мс,10,20 и.т.д

 
HiSERДата: Воскресенье, 07.02.2010, 10:36 | Сообщение # 2
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Репутация: 11
Статус: Offline
http://my-avr.at.ua/publ....-1-0-40
 
vit701-Дата: Воскресенье, 07.02.2010, 15:05 | Сообщение # 3
Рядовой
Группа: Пользователи
Сообщений: 11
Репутация: 1
Статус: Offline
Спасибо за помощь.

Но все же есть еще парочка вопросов.

Импульсы у вас подаются на порт D.2. Но в исходнике ни вижу связки с этим портом.

И еще не понятно зачем смена битов

void shiftbit(unsigned char newbit) {
if (newbit!=0) DS=1;
SH_CP=1;
SH_CP=0;
DS=0;
ST_CP=1;
ST_CP=0;
}

Это для 7 семисегментника?

 
HiSERДата: Воскресенье, 07.02.2010, 17:02 | Сообщение # 4
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Репутация: 11
Статус: Offline
Внешние прерывания:
PORTD.2 - INT0
PORTD.3 - INT1

shiftbit - это для семи-сегментника

 
vit701-Дата: Воскресенье, 07.02.2010, 21:44 | Сообщение # 5
Рядовой
Группа: Пользователи
Сообщений: 11
Репутация: 1
Статус: Offline
HiSER, Я вам очень благодарен.

Добавлено (07.02.2010, 21:44)
---------------------------------------------
Все таки от в этом месте хотелось бы поподробнее.

void tmr_start() {
TCNT1=0; //Обнуляем счетчик
//Устанавливаем делитель 64
//Частота МК 1000KHz/64=15.625KHz
//15625 тиков в секунду, промежуток времени до переполнения 65536/15625=4.1943s
TCCR1B=0x03;
}

Не пойму как здесь фигурирует цифра 64.

Связанны ли настройки таймера с частотой мк. Я вот хочу работать на 8 мгц.

Просто я собрал эту схему в протеусе, только семисегментник заменил на rs232
Прерывание срабатывает только 1 раз.

И переменная show_data выводится со значением 0.

Частота мк в протеусе 8 мгц. когда ставлю на 1 не работает данная прошивка.

*********
Вот код.

#include <mega8.h>
#include <stdio.h>
#include <delay.h>

int show_data=0; //Отображаемое число

void tmr_start() {
TCNT1=0; //Обнуляем счетчик
//Устанавливаем делитель 64
//Частота МК 1000KHz/64=15.625KHz
//15625 тиков в секунду, промежуток времени до переполнения 65536/15625=4.1943s
TCCR1B=0x03;
}

void tmr_stop(void) {
TCCR1B=0x00; //Выключаем счетчик
}

//Внешнее прерывание
interrupt [EXT_INT0] void ext_int0_isr(void) {
tmr_stop(); //Останавливаем счетчик
//[Счетчик]/(15625/1000)=промежуток в ms
//Сохраняем для отображения в переменой show_data
show_data=TCNT1/15.625;

printf("time= %i\r",show_data);

tmr_start(); //Включаем счетчик
}

//Прерывание переполниния счетчика 1
interrupt [TIM1_OVF] void timer1_ovf_isr(void) {
tmr_stop(); //Останавливаем счетчик
TCNT1--; //Устанавливаем максимальное значение счетчика
}

void main(void) {

UCSRA=0x00;
UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;

DDRB=7; //Выход для семи-сегментника
TCCR1A=0x00; //Устанавливаем нормальный режим счетчика, максимальное значение 0xffff
//Устанавливаем внешнее прерывание INT0, по поднятию уровня
GICR=0x40;
MCUCR=0x03;
GIFR=0x40;
TIMSK=0x04; //Прерывание для счетчика 1
#asm("sei") //Разрешаем прерывание
while (1)
{
delay_ms(1);
}

}

Сообщение отредактировал vit701- - Воскресенье, 07.02.2010, 21:45
 
HiSERДата: Воскресенье, 07.02.2010, 23:28 | Сообщение # 6
Продвинутый автор!
Группа: Проверенные
Сообщений: 254
Репутация: 11
Статус: Offline
64 это делитель выставляется в TCCR1B, частота таймера = частота мк / делитель
не плохо было бы тебе ознакомиться с http://www.alldatasheet.com/datasheet-pdf/pdf/80247/ATMEL/ATMEGA8.html
не хорошее место нашел для printf, лучше в цикл запихай.
иначе счет будет не правильный.
 
vit701-Дата: Среда, 10.02.2010, 21:15 | Сообщение # 7
Рядовой
Группа: Пользователи
Сообщений: 11
Репутация: 1
Статус: Offline
Разобрался почему таймер не стартовал. Просто автор забыл его запустить)
С расчетами тоже разобрался) Спасибо вам)

В исходнике добавьте в void main(void)

tmr_start();

Добавлено (10.02.2010, 21:15)
---------------------------------------------
Вот исправленный код с выводом на RS-232

#include <mega8.h>
#include <stdio.h>
#include <delay.h>

int show_data=0; //Отображаемое число

void tmr_start2() {
printf("time_pre= %i\r",show_data);
}

void tmr_start() {
TCNT1=0; //Обнуляем счетчик
//Устанавливаем делитель 64
//Частота МК 1000KHz/64=15.625KHz
//15625 тиков в секунду, промежуток времени до переполнения 65536/15625=4.1943s
TCCR1B = 0b00000101;
}

void tmr_stop(void) {
TCCR1B=0x00; //Выключаем счетчик
}

//Внешнее прерывание
interrupt [EXT_INT0] void ext_int0_isr(void) {
tmr_stop(); //Останавливаем счетчик
//[Счетчик]/(15625/1000)=промежуток в ms
//Сохраняем для отображения в переменой show_data
show_data=TCNT1/7.8125;
printf("time_pre= %i\r",show_data);
TCNT1=0; //Обнуляем счетчик
tmr_start();

}

//Прерывание переполниния счетчика 1
interrupt [TIM1_OVF] void timer1_ovf_isr(void) {
tmr_stop(); //Останавливаем счетчик
TCNT1--; //Устанавливаем максимальное значение счетчика
}

void main(void) {


UCSRA=0x00;
UCSRB=0x08;
UCSRC=0x86;
UBRRH=0x00;
UBRRL=0x33;

DDRB=7; //Выход для семи-сегментника
TCCR1A=0x00; //Устанавливаем нормальный режим счетчика, максимальное значение 0xffff
//Устанавливаем внешнее прерывание INT0, по поднятию уровня
GICR=0x40;
MCUCR=0x03;
GIFR=0x40;
TIMSK=0x04; //Прерывание для счетчика 1
#asm("sei") //Разрешаем прерывание
tmr_start();
}

Сообщение отредактировал vit701- - Среда, 10.02.2010, 20:49
 
Co@ateДата: Четверг, 01.12.2011, 14:08 | Сообщение # 8
Рядовой
Группа: Пользователи
Сообщений: 3
Репутация: 0
Статус: Offline
Здраствуйте. Спасибо очень хорошие примеры на вашем сайте ,и очень важно что примеры реально работают в железе, вот этот например http://my-avr.at.ua/publ/1-1-0-19 собрал учел добавления в коментариях, работает вещь !!!
У меня такой вопрос , вот там есть иницилизация таймера А
Code

// 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
     
}

Скажите, а второй таймер там можно также включить , что бы на одном МК работало два независимых таймера, (например для циклического таймера)
С моими знаниями , я тут просто уже моск сломал (шутка пока нечему ломатся).
В общем без примера никак не понятно как это сделать , если это можно сделать...
Спасибо, хороший стиль написания статей.
 
Форум » Микроконтроллеры » Вопросы по статьям » Таймер (помогите разобраться...)
  • Страница 1 из 1
  • 1
Поиск:

Хостинг от uCoz