Forum: Mikrocontroller und Digitale Elektronik VS1011e & PIC 18f452


von Bastian F. (Gast)


Lesenswert?

Hallo

Ich habe eine kleine Testroutine in C18 verfasst, um den Sinustest des 
VS1011 durchzuführen. Leider bringt das Teil aber keinen Ton raus. Kann 
vielelicht jemand den Code durchschauen ob irgendwas falsch läuft?



1
 #include <p18f452.h>
2
 #include <delays.h>
3
 #include <stdio.h>
4
5
 #pragma config OSC = HS
6
 #pragma config PWRT = ON
7
 #pragma config BOR = OFF
8
 #pragma config WDT = OFF
9
 #pragma config LVP = OFF
10
11
 #define XRESET  LATBbits.LATB1
12
 #define DREQ    PORTBbits.RB2
13
 #define XDCS    LATBbits.LATB3
14
 #define XCS     LATBbits.LATB4
15
16
 void SPI_WRITE(unsigned int bData);
17
 void vs_sci(char inout, char addr, char data1, char data2);
18
 void vs_reset_hard(void);
19
 void vs_reset_soft(void);
20
 void vs_sine_test(void);
21
22
23
void main()
24
{
25
  TRISB=0b00000100;        //DREQ als Eingang
26
  TRISC=0b00010000;        //SDI als Eingang
27
28
  SSPCON1 = 0b00010010;    //Synchronous Serial Port Enable, SPI Master mode, clock = FOSC/64
29
30
   vs_reset_hard();
31
32
   vs_reset_soft();
33
   vs_sine_test();
34
}
35
36
37
38
void SPI_WRITE(unsigned int bData)
39
{
40
    SSPBUF = bData;      
41
} 
42
43
44
void vs_reset_hard(void)
45
{
46
   XCS = 1;   
47
   XDCS = 1;
48
   Delay10KTCYx(500);
49
   
50
   do{
51
      XRESET = 0;
52
      Delay10KTCYx(100);
53
      XRESET = 1;
54
      Delay10KTCYx(500);
55
      vs_sci(0x02,0x00,0x00,0x04);
56
      Delay10KTCYx(500);
57
   }while(!DREQ);
58
   
59
   Delay10KTCYx(1); 
60
   vs_sci(0x02,0x00,0x08,0x00);
61
   Delay10KTCYx(1);
62
   vs_sci(0x02,0x0b,volume,volume);
63
   Delay10KTCYx(1);;
64
   
65
}
66
67
void vs_reset_soft(void)
68
{
69
   vs_sci(0x02,0x00,0x08,0x04);
70
   Delay10KTCYx(1);
71
   vs_sci(0x02,0x0b,volume,volume);
72
   Delay10KTCYx(1);
73
}
74
75
void vs_sci(char inout, char addr, char data1, char data2)
76
{
77
   XDCS = 1;
78
   XCS = 0;
79
   
80
   SPI_WRITE(inout);
81
   SPI_WRITE(addr);
82
   SPI_WRITE(data1);
83
   SPI_WRITE(data2);
84
   
85
   XCS = 1;
86
}
87
88
void vs_sine_test(void)
89
{
90
   vs_sci(0x02, 0x00, 0x08, 0x20);
91
   while(!DREQ);
92
   
93
   XDCS = 0;
94
   
95
   SPI_WRITE(0x53);
96
   SPI_WRITE(0xEF);
97
   SPI_WRITE(0x6E);
98
   SPI_WRITE(0x44);
99
   SPI_WRITE(0x00);
100
   SPI_WRITE(0x00);
101
   SPI_WRITE(0x00);
102
   SPI_WRITE(0x00);
103
   Delay10KTCYx(500);
104
   
105
   SPI_WRITE(0x45);
106
   SPI_WRITE(0x78);
107
   SPI_WRITE(0x69);
108
   SPI_WRITE(0x74);
109
   SPI_WRITE(0x00);
110
   SPI_WRITE(0x00);
111
   SPI_WRITE(0x00);
112
   SPI_WRITE(0x00);
113
   Delay10KTCYx(500);
114
   
115
   XDCS = 1;
116
}

