Comment utiliser un microcontrôleur ne disposant que de 384 octets de mémoire programme?

67

Par exemple un PIC10F200T

Pratiquement tous les codes que vous écrivez seront plus gros que cela, à moins que ce ne soit une puce à usage unique. Est-il possible de charger plus de mémoire programme depuis un stockage externe ou quelque chose de ce genre? Je suis juste curieux, je ne vois pas en quoi cela pourrait être très utile ... mais ça doit l'être.

coder543
la source
6
Il y a beaucoup d'applications pour de minuscules micro - contrôleurs, des générateurs de signaux à usage spécial, aux convertisseurs de protocole, à « nœuds » dans un système de contrôle plus grand, etc., etc.,
Dave Tweed
13
Un programme d'échecs prend 672 octets, donc ce n'est pas bon. en.wikipedia.org/wiki/1K_ZX_Chess
John Burton
8
Voici quelques exemples de ce que l’on peut faire avec de petits programmes (moins de 256 octets).
hammar
9
Que voulez-vous dire par "à moins que ce ne soit une puce à usage unique"? La majorité des systèmes embarqués sont à usage unique.
Jeanne Pindar
6
De retour au collège, j'ai construit un programme de feux de signalisation entièrement fonctionnel pour un ordinateur 8085/8155 (maximum 256 octets) que j'ai assemblé. Il y avait des boutons de marche et des capteurs simulant la présence d’un véhicule.
Zoredache

Réponses:

133

Vous les enfants, sortez de ma pelouse!

384 octets, c'est beaucoup d'espace pour créer quelque chose d'assez complexe dans l'assembleur.

Si vous remontez dans l’histoire jusqu’à l’époque où les ordinateurs avaient la taille d’une pièce, vous découvrirez des exploits artistiques vraiment étonnants exécutés à moins de 1 000 km.

Par exemple, lisez le classique Story of Mel - Un vrai programmeur . Certes, ces gars-là avaient 4096 mots de mémoire à jouer, les infidèles décadents.

Jetez également un coup d'œil à certaines des anciennes compétitions de demoscene où le défi consistait à insérer une "intro" dans le bloc-notes d'une disquette, les cibles typiques étant 4k ou 40k et parvenant généralement à inclure de la musique et de l'animation.

Modifier pour ajouter : vous pouvez implémenter la première calculatrice scientifique au monde à 100 $ en 320 mots.

Éditer pour les jeunes non:

  • Disquette = disquette.
  • Bootblock = 1er secteur de la disquette lue au démarrage.
  • Demoscene = Compétitions de programmation parmi les groupes de hackers.
  • Assembleur = façon élégante de programmer un appareil si vous êtes trop souple pour utiliser 8 commutateurs à bascule et un bouton "Mémoriser".
