¿Cómo puede alguien usar un microcontrolador que tiene solo 384 bytes de memoria de programa?

67

Por ejemplo un PIC10F200T

Prácticamente cualquier código que escriba será más grande que eso, a menos que sea un chip de propósito único. ¿Hay alguna forma de cargar más memoria de programa desde un almacenamiento externo o algo así? Solo tengo curiosidad, no veo cómo esto podría ser muy útil ... pero debe serlo.

codificador543
fuente
66
Hay muchas aplicaciones para pequeños microcontroladores, desde generadores de señal de propósito especial, hasta convertidores de protocolo, hasta "nodos" en un sistema de control más grande, etc., etc.,
Dave Tweed
13
Bueno, un programa de juego de ajedrez toma 672 bytes, así que eso no es bueno. en.wikipedia.org/wiki/1K_ZX_Chess
John Burton
8
Estos son algunos ejemplos de lo que se puede hacer con pequeños programas (menos de 256 bytes).
hammar
9
¿Qué quieres decir con "a menos que sea un chip de un solo propósito"? La mayoría de los sistemas integrados tienen un solo propósito.
Jeanne Pindar
66
De vuelta en la universidad, construí un programa de semáforo completamente funcional para una computadora 8085/8155 (máximo 256 bytes) que ensamblé. Tenía botones para caminar y algunos sensores que simularían la presencia de un vehículo.
Zoredache

Respuestas:

133

¡Chicos, salgan de mi césped!

384 bytes es mucho espacio para crear algo bastante complejo en ensamblador.

Si revisas la historia de cuando las computadoras eran del tamaño de una habitación, encontrarás algunas hazañas de arte verdaderamente sorprendentes ejecutadas en <1k.

Por ejemplo, lea la historia clásica de Mel - Un programador real . Es cierto que esos tipos tenían 4096 palabras de memoria para jugar, los infieles decadentes.

También mire algunas de las viejas competencias de demoscene donde el desafío era encajar una "introducción" en el bloque de arranque de un disquete, los objetivos típicos son 4k o 40k y generalmente logran incluir música y animación.

Editar para agregar : Resulta que puedes implementar la primera calculadora científica de $ 100 del mundo en 320 palabras.

Editar para los jóvenes 'uns:

  • Disquete = disquete.
  • Bootblock = 1.er sector de la lectura del disquete en el arranque.
  • Demoscene = competencias de programación entre grupos de hackers.
  • Ensamblador = forma elegante de programar un dispositivo si eres demasiado blando para usar 8 interruptores de palanca y un botón "almacenar".
John U
fuente
44
La consola de juegos Atari 2600 tenía solo 4KB de almacenamiento en los cartuchos de juegos ROM (aunque algunos juegos superaron esta limitación al usar el cambio de banco para acceder a más de 4K).
Johnny
1
Hace eones hice un canto de pájaro bastante realista (lo suficiente como para que la gente buscara el pájaro en lugar de sospechar de la computadora), cuyas tripas (pero no el código aleatorio que evitó que emitiera exactamente el mismo sonido cada vez) se habrían sacudido en 384 bytes y tenía las restricciones adicionales de no escribir direcciones y un byte cero no estaba permitido en el binario.
Loren Pechtel
2
Necesito salir más, recordé esto desde el principio
John U
77
+1 para "La historia de Mel". Una de las mejores cosas que he leído toda la semana.
Justin ᚅᚔᚈᚄᚒᚔ
1
@JohnU: Los primeros juegos en el Atari 2600 fueron todos 2K. Muchos desarrolladores nunca diseñaron ningún juego que fuera más allá de 4K, porque a pesar de que los chips de 8K eran asequibles (y los carros de algunas compañías simplemente usaban la mitad de un chip de 4K) agregando el cambio de banco a una tarjeta usando un estándar (selección de chip bajo activo) chip aumentó el número de chips de soporte de uno a tres.
supercat
59

Los microcontroladores son lo suficientemente baratos como para que a menudo se usen para hacer cosas realmente simples que en años anteriores probablemente se habrían hecho con lógica discreta. Cosas realmente simples. Por ejemplo, uno podría desear que un dispositivo encienda una salida durante un segundo cada cinco segundos, más precisamente de lo que un temporizador 555 podría hacer.

  movwf OSCCON
