Захват для AVR

Обсуждаем контроллеры компании Atmel.
Ответить
ATH
Родился
Сообщения: 10
Зарегистрирован: Пн фев 04, 2013 13:42:48

Сообщение ATH »

Здравствуйте, решил изучить захват таймера T1 МК ATmega8535. Если не обнулять счетный регистр TCNT1=0; то таймер считает нормально до 65535, но если в прерывании обнулить TCNT1=0 то таймер считает только до 255 :(
#include <mega8535.h>
#include <alcd.h>
#include <delay.h>
#include <stdio.h>

char lcd_buffer[33];
unsigned int tachBuf=0;

// Timer1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
tachBuf=ICR1H<<8;
tachBuf=tachBuf|ICR1L;
sprintf(lcd_buffer,"naschitano %u",tachBuf);
lcd_puts(lcd_buffer);
delay_ms(200);
lcd_clear();

}
Реклама
Вымогатель припоя
Аватара пользователя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

Сообщение zero648 »

Каким образом происходит захват, возможно не правильный режим таймера, инициализация таймера где?
А если вот это:
tachBuf=ICR1H<<8;
tachBuf=tachBuf|ICR1L;
заменить на это:
tachBuf=ICR1;
Реклама
ATH
Родился
Сообщения: 10
Зарегистрирован: Пн фев 04, 2013 13:42:48

Сообщение ATH »

Спасибо за отклик. Tаймер настроен регистром TCCR1B так что коэффициент деления частоты равен 1024, захват происходит по ниспадающему фронту, подавление помех отключено. Ниже полный код. При замене tachBuf=ICR1; компилятор выдает ошибку, что он "не знает" что такое ICR1.
#include <mega8535.h>
#include <alcd.h>
#include <delay.h>
#include <stdio.h>

char lcd_buffer[33];
unsigned int tachBuf=0;

// Timer1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
tachBuf=ICR1H<<8;
tachBuf=tachBuf|ICR1L;
sprintf(lcd_buffer,"naschitano %u",tachBuf);
lcd_puts(lcd_buffer);
delay_ms(200);
lcd_clear();
}


void main(void)
{


// Input/Output Ports initialization
// Port A 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
PORTA=0x00;
DDRA=0x00;

// Port B 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
PORTB=0x00;
DDRB=0x00;

// Port C 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
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=0xFF;
DDRD=0x00;


TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;
TCCR1A=0x00;
TCCR1B=0x5;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;

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

// USART initialization
// USART disabled
UCSRB=0x00;

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

// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTC Bit 0
// RD - PORTC Bit 1
// EN - PORTC Bit 2
// D4 - PORTC Bit 3
// D5 - PORTC Bit 4
// D6 - PORTC Bit 5
// D7 - PORTC Bit 6
// Characters/line: 8
lcd_init(16);

// Global enable interrupts
#asm("sei")

while (1)
{
// Place your code here

}
}
Вымогатель припоя
Сообщения: 541
Зарегистрирован: Вт фев 09, 2010 17:52:26

Сообщение codenamehawk »

ATH писал(а): sprintf(lcd_buffer,"naschitano %u",tachBuf);
lcd_puts(lcd_buffer);
delay_ms(200);
lcd_clear();
Пока будут выполнятся эти строки таймер и дальше считает.
Этот код перенесите в основной цикл.

Для локализации ошибки попробуйте

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

tachBuf=ICR1H<<8;
tachBuf=tachBuf|ICR1L;
заменить на

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

unsigned int temp_h;
unsigned int temp_l;
temp_h =ICR1H;
temp_l = ICR1L;

tachBuf=temp_h*256+temp_l;

и сделайте
volatile unsigned int tachBuf=0;
Реклама
Эиком - электронные компоненты и радиодетали
ATH
Родился
Сообщения: 10
Зарегистрирован: Пн фев 04, 2013 13:42:48

Сообщение ATH »

Программа работает, при уменьшении частоты можно заметить что при нажатии кнопки сначала показывается небольшое число, например, сначала 137 потом 2734. Почему так происходит?
#include <mega8535.h>
#include <alcd.h>
#include <delay.h>
#include <stdio.h>
unsigned int temp_h;
unsigned int temp_l;
char lcd_buffer[33];
volatile unsigned int tachBuf=0;

// Timer1 input capture interrupt service routine
interrupt [TIM1_CAPT] void timer1_capt_isr(void)
{
TCNT1=0;
}

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

// Input/Output Ports initialization
// Port A 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
PORTA=0x00;
DDRA=0x00;

// Port B 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
PORTB=0x00;
DDRB=0x00;

// Port C 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
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=0xFF;
DDRD=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=0xFF
// OC0 output: Disconnected
TCCR0=0x00;
TCNT0=0x00;
OCR0=0x00;

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

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

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

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

// USART initialization
// USART disabled
UCSRB=0x00;

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

// ADC initialization
// ADC disabled
ADCSRA=0x00;

// SPI initialization
// SPI disabled
SPCR=0x00;

// TWI initialization
// TWI disabled
TWCR=0x00;

// Alphanumeric LCD initialization
// Connections are specified in the
// Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu:
// RS - PORTC Bit 0
// RD - PORTC Bit 1
// EN - PORTC Bit 2
// D4 - PORTC Bit 3
// D5 - PORTC Bit 4
// D6 - PORTC Bit 5
// D7 - PORTC Bit 6
// Characters/line: 8
lcd_init(16);

// Global enable interrupts
#asm("sei")
while (1)
{
#asm("cli")
temp_h =ICR1H;
temp_l = ICR1L;
#asm("sei")
tachBuf=temp_h*256+temp_l;
sprintf(lcd_buffer,"naschitano %u",tachBuf);
lcd_puts(lcd_buffer);
delay_ms(100);
lcd_clear();

}
}
Реклама
akl
Друг Кота
Сообщения: 4463
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Сообщение akl »

Порядок чтения 16-разрядного ICR должен быть иным

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

temp_l = ICR1L;
temp_h =ICR1H;
Изображение
обмен с ICR.GIF
Естественно, это касается и TCNT1 и OCR1A/B
Реклама
ATH
Родился
Сообщения: 10
Зарегистрирован: Пн фев 04, 2013 13:42:48

Сообщение ATH »

Спасибо, тему можно закрывать
Ответить

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