Vad är det som skapar en "död punkt" i denna loop?

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Magnus_K »

Nu handlar detta om att programmera en µC men valde att göra tråden i denna kategori då det nog är mer programmeringsrelaterat.

När jag kör den här koden (klippt bort configen med mera som jag tror är onödigt) så skapas en "glitch". Målet är att PWM1_Set_Duty ska gå fram och tillbaka med värde "value" men när värdet når 100 tycks något hända innan eller precis när value ska räknas ner igen.
Ser någon vad som kan skapa detta? Det är precis som att den hoppar ur loopen och sen återvänder...
Om det är nödvändigt så ska jag givetvis posta hela koden och förklara mer ingående vad som händer.

Kod: Markera allt

unsigned char step;
unsigned char value;
const unsigned char constants[100] = {1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,
                                      11,12,12,13,13,14,14,14,15,15,16,16,17,17,18,
                                      18,19,19,20,20,21,21,22,23,23,24,25,25,26,27,
                                      27,28,28,30,31,32,33,34,36,37,39,41,42,44,45,
                                      47,49,52,55,57,60,62,65,68,71,75,79,83,87,91,
                                      95,99,103,107,111,115,119,123,127,131,134,138,
                                      142,146,150,154,158,162,166};


void main() {

PWM1_Set_Duty(1);
Delay_mS(5);
step = 0;


        while(1)
         {
                for(step = 0; step < 100; step++)
                {
                PWM1_Set_Duty(value);
                value = constants[step];
                Delay_ms(30);
                }
                for(step = 100; step > 0; step--)
                {
                PWM1_Set_Duty(value);
                value = constants[step];
                Delay_ms(30);
                }
         }
}
Användarvisningsbild
Klas-Kenny
Inlägg: 11811
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Klas-Kenny »

constants[100] som du försöker läsa i den andra loopen finns inte.
Nerre
Inlägg: 27168
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Nerre »

Precis, en matris dimensionerad med [100] innehåller 100 element numrerade från 0 till 99.

http://www.drpaulcarter.com/cs/common-c-errors.php#2.4
sodjan
EF Sponsor
Inlägg: 43242
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av sodjan »

Nu vet jag inte var du kör, men i alla fall med MPLAB (X eller 8 ) och
CX8 så borde det gå att köra det i simulatorn och kontrollera
vad som händer vid det läget. Nu talar ju allt för att det
är indexeringsfel av arrayen, men till nästa gång... :-)
Nerre
Inlägg: 27168
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Nerre »

Kan ju tilläggas att den första loopen funkar eftersom den går från 0 och så länge den är mindre än 100. Den går från 0 till 99 alltså. Den andra loopen försöker gå från 100 till 1 (så länge den är större än noll). (Jag TROR att det också är vanligt C-misstag:)

Så för att rätta till koden skulle jag dels rekommendera att använda rätt gränser (0 och 99) och dels använda <= respektive >= i jämförelsen. (Möjligen kan man vända på jämförelsen också, jag minns inte om det har några bieffekter.)

Detta för att kunna ha samma siffror i bägge looparna.
sodjan
EF Sponsor
Inlägg: 43242
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av sodjan »

Att en 100-pos array inte indexeras 1-100 är dels
ett av de vanligaste nybörjarfelen och samtidigt
en av de mer korkade sakerna med C... :-)
Användarvisningsbild
Klas-Kenny
Inlägg: 11811
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Klas-Kenny »

Vad finns det för språk som inte indexerar arrayer likt C?

Alla jag någonsin skrivit kod i fungerar på samma sätt. :)
johano
Inlägg: 1943
Blev medlem: 22 januari 2008, 10:07:45
Ort: Stockholm

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av johano »

Att C indexerar från 0 är ju en direkt följd av pekar/array-ekvivalensen där array[ offset ] skall vara helt
utbytbart mot *( array + offset )

Basic däremot har indexering från 1.
Många andra språk har nog valt indexering från 0 som "arv" från C, de hade kunnat
välja 1 istället..

/johan
Zeela
Inlägg: 176
Blev medlem: 28 augusti 2008, 11:23:49
Ort: Åtvidaberg
Kontakt:

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Zeela »

Basic har arrayer som startar på 1.
Pascal har valbara index för arrayer... Typ Arr[1..9] eller Urr[67..123]
ADA kan tänkas stödja nåt liknande
PL/1 tror jag också har 1 baserat
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Magnus_K »

Japp, ni hade helt rätt i vad som var fel. När jag ändrade till 99 i looparna så fungerar det "glitch-fritt". Tackar för snabb support!

