Свежие обсуждения
Микроконтроллеры

Определение BPM звука на pic - ах

1 4

Хм.... народ, нужен Хелп))
Проблема в следующем - не получается установить у таймера нужные параметры выдачи тактов. Интервалы, предделители менял как угодно. В обработке прерываний стоит так

#int_TIMER2
void TIMER2_isr(void) {

if (++takt == 65534 ) takt = 0;

}

В программе (в цикле) так:

if (km == 0 && j==1){
temp_signal = 600000000 / takt;
takt = 0;
leds[0] = 1;
stop_count = time_delay;
}

В итоге результат измерений плавает даже при подаче сигнала с метронома (Где можно получить прямоугольные импульсы с чётким периодом следования).
Плавает +- 10 БПМ (а это около 100 милисукунд). Мне нужно чтоб плавал не более 0,1-0,2 БПМ. Ещё раз оговорюсь - плавает на уровне измерений, а не входной сигнал, это точно.

Текст старта программы

#device adc=10

#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NODEBUG //No Debug mode for ICD
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES WRT_50% //Lower half of Program Memory is Write Protected

#use delay(clock=16000000)

#include <math.h>
#include <string.h>

#define Keys1 PIN_B5
#define Keys2 PIN_B6
#define INF PIN_C1
#define CLC PIN_C0
#define LED PIN_B7
#define Beep_D 10
#define SND PIN_C2
#use fixed_io(b_outputs=PIN_B0,PIN_B1,PIN_B2,PIN_B3,PIN_B4,PIN_B7)
#byte ADCON0 = 0x1F

переменные.....

port_b_pullups (TRUE);
setup_adc_ports (AN0_AN1_AN2_AN3_AN4);
setup_adc (ADC_CLOCK_DIV_64);
setup_psp (PSP_DISABLED);
setup_spi (SPI_SS_DISABLED);
setup_timer_0 (RTCC_INTERNAL|RTCC_DIV_16);
setup_timer_1 (T1_DISABLED);
setup_timer_2(T2_DIV_BY_4,99,1);
setup_comparator (NC_NC_NC_NC);
setup_vref (FALSE);
enable_interrupts (INT_TIMER0);
enable_interrupts (INT_TIMER2);
enable_interrupts (GLOBAL);

там ещё чуть раньше программа обработки прерывания от таймера 0. На всякий случай привожу (если кому прога покажется знакомой - не удивляйтесь, я пользовался примерами и уже сделанными программами):

#INT_TIMER0
void TIMER0_isr(void){
static char i, tmp;

for (i = 7; i > 0; i--){

if (refresh)
{
refresh = 0;
for (i = 0; i <= 7; i++)
od[i] = d[i];
};

SetDIG(od[nvd]);
output_bit(LED,leds[nvd]);
SetNR(nvd);
if (Key > 128)
{
tmp = Key - 128;

if (((tmp == Decode(nvd)) && (input(Keys1) == 1)) ||
((tmp == Decode(nvd + 8)) && (input(Keys2) == 1))) Key = 0;

} else {

if (input(Keys1) == 0) Key = Decode(nvd);
if (input(Keys2) == 0) Key = Decode(nvd + 8);
if (Key > 0) ds = Beep_D;

}

if (nvd < 7) nvd++; else nvd = 0;

if (ds > 1) output_bit(SND, 0);
if (ds > 0) ds--;
if (ds == 1) output_bit(SND, 1);
}
}