|
Виж темите без отговор | Виж активните теми
Дата и час: Вто Юли 28, 2026 9:07 am
|
Страница 1 от 1
|
[ 14 мнения ] |
|
Как трябва да се направи част от Асемблеров код на C?
| Автор |
Съобщение |
|
E1
Ранг: Почетен член
Регистриран на: Нед Юли 22, 2007 8:57 pm Мнения: 607 Местоположение: Белград
|
 Как трябва да се направи част от Асемблеров код на C?
Опитвам се да схвана как това чудо ("C") работи, но доста ме мъчи самата организация на нещата. Иначе се уверих, че е МНОООГО по-лесно, отколкото с Асемблер. Хванах се да превеждам една готова програма, която писах на Асемблер, но една част от кода не мога изобщо да се сетя как може да се направи. Кодът по-долу е част от знаковия генератор, който прехвърля байтовете в буфери "Current1".."CurrentN", откъдето побайтово се
извеждат на светодиоден дисплей.
Въпросът ми е каква функция може да се използва най-икономично за паметта на контролера? Мислех да го правя с много на брой едномерни масиви(за всеки символ-масив), но не знам как "C" ги представя в микроконтролера и дали няма да го препълни. Преди да ме скастрите заради въпроса, имайте предвид, че с "C" съм все още на ниво кратки преправени готови процедури.
Дали вариант с куп масиви е удачен или има по-лесен начин? AA1
movlw b'00011000' ;A, column 1
movwf Current1
movlw b'00111101' ;A, column 2
movwf Current2
movlw b'00100101' ;A, column 3
movwf Current3
movlw b'00100101' ;A, column 4
movwf Current4
movlw b'00100101' ;A, column 5
movwf Current5
movlw b'00111111' ;A, column 6
movwf Current6
movlw b'00011110' ;A, column 7
movwf Current7
goto SCROLL_RRL
|
| Сря Яну 07, 2009 11:55 pm |
|
 |
|
MYXATA
Ранг: Форумен бог
Регистриран на: Пон Юни 05, 2006 1:48 pm Мнения: 4906 Местоположение: където небето среща земята, ракията е Jameson, а бирата Guinness
|
вместо да превеждаш я напиши начисто
напиши си алгоритъма на работа на прогата с молюф и тефтер  (по подразбиране ти е ясен, защото казваш, че си я писал на асемблер)
взимаш книжка за Ц..
четеш за входни/изходни операции, дефиниране на променливи, функции, заделяне на място в паметта.....
и пишеш
като тръгне тогава почни да мислиш, как да го напишеш така, че да е оптимален кода в смисъл бързодействие/заемана памет ....
_________________ ... ако трети ден не ти се работи... това означава, че е сряда !
|
| Чет Яну 08, 2009 1:01 am |
|
 |
|
E1
Ранг: Почетен член
Регистриран на: Нед Юли 22, 2007 8:57 pm Мнения: 607 Местоположение: Белград
|
Имам доста всевъзможни книжки за "C", от което не ми става по-лесно, защото имат различни подходи при представяне на езика... Това, както и да е. Избрах си нещо, по което работя(всъщност, посъветваха ме да се захвана с обединяване на готови процедури), но не е това въпросът.
Конкретно мога да сведа въпроса до следното: За да не си играя с безсмислено писане на код, дали следният подход е правилен?
Всички символи се дефинират като едномерни масиви, след което съдържанието на масива, съдържащ извиквания символ се прехвърля към един празен масив, от който се подава към текстовото поле.
Дефинирането, например така:
int A[7]={0x30,0x3D,0x25,0x25,0x25,0x3F,0x1E};
И другият проблем е как да направя прехвърлянето, ако масивите не са с еднаква размерност, т.е. как да присвоя на брояча стойността, отговаряща на размера на масива(в горния пример=7)?
....
Така явно няма да стане... За 8 символа ми изразходва 35% RAM... Ясно е и защо.
|
| Чет Яну 08, 2009 1:35 am |
|
 |
|
zaphod
Ранг: Форумен бог
Регистриран на: Нед Юли 24, 2005 10:28 am Мнения: 2658
|
ами това на асемблер дето си го писал пак ми изглежда дървено. и на С и на асемблер подобно нещо се прави с цикъл, а не ред по ред.
char row[]={......};
for(i=0;i<N;i++)current[i]=row[i];
а онова с размерността на масива става така (sizeof(row)/sizeof(row[0])) направо си го дефинирай като макрос, да не се гърчиш да го пишеш секи път.
това се смята при компилация, така че не се страхувай от деленето.
|
| Чет Яну 08, 2009 10:21 am |
|
 |
