Sida 1 av 1

ASM/C för EEPROM-modulen i PIC16F628A

Postat: 4 mars 2008, 12:51:12
av bos
Det är såhär att jag hade aldrig använt EEPROM-modulen i någon PIC-krets, så igår satte jag mig ner för att läsa databladet hur man använder den. Även om jag just nu inte har något större behov av den så vet man aldrig vad som händer i framtiden, och då kan det kanske vara bra att ha pillat lite.

Jag kopplade upp en 628A på brödplattan, kopplade in två switchar ("load" och "save"), en 3-DIP-switch och tre lysdioder. Med DIP-switchen ställer jag in talet 0-7, med save-switchen sparar jag detta värde på EEPROM-adress 0, och med "load"-switchen hämtas värdet och skickas till lysdioderna.

Med andra ord ett totalt meningslöst bygge, men det duger för laboration.

Koden blev den här:

Kod: Markera allt

    	#include	<p16f628a.inc>
        errorlevel  -302

        __config   _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_ON & _WDT_OFF & _PWRTE_OFF & _INTOSC_OSC_NOCLKOUT

reset_v code    0x0
        goto    start

main    code
start

        banksel OPTION_REG
        clrf    OPTION_REG                      ; Enable pullups on PORTB
        clrf    VRCON                           ; Disable VRef-module
        clrf    EECON1
        clrf    INTCON                          ; Disable interrupts
        movlw   b'11010000'                     ; PORTA - 4: DIP0, 7: DIP1, 6: DIP2
        movwf   TRISA
        movlw   b'00011000'                     ; PORTB - 0-2: LEDs
        movwf   TRISB                           ; 3: Load (switch), 4: Save (switch)
 
        banksel CMCON
        movlw   7
        movwf   CMCON                           ; Disable comparators
        clrf    PORTA                           ; Clear ports from junk
        clrf    PORTB

loop
        btfss   PORTB, 3
         goto   load_from_eeprom
        btfss   PORTB, 4
         goto   save_to_eeprom
        goto    loop


load_from_eeprom
        banksel EEADR
        clrf    EEADR                           ; Address to read
        bsf     EECON1, RD                      ; Initiate EEPROM-read
        movfw   EEDATA

        banksel PORTB
        movwf   PORTB
debounce_rb3
        btfss   PORTB, 3
         goto   debounce_rb3
        goto    loop

save_to_eeprom
        clrw                                    ; W contains EEPROM-data to be written

        ; Fetch the status of the DIP-switch
        btfsc   PORTA, 4                        ; RA4 - DIP0, RA7 - DIP1, RA6 - DIP2
         iorlw  1                               ; W = xxxxxxx1
        btfsc   PORTA, 7
         iorlw  2                               ; W = xxxxxx1x
        btfsc   PORTA, 6
         iorlw  4                               ; W = xxxxx1xx

        banksel EECON1
        movwf   EEDATA                          ; Store the data to save
        bsf     EECON1, WREN                    ; Write enable

        movlw   h'55'                           ; Write unlock sequence
        movwf   EECON2
        movlw   h'AA'
        movwf   EECON2
        bsf     EECON1, WR                      ; Write!
        bcf     EECON1, WREN                    ; Disable write enable

        banksel PORTB
        clrf    PORTB
debounce_rb4
        btfss   PORTB, 4
         goto   debounce_rb4
        goto    loop

        end
"Memory gauge" i MPLAB rapporterar "59 bytes program memory, 0 bytes data memory". Det senare eftersom jag optimerade bort variabelanvändningarna ganska hårt, för att få ner kodstorleken.

Sen råkade det bli så att jag laddade ner en utvärderingsversion av Hi-Tech PIC C-compiler (www.htsoft.com) och fick för mig att testa C-programmering. PIC-assembler har jag programmerat i över ett år nu, och vågar påstå att jag kan det rätt bra. Därför när jag ändå hade ett sånt här litet projekt igång så var det lika bra att prova vidare.

C-koden för samma projekt blev den här:

Kod: Markera allt

#include <htc.h>
#include <pic16f62xa.h>

__CONFIG(UNPROTECT & LVPDIS & BORDIS & MCLREN & WDTDIS & PWRTDIS & INTIO);

#define bitset(var,bitno) ((var) |= 1UL << (bitno))

