Por las dudas quiero aclarar primero mi posicion: El lenguaje de
programacion general para microcontroladores
debe ser C.
Pero C como herramienta general, no como
unica herramienta. Porque ese parece ser el punto donde gira esta discusion bizantina:
Usar "Un solo libro".
Una persona puede programar en C o en Basic si prefiere, pero
debe tener tambien un profundo conocimiento de Assembler.
Por que? --> Porque solo conociendo bien Assembler vas a entender bien el hardware que dispones.
Y necesitas conocer los elementos que estas usando no solo para saber
como hacer, tambien para cuando no anda saber
que puede ser y
como solucionarlo.
------------------------------------------------------
Se habla de velocidad, "precision" y tamaño del codigo generado con los diferentes lenguajes. Hasta donde es cierto?
Para aclarar en este sentido lo mejor es usar un ejemplo con
PicBasicPro.
Esto esta sacado de los samples de PBP, es un "Hello world" con un LCD.
Código:
Pause 500 ' Wait for LCD to startup
loop:
Lcdout $fe, 1 ' Clear LCD screen
Lcdout "Hello" ' Display Hello
Pause 500 ' Wait .5 second
Lcdout $fe, 1 ' Clear LCD screen
Lcdout "World"
Pause 500 ' Wait .5 second
Goto loop ' Do it forever
Muy legible y elegante como era de esperar.
Hay que destacar que ahi,
los unicos elementos propios del lenguaje Basic son la etiqueta "loop:" y el "Goto".
Ahora vamos a ver que genera al compilar.
Primero se genera esto:
Código:
; PICBASIC PRO(TM) Compiler 2.47, (c) 1998, 2006 microEngineering Labs, Inc. All Rights Reserved.
_USED EQU 1
INCLUDE "C:\ARCHIV~1\MCS\PBP247\16F628.INC"
RAM_START EQU 00020h
RAM_END EQU 0014Fh
RAM_BANKS EQU 00003h
BANK0_START EQU 00020h
BANK0_END EQU 0007Fh
BANK1_START EQU 000A0h
BANK1_END EQU 000EFh
BANK2_START EQU 00120h
BANK2_END EQU 0014Fh
EEPROM_START EQU 02100h
EEPROM_END EQU 0217Fh
R0 EQU RAM_START + 000h
R1 EQU RAM_START + 002h
R2 EQU RAM_START + 004h
R3 EQU RAM_START + 006h
R4 EQU RAM_START + 008h
R5 EQU RAM_START + 00Ah
R6 EQU RAM_START + 00Ch
R7 EQU RAM_START + 00Eh
R8 EQU RAM_START + 010h
FLAGS EQU RAM_START + 012h
GOP EQU RAM_START + 013h
RM1 EQU RAM_START + 014h
RM2 EQU RAM_START + 015h
RR1 EQU RAM_START + 016h
RR2 EQU RAM_START + 017h
_PORTL EQU PORTB
_PORTH EQU PORTA
_TRISL EQU TRISB
_TRISH EQU TRISA
INCLUDE "LCD.MAC"
INCLUDE "C:\ARCHIV~1\MCS\PBP247\PBPPIC14.LIB"
PAUSE?C 001F4h
LABEL?L _loop
LCDOUT?C 0FEh
LCDOUT?C 001h
LCDOUT?C 048h
LCDOUT?C 065h
LCDOUT?C 06Ch
LCDOUT?C 06Ch
LCDOUT?C 06Fh
PAUSE?C 001F4h
LCDOUT?C 0FEh
LCDOUT?C 001h
LCDOUT?C 057h
LCDOUT?C 06Fh
LCDOUT?C 072h
LCDOUT?C 06Ch
LCDOUT?C 064h
PAUSE?C 001F4h
GOTO?L _loop
END
Ha generado un programa en Assembler con una serie de directivas y declaraciones antes de nuestro codigo.
Si miramos la parte correspondiente al codigo original, el compilador ha expandido la instruccion Lcdout "Hello" en una serie de macros.
La definicion de estos macros esta en LCD.MAC y su expansion llama a una rutina
escrita en Assembler que se encuentra en la libreria PBPPIC14.LIB
Al compilarse este archivo ASM (lo podriamos hacer "a mano" con MPASM), los macros son expandidos y ejecutados generando esto:
Código:
MOVLW 0x1 ; PAUSE?C 001F4h
MOVWF 0x23
MOVLW 0xf4
CALL 0x53
;
; LABEL?L _loop
MOVLW 0xfe ; LCDOUT?C 0FEh
CALL 0x2
MOVLW 0x1 ; LCDOUT?C 001h
CALL 0x2
MOVLW 0x48 ; LCDOUT?C 048h
CALL 0x2
MOVLW 0x65 ; LCDOUT?C 065h
CALL 0x2
MOVLW 0x6c ; LCDOUT?C 06Ch
CALL 0x2
MOVLW 0x6c ; LCDOUT?C 06Ch
CALL 0x2
MOVLW 0x6f ; LCDOUT?C 06Fh
CALL 0x2
MOVLW 0x1 ; PAUSE?C 001F4h
MOVWF 0x23
MOVLW 0xf4
CALL 0x53
MOVLW 0xfe ; LCDOUT?C 0FEh
CALL 0x2
MOVLW 0x1 ; LCDOUT?C 001h
CALL 0x2
MOVLW 0x57 ; LCDOUT?C 057h
CALL 0x2
MOVLW 0x6f ; LCDOUT?C 06Fh
CALL 0x2
MOVLW 0x72 ; LCDOUT?C 072h
CALL 0x2
MOVLW 0x6c ; LCDOUT?C 06Ch
CALL 0x2
MOVLW 0x64 ; LCDOUT?C 064h
CALL 0x2
MOVLW 0x1 ; PAUSE?C 001F4h
MOVWF 0x23
MOVLW 0xf4
CALL 0x53
GOTO 0x7d ; GOTO?L _loop
Donde cualquiera que entienda un poco de Assembler se dara cuenta que ese codigo
es inobjetable, es lo mismo que habria escrito cualquier programador. Con la gran ventaja que PBP se encargo de escribir toda la parte "molesta" por nosotros y
tanto PAUSE (0x53) como LCDOUT (0x2) vienen enlatadas escritas en Assembler ( son igual de optimas y estan antes en ese listado, pero no las puse para que no se haga tan largo).
De mas esta decir que este es un ejemplo particular. El proceso de generacion de codigo ejecutable
tiene muchas mas opciones.
Con un ejemplo en C seria bastante "parecido", solamente que en general se van a necesitar mas declaraciones y que en C no se hace una traduccion tan "literal" del codigo que hemos escrito sino que puede sufrir modificaciones de acuerdo al nivel de optimizacion, generando un codigo superior cuando se trata de sentencias complejas.
Donde esta el problema con los lenguajes de alto nivel? Si de
lo que hemos escrito genera un codigo impecable?
--> Pues el "problema" esta en lo que
no hemos escrito.
Lo que no hemos escrito son precisamente las
rutinas de libreria, y esas son las responsables del tamaño del programa y la velocidad (suponiendo que uno no esta usando algoritmos horribles )
En general, estas rutinas
estan muy bien escritas. Y si dan problemas, es
cuando son demasiado generales y pierden tiempo+bytes analizando diferentes condiciones cuando tenemos solo una.
Otra causa puede ser la "precision de Thenot", si se necesitan tiempos exactos y la libreria no fue escrita pensando en eso --> No way.
Ahi es donde uno tiene que "customizar" su entorno de trabajo. Es decir, escribir macros y rutinas propias a gusto y necesidad.
Pero estos "tuneos" no hay que hacerlos necesariamente en Assembler y mucho menos escribir
el programa entero (señal de muuucho tiempo libre
)
Dependiendo del nivel de la rutina,
el Basic resulta insuficiente porque los tipos de variable y modos de direccionamiento son limitados (no maneja punteros, no se puede forzar el tipo de variable, no hay puntero a funcion...).
En consecuencia, para una rutina de bajo nivel, Basic casi siempre terminara llamando una rutina escrita originalmente en otro lenguaje (en el caso de PBP es en Assembler) -->
Esto no pasa en C, salvo por algunas instrucciones muy particulares (Murphy no falla) se puede escribir un sistema operativo completo sin necesidad de Assembler.
En esto ultimo ya entran los gustos personales --> Yo por ejemplo uso C, pero en los puntos donde no me gusta lo generado o se me cantan las b*l*s le inserto un bloque en Assembler.
Conclusion: Cuanto mas alto el nivel del lenguaje mas comodo laburas, pero mas limitado estas ==> Si el tema realmente te interesa
debes manejar bien tambien Assembler y C.