John U
la source
4
La console de jeu Atari 2600 ne disposait que de 4 Ko de stockage dans les cartouches de jeu ROM (bien que certains jeux aient contourné cette limitation en utilisant le changement de banque pour accéder à plus de 4 Ko).
Johnny
1
Il y a bien longtemps, j'avais émis un son assez réaliste (suffisamment pour que les gens recherchent l'oiseau plutôt que de suspecter l'ordinateur), dont les tripes (mais pas le code de randomisation qui l'empêchait de produire exactement le même son à chaque fois) l'auraient ébranlé. environ 384 octets et j'avais les restrictions supplémentaires de ne pas avoir d'adresses en écriture et un octet zéro n'était pas autorisé dans le binaire.
Loren Pechtel,
2
J'ai besoin de sortir plus, me souviens de cela dans le jour - économiseur d'écran en 368 octets: aminet.net/package/util/blank/368blanker
John U
7
+1 pour "L'histoire de Mel". Une des meilleures choses que j'ai lues toute la semaine.
Justin ᚅᚔᚈᚄᚒᚔ
1
@JohnU: Les premiers jeux sur l'Atari 2600 étaient tous deux. De nombreux développeurs n'ont jamais conçu de jeux allant au-delà de 4K, car même si les puces 8K étaient abordables (et les charrettes de certaines entreprises utilisaient simplement la moitié d'une puce 4K), elles permettaient de passer d'une carte à une autre à l'aide d'une carte standard (active-low chip-select). chip a augmenté le nombre de puces de support de un à trois.
Supercat
59

Les microcontrôleurs sont suffisamment bon marché pour être souvent utilisés pour faire des choses très simples qui, jadis, auraient probablement été réalisées avec une logique discrète. Des choses vraiment simples. Par exemple, on peut souhaiter qu'un périphérique active une sortie toutes les cinq secondes, plus précisément qu'une minuterie 555 ne pourrait le faire.

  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

Ce serait une application réelle et utilisable, avec moins de 32 mots (48 octets) d’espace de code. On pourrait facilement ajouter quelques options pour que certaines broches d’E / S contrôlent les options de minutage tout en conservant beaucoup d’espace libre, mais même si la puce correspondait exactement à ce qui est présenté ci-dessus, elle pourrait toujours être moins chère et plus facile que toute autre solution utilisant la technologie discrète. logique. En passant, les clrwdtinstructions pourraient être déplacées dans le sous-programme, mais cela rendrait les choses moins robustes. Comme indiqué, même si un problème entraînait la corruption de la pile d’adresses de renvoi, le chien de garde ne serait pas alimenté tant que l’exécution ne retournerait pas à la boucle principale. Si cela ne se produit jamais, le chien de garde réinitialisera la puce après quelques secondes.

supercat
la source
9
Honnêtement, vous pourriez optimiser un peu votre code, donnant ainsi un mauvais exemple aux enfants - 5 appels distincts à wait1sec ??? Gaspilleur! ;)
John U
9
@JohnU: FYI, le code utilise des appels séparés, car s'il utilisait un compteur de comptage à zéro et que le compte devenait figé, la boucle pourrait s'exécuter 255 fois au lieu de quatre, tout en alimentant le chien de garde une fois par seconde. Bien qu'il soit possible de se prémunir contre cela en vérifiant sur chaque boucle si le compte était à portée, le code pour le faire finit par être plus compliqué que cinq appels et cinq clrwdtinstructions. Ce type de compteur n’est pas le plus sûr possible, mais une attention particulière est accordée aux questions de sécurité (par exemple, éviter clrwdtun sous-programme).
Supercat
10
@ coder543: En l'absence d'éléments comme le bruit d'alimentation, pas très. D'autre part, dans certaines parties dépourvues de détecteur de baisse de tension, il est possible que toutes sortes de choses folles se produisent si la DMV tombe à un niveau situé entre la tension de fonctionnement minimale et la masse, puis revient à la normale. En règle générale, il convient de s’assurer que tout état dans lequel l’appareil peut se trouver reviendra à la normale dans un délai raisonnable. Les deux secondes ou plus que le chien de garde entre en action sont peut-être inévitables, mais quatre minutes pour un compteur saccadé pour atteindre zéro pourraient être un peu longues.
Supercat
10
@ coder543, ils se produisent plus souvent lors d'une démo importante que vous ne le croyez. Ce type de réflexion est également nécessaire lors de la création d'éléments profondément ancrés qui n'ont aucun moyen d'appeler à l'aide ou de signaler une erreur. Ou sont inaccessibles (pensez aux fonds marins ou à l'espace extra-atmosphérique) même si une erreur a été remarquée.
RBerteig
6
@JohnU: Je l'ai remarqué, mais je me suis dit qu'expliquer pourquoi j'ai écrit le code comme je l'avais fait pourrait être utile. A propos, j’essayais aussi de montrer que de petites tâches peuvent s’intégrer dans un petit processeur même si elles ne sont pas optimisées à la perfection.
Supercat
26

"SEULEMENT" 384 octets?

