[Risolto]PIC16F84A: codice in assembly va, in C no

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Avatar utente
ubuntumate
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1180
Iscrizione: giovedì 28 maggio 2015, 18:18
Distribuzione: Windows 7
Sesso: Maschile
Località: Milano

[Risolto]PIC16F84A: codice in assembly va, in C no

Messaggio da ubuntumate »

Ho scritto un banalissimo programmino in Assembly per PIC16F84A che fa lampeggiare tutti i LED collegati a PORTB. Poi ho scritto lo stesso programma in C e l'ho compilato per vedere le differenze tra il codice Assembly scritto da me e quello prodotto da XC8. Infine ho provato entrambi gli eseguibili su PicSimLab, una sorta di simulatore molto limitato e ho notato che il codice prodotto da me funziona, quello generato dal compilatore no. Devo dire che il simulatore non dispone del PIC16F84A, ma del 16F628A che comunque dovrebbe avere lo stesso set di istruzioni. Ho comunque testato il programma scritto con il simulatore di MPLAB X (per il momento di free che sia meglio di questa IDE non c'è nulla) e sembra funzionare.

Ora ci sono 4 possibilità:
- ho sbagliato io a scrivere il programma in C
- XC8 fa schifo
- il simulatore fa schifo
- una combinazione delle opzioni precedenti
Versione in Assembly

Codice: Seleziona tutto

PROCESSOR       p16f84a
    RADIX       dec
    INCLUDE     "p16f84a.inc"
    __CONFIG    0xFFF9
    
    ORG     0
    goto    SETUP
    
    ORG     4
    
    SETUP
    bsf     STATUS,RP0  ; banco 1;
    clrf    TMR0        ; azzera il timer
    clrf    TRISA       ; tutte uscite PORTA
    clrf    TRISB       ; tutte uscite PORTB
    movlw   0x07        ; configurazione OPTION_REG
    movwf   OPTION_REG  ; """""""""""""""""""""""""
    bcf     STATUS,RP0  ; banco 0
    clrf    PORTA       ; PORTA tutta a 0
    goto    MAIN
    MAIN
    movlw   0xFF        ; sposta 255 in W
    movwf   PORTB       ; PORTB = 255
    call    DELAY_50_MS ; ritardo di 50 ms
    call    DELAY_50_MS ; ritardo di 50 ms
    call    DELAY_50_MS ; ritardo di 50 ms
    call    DELAY_50_MS ; ritardo di 50 ms
    movlw   0x00        ; sposta 0 in W
    movwf   PORTB       ; PORTB = 0
    call    DELAY_50_MS ; ritardo di 50 ms
    call    DELAY_50_MS ; ritardo di 50 ms
    call    DELAY_50_MS ; ritardo di 50 ms
    call    DELAY_50_MS ; ritardo di 50 ms
    goto    MAIN
        
    DELAY_50_MS
    bcf     INTCON,T0IF ; bit overflow timer azzerato
    movlw   0x3D        ; sposta 61 in W
    movwf   TMR0        ; TMR0 = 61
    btfss   INTCON,T0IF ; se avviene interrupt salta istr. successiva
    goto    $-1         ; salta indietro di un'istruzione
    return
     
END
Versione in C

Codice: Seleziona tutto

#include <xc.h>
#define _XTAL_FREQ (4000000U)

void main(void)
{
    TRISA = 0x00;
    TRISB = 0x00;
    
    PORTA = 0x00;
    PORTB = 0x00;
    
    while(1)
    {
        PORTB = 0xFF;
        __delay_ms(200);
        PORTB = 0x00;
        __delay_ms(200);

    }
}
e relativo listato prodotto da XC8

Codice: Seleziona tutto



Microchip Technology PIC LITE Macro Assembler V1.37 build -260352376 
                                                                                               Sun May 29 15:42:15 2016

