Sida 1 av 5

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

Postat: 21 november 2014, 13:59:29
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);
                }
         }
}

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

Postat: 21 november 2014, 14:04:51
av Klas-Kenny
constants[100] som du försöker läsa i den andra loopen finns inte.

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

Postat: 21 november 2014, 14:18:35
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

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

Postat: 21 november 2014, 14:31:34
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... :-)

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

Postat: 21 november 2014, 14:38:30
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.

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

Postat: 21 november 2014, 15:19:55
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... :-)

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

Postat: 21 november 2014, 15:28:09
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. :)

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

Postat: 21 november 2014, 15:35:41
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

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

Postat: 21 november 2014, 15:37:29
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

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

Postat: 21 november 2014, 16:17:06
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....

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

Postat: 21 november 2014, 16:38:31
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.

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

Postat: 21 november 2014, 16:48:25
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--)

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

Postat: 21 november 2014, 21:27:06
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);
                }
         }

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

Postat: 21 november 2014, 21:37:33
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?

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

Postat: 21 november 2014, 21:43:26
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!