-
        

Ergebnis 1 bis 8 von 8

Thema: Zeitschleife funktioniert nicht (mit C programmiert)

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied Avatar von pointhi
    Registriert seit
    18.03.2009
    Alter
    22
    Beiträge
    139

    Zeitschleife funktioniert nicht (mit C programmiert)

    Anzeige

    Ich hab mir den C-Compiler SourceBoost heruntergeladen, und auch schon erste Programme geschrieben, die einwandfrei liefen. Da ich schon Assembler programmierte, und ich dort oft Zeitschleifen benötige, wollte ich eine solche Zeitschleife auch für meine C-Programme entwickeln. In meinem Testprogramm sollte ein Taster alle 250ms abgefragt werden, und danach ein LED nach dem Tasterzustand ein oder aus-geschalten werden.

    Hier der Code:
    Code:
    /*****************************************************************************
     Dateiname:	PortTest.c
     Autor:		pointhi
     Datum:  	März 2010
     Version:	1.00
    
     Letzte Änderung:	keine 
    			
    ******************************************************************************
    Funktionsbeschreibung des Programms:
    
    Abfragen des Taster in einem Intervall von 250ms
    
    *///******************************* include **********************************
    
    #include <.\PIC16F630.h>
    #include <.\stdio.h>
    #include <.\stdlib.h>
    
    //************************ Programmweite Variablen ***************************
    
    //***************************** kofiguration *********************************
    
    #pragma __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_ON & _MCLRE_OFF & _CPD_OFF & _INTRC_OSC_NOCLKOUT 
    
    /*
    	CP: Code Protection bit
    		ON
    	->	OFF
    	WDT: Watchdog Timer Enable bit
    		ON
    	->	OFF
    	BODEN: Brown-out Detect Enable bit
    	->	ON
    		OFF
    	PWRTE: Power-up Timer Enable bit
    	->	ON
    		OFF
    	MCLRE: GP3/MCLR pin function select
    		ON
    	->	OFF
    	CPD: Data Code Protection bit
    		ON
    	->	OFF
    	Oscillator Variations:
    		LP_OSC   = Low power crystal on GPIO4 and GPIO5 
    		XT_OSC   = Crystal/resonator on GPIO4 and GPIO5 
    		HS_OSC   = High speed crystal/resonator on GPIO4 and GPIO5 
    		EC_OSC   = I/O function on GPIO4 pin, CLKIN on GPIO5 
    	->	INTRC_OSC_NOCLKOUT  = I/O function on GPIO4 pin, I/O function on GPIO5 
    		INTRC_OSC_CLKOUT  = CLKOUT function on GPIO4 pin, I/O function on GPIO5 
    		EXTRC_OSC_NOCLKOUT  = I/O function on GPIO4 pin, RC on GPIO5 
    		EXTRC_OSC_CLKOUT    = CLKOUT function on GPIO4 pin, RC on GPIO5
    
    *///############################ Interupt ####################################
    
    void interupt (void)
    {
    
    	int status_int;
    	status_int = status;	// Rettet den Inhalt von STATUS
    
    
    
    	status = status_int;	// Schreibt den Wert von STATUS zurück
    	
    	asm
    		{
    		retfie
    		}
    }
    //########################## Unterprogramme ##################################
    
    //--------------------- Zeitschleife 1ms ---------------------
    
    void pause1ms(void)	 
    {
    int loop;
    int i;
    int oszilator;
    oszilator = 40;		// Verwendeter Oszilator (40 = 4MHz, 80 = 8MHz)
    for(i = 0; i >= oszilator; i ++)
    	{
    	for(loop = 0; loop >= 30; loop ++);
    	}
    }
    //----------------- Zeitschleife einstellbar -----------------
    
    void pause(int loop)
    {
    int i;
    for (i = 0; i >= loop; i ++)
    	{
    	pause1ms();
    	}
    }
    //############################ Hauptprogramm #################################
    
    void main(void)
    {
    porta = 0;			// Setzt alle Ports auf Low
    portc = 0;
    trisa = 0;		// 1 = Eingang, 0 = Ausgang
    trisc = 255;
    intcon = 0;			// Deaktiviert alle Interupts
    
    while(1)
    	{
    	if(portc.0 == 1)
    		porta = 255;
    	else
    		porta = 0;
    	pause(250);
    	}
    }
    
    
    //################################## Ende ####################################
    Das Problem ist, dass keinerlei Zeitverzögerung auftritt. Ich kann darum den LED z.b. 8 mal pro Sekunde schalten, obwohl es max. 4 mal sein dürfte.

    Findet ihr ein problem?

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    22.11.2005
    Ort
    Braunschweig
    Alter
    41
    Beiträge
    685
    Moin!
    Ich kenne mich zwar mit Deinem Compiler nicht aus, könnte mir aber vorstellen, dass dieser die Warteschleife wegoptimiert, weil da drin ja nichts passiert? Manchmal sieht man bei solchen Schleifen, dass da per Inline Assembler ein 'NOP' eingebaut wird, damit der Compiler denkt, da passiert was, alternativ kann man für Dein Vorhaben aber evtl. besser einen Timer bzw. Interrupt nutzen?

    MfG Volker
    Meine kleine Seite
    http://home.arcor.de/volker.klaffehn
    http://vklaffehn.funpic.de/cms
    neuer Avatar, meine geheime Identität

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    15.08.2008
    Alter
    40
    Beiträge
    19
    Hallo pointhi,
    aus meiner Sicht sind Deine for-Schleifen falsch aufgebaut, denn die Fortführbedingungen sind nie erfüllt. Im ersten Lauf ist i bzw. loop = 0. Am Ende erfolgt i / loop++ => jeweils eins und eins ist nicht größer oder gleich oszillator oder 30. Deshalb erfolgt keine Verzögerung.

    Gruß
    Matzenerich

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied Avatar von pointhi
    Registriert seit
    18.03.2009
    Alter
    22
    Beiträge
    139
    Hier ist der erstellte Assemblercode:
    Man sieht darin, dass ganz und gar nicht optimiert wird.


    Code:
    ;/////////////////////////////////////////////////////////////////////////////////
    ;// Code Generator: BoostC Compiler - http://www.sourceboost.com
    ;// Version       : 6.96
    ;// License Type  : Lite License (Unregistered)
    ;// Limitations   : PIC12,PIC16 max code size:2048 words, max RAM banks:2, Non commercial use only
    ;/////////////////////////////////////////////////////////////////////////////////
    
    	include "P16F630.inc"
    ; Heap block 0, size:53 (0x0000002B - 0x0000005F)
    __HEAP_BLOCK0_BANK               EQU	0x00000000
    __HEAP_BLOCK0_START_OFFSET       EQU	0x0000002B
    __HEAP_BLOCK0_END_OFFSET         EQU	0x0000005F
    ; Heap block 1, size:0 (0x00000000 - 0x00000000)
    __HEAP_BLOCK1_BANK               EQU	0x00000000
    __HEAP_BLOCK1_START_OFFSET       EQU	0x00000000
    __HEAP_BLOCK1_END_OFFSET         EQU	0x00000000
    ; Heap block 2, size:0 (0x00000000 - 0x00000000)
    __HEAP_BLOCK2_BANK               EQU	0x00000000
    __HEAP_BLOCK2_START_OFFSET       EQU	0x00000000
    __HEAP_BLOCK2_END_OFFSET         EQU	0x00000000
    ; Heap block 3, size:0 (0x00000000 - 0x00000000)
    __HEAP_BLOCK3_BANK               EQU	0x00000000
    __HEAP_BLOCK3_START_OFFSET       EQU	0x00000000
    __HEAP_BLOCK3_END_OFFSET         EQU	0x00000000
    gbl_status                       EQU	0x00000003 ; bytes:1
    gbl_indf                         EQU	0x00000000 ; bytes:1
    gbl_tmr0                         EQU	0x00000001 ; bytes:1
    gbl_pcl                          EQU	0x00000002 ; bytes:1
    gbl_fsr                          EQU	0x00000004 ; bytes:1
    gbl_porta                        EQU	0x00000005 ; bytes:1
    gbl_portc                        EQU	0x00000007 ; bytes:1
    gbl_pclath                       EQU	0x0000000A ; bytes:1
    gbl_intcon                       EQU	0x0000000B ; bytes:1
    gbl_pir1                         EQU	0x0000000C ; bytes:1
    gbl_tmr1l                        EQU	0x0000000E ; bytes:1
    gbl_tmr1h                        EQU	0x0000000F ; bytes:1
    gbl_t1con                        EQU	0x00000010 ; bytes:1
    gbl_cmcon                        EQU	0x00000019 ; bytes:1
    gbl_option_reg                   EQU	0x00000081 ; bytes:1
    gbl_trisa                        EQU	0x00000085 ; bytes:1
    gbl_trisc                        EQU	0x00000087 ; bytes:1
    gbl_pie1                         EQU	0x0000008C ; bytes:1
    gbl_pcon                         EQU	0x0000008E ; bytes:1
    gbl_osccal                       EQU	0x00000090 ; bytes:1
    gbl_wpua                         EQU	0x00000095 ; bytes:1
    gbl_wpu                          EQU	0x00000095 ; bytes:1
    gbl_ioca                         EQU	0x00000096 ; bytes:1
    gbl_ioc                          EQU	0x00000096 ; bytes:1
    gbl_vrcon                        EQU	0x00000099 ; bytes:1
    gbl_eedata                       EQU	0x0000009A ; bytes:1
    gbl_eeadr                        EQU	0x0000009B ; bytes:1
    gbl_eecon1                       EQU	0x0000009C ; bytes:1
    gbl_eecon2                       EQU	0x0000009D ; bytes:1
    pause1ms_00000_1_loop            EQU	0x00000024 ; bytes:2
    pause1ms_00000_1_i               EQU	0x00000026 ; bytes:2
    pause1ms_00000_1_oszilator       EQU	0x00000028 ; bytes:2
    CompTempVar574                   EQU	0x0000002A ; bytes:1
    CompTempVar575                   EQU	0x0000002A ; bytes:1
    pause_00000_arg_loop             EQU	0x00000020 ; bytes:2
    pause_00000_1_i                  EQU	0x00000022 ; bytes:2
    CompTempVar576                   EQU	0x00000024 ; bytes:1
    	ORG 0x00000000
    	GOTO	_startup
    	ORG 0x00000004
    pause1ms_00000
    ; { pause1ms ; function begin
    	MOVLW 0x28
    	BCF STATUS, RP0
    	MOVWF pause1ms_00000_1_oszilator
    	CLRF pause1ms_00000_1_oszilator+D'1'
    	CLRF pause1ms_00000_1_i
    	CLRF pause1ms_00000_1_i+D'1'
    label1
    	MOVF pause1ms_00000_1_i+D'1', W
    	XORLW 0x80
    	MOVWF CompTempVar574
    	MOVF pause1ms_00000_1_oszilator+D'1', W
    	XORLW 0x80
    	SUBWF CompTempVar574, W
    	BTFSS STATUS,Z
    	GOTO	label2
    	MOVF pause1ms_00000_1_oszilator, W
    	SUBWF pause1ms_00000_1_i, W
    label2
    	BTFSS STATUS,C
    	RETURN
    	CLRF pause1ms_00000_1_loop
    	CLRF pause1ms_00000_1_loop+D'1'
    label3
    	MOVF pause1ms_00000_1_loop+D'1', W
    	XORLW 0x80
    	MOVWF CompTempVar575
    	MOVLW 0x80
    	SUBWF CompTempVar575, W
    	BTFSS STATUS,Z
    	GOTO	label4
    	MOVLW 0x1E
    	SUBWF pause1ms_00000_1_loop, W
    label4
    	BTFSS STATUS,C
    	GOTO	label5
    	INCF pause1ms_00000_1_loop, F
    	BTFSS STATUS,Z
    	GOTO	label3
    	INCF pause1ms_00000_1_loop+D'1', F
    	GOTO	label3
    label5
    	INCF pause1ms_00000_1_i, F
    	BTFSC STATUS,Z
    	INCF pause1ms_00000_1_i+D'1', F
    	GOTO	label1
    ; } pause1ms function end
    
    	ORG 0x0000002C
    pause_00000
    ; { pause ; function begin
    	CLRF pause_00000_1_i
    	CLRF pause_00000_1_i+D'1'
    label6
    	MOVF pause_00000_1_i+D'1', W
    	XORLW 0x80
    	MOVWF CompTempVar576
    	MOVF pause_00000_arg_loop+D'1', W
    	XORLW 0x80
    	SUBWF CompTempVar576, W
    	BTFSS STATUS,Z
    	GOTO	label7
    	MOVF pause_00000_arg_loop, W
    	SUBWF pause_00000_1_i, W
    label7
    	BTFSS STATUS,C
    	RETURN
    	CALL pause1ms_00000
    	INCF pause_00000_1_i, F
    	BTFSC STATUS,Z
    	INCF pause_00000_1_i+D'1', F
    	GOTO	label6
    ; } pause function end
    
    	ORG 0x0000003F
    main
    ; { main ; function begin
    	BCF STATUS, RP0
    	CLRF gbl_porta
    	CLRF gbl_portc
    	BSF STATUS, RP0
    	CLRF gbl_trisa
    	MOVLW 0xFF
    	MOVWF gbl_trisc
    	BCF STATUS, RP0
    	CLRF gbl_intcon
    label8
    	BTFSS gbl_portc,0
    	GOTO	label9
    	MOVLW 0xFF
    	MOVWF gbl_porta
    	GOTO	label10
    label9
    	CLRF gbl_porta
    label10
    	MOVLW 0xFF
    	MOVWF pause_00000_arg_loop
    	CLRF pause_00000_arg_loop+D'1'
    	CALL pause_00000
    	GOTO	label8
    ; } main function end
    
    	ORG 0x00000053
    _startup
    	BCF PCLATH,3
    	BCF PCLATH,4
    	GOTO	main
    	END
    Wegen der for-schleife: Ich konnte keinen Fehler finden. Villeicht habe ich dich falsch verstanden. könntest du dass ein wenig genauer erläutern?

    Ich habe auch ein Problem vom Assemblercode entdeckt, dass der Auslösßer sein könnte. Ich werde ihn heute noch untersuchen:

    Code:
       MOVLW 0xFA
       MOVWF pause_00000_arg_loop
       CLRF pause_00000_arg_loop+D'1'
       CALL pause_00000
    Dabei wird zuerst der Wert 250 in die Variable pause_00000_arg_loop geschrieben, und danach durch CLRF pause_00000_arg_loop+D'1' wieder gelöscht. Was das +D'1' bedeutet, weiß ich nicht, da ich dass noch nie angewendet habe.

    Ist dass villeicht das problem?

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    15.08.2008
    Alter
    40
    Beiträge
    19
    Hallo pointhi,
    ich meine damit
    Code:
    void pause1ms(void)   
    {
       int loop;
       int i;
       int oszilator;
       oszilator = 40;      // Verwendeter Oszilator (40 = 4MHz, 80 = 8MHz)
       for(i = 0; i >= oszilator; i ++)
       {                                       
           //erster Durchgang i=0
          for(loop = 0; loop >= 30; loop ++);
       }    
              // hier i++ i ist dann 1 ABER eins ist nicht >= Oszillator (ist ja 40),
              somit wird die Schleife nicht weiter durchlaufen, da die
              Fortführbedingung ( i>=40 ) nicht erfüllt ist. Das meine ich damit, bei
              den anderen ist es ebenso müsste eigentlich < sein.
    }
    //----------------- Zeitschleife einstellbar -----------------
    
    void pause(int loop)
    {
    int i;
      for (i = 0; i >= loop; i ++)
      {
         pause1ms();
      }
    }

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied Avatar von pointhi
    Registriert seit
    18.03.2009
    Alter
    22
    Beiträge
    139
    Ich dachte immer, dass die Schelife so lage durchlaufen wird, bis i >= oszillator true ist.

    Mit der Zeitschleife habe ich auch fortschritte gemacht.
    Hab es mit der while schleife geschaft. Die schleife hat zurzeit noch eine Toleranz +- 10%. Dass muss ich verbessern, wenn ich Servos steuern möchte. Werde es heute ncoh mit der for-schleife versuchen. ist ja nur ein Zeichen, dass ich ändern muss.

    Danke für die gute Antwort. Wenn ich die Zeitschleife richtig optimiert habe, werde ich sie in diesem Tread veröffentlichen.

  7. #7
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    05.11.2007
    Ort
    Berlin
    Beiträge
    526
    Kleiner Fehler, mit großer Wirkung:
    Überall wo >= steht must Du lediglich <= schreiben.

    Siro

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied Avatar von pointhi
    Registriert seit
    18.03.2009
    Alter
    22
    Beiträge
    139
    Die häufigsten Fehler beim Programmieren sind oft nur ein paar Zeichen (;, =, ==, <=, >=,...)

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •