PIC: Toerental meting

Sorry maar van ASM snap ik werkelijk helemaal niks.
In C heb ik wel eens wat gedaan met de CCP maar echt goed snappen hoe die werkt doe ik nog niet.

Zoekt en gij zult vinden, vindt gij niet dan is het zoek

Mijn probleem is ook dat ik niet goed begrijp wat die module nu precies doet.

Zoals wij hem gbruikte deed ie naar mijn weten het volgende.
CCP1 = opgaande flank en CCP2 is neergaande flank.
Zodra ccp1 hoog wordt komt de waarde van de timer in ccp1 te staan, zodra ccp2 laag wordt komt de waarde van de timer in ccp2 te staan.

Beetje lastig uitleggen , als ik het niet vergeet zal ik morgen wel even het stukkie code posten, als ik het wel vergeet mag je me mailen als je intresse hebt.

Zoekt en gij zult vinden, vindt gij niet dan is het zoek

Ik heb zeer zeker intresse, ik ben nu al enkele avonden aan het stuntelen, en snap er nog erg weinig van.

Met een beetje geluk is er nog iemand bereid om ons uit te leggen wat die CCP module nu precies doet :)

[Bericht gewijzigd door MMSoft op woensdag 24 januari 2007 21:14:15

Dat zou nog mooier zijn, maar we komen er wel uit :+

Zoekt en gij zult vinden, vindt gij niet dan is het zoek

Hier heb je een progje dat puur en alleen de periodetijd meet m.b.v. CCP1. Het is wel voor een PIC16F685 dus er kan enig verschil zijn in banks of registernamen zitten.
De uitleg staat erachter :)
Draai 'm maar eens door MPsim dan kun je zien wat er gebeurt.

code:


;**********************************************************************
;                                                                     *
;    Filename:	    CAPT_TST.asm                                      *
;    Date:          25-01-2007                                        *
;    File Version:                                                    *
;                   PCB: MM150 rev B                                  *
;                   processor: PIC16F685                              *
;                   SET VELLEMAN PROGRAMMER TO: PIC16F676             * 
;    Author:                                                          *
;    Origin of program: MM150.ASM  							          *
;**********************************************************************
; NOTES
;
; This program measures the period time of an incoming signal using the CCP module.
; Every end of period, the new 16 bit value appears at portA/B
;
;
; - PIC16F685, clock frequency: 4 MHz ,internal clock oscillator 
; - Brown out reset enabled but disabled during sleep for lower power consumption
; 
; PIC ports used:
;
; RC5/P1A input: signal input
; PORTA: output LSB of period time
; PORTB: output MSB of period time
;
;**********************************************************************
; 
;
;**********************************************************************
	list	P=16f685
	
;   ;#include <c:\program files\microchip\MPASM Suite\p16f685.inc>
;   ;#include <c:\program files\microchip\MPASM Suite\picmac1.inc>
    #include "p16f685.inc"
;   #include "picmac1.inc"

	
    	__CONFIG  _FCMEN_ON & _IESO_OFF & _BOR_NSLEEP & _CPD_ON & _CP_ON &  _PWRTE_ON & _WDT_OFF &   _MCLRE_OFF &  _INTRC_OSC_NOCLKOUT



;Instruction shortcuts
	#define	BANK0		bcf	STATUS,RP0	;Bank0
	#define	BANK1		bsf	STATUS,RP0	;Bank1


	
	cblock 	0x20                ; start of general purpose registers
		
            STATUS_TEMP         ; register om de inhoud van het status register tijdelijk op
                                ; te slaan tijdens interrupt
            W_TEMP              ; register om de inhoud van het working register tijdelijk op			
                                ; te slaan tijdens interrupts
            per_lowb            ; lowbyte van de periodetijd
            per_highb           ; highbyte van de periodetijd

	endc
	

    		ORG 0x000
  	        goto	 init
            nop
            nop
            nop
            goto    CAPT_ISR    ; spring bij een CCP-interrupt naar de capture-interrupt subroutine


            ORG 0x005

