Jak spojit asm a C v MPLAB?

Dobrý večer,

prosím o radu, jak “přinutit ke spolupráci” kódy v asm s kódy v C.

Konkrétně:
Z dřívějška mám napsané podprogramy pro řízení LCD displeje a pro čtení 4x4 maticové klávesnice - oba v assembleru.

Hlavní program bude napsán v C.

Předpokládám, že bude stačit v MPLABu umístit všechny zdrojové texty do složky “Source Files” v okně projektu a že si s tím překladač a linker poradí.

Nevím však, jak z hlavního programu v C volat podprogramy v asm.

Poraďte, prosím, jak na to - děkuji!

Vl.

S tím si překladač neporadí. Asm kód pro to musí být uzpůsoben. Ty totiž v asm budeš zcela jistě používat stejné registry jako překladač v C a zavoláním podporgramu mu je všechny přepíšeš. On se pak vrátí do hromady nesmyslů. Ikdybys tohle všechno vyřešil (pushováním použitých registrů), musíš ještě vyřešit předávání parametrů.

Obsluhu displeje určitě seženeš hotovou. Klávesnici si z cvičných důvodů napiš znova :slight_smile:.

Tak jo, co se dá dělat … :slight_smile:

Jen mi bylo trošku líto nevyužít toho, co už mám hotové :slight_smile:.

Vl.

To jsi mohl rovnou zůstat u asm :smiley:
Nebuď pohodlný a napiš si to znovu… je to přeci na pár řádek… :smiley:

Jak pro koho … :slight_smile:

Stále v tom dost plavu …

Ale jo, nějak se to udělá :slight_smile:

Vl.

Já bych to tak černě neviděl.
Každý C překladač umožňuje vkládat asm příkazy , je n mu musíš říct, kde asm začíná a kde končí. V MPlab C18 pomocí _asm a _endasm.

Takže můžeš klidně svoje podprogramy v asm “zabalit” do C funkce.

např. inicializace displeje:

[code]void LCD_init()

{
_asm

//sem zkopíruješ svůj podprogram v asm




_endasm
}[/code]

Jen tak mimochodem v asembleru je napsaná většina knihovních funkcí nejen překladače MPlabC18, ale i jiných.

a překladač bych tak nepodceňoval - myslím, že si dokáže ošetřit, aby nenastala situace, kterou popisuje piityy , protože jinak by ta možnost vkládat vlastí asm kód postrádala jakýkoli smysl.

Ale na na druhou stranu s ním souhlasím - oboje (LCD i klávesnici) najdeš určitě hotové v několika variantách, nebo to vem jako cvičení :slight_smile:

Tak přestaň plavat a začni psát :smiley:
Případné otázky napiš sem.

Hoši, ještě dnes již poslední prosbu:

K ovládání LCD displeje potřebuji patřičnou knihovnu. Něco jsem sice na internetu objevil, ale nedokážu se v nich vyznat.

Nemůžete mi alespoň dát tip na knihovnu pro PIC18Fxx a HD44780?

Dost by mi to ulehčilo práci

Dík!

Vl.

A proto je lepší si napsat vlastní v které se pak vyznáš.

Jasně,

ale netuším, jak na to.

Hotová knihovna by pomohla i jako příklad, jak vytvořit vlastní :slight_smile:.

Ale něco už jsem našel, uvidím …

Vl.

zkus tohle: (příloha)

pro začátek budeš potřebovat dvě funkce - void init_lcd(void); a void zobraz(const rom char *buffer);

první dáš na začátek main funkce a druhou použiješ pro samotné zobrazení na LCD.

např.

[code]

#include “lcd.h” // pro obsluhu LCD
#include // pro fci itoa

unsigned char lcd_buffer[33];

void main()
{
lcd_init();
while(1)
{
itoa(1234,lcd_buffer); //převede číslo 1234 na ascii znaky a uloží do bufferu
zobraz(lcd_buffer); //zobrazí obsah bufferu na LCD
}
}[/code]

To vše ovšem za předpokladu, že použijěš zmiňovaný MPlab C18.

Oba soubory zkopíruj do složky s konkrétním projektem.

A v této části si uprav výstupy na které si lcd připojíš, případně použij ty zadané:

[code]#define RS PORTBbits.RB4
#define RW PORTBbits.RB3
#define E PORTBbits.RB2

#define DB4 PORTCbits.RC7
#define DB5 PORTCbits.RC6
#define DB6 PORTCbits.RC5
#define DB7 PORTCbits.RC4[/code]
LCD.rar (1.42 KB)

