Sida 1 av 1

Capture på PIC16 ger inte väntat resultat

Postat: 27 september 2017, 19:52:05
av bos
Jag ska dumpa data från en C64-kassettbandspelare. Enligt dokumentation jag hittat här och var så består den digitala dataströmmen av tre signaler; 0-bit, 1-bit och sync-bit. Det som skiljer dem åt är bredden/tiden mellan negativa flanker.

0-bit: 380us
1-bit: 520us
sync-bit: 700us

Med oscilloskop bekräftar jag dessa tider (+/- 20us) för ett originalspel på en originalbandspelare vars tonhuvud inte har justerats (låslacket sitter kvar på skruven).

Jag kopplar upp en PIC16F628A på labbplattan och sätter på en 20MHz kristall. Detta ger processorn en instruktionstid på 4/20M = 200ns, och kristallfrekvensen har bekräftats med oscilloskop.

Datasettens pinne 4 ("READ") kopplas till pinne 9 som är RB3/CCP1, och jag ställer in den pinnen att användas som "Capture mode, every falling edge".

Timer1 körs i "timer mode", vilket innebär att räknaren ökas med 1 för varje klockcykel/instruktion. Detta innebär att antalet ticks för datasettens bittar blir följande:

0-bit: 380us / 200ns = 1900
1-bit: 520us / 200ns = 2600
sync-bit: 700us / 200ns = 3500

För att få lite spelrum med brus och annat så lägger jag till lite marginaler:

0-bit: 1550-2250 ticks
1-bit: 2251-3050 ticks
sync: 3051-3950 ticks

Min enda avsikt här är att mäta tiderna. Jag läser in 40 värden (mer minne har jag inte tillgängligt) i en array, konverterar talen till strängar och skickar ut alla via RS232 till min laptop (där minicom tar emot allt och loggar datat). Därefter börjar loopen om; 40 nya värden mäts, konverteras, skickas. Repetera. Vissa bittar går förlorade under tiden RS232-leveransen sker, men det gör inget eftersom jag som sagt är ute efter pulstiderna.

När all data är överförd har jag en ungefär 12000 rader textfil som ser ut såhär, där siffrorna anger antal ticks:

02200
01847
02289
02179
02269
01152
02261
02625
02223
01817
02284
02173
02273
...

Detta matar jag sen till ett Python-script för att se hur tiderna är utspridda.

Resultatet förväntas bli relativt jämn spridning mellan 0/1/sync och några få lower/higher (utanför mina marginaler), men resultatet ser ut såhär:

Kod: Markera allt

  $ ./1531.py 1531_dump.1506334803
  {'lower': 113565,
    'ones': 94978,
    'zeros': 24804,
    'sync': 36932,
    'higher': 1}
Ett annat originalspel ger detta resultat:

Kod: Markera allt

  $ ./1531.py 1531_dump.1506333406
  {'lower': 84634,
   'ones': 10651,
   'zeros': 82658,
   'sync': 75088,
   'higher': 9}
I båda fallen är det en grav överrepresentation av "lower" ("higher" är ok), och jag kan inte komma på vad det är som är fel. Eftersom oscilloskopet ger mig rätt tider är det något i min kod som är feltänkt. Jag kollade databladet för att se minimitider till Capture-modulen, men alla dessa ligger på nivån nanosekunder så det bör inte vara att Capture triggas för snabbt.

Hela den körbara källkoden finns här: http://99dbf8a8cf47aef7.paste.se/

Finns det något uppenbart som jag har gjort/tänkt fel här?

Re: Capture på PIC16 ger inte väntat resultat

Postat: 27 september 2017, 20:28:06
av H.O
Hur ser signalen ut vad gäller signalnivåer och eventuella störningar? Kanske värt att låta den passera en schmitt-trigger?

Re: Capture på PIC16 ger inte väntat resultat

Postat: 27 september 2017, 23:59:35
av bos
Signalen är ren och fin på 'skopet, knappt nåt brus alls, och den kommer direkt från en schmigger så den behöver inte behandlas ytterligare.

.

Re: Capture på PIC16 ger inte väntat resultat

