Komma åt I/O pinnar från program med flera källfiler

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Johel572
Inlägg: 53
Blev medlem: 5 juli 2006, 10:36:01
Ort: Linköping

Komma åt I/O pinnar från program med flera källfiler

Inlägg av Johel572 »

Jag har tittat lite på hur man skriver relocatable kod och försökt skriva om lite gammal kod jag hade liggandes för att kunna används i någon sorts personligt kod bibliotek. Tanken är att man bara ska kunna lägga till filen i projektet och använda funktionerna direkt. Det har faktiskt fungerat riktigt bra men när jag skulle skriva om en LCD (HD44780) kod stötte jag på patrull.

Det hela handlar om att när jag ska skriva något till LCDn lär jag ju sätta E, R/W, RS hög eller låg lite beroende på vad som skall utföras. Problemet jag har är att jag inte kommer åt dessa pinnar från min funktion (som alltså ligger i en annan fil än huvudprogrammet). Finns det något bra sätt att komma runt det?

Problem nummer två är ju att det inte är speciellt praktiskt att ha tex bcf PORTB, RC7 (E=RC7) på tio olika ställen i koden. Ska man ha någon typ av generell kod borde man ju bara behöva ändra pinne på ett ställe. Så jag tog en titt på macron (har aldrig använt macron tidigare) och tyckte att det här vore ju en vettig lösning. Men det gick inge vidare det heller. Jag tänkte mig något i stil med följande.

Macro:

Kod: Markera allt

;Sätt E hög
E_high	macro  
	bsf PORTB,RB5
	endm
All ligger in en *.inc fil som jag sen inkluderar i huvudprogrammet. Men även här kommer jag inte åt PORTB. Tänker jag helt fel här eller hur ska man göra?

Jag har även funderat över något med #define (se nedan) men inte lyckats implementera det i min externa fil. Jag har inte använt det tidigare heller, med det faller ju även det på att jag inte kommer åt PORTB i min externa fil.

#define:

Kod: Markera allt

 #define      E   PORTB,RC7      ; Kontrollerar E
Jag skulle vara tacksam för något tips eller input då det känns som jag kört fast. Det är föresten en pic18f458 jag använder.
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Komma åt I/O pinnar från program med flera källfiler

Inlägg av Icecap »

Jag har löst detta på det sätt att jag har ett antal filer med olika funktioner i, LCD, EEPROM osv. Dessa inkluderar när jag behöver dom och förvisso håller jag mig till C men principen är det samma:
#define LCD_E PORTB,RC7
#define LCD_Data PORTC
(bara exempel)

Sedan utför funktionen som jag inkluderar sina funktioner med LCD_E/LCD_Data osv.

Jag inkluderar i övrigt aldrig som .INC-filer men som .ASM, det är smak och tycke men har man en färdig funktion (t.ex. skriva till LCD) anger man dessa #defines först som programsnutten är beroende av och sedan inkluderar jag filen.

Och när jag inkluderar filen gör jag det inte i projektet men i källkodsfilen, då blir den inkluderade filen en del av källkoden. Man kan även vara "tvungen" att definiera vissa funktioner som globala för att kompilern ska "se" dom i alla lägen.
Användarvisningsbild
Johel572
Inlägg: 53
Blev medlem: 5 juli 2006, 10:36:01
Ort: Linköping

Re: Komma åt I/O pinnar från program med flera källfiler

Inlägg av Johel572 »

Det låter precis som jag vill ha det. Dock blir jag lite fundersam över hur du får till det. Jag har suttit och testat lite med
#define E PORTB,RC7 ; Kontrollerar E
i min andra källkodsfil. Då kan jag tex bcf E men jag får error i define raden då kompilatorn inte känner igen RC7. Min tanke på ett macro var att man skulle slippa detta men det faller som sagt på att jag inte kommer åt PORTB från macro filen heller :humm:
Och när jag inkluderar filen gör jag det inte i projektet men i källkodsfilen, då blir den inkluderade filen en del av källkoden.
Kör du med något i stil med include "funktionsfil.asm"? Jag trodde man skulle slippa detta i och med att man lägger till filen som en källkodsfil i projektet och låter kompilatorn sköta länkningen eller är jag ute och cyklar?
Användarvisningsbild
JockeE
Inlägg: 330
Blev medlem: 4 augusti 2004, 08:46:50

Re: Komma åt I/O pinnar från program med flera källfiler

Inlägg av JockeE »

