Programmeringsbekymmer, nu i C

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
PaNiC
Inlägg: 2610
Blev medlem: 15 augusti 2003, 22:16:15
Ort: Skånelandet

Programmeringsbekymmer, nu i C

Inlägg av PaNiC »

I förra veckan skrev jag mina första rader C. Jag har lyckats med lite småsaker, exempelvis att blinka lite leds, räkna upp och ner, räkna med nixierör osv. Nu har det kommit till interrupts. Problemet här är att Timer1 overflow-interruptet aldrig tycks trigga. Eller i vart fall så fastnar något innan värdena hinner komma ut på PORTA-C.

Kod: Markera allt

#include "avr/io.h"
#include "inttypes.h"
#include "avr/interrupt.h"
#include "avr/signal.h"
#include "string.h"
#include "stdio.h"

#define clock = 2000000

	unsigned char secs = 0;
	unsigned char tsecs = 0;
	unsigned char mins = 0;
	unsigned char tmins = 0;
	unsigned char hrs = 0;
	unsigned char thrs = 0;

void delay1()
	{
	unsigned char delayvar1;
	delayvar1 = 255;
	while(delayvar1 != 0)
		{
		delayvar1--;
		}
	}

void setup()
	{
	DDRA = 0xFF;
	DDRB = 0xFF;
	DDRC = 0xFF;
	DDRD = 0b00011000;
	//OCR1A = 31250;
	TCCR1A = (3<<CS10); //(CK/64)
	//TCCR1B = (1<<CTC1);
	PORTA = 0x00;
	PORTB = 0x00;
	PORTC = 0x00;
	TIMSK = (1<<TOIE1);
	sei();
	}


SIGNAL(SIG_OVERFLOW1)
	{
	
	secs++;
	if ((secs == 10))
		{
		secs = 0;
		tsecs++;
		}
	if ((tsecs == 6))
		{
		tsecs = 0;
		mins++;
		}
	if ((mins == 10))
		{
		mins = 0;
		tmins++;
		}
	if ((tmins == 6))
		{
		tmins = 0;
		hrs++;
		}
	if ((hrs == 10))
		{
		hrs = 0;
		thrs++;
		}
	if ((thrs == 2)&&(hrs == 4))
		{
		secs = 0;
		tsecs = 0;
		mins = 0;
		tmins = 0;
		hrs = 0;
		thrs = 0;
		}
	PORTA = ((secs)|(tsecs<<4));
	PORTB = ((mins)|(tmins<<4));
	PORTC = ((hrs)|(thrs<<4));
	delay1();
	}



int main(void)
	{
	setup();
	sei();
	for(;;)
		{
	
		}
	}
	
Använder WinAVR inpluggat i AVRStudio.
Användarvisningsbild
teodorl
Inlägg: 97
Blev medlem: 29 december 2004, 00:45:26
Ort: Sthlm

Inlägg av teodorl »

OT:

Hur lär man sig detta..? Jag vill också! :wink:
sodjan
EF Sponsor
Inlägg: 43231
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Som man lär sig allt annat, läser dokumentation, kollar (fungerande!) exempel, frågar på online forum, o.v.s o.s.v.

Personligen kan jag inte AVR-C, så jag kan nog inte vara till stor hjälp här.

Ett par mindre sakar bara (med bakgrund från PIC-assembler, men i alla fall... :-) )

- Behöver man inte "återställa" någon timer0-overflow-interrupt-flagga innan man avslutar interrupt rutinen ("SIG_OVERFLOW1") ? Eller läggs det till av compilatorn automatiskt ?

- Vad har du gjort för att debugga ?
- *Var* fastnar koden ?
- Anropas setup() alls ?
Användarvisningsbild
Icecap
Inlägg: 26610
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Jag jobbar inte med AVR men generellt:
* Initialisering utförs vid att stoppa interrupts, rensa gamla interrupt-flaggor, tillåta interrupts och sist starta hårdvaran. Om man starter hårdvaran först kan den generera en interrupt innan den accepteras, det kan ge "roliga" effekter eller ingen effekt alls.
* En interruptrutin ska mycket ofta innehålla en funktion som berättar för hårdvaran som har genererat interrupten att den kan ta't lugnt fram till nästa gång. I PIC clearar man interruptflaggan t.ex.

Förklara för mig vad TUSAN en delay-rutin gör i en ISR? (ISR = Interrupt Service Rutin). Då en ISR ska köras igenom snabbast möjligt "får" sånt inte förekomma! (generellt synspunkt om ISR, specialfall finns).
sodjan
EF Sponsor
Inlägg: 43231
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

> Problemet här är att Timer1 overflow-interruptet aldrig tycks trigga.

"Tycks" ? Hur då "tycks" ?

Du måste vara *säker* på om den anropas eller inte.

Sätt in några hårdkodade värden istället för :

PORTA = ((secs)|(tsecs<<4));
PORTB = ((mins)|(tmins<<4));
PORTC = ((hrs)|(thrs<<4));

som t.ex :