Postat: 2 oktober 2017, 14:04:29
av bearing
"Det som skiljer dem åt är bredden/tiden mellan negativa flanker"

Är du säker på att det inte är tiden mellan positiv och negativ flank?

Re: Capture på PIC16 ger inte väntat resultat

Postat: 2 oktober 2017, 14:10:06
av bos
bearing skrev:"Det som skiljer dem åt är bredden/tiden mellan negativa flanker"

Är du säker på att det inte är tiden mellan positiv och negativ flank?
Ja. All referensmaterial jag tittat i säger samma sak.

En bekant gav dock tips om det kan ha att göra med en fastloader till C64. Finns en sån så är flanktiderna ändrade.

.

Re: Capture på PIC16 ger inte väntat resultat

Postat: 2 oktober 2017, 16:51:03
av bearing
Ok, så om det är din kod som är problemet, föreslår jag att du lägger upp den. CCP:n har ju använts i decennier, så den lär inte ha några okända buggar.

Re: Capture på PIC16 ger inte väntat resultat

Postat: 2 oktober 2017, 16:56:26
av bos
Länk till koden finns i ursprungsinlägget, näst sista stycket.

.

Re: Capture på PIC16 ger inte väntat resultat

Postat: 2 oktober 2017, 17:27:36
av bearing
Min gissning är att detta är en bugg:
TMR1 = 0;

Har inte hållit på med PIC på många år, men har för mig att det där behöver göras på ett speciellt sätt, annars kan man hamna på 256 efter nollställning.

Jag har, sedan jag insett detta problem på diverse processorer, ändrat strategin till att låta timern löpa fritt, och sedan räkna fram avståndet mellan flankerna istället för att läsa direkt från CCP-registret. Detta är en mycket robustare lösning, eftersom att CCP-registret är statiskt ändå till nästa flank.

Kod: Markera allt

uint16_t edge, old_edge;
if (CCP1IF)
{
        CCP1IF = 0;

        edge = CCPR1;
        bit_time = (uint16_t) edge - old_edge;
        old_edge = edge;
}
(Notera att detta fungerar även om TMR1 "slagit runt" mellan old_edge och edge.)

Den andra buggen är att TMR1 kommer ha ett slumpmässigt värde efter att du skickat dina 40 bytes, så den följande mätningen kommer vara fel.

Re: Capture på PIC16 ger inte väntat resultat

Postat: 2 oktober 2017, 19:30:24
av lillahuset
Hur kommer det sig att du bara har minne till en buffer för 40 värden? Processorn har 224 byte RAM.
I main() kastar du bort 4 byte på onödiga variabler.
Gör du convert_time_to_chars() till en del av main() sparar du 10 byte RAM (numbers).
Ta bort bit_count så sparar du 4 byte RAM.
Vad gör kompilatorn av resterande RAM? Rimligen borde du kunna ha en buffer med 100 värden.

Sedan skulle jag aldrig lita på en PIC med 20MHz klocka på en labbplatta.


Nu till det jag tror är fel. Jag gissar på ditt pythonscript. Bara en gissning. Men de mätvärden (ja väldigt få) du visar har följande fördelning:
L 1 (jag antar att du menar lägre än lägsta godkända värde)
0 6
1 6
S 0
H 0 (högre än godkänt)

Lägg upp några filer med rådata så får vi se.

Re: Capture på PIC16 ger inte väntat resultat

Postat: 8 oktober 2017, 16:28:58
av bearing
Fick du ordning på det?

Re: Capture på PIC16 ger inte väntat resultat

Postat: 8 oktober 2017, 16:35:00
av bos
@bearing: Nej, familjen och firman kom emellan.

Jag hoppas kunna peta lite på det nu i veckan.

.

Re: Capture på PIC16 ger inte väntat resultat

Postat: 17 oktober 2017, 20:22:50
av bos

Re: Capture på PIC16 ger inte väntat resultat

Postat: 17 oktober 2017, 20:54:26
av lillahuset
Ja det var ju ett synnerligen begåvat ställe att lägga filerna på.
Varför inte bara zippa och bifoga?