von holger (Gast)


Lesenswert?

Du prügelst die Daten in das SPI Modul ohne auf das Ende
der letzten Übertragung zu warten.

von Jean P. (fubu1000)


Lesenswert?

Hi,
kenne den Pic und C18 nit. Aber was mir als erstes auffällt.
1.) Du wartest in deiner SPI_WRITE Fkt. nit bis das Schieberegister leer 
ist, bevor du den nächsten wert rein schiebst(ist bei Pic sicher auch 
notwendig, bei AVR wartet man auf das setzen des SPIF Bits).

2.) Der SCI Mode ist richtig gesetzt. Was für nen Quarz hägt denn an der 
Schaltung ? Eventuell musst das Clock Register noch setzen, falls Quarz 
Frequenz nit 24.576 MHz.

3.) Lass das Soft_reset erstmal weg, ist ja eh unnötig ander Stelle und 
Lautstärke ist eh default auf max. im VS eingestellt.

4.) Eventuell auch noch mal Schaltplan posten nit das sich da der Teufel 
im Detail versteckt hat.

Gruß

von Bastian F. (Gast)


Lesenswert?

wenn DREQ high ist, kann der VS min. 32byte empfangen..

einen Fehler habe ich allerdings gefunden. Die Initialisierung des SPI 
muss lauten:


SSPCON1 = 0b00100010;   //hab mich um ein bit verfehlt.


allerdings macht der VS immer noch keinen Mux

von Bastian F. (Gast)


Lesenswert?

Schaltplan ist der vom Datenblatt des VS mit ein paar Addons.


xReset - RB1
DREQ   - RB2
xDCS   - RB3
xCS    - RB4
SCLK   - RC3/SCK
SI     - RC5/SDO

SO vom VS sind über einen Jumper mit RC0 des PIC verbunden (noch nicht 
im Programm implementiert)

Hab nun bemerkt, dass man am Lautsprecher während des Resets zweimal 
einen Klaks hört. Hab kein Oszi hier um die Schwingung zu messen. Kann 
ich aber davon ausgehen, dass der Quarz überhaupt schwingt?

von Bastian F. (Gast)


Lesenswert?

Update
Ich hab nun die SPI Übertragung von rising auf falling edge umgestellt- 
Seitdem bekomm ich bei Sinustest ein Klaksen im Sekundentakt etwa, wie 
gesagt ich hab kein Oszi... Hat jemand eine Idee?

von Jean P. (fubu1000)


Lesenswert?

Hi,
das knacken zeigt dir das der Reset erfolgreich war. 2 knackser, weil du 
einmal nen Hard und dann nen Softreset machst.
also ich war mal so frei und habe mir das Datenblatt fix reingezogen.
Hatte nochn nie mit Pic's zu tun, aber ich denke so sollte es gehen.

1.) SSPCON1 = 0b00010010;   --->falsch, da die CPOL setzt und nicht 
SSPEN
    besser SSPCON1 = 0x22;
    noch besser SSPCON1 |= (1<<SSPEN) | (1<<SSMP1);

2.)void SPI_WRITE(unsigned int bData)
  {
     SSPBUF = bData;
     while(!(PIR1 & (1<<SSPIF) );
     PIR1 &= ~(1<<SSPIF);           //vorsichtshalber, da im DS steht 
von   Hand löschen
  }

3.) und um deinen Sinus Test machste mal ne while Schleife zum testen.


P.S: Vielleicht verrätst du mal welche Frequenz dein Quarz und hast. 
Zudem solltest du die Beiträge mal lesen die geschrieben wurden.

gruß

von Bastian F. (Gast)


Lesenswert?

danke für die Tipps:

1) habe ich schon in meinem 2. Posting behoben
2) das fand ich überflüssig, da WCOL 0 ist:

bit 7 WCOL: Write Collision Detect bit (Transmit mode only)
1 = The SSPBUF register is written while it is still transmitting the 
previous word
(must be cleared in software)
0 = No collision

3)das probier ich glecih mal.



Aja das Sekundenklaksen kam daher, da ich im Programm keine Schleife 
eingebaut hatte und somit der VS immer wieder aufs neue gereseted 
wurde...

von Jean P. (fubu1000)


Lesenswert?

Ähm,
du scheinst da was falsch verstanden zu haben.
Das WCOL flag zeigt dir mit einer 1 an, das eine write Collision statt 
fand.
In dem du es auf 0 setzt , schützt es nit davor. Also benutze lieber die 
SPI_WRITE Methode, wie ich sie weiter oben gepostet habe.

P.S: Keine 100% Gewähr. Habe nur 5min das Datenblatt gelesen. Aber 
sollte passen.

P.S: Du kannst natürlich(was auch besser wäre), das SSPIF Bit vor dem 
schreiben des SSPBUF Registers abfragen. Allerdings gab es da bei den 
Avr's z.B. Probleme. Man mustte an Anfang des Programmes ein Dummy byte 
reinschreiben, damit im folgenden Programmablauf das SPIF bit funzt (ich 
meine zumindest das das so war ;-/

Gruß

von Bastian F. (Gast)


Lesenswert?

ja, da hab ich wohl mist gebaut, danke für die Aufklärung. Hab nun 
deinen Code eingebaut, allerdings bekomm ich die Meldung "Error [1105] 
symbol 'SSPIF' has not been defined"

benötige ich dafür noch eine header datei?

von Jean P. (fubu1000)


Lesenswert?

Hi,
habe mir mal schnell die p18f452.h ergoogelt.
dann probiers mal so(sollte auf jeden Fall gehen):

SSPBUF = bData;
while(!PIR1bits.SSPIF);          // wait for interrupt
PIR1bits.SSPIF = 0;          // then clear it.


sind wahrscheinlich in structs verpackt die Bitflags.

Gruß

von Bastian F. (Gast)


Lesenswert?

danke....


geht immer noch nicht. Ich hab einen 25MHz Quarz am VS. Glaube aber 
kaum, dass das die Ursache ist...
Der Code sieht mittlerweile folgend aus:
1
void main()
2
{
3
unsigned char i;
4
TRISB=0b00000100;
5
TRISC=0b00010001;
6
7
SSPCON1 = 0b00100010;  
8
SSPSTAT = 0b00000000; 
9
10
11
  SPI_WRITE(0xff);  //dummy
12
  vs_reset_hard();
13
  vs_sine_test();
14
  while(1);
15
16
}
17
18
void vs_sci(char inout, char addr, char data1, char data2)
19
{
20
  while (DREQ = 0);  //check if VS is able to accept data
21
  XDCS = 0;
22
  
23
  SPI_WRITE(inout);
24
  SPI_WRITE(addr);
25
  SPI_WRITE(data1);
26
  SPI_WRITE(data2);
27
   
28
  XDCS = 1;
29
}
30
31
void SPI_WRITE(unsigned int bData)
32
{
33
     SSPBUF = bData;        //transmit data over SPI
34
     while(PIR1bits.SSPIF = 0);    //check if data has been sent
35
     PIR1bits.SSPIF ==0;       //reset interrupt
36
} 
37
38
39
void vs_reset_hard(void)
40
{
41
  XCS = 1;   
42
  XDCS = 1;
43
  Delay10KTCYx(200);
44
   XRESET = 0;
45
   Delay10KTCYx(200);
46
   XRESET = 1;
47
48
  vs_sci(0x02,0x00,0x00,0x04);
49
  vs_sci(0x02,0x00,0x08,0x00);
50
  vs_sci(0x02,0x0b,volume,volume);
51
   
52
}
53
54
void vs_reset_soft(void)
55
{
56
   vs_sci(0x02,0x00,0x08,0x04);
57
   vs_sci(0x02,0x0b,volume,volume);
58
}
59
60
61
void vs_sine_test(void)
62
{
63
   vs_sci(0x02, 0x00, 0x08, 0x20);
64
   
65
   XDCS = 0;
66
   
67
   SPI_WRITE(0x53);  // Sine Command
68
   SPI_WRITE(0xEF);
69
   SPI_WRITE(0x6E);
70
   SPI_WRITE(0x88);  // 1500HZ @ a samplerate of 24000HZ
71
   SPI_WRITE(0x00);
72
   SPI_WRITE(0x00);
73
   SPI_WRITE(0x00);
74
   SPI_WRITE(0x00);
75
 
76
   
77
   XDCS = 1;         //Test wird nicht beendet, also weitergeführt
78
79
}

von holger (Gast)


Lesenswert?

>void SPI_WRITE(unsigned int bData)
>{
>     SSPBUF = bData;        //transmit data over SPI
>     while(PIR1bits.SSPIF = 0);    //check if data has been sent

     while(PIR1bits.SSPIF == 0);    //check if data has been sent

>     PIR1bits.SSPIF ==0;       //reset interrupt
>}

von holger (Gast)


Lesenswert?

>     PIR1bits.SSPIF ==0;       //reset interrupt

     PIR1bits.SSPIF =0;       //reset interrupt

von Bastian F. (Gast)


Lesenswert?

kann nicht glauben dass ich solche Fehler mach kopschüttel, while 
(DREQ == 0) war ebenfalls falsch

Hat aber trotzdem nichts gebracht. Immer nur die 2 klakse wärend dem 
Reset...

von Bastian F. (Gast)


Lesenswert?

ok ich habe nun die Pins am PIC durchgemessen. Was bei SDO hab ich kurz 
ein Signal drauf, was wohl auf gesendete Daten hinweist.
Allerdings messe ich bei SCK 0V, auch während des Bootens. Ich gehe 
deshalb davon aus, dass der PIC keinen Takt erzeugt. wäre das möglich, 
bzw. wie ist das zu erklären?

von Jean P. (fubu1000)


Lesenswert?

Bastian F. schrieb:
> danke....
>
>
> geht immer noch nicht. Ich hab einen 25MHz Quarz am VS. Glaube aber
> kaum, dass das die Ursache ist...
> Der Code sieht mittlerweile folgend aus:

Hehehe. Biste sicher das das kein Oberton Quarz ist ???
Clock Register musste also im VLSI einstellen.

Deinen Code schau ich mir noch mal in Ruhe an, will jetzt was essen und 
zieh mir den dabei rein ;-)