mainLp:
  ; Set output low
  clrf  GPIO
  movlw 0xFE
  movwf TRIS
  clrwdt
  call  Wait1Sec
  clrwdt
  call  Wait1Sec
  clrwdt
  call  Wait1Sec
  clrwdt
  call  Wait1Sec
  ; Set output high
  bsf   GPIO,0
  clrwdt
  call  Wait1Sec
  goto  mainLp
Wait1Sec:
  movlw 6
  movwf count2
  movlw 23
  movwf count1
  movlw 17
  movwf count0
waitLp:
  decfsz count0
   goto   waitLp
  decfsz count1
   goto   waitLp
  decfsz count2
   goto   waitLp
  retlw  0

Esa sería una aplicación real, utilizable, en menos de 32 palabras (48 bytes) de espacio de código. Uno podría agregar fácilmente algunas opciones para que algunos pines de E / S controlen las opciones de temporización y aún tenga mucho espacio de sobra, pero incluso si todo el chip fuera precisamente lo que se muestra arriba, aún podría ser más barato y más fácil que cualquier otra alternativa usando discreto lógica. Por cierto, las clrwdtinstrucciones podrían trasladarse a la subrutina, pero hacerlo haría las cosas menos robustas. Tal como está escrito, incluso si una falla causa que la pila de la dirección de retorno se corrompa, el perro guardián no se alimentará hasta que la ejecución regrese al bucle principal. Si eso nunca sucede, el perro guardián reiniciará el chip después de un par de segundos.

Super gato
fuente
9
Honestamente, podría optimizar un poco su código, dando un mal ejemplo a los niños: ¿¿5 llamadas separadas a wait1sec ??? ¡Derrochador! ;)
John U
9
@JohnU: FYI, el código usa llamadas separadas porque si usaba un contador de cuenta a cero y el recuento fallaba, el ciclo podría ejecutarse 255 veces en lugar de cuatro, mientras alimentaba al perro guardián una vez por segundo. Si bien sería posible protegerse contra eso al verificar en cada bucle si el recuento estaba dentro del rango, el código para hacerlo termina siendo más complicado que cinco llamadas y cinco clrwdtinstrucciones. Esta no es la disposición de contador más segura posible a prueba de fallas, pero se da cierta consideración a los problemas de seguridad (por ejemplo, evitar clrwdtdentro de una subrutina).
supercat
10
@ coder543: en ausencia de cosas como el ruido de la fuente de alimentación, no mucho. Por otro lado, en partes sin un detector de oscurecimiento, es posible que ocurran todo tipo de locuras si el VDD cae a un nivel entre el voltaje mínimo de operación y tierra, y luego vuelve a la normalidad. En general, se debe tratar de garantizar que cualquier estado en el que se encuentre el dispositivo vuelva a la normalidad en un período de tiempo razonable. Los dos segundos más o menos para que el perro guardián pueda patear pueden ser inevitables, pero cuatro minutos para que un contador fallido llegue a cero podría ser un poco demasiado.
supercat
10
@ coder543, suceden más a menudo en una demostración importante de lo que quieres creer. Este tipo de pensamiento también es necesario cuando se construyen cosas profundamente incrustadas que no tienen medios para pedir ayuda o informar un error. O son inaccesibles (piense en el mar profundo o en el espacio exterior) incluso si se notó un error.
RBerteig
66
@JohnU: Lo noté, pero pensé que explicar por qué escribí el código tal como lo hice podría ser útil. Por cierto, también estaba tratando de mostrar que las pequeñas tareas pueden caber en un procesador pequeño, incluso si no están optimizadas de manera absolutamente perfecta.
supercat
26

"SOLO" 384 bytes?

