펄스 카운터

H

HeiFelix

Guest
내가 TMR0의 입력 펄스를 세어 RA4에 frequncy 변화를 감지 PIC16F87A를 사용하겠습니다.주변의 센서와 80KHz의 주파수에 따라 OSC 8MHz의입니다.안정적인 매 160ms에서는 펄스의 수를 0x36B5 또는 0x36B6는 주파수를 의미합니다.
나는이 기간에 더 많은 펄스를 하나 또는 두 가지를 감지하려면 가능한 한 빨리.그래서, 난
16 년 (X10ms) consectutive 기간 펄스의 수를 기록하는 FIFO 설정할 수있습니다.각 시대의 종말, FIFO의 합이하고 표준과 비교합니다.내가 10ms의 변화를 감지할 수있습니다 이러한 방법으로 믿습니다.하지만 지난 160ms의, 합계 0x36B3에서 요동 쳤다 - 0x36B6는 수표에 대한 표준을 얻을 수 없다는 뜻.일부 맥박을 잃었 때 그것을 기록해야한다.제가 어떻게 그런 16X10ms 기간에 0x35B5 또는 0x35B6으로 예상 금액을받을 수 있습니까?이 코드는 다음과 같습니다 :
코드 :..........;;;;;;;;;;;;;;;;;; 인터럽트 서비스 ;;;;;;;;;;;;;;;;;;;;;

IntService

movwf W_Temp

swapf 승, STATUS_Temp

movwf STATUS_Temp

bcf 상태, RP0

btfsc INTCON, T0IF

전화 IntServiceTimer0

swapf STATUS_Temp, 승

movwf 상태

swapf W_Temp로, F

swapf W_Temp, 승

retfieTimer0 인터럽트 서비스 ;;;;;;;;;;;;;;;;;; 대한 ;;;;;;;;;;;;;;;;;;;;;

IntServiceTimer0

bcf INTCON, T0IF

incf TMR0_High로, F

반환;;;;;;;;; 주요 프로그램 ;;;;;;;;

본선

InitialPIC 전화

InitialDetector 전화

movlw CounterLength

movwf CounterCounter

MainLoop

btfss PIR1, TMR2IF : 10ms overfloe

고토 MainLoop

bcf PIR1, TMR2IF

movf TMR0, 승

clrf TMR0

movwf TMR0_TempL

movf TMR0_High, 승

movwf TMR0_TempH

clrf TMR0_High

............
....... 16x10ms 기간의 합계를 얻으려면 TMR0_TempL 및 TMR0_TempH 사용

.............
할 특정 작업을 ......... frequncy의 변화 감지

고토 MainLoop

 
아마 어딘가에서 전화 서비스를 방해하여 필요
gosub IntService를
추가하여그러나 나는이 일과 아무도 전화 통화를 참조하는 대신
그렇다면 또 한 번 실행됩니다 그래서이 없다면 그것은 당신 결과로 할 것입니다 방해가?<img src="http://www.edaboard.com/images/smiles/icon_rolleyes.gif" alt="롤링 아이즈" border="0" />ftopic85121.html" class="nav"> 맨 위로 이동

<img src="http://www.edaboard.com/templates/subSilver/images/lang_english/icon_profile.gif" alt="View user's profile" title="사용자의 프로필보기" border="0" />
 
이 인터럽트 서비스 TMR0 인터럽트에 대한 불린다.- TMR0는 8 비트 등록이 있고 그것을 수있습니다 오버플로우 the
10ms 기간 동안입니다.이 TMR0과 TMR2 InitialDetector에 initailized있다.

 
당신에 대해 1의 변화
/ 16000, 또는
0.006 %를 감지하고 있어요!그 때문에 탐지하려는
60ppm 변경하고 저렴한 크리스탈의 난 당신이 높은 - 안정성을 사용하고 희망, 낮은 - tempco 또는 오븐 - 8MHz의 크리스털 제어 100ppm 또는 악화 안정성있다.

당신은 그것을 중지하지 않고 카운터를 읽을해야한다; 당신은 단일 셀 잃을 수없습니다.

