www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik VS1011e & PIC 18f452


Autor: Bastian F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?




 #include <p18f452.h>
 #include <delays.h>
 #include <stdio.h>

 #pragma config OSC = HS
 #pragma config PWRT = ON
 #pragma config BOR = OFF
 #pragma config WDT = OFF
 #pragma config LVP = OFF

 #define XRESET  LATBbits.LATB1
 #define DREQ    PORTBbits.RB2
 #define XDCS    LATBbits.LATB3
 #define XCS     LATBbits.LATB4

 void SPI_WRITE(unsigned int bData);
 void vs_sci(char inout, char addr, char data1, char data2);
 void vs_reset_hard(void);
 void vs_reset_soft(void);
 void vs_sine_test(void);


void main()
{
  TRISB=0b00000100;        //DREQ als Eingang
  TRISC=0b00010000;        //SDI als Eingang

  SSPCON1 = 0b00010010;    //Synchronous Serial Port Enable, SPI Master mode, clock = FOSC/64

   vs_reset_hard();

   vs_reset_soft();
   vs_sine_test();
}



void SPI_WRITE(unsigned int bData)
{
    SSPBUF = bData;      
} 


void vs_reset_hard(void)
{
   XCS = 1;   
   XDCS = 1;
   Delay10KTCYx(500);
   
   do{
      XRESET = 0;
      Delay10KTCYx(100);
      XRESET = 1;
      Delay10KTCYx(500);
      vs_sci(0x02,0x00,0x00,0x04);
      Delay10KTCYx(500);
   }while(!DREQ);
   
   Delay10KTCYx(1); 
   vs_sci(0x02,0x00,0x08,0x00);
   Delay10KTCYx(1);
   vs_sci(0x02,0x0b,volume,volume);
   Delay10KTCYx(1);;
   
}

void vs_reset_soft(void)
{
   vs_sci(0x02,0x00,0x08,0x04);
   Delay10KTCYx(1);
   vs_sci(0x02,0x0b,volume,volume);
   Delay10KTCYx(1);
}

void vs_sci(char inout, char addr, char data1, char data2)
{
   XDCS = 1;
   XCS = 0;
   
   SPI_WRITE(inout);
   SPI_WRITE(addr);
   SPI_WRITE(data1);
   SPI_WRITE(data2);
   
   XCS = 1;
}

void vs_sine_test(void)
{
   vs_sci(0x02, 0x00, 0x08, 0x20);
   while(!DREQ);
   
   XDCS = 0;
   
   SPI_WRITE(0x53);
   SPI_WRITE(0xEF);
   SPI_WRITE(0x6E);
   SPI_WRITE(0x44);
   SPI_WRITE(0x00);
   SPI_WRITE(0x00);
   SPI_WRITE(0x00);
   SPI_WRITE(0x00);
   Delay10KTCYx(500);
   
   SPI_WRITE(0x45);
   SPI_WRITE(0x78);
   SPI_WRITE(0x69);
   SPI_WRITE(0x74);
   SPI_WRITE(0x00);
   SPI_WRITE(0x00);
   SPI_WRITE(0x00);
   SPI_WRITE(0x00);
   Delay10KTCYx(500);
   
   XDCS = 1;
} 


Autor: holger (Gast)
Datum:

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

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Bastian F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Bastian F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Bastian F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Bastian F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Bastian F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Bastian F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:

void main()
{
unsigned char i;
TRISB=0b00000100;
TRISC=0b00010001;

SSPCON1 = 0b00100010;  
SSPSTAT = 0b00000000; 


  SPI_WRITE(0xff);  //dummy
  vs_reset_hard();
  vs_sine_test();
  while(1);

}

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;
}

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


void vs_reset_hard(void)
{
  XCS = 1;   
  XDCS = 1;
  Delay10KTCYx(200);
   XRESET = 0;
   Delay10KTCYx(200);
   XRESET = 1;

  vs_sci(0x02,0x00,0x00,0x04);
  vs_sci(0x02,0x00,0x08,0x00);
  vs_sci(0x02,0x0b,volume,volume);
   
}

void vs_reset_soft(void)
{
   vs_sci(0x02,0x00,0x08,0x04);
   vs_sci(0x02,0x0b,volume,volume);
}