En el pasado, tenía el trabajo de escribir un sistema operativo completo (solo) para una computadora especializada que servía a la industria de la gestión de buques, tuberías y refinerías. El primer producto de este tipo de la compañía se basó en 6800 y se estaba actualizando a 6809, y querían un nuevo sistema operativo junto con el 6809 para poder eliminar los costos de licencia del sistema operativo original. También aumentaron el tamaño de la rom de arranque a 64 bytes, en lugar de 32. Si recuerdo bien, ¡fue hace unos 33 años! - Convencí a los ingenieros de que me dieran 128 bytes para poder poner todos los controladores de dispositivo del sistema operativo en la rom y así hacer que todo el dispositivo sea más confiable y versátil. Esto incluyó:

  • Controlador de teclado con tecla antirrebote
  • Controlador de video
  • Controlador de unidad de disco y sistema de archivos rudimentario ("abloader format" de Motorola, IIRC), con capacidad incorporada para tratar la memoria "almacenada" como si fuera un espacio en disco realmente rápido.
  • Controlador de módem (obtuvieron el FSK al revés, por lo que estos módems solo hablaban entre sí)

Sí, todos estos fueron tan simples como se ve, y optimizados a mano para eliminar cada ciclo extraño, pero perfectamente reparables y confiables. Sí, calcé todo eso en los bytes disponibles; oh, TAMBIÉN configuró el manejo de interrupciones, las diversas pilas e inicialicé el sistema operativo en tiempo real / multitarea, solicité al usuario las opciones de arranque y reinicié el sistema.

¡Un amigo mío que todavía está afiliado a la compañía (su sucesor) me dijo hace unos años que mi código todavía está en servicio!

Puedes hacer MUCHO con 384 bytes ...

Richard T
fuente
2
dices rom de arranque y mencionas mover controladores a la rom de arranque ... esto me indica que había un medio de almacenamiento secundario disponible. En esta discusión, ya hemos determinado que no puede cargar el código del almacenamiento externo en este PIC.
coder543
55
@ coder543 Eso pierde el punto: ¡384 bytes es suficiente para hacer mucho! La pregunta original leer como una queja de que 384 no fue suficiente para hacer algo útil - que era más de lo que necesitaba - una gran cantidad más - para proporcionar todos los componentes fundamentales de un tiempo real, multi-tarea del sistema operativo ...
Richard T
17

Diseñé un sensor de humedad para plantas que rastrea la cantidad de agua que tiene la planta y parpadea un LED si la planta necesita agua. Puede hacer que el sensor aprenda el tipo de planta y, por lo tanto, cambie su configuración mientras se ejecuta. Detecta bajo voltaje en la batería. Me quedé sin flash y ram, pero pude escribir todo en código C para que este producto funcionara perfectamente.

Usé el pic10f que mencionas.


Aquí está el código que hice para mi sensor de agua de la planta. Utilicé el pic10f220 ya que tiene un módulo ADC, tiene la misma memoria que el pic10f200, intentaré encontrar el Esquema mañana.

El código está en español, pero es muy simple y debe entenderse fácilmente. Cuando el Pic10F se activa desde el modo de suspensión, se reiniciará, por lo que debe verificar si fue un PowerUp o un reinicio y actuar en consecuencia. La configuración de la planta se mantiene en ram ya que nunca se apaga realmente.

C PRINCIPAL

/*
Author: woziX (AML)

Feel free to use the code as you wish. 
*/

#include "main.h"

