Страница 1 из 1

Мигалка на таймере1

Добавлено: 26 фев 2012, 09:53
ASDFG123
подскажите как написать рабочую программу для мигалки с использованием прерываний.

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

#include <mega8.h>
unsigned int num;
// Timer1 output compare A interrupt service routine
interrupt [TIM1_COMPA] void timer1_compa_isr(void)
{ // Place your code here
num = TCNT1;
num++;
PORTB.0 = 1;
num = 0;
TCNT1 = 0;
if (TCNT1>0x7a1)
{PORTB=0;
}
}

unsigned int led;// Declare your global variables here

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

// Input/Output Ports initialization
// Port B initialization
// Func7=Out Func6=Out Func5=Out Func4=Out Func3=Out Func2=Out Func1=Out Func0=Out 
// State7=0 State6=0 State5=0 State4=0 State3=0 State2=0 State1=0 State0=0 
PORTB=0x00;
DDRB=0xFF;

// Port C initialization
// Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTC=0x00;
DDRC=0x00;

// Port D initialization
// Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In 
// State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T 
PORTD=0x00;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
TCCR0=0x00;
TCNT0=0x00;

// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: 3,906 kHz
// Mode: CTC top=OCR1A
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer1 Overflow Interrupt: Off
// Input Capture Interrupt: Off
// Compare A Match Interrupt: On
// Compare B Match Interrupt: Off
TCCR1A=0x40;
TCCR1B=0x0D;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x07;
OCR1AL=0xA1;
OCR1BH=0x00;
OCR1BL=0x00;

// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: Timer2 Stopped
// Mode: Normal top=FFh
// OC2 output: Disconnected
ASSR=0x00;
TCCR2=0x00;
TCNT2=0x00;
OCR2=0x00;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
MCUCR=0x00;

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

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
SFIOR=0x00;

// Global enable interrupts
#asm("sei")
led = 0b10000000;
while (1)
      {

      };
}
это то что я написал, ошибка в том что сд загоряется после отрезка OCR1 и горит постоянно.
Пожалуйста распишите как правильно и рационально использовать таймер

Re: Мигалка на таймере1

Добавлено: 26 фев 2012, 13:07
boogyman
К чему такие сложности, не просто ли сделать условие по переполнению счетчика, или нужно обязательно использовать прерывания?

Re: Мигалка на таймере1

Добавлено: 26 фев 2012, 14:17
ASDFG123
наверно проще, просто я еще не разбираюсь ;)
а про переполенение счетчика как реализовать ? внести начальное значение например 57724 и досчитывать до 65536 а дальше как ?
п.с я все таки сделал мигалку на прерываниях но для этого пришлось назначить ОС1 выводом, но период 18 сек почему -то

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

TCCR1A=0x40;
TCCR1B=0x05;
OCR1AH=0x0F;
OCR1AL=0x42;
OCR1BH=0x00;
OCR1BL=0x00;

Re: Мигалка на таймере1

Добавлено: 26 фев 2012, 17:07
boogyman
ASDFG123 писал(а):наверно проще, просто я еще не разбираюсь ;)
а про переполнение счетчика как реализовать ?
Делаешь функцию задержки при помощи таймера и вставляешь ее между включенным и выключенным состоянием вывода

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

void delay (void)
{
TCNT1=0;
while (TCNT1 < 900){ };
} 
....
....
PORTB.0 = 1;
delay();
PORTB.O = 0;
delay();



Re: Мигалка на таймере1

Добавлено: 27 фев 2012, 06:56
ASDFG123
спасибо зароботало. Несколько дней назад пробовал создать функцию тлько назвал wait как в книге Белова не работало

Re: Мигалка на таймере1

Добавлено: 06 мар 2012, 19:22
ASDFG123
Занимаюсь улучшением проги, конкретнее хочу добавить кнопки управления скоростью мигания. Сейчас схема работы такая: сверхмедленный шим с кд /1024 на таймере 0, управлять пытаюсь регистром сравнения ОС 0, при нажатии кнопки скважность меняется и идет циклично с 0 до 256 отпускаю, на исходную
я понимаю что это не совсем то, потому как длительность общего периода не меняется а остается емкостью таймера, но шим тоже надо изучить хотя бы для управления вентиляторами и т.д

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

#include <avr/io.h>
void pause (unsigned int a)
{ 
unsigned int i;
for (i=a;i>0;i--);
}
int main(void)
{
	DDRD = 0x00;
	PORTD = 0xFF;
	unsigned int veloc;
	veloc = 0x80;
	
	DDRB = 0xFF;
	PORTB = 0x00;
	OCR0 = 0x40; 	
	TCCR0 |= (1 << CS02)|(0 << CS01)|(1 << CS00)|(1<<WGM00)|(1<<WGM01)|(0<<COM00)|(1<<COM01);
	
	while(1)
	{
	if ((PIND&(1 << PD0)) == 0)
	{
		unsigned char i;
		for (i=0;i<255;i++)
		{
			OCR0++;
			pause(1000);
		}
	}	
	}
}

Re: Мигалка на таймере1