Gruß

von Jean P. (fubu1000)


Lesenswert?

Das ist schon mal falsch:

void vs_sci(char inout, char addr, char data1, char data2)
{
  while (DREQ = 0);  //check if VS is able to accept data
  XDCS = 0;

  SPI_WRITE(inout);
  SPI_WRITE(addr);
  SPI_WRITE(data1);
  SPI_WRITE(data2);

  XDCS = 1;
}

du musst statt XDCS, XCS auf Low ziehen und !DREQ oder DREQ == 0.

von Bastian F. (Gast)


Lesenswert?

der Clock ist wohl doch da. Hab nun eine Schleife mit SPI_WRITE erzeugt 
um sicherzugehen, dass er dauernd sendet. Dabei konnte ich eine Spannung 
von etwa 2,4V an CLK messen, also stimmts wohl doch...

Was die Qaurze anbelangt... der PIC & sein Quarz funzen ohne Anstand, 
habe mittlerweile mehrere Programme getestet

Beim Qaurz vom VS dachte ich, dass er schwang (oder schwingte :)) weil 
ich beim "Sekundenklaksen" vorhin die Messspitze auf Crystal Input 
gesetzt habe und da war das Klakse weg. Wie kann ich da am besten auf 
Nummer sicher gehen?

von Bastian F. (Gast)


