PIC programmering i C - Kompilator?

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> USART'en är väll det snabbaste sättet att skicka data mellan PIC'arna?

I2C eller SPI skulle nog kunna vara snabbare, men kanske lite mer job
att få igång om man inte har använt det tidigare.

Eftersom du själv har full kontroll över båda ändar av kommunikationen
så kan du ju hitta på vilket protokoll som helst...

> Jag tänkte att under den tiden som timer2 rullar kanske jag får ignorera USART'en

Nja, du kan ju göra annat (t.ex läsa USART'en) medan timern rullar.

> 10mS på mig, räcker det till 10byte tror ni?

Det beror ju helt på baud-raten... :-)
Användarvisningsbild
Greve Hamilton
EF Sponsor
Inlägg: 544
Blev medlem: 4 september 2004, 15:03:35
Ort: GBG

Inlägg av Greve Hamilton »

Om man absolut måste använda delay_ms och med variabler, så finns vdelay_ms att använda.

Mina erfarenheter av delay_ms är precis som sodjan och icecap säger - man låser sig oftast alldeles för mycket. Det fungerar bra till blink-a-LED-program och om man bara behöver en liten delay på något enstaka ställe, men annars finns det ingen som helst anledning att inte använda uC:ns timer, då den oftast är så enkel.
Användarvisningsbild
squiz3r
Inlägg: 5424
Blev medlem: 5 september 2006, 20:06:22
Ort: Lund
Kontakt:

Inlägg av squiz3r »

"..så kan du ju hitta på vilket protokoll som helst..."
Det är så det brukar bli, men jag tänkte att jag skulle försöka standardisera mig lite mera :)

"Nja, du kan ju göra annat (t.ex läsa USART'en) medan timern rullar."
Är det inte risk att man förlorar data m.m. om man har interruppt på när man håller på med USART'en?

"Det beror ju helt på baud-raten..."
Frågan är hur hög baud-rate den klarar av att köra, och sen minns jag inte riktigt hur man räknar på baud-rate, är det byte/sekund eller bit/sekund? :)

"men annars finns det ingen som helst anledning att inte använda uC:ns timer, då den oftast är så enkel."
Mjo.. Eftersom det bara finns 3 timrar så kan de ta slut :)

Mvh
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

baud = "antalet nivåändringar på linjen per sekund".
*Oftast* är detta lika med "bitar per sekund", men inte alltid, man
kan t.ex ha en linje som använder 4 olika spänningsnivåer, och då
blir varje "baud" = 2 "bps"... :-) Om man sedan tittar på t.ex en
ADSL linje, så blir det ändå mer komplext... :-) :-)

> Är det inte risk att man förlorar data m.m. om man har interruppt på när man håller på med USART'en?

Alltså, USART'en kan ta imot data samtidigt som du servar andra interrupt.
Den enda kravet är att du inte ligger i ett annat interrupt längre än
tiden för att ta imot ett komplett tecken, då kommer du att få en "over-run".

Det är större sannolikthet att din USART-ISR kommer att störa genereringen
av servo-pulser så att servot rycker lite. Men du kan ju styra GIE så att
du t.ex enbart hanterar USART'en i 20 ms mellanrummet mellan
pulserna, det är inte så kritiskt. Och ha GIE = 0 under själva servo pulsen.

D.v.s att du *kanske* ska köra USART'en lite långsammare istället
för så snabbt som möjligt...
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Det är ett grovt designmiss att köra soft-UART till att börja med! Soft-UART är en nödlösning som i det längste ska undvikas och med interrup aktiva är det bannlyst att ha soft-UART!

Så enkelt är det!

Du blandar ihop de sämsta funktioner till ett system som då med stor sannolikhet blir instabilt som bäst.
Användarvisningsbild
squiz3r
Inlägg: 5424
Blev medlem: 5 september 2006, 20:06:22
Ort: Lund
Kontakt:

Inlägg av squiz3r »

Sodjan: Hmm. Ok, värt att fundera på! Nu la jag in det så att ett interruppt kan avbryta USART'en, men bara det korta som kommer var 12'e mS. Det som tar långtid (1-2ms) väntar tills USART'en är klar. (men nu skickar jag bara en byte)