void main(void) 
{  
    unsigned char Humedad_Ref;
    unsigned char Ciclos;
    unsigned char Bateria_Baja;
    unsigned char Humedad_Ref_Bkp;

    OSCCAL &= 0xfe;             //Solo borramos el primer bit
    WDT_POST64();                   //1s
    ADCON0 = 0b01000000;
    LEDOFF();
    TRIS_LEDOFF(); 

    for(;;) 
    {  
        //Se checa si es la primera vez que arranca
        if(FIRST_RUN())
        {
            Ciclos = 0;
            Humedad_Ref = 0;
            Bateria_Baja = 0;
        }

        //Checamos el nivel de la bateria cuando arranca por primera vez y cada 255 ciclos.
        if(Ciclos == 0)
        {
            if(Bateria_Baja)
            {
                Bateria_Baja--;
                Blink(2);
                WDT_POST128();
                SLEEP();
            }       

            if(BateriaBaja())
            {
                Bateria_Baja = 100;     //Vamos a parpadear doble por 100 ciclos de 2 segundos
                SLEEP();
            }
            Ciclos = 255;
        }   

        //Checamos si el boton esta picado
        if(Boton_Picado)
        {
            WDT_POST128();
            CLRWDT();
            TRIS_LEDON(); 
            LEDON();
            __delay_ms(1000);   
            TRIS_ADOFF();
            Humedad_Ref = Humedad();
            Humedad_Ref_Bkp = Humedad_Ref;
        }   

        //Checamos si esta calibrado. Esta calibrado si Humedad_Ref es mayor a cero
        if( (!Humedad_Ref) || (Humedad_Ref != Humedad_Ref_Bkp) )
        {
            //No esta calibrado, hacer blink y dormir
            Blink(3);
            SLEEP();
        }   

        //Checamos que Humedad_Ref sea mayor o igual a 4 antes de restarle 
        if(Humedad_Ref <= (255 - Offset_Muy_Seca))
        {
            if(Humedad() > (Humedad_Ref + Offset_Muy_Seca)) //planta casi seca
            {
                Blink(1);
                WDT_POST32();
                SLEEP();    
            }       
        }

        if(Humedad() >= (Humedad_Ref))  //planta seca
        {
            Blink(1);
            WDT_POST64();
            SLEEP();    
        }   

        if(Humedad_Ref >= Offset_Casi_Seca )
        {
            //Si Humedad_Ref es menor a Humedad, entonces la tierra esta seca. 
            if(Humedad() > (Humedad_Ref - Offset_Casi_Seca))  //Planta muy seca
            {
                Blink(1);
                WDT_POST128();
                SLEEP();    
            }
        }

        SLEEP();
    }  
} 

unsigned char Humedad (void)
{
    LEDOFF();
    TRIS_ADON();
    ADON();
    ADCON0_CH0_ADON();
    __delay_us(12); 
    GO_nDONE = 1;
    while(GO_nDONE);
    TRIS_ADOFF();
    ADCON0_CH0_ADOFF();
    return ADRES;
}   

//Regresa 1 si la bateria esta baja (fijado por el define LOWBAT)
//Regresa 0 si la bateria no esta baja
unsigned char BateriaBaja (void)
{
    LEDON();                
    TRIS_ADLEDON();
    ADON();
    ADCON0_ABSREF_ADON();
    __delay_us(150);        //Delay largo para que se baje el voltaje de la bateria 
    GO_nDONE = 1;
    while(GO_nDONE);
    TRIS_ADOFF();
    LEDOFF();
    ADCON0_ABSREF_ADOFF();  
    return (ADRES > LOWBAT ? 1 : 0);
}   

void Blink(unsigned char veces)
{
    while(veces)
    {
        veces--;
        WDT_POST64();
        TRIS_LEDON(); 
        CLRWDT();
        LEDON();
        __delay_ms(18); 
        LEDOFF();
        TRIS_ADOFF();
        if(veces)__delay_ms(320);   
    }   
}   

PRINCIPAL.H

/*
Author: woziX (AML)

Feel free to use the code as you wish. 
*/

#ifndef MAIN_H
#define MAIN_H

#include <htc.h>
#include <pic.h>

 __CONFIG (MCPU_OFF  & WDTE_ON & CP_OFF & MCLRE_OFF & IOSCFS_4MHZ ); 

#define _XTAL_FREQ              4000000
#define TRIS_ADON()             TRIS = 0b1101
#define TRIS_ADOFF()            TRIS = 0b1111
#define TRIS_LEDON()            TRIS = 0b1011
#define TRIS_LEDOFF()           TRIS = 0b1111
#define TRIS_ADLEDON()          TRIS = 0b1001


#define ADCON0_CH0_ADON()          ADCON0 = 0b01000001;     // Canal 0 sin ADON
#define ADCON0_CH0_ADOFF()       ADCON0 = 0b01000000;       // Canal 0 con adON
#define ADCON0_ABSREF_ADOFF()    ADCON0 = 0b01001100;       //Referencia interna absoluta sin ADON
#define ADCON0_ABSREF_ADON()     ADCON0 = 0b01001101;       //referencia interna absoluta con ADON