Det lät väldigt intressant det du skrev sodjan om simulator så jag grottade ner mig lite i MikroC:s IDE och visst, det fanns något dom kallade för debugger som verkar vara precis det du skriver! Efter lite meckande så fick jag i gång det och även fick se variabeln step i rörelse.
Mycket sant så gick den upp till 100 vid min orignalkod men efter ovan modifiering så blev det 99 innan den vände. VÄLDIGT användbart för framtiden så tack för det!
(I och för sig så kanske det i det här fallet inte spelat någon roll då jag ändå trodde att 100 var ok)

Den där sidan du länkade till Nerre var ju som skriven till mig. Har bokmärkat den tills allt sitter.

Som lite följdfråga så är jag blev jag nyfiken på det du rekommenderade att ändra till Nerre: <= och >=
Personligen förstår jag inte skillnaden mer än möjligtvis en lite mer lättläst kod men visst är väl tex x <= 5 och x < 6 men det är just dom eventuella bieffekterna du nämner som kanske kan uppstå. Finns det några såna i detta fall?

EDIT: Tänkte nog lite väl snabbt här. Återkommer....
ie
EF Sponsor
Inlägg: 1371
Blev medlem: 23 oktober 2006, 13:12:57
Ort: Tyresö

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av ie »

Sen ser det lite kontigt ut att du först sätter PWM baserat på value, för att i nästa rad tilldela value ett värde ur matrisen. Det innebär att value är odefinierad första gången du går in i första loopen.
Nerre
Inlägg: 27168
Blev medlem: 19 maj 2008, 07:51:04
Ort: Upplands väsby

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Nerre »

Magnus_K skrev: Som lite följdfråga så är jag blev jag nyfiken på det du rekommenderade att ändra till Nerre: <= och >=
Personligen förstår jag inte skillnaden mer än möjligtvis en lite mer lättläst kod men visst är väl tex x <= 5 och x < 6 men det är just dom eventuella bieffekterna du nämner som kanske kan uppstå. Finns det några såna i detta fall?
Det var bara i det här fallet som det blir enklare.

Om du bara ändrade 100 till 99 i den andra loopen så kommer den att gå från 99 till 1 (den går inte till 0 om du har villkoret step > 0).

Ska du göra rätt med < och > så ska den ena loopen alltså ha värdena 0 (startvärde) och villkoret step < 100, medans den andra loopen ska ha värdena 99 (startvärde) och villkoret step > -1.

Det blir tydligare om du gör den första loopen med startvärde 0 och villkoret step <= 99 och den andra med startvärdet 99 och villkoret step >= 0. Då kan du nämligen byta ut 0 och 99 mot konstanter som är samma i bägge looparna.

Ex.

Kod: Markera allt

Min = 0;
Max = 99;
for(step = Min; step <= Max; step++)

for(step = Max; step >= Min; step--)
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Magnus_K »

@ie: Du har så rätt. Det där jag har rättat till. Tack.

@Nerre: Har suttit en timma med detta nu men jag får inte det att lira riktigt. Jag har skrivit som dig men jag använde inte "Min" och "Max", utan siffror.
Det som händer är att vid 99 så fortsätter den bara upp, förbi 99.

Det jag TROR händer är att det har betydelse om ++ och -- sitter innan eller efter variablen. I detta fallet efter och om jag förstår det rätt så loopar den första loopen runt tills den kommer till 99 och SEN ökar med 1 och passerar "stoppet".
Vad som sen händer har jag inte en aning om och jag vet som sagt inte heller om ovan är möjligt men det är så jag tolkar debuggen.

Jag testade att flytta ++ till framför och då vänder den så fint vid 99 men sen hur jag än placerar -- så stannar den inte vid 0.

Ja, som ni kanske förstår så är jag inte speciellt duktig på det här men det är kul!

Om jag använder 100 i andra loopen så fungerar det.
Nedan är hur det ser ut när den inte vänder.

Kod: Markera allt

while(1)
         {
                for(step = 0; step <= 99; step++)
                {
                value = constants[step];
                PWM1_Set_Duty(value);
                Delay_ms(30);
                }
                for(step = 99; step >= 0; step--)
                {
                value = constants[step];
                PWM1_Set_Duty(value);
                Delay_ms(30);
                }
         }
Zkronk
Inlägg: 1439
Blev medlem: 23 augusti 2005, 16:44:36
Ort: Uppsala

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Zkronk »

På den andra for-loopen, blir det inte konstigt när villkoret för att den ska fortsätta köras är "större eller lika med noll"? Den kommer ju köras även när step är noll och subtrahera ett så att step blir lika med -1, och när du försöker komma åt constants[-1] så blir det nog problem?
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Vad är det som skapar en "död punkt" i denna loop?

Inlägg av Magnus_K »

Jo, det har du helt rätt i. Tror inte det går att göra så här om jag inte skriver något i stil med:

Kod: Markera allt


                for(step = 0; step <= 99; ++step)
                for(step = 99; step >= 1; step--)
EDIT: Jo det verkar fungera bra!
Skriv svar