;****************************************************************
init                                 ; initialisatie van programma start hier	

            movlw   OSCCON           ; stel oscillator in
            movwf   FSR              ; op 
            movlw   b'11100111'      ; internal oscillator,
            movwf   INDF             ; 4 MHz
			
            movlw   TRISA            ; port A
            movwf   FSR              ; all
            clrw                     ; out-
            movwf   INDF             ; puts

            movlw   TRISB            ; Port B
            movwf   FSR              ; all
            movlw   0x00             ; out-
            movwf   INDF             ; puts

            movlw   TRISC            ; Port C
            movwf   FSR              ; all
            movlw   b'00100000'      ; out-
            movwf   INDF             ; puts exept RC5; RC5 = CCP-input

        
            BANK0
            clrf    PORTA            ; initiali-
            clrf    PORTB            ; seer  
            clrf    PORTC            ; outputs
			
            clrf    T1CON            ; initialiseer timer 1
		 
            movlw   b'00000101'      ; stel de CCP module in op
            movwf   CCP1CON          ; capture-input, positief edge triggered

            bsf     T1CON,TMR1ON     ; zet timer1 aan 
            BANK1
            bsf	    PIE1,CCP1IE	     ; enable CCP capture interrupts
            BANK0
            bsf	    INTCON,PEIE      ; enable perifere interrupts
            bsf	    INTCON,GIE       ; enable global interrupts
	        
 


;************************************************************************
; MAIN PROGRAM
;************************************************************************

MAIN        BANK0
            clrwdt                  ; zet watchdogtimer op 0
            movf   per_lowb,w       ; haal lowbyte op en  
            movwf  PORTA            ; zet in PORTA
            movf   per_highb,w      ; haal highbyte op en  
            movwf  PORTB            ; zet in PORTB
            goto   MAIN             ; en herhaal 

           		



;**************************************************************************
; Subroutine CAPT_ISR 
;**************************************************************************						
CAPT_ISR                        ; er is een capture-interrupt

        movwf	W_TEMP          ; standaard actie, overgenomen uit een
        swapf	STATUS,W        ; microchip application note, om de actuele inhoud van
        clrf	STATUS          ; het status register en het working register
        movwf	STATUS_TEMP     ; veilig te stellen

        BANK0                   ; switch naar memorybank 0
        bcf	    PIR1, CCP1IF    ; zet capture-interruptvlag terug
        movf	CCPR1H,w        ; haal de nieuwe highbyte van de periodetijd op en
        movwf	per_highb       ; zet weg in register period_highbyte
        movf	CCPR1L,w        ; haal de nieuwe lowbyte van de periodetijd op en
        movwf	per_lowb        ; zet weg in register period_lowbyte
        clrf	TMR1L           ; zet timer1 op nul om een nieuwe meting te starten
        clrf	TMR1H           ; zet timer1 op nul om een nieuwe meting te starten

STOP    SWAPF   STATUS_TEMP,W   ; standaard actie om de 
        MOVWF	STATUS          ; inhoud van status en working register
        SWAPF	W_TEMP,F        ; terug
        SWAPF	W_TEMP,W        ; te zetten
        RETFIE                  ; Return From Interrupt and Enable interrupts





;********************************************************************************************
; *******************************************************************************************

  
			end

code:


{
   rise = CCP_1;  
   fall = CCP_2;  

   pulse_width = fall - rise;     // CCP_1 is the time the pulse went high
}

setup_ccp1(CCP_CAPTURE_RE);    // Configure CCP1 to capture rise
   setup_ccp2(CCP_CAPTURE_FE);    // Configure CCP2 to capture fall
   setup_timer_1(T1_INTERNAL);    // Start timer 1

Dit stukje code hebben we gebruikt bij een temperatuur sensor warvan de Dutyccyle veranderde aan de hand van de temperatuur.

Zoals ik het begrijp staat in ccp 1 de waarde die de teller had op het moment dat ccp1 hoog werd.
En in ccp2 staat dan de waarde van het moment dat ie laag wordt.