Har du inkluderat processordefinitionsfilen (p18f458.inc) i din andra källkodsfil? Annars fungerar det givetvis inte att använda namn som PORTB och RC7, de är ju i så fall inte definierade!
Användarvisningsbild
Icecap
Inlägg: 26659
Blev medlem: 10 januari 2005, 14:52:15
Ort: Starup (Haderslev), Danmark

Re: Komma åt I/O pinnar från program med flera källfiler

Inlägg av Icecap »

Som sagt: jag kör med C och då kan det bli lite annorlunda. Dessutom gillar jag att man ser vilka filer/funktioner som ingår enbart vid att kolla på källkoden, därför inkluderar jag i källkoden.

Och sedan är det en sak jag inte gillar med din definition och det är att du använder en hexadecimal siffer som definitionen, dels blir det MYCKET svårt att läsa senare vad fan 'E' är och dels kan det bli (sannolikt inte men ändå...) knas för kompilern.

'LCD_Enable' är definitivt mer tydligt än 'E' eller hur? Det visar vad definitionen används till och ger tydlighet i programmet.

Dessutom är det så att om du kör ASM duger definitionen
#define LCD_Enable PORTB,7
alldeles utmärkt.
Senast redigerad av Icecap 3 februari 2009, 21:47:32, redigerad totalt 1 gång.
Användarvisningsbild
Johel572
Inlägg: 53
Blev medlem: 5 juli 2006, 10:36:01
Ort: Linköping

Re: Komma åt I/O pinnar från program med flera källfiler

Inlägg av Johel572 »

Har du inkluderat processordefinitionsfilen (p18f458.inc) i din andra källkodsfil?
Eh, nej. Trodde inte det behövdes då den var inkluderar i huvudfilen :vissla: Nu fungerar det hur bra som helst. Jag sätter in några #define och jag tror att allt kommer att vara löst (ska göra hårdvaru test i morgon för att verifiera). Jag visste väl att det var något skit fel, får skylla på brist på rutin.

'LCD_Enable' är definitivt med tydligt än 'E' eller hur?
Håller helt klar med, blir betydligt lättare att läsa koden vilket kan vara viktigt om man använder färdigskrivna rutiner. Ska fixa det bums.

Tack!
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: Komma åt I/O pinnar från program med flera källfiler

Inlägg av sodjan »

Varje ASM fil assembleras helt för sig själv till en egen O (objekt) fil och
varje ASM fil måste alltså ha alla #include och så vidare som man behöver.

Ett sätt är att skapa en generell INC fil för hela projektet där du kan
lägga sådant som måste finnas i alla ASM filer i projektet. Där kan
du även lägga #include av "device-filen" så slipper du ha flera #include
i varje fil. Skulle du byta processor till projektet så blir det bara ett
ställa att ändra device-fil (istället för i alla ASM filer), dessutom...

EDIT: Ett litet exempel...

Antag att projektet heter ABC. Då kanske vi har ASM filerna
ABC1.ASM, ABC2.ASM, ABC3.ASM o.s.v (men sannolikt med "bättre" namn).

Sedan har vi en gemensam include fil som heter ABC.INC.

Varje ABCx.ASM innehåller ett "#include ABC.INC".

ABC.INC innehåller sedan t.ex #include P16F88.INC. PÅ så sätt kommer alla
definitionrena i device-filen automatiskt med i alla ABCx.ASM filerna och det
blir bara ett ställe att ändra om man byter processor. ABC.INC kan sedan
även innhålla allt annat som man vill ska vara "synligt" över alla filer som
olika #defines.

Notera dock att vad som inte går att hantera på detta sätt är GLOBAL och
EXTERN. Man kan inte göra EXTERN på en symbol som har sin definition
i samma fil. Det går att komma runt genom att först definiera en symbol
innan man gör #include ABC.INC och sedan ha en test på denna symbol
och hoppa över EXTERN direktivet. Alltså, antag att ABC3 har en subrutin
kallad abc3_sub som man vill anropa från ABC1 och ABC2, så kan man göra
så att i ABC.INC har man :

#ifdef this_file_is_ABC3
global abc3_sub
#else
extern abc3_sub
#endif

Sedan, i ABC3.ASM så gör man

#define this_file_is_ABC3
#include ABC.INC

Alltså kommer ABC1 och ABC2 att se ett "extern" direktiv och ABC3 ett "global" direktiv...

Otestat, men bör fungera... :-)
Skriv svar