Programsablonok
A programsablonok tulajdonképpen a PIC-es programjaim váza. Tartalmazzák azokat a inicializálásokat, amelyek az adott kontrollerhez feltétlen szükségesek. Használatukkal a tényleges feladatra lehet koncentrálni. A programjaimnál a következő alapelveket követem, ha ezeket betartod, akkor te tudod használni a sablonokat és modulokat:
- A programjaimat case sensitiv módon irom, tehát a kisbetü és nagybetü kulönbözik!
- A főprogramomat egy programsablonból alakitom ki.
- A perifáriák kezelését ugynevezett modulokal végzem.
- A modul legtöbb esetben egy <modulnev>.mac és <modulnev>.inc fájlból áll. (De lehetséges, hogy valamelyik elmarad.)
- A <modulnev>.mac a Makrokat tartalmazza, a program elején kell includálni.
- A <modulnev>.inc a függvényeket tartalmazza, és a program végén kell includálni.
- A modulok általaban tartalaznak egy <modulnev>_INIT makrót. A modul használatához ezt mindenképpen fel kell hivni a főprogram elején.
- Bizonyos modulok függenek egymástól. Itt mindig azt a modult kell inkludálni elöször, amitöl a másik függ.
- A programban mindig a bank0 fileregiszterbank az aktiv. Csak ha szükséges, akkor váltok át más bankra, és ha már nem kell akkor rögtön vissza. A modulok is ugy vannak megirva, hogy feltételezik, hogy a bank0 az aktiv.
- A modulok a bank0-ból használnak file regisztereket. Ha több bankja is van az adott kontrollernek akkor a cblock-al definiált regisztereknél a föprogramban a bank0-hoz tartozó cblock-ot kell utoljára tenni. (Ez a sablonokban igy van, ezért ne cseréld fel öket.)
- A több byte-ból álló változókat mindig MSB First módon kezelem, azaz a magasabb helyiértékü byte van a memóriában a kisebb cimen. (Motorola)
Egy sablon elemzése
A program elején egy hatalmas kommentárban találhatóak a file nevére, modosításának dátumára, verziójára, szerzőjére vonatkozó információk. Továbbá itt található a program megnevezése rövid leirása, a PIC portlábainak bekötése (jelentése) és a PIC-ben lévő erőforrások kihasználásáról info. A blokk végén a modosítások követésére szolgáló táblázat található.
;************************************************************************** ;* FileName : DUMMY872.ASM ;* Date : 25.08.2005 ;* File version : v1.00 ;* ;* Author : MIKO, Imre ;* Company : ;* Homepage : http://majki.atw.hu ;* E-mail : majki.mester#gmail.com ;* ;*------------------------------------------------------------------------- ;* ;* Description : Dummy test ;* ================================== ;* Dummy test code. ;* ;* ;*------------------------------------------------------------------------- ;* ;* Connections : _______ _______ ;* | \_/ | ;* -reset ==| -MCLR RB7 |== n.c. ;* n.c. ==| RA0 RB6 |== n.c. ;* n.c. ==| RA1 RB5 |== n.c. ;* n.c. ==| RA2 RB4 |== n.c. ;* n.c. ==| RA3 RB3 |== n.c. ;* n.c. ==| RA4 RB2 |== n.c. ;* n.c. ==| RA5 RB1 |== n.c. ;* GND ==| Vss RB0 |== n.c. ;* quartz1 ==| OSC1 Vdd |== +5V ;* quartz2 ==| OSC2 Vss |== GND ;* n.c. ==| RC0 RC7 |== n.c. ;* n.c. ==| RC1 RC6 |== n.c. ;* n.c. ==| RC2 RC5 |== n.c. ;* n.c. ==| RC3 RC4 |== n.c. ;* |_________________| ;* PIC16F872 ;* ;*------------------------------------------------------------------------- ;* ;* Resource : Ports : xx / 22 pin ( %) ;* Data memory : xx / 128 byte ( %) ;* Prog memory : xxx / 2048 word ( %) ;* EEPROM : xx / 64 byte ( %) ;* Timers : ;* Interrupt : ;* CCP : ;* MSSP : ;* AD : ;* ;************************************************************************** ;* Revision History: ;* ;* 1.00 25/08/2005 Initial Release ;* ;**************************************************************************A tényleges program a PI tipusának, a programban használatos radix (alapártelmezett számrendszer) beállitásával kezdödik. l=0 a listafile oldalakra tördelését akadályozza meg.
list p=16f872, r=dec, l=0Ezt követi a két alapvető include file behúzása. Az első a microchip által az MPLAB-al adott PIC-specifikus include file. A második pedig az általam készitett base modul, ami a programozás segitő define-okat és makrokat tartalmaz.
;***** INCLUDES *********************************************************** include "p16f872.inc" include "..\..\modules\base.inc"Itt állitom be a konfigurációs word-ot, es a ID-t. Továbbá itt találhatóak a modulokhoz szükséges egyszer futatandó makrók felhivása.
;***** CONFIG ************************************************************ CFG_1 EQU _XT_OSC & _WDT_OFF & _PWRTE_ON & _BODEN_ON & _LVP_OFF CFG_2 EQU _CPD_OFF & _WRT_ENABLE_OFF & _DEBUG_OFF & _CP_OFF __CONFIG CFG_1 & CFG_2 __IDLOCS 0100h ; version EXPAND_MACROS EXP_COND ; macro expansion modeEzután következnek a define-ok. Az első 4 kikommentezett a program teszteléséhez, szimulálásához kell. Segitságükel nem kell végigvárni a késleltetéseket, igy gyorsabb a munka.
Itt van továbbá definiálva a PIC órajele, ez fontos beállitani a pontos időzitésekhez.
Szintén itt vannak definiálva a portlábak. A program irása közben csak át kell irni a neveket egy beszédesebbre, es már folytathatjuk is a munkát. Pl ha a PORTA_0-ra egy LED-et kapcsolunk, akkor a PORTA_0-t irjuk át LED-re, és már használhatjuk is a bsf LED-et a LED bekapcsolására, és a bcf LED-et a LED kikapcsolására.;***** DEFINES ************************************************************ ;#define DEBUG ; for some debug message ;#define NO_DELAY ; for fast simulation ;#define NO_RS232 ; for fast simulation ;#define NO_EE24 xtal_freq EQU 4 MHz ; crystal frequency core_freq EQU xtal_freq/4 ; core operating frequency ; ----- porta ------------------------------------------------------------- #define PORTA_0 PORTA,0 ; free #define PORTA_1 PORTA,1 ; free #define PORTA_2 PORTA,2 ; free #define PORTA_3 PORTA,3 ; free #define PORTA_4 PORTA,4 ; free (open drain!) #define PORTA_5 PORTA,5 ; free ; ----- portb ------------------------------------------------------------- #define PORTB_0 PORTB,0 ; free #define PORTB_1 PORTB,1 ; free #define PORTB_2 PORTB,2 ; free #define PORTB_3 PORTB,3 ; free #define PORTB_4 PORTB,4 ; free #define PORTB_5 PORTB,5 ; free #define PORTB_6 PORTB,6 ; free #define PORTB_7 PORTB,7 ; free ; ----- portc ------------------------------------------------------------- #define PORTC_0 PORTC,0 ; free #define PORTC_1 PORTC,1 ; free #define PORTC_2 PORTC,2 ; free #define PORTC_3 PORTC,3 ; free #define PORTC_4 PORTC,4 ; free #define PORTC_5 PORTC,5 ; free #define PORTC_6 PORTC,6 ; free #define PORTC_7 PORTC,7 ; freeItt következnek a modulokhoz tartozó makrók:
;***** MACROS ************************************************************* include "..\..\modules\dummy.mac"Ezt követi konstansok definiálása:
;***** CONSTANT DEFINITIONS *********************************************** option_val EQU 00000010b ; Timer source : intclk / 8 trisa_val EQU 00111111b ; TRISA value (all input) trisb_val EQU 11111111b ; TRISB value (all input) trisc_val EQU 11111111b ; TRISC value (all input) adcon0_val EQU 00000000b ; ADCON0 value (AD off) adcon1_val EQU 00000110b ; ADCON1 value (add digital input) intcon_val EQU 00100000b ; Interrupt controlMajd a változóké. Ahogy fent már emlitettem az utolsó a Bank0-hoz tartozó cblock, hogy a modulokban definiált változók a Bank0-ba kerüljenek.
;***** VARIABLE DEFINITIONS *********************************************** cblock 70h ; common RAM icd_temp ; reserved for ICD w_temp ; variable used for context saving status_temp ; variable used for context saving fsr_temp ; variable used for context saving endc ;-------------------------------------------------------------------------- cblock 0BBh icd_temp2:5 ; reserved for ICD endc ;-------------------------------------------------------------------------- cblock 20h TEMP ; dummy register endcItt kezdödik végre ténylegesen a program vágrehajtása. (0000-ás cim) Ahonnan rögtön el is ugrunk a IT rutin utánni szabad cimre.
;***** ENTRY POINT ******************************************************** ORG 000h ; processor reset vector nop clrwdt clrf STATUS goto startItt pedig a megszakitás kezelőt találjuk. Jelenleg a regiszterek mentésén kivül nem tartalmaz semmit. Figyelem nem tudni, hogy az IT bekövetkezésekor melyik file regiszter bank van kiválaszta, ezért ha file regisztereket akarunk elérni az IT rutinból akkor mindig váltsunk először a megfelelő bankra. A visszaváltás a STATUS visszaállitásával autómatikusan megtörténik.
;***** IT HANDLER ********************************************************* ;* Interrupt handler ;* <comment> ;************************************************************************** ORG 004h ; interrupt vector location movwf w_temp ; save off current W register contents swapf STATUS,w ; move STATUS register into W register movwf status_temp ; save off contents of STATUS register movf FSR,w ; save FSR movwf fsr_temp ;-------------------------------------------------------------------------- clrf STATUS ; bank 0 ;;-------------------------------------------------------------------------- movf fsr_temp,w ; restore FSR movwf FSR swapf status_temp,w ; retrieve copy of STATUS register movwf STATUS ; restore pre-isr STATUS register contents swapf w_temp,f swapf w_temp,w ; restore pre-isr W register contents retfie ; return from interrupt Itt már tényleg a főprogramunk kezdödik, ahol az elején megtörténnek az inicializálások. Többek között AD kikapcsolása és az IT tiltása is. Az AD (vagy egyes tipusoknál a komparátor) kikapcsolása fontos, mert a PORT_A lábai defaultban analog bemenetek. Ezt követöen tehetjük meg a saját inicializálásainkat, és felhivhatjuk a modulok INIT-jeit.
;***** REAL PROGRAM START ************************************************* start ;----- set configuration -------------------------------------------------- clrf PORTA ; clear latch clrf PORTB ; clear latch clrf PORTC ; clear latch bank1 movlw option_val movwf LL OPTION_REG ; set OPTION_REG movlw trisa_val movwf LL TRISA ; set TRISA movlw trisb_val movwf LL TRISB ; set TRISB movlw trisc_val movwf LL TRISC ; set TRISC movlw adcon1_val movwf LL ADCON1 ; set ADCON1 bank0 movlw adcon0_val movwf ADCON0 ; set ADCON0 movlw intcon_val movwf INTCON ; set INTCONIde jön a mag. A saját főprogram. Ez általában egy ciklus lesz.
;----- main cycle -------------------------------------------------------- main_cycle nop ;goto main_cycle
Itt egy szubrutin sablon található. Ezt lemásolva és kitöltve készithetünk saját függvényket.
;***** SUB1 *************************************************************** ;* ;* Input : ; ;* Output: ; ;* Clock : ;************************************************************************** sub1 returnItt pedig a modulok függvényeit szippantjuk be.
;***** INCLUDES *********************************************************** include "..\..\modules\dummy.inc" ;************************************************************************** end ; end of programÉs itt a vége.