PORTA = 0xFF;
PORTB = 0xFF;
PORTC = 0xFF;

då vet du om du kommer dit alls.

Eventuellt plocka bort all sek/min/tim beräkning...

Debuggning innebär att plocka bort (kommentera bort) kod
tills det fungerar, sedan lägga tillbaka mindre bitar tills
det lägger av igen. Å så fram och tillbaka tills du förstår vad
som är problemet... :-)
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

TCCR1A borde det inte vara TCCR1B ?
sodjan: AVRen rensar själv interupt flagan..
Användarvisningsbild
björn
EF Sponsor
Inlägg: 2570
Blev medlem: 29 mars 2004, 23:09:55

Inlägg av björn »

Behöver man verkligen inte en clear interrupt? Jag har i den lilla interrupt kod jag gjort iallafall cli() när man kommer in i interrupten, men det är möjligt att det inte behövs.
Användarvisningsbild
PaNiC
Inlägg: 2610
Blev medlem: 15 augusti 2003, 22:16:15
Ort: Skånelandet

Inlägg av PaNiC »

We have a winner!
exile is the one.

Och gah, det borde jag verkligen ha sett. Jag kollade ju alla kontrollregister hur många gånger som helst. Stirrade väl mig blind som vanligt.

sodjan: Tycks var väl ett dåligt ordval. Jag var säker :).
I övrigt, Icecap och sodjan. AVR sköter det där själv, vilket gör mig glad att jag valde dem en gång i tiden :).
Delayrutinen blev kvar efter att jag i debuggningen ändrade till att kalla på interruptrutinen manuellt. Den ska mycket riktigt inte vara där.

teodorl: Jag rekommenderar iaf att börja med assembler så att du vet vad som händer på låg nivå. När du fått hyfsad kläm på det så kan du börja med något annat språk, fördelaktligen C.
Visst kan man börja med C också, men jag är iallafall sådan att om jag inte vet något om bakomliggande orsaker till att saker händer så begriper jag ingenting alls. Kan vara det som har gjort mig så dålig i matte.

Tack alla!

Edit: http://panic.klippanlan.net/annat/CIMG0220.AVI
Senast redigerad av PaNiC 1 november 2005, 22:57:35, redigerad totalt 1 gång.
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

Nej den rensar clerar globala interupt flagan själv och sätter den själv när den hoppar ur interuptet, det är därför man har en egen opcod för return när man hoppar tillbaka fråninterupt (reti som sätter flagan) ser du :wink:

Panic: Visst är stödet för GCC AVRstudet under bart :)
sodjan
EF Sponsor
Inlägg: 43231
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Inlägg av sodjan »

Fint att det fungerar :-)

När det gäller int flaggorna, och eftersom jag nämnde det först...

Det var inte *globala* interrupt flaggan jag tänkte på, utan den/de specifica flaggorna för de olika int källorna, t.ex "timer1 overflow". Jag antog att man får cleara den innan man gör "return from interrupt", annars anropas samma interrupt direkt igen.

Hur som helst, kompilatorn (eller AVR hårdvaran) kanske fixar det självt (om det behövs alls !)...
Användarvisningsbild
exile
EF Sponsor
Inlägg: 496
Blev medlem: 21 oktober 2005, 23:32:07

Inlägg av exile »

När det gäller timer1 overflow flagan så "cleras" den mär man hoppar in i timer1 overflow interupten av AVRs hårdvara... och det är liknade för alla interupt.
Ex uart reciv interuptet "cleara" när man läser ut datan från uarten...
Användarvisningsbild
PaNiC
Inlägg: 2610
Blev medlem: 15 augusti 2003, 22:16:15
Ort: Skånelandet

Inlägg av PaNiC »

exile: Visst är det :). Det var först när jag fick höra talas om att det fanns stöd för C i AVRStudio som jag bestämde mig för att börja med C. Orkar verkligen inte hoppa mellan en massa olika jobbiga program.

sodjan: Vi pratar nog om lite skilda saker. En sak som jag vill minnas skiljer PIC och AVR är att PIC bara har en interruptflagga och sedan måste man själv ta reda på var interruptet kommer ifrån. AVR har många flaggor och kan hoppa direkt till rätt kodsnutt. Flaggorna clearas av hårdvaran, exakt när har jag inte riktigt koll på, men man behöver iallafall inte bry sig.
Användarvisningsbild
Icecap
Inlägg: 26610
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Inlägg av Icecap »

Det lät ju smidigt faktisk med att den rensar flaggan själv och det är bra att den kör numera. Nu fattas det bara en DCF77-mottagare på med tillhörande dekodning, sen har du en stabil klocka! :wink:
Användarvisningsbild
PaNiC
Inlägg: 2610
Blev medlem: 15 augusti 2003, 22:16:15
Ort: Skånelandet

Inlägg av PaNiC »

Mja.. DCF77 har jag inte på denna klockan, som för övrigt är min nixieklocka som jag visade här för hur länge sedan som helst.
Den nyttjar en DS1302 istället.
Skriv svar