Lesenswert?

DREQ hatte ich bereits geändert (siehe oben)
XDCS und XCS hatte ich einige male probeweise umgeändert, immer mit dem 
selben Ergebnis...
Hab nun man die Kondensatoren am Quarz abgelötet. Wenn ich bei Crystal 
input mit der Messspitze draufgehe, kommt am Lautsprecher ein 
motorsägenartiges Geräusch heraus...

von Jean P. (fubu1000)


Lesenswert?

Hehehe,
wenigstens ein Zeichen, zwar kein gutes aber immerhin ^^.

a.) Was passiert denn wenn du erst das Array im Sinus Test sendest:
{0x53 , 0xEF , 0x6E , 0x44 , 0x00 , 0x00 , 0x00 , 0x00};

b.)500ms wartest

c.) und dann dieses sendest:
{0x45 , 0x78 , 0x69 , 0x74 , 0x00 , 0x00 , 0x00 , 0x00};

d.)wieder 500ms warten.

und von a beginnst, also while(1) schleife drum herum.
Kommt da auch ne Motorsäge ^^. Sollte eigentlich dann im Sekunden Takt 
piepsen.

achso,
so setzte das clock register für 25Mhz

//CLOCK
void vs_sci(0x02 , 0x03 , 0x30 , 0xD4);

Gruß



Gruß

von Bastian F. (Gast)


Angehängte Dateien:

Lesenswert?

immer das selbe... langsam befürchte ich, dass der Chip übern Jordan 
ist. Angeschlossen ist er und war er immer korekt, vielleicht hab ich 
ihn beim einlöten geschmort. Hatte zwar bislang noch nie Einbußen dabei 
aber könnte ja mal sein.
Anbei die Ächzer und Krächzer des VS

von Jean P. (fubu1000)


Lesenswert?

Aua,
den haste wohl kaputt gedoktert. Drücke trotzdem beide Daumen das er 
noch lebt.
Gruß

von Bastian F. (Gast)


Lesenswert?

wieder ein Update für alle die nicht schlafen wollen:
hab den Quarz mal abgelötet. Das Resultat: DREQ blieb dauernd low. Erst 
als ich den Quarz wieder ranmachte, wurde DREQ high. Also geh ich davon 
aus, dass der Quarz zumindest etwas anschwingt und dass der VS nicht 
toter als maximal halbtot sein kann ::)

naja doktorn wir mal weiter, danke Jean inzwischen mal!

von Bastian F. (Gast)


Angehängte Dateien:

Lesenswert?

OK, habe nun SO vom VS mit SDI vom PIC verbunden um eigentlich zu sehen, 
ob der VS auf irgendwas reagiert... dazu hab ich vorerst mal folgenden 
Code geändert:
1
void SPI_WRITE(unsigned int bData)
2
{  
3
  while(PIR1bits.SSPIF == 0);    //check if old data has been sent
4
  PIR1bits.SSPIF =0;                      //reset check
5
  SSPBUF = bData;        //transmit data over SPI
6
  while (SSPSTATbits.BF ==0);             //*neu* wait until receive complete
7
  TXREG = SSPBUF;                         //*neu* send receive data to UART
8
}

über UART wurde nichts ausgegeben was noch nicht weiter verwunderlich 
ist. DOch ich hatte plötzlich einen Sinus freu

Macht das aber einen Sinn? AUßerdem funktioniert es auch manchmal nicht, 
dann muss man beim PIC einen Reset auslösen und dann gehts meistens 
gleich wieder.

von Bastian F. (Gast)


Lesenswert?

ok hier mal der entgültige Code damit andre was zu knabbern haben:
1
 #include <p18f452.h>
2
 #include <delays.h>
3
 #include <stdio.h>
4
5
 #pragma config OSC = HS
6
 #pragma config PWRT = ON
7
 #pragma config BOR = OFF
