Visa värde på 7 segment display

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
morre95
Inlägg: 23
Blev medlem: 28 juli 2011, 12:35:04

Visa värde på 7 segment display

Inlägg av morre95 »

Jag försöker lära mig att programmera PIC. Och i den boken som jag läser så är avslutas varje kapitel med övningar. Och i den övningen som jag inte lyckas lösa så ska man mäta på en potentiometer och skriva ut resultatet på två 7 segment displayer. Den ända hjälpen man får är ett kopplingsschema.

Jag har dubbelkollat så jag har kopplat rätt. Så jag misstänker att det är jag som missat något i koden:

Kod: Markera allt

#include <pic18.h>
#include <delay.c>

unsigned char sjuseg(unsigned char siffra);
unsigned char ad8bit(unsigned char kanal);

double Ain;
char Aint;

void main () {
	TRISC = 0x00;
	ADCON0 = 0xC1;
	TRISD = 0x00;
	CMCON = 0x07;

	LAT7 = 1;	
	LAT6 = 1;
	
	while(1) {
		Ain = 0.01953*ad8bit(0)+0.05;
		Aint = (char)(Ain * 10);
		PORTC = sjuseg(Aint/10+0x30);

		LAT6=0;
		DelayMs(1);
		LAT6=1;

		PORTC = sjuseg(Aint%10+0x30);
		LAT7=0;
		DelayMs(1);
		LAT7=1;
	}
}

unsigned char ad8bit(unsigned char kanal) {
	kanal <<= 3;
	ADCON0 = 0xC1;
	DelayMs(10);
	GODONE = 1;
	while (GODONE);
	return ADRESH;
}

unsigned char sjuseg(unsigned char siffra) {
	unsigned char seg;
	switch (siffra)  {
		case 0:
			seg = 0x3f;
			break;
		case 1:
			seg = 0x06;
			break;
		case 2:
			seg = 0x5b;
			break;
		case 3:
			seg = 0x4f;
			break;
		case 4:
			seg = 0x66;
			break;
		case 5:
			seg = 0x6d;
			break;
		case 6:
			seg = 0x7d;
			break;
		case 7:
			seg = 0x07;
			break;
		case 8:
			seg = 0x7f;
			break;
		case 9:
			seg = 0x6f;
			break;
	}

	return seg;
}
Jag får inga felmeddelanden när jag kompilerar koden och jag lyckas ladda in den i PIC:en med min PICKIT 3. Men displayerna visar inget. Är det någon som kan hjälpa mig med vad jag gjort för fel? Behöver ni kopplingsschemat så säg till så ska jag försöka fixa till något.
Användarvisningsbild
Klas-Kenny
Inlägg: 11840
Blev medlem: 17 maj 2010, 19:06:14
Ort: Växjö/Alvesta

Re: Visa värde på 7 segment display

Inlägg av Klas-Kenny »

Jag vill i alla fall gärna se kopplingsschemat.

Sen kan du ju testa ett väldigt simpelt program, att bara tända alla segment i displayerna genom att sätta PORTC och PORTD till 255, för att se om det fungerar alls.

Edit: Förresten, det är inte så att det är displayer med gemensam Anod, och du kopplat Anoden till 0v? Eller tvärt om.
Användarvisningsbild
anders_bzn
Inlägg: 5778
Blev medlem: 17 december 2008, 19:22:18
Ort: Kävlinge
Kontakt:

Re: Visa värde på 7 segment display

Inlägg av anders_bzn »

1. Testa med att i din loop anropa sjuseg() med tex 1. Vad händer.
2. Fundera på vad som händer i funktionen om in argumentet är skilt från 0..9
3 Kolla hur du anropar funktionen just nu, vilka värden skickar du in.

EDIT: Jag ser fel, men försöker göra en Sodjan!
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Visa värde på 7 segment display

Inlägg av Icecap »

Jag ser felen också men har lite kommentarer till själva programmet.

morre95: du använder flyttal, varför?
Tydligen vill du visa de höga 8 bit från AD-omvandlaren på 2 siffror och efter vad jag kan räkna ut ska de visa 00-50. Men det kan åstadkommas mycket snabbare och enklare med heltal! Flyttal tar lång tid att räkna med om man undviker dom mest möjligt i µC, helt enkelt för att det är så resurskrävande och nästan alltid onödiga.

För att konvertera 0-255 till 0-50 ska du egentligen dela med 5,1 bara - men det går ju inte med heltal! Men gör som följer:
Aint = (ad8bit(0) * 10)/51; // Då så, värdet är omräknat från 0-255 till 0-50
Ain = Ain % 10; // Ain är nu 1-tals värdet
Aint /= 10; // Aint är numera 10-värdet

Sedan borde din scanning av displayen vara baserat på en timer-interrupt och du skulle bara skriva mönstret i var sin minneslokation, dessa lokationer skulle interrupt-rutinen sedan läsa av och visa på rätt display men till detta kan det väl duga, det är dock ett mycket fel sätt att lösa det på.

Din sjuseg() är inte imponerande heller, mest överskådligt (och snabbare i.o.m. PIC18) hade varit att bygga en tabell:
unsigned char sjuseg(unsigned char siffra)
{
const unsigned char Pattern[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6f};
return(Pattern[siffra]);
}
morre95
Inlägg: 23
Blev medlem: 28 juli 2011, 12:35:04

Re: Visa värde på 7 segment display

Inlägg av morre95 »

Tack för snabba svar, det är uppskattat!

@Icecap: Jag använder flyttal för att det är vad författaren i boken gör. Jag är på kap. 11 av 28 så det är ju lite tråkigt om man får lära sig fel från början.

Jag lyckades lösa det. Så här ser min while loop ut nu:

Kod: Markera allt

while(1) {
	Aint = (ad8bit(0) * 10)/51;
	LATD6=0;
	PORTC = sjuseg(Aint%10);
	DelayMs(1);
	LATD6=1;
	LATD7=0;
	PORTC = sjuseg(Aint/10);
	DelayMs(1);
	LATD7=1;
}
Kan man skriva ut värden eller på något vis ta reda på vad en variabel innehåller för värde? Det skulle underlätta massa när man felsöker i så fall.
Användarvisningsbild
Icecap
Inlägg: 26647
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Visa värde på 7 segment display

Inlägg av Icecap »

Såklart man kan! Med en PICKit3 och MPLAB ska du kunde debugga direkt och då placera de önskade värden i ett watch-fönster. Då kan du t.ex. köra programmet till cursorn, singlesteppa, se alla värden i watch-fönstret osv.

Men sättet jag gör det på när jag startar upp ett nytt projekt är att koppla upp en seriell port, med en nivå-omvandlare (t.ex. MAX232 eller klon) kan jag sedan koppla till en seriell port på en PC och använda ett terminalprogram och då går det snabbt.

Men att debugga med PICKit3 fungerar minst lika bra!
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Visa värde på 7 segment display

Inlägg av sodjan »

> Kan man skriva ut värden eller på något vis ta reda på vad en variabel innehåller för värde?

En enkel felsökning är att köra det i MPSIM.
Du får kanske hårdkoda ett värde från ADC'n istället för att läsa från den,
men du kan enkelt köra 7-seg rutinerna och se om du får ut det som du tror.

Sen så är det ju helt onödigt att köra float/double här, som Icecap också skrev.
Men å andra sidan, för denna demo så fungerar det ju och det kanske är viktigast.
Skriv svar