Behöver nybörjarhjälp att programmera i C
Re: Behöver nybörjarhjälp att programmera i C
Eftersom du använder MikroC Pro så finns det en del exempel på LIBstock
tex
http://www.libstock.com/projects/view/5 ... t-displays
Kanske du hittar något användbart där.
Det var bara ett tips
//
tex
http://www.libstock.com/projects/view/5 ... t-displays
Kanske du hittar något användbart där.
Det var bara ett tips
//
- Magnus_K
- EF Sponsor
- Inlägg: 5854
- Blev medlem: 4 januari 2010, 17:53:25
- Ort: Skogen mellan Uppsala-Gävle
Re: Behöver nybörjarhjälp att programmera i C
Tack för tipset DJNZ. Ska kika på detta lite under kvällen.
Ja, nu har jag skrivit lite pseudokod. Eller i alla fall tror mig gjort.
Den första interrupten startar SPI_klockan och när adc_data har fyllts så stänger den av klockan. Har inte bestämt ännu med vilken frekvens detta ska göras men förhållandevis ofta.
Den andra interrupten gör just skrivningen till displayerna enligt (förhoppningsvis) era tips.
Sitter just nu och försöker kladda ner flödet på just att "stycka av" adc_data till 1000, 100, 10, och en-tal.
Ser det allt för bedrövligt ut, tankemässigt alltså?
(Nu kanske ni förstår vilken låg nivå jag ligger på angående programmeringen...)
Ja, nu har jag skrivit lite pseudokod. Eller i alla fall tror mig gjort.
Den första interrupten startar SPI_klockan och när adc_data har fyllts så stänger den av klockan. Har inte bestämt ännu med vilken frekvens detta ska göras men förhållandevis ofta.
Den andra interrupten gör just skrivningen till displayerna enligt (förhoppningsvis) era tips.
Sitter just nu och försöker kladda ner flödet på just att "stycka av" adc_data till 1000, 100, 10, och en-tal.
Ser det allt för bedrövligt ut, tankemässigt alltså?
(Nu kanske ni förstår vilken låg nivå jag ligger på angående programmeringen...)
Kod: Markera allt
unsigned short adc_data;
bool adc_flag;
void interrupt1(TIMER0FLAG == 1) { // Vet inte hur ofta den ska läsa datan från ADC:n
// men denna timer ställs in efter det kravet
adc_data &= 0xffff
Starta SPI_klocka
if(SPI_BUFFER är full !& adc_flag) { //Det ska även maskas av med mera i dessa metoder
Flytta dom 8 bitarna till adc_data MSB
}
if{SPI_BUFFER är full && adc_flag) {
Flytta dom 8 bitarna till adc_data LSB
Stäng av SPI_klocka
}
void interrupt2(TIMER1FLAG == 1) { // Denna timer snurrar med 400 Hz så varje
// siffra (4 st) uppdateras med 100 Hz
Släck segment
Läs porten och maska av (AND:a med 0)
Skicka värdet till LAT
Räkna upp vilken display som ska laddas nästa gång
Om >3 så nolla
Tänd nya segment
}
void main() {
while(1) {}
}
Re: Behöver nybörjarhjälp att programmera i C
Denna pseudokod (?) är för mig svårläst pga märklig formatering (kanske för att jag läser på en telefon) men rekommenderar att du, för ökad läsbarhet, väntar med att blanda in LCD mm tills du fått rätt på grundfunktionaliteten.
Jag tycker generellt att du "överplanerar" och ägnar för mycket tid att tänka igenom saker i förväg - du ställer frågor om saker för tidigt och alla olika svar du får, hur korrekta de än är, förvirrar ibland mer än vad de förklarar eftersom de ofta väcker nya frågor hos dig - frågor som du själv kunnat besvara senare, vis av erfarenheten av att först ha försökt.
Sätt igång och implementera på riktigt nu och återkom med reella problem när du verkligen kört fast istället.
Jag tycker generellt att du "överplanerar" och ägnar för mycket tid att tänka igenom saker i förväg - du ställer frågor om saker för tidigt och alla olika svar du får, hur korrekta de än är, förvirrar ibland mer än vad de förklarar eftersom de ofta väcker nya frågor hos dig - frågor som du själv kunnat besvara senare, vis av erfarenheten av att först ha försökt.
Sätt igång och implementera på riktigt nu och återkom med reella problem när du verkligen kört fast istället.
- Magnus_K
- EF Sponsor
- Inlägg: 5854
- Blev medlem: 4 januari 2010, 17:53:25
- Ort: Skogen mellan Uppsala-Gävle
Re: Behöver nybörjarhjälp att programmera i C
Jo det har du nog rätt i hanzibal. Det blir tyvärr lite för djupa tankar ibland.
Ska se om jag får till något vettigt.
Angående formateringen vet jag inte. I mina ögon ser det överskådligt ut med antagligen är det för att jag är författaren. Ni som kan det här, ser säkert bara runskrift.
Ska se om jag får till något vettigt.
Angående formateringen vet jag inte. I mina ögon ser det överskådligt ut med antagligen är det för att jag är författaren. Ni som kan det här, ser säkert bara runskrift.
- Magnus_K
- EF Sponsor
- Inlägg: 5854
- Blev medlem: 4 januari 2010, 17:53:25
- Ort: Skogen mellan Uppsala-Gävle
Re: Behöver nybörjarhjälp att programmera i C
Vart är det lämpligt att lägga själva uträkningen för vilken siffra som ska visa vad?
Just nu ser det ut som följer:
- Interrupt 1 skickar klockpuls till ADC:n och samlar svaret i en variabel.
- Interrupt 2 gör själva sifferbytet. Vid varje interrupt så uppdaterar den en av siffrorna dvs när 4 st interrupter skett så har alla 4 siffror uppdaterats.
Frågan gäller alltså vart det är lämpligt att lägga uträkningen där jag delar ner ADC-datan i delar och tilldelar ett nummer till respektive siffra.
Är det feltänk att man låter while-loopen göra detta om och om igen och när interrupt 2 sker så är det redan klart vilken siffra den ska visa på respektive position.
Spontant så känns det som att lägga denna uträkning i interrupten så kommer ta en massa tid, vilket man inte vill att den ska göra.
Förstår någon vad jag menar? Känns lite rörigt.
Just nu ser det ut som följer:
- Interrupt 1 skickar klockpuls till ADC:n och samlar svaret i en variabel.
- Interrupt 2 gör själva sifferbytet. Vid varje interrupt så uppdaterar den en av siffrorna dvs när 4 st interrupter skett så har alla 4 siffror uppdaterats.
Frågan gäller alltså vart det är lämpligt att lägga uträkningen där jag delar ner ADC-datan i delar och tilldelar ett nummer till respektive siffra.
Är det feltänk att man låter while-loopen göra detta om och om igen och när interrupt 2 sker så är det redan klart vilken siffra den ska visa på respektive position.
Spontant så känns det som att lägga denna uträkning i interrupten så kommer ta en massa tid, vilket man inte vill att den ska göra.
Förstår någon vad jag menar? Känns lite rörigt.
Re: Behöver nybörjarhjälp att programmera i C
Interrupten som växlar vilken siffra som visas ska ENBART sköta den bit!
Den ska ha 4 bytes reserverat (en per siffra, det var väl 4?) och i de bytes ska de färdiga bitmönster vara, ingen dekodning eller annat som ska utföras av ISR'n!
När du sedan har ett värde att skriva ut gör du det via en rutin i mainloop. Den rutin lägger rätt siffermönster i rätt byte av de 4 så att scanningen bara ska tugga på och ingen stör den.
Om du har en interrupt som anger att A/D-omvandlaren är klar är mitt sätt att dels läsa värdet till en variabel, starta om A/D-omvandlaren (om det behövs) och sedan sätta en flagga som betyder att det finns ett värde att omvandla.
I mainloop kollas flaggan, är den aktiv hoppas rutinen som behandlar det värde inte över.
Rutinen omvandlar värdet som beskrivit ovan.
Sedan nollas flaggan.
Klart.
Om du vill starta A/D-omvandlaren här går det såklart bra.
Den ska ha 4 bytes reserverat (en per siffra, det var väl 4?) och i de bytes ska de färdiga bitmönster vara, ingen dekodning eller annat som ska utföras av ISR'n!
När du sedan har ett värde att skriva ut gör du det via en rutin i mainloop. Den rutin lägger rätt siffermönster i rätt byte av de 4 så att scanningen bara ska tugga på och ingen stör den.
Om du har en interrupt som anger att A/D-omvandlaren är klar är mitt sätt att dels läsa värdet till en variabel, starta om A/D-omvandlaren (om det behövs) och sedan sätta en flagga som betyder att det finns ett värde att omvandla.
I mainloop kollas flaggan, är den aktiv hoppas rutinen som behandlar det värde inte över.
Rutinen omvandlar värdet som beskrivit ovan.
Sedan nollas flaggan.
Klart.
Om du vill starta A/D-omvandlaren här går det såklart bra.
- Magnus_K
- EF Sponsor
- Inlägg: 5854
- Blev medlem: 4 januari 2010, 17:53:25
- Ort: Skogen mellan Uppsala-Gävle
Re: Behöver nybörjarhjälp att programmera i C
Japp, det var 4 st LED-siffror.
Klart som korvspad Icecap!
Tack!
Förstår inte hur ni håller reda på allt. Är uppe i nästan 150 rader kod och är alldeles snurrig av allt.
Klart som korvspad Icecap!
Tack!
Förstår inte hur ni håller reda på allt. Är uppe i nästan 150 rader kod och är alldeles snurrig av allt.
Re: Behöver nybörjarhjälp att programmera i C
Och du tror att vi håller reda på allt? Jag sitter just och grejer ett projekt där jag använder samma buffer till att skicka data i till en funktion som skriver ut i en buffer och skickar med radio. Tyvärr är det samma buffer så det skiter sig rejält... Men jag hittade det och löser det...
EDIT: Har löst det och nu fungerar den del.
Er uppe på 1400+ rader kod - och det är "bara" en trådlös varningsskylt som i grunden bara kan skicka en "slå på nu i såhär lång tid" från sändaren till mottagaren.
Sedan tillkommer alla rutiner i egna filer, seriell kommunikation (3 st UART) med interruptstyrd buffring på alla samtidig (3* 220 rader), kryptering av kommunikationen, systeminitieringen (220 rader + 630 rader) och lite andra småsaker, så som en kommandotolk av typen klartext. ("set intensity 100", "get unit name", set unit name skitsystem norr" osv.)
EDIT: Har löst det och nu fungerar den del.
Er uppe på 1400+ rader kod - och det är "bara" en trådlös varningsskylt som i grunden bara kan skicka en "slå på nu i såhär lång tid" från sändaren till mottagaren.
Sedan tillkommer alla rutiner i egna filer, seriell kommunikation (3 st UART) med interruptstyrd buffring på alla samtidig (3* 220 rader), kryptering av kommunikationen, systeminitieringen (220 rader + 630 rader) och lite andra småsaker, så som en kommandotolk av typen klartext. ("set intensity 100", "get unit name", set unit name skitsystem norr" osv.)
Senast redigerad av Icecap 9 december 2014, 19:03:13, redigerad totalt 1 gång.
Re: Behöver nybörjarhjälp att programmera i C
> Är uppe i nästan 150 rader kod och är alldeles snurrig av allt.
Det handlar bara om att hantera hela applikationen i lämpliga
bitar i taget. Om du börjar få 100 eller fler rader i main()
eller i en enstaka funktion som ett enda block, så kan det
vara dags att bryta upp det i fler funktioner. Varje funktion
ska inte vara större än att den enkelt kan överblickas och
både förstås och testas. Sedan (när man håller på med
koden "ovanför") så behöver man inte tänka mer på det.
Och vad är "för mycket kod på ett ställe"? Tja, det kan
väl vara då man får den känsla som du uttrycker...
Aplikationerna som vi underhåller "på jobbet" har 10-tusentals
rader totalt med alla under/sub rutiner och det är kod skriven
under en 30+ års period i 6-7 olika språk. Man kan så klart
inte hålla allt i huvudet utan får ha tydliga gränssnitt mot
de olika rutinerna och lita på att det fungerar...
Men "bara" 150 rader för en komplett applikation är
inte speciellt mycket...
Det handlar bara om att hantera hela applikationen i lämpliga
bitar i taget. Om du börjar få 100 eller fler rader i main()
eller i en enstaka funktion som ett enda block, så kan det
vara dags att bryta upp det i fler funktioner. Varje funktion
ska inte vara större än att den enkelt kan överblickas och
både förstås och testas. Sedan (när man håller på med
koden "ovanför") så behöver man inte tänka mer på det.
Och vad är "för mycket kod på ett ställe"? Tja, det kan
väl vara då man får den känsla som du uttrycker...

Aplikationerna som vi underhåller "på jobbet" har 10-tusentals
rader totalt med alla under/sub rutiner och det är kod skriven
under en 30+ års period i 6-7 olika språk. Man kan så klart
inte hålla allt i huvudet utan får ha tydliga gränssnitt mot
de olika rutinerna och lita på att det fungerar...

Men "bara" 150 rader för en komplett applikation är
inte speciellt mycket...
- Magnus_K
- EF Sponsor
- Inlägg: 5854
- Blev medlem: 4 januari 2010, 17:53:25
- Ort: Skogen mellan Uppsala-Gävle
Re: Behöver nybörjarhjälp att programmera i C
Försöker verkligen hålla mig till att göra en funktion, testa, lägga undan. Ny funktion, testa och lägga undan. Det är nog en fråga om rutin och kunskap också. Jobbar på det!
Nu till ett par mer programmeringsspecifika frågor:
För att omvandla 12-bitars ADC-datan till en spänningsnivå så tänkte jag göra som följer. Men vad händer när det blir decimaler? Finns det något annat sätt?
Jag försöker alltså få värdet att istället för att bara ge "5" så ska det ge "5000" och sen placerar jag decimalen manuellt på displayen.
Här nedan vill jag sedan dela ner total_voltage för att skickas vidare till "scannern".
Det som alltså är klart sedan tidigare är att tex en 2:a har en färdig byte som heter NUMBER[2], en 5:a heter NUMBER[5] osv.
Vad använder jag för funktion för att utföra ta värdet från ett voltage-element och placera detta inom [] på NUMBER?
Skit vad svårt det här var att förklara... Nytt försök:
Hur skriver jag för att få elementsiffran i NUMBER att matcha värdet i voltage-elementet
Fungerar något i stil med:
Nu till ett par mer programmeringsspecifika frågor:
För att omvandla 12-bitars ADC-datan till en spänningsnivå så tänkte jag göra som följer. Men vad händer när det blir decimaler? Finns det något annat sätt?
Jag försöker alltså få värdet att istället för att bara ge "5" så ska det ge "5000" och sen placerar jag decimalen manuellt på displayen.
Kod: Markera allt
total_voltage = adc_data * 4,8823;
Kod: Markera allt
unsigned short voltage[3];
voltage[3] = total_voltage % 1000;
total_voltage /= 1000;
voltage[2] = total_voltage % 100;
total_voltage /= 100;
voltage[1] = total_voltage % 10;
total_voltage /= 10;
voltage[0] = total_voltage % 1;
Vad använder jag för funktion för att utföra ta värdet från ett voltage-element och placera detta inom [] på NUMBER?
Skit vad svårt det här var att förklara... Nytt försök:
Hur skriver jag för att få elementsiffran i NUMBER att matcha värdet i voltage-elementet
Fungerar något i stil med:
Kod: Markera allt
NUMBER[voltage[1]];
Re: Behöver nybörjarhjälp att programmera i C
Ett sätt är att använda flyttal. Det kostar exekveringshastighet och programminne - men det går.
Ett annat är att räkna lite:
unsigned long Work;
Work = ADC_Value;
Work *= 48823;
Nu är Work rätt skalad fast 10000000 är 1,0000V.
Man kan ju i samma veva skala det hela lite ner, kanske till en unsigned short:
Work /= 10000;
Då är 1000 = 1,000V
Internt går det alldeles utmärkt att räkna så men vid visningstillfällen ska du peta in komma på rätt position.
Varför har du bara 3 platser för scannaren? Var det inte 4 siffror?
Men för att göra om det till synbara tal måste du i grunden ha två rutiner:
En som plockar ut rätt siffra - och det har vi ju varit igenom redan.
Och en som slår upp i en tabell för att omvandla siffra till binärt mönster att visa.
För att göra det lätt för mig i sin tid gjorde jag mycket jobb som gjorde att det blev litet jobb om jag skulle ändra något.
på detta vis kunde jag skriva koden och sedan rita mönsterkortet, skulle jag ändra vilken portpinne som gick var passar tabellen fortfarande, det är bara definitionerna som ska ändras, sedan är tabellen som sådan OK.
Man kan såklart baka ihop dessa funktioner.
Ett annat är att räkna lite:
unsigned long Work;
Work = ADC_Value;
Work *= 48823;
Nu är Work rätt skalad fast 10000000 är 1,0000V.
Man kan ju i samma veva skala det hela lite ner, kanske till en unsigned short:
Work /= 10000;
Då är 1000 = 1,000V
Internt går det alldeles utmärkt att räkna så men vid visningstillfällen ska du peta in komma på rätt position.
Varför har du bara 3 platser för scannaren? Var det inte 4 siffror?
Men för att göra om det till synbara tal måste du i grunden ha två rutiner:
En som plockar ut rätt siffra - och det har vi ju varit igenom redan.
Och en som slår upp i en tabell för att omvandla siffra till binärt mönster att visa.
För att göra det lätt för mig i sin tid gjorde jag mycket jobb som gjorde att det blev litet jobb om jag skulle ändra något.
Kod: Markera allt
#define Seg_A 0x01
#define Seg_B 0x02
#define Seg_C 0x04
#define Seg_D 0x08
#define Seg_E 0x10
#define Seg_F 0x20
#define SEG_F 0x40
#define DP 0x80
const BYTE Pattern[] = {
Seg_A + Seg_B + Seg_C + Seg_D + Seg_E + Seg_F, // '0'
Seg_A + Seg_B, // '1'
osv osv...
}
BYTE Get_Pattern(BYTE Digit)
{
return(Pattern[Digit]);
}
Man kan såklart baka ihop dessa funktioner.
- Magnus_K
- EF Sponsor
- Inlägg: 5854
- Blev medlem: 4 januari 2010, 17:53:25
- Ort: Skogen mellan Uppsala-Gävle
Re: Behöver nybörjarhjälp att programmera i C
Ni ska verkligen ha en klapp på axel och under granen för att ni står ut med mig
Jag har gjort omvandligen precis som du visade överst i ditt inlägg Icecap men jag får inte ordning på min interrupt. Den som scannar de 4 LED-siffrorna.
Interrupten har en frekvens av 500 Hz och eftersom den uppdaterar en LED-siffra i taget så hamnar varje siffra på ca 150 Hz vilket borde räcka.
Det största problemet jag har med detta är att alla 4 siffror visar samma siffra hela tiden. Har aldrig lyckats få dom att visa olika.
Ser någon vart jag tänkt fel i interrupten nedan?
Det är ju mer kod "runt om" men jag försökte skala ner det till enbart det nödvändiga för frågan. Om någon mer del behövs så postar jag gärna den också.

Jag har gjort omvandligen precis som du visade överst i ditt inlägg Icecap men jag får inte ordning på min interrupt. Den som scannar de 4 LED-siffrorna.
Interrupten har en frekvens av 500 Hz och eftersom den uppdaterar en LED-siffra i taget så hamnar varje siffra på ca 150 Hz vilket borde räcka.
Det största problemet jag har med detta är att alla 4 siffror visar samma siffra hela tiden. Har aldrig lyckats få dom att visa olika.
Ser någon vart jag tänkt fel i interrupten nedan?
Det är ju mer kod "runt om" men jag försökte skala ner det till enbart det nödvändiga för frågan. Om någon mer del behövs så postar jag gärna den också.
Kod: Markera allt
const int DIGIT[4] = {
0b00000010,
0b00000100,
0b00001000,
0b00010000
};
const int NUMBER[10] = {
0b11000000, //0
0b11111001, //1
0b10100100, //2
0b10110000, //3
0b10011001, //4
0b10010010, //5
0b10000010, //6
0b11111000, //7
0b10000000, //8
0b10010000 //9
};
void interrupt(void) {
if(INTCON.TMR0IF) {
LATA &= (PORTA & 0x00); // Släck anod
LATD &= (PORTD & 0x00); // Släck segmenten
i++; // Räkna upp vilken display som ska laddas nästa gång
if(i == 4) {i = 0;}; // Om >3 så nolla
j = voltage[i]; // Tilldela j siffran som ska visas på nästa LED
LATD |= NUMBER[j]; // Aktivera rätt segment
LATA |= DIGIT[i]; // Tänd ny anod
Counter++; // Öka räknaren som vid 3 triggar ny ADC-läsning
INTCON.TMR0IF = 0; // Nolla overflow flaggan
}
}
Re: Behöver nybörjarhjälp att programmera i C
Du har bara glömt öka i inne i interruptet? EDIT: Nej det gör du ju Annars hade du bara haft en siffra lysande
Jag är blind...
Hmmm, och du har stoppat in olika saker i voltage[] ?
Sen är det ett ; för mycket här: "if(i == 4) {i = 0;}; // Om >3 så nolla"
MVH: Mikael

Hmmm, och du har stoppat in olika saker i voltage[] ?
Sen är det ett ; för mycket här: "if(i == 4) {i = 0;}; // Om >3 så nolla"
MVH: Mikael
- Magnus_K
- EF Sponsor
- Inlägg: 5854
- Blev medlem: 4 januari 2010, 17:53:25
- Ort: Skogen mellan Uppsala-Gävle
Re: Behöver nybörjarhjälp att programmera i C
Det hade du rätt i adent! Konstigt att inte det gav något fel när jag kompilerade.
Tog bort den sista ";" men gjorde tyvärr ingen skillnad.
voltage[] arrayen har 4 element och jag ger dessa induviduella värden enligt rutinen jag postat tre inlägg upp.
(enda skillnaden är att jag dividerar med 10 mellan varje modulus, tankevurpa)
Först fick jag bara nollor på displayen och trodde det var rätt visat men bara jag som inte lyckas få ADC-datan rätt konverterad.
Senare visade det sig att displayen bläddrar till ibland till "1111", "4444" eller "0.0.0.0." så då misstänkte jag att det är något i denna interrupt som felar. Ser bara inte vad...
EDIT: Hmm, kom på det nu när jag skrev det. Jag har inte definerat någonstans hur ett decimaltecken ska skrivas ut, tänkte vänta med det, men ändå visas alla fyra ibland.
Ytterligare ett tecken på att jag inte skriver till porten riktigt... eller felkopplat! Återkommer om detta!
Tog bort den sista ";" men gjorde tyvärr ingen skillnad.
voltage[] arrayen har 4 element och jag ger dessa induviduella värden enligt rutinen jag postat tre inlägg upp.
(enda skillnaden är att jag dividerar med 10 mellan varje modulus, tankevurpa)
Först fick jag bara nollor på displayen och trodde det var rätt visat men bara jag som inte lyckas få ADC-datan rätt konverterad.
Senare visade det sig att displayen bläddrar till ibland till "1111", "4444" eller "0.0.0.0." så då misstänkte jag att det är något i denna interrupt som felar. Ser bara inte vad...
EDIT: Hmm, kom på det nu när jag skrev det. Jag har inte definerat någonstans hur ett decimaltecken ska skrivas ut, tänkte vänta med det, men ändå visas alla fyra ibland.
Ytterligare ett tecken på att jag inte skriver till porten riktigt... eller felkopplat! Återkommer om detta!
Re: Behöver nybörjarhjälp att programmera i C
Som nån pepekade:
unsigned short voltage[3];
3 ska vara 4.
Har du provat att ändra:
till:
?
MVH: Mikael
unsigned short voltage[3];
3 ska vara 4.
Har du provat att ändra:
Kod: Markera allt
voltage[3] = total_voltage % 1000;
total_voltage /= 1000;
voltage[2] = total_voltage % 100;
total_voltage /= 100;
voltage[1] = total_voltage % 10;
total_voltage /= 10;
voltage[0] = total_voltage % 1;
Kod: Markera allt
voltage[3] =1;
voltage[2] = 2;
voltage[1] = 3;
voltage[0] = 4;
MVH: Mikael