|
RM
Ранг: Почетен член
Регистриран на: Нед Окт 19, 2008 7:26 pm Мнения: 673
|
Опитай с процесор който има повече ресурс, и след като свикнеш
да пишеш на С, вече ще се глезиш с оптимизация.
Аз се опитвам да разбера в по големи подробности какви са предимствата на адресната аритметика
при работа с масивите, и доколко се увеличава бързодействието на кода специално при 8-битовите.
|
| Чет Яну 08, 2009 10:31 am |
|
 |
|
Cino
Ранг: Новодошъл
Регистриран на: Чет Окт 02, 2008 10:24 pm Мнения: 105
|
дефинирай цялата символна таблица в програмната памет.
пр.
const flash unsigned char arrCharSymbolCode8[]={...}; , зависи от компилатора за MPLAB-MCC18 e const rom unsigned char...
Ако символите са с променливи дължини ,
поддържай още един масив с конкретните дължини на символите
или с масив тяхното отместване спрямо началото на масива също в програмната памет.
После ги дърпай по Ascii код, и отместване за текуща колона.
|
| Чет Яну 08, 2009 10:49 am |
|
 |
|
E1
Ранг: Почетен член
Регистриран на: Нед Юли 22, 2007 8:57 pm Мнения: 607 Местоположение: Белград
|
Точно това имах предвид-прехвърляне в програмната памет. Това в Асемблер, макар и дървено, пести много памет. Компилаторът е mikroC.
|
| Чет Яну 08, 2009 2:13 pm |
|
 |
|
ji4ka
Ранг: Форумен бог
Регистриран на: Чет Фев 01, 2007 4:04 am Мнения: 1539
|
Точно обратното - заема два пъти повече памет от необходимото (флаш). Обаче имай в предвид ,че това е най-бързия вариант, всяко преминаване към цикли, индекси, масиви и т.н. ще намали бързодействието 5-10 пъти. Но щом не ти стига памет защо не вземеш някой по-нов контролер - хем са с повече памет, хем и по-евтини. Правиш наново всичко на Ц и сравняваш със стария вариант. Впрочем крайния резултата в Ц-то няма как да е много по-различен от това което правиш на асемблер - просто се улеснява записа ,резултата в края на краищата е същия.
|
| Чет Яну 08, 2009 7:34 pm |
|
 |
|
E1
Ранг: Почетен член
Регистриран на: Нед Юли 22, 2007 8:57 pm Мнения: 607 Местоположение: Белград
|
О.К. Неправилно се изразих за паметта... Имах предвид, че съм силно ограничен откъм РАМ и съм предпочел варианта с използване на програмната памет. Така програмата се държи добре и скоростта не ми е критичен параметър. Предвид, че трябва да дефинирам горе-долу 2х26+25 или около 80 символа, болшинството, от които заемат по 7 байта, това е 560 байта и то за минимума на програмата, а ако реша да вкарам и кирилицата, ще станат още 2х30х7=420 байта или общо 980 байта. Отделно ми трябва памет и за променливите за другите операции, което ми се струва множко... Затова съм се ориентирал към използване на това, което имам достатъчно-програмна памет, като използвам само 11 байта РАМ, където вкарвам символа, непосредствено преди да се изведе на дисплея. Сигурно ще отнеса критики за подхода си, но на мен ми се стори удачно и вече втори месец програмата работи на десетина дисплея, почти непрекъснато и без никакви проблеми. Това не означава, че не съм съгласен с варианта на ji4ka, напротив, ще го приложа, но на по-късен етап. Кой контролер ми препоръчваш, ji4ka, PIC18F4550?
MicroC не иска да компилира с "flash" и "rom" от кода, който даде Cino. Някой знае ли как става при този компилатор?
|
| Чет Яну 08, 2009 11:58 pm |
|
 |
|
ji4ka
Ранг: Форумен бог
Регистриран на: Чет Фев 01, 2007 4:04 am Мнения: 1539
|
Какъв вариант съм предлагал бре? Да знаеш , не отговарям за нищо.
Според мен както си го направил сега е правилния начин, поне за малките контролери. Даже в началото помислих ,че не ти стига флаш защото по принцип знаковите генератори си стоят в РОМ-а (или в случая флаш) а се "теглят" в момента на ползването им. Ти явно искаш да правиш нещо като видеопамет, по принцип е добре но ще ти трябва РАМ колкото е цялото видеополе и Ц-то няма да ти спести нищо, освен по-лесното управление. Просто трябва да си определиш хардуерните ресурси които ти трябват и да си избереш контролер който ги покрива на цената която те устройва. Като го избереш пускаш едно запитване във форума дали някой е имал проблеми с него и после действаш. Може да огледаш и 24-ките само провери дали комета ги зарежда редовно.
|
| Пет Яну 09, 2009 2:08 am |
|
 |