Icecap:Ok.. Problemet är att jag bara har en USART på PIC'en (16F887 eller 16F877A) och den ska jag använda till en annan sak som ska överföra mycket mer data. Så vad rekomenderar du i så fall?

---

Nu har jag fått det att fungera så att jag styr ett servo (possition mellan 1-26) från datorn serie port. Dock kan jag bara skicka sifran 0-9 eftersom det skickas som ASCII.. Så då är frågan, hur ska jag göra för att ta imot två siffror sedan göra om dem till EN short (0-256)? Jag vet hur jag gör om dem till short, men sen ska dem läggas ihop till en..

En idé jag fick var att göra såhär (var1 och var2 är det som tas emot från USART'en och var3 är den jag kan använda sen):
var1 = 2
var2 = 5

var3 = (var1 * 10) + var2

Men om man bara skickar t.ex. "8" så kommer det uppfattas som "80" annars måste man skriva "08".. Och vad händer om man råkar skriva in 3siffror istället, då kommer den komma i oordning så att den första kommer i den andra och vice versa, så måste man antingen starta om den eller skriva ett till tal med ojämnt antal siffror i för att få det rätt igen :S.

Iverförsig är inte detta något problem när man kör den från en annan PIC som skickar det i en systematisk ordning, men det hade varit roligt om den fungerade som servokontroller från datorn :).

Mvh
thepirateboy
EF Sponsor
Inlägg: 2109
Blev medlem: 27 augusti 2005, 20:57:58
Ort: Borlänge

Inlägg av thepirateboy »

Ett sätt kan vara att definera start och slut på överföringen, med till exempel 0x02 (STX = Start text) och 0x03 (ETX = End text)

Exempel: 0x02 '8' 0x03
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Det var kollosalt vad svårt du gör det för dig ! :-)
Det är väl bara att du bestämmer dig för ett format, så är det ju löst... :-)
Ett format med givna start/stopp tecken som thepirateboy föreslår
är aldrig fel.

Är det bara ett servo ? Annars kanske du behöver ett servonummer också.
Men som sagt, jag förstår inte vad som är problemet, bestäm dig bara... :-)

> Nu la jag in det så att ett interruppt kan avbryta USART'en,

Hur då "avbryta" ? Vad är det som "avbryts" ?
USART'en är ju i hårdvaran, så *den* kan inte "avbrytas".

> Det som tar långtid (1-2ms)

Finns det ett avbrott (interrupt) som tar 1-2 ms att "serva" ?
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Och med "mitt" projekt skriver man t.ex. STX 1499 ETX eller i hex: 02 31 34 39 39 03

I det program har du ALLT du vill ha... men det är ju tydligen för komplicerat fastän det finns en del kommentarer som hjälp.

Det är dock ett ganska enkelt program och kan du inte använda delar av det och/eller bli inspirerat tror jag att du kommer att gå bet ändå, helt enkelt för att projektet verkar mer komplicerat än du klarar av i dagsläget.

Och hur du ska klara av att undvika soft-UART?
PIC18F44J11, PIC18F45J11 & PIC18F46J11 har alla dubbla UART och är i 40-pinnars kapsling.
Användarvisningsbild
squiz3r
Inlägg: 5424
Blev medlem: 5 september 2006, 20:06:22
Ort: Lund
Kontakt:

Inlägg av squiz3r »

"USART'en är ju i hårdvaran, så *den* kan inte "avbrytas"."
Förlåt, dåligt uttryckt. Menade att rutinen som läser USART'en avbryts. :)

"Finns det ett avbrott (interrupt) som tar 1-2 ms att "serva" ?"
Mje.. Men var 10'e mS kommer det ett interrupt som sätter en flagga, sedan går den tillbaks till huvudprogrammet. När den kommer dit och ser att flaggan är satt skickas den till en funktion (efter att ha gjort klart dataöverföringen om det fanns någon) i den funktionen sätts utgången till servot hög, sedan sätter jag på en timer (tmr2) som gör ett interrupt var 50'e µS där den räknar upp en variabel. När den variabeln är lika stor som den önskade servopositionen blir utgången låg. När variabeln är 45 (max position vad servot kan stå på) går den ur funktionen och tillbaks till main-loopen. Så det är den funktionen som tar ca. 2ms.