Jo, to je ono, zkusím.

Díky moc!

Vl.

Ještě doplním, že snad každý C compiller - tedy i mcc18 má vlastní knihovní funkce pro tento typ řadiče LCD - některé i pro graf. displeje.

Návod najdeš v helpu - Topics - MPLAB C18 libraries - ten sice neumí česky, zato umí spoustu jiných věcí, třeba kursor :slight_smile: .

Lou,

tak každý ho asi nemá nebo jej neumím najít :slight_smile:.

Momentálně zkouším Hi-Tech pro řadu PIC16xx, protože to potřebuji do školy.
A vypadá to, že tento compiler funkce pro LCD nemá, alespoň v manuálu jsem je nenašel.

V manuálu C18 jsem je našel okamžitě.

Takže si vyrobím zkušební desku na PIC18Fxx a bude to vyřešené :slight_smile:.

Dík za tip!

Vl.

skusil si zlozku C:\Programs\Microchip\HI TECH 9.81\samples
res tam kde si si to nainsataloval…

ked sme uz pritom mam v asm komunikacnu rutinu odladenu s presnym casovanim…skusil som to prepisat do Cka ale akosi to uz nekomunikuje predpokladam ze sa rozhodi casovanie, TAk ze bodol by nejaky link ako skombinovatasms C hitech, ide mi hlavne o predavanie dat medzi asm a Ckom, natrepat tam asm niej eproblem ale ako vysvetlit predavanie dat… dakujem

Hi Tech neznám, ale je dost pravděpodobné, že si budeš muset upravit názvy sfr registrů, přístup k bitům portů (PORTBbits.RB0) a čekací smyčku (Delay100TCYx(24)) pokud nejsou shodné.

Atlan:

Ano, vím, že tam je příklad na komunikaci s LCD.
Na začátku je toto:

#include <htc.h>
#include “lcd.h”

Ale nikde jsem tam nenašel “lcd.h”.

Jinak s tím asm …
Přesně o to mi jde - řekl bych, že v asm je možno časování nastavit naprosto přesně. Jak je to v C, nevím.

Ale našel jsem v nějakém ukázkovém programu přímo od Microchipu toto (ukázka):

CMD_SEQ
;
if ( Four_bit )
if ( !Data_HI )
MOVLW 0X02 ; 4-bit low nibble xfer
else
MOVLW 0X020 ; 4-bit high nibble xfer
endif
;
else ; 8-bit mode
MOVLW 0X038
endif
;
MOVWF LCD_DATA ; This code for both 4-bit and 8-bit modes
BSF LCD_CNTL, E ;
BCF LCD_CNTL, E ;
;
if ( Four_bit ) ; This code for only 4-bit mode (2nd xfer)
if ( !Data_HI )
MOVLW 0x08 ; 4-bit low nibble xfer
else
MOVLW 0x080 ; 4-bit high nibble xfer
endif
MOVWF LCD_DATA ;
BSF LCD_CNTL, E ;
BCF LCD_CNTL, E ;
endif

Co to je? Je to kombinace asm a příkazů C v jednom souboru nebo jsou takto využity řídící directiva překladače?

Vl.

Omlouvám se, je tam i lcd.h. Přehlédl jsem to.

Vl.

velmi som do toho nepozeral ale tusim to zatrepe cely port s LCD… lepsim risenim je pouzit nejaky medziradic pre LCD a tym padom pouzit len 3 vodice…

řekl bych že to: if ( Four_bit ) je nějaké asm makro - ne C příkaz

za prvé - třeba v mcc 18 zavoláním C funkce Delay10TCYx(); zavoláš toto:

[code]D10TCYXCODE CODE

Delay10TCYx
movlw 0xff
movf PLUSW1,0
dcfsnz WREG,1
return

D10x
nop
bra $+2
bra $+2
bra $+2
D10_1
decfsz WREG,1
bra D10x
return

GLOBAL  Delay10TCYx
END[/code]

tedy úplně to samé (nebo hodně podobné) co jsi určitě používal do teď v asm a stejně tak můžeš ladit přesné časy přidáváním nějakých nopů i v C zápisu.

edit:
zapomněl jsem napsat
za druhé: výše uvedený způsob je nejnehospodárnější časování - vhodné leda tak při nějaké inicializaci

od časování jsou v MCU časovače, které pouhým zadáním jejich hodnoty můžeš ladit až mikroskopicky přesně - a je jedno jestli k tomu použiješ asembler, nebo C