Ich habe ein Frage bezüglich der CAN-Schnittstelle mit dem DSPIC. Ich möchte Sensorwerte über CAN mit dem DSPIC einlesen. Der Sensor hat eine Baudrate von 125 KBit/s (auch 250KBit/s möglich). Der DSPIC hat einen Quarz mit 7,3728 Mhz. Wenn der Sensor nicht angesteckt ist, gibt es keine Fehler. Sobald ich den Sensor anstecke werden die Fehlerflags von der CAN-Schnittstelle vom Interrupt Flag Register gesetzt(RXEP, IVRIF und ERRIF). Kann es daran liegen, dass der Quarz einen zu krummen Wert(Einstellung C1CFG1 = 0 und C1CFG2 0x04B0) hat und die Fehlertoleranz zu hoch ist oder wäre die noch zulässig ? Vielleicht den Quarz auf 10 oder 12 MHz erhöhen ? Wäre schön wenn mir jemand helfen könnte.
Tonelli schrieb:
> Kann mir keiner helfen ???
Nö.
Oder wie willst Du mit der krummen Quarzfrequenz die Bitrate auf besser
0,5% einschließlich Quarztoleranz treffen?
Gruß Anja
Ich habs mal grob überschlagen. Das müsste eigentlich gehen. Du müsstest mit Faktor 16 auf Tcy = 117,964 MHz kommen. Damit solltest du bei 125 und 250 kBaud auf unter 2% Fehler kommen, das langt für den CAN Bus locker. 0,5 % wie zuvor geschrieben sind absolut übertrieben. Rechne es mal nach, ich komme bei 125 kBaud auf BRP = 28 und bei 250 kBaud auf BRP = 14
Willivonbienemaya .. schrieb: > langt für den CAN Bus locker. 0,5 % wie zuvor geschrieben sind absolut > übertrieben. Die 0,5% stehen m.W. so in der Spezifikation von CAN 1.1 drin. In 2.0 sind laut Bosch und Microchip im besten Fall bis 1,58% drin, abhängig von den gewählten oder erzwungenen Parametern u.U. auch weniger. Und auch das nur bis 125Kbps.
A. K. schrieb: > Willivonbienemaya .. schrieb: > >> langt für den CAN Bus locker. 0,5 % wie zuvor geschrieben sind absolut >> übertrieben. > > Die 0,5% stehen m.W. so in der Spezifikation von CAN 1.1 drin. In 2.0 > sind laut Bosch und Microchip im besten Fall bis 1,58% drin, abhängig > von den gewählten oder erzwungenen Parametern u.U. auch weniger. Und > auch das nur bis 125Kbps. Ich habe grad mal nachgelesen. Die 0,5% -> 1,58% beziehen sich auf die Oszillatorfrequenz. Zur zulässigen Abweichung der Baudrate habe ich jetzt auf die schnelle nichts gefunden, aber die ist Erfahrungsgemäß relativ unkritisch, da ja alle paar Bits neu synchronisiert wird.
Willivonbienemaya .. schrieb: > Ich habe grad mal nachgelesen. Die 0,5% -> 1,58% beziehen sich auf die > Oszillatorfrequenz. Das ist zwar richtig, ändert aber nichts. Denn wenn man von 120MHz ausgeht und mit 117.xMhz einen Fehler von 2% hat, dann hat man runtergeteilt auf Tq oder auf die Bitrate immer noch noch 2% Fehler. Das ändert sich erst, wenn man schon dermassen schweinemässig daneben liegt, dass man mit einem anderen Teilerwert oder einer anderen Zeitaufteilung besser liegt. Die wohl autoritativste Quelle ist Boschs CIA99paper: http://www.datamicro.ru/download/iCC_06_The_Configuration_of_the_CAN_Bit_Timing.pdf
A. K. schrieb: > Das ist zwar richtig, ändert aber nichts. Denn wenn man von 120MHz > ausgeht und mit 117.xMhz einen Fehler von 2% hat, Meine 2% haben nichts mit den Taktfrequenz zu tun. Ich spreche dabei von dem Bitratenfehler. > dann hat man > runtergeteilt auf Tq oder auf die Bitrate immer noch noch 2% Fehler. Nein, beim CAN Modul des dsPIC30 gibt es so viele Stellschrauben dass du auf keinen Fall von einer Taktfrequenzabweichung automatisch auf einen Bitratenfehler schliessen kannst.
Willivonbienemaya .. schrieb: > Rechne es mal nach, ich komme bei 125 kBaud auf BRP = 28 und bei 250 > kBaud auf BRP = 14 Ich nehme an, du hast die Bedingung fCAN <= 30MHz übersehen. Oder meinst du wirklich N=4 (propseg=ph1seg=ph2seg=1)? Selbst mit fCAN = 120MHz ersetzt du einen Fehler von 1,72% nur durch einen Fehler von 1,69%. Das reisst nichts raus.
Tonelli schrieb:
> C1CFG1 = 0 und C1CFG2 0x04B0) hat
Woher hast du diese Werte? Irgendwo abgeschrieben?
Bedeutet prescaler=2, propseg=1 ph1seg=7 ph2seg=5, Summe 14xTq.
Das passt nur zu einer Oszillatorfrequenz von
125KHz * N=14 * Prescaler=2 * 4 = 14MHz.
Was passen könnte: Oszillatorfrequenz im x16-Modus auf 117MHz legen. Mit
Prescaler=26 und N=9xTq ergeben sich:
propseg=1
ph1seg=4
ph2seg=3
SJW=3
und ein zulässiger Fehler von 1,3% bei einem realen Fehler von 0.8%.
Achtung: Diese Werte für Prescaler und die Segmente sind nicht die
Registerwerte vom Controller, sondern die realen Werte!
Erstmal vielen Dank für die Antworten. @A.K.: Ich habe die Werte mit dem Microchip Can Bit Timing Calculator ausgelesen.
Ich habe allerdings einen Fehler gemacht. Hatte die falsche Oszillatorfrequenz angegeben.
Ich bin es nochmal. Leider läuft es bei mir noch immer nicht. Habe die Oszilatorfrequenz im X16 Modus (XT_PLL16). C1CFG1 auf 0x019 (SJW =1 und BRP auf 25) und C1CFG2 auf 0x0298 (Propagation = 1, ph1seg=4 und ph2seg=3) Wenn ich zwei DSPic miteinander verbinde, funktioniert es einwandfrei und ich kann mir die 8 Bytes hin- und herschicken. Doch sobald ich meinen Sensor an den CAN-Bus anstecke kommen die Fehler. Habe auch an Abschlusswiderstände (120 Ohm) gedacht.
Wenn der Prescaler durch 26 teilen soll, dann muss BRP auf 12 gesetzt werden.
@Jochen 64.: Ja habe den MCP2551 zwischengeschaltet. @ A.K.: okay werde ich das mal probieren. Ich dachte man trägt BRP direkt ein.
Tonelli schrieb: > @ A.K.: okay werde ich das mal probieren. Ich dachte man trägt BRP > direkt ein. BRP trägt man direkt ein, aber dieser im Register codierte Wert ist nicht der eigentliche Teiler. Der Takt wird durch 2*(BRP+1) geteilt.
Leider geht es immer noch nicht. Ich schicke mal den Quellcode mit. Vielleicht habe ich da ja noch irgendein Fehler.
1 | //-------------------------------------
|
2 | // Configuration dsPIC30F5013
|
3 | //-------------------------------------
|
4 | |
5 | _FOSC(CSW_FSCM_OFF & XT_PLL16); // High Speed Crystal / Resonator 7.325 MHz |
6 | _FWDT(WDT_OFF & WDTPSA_64 & WDTPSB_8); |
7 | _FBORPOR(BORV_27 & MCLR_EN); // Enable MCLR reset pin & Brown-out Reset enabled and controlled by software |
8 | _FGS(CODE_PROT_OFF); |
9 | |
10 | |
11 | |
12 | |
13 | // ***** main *****
|
14 | |
15 | int main(void) |
16 | {
|
17 | |
18 | TRISF = 0x0001; |
19 | |
20 | C1CTRL = 0x2C80; |
21 | |
22 | while (C1CTRLbits.OPMODE <=3); |
23 | |
24 | C1CFG1 = 0x000D; |
25 | C1CFG2 = 0x07B8; |
26 | |
27 | CAN1SetFilter(0,0x1604,0); |
28 | CAN1SetMask(0,0x1FFD,0); |
29 | |
30 | CAN1SetTXMode(0,0); |
31 | CAN1SetRXMode(0,0x04); |
32 | |
33 | ConfigIntCAN1(0x0021,0xFFFF); |
34 | |
35 | CAN1SetOperationMode(0x0802); |
36 | while (C1CTRLbits.OPMODE !=0); |
37 | |
38 | CAN1SendMessage(0xC004,0, txdata,8,0); |
39 | |
40 | while (!CAN1IsTXReady(0)); |
41 | |
42 | // clear TXREQ
|
43 | C1TX0CONbits.TXREQ = 0; |
44 | |
45 | // main loop
|
46 | |
47 | while(1) |
48 | {
|
49 | |
50 | }
|
51 | |
52 | return 0; |
53 | }
|
54 | |
55 | void __attribute((interrupt, no_auto_psv))_C1Interrupt(void) |
56 | {
|
57 | IFS1bits.C1IF = 0; |
58 | |
59 | if (C1INTFbits.RX0IF) |
60 | {
|
61 | C1INTFbits.RX0IF = 0; |
62 | |
63 | CAN1ReceiveMessage(rxdata, data_length, tx_rx_number); |
64 | C1RX0CONbits.RXFUL = 0; |
65 | while (CAN1IsRXReady(0)); |
66 | }
|
67 | |
68 | if (C1INTFbits.ERRIF) |
69 | {
|
70 | C1INTFbits.ERRIF = 0; |
71 | |
72 | C1INTFbits.EWARN = 0; |
73 | C1INTFbits.RXWAR = 0; |
74 | C1INTFbits.TXWAR = 0; |
75 | C1INTFbits.TXBO = 0; |
76 | C1INTFbits.RX1OVR = 0; |
77 | C1INTFbits.RX0OVR = 0; |
78 | }
|
79 | }
|
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.