당신 카운트 잃고 그 이유는 당신이 카운터 리셋이야되지만, 그것을 완벽하게 행복하게 당신이 그것을 재설정하지 않습니다 세고,하지만 대신 0 당신은 시대의 시작에있는 16 - 비트 값을 계속 기억에서 시작된다 그리고 16 - 비트 값에서 기간의 마지막에 그것을 뺍니다.

자네 같은 wrapover 카운터 - 255과 함께 8 비트 모드있어 것
같습니다 -> 0 인터럽트를 일으키는; 않습니다 그것은 16 - 비트 모드가?16 (- 비트 모드에서 당신은 일상적인 방해, 당신은 그저 카운터 카운트 입력 펄스에게도 필요하지 않습니다.

어느 모드에서, 당신이 뭔가해야
할 것이다 :

/ / 초기화
startcount = 0
tmr0_low = 0; tmr0_high = 0
...
/ / 모든 10ms :
반면 낮은과
높은 바이트 읽기 / /, 반복하려는 카운터를 읽을 때까지 낮은 카운터 (은 매우 가끔) 시도합니다 변경되지 않았습니다
(
countlow = tmr0_low
counthigh = tmr0_high
)까지 countlow == tmr0_low / / 낮은 바이트를 다시 읽어 낮은 반면 높은 바이트 독서 후 그것을 변경되지 않았을 확인
/ /이 기간 중에 작품의 증가
thiscount = ((counthigh <<

<img src="http://www.edaboard.com/images/smiles/icon_cool.gif" alt="차가운" border="0" />

| countlow) - startcount
/ / 카운터 값은 다음 기간의 끝에 빼기 위해 사용하기
startcount = ((counthigh <<

<img src="http://www.edaboard.com/images/smiles/icon_cool.gif" alt="차가운" border="0" />

| countlow)
... thiscount 사용

당신은 아마 최초의 읽기, 폐기되었는지 확인 할 것 즉, startcount 올바르게 10ms까지 기간의 시작에있는 수를 추적합니다.

심지어 카운트 카운터 때 잃는 것이 아니라, 카운터의 샘플링 10ms의 정확성을 매우 중요하다; 그것은 매우 정확하게, 지터를 많이하고있는 80kHz의 샘플링 비율, 즉 하나의 기간보다 훨씬 적은
5월 12일 미만 읽을 수 있어야합니다 우리를.* 언제
* 최악의 경우는 것 같이 ()
5 이상 걸릴 - 6us 실행하기 위해 실행하는 인터럽트를 가질 수없습니다.

행운을 빕니다!

HTH
Barny

 
Barny451 :
네, 저는 약 2의 변화 / 16000 감지하도록 노력하고있습니다.이 회로는 주파수가 매우 안정적으로 확인합니다.난 그 20ppm의 결정과 함께, 카운터 안정의 차이가 보인다
1 펄스 테스트했습니다 160ms 기간에 있기 때문에 낮은 - - 높은 전환 그냥 시대의 시작부터 다리가
밖으로 또는 인하.
네 말이 맞다는 일부 펄스의 재설정 및 서비스 중단으로 잃게됩니다.10ms까지 올바르게 startcount 기간의 시작에있는 수를 추적하는 최초의 독서를 쫓고 일부 루프에 의해 삭제됩니다.
유일한 16 - 비트 타이머 TIMER1 내가 어떤 다른 목적을 위해 사용한 적이있다.하지만 16 비트 타이머를하지 않고, 거기에 방해하지 않도록하는 방법은없습니다.나는 그 같은 기간에 걸릴 중단 서비스 타이머의 surpose 않는 일들은 거의 같은 시간에 Timer0 중단과 Timer2 오버플로우.
어쨌든, 당신의 좋은 아이디어 감사합니다!거기에 어떤 다른 제안이 있습니까?거기는 RA4에서 상당히 안정적인 작품과 내가 수행하려고합니다 비슷한 제품입니다.

감사합니다

 

Welcome to EDABoard.com

Sponsor

Back
Top