"Är det bara ett servo ? Annars kanske du behöver ett servonummer också."
Nu är det bara ett servo, men jag tänkte ha fler sen.

När den ska komunisera med den andra PIC'en tänkte jag göra det enklare genom att inte konvertera det till ASCII utan skicka det direkt som det är. Om jag tex. vill att servo1 ska vara på possition 5, servo2 på 11, servo3 på 23 så tänkte jag att jag kan skicka såhär (decimalt):

083 005 011 023 069

Där 083 ('S') är startbit, och 069 ('E') är slutbit.

Icecap: Jag ska läsa igenom ditt program ett par gånger till. Där är många syntax som jag inte känner till, men man lär ju sig efterhand :).

Mvh.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Menade att rutinen som läser USART'en avbryts.

OK, då är jag med. :-)
Å endra sidan behövs det inte många instruktioner för att läsa RXREG.
Å tredje sidan så läses väl USART'en i en ISR, så den kan inte avbrytas...

Sedan kanske du kan hantera både pausen och pulsen på samma sätt.
D.v.s genom att kolla en flagga i main(). D.v.s istället för att
ligga kvar i din 2ms-funktion. Eller som nedan...

> När den variabeln är lika stor som den önskade servopositionen

Jag antar att det kollas i din "2ms-funktion". Det kan göras i ISR'en istället.
Och då behöver du inte ligga kvar i funktionen, utan kan gå direkt
tillbaka till main().

Jag skulle låta ISR'en till Timer2 även avsluta pulsen direkt, så spara du
lite tid för main().

Ett annat sätt är att ställa en timer till *olika* värden (d.v.s "positioner"), då
slipper du en räknare och servo pulsen avslutas direkt vid första interruptet.
Dessutom blir det lite enklare att ha finare upplösning på positionen.
I ditt fall kommer det att bli väldigt tätt mellan avbrotten...
Användarvisningsbild
squiz3r
Inlägg: 5424
Blev medlem: 5 september 2006, 20:06:22
Ort: Lund
Kontakt:

Inlägg av squiz3r »

URK! Jag hatar spärren på 2k programm :cry:.

Det var inte ett stort programm man kunde göra i µC innan man kom upp i det... Nu fuskade jag lite (Förlåt Icecap! :)) och använde den färdiga rutinen för LCD-displayen.. Jag undrar om den är mycket mer ineffektiv än att göra en egen.. Någon som vet?

Min erfarenhet säger att om jag hade gjort samma programm i ASM hade det tagit max 0,5kb..

Har funderat på att köpa det, men om minnet går såhär snabbt är det ju knappt någon idé, för då är det ju ändå inte mycket man får in i processorerna..

Mvh
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Om du använder printf() eller liknande är det vad som fyller upp minnet! Jag testade att skriva ut tal på "eget sätt" och med printf() och med printf() var minnet fullt direkt, med "eget sätt" tog hela programmet ca: ½k.

Gissa själv vilken version jag använder...
Niklas-k
Inlägg: 354
Blev medlem: 10 mars 2004, 15:59:21
Ort: Katrineholm

Inlägg av Niklas-k »

Det finns en LCD rutin att ladda ner på
http://www.mikroe.com/en/projects/mikrobasic.php
Som heter LCD4 OPTIMUM och är mycket mer minnes effektiv.
Användarvisningsbild
squiz3r
Inlägg: 5424
Blev medlem: 5 september 2006, 20:06:22
Ort: Lund
Kontakt:

Inlägg av squiz3r »

Niklas-k: Men det är i mikro basic, jag kör med mikro C :)

Icecap: Okej, jag tror att jag ska göra det istället då :). Måste bara lära mig hur man gör för att få det i 4bitars mode..

Mvh
Skriv svar