Добавлено: 09 мар 2012, 12:04
boogyman
А какая частота ШИМ в этом примере?

Re: Мигалка на таймере1

Добавлено: 10 мар 2012, 18:43
ASDFG123
частота Т1 - 3,906 кГц но отказался от этой реализации сделал вот так

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

#include <avr/io.h>
unsigned int veloc; //перем скорости

void pause (void)
{
	unsigned int veloc;
	veloc=350;
	TCNT1 = 0;
	if((PIND&(1<< PD0)) == 0) // если нажато
	{
		veloc=veloc+500; // увеличение счета 
	}
	while (TCNT1<veloc) // до скольки будет считать
	{}
		
}

int main(void)
{
	unsigned char line;
	
	
	TCCR1B=(1<<CS12)|(1<<CS10);
	PORTB=0x00;
	DDRB=0xFF;
	DDRD=0x00;
	PORTD=0xFF;
    line=0b00000001;
	while(1)
    {
		
		line=line<<1;  //бегущий огонь
		if (line==0)
		{line = 0b00000001;}
		PORTB=line;
		pause ();
		}	
		
					
}
получилась 2х позиционная мигалка, К не нажата - быстрый бег, К нажата - помедленее, как бы сделать плавное управление? (чтобы кнопку не нужно было зажимать)

Re: Мигалка на таймере1

Добавлено: 10 мар 2012, 23:49
boogyman
ASDFG123 писал(а): получилась 2х позиционная мигалка, К не нажата - быстрый бег, К нажата - помедленее, как бы сделать плавное управление? (чтобы кнопку не нужно было зажимать)
Кнопка нажал - отжал, увеличение на 1 шаг, если долго держишь увеличение на несколько шагов

Re: Мигалка на таймере1

Добавлено: 11 мар 2012, 08:09
ASDFG123
да да, под микрики

Re: Мигалка на таймере1

Добавлено: 20 июл 2012, 09:54
ASDFG123
Новой темы создавать не стал.
Но как подключить библиотеки в авр студии 5 если кокретно то http://radioparty.ru/index.php/prog-avr ... nt-library.
Никак не могу подключить. При этом если сделать экспорт то он видит display.h

Re: Мигалка на таймере1

Добавлено: 22 июл 2012, 10:05
boogyman
ASDFG123 писал(а): как подключить библиотеки в авр студии 5
Я думаю также как и в AVRSTUDIO 4

Re: Мигалка на таймере1

Добавлено: 23 июл 2012, 11:34
ASDFG123
4 у меня вообще не запускается, только 5 работает.
подключить биб. я пытаюсь так, solution explorer/ add / existing item / display.h /display.c потом build
в ошибках пишет что "текст переполнен с ннным колвом байтов" но при этом те команды из билиотек в ошибках нет.

(в общем то я проект запустил, просто импортировав, он заработал, но хотелось бы научиться как подключать биб. с нуля)

Re: Мигалка на таймере1

Добавлено: 23 июл 2012, 23:18
boogyman
Про добавление библиотек в AVRStudio 5 смотреть здесь http://radioparty.ru/forums/viewtopic.php?f=2&t=620

Re: Мигалка на таймере1

Добавлено: 24 июл 2012, 22:30
ASDFG123
спасибо

вдруг кому понадобится, код проги на линейки светодиодов 8 штук бегущий огонь управляемый 2 кнопками (быстрей, медленней )

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

#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>//Библиотека прерываний
unsigned int veloc; //перем скорости
#define DataPort	PORTB
#define nop() {asm("nop");}

unsigned int x,i;



void pause (unsigned int a) //значение "а" вставим потом 
{
	unsigned int incr;
	incr = 60000; // начальное значение переменной
	for (x=a; x>0 ;x--); // формула паузы
	nop ();
		
}


int main(void)
{
	unsigned int i=10000;
	unsigned int incr;
	incr = 20000;
	unsigned char line;
	MCUCR = 1<<ISC01 | 1<<ISC00; // это не нужно, не помню зачем это вставлял 
	GICR = 1<<INT0;	
	TCCR1B=(1<<CS12)|(1<<CS10);
	PORTB=0x00;
	DDRB=0xFF;
	DDRD=0x00;
	PORTD=0xFF;
    line=0b00000001;
	sei();	
	while(1)
    {
		if((PIND&(1 << PD0)) == 0) //если кнопка "больше" нажата
		{
              
			  i = i+500;                   // увеличиваем i на 500
			  incr = i;                 // записываем переменную в регистр сравнения
			  _delay_ms(30);             // задержка 30ms
			  }
		
		if((PIND&(1 << PD1)) == 0) //если кнопка "ментше" нажата
		{
			  i = i-500;                   //  i на 500
			  incr = i;                 // записываем переменную в регистр сравнения
			  _delay_ms(30);             // задержка 30ms
			  }
		
		line=line<<1;  //бегущий огонь
		if (line==0)
		{line = 0b00000001;}
		PORTB=line;
		pause(incr); //это изменение длины паузы которая зависит от нажатий
		}	
		
					
}
загрузка атмеги 16 в протеусе 25-30%