Forum: Mikrocontroller und Digitale Elektronik PIC - delay macht mehr als es soll


von Ben S. (theben)


Lesenswert?

Hallo Leutz,

ich probiere mich gerade an einem PIC16F676 rum. Als die _delay(x) die x 
Systemtakte wartet ausprobieren wollte spielt mein Board verrückt.
Kurz zum Programm:
1
void main (void)
2
{
3
    ANSEL = 0x00;
4
    TRISA = 0b00000000;
5
    PORTA = 0b00000000;
6
    TRISC = 0b00000001;
7
    PORTC = 0b00000000;
8
    while (1)
9
    {
10
        // Anzeige zum Leben des Pic
11
        //_delay(500000);
12
        RC2 = 1; //LED1
13
        RA2 = 1; //LED2
14
        //_delay(500000);
15
        RC2 = 0; //LED1
16
        RA2 = 0; //LED2
17
        // Ist Taster 0 an PortC gedrückt?
18
        if(RC0==1)
19
        {
20
            //Ja
21
            RA1 = 1; //LED3
22
            RC1 = 1; //LED4
23
            RA0 = 1; //LED5
24
        }
25
        else
26
        {
27
            //Nein
28
            RA1 = 0; //LED3
29
            RC1 = 0; //LED4
30
            RA0 = 0; //LED5
31
        }
32
    }
33
}
An PortA0 1 und 2 sowie an PortC1 und 2 sitzen LED's an PortC0 hängt ein 
Taster. Nach diesem Programm läuchten die LED's 1 und 2 mit halber Kraft 
weil sie andauernd ein und aus geschaltet werden. Wenn ich den Taster 
gedrückt halte dann gehen die restlichen LED's 3 4 und 5 dauerhft an.
So alles gut.

Doch wenn ich die Kommentare vor den delays wieder lösche gehts richtig 
ab.

Zuerst blinken LED 1 und 2 wie gewollt in einem Takt, doch wenn ich den 
Taster drücke haben die anderen LED ein völlig unterschiedliches 
Verhalten.
LED4 ist wie gewollt dauehaft an
LED3 blinkt im gegensätzlichen Takt wie LED 1 und 2
LED5 geht garnich erst an

Mir will einfach nicht in den Kopf warum das passiert. Hat da einer ne 
Ahnung?

P.S.
Ich arbeite mit MPLAP X dem Compiler XC8 und dem Eval Board EasyPic V7 
von Elektronika

von PIC N. (eigo) Benutzerseite


Lesenswert?

[..]error will result if the delay period requested is too large 
(approximately 50,659,000 instructions). For very large delays, call 
this function multiple times[..]

Du könntest auch statt _delay() eine entsprechende Funktion wie 
_delay_ms() o.ä. verwenden. Dabei darf dann aber nicht vergessen werden 
vorweg _XTAL_FREQ zu definieren.

von Stefan (Gast)


Lesenswert?

Das Programm macht nur das was du eingibst.
Setz die Ports mal auf digital.

von Peter C. (peter_c49)


Lesenswert?

Hello Ben,

zeig bitte dein config und includes, bzw prüfe dies selbst.
Die _delay*XY() funktionen sind Macros die davon leben das DU
den Systemtakt richtig eingestellt bzw bekannt gegeben hast.
Ohne diese werte kommt nix gutes raus, wenn es denn überhaupt 
compiliert.

ie:

// PIC18F4520 Configuration Bit Settings

#include <xc.h>   <= wichtig

// CONFIG1H
#pragma config OSC = INTIO67    // Oscillator Selection bits (Internal 
oscillator block, port function on RA6 and RA7)
...

#define FOSC 32000000UL         // 32mhz -> befehlstakt -> 8mhz cycle 
freq
#define FCY  FOSC / 4UL        // Cycle Frequenz
#define XTAL_FREQ 32000000UL  // <== WICHTIG FÜR delay.h und xc.8 libs 
!!
#define BAUDRATE 19200UL
#define BRG (( FCY  16  BAUDRATE ) -1UL)

#include <delays.h>   <= und hier der wichtigste!!
...