Microchip Technology Omniscient Code Generator v1.37 (Free mode) build 201603110536
     1                              processor   16F84A
     2                              opt pw 120
     3                              opt lm
     4                              psect   cinit,global,class=CODE,merge=1,delta=2
     5                              psect   cstackBANK0,global,class=BANK0,space=1,delta=1
     6                              psect   maintext,global,class=CODE,split=1,delta=2
     7                              dabs    1,0x4E,2
     8  0000                        ;# 
     9  0001                        ;# 
    10  0002                        ;# 
    11  0003                        ;# 
    12  0004                        ;# 
    13  0005                        ;# 
    14  0006                        ;# 
    15  0008                        ;# 
    16  0009                        ;# 
    17  000A                        ;# 
    18  000B                        ;# 
    19  0081                        ;# 
    20  0085                        ;# 
    21  0086                        ;# 
    22  0088                        ;# 
    23  0089                        ;# 
    24  0005                     _PORTA set 5
    25  0006                     _PORTB set 6
    26  0085                     _TRISA set 133
    27  0086                     _TRISB set 134
    28                           
    29                           ; #config settings
    30  0000                     
    31                              psect   cinit
    32  03FE                     start_initialization:  
    33  03FE                     __initialization:  
    34  03FE                     end_of_initialization: 
    35                           ;End of C runtime variable initialization code
    36                           
    37  03FE                     __end_of__initialization:  
    38  03FE  0183                  clrf    3
    39  03FF  2BD8                  ljmp    _main   ;jump to C main() function
    40                           
    41                              psect   cstackBANK0
    42  000C                     __pcstackBANK0:    
    43  000C                     ?_main:    
    44  000C                     ??_main:   
    45                           ; 1 bytes @ 0x0
    46                           
    47                           
    48                           ; 1 bytes @ 0x0
    49  000C                        ds  3
    50                           
    51                              psect   maintext
    52  03D8                     __pmaintext:   
    53 ;;
    54 ;;Main: autosize = 0, tempsize = 3, incstack = 0, save=0
    55 ;;
    56 ;; *************** function _main *****************
    57 ;; Defined at:
    58 ;;       line 9 in file "hello_blink.c"
    59 ;; Parameters:    Size  Location     Type
    60 ;;       None
    61 ;; Auto vars:     Size  Location     Type
    62 ;;       None
    63 ;; Return value:  Size  Location     Type
    64 ;;                  1    wreg      void 
    65 ;; Registers used:
    66 ;;       wreg, status,2
    67 ;; Tracked objects:
    68 ;;       On entry : B00/0
    69 ;;       On exit  : 0/0
    70 ;;       Unchanged: 0/0
    71 ;; Data sizes:     COMMON   BANK0
    72 ;;      Params:         0       0
    73 ;;      Locals:         0       0
    74 ;;      Temps:          0       3
    75 ;;      Totals:         0       3
    76 ;;Total ram usage:        3 bytes
    77 ;; This function calls:
    78 ;;       Nothing
    79 ;; This function is called by:
    80 ;;       Startup code after reset
    81 ;; This function uses a non-reentrant model
    82 ;;
    83                           
    84                           
    85                           ;psect for function _main
    86  03D8                     _main: 
    87                           
    88                           ;hello_blink.c: 11: TRISA = 0x00;
    89                           
    90                           ;incstack = 0
    91                           ; Regs used in _main: [wreg+status,2]
    92  03D8  1683                  bsf 3,5 ;RP0=1, select bank1
    93  03D9  0185                  clrf    5   ;volatile
    94                           
    95                           ;hello_blink.c: 12: TRISB = 0x00;
    96  03DA  0186                  clrf    6   ;volatile
    97                           
    98                           ;hello_blink.c: 14: PORTA = 0x00;
    99  03DB  1283                  bcf 3,5 ;RP0=0, select bank0
   100  03DC  0185                  clrf    5   ;volatile
   101                           
   102                           ;hello_blink.c: 15: PORTB = 0x00;
   103  03DD  0186                  clrf    6   ;volatile
   104  03DE                     l486:  
   105                           ;hello_blink.c: 17: while(1)
   106                           
   107                           
   108                           ;hello_blink.c: 18: {
   109                           ;hello_blink.c: 19: PORTB = 0xFF;
   110  03DE  30FF                  movlw   255
   111  03DF  1283                  bcf 3,5 ;RP0=0, select bank0
   112  03E0  0086                  movwf   6   ;volatile
   113                           
   114                           ;hello_blink.c: 20: _delay((unsigned long)((200)*((4000000U)/4000.0)));
   115  03E1  3002                  movlw   2
   116  03E2  008E                  movwf   ??_main+2
   117  03E3  3004                  movlw   4
   118  03E4  008D                  movwf   ??_main+1
   119  03E5  30BA                  movlw   186
   120  03E6  008C                  movwf   ??_main
   121  03E7                     u17:   
   122  03E7  0B8C                  decfsz  ??_main,f
   123  03E8  2BE7                  goto    u17
   124  03E9  0B8D                  decfsz  ??_main+1,f
   125  03EA  2BE7                  goto    u17
   126  03EB  0B8E                  decfsz  ??_main+2,f
   127  03EC  2BE7                  goto    u17
   128  03ED  0000                  nop
   129                           
   130                           ;hello_blink.c: 21: PORTB = 0x00;
   131  03EE  1283                  bcf 3,5 ;RP0=0, select bank0
   132  03EF  0186                  clrf    6   ;volatile
   133                           
   134                           ;hello_blink.c: 22: _delay((unsigned long)((200)*((4000000U)/4000.0)));
   135  03F0  3002                  movlw   2
   136  03F1  008E                  movwf   ??_main+2
   137  03F2  3004                  movlw   4
   138  03F3  008D                  movwf   ??_main+1
   139  03F4  30BA                  movlw   186
   140  03F5  008C                  movwf   ??_main
   141  03F6                     u27:   
   142  03F6  0B8C                  decfsz  ??_main,f
   143  03F7  2BF6                  goto    u27
   144  03F8  0B8D                  decfsz  ??_main+1,f
   145  03F9  2BF6                  goto    u27
   146  03FA  0B8E                  decfsz  ??_main+2,f
   147  03FB  2BF6                  goto    u27
   148  03FC  0000                  nop
   149  03FD  2BDE                  goto    l486
   150  03FE                     __end_of_main: 
   151  004E                     btemp  set 78  ;btemp
   152  004E                     wtemp  set 78
   153  004E                     wtemp0 set 78
   154  0050                     wtemp1 set 80
   155  0052                     wtemp2 set 82
   156  0054                     wtemp3 set 84
   157  0056                     wtemp4 set 86
   158  0058                     wtemp5 set 88
   159  004F                     wtemp6 set 79
   160  004E                     ttemp  set 78
   161  004E                     ttemp0 set 78
   162  0051                     ttemp1 set 81
   163  0054                     ttemp2 set 84
   164  0057                     ttemp3 set 87
   165  004F                     ttemp4 set 79
   166  004E                     ltemp  set 78
   167  004E                     ltemp0 set 78
   168  0052                     ltemp1 set 82
   169  0056                     ltemp2 set 86
   170  0050                     ltemp3 set 80
Qual è la causa?
Ultima modifica di ubuntumate il lunedì 30 maggio 2016, 12:04, modificato 1 volta in totale.
Software engineers shall participate in lifelong learning regarding the practice of their profession and shall promote an ethical approach to the practice of the profession.
ACM/IEEE Code of ethics.
Avatar utente
M_A_W_ 1968
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 856
Iscrizione: venerdì 15 febbraio 2013, 3:57
Desktop: KDE
Distribuzione: SuSE
Sesso: Maschile
Località: Un luogo geometrico
Contatti:

Re: PIC16F84A: codice in assembly va, in C no

Messaggio da M_A_W_ 1968 »

Un Vero Programmatore usa lo XOR con 0xFF per invertire ad ogni iterazione lo stato dell'intero port, potando alla radice una inutile duplicazione di codice.

Al di là di questo, credo di aver ripetuto almeno due o tre catacurbitioni (potenza disneyana del dieci con una sessantaquattrina di zeri, più o meno...) di volte che per chi inizia è estremamente importante usare strumenti e ambienti di lavoro affidabili, possibilmente anche certificati. L'ultima cosa da fare è affidarsi ad un accrocco amatoriale, scritto nel tempo libero da qualche dilettante che in definitiva ne sa meno di te: il rischio è quello di prendere fischi per fiaschi, rincorrendo ectoplasmi d'errore dovuti semplicemente all'incapacità, all'imperizia e alla negligenza di chi non capisce la differenza tra "basta che funzioni" e software engineering.

Il simulatore di MPLab, per quanto ben lontano dalle vette eccelse dei sistemi di sviluppo professionali per MCU e SoC più seri, è comunque un aggeggio decorosamente funzionale e ampiamente documentato (una volta su carta, oggi in PDF). Concentrati su quello, e più non dimandar... :lol:
Sì, un blog ce l'ho perfino io: gli è che mi manca il tempo...

"...in una società che sembra sempre più spaventata dai problemi troppo articolati e che rigetta come un corpo estraneo ogni elemento di complessità, sapremo ancora come utilizzare il parere degli esperti?"
Avatar utente
ubuntumate
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1180
Iscrizione: giovedì 28 maggio 2015, 18:18
Distribuzione: Windows 7
Sesso: Maschile
Località: Milano

Re: PIC16F84A: codice in assembly va, in C no

Messaggio da ubuntumate »

Pensare di fare lo XOR con 0xFF è un po' come scoprire le LUT: entrambi i trucchetti si basano su concetti banali, ma nessuno ci arriva autonomamente e io non faccio eccezione.

A questo punto direi che posso porre fine alle ricerche ad un'alternativa a MPLAB X. Di certo PicSimLab per definizione non potrà essere migliore del simulatore realizzato da Microchip pertanto mi terrò questa IDE con l'effetto collaterale di non dovermi più preoccupare di poter usare MPASM come modulo a parte. Avendo poi controllato il listato generato da XC8 e non avendo trovato nulla di strano, le possibilità in realtà si riducevano ad un mio errore e/o ad un (o più) bug del software amatoriale, però trattandosi dei primissimi tentativi di leggere listati prodotti dal compilatore, ho messo in discussione XC8 anche se improbabile che ci siano problemi così gravi perché immagino ci sia dietro un sano lavoro di engineering anche per i tool di sviluppo per studenti.
Per quanto riguarda la documentazione reperibile sul sito della Microchip non c'è nulla da dire, hanno documentato tutto. Se continuano così finiranno per documentare anche quanto defecano i loro dipendenti :rotfl:
EDIT: dimenticavo...cosa sarebbe ??_main?
Software engineers shall participate in lifelong learning regarding the practice of their profession and shall promote an ethical approach to the practice of the profession.
ACM/IEEE Code of ethics.
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 15 ospiti