C-kods problem
Okej, nu har jag skrivit det och kompilator klagar inte.
Men om någon vill så kan den få ögna igenom detta och se ifall jag har tänkt helt fel.Fick göra en switch av tecknen då de inte ligger på rad i ASCII tabellen.
Tack ska ni ha för all hjälp!
//Emil
Men om någon vill så kan den få ögna igenom detta och se ifall jag har tänkt helt fel.
Kod: Markera allt
const unsigned char char_A[] PROGMEM = {0b01111110, 0b10010000, 0b10010000, 0b10010000, 0b01111110};
...................
const unsigned char char_Z[] PROGMEM = {0b10000110, 0b10001010, 0b10010010, 0b10100010, 0b11000010};
const unsigned char char_0[] PROGMEM = {0b01111100, 0b10000010, 0b10000010, 0b10000010, 0b01111100};
..................
const unsigned char char_9[] PROGMEM = {0b01100000, 0b10010000, 0b10010000, 0b10010000, 0b01111110};
const unsigned char char_UT[] PROGMEM = {0b01110000, 0b10001010, 0b01110000}; // !
..................
const unsigned char char_HPI[] PROGMEM = {0b01000100, 0b00101000, 0b00010000}; // >
PGM_P char_array[26] PROGMEM = {char_A, char_B, char_C, char_D, char_E, char_F, char_G, char_H, char_I, char_J, char_K, char_L, char_M, char_N, char_O, char_P, char_Q, char_R, char_S, char_T, char_U, char_V, char_W, char_X, char_Y, char_Z};
PGM_P num_array[10] PROGMEM = {char_0, char_1, char_2, char_3, char_4, char_5, char_6, char_7, char_8, char_9};
PGM_P sign_array[22] PROGMEM = {char_UT, char_PRO, char_SLASH, char_VP, char_HP, char_VHP, char_HHP, char_VKP, char_HKP, char_LIKA, char_FT, char_PLUS, char_MINUS, char_PUNKT, char_KOLON, char_UL, char_APOSTROF, char_DL, char_STJ, char_UPI, char_VPI, char_HPI};
void LCD_Write_Char(unsigned char x, unsigned char y, char ch)
{
unsigned char ch_data[5] = {0, 0, 0, 0, 0};
PGM_P p;
if((ch >= 'A') && (ch <= 'Z'))
{
memcpy_P(&p, &char_array[ch - 'A'], sizeof(PGM_P));
strcpy_P(ch_data, p);
}
else if((ch >= '0') && (ch <= '9'))
{
memcpy_P(&p, &num_array[ch - '0'], sizeof(PGM_P));
strcpy_P(ch_data, p);
}
else
{
switch(ch)
{
case '!': memcpy_P(&p, &sign_array[0], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case '%': memcpy_P(&p, &sign_array[1], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case '/': memcpy_P(&p, &sign_array[2], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case '(': memcpy_P(&p, &sign_array[3], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case ')': memcpy_P(&p, &sign_array[4], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case '[': memcpy_P(&p, &sign_array[5], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case ']': memcpy_P(&p, &sign_array[6], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case '{': memcpy_P(&p, &sign_array[7], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case '}': memcpy_P(&p, &sign_array[8], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case '=': memcpy_P(&p, &sign_array[9], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case '?': memcpy_P(&p, &sign_array[10], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case '+': memcpy_P(&p, &sign_array[11], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case '-': memcpy_P(&p, &sign_array[12], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case '.': memcpy_P(&p, &sign_array[13], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case ':': memcpy_P(&p, &sign_array[14], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case '_': memcpy_P(&p, &sign_array[15], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case '´': memcpy_P(&p, &sign_array[16], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case '|': memcpy_P(&p, &sign_array[17], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case '*': memcpy_P(&p, &sign_array[18], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case '^': memcpy_P(&p, &sign_array[19], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case '<': memcpy_P(&p, &sign_array[20], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
case '>': memcpy_P(&p, &sign_array[21], sizeof(PGM_P)); strcpy_P(ch_data, p); break;
default: break;
}
}
osv..osv..osv
}
Tack ska ni ha för all hjälp!
//Emil
Okej, då ingen säger något så antar jag att den är okej. 
Men, nu har jag börjat blivig orolig för storleken på programmet.
Hur vet man hur mycket minne det kommer ta?
Såhär ser en rad i .hex filen ut: ":100000000C9437010C9452010C9452010C9452013F" och filen är 6109 byte stor nu.
Harför mig att jag fick svar för detta i en gammal tråd men jag lyckades inte hitta den.
//Emil

Men, nu har jag börjat blivig orolig för storleken på programmet.
Hur vet man hur mycket minne det kommer ta?
Såhär ser en rad i .hex filen ut: ":100000000C9437010C9452010C9452010C9452013F" och filen är 6109 byte stor nu.
Harför mig att jag fick svar för detta i en gammal tråd men jag lyckades inte hitta den.
//Emil
-
- EF Sponsor
- Inlägg: 2109
- Blev medlem: 27 augusti 2005, 20:57:58
- Ort: Borlänge
Jag tror inte din kod stämmer riktigt. Du ska nog skippa alla anrop till strcpy_P(). Så här hade jag tänkt:
Jag har alltså tänkt att du först bestämmer plats i minnet och hur många bytes som ska kopieras. Sen när alla kollar är gjorda så gör du själva anropet till memcpy_P(). I övrigt vet jag inte om det går att förstå vad jag menar i koden. Fråga om du inte förstår. 
sizeof(PGM_P) som du hade skrivit blir inte rätt va? Kontrollera.
Kod: Markera allt
void LCD_Write_Char(unsigned char x, unsigned char y, char ch)
{
unsigned char ch_data[5] = {0, 0, 0, 0, 0};
unsigned char bytes = 0;
PGM_P p = NULL;
if ((ch >= 'A') && (ch <= 'Z'))
{
p = &char_array[ch - 'A'];
bytes = sizeof(char_array[0]);
}
...
//bla bla
switch (ch)
{
case '!': p = &sign_array[0]; break;
case '%': p = &sign_array[1]; break;
...
}
if (p)
bytes = sizeof(sign_array[0]);
//bla bla
memcpy_P((void*)ch_data, p, bytes);
...

sizeof(PGM_P) som du hade skrivit blir inte rätt va? Kontrollera.
Jag har ingen aning om min kod funkar än men kompilatorn klagar inte.
Jag gjorde exakt lika som på http://www.nongnu.org/avr-libc/user-man ... _rom_array och där står det att man man ska göra så.
För jag har igenteligen ingenaning om hur detta funkar.
Jag förstår inte helle riktigt din kod.
Sen kör du sizeof alltid på det första elementet fast att vissa element inte har samma storlek.
Fast man kanske ska göra så. Somsagt, jag vet inte.
//Emil
Jag gjorde exakt lika som på http://www.nongnu.org/avr-libc/user-man ... _rom_array och där står det att man man ska göra så.
För jag har igenteligen ingenaning om hur detta funkar.
Jag förstår inte helle riktigt din kod.
Sen kör du sizeof alltid på det första elementet fast att vissa element inte har samma storlek.
Fast man kanske ska göra så. Somsagt, jag vet inte.

//Emil
Korken: Största problemet är att det är olika storleker på teckentabellen. Detta kan lösas på olika sätt och ett av de smartaste är att ange storleken.
Jag har gjort en teckentabell till ett projekt där varje inlägg var:
Längd, Data1, Data2, Data3, Data4, Data5
osv.
Då kunde rutinen enkelt slå upp i tabellen, läsa HUR många bytes som skulle skrivas och vilka de var. Ingen massa jävla "case: break".
Visst, det fyllde tomma bytes i minnet men case: break är inte billigt heller.
På mig verkar det som att du vill göra den mest ineffektiva och långsamma kod som möjligt men det kanske är för att"Jag förstår inte heller riktigt din kod".
Jag vet inte hur mycket minne du har men en komplett teckentabell (karaktär 0-255, 6 bytes/karaktär) fyller 1536 bytes. Då har du en 5*7(8) matris med storleksangivelse, är storleken 0 finns det tecken inte.
Enklare mjukvara än så finns inte, kanske inte världens mest effektiva i kodstorlek men snabbt som fan.
Jag har gjort en teckentabell till ett projekt där varje inlägg var:
Längd, Data1, Data2, Data3, Data4, Data5
osv.
Då kunde rutinen enkelt slå upp i tabellen, läsa HUR många bytes som skulle skrivas och vilka de var. Ingen massa jävla "case: break".
Visst, det fyllde tomma bytes i minnet men case: break är inte billigt heller.
På mig verkar det som att du vill göra den mest ineffektiva och långsamma kod som möjligt men det kanske är för att"Jag förstår inte heller riktigt din kod".
Jag vet inte hur mycket minne du har men en komplett teckentabell (karaktär 0-255, 6 bytes/karaktär) fyller 1536 bytes. Då har du en 5*7(8) matris med storleksangivelse, är storleken 0 finns det tecken inte.
Enklare mjukvara än så finns inte, kanske inte världens mest effektiva i kodstorlek men snabbt som fan.
Kod: Markera allt
typedef unsigned char byte;
const byte Teckentabell[6][] PROGMEM = {
{0,0x00,0x00,0x00,0x00,0x00}, // Index ASCII 0
{0,0x00,0x00,0x00,0x00,0x00}, // Index ASCII 1
{0,0x00,0x00,0x00,0x00,0x00}, // Index ASCII 2
{0,0x00,0x00,0x00,0x00,0x00}, // Index ASCII 3
{0,0x00,0x00,0x00,0x00,0x00}, // Index ASCII 4
....
{3,0x00,0x00,0x00,0x00,0x00}, // Index ASCII 32 ' '
{1,0x7D,0x00,0x00,0x00,0x00}, // Index ASCII 33 '!'
{3,0xC0,0x00,0xC0,0x00,0x00}, // Index ASCII 34 '"'
....
};
void LCD_Write_Char(unsigned char x, unsigned char y, char ch)
{
if(Teckentabell[0][ch])
{
memcpy_P((void*)ch_data, Teckentabell[1][ch], Teckentabell[0][ch]);
// eller rättare: skriv ut på displayen, datan finns i Teckentabell[1-5][ch]
// och antalet bytes i Teckentabell[0][ch]
};
Senast redigerad av Icecap 17 april 2007, 19:27:15, redigerad totalt 1 gång.
-
- EF Sponsor
- Inlägg: 2109
- Blev medlem: 27 augusti 2005, 20:57:58
- Ort: Borlänge
Icecap: Testade din metod och den verkar ta upp 402 bytes (1514-1112) mer minne. Då körde jag 5 bytes/tecken på alla tecken på båda metoderna. Med din metod gjorde jag en array med 128 tecken. Fast din metod är ju bra mycket snyggare.
Men varför kör du med ett "Längd"-fält? Man kan väl lika gärna köra med 5 bytes överallt. Nollorna antar jag inte gör någon skillnad i Korkens LCD-funktion.
Korken: Gör ett testprogram som endast lagrar en byte i Flash-minnet. Sen försöker du läsa av det och låt en LED blinka om du läser rätt byte. Sen går du vidare med arrayer osv. Förstår du inte exakt hur allt fungerar så ska du absolut inte ta för givet att en så stor kodbit, som du har skrivit, fungerar direkt.
Det jag tror du ska använda är memcpy_P(). Sen verkar det som att du ska använda pekartypen PGM_VOID_P istället för PGM_P som du/jag har använt. Se också memcpy(), för att se hur den funktionen fungerar.
Försök fixa en liten testkod och se vad som händer. Eller posta här, så kan jag/vi kolla på koden.
Men varför kör du med ett "Längd"-fält? Man kan väl lika gärna köra med 5 bytes överallt. Nollorna antar jag inte gör någon skillnad i Korkens LCD-funktion.
Korken: Gör ett testprogram som endast lagrar en byte i Flash-minnet. Sen försöker du läsa av det och låt en LED blinka om du läser rätt byte. Sen går du vidare med arrayer osv. Förstår du inte exakt hur allt fungerar så ska du absolut inte ta för givet att en så stor kodbit, som du har skrivit, fungerar direkt.
Det jag tror du ska använda är memcpy_P(). Sen verkar det som att du ska använda pekartypen PGM_VOID_P istället för PGM_P som du/jag har använt. Se också memcpy(), för att se hur den funktionen fungerar.
Försök fixa en liten testkod och se vad som händer. Eller posta här, så kan jag/vi kolla på koden.