|
zaphod
Ранг: Форумен бог
Регистриран на: Нед Юли 24, 2005 10:28 am Мнения: 2658
|
ясно, тревожи те че един масив ще се цопне в рама.
ок, ами идват ми следните идеи:
1. напиши пред масива const - добър компилатор ще ползва само програмната памет , но все пак провери кода дали ефекта е както се очаква
2. ползвай флаша
3. в краен случай просто пиши това което си писал на асемблер - ред по ред присвояване. тъпото е че в С няма b префикс, много ми е липсвал, но и шеснайсетично става.
|
| Пет Яну 09, 2009 9:39 am |
|
 |
|
E1
Ранг: Почетен член
Регистриран на: Нед Юли 22, 2007 8:57 pm Мнения: 607 Местоположение: Белград
|
Дойдохме си на думата, значи! Виждам, че и ji4ka и zaphod разбират какъв ми е проблемът, а и какво искам.  Що се отнася до "b" префикса, ако нещо не съм разбрал погрешно, mikroC го поддържа (поне така пише в описанието на синтаксиса на езика), освен ако нещо не съм разбрал неправилно... Пише, че се се дефинира с 0b... , но не съм пробвал все още, а тръгнах на класически вариант- да използвам вградения калкулатор на компилатора. Всъщност, причината, поради която се хванах за това "mikroС" е в декларираните възможностите за бързо използване на готови библиотеки за комуникация. Имам EasyPIC5, а на практика съм си купил и всички (или почти всички) допълнителни аксесоари, просто едва чакам да спра да се мъча с писане на страници кодове(както на шега ми казаха преди около една година-писане на код до посиняване на пръстите на Асемблер... ама си е направо така)
|
| Пет Яну 09, 2009 1:31 pm |
|
 |
|
Cino
Ранг: Новодошъл
Регистриран на: Чет Окт 02, 2008 10:24 pm Мнения: 105
|
#include <p18f1320.h>
const rom unsigned char arrSource[7]={0x30,0x3D,0x25,0x25,0x25,0x3F,0x1E};
unsigned char arrDest[7];
void extract7bytes(static unsigned char rom *p,static unsigned char *q);
void main(void)
{
extract7bytes((unsigned char rom *)&arrSource[0],&arrDest[0]);
// след тази функция 7 байта от масива arrSource-програмна памет ,
// са прехвърлени в масива arrDest-RAM.
while(1)
{
}
}//end main
//-------------------------------------------------------------------------
void extract7bytes(static unsigned char rom *p,static unsigned char *q)
{
_asm
movf q,0,1 //*вземане на адреса на първия Dest байт
movwf FSR0,0
movf p,0,1 //*вземане на адреса на първия Source байт
movwf TBLPTRL,0
movf p+1,0,1
movwf TBLPTRH,0
TBLRDPOSTINC
movff TABLAT,POSTINC0
TBLRDPOSTINC
movff TABLAT,POSTINC0
TBLRDPOSTINC
movff TABLAT,POSTINC0
TBLRDPOSTINC
movff TABLAT,POSTINC0
TBLRDPOSTINC
movff TABLAT,POSTINC0
TBLRDPOSTINC
movff TABLAT,POSTINC0
TBLRDPOSTINC
movff TABLAT,POSTINC0
nop
_endasm
}
Пика е 18f1320, а компилатора е MCC18 на Microchip.
дори и да не са те , идеята е ясна.
Дано това да помогне.
|
| Пет Яну 09, 2009 5:58 pm |
|
 |
|
E1
Ранг: Почетен член
Регистриран на: Нед Юли 22, 2007 8:57 pm Мнения: 607 Местоположение: Белград
|
Благодаря! Ще преправя и този код, според изискванията на компилатора.
Много се изкушавах за това с вмъкването на Асемблер, но не бях много сигурен дали да го пробвам.
Иначе zaphod се оказа прав. Написах:
const unsigned char A[7]={0x30,0x3D,0x25,0x25,0x25,0x3F,0x1E} ;
и компилаторът ми остави РАМ-а на мира. 
|
| Пет Яну 09, 2009 8:52 pm |
|
|
|
Страница 1 от 1
|
[ 14 мнения ] |
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 3 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|