друзья доброго всем здоровья!
Решил сделать программу частотомера.
Конечно, таких программ в инете много, но сами понимаете нужно самому научится творить программы
Пусть скромные но свои.
Так ,вот начал с элементарного понятия частоты -это число импульсов за определенный период времени
Берем интервал в 1 сек и считаем количество импульсов за это время (метод временных ворот)
Взял доступную
ATtiny2313 с внешним кварцем 8 192 000 Гц.
В переди поставил схему совпадения(см прилоеженный рисунок) на первый вход которого подаю импулсы измеряемой частоты ,а на другой сформированный микрокортроллерем односекундный импульс.С выхода схемы совпадения импульсы подаются на вход T0 таймера счетчика
TCNT0,который работает в режиме внешнего счета.
Ниже приводится программа( без подпрограммы для LCD использование которой не вызывает затруднении) на Ваше обсуждение:
T1 задействован для формирования интервала 1 сек.
Для этого он должен посчитать 8 192 000 импульсов и остановится, но так как сам таймер считает только до 65536, то приходится многократно посчитать переполнение ,пока в сумме не получим число 8 192 000 .
Такой счет идет в переменной "d".
Получаем 8 192 000/ 65536 =125 (dec) = 0x7D (HEX)
Chip type : ATtiny2313
Clock frequency : 10,0000 MHz
Memory model : Tiny
External SRAM size : 0
Data Stack size : 32
************************************************** ***/
#include ‹tiny2313.h›
#include ‹delay.h›
unsigned long int a,b,c,d;//задаем переменные
char r;
//----------------------------------------------
// Timer 1 overflow interrupt service routine //прерывание по переполнению таймера 1.
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
d++;
}
//-----------------------------------------------
// Timer 0 overflow interrupt service routine //прерывание по переполнению таймера 0.
interrupt [TIM0_OVF] void timer0_ovf_isr(void)
{
c++;
}
void main(void)
{
// Declare your local variables here
// Crystal Oscillator division factor: 1
#pragma optsize-
CLKPR=0x80;
CLKPR=0x00;
#ifdef _OPTIMIZE_SIZE_
#pragma optsize+
#endif
PORTA=0x00;
DDRA=0x00;
PORTB=0xFF;
DDRB=0x00;
PORTD=0x54;
DDRD=0x2B;
// Timer/Counter 0 initialization
// Clock source: T0 pin Rising Edge
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x07;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;
// Timer/Counter 1 initialization
// Clock source: System Clock
// Clock value: Timer 1 Stopped
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
// Timer 1 Overflow Interrupt: On
// Input Capture Interrupt: Off
// Compare A Match Interrupt: Off
// Compare B Match Interrupt: Off
TCCR1A=0x00;
TCCR1B=0x01;
TCNT1H=0x00;
TCNT1L=0x00;
ICR1H=0x00;
ICR1L=0x00;
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;
// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
GIMSK=0x00;
MCUCR=0x00;
// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x82;
// Universal Serial Interface initialization
// Mode: Disabled
// Clock source: Register & Counter=no clk.
// USI Counter Overflow Interrupt: Off
USICR=0x00;
// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;
// Global enable interrupts
#asm("sei")
while (1)
{
if(d›=0x7D)
{
PORTD.5=0;
TCCR1B=0x00;
a=((c*0x100)+TCNT0); // определяемая частота
d=0;
c=0;
TCNT0=0;
TCNT1=0;
delay_ms(20);
TCCR1B=0x01;
PORTD.5=1;
}
};
}
Дорогие друзья ,знатоки, прокотролируйте пожалуйсто мою програмку. Все ли у меня верно,
Не будут ли мешать два прерывания друг другу и если да, как от этого избавится?
В ПРОТЕУСе ,в окне где смотрят переменные и регистры, числа получались одни и те же,
а в самом деле как будет не знаю.
Хотелось бы услышать Ваше авторитентное мнение, ато мне кажется, что так просто это не должно быть. Так в чем моя неграмотность?
Заранее благодарен за любые коментарии.