Sida 1 av 1

PIC16F737, SPI, extern ADC

Postat: 16 april 2006, 19:19:59
av J10
Tjosan

Jag har en AD677 som jag försöker interfacea mot SPI-porten på min PIC.
677an har seriellt interface som vill ha 17 klockpulser på in-klockpinnen per konvertering
Första klockpulsen gör ingenting för interfacet, men de nästkommande 16 shiftar ut data på ut-datapinnen och skickar ut klocksignaler på ut-klockpinnen, bredden på in-klockan påverkar inte utklockans bredd

Jag har kopplat ut-datapinnen till SDI på picen och ut-klockpinnen till SCK på picen
SSPn är konfigurerad som SPI-slave utan SS-pinne
In-klockpinnen hade jag från början kopplat till en vanlig utgång på picen och fixade klockpulser med mjukvara
Så långt fungerar allt finfint, men jag ville ha mera fart i det hela så jag bestämde mig för att använda pwm-utgången till att generera klocksignal så att man kan göra annat under tiden datan tas emot

Picen körs med 8MHz intern oscillator och jag räknade ut att högsta pwm-frekvensen som går att få blir 2MHz, helt ok hastighet
Konfigurerade för ca 50% pulsbredd och 2MHz, fungerar fint, får ut en snygg signal på pwm-pinnen
Fixade mjukvarutiming och grejjer så att jag får ut 17 klockpulser åt gången, fungerar finfint
Får ut 16 pulser tillsammans med datan ur adcn
Men... jag får bara ut en byte ur SSPn och den är helt rätt men det är allt jag får, den andra byten är som bortblåst
VARFÖR?!?!?!? :cry:

Efter en hel del testande och mätande märker jag att det fungerar fint med samma setup fast med 1MHz pwm, får 17 pulser ut från picen, 16st in i picen tillsammans med datan

Klockpulserna som kommer från adcn är ca 400nS höga och 80nS låga, som jag förstått det av "Electrical specifications" så räcker det med 40nS hög/låg för att picen ska hinna med

Så... ja, vad har jag missat eller vad handlar det om?

Postat: 16 april 2006, 19:57:41
av sodjan
8 Mhz = 0.5 us Tcy.
SPI med 2 Mhz och 0.5 us Tcy = 8 cyckler/byte.
Du har inte mycket tid på dig att spara undan
första byten innan nästa kommer...

> Klockpulserna som kommer från adcn är ca 400nS höga och 80nS låga,
> som jag förstått det av "Electrical specifications" så räcker det med 40nS
> hög/låg för att picen ska hinna med...

Jo för att läsa in *1* byte, men sedan måste ju din kod också "hinna med".
Gör den det ?

> Så... ja, vad har jag missat...

Bl.a att ange vilket "språk" du kör med, och eventuellt ett litet "test-case"... :-)

Notera också att AD6677 inte har ett riktigt SPI interface, så det blir lite
av ett "hack"...

Postat: 16 april 2006, 20:22:59
av J10
Hähä, jo, fulhack av grövsta slag är det, men det funkar

Jag kör assembler

Från det att jag enablat pwmen så väntar jag 4.5µS (har provat mellan 0.5µS (för kort) och 20µS), altså 9 klockcykler
Läser av SSPBUF, sparar undan
Väntar återstående tid (har provat mellan 0.5µS (för kort) och 20µS)
och läser av SSPBUF igen

SSPOV biten har aldrig satts

Test-case vetifan, det kommer in en byte i SSPBUF och 8 klockcykler senare har det fortfarande inte kommit in någon fler byte trots klockpulser på SCK-pinnen

Det är ju ingenting kritiskt, fungerar lika bra att köra i 1MHz
Men det stör mig att jag kan ge den en dubbelt så hög klockfrekvens men inte kan använda den pga något dumt

Postat: 16 april 2006, 20:29:17
av sodjan
OK, om du vägrar att visa kod, så kommer vi inte längre...

Postat: 16 april 2006, 20:41:54
av J10

Kod: Markera allt

movlw b'00101100'
movwf CCP1CON

goto $+1 ;Delay
goto $+1
goto $+1
goto $+1

movf SSPBUF,w
movwf adhigh

goto $+1 ;Delay
goto $+1
goto $+1
goto $+1

clrf CCP1CON

movf SSPBUF,w
movwf adlow
När PR2 är 0 så går det inte att stänga av pwmen genom att bara stänga av TMR2 så jag sköter det via CCP1CON istället, då slipper man cleara pinnen också ifall man stänger av den medan den är hög

Efter denna koden så skickas adhigh och adlow till datorn via usarten i 250kbit/s och allt upprepas igen
Jag har provat alla möjliga kombinationer av fördröjningar utan resultat

Postat: 16 april 2006, 21:15:49
av sodjan
Har du provat att polla BF istället för att hårdkoda delays ?

Postat: 16 april 2006, 21:22:49
av J10
Jo, BF sätts efter första byten men efter det är det dött :cry:

Nu har jag provat massa mera och det verkar som att den helt enkelt missar en klocksignal, om jag avbryter pwmen precis när den gått 4.5µS, läser av sspbuf och startar den igen och stänger av efter 4µS så fungerar det...

SSP modulen kanske tar en instruktionscykel på sig att flytta från SSPSR till SSPBUF och dissar allt som händer under den tiden
Det kan jag iofs förstå, att den ska kunna ta emot data i samma klockfrekvens som allt annat går i är väl kanske att kräva mycket :)

Edit: jag tror jag lägger ner detta och kör i 1MHz istället, en del av iden med detta var att få en jämn tid mellan klocksignalerna hela vägen (tror att adcn uppskattar det också) plus att det inte är värt mödan att hålla på och bråka mera
Men om någon har en lösning eller ide så välkomnas det

Postat: 17 april 2006, 00:44:56
av sodjan
OK.
Nä, det kan var svårt när ADCn ju inte kör "riktig" SPI.

Vad jag såg så har din ADC ganska snäva krav på frekvensen
på klocksignalen, den verkar vara en del av själva
konverteringen. Det är väl ett sätt få upp den i 100 ksps
vid 16 bitar, att köra konvertering och överföring samtidigt.

Man skulle kanske kunna tänka sig ett externt shiftreg,
men det blir lite knökigare att få in det i PICen sen.

Eller en annan ADC med ett mer "normalt" interface... :-)