void main() {
    OPTION = 0;
    VRCON = 0;
    EECON1 = 0;
    TRISA = 0b11010100;
    TRISB = 0b00011000;
    CMCON = 0x7;
    INTCON = 0;
    PORTA = 0;
    PORTB = 0;    

    while (1) {
        if (!(RB3)) {
            PORTB = eeprom_read(0);
            while (!(RB3)) { /* Debounce switch */ }
        }
        if (!(RB4)) {
            unsigned char data = 0;
            if (RA4) bitset(data, 0); 
            if (RA7) bitset(data, 1);
            if (RA6) bitset(data, 2);

            eeprom_write(0, data);
            PORTB = 0;
            while (!(RB4)) { /* Debounce switch */ }
        }        
    }
}
En viss skillnad i storlek, och löjligt bekvämt med eeprom_read/write. Man går ju förstås om miste om "one-to-one-relationship" i sin kod jämfört med maskinkoden. Memory gauge för C-koden rapporterade "88 bytes program memory, 5 bytes data memory", så lite större blev det allt (vilket iofs var väntat).

Slutsatsen för mig blir att C är trevligt även för PIC-processorer. Enda trista är att PICC är så sablans dyr, annars hade jag gärna införskaffat en licens.

Postat: 4 mars 2008, 13:09:12
av sodjan
> och löjligt bekvämt med eeprom_read/write.

Det är bara att göra en egen. Man måste ju inte skriva ASM
koden så som du har gjort.

Kod: Markera allt

eprom_write macro addr
    movlw   addr
    movwf   eprom_addr
    call    eprom_do_write
    endm
...
...
...

; Fetch the status of the DIP-switch
        btfsc   PORTA, 4                        ; RA4 - DIP0, RA7 - DIP1, RA6 - DIP2
         iorlw  1                               ; W = xxxxxxx1
        btfsc   PORTA, 7
         iorlw  2                               ; W = xxxxxx1x
        btfsc   PORTA, 6
         iorlw  4                               ; W = xxxxx1xx

        banksel EECON1
        movwf   EEDATA                          ; Store the data to save

        eprom_write 0

        banksel PORTB
        clrf    PORTB
...
...
...

eprom_do_write

        bsf     EECON1, WREN                    ; Write enable

        movlw   h'55'                           ; Write unlock sequence
        movwf   EECON2
        movlw   h'AA'
        movwf   EECON2
        bsf     EECON1, WR                      ; Write!
        bcf     EECON1, WREN                    ; Disable write enable
        return

Ungefär. Plus ev banking o.s.v...

Postat: 4 mars 2008, 13:37:08
av bos
Självfallet går det att skriva eget. Min kod var inte på nåt sätt det enda rätta, den är som du visar t.ex inte särskilt modulär eller skalbar.

Ett stort minus i PICC är att config-bitarna inte har samma namn som Microchips i MPASM, och det gör att man måste läsa header-filerna en extra gång istället för att kunna ta dem direkt från ryggmärgen. Är väl iofs en bagatell egentligen, men det känns dumt att ha två uppsättningar med namn på något som åsyftar exakt samma sak.

Re: ASM/C för EEPROM-modulen i PIC16F628A

Postat: 4 mars 2008, 13:51:49
av TomasL
bos skrev:Slutsatsen för mig blir att C är trevligt även för PIC-processorer. Enda trista är att PICC är så sablans dyr, annars hade jag gärna införskaffat en licens.
Köp WIZ-C, så får du en ANSI-kompatibel kompilator som är minst lika bra som PICC.
Kostar beroende på version, mellan helt gratis och ca tusenlappen

Postat: 4 mars 2008, 14:14:42
av bos
Känner igen namnet. Var det den kompilatorn som kom med en egen IDE och inte gick att integrera med MPLAB? Om det är det så har jag testkört programmet, och det var inget för mig. Gränssnittet var hur hjärndött som helst, med massa onödiga fönster som inte gick att stänga ner utan var absolut tvunget att ha framme.

Postat: 4 mars 2008, 14:39:24
av TomasL
Jo det har en egen IDE, och det är förvisso så att det inte går att köra i MPLAB, men å andra sidan finns det ingen orsak till att använda MPLAB, då WIZ-C ide'n är betydligt bättre.

Beträffande fönstren så tror jag det var så för en massa versioner sedan, jag känner ialla fall inte till det problemet (använder det sedan nån gång 2003)

Fördelen med en grafisk simulator som dessutom emulerar kringutrustning är en sak som sparar mängder med tid. (Nu har väl andra som Hitec mfl börjat härma Wiz-C på detta har jag för mig) men fortfarande slår priset (och en mycket bra support) i stort sett allting jag sett.

EN annan tidsbesparande grej är när man använder ICD så följer debuggern både C-Koden och den genererade ASM-Filen.

Postat: 4 mars 2008, 15:17:07
av sodjan
> den är som du visar t.ex inte särskilt modulär eller skalbar.

Jag är inte helt med på vad som är problemet. Men å andra sidan
så kan ett 3-minuters hack inte bli hur bra som helst.