//Llamar a WDT_POST() tambien cambia las otras configuracion de OPTION
#define WDT_POST1()   OPTION = 0b11001000
#define WDT_POST2()   OPTION = 0b11001001
#define WDT_POST4()   OPTION = 0b11001010
#define WDT_POST8()   OPTION = 0b11001011
#define WDT_POST16()  OPTION = 0b11001100
#define WDT_POST32()  OPTION = 0b11001101
#define WDT_POST64()  OPTION = 0b11001110
#define WDT_POST128() OPTION = 0b11001111

#define Boton_Picado    !GP3
#define FIRST_RUN()     (STATUS & 0x10) //Solo tomamos el bit TO

//Offsets
#define Offset_Casi_Seca  5
#define Offset_Muy_Seca   5

 //Low Bat Threshold
#define LOWBAT                    73
/*
Los siguientes valores son aproximados
LOWBAT  VDD
50      3.07
51      3.01
52      2.95
53      2.90
54      2.84
55      2.79
56      2.74
57      2.69
58      2.65
59      2.60
60      2.56
61      2.52
62      2.48
63      2.44
64      2.40
65      2.36
66      2.33
67      2.29
68      2.26
69      2.23
70      2.19
71      2.16
72      2.13
73      2.10
74      2.08
75      2.05
76      2.02
77      1.99
78      1.97
*/


#define LEDON()                 GP2 = 0; //GPIO = GPIO & 0b1011
#define LEDOFF()                GP2 = 1; //GPIO = GPIO | 0b0100
#define ADON()                  GP1 = 0; //GPIO = GPIO & 0b1101
#define ADOFF()                 GP1 = 1; //GPIO = GPIO | 0b0010

unsigned char Humedad (void);
unsigned char BateriaBaja (void);
void Delay_Parpadeo(void);
void Blink(unsigned char veces);

#endif

Avíseme si tiene preguntas, intentaré responder según lo que recuerdo. Lo codifiqué hace varios años, así que no verifiquen mis habilidades de codificación, han mejorado :).

Nota final Usé el compilador Hi-Tech C.

flaco
fuente
3
De hecho, sería realmente interesante leer cómo hiciste esto. ¿Tomó alguna nota mientras lo hacía que no le importaría compartir en las webs?
RhysW
1
Hola RhysW, creo que todavía tengo el código. Fue realmente simple en realidad. Podría enviarle mi código si está interesado. Házmelo saber. El circuito que diseñé es muy simple y fresco, solo 3 resistencias, un mosfet de canal p (para protección de batería inversa), una tapa de 100nF y un LED. Utilizo un diodo interno en el pic10f para usarlo como referencia para la medición de la batería y para mantener constantes las lecturas de ADC.
flaco
1
Eso suena como un proyecto ordenado. ¿Hay alguna posibilidad de que pueda publicar los detalles aquí (o al menos publicarlos en algún lugar y vincularlos)?
Ilmari Karonen
1
Hola scrafy Por favor, si tiene algo que agregar a una respuesta, use el enlace "editar" en lugar de publicar una nueva respuesta, ya que este sitio usa la votación y no funciona como un foro.
clabacchio
16

Algo que no he visto mencionado: el microcontrolador que mencionó cuesta solo $ 0.34 cada uno en cantidades de 100. Por lo tanto, para productos baratos producidos en masa, puede tener sentido ir al problema de codificación adicional impuesto por una unidad tan limitada. Lo mismo podría aplicarse al tamaño o al consumo de energía.

Mark Harrison
fuente
2
Ese fue exactamente mi primer pensamiento. Además: si fuera una startup con una idea clara, pero solo unos pocos cientos de dólares sueltos, cosas como esta pueden significar la diferencia entre volver al trabajo diario y dejar el trabajo diario.
phresnel
14

Cuando estaba en la escuela secundaria, tenía un maestro que insistía en que atenuar la luz era una tarea demasiado difícil para un estudiante como yo.

Así desafiado, pasé bastante tiempo aprendiendo y entendiendo la atenuación de la luz basada en fases usando triacs y programando el 16C84 desde el microchip para realizar esta hazaña. Terminé con este código de ensamblaje:

'Timing info:
'There are 120 half-cycles in a 60Hz AC waveform
'We want to be able to trigger a triac at any of 256 
'points inside each half-cycle.  So:
'1 Half cycle takes 8 1/3 mS
'1/256 of one half cycle takes about 32.6uS
'The Pause function here waits (34 * 0xD)uS, plus 3uS overhead
'Overhead includes CALL PAUSE.
'This was originally assembled using Parallax's "8051 style" 
'assembler, and was not optimized any further.  I suppose
'it could be modified to be closer to 32 or 33uS, but it is
'sufficient for my testing purposes.

list 16c84

    movlw   0xFD     '11111101
    tris    0x5      'Port A
    movlw   0xFF     '11111111
    tris    0x6      'Port B
WaitLow:             'Wait for zero-crossing start
    btfss   0x5,0x0  'Port A, Bit 1
    goto    WaitLow  'If high, goto WaitLow
WaitHigh:            'Wait for end of Zero Crossing
    btfsc   0x5,0x0  'Port A, Bit 1
    goto    WaitHigh 'If low, goto waitHigh
    call    Pause    'Wait for 0xD * 34 + 3 uS
    bcf     0x5,0x1  'Put Low on port A, Bit 1
    movlw   0x3      'Put 3 into W
    movwf   0xD      'Put W into 0xD
    call    Pause    'Call Pause, 105 uS
    bsf     0x5,0x1  'Put High on Port A, Bit 1
    decf    0xE      'Decrement E
    movf    0x6,W    'Copy Port B to W
    movwf   0xD      'Copy W to 0xD
    goto    Start    'Wait for zero Crossing
Pause:               'This pauses for 0xD * 34 + 3 Micro Seconds
                     'Our goal is approx. 32 uS per 0xD
                     'But this is close enough for testing
    movlw   0xA      'Move 10 to W
    movwf   0xC      'Move W to 0xC
Label1:
    decfsz  0xC      'Decrement C
    goto    Label1   'If C is not zero, goto Label1
    decfsz  0xD      'Decrement D
    goto    Pause    'If D is not zero, goto Pause
    return           'Return

Por supuesto, necesitaría modificar esto para el chip que menciona, y tal vez agregar una rutina serial barata para la entrada ya que su chip no tiene un puerto de 8 bits de ancho para escuchar, pero la idea es que un trabajo aparentemente complejo puede debe hacerse en muy poco código: puede colocar diez copias del programa anterior en el 10F200.

Puede encontrar más información sobre el proyecto en mi página de Atenuación de luz . Por cierto, nunca le mostré esto a mi maestro, pero terminé haciendo una serie de equipos de iluminación para mi amigo DJ.

Adam Davis
fuente
12

Bueno, hace años escribí un controlador de temperatura con E / S en serie (golpeando la E / S en serie porque el MCU no tenía un UART) y un simple intérprete de comandos para hablar con el controlador. MCU era un MC68HC705K1 de Motorola (ahora Freescale) que tenía 504 bytes de memoria de programa (OTPROM) y unos 32 bytes de RAM. No es tan pequeño como el PIC al que hace referencia, pero recuerdo que me queda algo de ROM. Todavía me quedan algunas unidades ensambladas, 17 años después; quieres comprar uno?

Entonces sí, se puede hacer, al menos en conjunto.

En cualquier caso, recientemente he escrito programas C muy simples que probablemente habrían encajado dentro de 384 bytes cuando estén optimizados. No todo requiere un software grande y complejo.

Lyndon
fuente
5

Puede escribir un parpadeo de un LED con 384 bytes de memoria de programa, y ​​aún más.

Hasta donde yo sé, no es posible extender la memoria del programa con un chip externo (a menos que esté construyendo un intérprete ASM completo en los 384 bytes , lo que sería lento). Sin embargo, es posible ampliar la memoria de datos con un chip externo (EEPROM, SRAM).


fuente
1
No sería difícil construir un simulador de máquina de Turing en 384 bytes ...
Chris Stratton
@ChrisStratton Me refería a un intérprete completo, para que la 'memoria de programa extendida' tuviera las mismas características que lo normal.
Sí, eso es lo que sugerí como un medio de implementación estricta. El resto es solo diseño de compilador ...
Chris Stratton
77
Si se quisiera almacenar la lógica del programa en una EEPROM externa, tratar de emular el conjunto de instrucciones PIC no sería el camino a seguir. Un mejor enfoque sería diseñar un conjunto de instrucciones optimizado para su uso con la máquina virtual; de hecho, ese es el enfoque que tomó Parallax con su "SELLO BÁSICO" en la década de 1990. Era un PIC con 3072 bytes de espacio de código, emparejado con un chip EEPROM en serie.
supercat
3
Por cierto, una nota adicional sobre el sello BASIC: se introdujo en un momento en que los microcontroladores basados ​​en flasheados o basados ​​en EEPROM eran relativamente raros, pero los chips de EEPROM en serie eran bastante baratos. Para aplicaciones que no necesitaban mucha velocidad, un micro de código fijo con una parte EEPROM serie sería más barato que un EEPROM de tamaño comparable o un micro basado en flash. El diseño del BASIC Stamp no tendría sentido hoy, pero fue bastante práctico cuando se introdujo.
supercat
4

En realidad es peor de lo que piensas. Su página vinculada de Mouser es confusa cuando especifica que este procesador tiene 384 bytes de memoria de programa. El PIC10F200 en realidad tiene 256 palabras de 12 bits de de memoria de programa.

Entonces, ¿qué puedes hacer con eso? El conjunto de instrucciones PIC de 12 bits utilizado por los dispositivos PIC10F20 x son todas instrucciones de una sola palabra, por lo que después de restar algunas instrucciones para la configuración del procesador, tiene suficiente espacio para un programa de aproximadamente 250 pasos. Eso es suficiente para muchas aplicaciones. Probablemente podría escribir un controlador de lavadora en ese tipo de espacio, por ejemplo.

Acabo de mirar los compiladores PIC C disponibles, y parece que aproximadamente la mitad ni siquiera intentará emitir código para un PIC10F200. Aquellos que probablemente publican tanto código repetitivo que es posible que solo pueda escribir una luz intermitente LED en el espacio restante. Realmente desea utilizar lenguaje ensamblador con dicho procesador.

Warren Young
fuente
Tienes razón acerca de las 256 palabras de instrucción. En realidad, uno de ellos está ocupado con la constante de calibración del oscilador, por lo que obtienes 255 instrucciones utilizables. Además, el 10F200 no utiliza el conjunto de instrucciones PIC 16 de 14 bits habitual. Utiliza el conjunto de instrucciones PIC 12 de 12 bits. Sin embargo, estoy de acuerdo con sus premisas básicas. He hecho muchas cosas útiles con un PIC 10F200. +1
Olin Lathrop
@OlinLathrop: he aclarado la respuesta. Obtuve el término PIC16 de la página 51 del conjunto de datos , pero he decidido que es más claro simplemente referirme al "conjunto de instrucciones de 12 bits". El prefijo de la parte no es una guía confiable para el conjunto de instrucciones utilizado.
Warren Young
0

agitando mi bastón en mi día, ¡tuvimos que grabar nuestras propias partes en la arena!

En 1976 (o por ahí), el sistema Atari 2600 VCS era una de las "plataformas de videojuegos" más populares de la época. En él, el microprocesador (MOSTEK 6507) funcionaba a una velocidad de ~ 1 MHz y tenía **** 128 bytes de RAM **.

Un segundo ejemplo que recuerdo de un microcontrolador con RAM extremadamente limitada (~ 128 bytes) fue un PIC12F utilizado en un convertidor DC-DC. Este micro también tuvo que usar lenguaje ensamblador para poder ejecutarse.

cowboydan
fuente
44
El OP no está hablando de RAM, está hablando del espacio del programa. El espacio del programa en el Atari 2600 está en el cartucho, no en el chip RIOT . El programa 2600 soportaba ROMs de hasta 4 kiB sin cambio de banco. (¡Y algunos cartuchos comerciales hicieron cambio de banco!) En cuanto a su ejemplo PIC12F, los OP lo han superado: los dispositivos de la serie PIC10F20x tienen 16 o 24 bytes de SRAM.
Warren Young