[Bericht gewijzigd door diode op donderdag 25 januari 2007 16:06:37

Zoekt en gij zult vinden, vindt gij niet dan is het zoek

Ik ben begonnen met de code van Zonnepaneeltje.
Deze code heb ik omgezet naar code voor een 18F876A.

Het probleem is dat de CCP geen interrupt veroorzaakt.
Wat is er anders bij de 876A ?

Dit is de Init code die ik nu heb:

code:



Init:
BCF     STATUS,RP0      ;Select Bank 0
clrf    T1CON           ;initialiseer timer 1
movlw   B'00000101'     ;stel de CCP module in op
movwf   CCP1CON         ;capture-input, positief edge triggered
bsf     T1CON,TMR1ON    ;zet timer1 aan 
BSF     STATUS,RP0      ;Select Bank 1
bsf     PIE1,CCP1IE	;enable CCP capture interrupts
BCF     STATUS,RP0      ;Select Bank 0
bsf     INTCON,PEIE     ;enable perifere interrupts
bsf     INTCON,GIE      ;enable global interrupts

Edit:
Ik heb intussen van alles geprobeerd, maar het werkt nog steeds niet |:(

Zonnepaneeltje: vraagje over je code, waarom wordt er in de Init telkens een waarde naar FSR geschreven ?

diode: Is dat alle code voor de CCP module ?

[Bericht gewijzigd door MMSoft op donderdag 25 januari 2007 22:02:56

Wat veroorzaakt een interrupt bij een CCP module ?

Ik heb toch alle Interrupts vrijgegeven, of zie ik er nog een over het hoofd ?

Pen RC2 CCP1 is voorzien van pulsjes.

Is CCP1CON zo juist ingesteld (00000101) ?

Pen RC2 CCP1 is als ingang ingesteld.

Wat ik ook doe/probeer het wil maar niet, ik ben nu al vele uren aan het zoeken en krijg de fout maar niet gevonden.

Wie wel er een poging doen om met een PIC16F876A dit voor elkaar te krijgen ?

Een interrupt op de ccp wordt veroorzaakt door een opgaande of neergaande flank, ligt eraan hoe je hem instelt.
Heb het vandaag even nagevraagd en het geen wat ik over de inhoud van de registers schreef, klopt.

Zoekt en gij zult vinden, vindt gij niet dan is het zoek

En hoe moet ik die interrupt afhandelen ?
Dus welk register, Bit moet ik dan reseten ?

Edit:
Ik heb een blokgolf aangesloten op pen RC2, dus moeten er zeker interrupts worden gestart.

[Bericht gewijzigd door MMSoft op vrijdag 26 januari 2007 20:16:06

Op 26 januari 2007 20:13:09 schreef MMSoft:
En hoe moet ik die interrupt afhandelen ?
Dus welk register, Bit moet ik dan reseten ?

Wat bedoel je hiermee?

Zoekt en gij zult vinden, vindt gij niet dan is het zoek

Als er een interrupt optreed, wordt de Interrupt routine opgeroepen.
Daar die je 'iets', tevens zet je het interrupt bitje weer op 0 en verlaat de routine.
Wie veroorzaakt de routine, Timer 1 of de CCP module ?

Bij CCP (ASM):
BCF PIR1,CCP1IF ;zet capture-interruptvlag terug

Bij CCP (Basic):
PIR1.CCP1IF = 0 ;zet capture-interruptvlag terug

[Bericht gewijzigd door MMSoft op vrijdag 26 januari 2007 20:24:30

Die FSR-methode heeft als voordeel dat je geen bankswitches hoeft te doen, dus geen fouten en ook geen (on)terechte bankswitch-foutmeldingen ;)

Gooi die code toch in MPsim! Dan zie je wat er gebeurt.

Die PIC16F685-code doet 't goed, heb 'm gisteren ook nog op 'n breadbord getest. Functiegenerator eraan gehangen en wat ledjes op de uitgangen.
En in MPsim zie je 'm naar de interruptroutine springen.
Ik vind die 16F876A maar ondingen" :P, geef mij maar een moderne controller ;)

Gooi die code toch in MPsim! Dan zie je wat er gebeurt

Ook al werkt het in MPsim, dan werkt het nog niet in de 16F876A, en daar gaat het juist om.

Ik vind die 16F876A maar ondingen" , geef mij maar een moderne controller

Zou daar het probleem inzitten ?

[Bericht gewijzigd door MMSoft op vrijdag 26 januari 2007 20:30:42

Haha, tja, ik denk dat ie te 'groot' voor mij is. :P
Heb er ooit 1 aangeschaft en heb 't "kreng" nooit lekker aan de praat gekregen.
Met de 12F683, 16F684 en 16F685 nooit van die zeurderige problemen gehad waar je gewoon niet uit komt.

Werkt jouw 16f877-code dan wel in MPsim?

Het lijkt erop dat het een hardware probleem is.

code:



------                       ------
      |                      |
      |                      |
PIC 1 |                      |PIC 2
      |                      |
  Uit |----------------------|CCP
      |                      |
      |                      |
   0v |----------------------|0v
------                       ------

PIC 1 Maakt een blokgolf
PIC 2 Meet de freq. (toerental meting)

PIC 2 geeft continu dezelde waarde aan, ook als de freq. wijzigd.

Als ik de CCP ingang even met de 0 volt verbind, dan wordt er een andere waarde getoond (op het moment dat de verbonding met 0 volt wordt verwijderd).

Edit1:
Een diode (1N4148) geplaatst tussen de PIC's, en het werkt !
Wie heeft hier een verklaring voor ?

Edit2:
Nu werkt het ook zonder diode !
Dit nadat de code gefatsoeneerd is.

De CCP werkt nu dus.

Zit ik nog met 1 ding:
Als het signaal op de ingang wordt weggenomen, blijft de laatste waarde staan.

Ik dacht dit op te lossen met een overflow interrupt van timer 1.
Als er geen puls komt (de timer blijft lopen) is er op een gegeven moment een overloop.
Als er wel een puls komt, dan wordt de timer weer gereset en komt er geen overloop.

code:



Init:
BSF   PIE1,TMR1IE    ;Enable Timer 1 overflow interrupts


Interrupt routine:
 BTFSS  PIR1,TMR1IF   ;Timer 1 Overflow ?
 GOTO  M001           ;Geen overflow 
 BCF  PIR2,TMR1IF     ;Overflow
 CLRF Laag            ;
 CLRF Hoog            ;
M001:                 ;end

Helaas werkt dit niet, kan iemand dit verklaren ?

[Bericht gewijzigd door MMSoft op zaterdag 27 januari 2007 12:23:13

De eerste 2 regels van de interrupt: Je hoeft die hele vlagtest niet te doen want je zit al in de interrupt.
Verder zie ik PIR1 en PIR2 staan, waar zit die vlag in PIR1 of PIR2?
En een interruptroutine sluit je af met RETFIE.

De eerste 2 regels van de interrupt: Je hoeft die hele vlagtest niet te doen want je zit al in de interrupt.

Dit maar een deel van de Interrupt routine.
In de interrupt routine wordt ook de CCP afhandeling gedaan. Dit stukje wordt alleen uitgevoed als er een overflow van Timer 1 is (altands dat is de bedoeling)

Verder zie ik PIR1 en PIR2 staan, waar zit die vlag in PIR1 of PIR2?

PIR1, omdat dat niet werkte heb ik 2 geprobeerd. Helaas werkte dat ook niet.

En een interruptroutine sluit je af met RETFIE.

De interrupt routine wordt ook met RETFIE afgesloten, deze code is dus maar een deel van de routine.

De code is nu:

code:



Init:
BSF   PIE1,TMR1IE    ;Enable Timer 1 overflow interrupts


Interrupt routine:
 BTFSS  PIR1,TMR1IF   ;Timer 1 Overflow ?
 GOTO  M001           ;Geen overflow 
 BCF  PIR1,TMR1IF     ;Overflow
 CLRF Laag            ;
 CLRF Hoog            ;
M001:                 ;end

Dit werkt helaas niet...

[Bericht gewijzigd door MMSoft op zaterdag 27 januari 2007 12:24:08

Zonnepaneeltje (of iemand anders): Zou jij een poging willen doen om dat in jou code voor elkaar te krijgen ?

Als je wilt controleren of timer1 overloopt d.m.v. een vlagtest, doe je dat in je hoofdprogramma. Dan gebruik je dus geen interrupt en mag het timer1-interruptenable bit niet geset worden.
Of je maakt een tweede interruptroutine erbij, dan wordt het weer een heel ander verhaal.

Als er een interrupt optreed, wordt toch altijd dezelfde interrupt routine gestart (afgezien van een PIC uit de 18 serie, die heeft Low en High level interrupts) ?
In die routine kijk je dan toch welk onderdeel de interrupt heeft veroorzaakt.
Je doet iets, zet de flag terug en verlaat de routine.

Altands, dat heb ik altijd begrepen.
Ik ben dan ook erg benieuwd hoe je een tweede interruptroutine erbij maakt.

[Bericht gewijzigd door MMSoft op zaterdag 27 januari 2007 18:45:07