PIC arbeitet mir Quarz langsamer

OP #2472395
Lesenswert?

Hallo!

Ich habe an meinem PIC einen 32,768kHz Quarz und den will ich nur für 
Timer1 verwenden und nicht als Systemtakt, deswegen muss ich ja FOSC_LP 
als Konfigurationsbit setzen, dann wird aber in folgendem Code-Beispiel 
RA2 nur alle 250 us getoggled und nicht wie bei FOSC_INTRCCLK alle 5us. 
Wieso ist das so?

Mein PIC16F690 läuft standard mit 4MHz internem Takt.
1
#include <htc.h>
2

3
__CONFIG(FOSC_INTRCCLK & WDTE_OFF & PWRTE_OFF & MCLRE_OFF & CPD_OFF & CP_OFF & BOREN_OFF & IESO_OFF & FCMEN_OFF);
4

5
#define _XTAL_FREQ 4000000
6

7
void main(void)
8
{
9
  ANSEL=0;
10
  ANSELH=0;
11
  
12
  TRISA=0b11111011;
13
  TRISC=0b11110000;
14
  
15
  while(1)
16
  {
17
    RA2=~RA2;
18
  }  
19

20
}
Gast #2472996
Lesenswert?

Manuel H. schrieb:
> Mein PIC16F690 läuft standard mit 4MHz internem Takt

dazu muss aber die Config so beginnen:

__config (_INTRC_OSC_NOCLKOUT

oder:

__config (_INTRC_OSC_CLKOUT

Damit Timer 1 den externen Uhrenquarz benutzt, muss Timer 1 Clock Source 
auf externen Clock eingestellt werde: T1CON,TMR1CS setzen.

die Zeile: #define _XTAL_FREQ 4000000 weist lediglich dem 
Namen"_XTAL_FREQ" den Wert: "4000000" zu, bewirkt aber nichts an der 
Konfiguration der PIC Hardware.
OP #2473092
Lesenswert?

Also ich verwende den HI-Tech C Compiler, welcher das "#define 
_XTAL_FREQ 4000000" nur für die __delay_us und __delay_ms Funktion 
braucht (Verzögerung entweder in µs oder ms).

Aber ich möchte doch meinen Quarz für den Timer1 verwenden und das heißt 
ich muss dem PIC mit FOSC_LP sagen, dass er OSC1/OSC2 Ein-/Ausgang als 
Takt Eingang nehmen soll, und nicht als I/O Pin.

In meinem Beispiel steht oben aber FOSC_INTRCCLK, das ist halt jetzt das 
was normal läuft also mit 4MHZ intern.

Kleiner Ausschnitt aus der pic16f690.h Include-Datei:
1
// Config Register: CONFIG
2
#define CONFIG               0x2007
3
// Oscillator Selection bits
4
// RC oscillator: CLKOUT function on RA4/OSC2/CLKOUT pin, RC on RA5/OSC1/CLKIN
5
#define FOSC_EXTRCCLK        0xFFFF
6
// RCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, RC on RA5/OSC1/CLKIN
7
#define FOSC_EXTRCIO         0xFFFE
8
// INTOSC oscillator: CLKOUT function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN
9
#define FOSC_INTRCCLK        0xFFFD
10
// INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN
11
#define FOSC_INTRCIO         0xFFFC
12
// EC: I/O function on RA4/OSC2/CLKOUT pin, CLKIN on RA5/OSC1/CLKIN
13
#define FOSC_EC              0xFFFB
14
// HS oscillator: High-speed crystal/resonator on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN
15
#define FOSC_HS              0xFFFA
16
// XT oscillator: Crystal/resonator on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN
17
#define FOSC_XT              0xFFF9
18
// LP oscillator: Low-power crystal on RA4/OSC2/CLKOUT and RA5/OSC1/CLKIN
19
#define FOSC_LP
OP #2473115
Lesenswert?

Hab jetzt mal das OSC so eingestellt wie es gehört und siehe da er 
arbeitet schonmal mit 4MHz,aber der Timer1 wechsel nur alle 250µs bei 
1:1 Prescaler, wie kommt das zustande?
1
  
2

3
T1CON=0b00001011;
4
while(1)
5
{
6
if(TMR1L!=old_TMR1L)// Taktteil
7
{
8
    RA2=~RA2;
9
    old_TMR1L=TMR1L;
10
}    
11
}
OP #2473151
Lesenswert?

Wie kann dieses Oszilloskop-Bild enstehen bei diesem Code (Messung RA2):
1
#include <htc.h>
2

3
__CONFIG(FOSC_LP & WDTE_OFF & PWRTE_OFF & MCLRE_OFF & CPD_OFF & CP_OFF & BOREN_OFF & IESO_OFF & FCMEN_OFF);
4

5
#define OSCFREQ 32765 //gemessene Quarz Frequenz
6

7
unsigned char second=0;
8
unsigned char minute=0;
9
unsigned char hour=0;
10
  
11
unsigned int clock=0;
12
unsigned int clock2=0;
13
int old_TMR1L=0;
14
char takt=0;
15
char halftakt=0;
16
char oldtakt=0;
17
char oldhalftakt=0;
18
char start=1;
19
char pressed=0;
20

21
void main(void)
22
{
23
  OSCCON=0b01100101;
24
  
25
  ANSEL=0;
26
  ANSELH=0;
27
  
28
  TRISA=0b11111011;
29
  TRISB=0b11111111;
30
  TRISC=0b11100000;
31
  
32
  PORTA=0b00000000;
33
  PORTB=0b00000000;
34
  PORTC=0b00000000;
35
  
36
  //----Interrupt-Initialisierung-------
37
  RABIF=0;
38
  TMR1IF=0;  
39
  GIE=1;
40
  PEIE=1;
41
  TMR1IE=1;
42
  RABIE=1;
43
  IOCA0=1;
44
  IOCA1=1;
45
  
46
  //----Timer1-Initialisierung----------
47
  T1CON=0b00001111;
48
  
49
  
50
  while(1)
51
  {    
52
  
53
    //--------------Timer Teil---------------//
54
    if(TMR1L!=old_TMR1L)// Taktteil
55
    {
56
        RA2=~RA2;
57
        old_TMR1L=TMR1L;
58
      }
59
    //-------------------------------------------------------------------//
60
  }
61
}
62

63
void interrupt isr(void)
64
{
65
  if(TMR1IF==1)
66
  {
67
    TMR1IF=0;
68
  }
69
}
Angehängte Dateien:
#2473294
Lesenswert?

Deine Denkfehler:

TMR1L wird mit jedem Takt (FCY) erhöht.
Deine Schleife braucht mindestens 30 Takte (oder mehr, hängt vom 
Compiler ab). Also ist TMR1L dann eher unbestimmt, wenn du das nächste 
mal dort ankommst.

Dann kommt noch dazu, dass TMR1 von 0 bis 65535 zählt.
Dein TMR1L erreicht also zweimal in der Periode den Wert auf den du 
testest.
Außerdem ….

Polle einfach auf TMR1IF oder nimm gleich eine ISR!
OP #2476014
Lesenswert?

Der interne Takt des PIC ist doch 4MHz, das heißt die Befehle werden ja 
viel schneller abgearbeitet, als der Quarz schwingt und somit das TMR1L 
erhöht. Mit Interrupt kann ich nicht arbeiten, da es zu lange dauern 
würde (2 Sekunden) und ich will ja eine Uhr machen, da brauch ich 
mindestens eine Sekunde und für den DOppelpunkt der alle 0,5 Sekunden 
blink braucht ich also mindestens 0,5s also kann ich nicht mit Interrupt 
und Quarz gleichzeitig arbeiten.

Der Quarz schwingt schon mit seinen 32,765kHz und Timer1-L-Register mit 
dem
Vorteiler 8 ändert sich nur alle 4.3ms obwohl es sich alle ca. 244 µs
ändern müsste, das versteh ich i-wie grad net.

Im Anhang, ist das Programm von meiner Uhr, wobei ich RA2 zur Kontrolle 
bei jeder TMR1L-Änderung toggle (das wäre der Doppelpunkt der Uhr).
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren