Микроконтролери и електроника
http://mcu-bg.com/mcu_site/

"C" въпрос, как се прави това?
http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=15921
Страница 1 от 6

Автор:  stefan63 [ Чет Май 10, 2018 7:52 am ]
Заглавие:  "C" въпрос, как се прави това?

Здравейте, опитвам се ... и да науча Ц-то

Имам асемблерски файл, от който трябва да извлека данни:
Код:
Асемблерски файл:

A1start:
ATable1words:
  dw Apoint0-A1start //2 байта
  dw Apoint1-A1start //2 байта
  dw Apoint2-A1start //2 байта
  dw Apoint3-A1start //2 байта
....
ConstAsmSegStart: DL A1start ;//4 байта

ATable1longs:
  DL Apoint0 //4 байта
  DL Apoint1 //4 байта
  DL Apoint2 //4 байта
  DL Apoint3 //4 байта

Apoint0:
  db .......
  db...
.......
Apoint3:
  db .......
  db 0x31
  ...



Особеното е, че за икономия на място искам да ползвам по-късата таблица ATable1words (с относителни спрямо началото на сегмента адреси) вместо по-дългата таблица ATable1longs (с абсолютни адреси).

Имам проблем с добавянето на базата към относителния адрес.
Цитат:

//квалификаторът __data20 кара компилатора да ползва 20- битови( реално 32) вместо 16 -битови адреси.
//IAR EW MSP430


#pragma type_attribute=__data20
extern const unsigned int ATable1words[];

__no_init const unsigned char __data20 * Bptr1;
__no_init const unsigned char __data20 * Bptr2;
__no_init const unsigned char __data20 * Bptr3;
__no_init const unsigned int __data20 * Wptr;


__no_init const unsigned char __data20* AsmSegStart;

extern const unsigned char __data20 * ConstAsmSegStart;

// Извикването getexternchar(3,1) трябва да върне 0x31
char getexternchar(unsigned int pointnumber, unsigned int bytenumber)
{

//тези три реда се транслират до асемблер еднакво
Wptr=(unsigned int *) ATable1words[pointnumber];
Bptr1= ( (unsigned char *) ATable1words[pointnumber]);
Bptr3= ( unsigned char *)( (unsigned int *) ATable1words[pointnumber]);

//Bptr2= ( (unsigned int *) ATable1words[pointnumber]);
//Error[Pe513]: a value of type "unsigned int *" cannot be assigned to an entity of type "unsigned char *"



//следшащите два реда се транслират еднакво
AsmSegStart=( const unsigned char *) (&ATable1words);
AsmSegStart=( const unsigned char *) (ATable1words);


Bptr1+=AsmSegStart; // добавяне на базата
Error[Pe031]: expression must have integral type

Bptr3+=ConstAsmSegStart; // добавяне на базата
Error[Pe031]: expression must have integral type


return *Bptr1;
}


Как е коректно да се направи това?

Автор:  stefan63 [ Чет Май 10, 2018 8:26 am ]
Заглавие:  Re: "C" въпрос, как се прави това?

май го нацелих, сега минава:

Bptr1+=( long)AsmSegStart; // добавяне на базата
Bptr3+=( long)ConstAsmSegStart; // добавяне на базата
Bptr1+=(long)(&ATable1words);

Автор:  palavrov [ Чет Май 10, 2018 11:52 pm ]
Заглавие:  Re: "C" въпрос, как се прави това?

По правилно е да не cast-ваш т.е. нещо ей такова

Код:

extern const unsigned int ATable1words[];
extern const unsigned char __data20 * ConstAsmSegStart;

char getexternchar(unsigned int pointnumber)
{
  return AsmSegStart[ATable1words[pointnumber]];
}



Едит: Не ми харесва как е дефиниран AsmSegStart и най вероятно няма да се получи резултатът който очакваш. Я обясни какво точно искаш да направиш, за да поправя примера ...

Автор:  stefan63 [ Пет Май 11, 2018 6:19 am ]
Заглавие:  Re: "C" въпрос, как се прави това?

Имам 2 -3 такива файла, точките Apoint0,Apoint1..ApointN са неща ,които мога да опиша като структури , но това ще го оставя за по-нататък. В конкретния файл тия структури са с променлива дължина - байт 0 показва ,колко колони е широк символът , байт 1- колко празни реда трябва да се добавят отгоре, байт 2 -не си спомням сега -май брой редове, байт 3 - колко байта описват една колона, следва различен брой байтове за самите точки - колона, колона....последна колона.
В другите случаи структурите са с почти еднаква дължина , например описват менюта - когато менюто е въпрос от типа - ДА/НЕ , към него няма номер на структура -описваща пък данните за редактиране . В такъв случай съм си спестявал някой байт в края на структурата за меню . Там ще ги допълня за да е униформена работата, но в случая с шрифтовете ще си е чиста загуба.

Автор:  stoyanoff [ Пет Май 11, 2018 5:52 pm ]
Заглавие:  Re: "C" въпрос, как се прави това?

Мисля, че много сложно си го представяш и съответно много сложно го правиш. До колкото разбирам искаш да вкараш в един масив структури от данни. Аз бих направил една стандартна фукция(примерно serialiser), на която да подавам указател към свободна позиция от буфера, указател към структурата и броя на байтовете в структурата. Функцията ще връща броя на байтовете, които са добавени и така ще знаеш коя е следващата свободна позиция..

Автор:  stefan63 [ Пет Май 11, 2018 6:14 pm ]
Заглавие:  Re: "C" въпрос, как се прави това?

Направил съм го отдавна, сега го превеждам на Ц.
За мене не е сложно направено, поне щом си го разбирам. :D
В конкретния случай става дума за фонт и бързото му извличане . Може със структура на Ц да стане пак бързо, но вероятно ще ми нарастне и стека. Това ше го гледам с другите структури. Шрифтът ще го подкарам така, ако не настъпя някоя мотика, де.

Автор:  stoyanoff [ Пет Май 11, 2018 7:08 pm ]
Заглавие:  Re: "C" въпрос, как се прави това?

Виж как го правя аз. Моят фонт е генериран от програмка, която един колега ми даде. Трябва да е тук някъде темата. Програмката генерира къстъм фонт, какъвто си пожелаеш. Имаш 3 масива от данни - първият съдържа символите, вторият съдържа позицията на първият байт на даден символ в масив 1, третият съдържа широчината на символа. Като знаеш колко е височината шрифта и третия масив изчисляваш колко байта има.
Програмката ти е проста - подаваш на функцията символ(примерно 'а') и това е първата буква в азбуката и съответно в масива. Функцията изважда от 'а' 97, за да превърне символът в номер - 0(първи елемент). От масив 2 намира, кой е първият значещ байт на големия масив. После изчислява колко байта има в този символ - височината на шрифта умножена по числото на съответната позиция на масив 3. След това програмата ти просто чете необходимият брой байтове от големия масив като започне от стартовата позиция. Моята програма е малко по-съвършенна като връща крайните пиксели на дадем символ, за да се изчисли позицията на следващият символ и буквите да са с константно разстояние една от друга. Също така използвам и няколко шрифта. По-сложните програми могат и да интерполират символите, за да сменят размера.
Вече зависи при теб в какъв формат е фонта и как го визуализираш точно. При мен това действа и е относително просто.
Още нещо, не знам в какво държиш фонта, но обикновено Ц не дава да насочваш указател към константа, т. е. трябва да го заредиш в РАМ-а... Сега може твоят компилатор да дава...
Ако ти трябва пример кажи да търся файлове и да ти кача!

Автор:  stefan63 [ Пет Май 11, 2018 9:29 pm ]
Заглавие:  Re: "C" въпрос, как се прави това?

Stoyqnoff, не си прав, не искам да си оспамвам сам темата, ма...кво да те прявя.
Колко байта отделяш за представянето на шпацията в шрифт с височина 30 реда и ширина средно 13 пиксела ?
Използвам няколко шрифта, някои са големи, ама ми трябват само цифрите , точката и знака минус. Схващаш ли?
ЛЦД с контролер Т6963 е съвсем различно от UC1608. И когато имаш малко рам- нещата се усложняват.
Шрифтовете са ми с различен брой символи, основният обхваща източна Европа, високият -само цифрите. Не ми продавай шрифтове. Ако си наясно как да имплеметирам Bitstream Fusion - направи ми оферта.

Автор:  stefan63 [ Пет Май 11, 2018 9:32 pm ]
Заглавие:  Re: "C" въпрос, как се прави това?

Цитат:
Още нещо, не знам в какво държиш фонта, но обикновено Ц не дава да насочваш указател към константа

И защо ?
Ако искаш да си дисциплиниран - обявяваш ,че указателят е към константа, недей да пишеш в константата и Ц-то ще е хепи.

Автор:  stoyanoff [ Пет Май 11, 2018 10:18 pm ]
Заглавие:  Re: "C" въпрос, как се прави това?

Не мога да разбера какво се товариш?! Дадох ти пример как може да си построиш програмата. Аз последно правих меню за ST7735 с контролер, който има само 32к FLASH и 2k RAM. Като използвам 3-4 различни фонта и менюто е сериозно(70% от ресурса на контролера). Аз не съм казал, че вариантът, който ти предлагам е идеален за твоя случай. Налага се да го пригодиш - примерно не е необходимо да слагаш целия фонт в кода, а само символите, които смяташ да използваш...
И не ти продавам нищо, а се опитвам да ти покажа как да си решиш проблемите. Ако искаш утре ти кача програмката, която обръща имволи във фонт. Зареждаш си необходимите символи от необходимия фонт - и после си правиш, каквото ти харесва. Може даже снимка да обърне. Или потърси темата ако бързаш.

Автор:  stefan63 [ Съб Май 12, 2018 6:53 am ]
Заглавие:  Re: "C" въпрос, как се прави това?

Не се товаря,бре, винаги си добре дошъл. :)
Обичам ,когато става спор.
Поздравления за TFT-то. За темата - ще е интерено да постнеш част от кода за визуализация.

Автор:  stoyanoff [ Съб Май 12, 2018 1:22 pm ]
Заглавие:  Re: "C" въпрос, как се прави това?

Ето това ми е основната функция:
Код:
unsigned int DisplayLetter(char x0, char y0,char symbol,char fontID, unsigned int color)

Подавам и координати по x и y, буква(символ), фонт и цвят. Символът го трансформирам така че да го намеря в масива на фонта и го визуализирам.
Какво имаш в предви под кода за визуализация?! Самата функция, която рисува по дисплея?! Или тази, която обръща бит от данна в пиксел?!

Автор:  stefan63 [ Съб Май 12, 2018 2:43 pm ]
Заглавие:  Re: "C" въпрос, как се прави това?

unsigned int DisplayLetter(char x0, char y0,char symbol,char fontID, unsigned int color)

Покажи тази например.

Автор:  stoyanoff [ Съб Май 12, 2018 8:08 pm ]
Заглавие:  Re: "C" въпрос, как се прави това?

Код:
unsigned int DisplayLetter(char x0,char y0,char number,char fontID, unsigned int color)
{
    long int ulOffset;
    char j,y,xx,i,w;
    char part1,rowCounter;
    char letterWidth=GetLetterWidth(fontID,number);
    char letterHeight=GetLetterHeight(fontID,number);
    ulOffset=GetLetterOffset(fontID,number);

    j=0;
    rowCounter=0;
    while(rowCounter<letterHeight)
    {
        w=0;
        while(w<letterWidth)
        {
            part1=GetLetterNibble(fontID,j+ulOffset,number);
            j++;
            for(i=0;i<8;i++)
            {
                if(bittest(part1,i))
                {
                    xx=x0+8+w*8-i;
                    y=y0+rowCounter;
                    drawPixel(xx, y+y0, color);
                }
            }
            w++;
        }
        rowCounter++;
    }
    return letterWidth;
}

Автор:  stefan63 [ Нед Юни 03, 2018 7:14 am ]
Заглавие:  Re: "C" въпрос, как се прави това?

Да попитам нещо "теоретично".

char func1(void)
{
func2();
func3();
func4();
return 1;
}


char func0(void)
{
if.....
return func1();else return func111();
}

Функцията func1 връща резултат "1" , важното е да се изпълнят всичките и редове.
Но ме гложди съмнение , че един оптимизиращ компилатор може да "прескочи" извикването на func2,3,4 и направо да
върне "1", или още по-"оптимизирано" - във функцията func0 -да замести извикването "func1()" с "return 1", а цялото тяло на func1 да бъде премаханато от кода.
Възможно ли е това,или стандартите не го позволяват?
Ако е възможно - как се предотвратява?

Страница 1 от 6 Часовете са според зоната UTC + 1 час [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/