VS1011e & PIC 18f452

Gast #1387473
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
}
#1387496
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ß
Gast #1387562
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?
#1387969
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ß
Gast #1387986
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...
#1387995
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ß
Gast #1388064
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
}
#1388191
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ß
Gast #1388205
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?
#1388251
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ß
Gast #1388341
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!
Gast #1388576
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.
Angehängte Dateien:
Gast #1388745
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

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