void vs_sine_test(void)
{
   vs_sci(0x02, 0x00, 0x08, 0x20);
   
   XDCS = 0;
   
   SPI_WRITE(0x53);  // Sine Command
   SPI_WRITE(0xEF);
   SPI_WRITE(0x6E);
   SPI_WRITE(0x88);  // 1500HZ @ a samplerate of 24000HZ
   SPI_WRITE(0x00);
   SPI_WRITE(0x00);
   SPI_WRITE(0x00);
   SPI_WRITE(0x00);
 
   
   XDCS = 1;         //Test wird nicht beendet, also weitergeführt

} 










Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
>}

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>     PIR1bits.SSPIF ==0;       //reset interrupt

     PIR1bits.SSPIF =0;       //reset interrupt

Autor: Bastian F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Bastian F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Bastian F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Bastian F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Jean Player (fubu1000)
Datum:

Bewertung
0 lesenswert
nicht 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ß

Autor: Bastian F. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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

Autor: Jean Player (fubu1000)
Datum:

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

Autor: Bastian F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Bastian F. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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:
void SPI_WRITE(unsigned int bData)
{  
  while(PIR1bits.SSPIF == 0);    //check if old data has been sent
  PIR1bits.SSPIF =0;                      //reset check
  SSPBUF = bData;        //transmit data over SPI
  while (SSPSTATbits.BF ==0);             //*neu* wait until receive complete
  TXREG = SSPBUF;                         //*neu* send receive data to UART
} 
 

ü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.

Autor: Bastian F. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ok hier mal der entgültige Code damit andre was zu knabbern haben:
 #include <p18f452.h>
 #include <delays.h>
 #include <stdio.h>

 #pragma config OSC = HS
 #pragma config PWRT = ON
 #pragma config BOR = OFF
 #pragma config WDT = OFF
 #pragma config LVP = OFF

#define XRESET  LATBbits.LATB1
#define DREQ    PORTBbits.RB2
#define XDCS    LATBbits.LATB3
#define XCS     LATBbits.LATB4

void SPI_write(unsigned int bData);
void VS_sci(char inout, char addr, char data1, char data2);
void VS_reset(void);
void VS_sinetest_start(void);
void VS_sinetest_end(void);

unsigned char volume = 0;


void main()
{
  TRISB=0b00000100;          //DREQ als Eingang
  TRISC=0b00010000;          //SDI als Eingang

  SSPCON1 = 0b00100001;     //SPI enable, FOSC/64
  SSPSTAT = 0b01000000;     //SPI data transmitted on rising edge

  SSPBUF =0xff;  //send SPI dummy byte
  VS_reset();

  VS_sinetest_start();
  Delay10KTCYx(255);
  Delay10KTCYx(255);
  Delay10KTCYx(255);
  Delay10KTCYx(255);
  VS_sinetest_end();

  while(1);
}

void VS_sci(char inout, char addr, char data1, char data2)
{
  while (DREQ == 0);  //check if VS is able to accept data
  XCS = 0;
  SPI_write(inout);
  SPI_write(addr);
  SPI_write(data1);
  SPI_write(data2);
  XCS = 1;
}

void SPI_write(unsigned int bData)
{  
  
  while(PIR1bits.SSPIF == 0);    //check if data has been sent
  PIR1bits.SSPIF =0;         //reset check
  SSPBUF = bData;          //send data over SPI
  while (SSPSTATbits.BF ==0);    //wait until data-receive is complete
} 


void VS_reset(void)
{
  XCS = 1;   
  XDCS = 1;
  Delay10KTCYx(100);
  XRESET = 0;
  Delay10KTCYx(100);
  XRESET = 1;

  VS_sci(0x02,0x00,0x00,0x04);  //SoftReset
  VS_sci(0x02,0x0b,volume,volume);//Adjust Volume 
  VS_sci(0x02,0x03,0x30,0xD4);  //Adjust XTAL
  VS_sci(0x02,0x00,0x08,0x00);  //native Mode
}

void VS_sinetest_start(void)
{
  VS_sci(0x02,0x00,0x08,0x20);  //TestMode enabled 
  XDCS=0;
  SPI_write(0x53);  // Sine Command
  SPI_write(0xEF);
  SPI_write(0x6E);
  SPI_write(0x44);  // Frequency
  SPI_write(0x00);
  SPI_write(0x00);
  SPI_write(0x00);
  SPI_write(0x00);
  XDCS=1;
}

void VS_sinetest_end(void)
{
  while (DREQ == 0);    //check if VS is able to accept data
  XDCS=0;
  SPI_write(0x45);      // End Sine Command
  SPI_write(0x78);
  SPI_write(0x69);
  SPI_write(0x74);
  SPI_write(0x00);
  SPI_write(0x00);
  SPI_write(0x00);
  SPI_write(0x00);
  XDCS = 1;
  VS_sci(0x02,0x00,0x08,0x00);  //TestMode disabled 
}
  

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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.