atmelsudio Проблема с настройкой частоты и еще пара вопросов

Обсуждаем контроллеры компании Atmel.
Ответить
Первый раз сказал Мяу!
Сообщения: 34
Зарегистрирован: Вс авг 21, 2016 19:53:33

Сообщение Catdawr »

Здравствуйте друзья, у меня возникли проблемы с настройкой частоты микроконтроллера(attiny2313) в программе, творится какая-то мистика. В общем частота прерываний рассчитана так, чтобы прерывания по таймеру 1 появлялись раз в секунду. Для 8МГц с предделителем 256, получается 31250 , записав это число в
OCR1A , и проверив интервал в proteus ( пробовал и с внешним и с внутренним генератором, и в строке "clock frequency" стоит 8 МГц ) у меня получается не 1 секунда, а 8 секунд. И, в общем, как я не пересчитывал, программа будто считает что у меня всего 1 МГц.
Ниже сброшу код, который я где то взял и доворотил под свои нужды.
( программа для часов, время выводится на 7и сегментном индикаторе, для экономии ног используется 4017(decade counter), в этом деле я новичок-любитель, не судите строго)

Код: Выделить всё

#define F_CPU 8000000UL 

#include <avr/interrupt.h>
#include <util/delay.h>



//----------------------------------0-----1-----2-----3-----4-----5-----6-----7-----8------9
unsigned char SEGMENTE[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};


 unsigned char segcounter = 0;
volatile int hour = 0;
volatile int minute = 0;
volatile int sec = 0;

// Обработчик прерывания по переполнению таймера 0
ISR(TIMER0_OVF_vect)
{	
	PORTB = 0xFF; // Гасим все разряды
	
PORTD |=(1<<PD0) ;
PORTD &= ~(1<<PD0) ;
		  
	switch(segcounter)
	{
		case 0:
		PORTB = ~(SEGMENTE[hour % 10]+0b10000000); // Раскладываем число на разряды
		
		break;
		case 1:
		PORTB = ~(SEGMENTE[minute % 100/10] );
		
		break;
		case 2:
		PORTB = ~(SEGMENTE[minute % 10]+0b10000000);
		
		break;
		case 3:
		PORTB = ~(SEGMENTE[sec % 100/10 ]);
		
		break;
		case 4:
		PORTB = ~(SEGMENTE[sec % 10]);
		
		break;
		case 5:
		PORTB = ~(SEGMENTE[hour %100/10]);
		break;
	}	
	
 	segcounter++; 

if(segcounter > 5) {segcounter = 0;}	

				
 

}
ISR(TIMER1_COMPA_vect)
{
	sec++ ;
	if (sec >= 60) {minute++; sec=0; }
	if (minute >= 60)	{hour++; minute=0; sec=0;}
	if (hour >= 24)	{ hour= 0; minute =0; sec= 0;}
		
			
}

// Главная функция
int main(void)
{
	DDRD = 0b00000011; // Порт D - вход PD0 - вывод
	PORTD = 0b00011100;
	DDRB = 0xFF; // Порт B - выход
	PORTB = 0x00;
	
	//------------ таймер для настройки индикаторов
	TCCR0B  = (0<<CS02) |(0 <<CS01) |(1<<CS00);
	
	// -------- таймер для настройки времени-времени
	
	TCCR1B = (0<<CS12) |(1<<CS11) |(1<<CS10)| (1<<WGM12);
	OCR1A =15625;
	
	TIMSK |= (1 << TOIE0)  |(1<<OCIE1A)  ; // Разрешение прерывания по таймеру 0 | разрешение прерывания по совпадения таймера 1
		 	
	sei(); // Глобально разрешаем прерывания
	
	while(1)
	{
	
	if((PIND&(1<<PD2))==0) {hour++;_delay_loop_2(35535); }
	if((PIND&(1<<PD3))==0) {minute++;_delay_loop_2(15535); }
	
    

	}
}
Изображение

еще хотелось бы задать пару вопросов, например :
1) в последней части кода для использования кнопок для настройки времени, нужно использовать задержку, что б не было дребезга, если использовать обычный delay_ms то тормозится вся программа, и гаснут индикаторы, с delay_Loop_2 такого нету, но я не знаю как настроить на них точное время( хотел еще кое-что прилепить к этим часам в будущем, для чего мне это пригодится), вот есть еще какие-нибудь задержки чтобы, скажем, не давали повторять какую то процедуру чаще чем "какой то промежуток времени", не тормозя всю программу?