Il y a longtemps, j'avais pour tâche d'écrire (par moi-même) un système d'exploitation complet pour un ordinateur spécialisé destiné à l'industrie de la gestion des navires, des pipelines et des raffineries. Le premier produit de ce type, basé sur la norme 6800, était en cours de mise à niveau vers la version 6809; elle souhaitait qu'un nouveau système d'exploitation vienne avec le système 6809 afin d'éliminer les coûts de licence du système d'exploitation d'origine. Ils ont également augmenté la taille de la rom de démarrage à 64 octets, au lieu de 32. Si je me souviens bien - il y a environ 33 ans! - J'ai convaincu les ingénieurs de me donner 128 octets afin de pouvoir mettre tous les pilotes de périphérique du système d'exploitation sur la rom et de rendre ainsi le périphérique plus fiable et polyvalent. Cela comprenait:

  • Pilote de clavier avec clé anti-rebond
  • Pilote vidéo
  • Pilote de lecteur de disque et système de fichiers rudimentaire (format "abloader" de Motorola, IIRC), avec possibilité intégrée de traiter la mémoire "mise en banque" comme s'il s'agissait d'un espace disque très rapide.
  • Modem Driver (ils ont reçu la FSK à l'envers, ces modems ne se sont donc entretenus)

Oui, tous ces éléments étaient aussi simples que possible, et optimisés à la main pour supprimer tous les cycles superflus, mais parfaitement réparables et fiables. Oui, j'ai tout concocté dans les octets disponibles - oh, il a ÉGALEMENT configuré la gestion des interruptions, les différentes piles et initialisé le système d'exploitation temps réel / multitâche, a invité l'utilisateur à choisir les options de démarrage et a démarré le système.

Un ami à moi qui est toujours affilié à la société (son successeur) m'a dit il y a quelques années que mon code est toujours en service!

Vous pouvez faire beaucoup avec 384 octets ...

Richard T
la source
2
vous dites démarrage de démarrage, et vous mentionnez le déplacement des pilotes sur le démarrage de démarrage ... cela indique pour moi qu'un support de stockage secondaire était disponible. Dans cette discussion, nous avons déjà déterminé qu'il était impossible de charger du code à partir d'un stockage externe sur ce PIC.
coder543
5
@ coder543 Cela passe à côté de l'essentiel: 384 octets suffisent pour faire pas mal de choses! La question initiale se présentait comme une plainte selon laquelle 384 n'était pas suffisant pour faire quelque chose d'utile - c'était plus que ce dont j'avais besoin - BEAUCOUP plus - pour fournir tous les composants fondamentaux d'un système d'exploitation multi-tâches en temps réel ...
Richard T
21

Vous pouvez l'utiliser pour de très petites applications (par exemple , démarrage retardé du PSU , remplacement de la minuterie 555 , commande à base de triac , clignotement des voyants, etc.) avec un encombrement inférieur à celui nécessaire avec des portes logiques ou une minuterie 555.

Renan
la source
3
Je viens de remarquer que ces deux premiers exemples provenaient de Stack lui-même! bien joué.
coder543
9
+1 pour mentionner l'empreinte. Parfois, la taille est tout.
embedded.kyle
17

J'ai conçu un capteur d'humidité pour les plantes qui surveille la quantité d'eau de la plante et fait clignoter une LED si la plante a besoin d'eau. Vous pouvez faire en sorte que le capteur connaisse le type d’installation et modifie ainsi ses paramètres pendant le fonctionnement. Il détecte une basse tension sur la batterie. J'ai manqué de mémoire flash et de mémoire vive, mais j'ai pu tout écrire en code C pour que ce produit fonctionne parfaitement.

J'ai utilisé le pic10f que vous mentionnez.


Voici le code que j'ai créé pour mon capteur d'eau de plante. J'ai utilisé le pic10f220 car il a un module ADC, il a la même mémoire que le pic10f200, je vais essayer de trouver le schéma demain.

Le code est en espagnol, mais il est très simple et devrait être facilement compris. Lorsque le Pic10F sort du mode veille, il se réinitialise. Vous devez donc vérifier s’il s’agit d’un PowerUp ou d’une réinitialisation et agir en conséquence. Le réglage de l’usine est gardé en mémoire, car il n’est jamais vraiment mis hors tension.

PRINCIPAL C

/*
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);   
    }   
}   

MAIN.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

Faites-moi savoir si vous avez des questions, je vais essayer de répondre en fonction de ce que je me souviens. J'ai codé cela il y a plusieurs années, alors ne vérifiez pas mes compétences en codage, elles se sont améliorées :).

Note finale J'ai utilisé le compilateur Hi-Tech C.

émietté
la source
3
En fait, je serais très intéressant de lire comment vous avez fait cela. Avez-vous pris des notes pendant que vous les faisiez que vous ne voudriez pas partager sur le Web?
RhysW
1
Bonjour RhysW, je pense avoir encore le code. C'était vraiment simple en fait. Je pourrais vous envoyer mon code si cela vous intéresse. Faites le moi savoir. Le circuit que j’ai conçu est très simple et cool, il n’ya que 3 résistances, un MOSFET à canal P (pour la protection inverse de la batterie), un capuchon 100nF et une LED. J'utilise une diode interne dans le pic10f à utiliser comme référence pour la mesure de la batterie et pour maintenir les lectures de l'ADC constantes.
Scrafy
1
Cela ressemble à un projet soigné. Y a-t-il une chance que vous publiiez les détails ici (ou au moins les poster quelque part et les relier à eux)?
Ilmari Karonen
1
Bonjour Scrafy! S'il vous plaît, si vous avez quelque chose à ajouter à une réponse, utilisez le lien "modifier" au lieu de poster une nouvelle réponse, car ce site utilise le vote et ne fonctionne pas comme un forum.
Clabacchio
16

Une chose que je n'ai pas encore vue mentionnée: le microcontrôleur que vous avez mentionné ne coûte que 0,34 USD l'unité par 100. Ainsi, pour les produits bon marché et fabriqués en série, il peut être judicieux de passer au problème de codage supplémentaire imposé par une unité aussi limitée. La même chose peut s'appliquer à la taille ou à la consommation d'énergie.

Mark Harrison
la source
2
C'était exactement ma première pensée. Aussi: si je suis une start-up avec une idée géniale, mais avec seulement quelques centaines de dollars en poche, des choses comme celle-ci peuvent faire la différence entre un travail de retour à la vie quotidienne et un travail de jour sans emploi.
Phresnel
14

Lorsque j'étais au lycée, un enseignant m'a insisté sur le fait qu'il était trop difficile pour une étudiante telle que moi de réduire l'intensité de la lumière.

C'est pourquoi j'ai passé beaucoup de temps à apprendre et à comprendre la gradation de la lumière en phase avec des triacs et à programmer le 16C84 à partir d'une puce pour réaliser cet exploit. J'ai fini avec ce code d'assemblage:

'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

Bien sûr, vous devrez modifier cela pour la puce que vous mentionnez, et peut-être ajouter une routine série bon marché pour l’entrée puisque votre puce n’a pas de port 8 bits à écouter, mais l’idée est qu’un travail apparemment complexe peut être fait dans très peu de code - vous pouvez insérer dix copies du programme ci-dessus dans le 10F200.

Vous pouvez trouver plus d’informations sur le projet sur ma page Light Dimming . D'ailleurs, je n'ai jamais montré cela à mon professeur, mais j'ai fini par installer plusieurs appareils d'éclairage pour mon ami DJ.

Adam Davis
la source
12

Il y a des années, j’ai écrit un contrôleur de température avec une E / S série (bourdonnant l’E / S série car la MCU n’avait pas d’UART) et un interpréteur de commandes simple pour communiquer avec le contrôleur. MCU était un MC68HC705K1 de Motorola (maintenant Freescale) qui disposait de 504 octets de mémoire de programme (OTPROM) et d’environ 32 octets de RAM. Pas aussi peu que le PIC que vous avez mentionné, mais je me souviens d’avoir encore de la ROM. Il me reste quelques unités assemblées, 17 ans plus tard; veux en acheter un?

Alors oui, cela peut être fait, au moins en assemblée.

Dans tous les cas, j’ai récemment écrit des programmes C très simples qui auraient probablement pu s’intégrer dans les 384 octets lorsqu’ils ont été optimisés. Tout ne nécessite pas un logiciel volumineux et complexe.

Lyndon
la source
5

Vous pouvez écrire une LED clignotante avec une mémoire programme de 384 octets, voire plus.

Autant que je sache, il n'est pas possible d'étendre la mémoire du programme avec une puce externe (sauf si vous construisez un interpréteur ASM complet dans les 384 octets , ce qui serait lent). Il est toutefois possible d'étendre la mémoire de données avec une puce externe (EEPROM, SRAM).


la source
1
Il ne serait pas difficile de construire un simulateur de machine de Turing en 384 octets ...
Chris Stratton
@ChrisStratton Je voulais dire un interprète complet, de sorte que la "mémoire de programme étendue" aurait les mêmes fonctionnalités que la normale.
Oui, c’est ce que j’ai suggéré comme moyen de l’appliquer étroitement. Le reste n'est que de la conception de compilateurs ...
Chris Stratton
7
Si une personne souhaitait que la logique du programme soit stockée dans une EEPROM externe, essayer d'émuler le jeu d'instructions PIC ne serait pas la solution. Une meilleure approche consisterait à concevoir un jeu d’instructions optimisé pour une utilisation avec la machine virtuelle; En effet, c’est l’approche adoptée par Parallax avec son "Basic Stamp" dans les années 90. C’était un PIC avec 3072 octets d’espace de code, associé à une puce série EEPROM.
Supercat
3
BTW, une note supplémentaire sur le timbre BASIC: il a été introduit à une époque où les microcontrôleurs à mémoire flash ou EEPROM étaient relativement rares, mais les puces EEPROM en série étaient relativement bon marché. Pour les applications nécessitant peu de rapidité, un micro à code fixe avec une partie EEPROM série serait meilleur marché qu'un micro de type EEPROM ou Flash de taille comparable. Le design du BASIC Stamp n’a pas de sens aujourd'hui, mais il était très pratique lors de son introduction.
Supercat
4

C'est en fait pire que vous ne le pensez. Votre page Mouser liée est source de confusion quand elle spécifie que ce processeur possède 384 octets de mémoire programme. Le PIC10F200 dispose en réalité de 256 12 bits mots de de mémoire programme.

Alors, que pouvez-vous faire avec ça? Le jeu d'instructions PIC 12 bits utilisé par le PIC10F20 périphériques x est constitué d'instructions d'un seul mot. Par conséquent, après avoir soustrait quelques instructions pour la configuration du processeur, vous disposez de suffisamment d'espace pour un programme d'environ 250 étapes. Cela suffit pour beaucoup d'applications. Je pourrais probablement écrire un contrôleur de machine à laver dans ce genre d'espace, par exemple.

Je viens de regarder les compilateurs PIC C disponibles et il semble qu'environ la moitié d'entre eux n'essayent même pas d'émettre du code pour un PIC10F200. Ceux qui le font émettent probablement tellement de code passe-partout que vous ne pourrez peut-être écrire qu'un clignotant à DEL dans l'espace restant. Vous voulez vraiment utiliser le langage assembleur avec un tel processeur.

Warren Young
la source
Vous avez raison à propos des 256 mots d’instruction. En fait, l’un d’eux est associé à la constante de calibrage de l’oscillateur, ce qui donne 255 instructions utilisables. En outre, le 10F200 n'utilise pas le jeu d'instructions PIC 16 à 14 bits habituel. Il utilise le jeu d'instructions PIC 12 12 bits. Cependant, je suis d'accord avec vos prémisses de base. J'ai fait beaucoup de choses utiles avec un PIC 10F200. +1
Olin Lathrop
@OlinLathrop: J'ai clarifié la réponse. Le terme PIC16 provient de la page 51 de la base de données , mais j’ai décidé qu’il était plus clair de se référer à "le jeu d’instructions 12 bits". Le préfixe de la pièce n'est pas un guide fiable du jeu d'instructions utilisé.
Warren Young
0

agitant ma canne dans ma journée, nous avons dû graver nos propres morceaux de sable!

En 1976 (ou à peu près), le système Atari 2600 VCS était l’une des «plateformes de jeux vidéo» les plus populaires de l’époque. Dans ce document, le microprocesseur (MOSTEK 6507) fonctionnait à environ 1 MHz et disposait de 128 octets de RAM **.

Un deuxième exemple de microcontrôleur dont la RAM est extrêmement limitée (~ 128 octets) est un PIC12F utilisé sur un convertisseur continu-continu. Ce micro devait également utiliser un langage d'assemblage pour pouvoir fonctionner.

cowboydan
la source
4
Le PO ne parle pas de RAM, il parle d'espace de programme. L'espace de programmation de l'Atari 2600 se trouve dans la cartouche et non dans la puce RIOT . Les 2600 programmes pris en charge pouvaient contenir jusqu'à 4 Ko de mémoire ROM sans commutation de banque. (Et certaines cartouches du commerce ont effectivement changé de banque!) En ce qui concerne votre exemple PIC12F, le terminal opérateur vous bat: les périphériques de la série PIC10F20x disposent de 16 ou 24 octets de mémoire SRAM.
Warren Young