Hallo, ich möchte ein IC über den SPI-Bus ansteuern, welches im "Motorola SSP frame format" kommuniziert. Wie muss ich den SPI am AVR (z.B. ATMega48) einstellen, damit sich die beiden Bausteine verstehen? Im Forum von AVR Freaks habe ich etwas von der Einstellung CPOL = 0 CPHA = 1 gelesen - stimmt das?
Es wäre recht hilfreich, wenn du uns sagen würdest, WELCHEN IC du verwendest bzw. einen Link zu einem Datenblatt postest oder dieses hier hochlädst. Mit dem Begriff "Motorola SSP frame format" kann ich persönlich nichts anfangen. Üblicherweise werden die Datenframes und das Timing im Datenblatt genau erklärt. Ich glaube nicht, dass da nur "Motorola SSP Frame Format" ohne genauere Beschreibung drin steht. Wenn es wirklich SPI-Kommunikation ist, die dein IC braucht: Prinzipiell sind beim AVR vier verschiedene SPI-Modi möglich. Eine Beschreibung zu diesen Modi gibt's z.B. hier: http://www.mikrocontroller.net/articles/Serial_Peripheral_Interface Der Rest steht im Datenblatt deines AVR.
Wie kommst du eigentlich auf die Idee, dass dieser Chip SPI braucht? Laut diesem Datenblatt hat der ADS1251 überhaupt kein SPI-Interface. Der wird über ein 2Wire-Interface angesprochen.
Wenn ich auf der TI Seite nach ADCs suche und die Suchoption "Serial SPI Interface" anklicke, erscheint dieser Chip. Außerdem kann ich ihn mit einem ARM7 über SPI auslesen. Kennst du dich mit diesem Chip aus oder hast du eine Library zur Kommunikation?
Naja ist halt wieder ne typische Peter (Gast) Anfrage:-) Im ganzen Datasheet des ADS1251 kommt "Motorola SSP frame format" nicht vor! @Peter (Gast) was bastelst du eigentlich? Lies doch mal das Datasheet ab Seite 12 "SERIAL INTERFACE" durch.. Wird wohl etwas aufwendig mit dem SPI Interface des AVR (ATMega48). Der ADS1251 ist wohl nichts für Anfänger.
Auf das "Motorola SSP frame format" komme ich, weil ich beim ARM7-Controller dieses eingestellt habe und es damit funktioniert. Heute habe ich einfach mal nach den zwei Flanken den SCLK Pin getoggelt so dass Daten ankamen. Werde das dann wohl "per Hand" ohne SPI machen. "ADS1251 ist wohl nichts für Anfänger" --> Da hast du Recht - kein Mensch kennt sich damit aus - selbst die Gurus aus den Foren können nicht weiterhelfen. Naja, in den nächsten Tagen wird es bei mir laufen und dann poste ich den Code.
>selbst die Gurus aus den Foren können >nicht weiterhelfen. Vieleicht haben die den Baustein noch nie verwendet. Ich habe das Datasheet ab Seite 12 "SERIAL INTERFACE" nochmals kurz überflogen. Ist eine "nicht übliche" Schnittstelle mit einigen Tücken. Die hatten halt 1 Pin zu wenig! Wie hoch ist den deine CLK Frequenz an Pin 4? >Naja, in den nächsten Tagen wird es bei mir laufen >und dann poste ich den Code. Mit einger Erfahrung im Embedded-Design und eine guten Scope zum debugen ist das sicher möglich. Viel Erfolg!
Die Ansteuerung ist eigentlich echt simpel, wenn man KEIN SPI verwendet, sondern das "per Hand" macht: Zunächst einmal muss man einen "beliebigen" Takt an den CLK Pin anlegen (beliebig in sofern, dass man damit die DATA OUTPUT RATE bestimmt - s. Datenblatt auf Seite 8). Danach kann man mit dem Oszilloskop auf der DOUT-Leitung zwei Peaks erkennen (ein langer und ein kurzer). Diese Peaks muss man abwarten, bevor man die Daten dann über Toggles an SCLK am Pin DOUT "heraustakten" kann. Das muss man 24 mal machen (da 24 Bit). Meine Realisierung dazu sieht so aus:
1 | // Init Timer - initialization of the 16-Bit Timer
|
2 | void init_timer(void) |
3 | {
|
4 | TCCR1A = (1<<COM1A0); // Toggle on OC1A |
5 | TCCR1B = (1<<CS10)|(1<<WGM12); |
6 | |
7 | OCR1A = 128; |
8 | }
|
9 | |
10 | int main (void) |
11 | {
|
12 | // local variables
|
13 | uint32_t single_value = 0; |
14 | uint8_t n,m; |
15 | uint8_t m_value[3] = {0,0,0}; |
16 | char buffer[12]; |
17 | |
18 | // initialization
|
19 | init_main(); |
20 | init_timer(); |
21 | lcd_init(); |
22 | |
23 | sei(); |
24 | |
25 | // main program
|
26 | while(1) |
27 | {
|
28 | while(!(PINB & (1<<4))){}; |
29 | _delay_us(500); // wait until the two peaks passed |
30 | |
31 | m_value[0] = 0; |
32 | m_value[1] = 0; |
33 | m_value[2] = 0; |
34 | for (m = 0; m<3; m++) { |
35 | for (n = 0; n<8; n++) { |
36 | PORTB |= (1<<5); // set |
37 | _delay_us(3); |
38 | PORTB &= ~(1<<5); // reset |
39 | m_value[m] |= (((PINB & (1<<4))>>4)<<(7-n)); |
40 | _delay_us(2); |
41 | }
|
42 | }
|
43 | single_value = ((uint32_t)m_value[0]<<16) + ((uint32_t)m_value[1]<<8) + m_value[2]; |
44 | ultoa(single_value, buffer, 10); |
45 | usart_write("SPI = %s\r", buffer); |
46 | |
47 | _delay_ms(500); |
48 | }
|
49 | }
|
Es geht mit Sicherheit noch einfacher (besonders die Shift-Operationen lassen sich noch vereinfachen - das sehe ich schon beim Posten, aber: "never change a running system" :-D) Ich finde den Chip jetzt - seit er funktioniert - eigentlich ganz nett, da er sehr kompakt (8 SOIC) ist, eine hohe Auflösung bietet und über nur drei Leitungen + Versorgungsspannung betrieben werden kann.
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.