erst XTAL_FREQ definieren, DANN der include <delays.h>
siehe "help" in mplabx, suchwort _delay und dann xc8 waehlen falls du 
ander compiler auch installiert hast.

solle so aehnlich in der hilfe sein:
As it is often more convenient request a delay in time-based terms 
rather than in cycle
counts, the macros __delay_ms(x) and __delay_us(x) are provided. These 
macros simply wrap around _delay(n) and convert the time based request 
into instruction cycles based on the system frequency. In order to 
achieve this, these macros require the prior definition of preprocessor 
symbol _XTAL_FREQ. This symbol should be defined as the oscillator 
frequency (in Hertz) used by the system.

mfG
Peter

von PIC N. (eigo) Benutzerseite


Lesenswert?

Peter C. schrieb:
> Die _delay*XY() funktionen sind Macros die davon leben das DU
> den Systemtakt richtig eingestellt bzw bekannt gegeben hast.

Das stimmt! Aber nicht so die _delay()

von Ben S. (theben)


Lesenswert?

Bei __delay_ms(); bkomm ich immer eine rote Zackenlinie und wenn ich 
drauf gehe steht da unable resolve identifier aber auch da habe ich das 
selbe Phänomen

Hier nochmal der Code Kopf
1
// Hauptinclude für den Pic
2
#include <xc.h>
3
// Wert des vorherschenden CPU Taktes
4
#define _XTAL_FREQ 4000000
5
#include <delays.h>
6
7
// Configurations Bits -----------------------------------------------------
8
9
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
10
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
11
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
12
#pragma config MCLRE = ON       // RA3/MCLR pin function select (RA3/MCLR pin function is MCLR)
13
#pragma config BOREN = ON       // Brown-out Detect Enable bit (BOD enabled)
14
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
15
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
16
17
//----------------------------------------------------------------------------

von PIC N. (eigo) Benutzerseite


Lesenswert?

Ich bin mir gerade nicht sicher aber ich glaube hier:
1
RC2 = 1; //LED1
wird der Port angesprochen nicht das LAT-Register. Schreibe es daher so:
1
LATCbits.LC2 = 1;
In der IF Abfrage ist es korrekt den Port zu verwenden. Ich kenne die 
Schreibweise allerdings nur in lang:
1
if( PORTCbits.RC0 == 1 ) ...

von Stefan (Gast)


Lesenswert?

Der µC hat kein LAT Register.

von Ben S. (theben)


Lesenswert?

Da bekomm ich nur Errors ich glaube die LAT gibt es bei PIC16 noch nicht 
erst ab PIC18

@Stefan das sollte ich mit
1
ANSEL = 0x00;
gemacht haben

von PIC N. (eigo) Benutzerseite


Lesenswert?

Richtig..

von Stefan (Gast)


Lesenswert?

Nein hast du nicht.
Das CMCON Register fehlt.

von Ben S. (theben)


Lesenswert?

Erster Preis geht an Stefan es fehlte das CMCON Register.

Mit
1
CMCON = 0b00000111;
klappts.

Danke

von skorpionx (Gast)


Lesenswert?

Bei einer Steuerung Zeit ist kostbar.  Funktion delay() das ist
verlorene Zeit.
Wie geht das anders? Im Interrupt werden Zeitflanken generiert und die 
werden in der while(1)Schleife ausgewertet. Delay() kann man nur außer 
while(1) verwenden für Initialisierung.

von Ben S. (theben)


Lesenswert?

Ja ich kenne mich mit AVR einigermaßen aus. Will mich jetzt mal in die 
Materie PIC ein arbeiten und da ist so ein blinken ganz praktisch damit 
man sieht ob der µC überhaupt noch arbeitet. Bei gescheiten Programmen 
werde ich dann an die Timer gehen aber wenn ich vorher schon zu blöd bin 
um Ein- und Ausgänge zu schalten dann bringt das auch nichts.

von skorpionx (Gast)


Lesenswert?

Vor einiger Zeit wollte ich auf diesem Forum eine Diskussion über 
unprofessionelle  Verwendung von delay() und auch über vernünftige 
Verwendung von goto anstoßen . Leider wurde dieser Thema nach sehr kurze 
Zeit gelöscht. Das sagte mir sehr viel über den Moderator...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.