8
 #pragma config WDT = OFF
9
 #pragma config LVP = OFF
10
11
#define XRESET  LATBbits.LATB1
12
#define DREQ    PORTBbits.RB2
13
#define XDCS    LATBbits.LATB3
14
#define XCS     LATBbits.LATB4
15
16
void SPI_write(unsigned int bData);
17
void VS_sci(char inout, char addr, char data1, char data2);
18
void VS_reset(void);
19
void VS_sinetest_start(void);
20
void VS_sinetest_end(void);
21
22
unsigned char volume = 0;
23
24
25
void main()
26
{
27
  TRISB=0b00000100;          //DREQ als Eingang
28
  TRISC=0b00010000;          //SDI als Eingang
29
30
  SSPCON1 = 0b00100001;     //SPI enable, FOSC/64
31
  SSPSTAT = 0b01000000;     //SPI data transmitted on rising edge
32
33
  SSPBUF =0xff;  //send SPI dummy byte
34
  VS_reset();
35
36
  VS_sinetest_start();
37
  Delay10KTCYx(255);
38
  Delay10KTCYx(255);
39
  Delay10KTCYx(255);
40
  Delay10KTCYx(255);
41
  VS_sinetest_end();
42
43
  while(1);
44
}
45
46
void VS_sci(char inout, char addr, char data1, char data2)
47
{
48
  while (DREQ == 0);  //check if VS is able to accept data
49
  XCS = 0;
50
  SPI_write(inout);
51
  SPI_write(addr);
52
  SPI_write(data1);
53
  SPI_write(data2);
54
  XCS = 1;
55
}
56
57
void SPI_write(unsigned int bData)
58
{  
59
  
60
  while(PIR1bits.SSPIF == 0);    //check if data has been sent
61
  PIR1bits.SSPIF =0;         //reset check
62
  SSPBUF = bData;          //send data over SPI
63
  while (SSPSTATbits.BF ==0);    //wait until data-receive is complete
64
} 
65
66
67
void VS_reset(void)
68
{
69
  XCS = 1;   
70
  XDCS = 1;
71
  Delay10KTCYx(100);
72
  XRESET = 0;
73
  Delay10KTCYx(100);
74
  XRESET = 1;
75
76
  VS_sci(0x02,0x00,0x00,0x04);  //SoftReset
77
  VS_sci(0x02,0x0b,volume,volume);//Adjust Volume 
78
  VS_sci(0x02,0x03,0x30,0xD4);  //Adjust XTAL
79
  VS_sci(0x02,0x00,0x08,0x00);  //native Mode
80
}
81
82
void VS_sinetest_start(void)
83
{
84
  VS_sci(0x02,0x00,0x08,0x20);  //TestMode enabled 
85
  XDCS=0;
86
  SPI_write(0x53);  // Sine Command
87
  SPI_write(0xEF);
88
  SPI_write(0x6E);
89
  SPI_write(0x44);  // Frequency
90
  SPI_write(0x00);
91
  SPI_write(0x00);
92
  SPI_write(0x00);
93
  SPI_write(0x00);
94
  XDCS=1;
95
}
96
97
void VS_sinetest_end(void)
98
{
99
  while (DREQ == 0);    //check if VS is able to accept data
100
  XDCS=0;
101
  SPI_write(0x45);      // End Sine Command
102
  SPI_write(0x78);
103
  SPI_write(0x69);
104
  SPI_write(0x74);
105
  SPI_write(0x00);
106
  SPI_write(0x00);
107
  SPI_write(0x00);
108
  SPI_write(0x00);
109
  XDCS = 1;
110
  VS_sci(0x02,0x00,0x08,0x00);  //TestMode disabled 
111
}

die Änderung die dann zum Funktionieren des Code geführt haben waren:
while (SSPSTATbits.BF ==0);
und der Eintrag isn Register:
SSPSTAT = 0b01000000;

Danke für die Hilfe hier!
Gruß
Bastian

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.