2) хотел что-то еще спросить, но забыл.. :dont_know: ... спрошу попозже
Реклама
Держит паяльник хвостом
Сообщения: 933
Зарегистрирован: Ср апр 13, 2011 11:09:20
Откуда: Екатеринбург

Сообщение Alkul »

Какая версия среды? С этого начинать надо
Реклама
Первый раз сказал Мяу!
Сообщения: 34
Зарегистрирован: Вс авг 21, 2016 19:53:33

Сообщение Catdawr »

Учту- atmel studio 7.0 .... ну а proteus 8, ( на всякий случай)
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Но предделитель то у Вас, для таймера 1, не на 256 установлен.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Эиком - электронные компоненты и радиодетали
Первый раз сказал Мяу!
Сообщения: 34
Зарегистрирован: Вс авг 21, 2016 19:53:33

Сообщение Catdawr »

Да, я забыл сказать, что я его оставил в настройках так, чтобы он выдавал 1 у секунду.
Реклама
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

В протеусе то у Вас фьюзы точно на 8 МГц?

------------

Внутренний делитель на 8 наверняка включен.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Первый раз сказал Мяу!
Сообщения: 34
Зарегистрирован: Вс авг 21, 2016 19:53:33

Сообщение Catdawr »

CKSEL fuse 1110, да и 0100 ставил, ( 8 МГц внешний/ внутренний), ну и в clock frequency написано 8 МГц, и всё по прежнему, будто у меня 1 Мгц,
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Z_h_e писал(а): Внутренний делитель на 8 наверняка включен.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Первый раз сказал Мяу!
Сообщения: 34
Зарегистрирован: Вс авг 21, 2016 19:53:33

Сообщение Catdawr »

я всегда думал, что (0<<CS12)|(1<<CS11)|(1<<CS10) это настройка единственного делителя на 64( потому как он там вроде 1) и настраиваю я его только для таймера 1, если это не внутренний, то какой же тогда внутренний?
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Вы не поняли. Я не про делитель для таймера, а для всего МК. Почитайте про регистр CLKPR. Делитель тактовой частоты. Этот регистр имеет большой список значений деления генератора тактовой частоты. А вот при сбросе, этот регистр инициализируется двумя возможными значениями или без деления или деление на 8. За значение инициализации отвечает специальный фьюз, по умолчанию делит на 8.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Первый раз сказал Мяу!
Сообщения: 34
Зарегистрирован: Вс авг 21, 2016 19:53:33

Сообщение Catdawr »

Почитал, разобрался с CLKPR и... теперь всё работает как надо, спасибо друг! А то я тут голову ломаю уже неделю над сим беспределом.

Ам, а про задержки никаких предложений нету?
Собутыльник Кота
Аватара пользователя
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Сообщение Z_h_e »

Не понятно почему у Вас все тормозится, как будто запрещаются прерывание. Точное время легко узнать, если установить точки останова до вызова функции и после. Поглядеть количество тактов/времени на ее выполнение.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Первый раз сказал Мяу!
Сообщения: 34
Зарегистрирован: Вс авг 21, 2016 19:53:33

Сообщение Catdawr »

Да нет же
1) в последней части кода для использования кнопок для настройки времени, нужно использовать задержку, что б не было дребезга, если использовать обычный delay_ms то тормозится вся программа, и гаснут индикаторы, с delay_Loop_2 такого нету, но я не знаю как настроить на них точное время( хотел еще кое-что прилепить к этим часам в будущем, для чего мне это пригодится), вот есть еще какие-нибудь задержки чтобы, скажем, не давали повторять какую то процедуру чаще чем "какой то промежуток времени", не тормозя всю программу?
получается как раз наоборот c delay loop 2 всё работает более менее как надо( правда там максимальное значение 65536)
и даже на максимуме сейчас за 1о быстрое нажатие кнопки hour++, накидывает по 3-4 часа. при этом индикаторы работают, а с delay ms на время работы задержки индикаторы останавливаются...
Хотя подождите, сейчас почему то такого уже нету, и с delay ms индикаторы не гаснут( точнее говоря, переставал посылаться сигнал на 4017, из за этого горел 1 разряд на время задержки)... мистика. Ладно, спасибо большое. больше вопросов нет...пока. :)
--------------
последнее замечание попробую учесть в будущем, хотя надо будет и узнать где-нибудь как это сделать
Ответить

Вернуться в «AVR»