Herkes sadece 384 byte program hafızasına sahip bir mikrodenetleyiciyi nasıl kullanabilir?


67

Örneğin bir PIC10F200T

Neredeyse yazdığınız herhangi bir kod, tek amaçlı bir yonga olmadığı sürece bundan daha büyük olacaktır. Harici depolama biriminden daha fazla program belleği yüklemenin bir yolu var mı? Sadece merak ediyorum, bunun ne kadar yararlı olabileceğini anlamıyorum ... ama olmalı.


6
Özel amaçlı sinyal jeneratörlerinden protokol dönüştürücülere, daha büyük kontrol sistemlerinde "düğümlere" vb. Kadar küçük mikrodenetleyiciler için birçok uygulama vardır,
Dave Tweed

13
Bir satranç oyun programı 672 byte alır, bu yüzden bu iyi değil. en.wikipedia.org/wiki/1K_ZX_Chess
John Burton

8
İşte küçük programlarla (256 byte'tan az) yapılabileceklerin bazı örnekleri .
Hammar

9
Ne demek "tek amaçlı bir çip değilse"? Gömülü sistemlerin çoğunluğu tek amaçtır.
Jeanne Pindar

6
Üniversiteye döndüğümde, 8085/8155 bilgisayar için (maksimum 256 bayt) tamamen işlevsel bir trafik ışığı programı oluşturdum. Yürüme düğmeleri ve bir aracın varlığını taklit edecek bazı sensörleri vardı.
Zoredache

Yanıtlar:


133

Siz çocuklar, çimlerimden defolun!

384 bayt, assembler'da oldukça karmaşık bir şey yaratmak için bol miktarda alandır.

Bilgisayarların bir odanın büyüklüğü olduğu zamana kadar geçmişe bakarsanız, <1k'de yürütülen gerçekten harika sanat eserlerini bulacaksınız.

Örneğin, klasik Mel Hikayesi - Gerçek Bir Programcı okuyun . Kuşkusuz, bu adamlar, çökmekte olan kâfirlerin oynayacağı 4096 kelime hafızasına sahipti.

Ayrıca, zorluğun bir disketin ön kısmına "intro" yerleştirmesi, tipik hedeflerin 4k veya 40k olması ve genellikle müzik ve animasyon eklemeyi başarması gibi bazı eski gösterişli yarışmalara bakın.

Eklemek için düzenleyin : Dünyanın ilk 100 dolarlık bilimsel hesap makinesini 320 kelimeyle uygulayabiliyorsunuz .

Gençler için düzenleme:

  • Disket = disket.
  • Bootblock = Disketin ilk bölümü açılışta okunur.
  • Demoscene = Hacker grupları arasındaki programlama yarışmaları.
  • Assembler = 8 geçiş düğmesi ve bir "mağaza" düğmesi kullanmayacak kadar yumuşaksanız, cihazın programlanmasının süslü yolu.

4
Atari 2600 oyun konsolu, ROM oyun kartuşlarında sadece 4KB depolama alanına sahipti (bazı oyunlarda 4K'dan fazla erişim sağlamak için banka geçişi kullanılarak bu sınırlama aşıldı).
Johnny 21

1
Kısa bir süre önce oldukça gerçekçi bir kuş cıvıltısı yaptım (insanlar bilgisayardan şüphelenmek yerine kuşu aradı) (bağırsakları her seferinde aynı sesi çıkarmasını engelleyen rastgele kod değil) etrafında 384 bayt ve ben yazılabilir adresleri hiçbir ek kısıtlamaları vardı ve ikili bir sıfır bayta izin verilmedi.
Loren Pechtel

2
Daha fazla dışarı çıkmam gerekiyor, bunu arkadan hatırladım - 368 byte ekran koruyucusu: aminet.net/package/util/blank/368blanker
John U

7
"Mel'in Öyküsü" için +1. Bütün hafta okuduğum en güzel şeylerden biri.
Justin,

1
@JohnU: Atari 2600'deki ilk birkaç oyun 2K idi. Pek çok geliştirici, hiçbir zaman 4K'nın ötesine geçen hiçbir oyun tasarlamadı; çünkü 8K çipleri uygun olsa da (ve bazı şirketlerin arabaları, 4K çipinin yarısını kullandı), standart (aktif düşük çip seçimi) kullanarak bir karta banka değiştirme eklendi yonga destek yongalarının sayısını bir ila üçe çıkardı.
supercat,

59

Mikrodenetleyiciler, geçmiş yıllarda kesin bir mantıkla daha büyük olasılıkla yapılacak basit şeyleri yapmak için sık sık kullanıldıkları için yeterince ucuzlar. Gerçekten basit şeyler. Örneğin, bir aygıt bir çıkışı 5 saniyede bir saniyede bir açmak isteyebilir, tam olarak 555 zamanlayıcının yapabileceğinden daha fazla.

  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

Bu, 32 kelimeden (48 bayt) az bir kod alanıyla gerçek, kullanışlı bir uygulama olacaktır. Biri, bazı I / O pinlerinin zamanlama seçeneklerini kontrol etmesi ve hala ayrılacak çok yerinin olması için kolayca birkaç seçenek ekleyebilir; mantık. BTW, clrwdttalimatlar alt rutine geçirilebilir, ancak böyle yapılması işleri daha az sağlam hale getirir. Yazıldığı gibi, bir aksaklık dönüş adresi yığınının bozulmasına neden olsa bile, yürütme ana döngüye geri dönene kadar bekçi uygulaması beslenmeyecektir. Bu asla olmazsa, bekçi birkaç saniye sonra çipi sıfırlar.


9
Dürüst olmak gerekirse, kodunuzu biraz optimize edebilir, çocuklar için kötü bir örnek oluşturabilirsiniz - wait1sec'e 5 ayrı çağrı ??? Wastrel! ;)
John U

9
@JohnU: FYI, kod ayrı çağrılar kullanır, çünkü bir sıfıra sayıcı sayıcı kullanılırsa ve sayım yalpalanırsa, döngü bekçi saniyede bir kez beslenirken dört yerine 255 kez çalışabilir. Saymanın menzil içinde olup olmadığını kontrol ederek her döngüyü kontrol ederek buna karşı korunmak mümkün olsa da, yapılacak kod beş çağrı ve beş clrwdtkomuttan daha karmaşık hale gelir . Bu, mümkün olan en kesin şekilde güvenli olmayan sayaç düzenlemesi değildir, ancak güvenlik konularına bir miktar önem verilir (örneğin, clrwdtbir alt programın içinde bulunmaması).
supercat

10
@ coder543: Güç kaynağı gürültüsü gibi şeylerin yokluğunda, çok değil. Öte yandan, bozma algılayıcısız parçalarda, VDD minimum çalışma gerilimi ve toprak arasında bir seviyeye düşerse ve sonra normale dönerse her türlü çılgınca şey olabilir. Genelde, cihazın kendisini bulabileceği herhangi bir durumun makul bir sürede normale döndüğünden emin olunmalıdır. Bekçi köpeğinin tekmelemesi iki saniye kaçınılmaz olabilir ancak parıldayan bir sayacın sıfıra ulaşması için dört dakika biraz fazla olabilir.
supercat

10
@ coder543, inanmak istediğinizden daha önemli bir demoda daha sık görülür. Bu tür bir düşünce, yardım isteme veya bir hata bildirme aracı olmayan derinden gömülü şeyler inşa ederken de gereklidir. Ya da bir hata fark edilse bile erişilemez (derin deniz veya uzayda düşünün).
RBerteig

6
@JohnU: Fark ettim ama kodu neden yazdığımı açıklamanın yardımcı olabileceğini düşündüm. Bu arada, aynı zamanda mükemmel şekilde optimize edilmemiş olsalar bile küçük görevlerin küçük bir işlemciye sığabileceğini göstermeye çalışıyordum.
supercat,

26

"SADECE" 384 bayt?

Güne dönüşte, gemiye, boru hattına ve rafineri yönetim endüstrisine hizmet veren uzman bir bilgisayar için tüm işletim sistemini (tek başıma) yazma işim vardı. Şirketin bu ilk ürünü 6800'e dayanıyor ve 6809'a yükseltiliyordu ve 6809 ile birlikte yeni bir işletim sistemi kurmak istiyorlardı, böylece orijinal işletim sisteminin lisans maliyetlerini ortadan kaldırabiliyorlardı. Ayrıca boot rom'un büyüklüğünü 32'den 64 byte'a çıkarıyorlardı. Doğru hatırlıyorsam - yaklaşık 33 yıl önceydi! - Mühendisleri bana 128 bayt vermeye ikna ettim, böylece tüm işletim sisteminin aygıt sürücülerini rom'a koyabilirim ve böylece tüm aygıtı daha güvenilir ve çok yönlü hale getirebilirim. Bu dahil:

  • Key debounce ile klavye sürücüsü
  • Video sürücüsü
  • Disk sürücüsü sürücü ve ilkel dosya sistemi (Motorola "abloader formatı", IIRC), yerleşik "hafızaya alınmış" hafızayı gerçekten hızlı disk alanıymış gibi işleyebilme özelliğine sahip.
  • Modem Sürücüsü (FSK'yi geri aldılar, bu yüzden bu modemler sadece birbirleriyle konuştu)

Evet, bunların hepsi olabildiğince çıplak kemiklerdi ve her yabancı döngüyü kaldırmak için elle optimize edildiler, ancak mükemmel şekilde uygulanabilir ve güvenilirdiler. Evet, bunların hepsini mevcut baytlara bağladım - oh, ayrıca, kesme işlemesi, çeşitli istifler kurdu ve gerçek zamanlı / çoklu görev işletim sistemini başlattı, kullanıcıyı önyükleme seçeneklerine yönlendirdi ve sistemi başlattı.

Hala şirkete bağlı bir arkadaşım (halefi) birkaç yıl önce kodumun hala hizmette olduğunu söyledi!

384 bayt ile LOT yapabilirsiniz ...


2
önyükleme romu söylüyorsunuz ve önyükleme çubuğuna hareket eden sürücülerden bahsediyorsunuz ... bu, bana ikincil bir depolama ortamı olduğunu gösteriyor. Bu tartışmada, bu PIC'deki harici depolama biriminden kod yükleyemeyeceğinizi belirledik.
kodlayıcı543

5
@ coder543 Bu noktası özlüyor: 384 bayt oldukça yapmak için yeterli! Orijinal soru, 384'ün faydalı bir şey yapmak için yeterli olmadığına dair bir şikayet gibi geldi - ihtiyacım olandan daha fazlasıydı - çok daha fazlası - gerçek zamanlı, çok görevli bir işletim sisteminin tüm temel bileşenlerini sağlamak için ...
Richard T


17

Tesisin sahip olduğu su miktarını takip eden ve tesisin suya ihtiyacı varsa LED'i yanıp sönen bitkiler için bir nem sensörü tasarladım. Sensörün tesis tipini öğrenmesini sağlayabilir ve böylece çalıştırırken ayarlarını değiştirebilirsiniz. Aküde düşük voltaj tespit eder. Flaş ve çarpma bitti ancak bu ürünün kusursuz çalışmasını sağlamak için her şeyi C kodunda yazabildim.

Bahsettiğin pic10f'u kullandım.


İşte Bitki Su Sensörüm için yaptığım kod. Pic10f220'yi kullandım, çünkü bir ADC modülüne sahipti, pic10f200 ile aynı hafızasına sahip, yarın Schematic'i bulmaya çalışacağım.

Kod ispanyolcadır, fakat çok basittir ve kolayca anlaşılması gerekir. Pic10F uyku modundan uyandığında sıfırlanacaktır, böylece bir PowerUp mı yoksa sıfırlama mı olduğunu kontrol etmeniz ve buna göre davranmanız gerekir. Tesis ayarı, hiç bir zaman tam olarak kapanmadığından ram içinde tutulur.

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

Sorularınız varsa, hatırladığım şeye dayanarak cevap vermeye çalışacağım. Bunu birkaç yıl önce kodladım, bu yüzden kodlama becerilerimi kontrol etmeyin, onlar gelişti.

Son Not Hi-Tech C derleyicisini kullandım.


3
Bunu nasıl yaptığını okumak gerçekten çok ilginç olurdu. Bunu yaparken, web’de paylaşmanın sakıncası olmayacak kadar not aldınız mı?
RhysW

1
Merhaba RhysW, kodun hala bende olduğuna inanıyorum. Aslında çok basitti. Eğer ilgilenirsen sana kodumu gönderebilirim. Bilmeme izin ver. Tasarladığım devre çok basit ve serin, sadece 3 direnç, bir p-kanal mosfet (ters akü koruması için) 100nF başlık ve bir LED. Pil ölçümü için bir referans olarak kullanmak ve ADC okumalarını sabit tutmak için pic10f'deki dahili diyotu kullanıyorum.
scrafy

1
Güzel bir proje gibi geliyor. Ayrıntıları buraya gönderebilme ihtimaliniz var mı (veya en azından bir yere göndermek ve bunlara bağlantı vermek)?
Ilmari Karonen

1
Merhaba scrafy! Lütfen, bir cevaba ekleyeceğiniz bir şey varsa, yeni bir cevap göndermek yerine "düzenle" bağlantısını kullanın, çünkü bu site oylama kullanır ve forum gibi çalışmaz.
clabacchio

16

Bahsetmediğim bir şey var: Bahsettiğiniz mikrodenetleyici her biri 100'lük miktarlarda sadece 0.34 $ 'dır. Bu nedenle, ucuz, seri üretilen ürünler için, bu kadar sınırlı bir birim tarafından dayatılan ekstra kodlama sorununa gitmek mantıklı gelebilir. Aynısı boyut veya güç tüketimi için de geçerli olabilir.


2
Bu benim ilk düşüncemdi. Ayrıca: Düzgün bir fikirle bir başlangıç ​​yaparsam, ancak sadece birkaç yüz dolar gevşek olsaydı, bunun gibi şeyler günlük işe dönüş ile günlük iş bırakma arasındaki fark anlamına gelebilir.
phresnel

14

Lisedeyken, ışığın karartılmasının başa çıkmam gibi bir öğrenci için zor olduğu konusunda ısrar eden bir öğretmenim vardı.

Böylece, zorlu zamanları, triyakları kullanarak faz tabanlı ışık karartmayı öğrenmek ve anlamak için 16C84'ü mikroçipten programlamak için biraz zaman harcadım. Bu montaj kodu ile bitti:

'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

Elbette, bahsettiğiniz çip için bunu değiştirmeniz ve belki de çipinizin dinleyeceği 8 bit genişliğinde bir bağlantı noktası olmadığından giriş için ucuz bir seri rutin eklemeniz gerekebilir, ancak fikir görünüşte karmaşık bir işin yapabileceği gibi. çok az kodla yapılmalıdır - yukarıdaki programın on kopyasını 10F200'e sığdırabilirsiniz.

Işık Karartma sayfamda daha fazla proje bilgisi bulabilirsiniz . Bu arada, bunu öğretmenime hiç göstermedim ama sonunda DJ arkadaşım için birkaç aydınlatma kulesi yaptı.


12

Yıllar önce seri G / Ç içeren bir sıcaklık kontrol cihazı yazdım (MCU'da bir UART olmadığı için seri G / Ç'yi bitirme) ve kontrol cihazıyla konuşmak için basit bir komut yorumlayıcısı yazdım. MCU bir Motorola (şimdi Freescale) olan MC68HC705K1, 504 bayt program hafızasına (OTPROM) ve 32 bayt RAM'e sahipti. Referans verdiğiniz PIC kadar az değil, fakat biraz ROM bıraktığımı hatırlıyorum. 17 yıl sonra hala birkaç montajlı birim kaldı; bir tane almak ister misin?

Yani evet, en azından montajda yapılabilir.

Her durumda, son zamanlarda, optimize edildiğinde muhtemelen 384 byte'a sığabilecek çok basit C programları yazdım. Her şey geniş ve karmaşık bir yazılım gerektirmez.


5

Yanıp sönen bir LED'i 384 bayt program hafızası ve hatta daha fazlası ile yazabilirsiniz.

Bildiğim kadarıyla, program belleğini harici bir yonga ile genişletmek mümkün değil ( 384 baytta yavaş bir ASM yorumlayıcısı oluşturmazsanız ). Veri belleğini harici bir yonga (EEPROM, SRAM) ile genişletmek mümkündür.


1
Turing makinesi simülatörünü 384 baytta yapmak zor olmaz ...
Chris Stratton

@ ChrisStratton Tam bir tercüman demek istedim, böylece 'genişletilmiş program hafızası' normal özelliklerle aynı olurdu.

Evet, sıkı bir şekilde uygulamak için bir araç önerdim. Gerisi sadece derleyici tasarımı ...
Chris Stratton

7
Bir program mantığının harici bir EEPROM'da saklanması isteniyorsa, PIC komut setini taklit etmeye çalışmak yolu olmaz. Sanal makine ile kullanım için optimize edilmiş bir komut seti tasarlamak daha iyi bir yaklaşım olacaktır; Gerçekten de, Parallax’ın 1990’larda “Temel Basamak” ile birlikte kullandıkları yaklaşım budur. Seri bir EEPROM yongasıyla eşleştirilmiş, 3072 baytlık kod alanına sahip bir PIC idi.
supercat

3
BTW, BASIC damgası hakkında ek bir not: Parlatmalı veya EEPROM tabanlı mikrodenetleyicilerin nispeten nadir olduğu, ancak seri EEPROM çiplerinin oldukça ucuz olduğu bir zamanda tanıtıldı. Çok fazla hıza ihtiyaç duymayan uygulamalar için, seri bir EEPROM parçasına sahip sabit kodlu bir mikro, karşılaştırılabilir boyutta bir EEPROM veya flaş bazlı mikrodan daha ucuz olacaktır. BASIC Stamp'in tasarımı bugün için bir anlam ifade etmiyordu, ancak piyasaya sunulduğunda oldukça pratikti.
supercat,

4

Aslında düşündüğünden daha kötü. Bağlantılı Mouser sayfanız, bu işlemciyi 384 bayt program hafızasına sahip olduğunu belirttiğinde, kafa karıştırıcıdır. PIC10F200 aslında 256 12 bit vardır kelimeleri program bellek.

Peki bununla ne yapabilirsin? 12 bitlik PIC komut seti PIC10F20 kullandığı x cihazların hepsi tek kelime talimatları, bu yüzden işlemci kurulumu için birkaç talimatları çıkarma sonra, yaklaşık 250 adımların bir program için yeterli alan sol ediyoruz. Birçok uygulama için bu yeterli. Örneğin, bir çamaşır makinesi kontrol cihazını bu tür bir alana yazabilirim.

Kullanılabilir PIC C derleyicilerini araştırdım ve yaklaşık yarısı PIC10F200 kodunu bile yayınlamaya çalışmayacak gibi görünüyor. Muhtemelen o kadar kazan plakası koyanlar ki, kalan alana sadece bir LED flaşör yazmanız mümkün olacak. Assembly dilini gerçekten böyle bir işlemciyle kullanmak istiyorsun.


256 talimat kelimesinde haklısın. Aslında bunlardan biri osilatör kalibrasyon sabiti ile alınır, bu nedenle 255 kullanılabilir talimat alırsınız. Ayrıca, 10F200 normal PIC 16 14 bit komut setini kullanmaz. PIC 12 12 bit komut setini kullanır. Ancak, temel tesislerinize katılıyorum. PIC 10F200 ile birçok faydalı şey yaptım. +1
Olin Lathrop,

@OlinLathrop: Cevabı netleştirdim. PIC16 terimini veri sayfasının 51. sayfasından aldım , ancak sadece "12 bitlik talimat setine" atıfta bulunmaya daha açık olduğuna karar verdim. Parça öneki, kullanılan komut seti için güvenilir bir rehber değildir.
Warren Young,

0

benim günümde bastonumu sallarken , kendi bitlerimizi kumdan kesmek zorunda kaldık!

1976'da (veya çevresinde) Atari 2600 VCS sistemi, zamanın en popüler "video oyun platformlarından" biriydi. İçinde mikroişlemci (MOSTEK 6507) yanan bir ~ 1 MHz'de çalışıyordu ve **** 128 byte RAM ** 'ye sahipti.

Son derece sınırlı RAM (~ 128 bytes) olan bir mikrodenetleyiciyi hatırladığım ikinci bir örnek , bir DC-DC dönüştürücüsünde kullanılan bir PIC12F idi. Bu mikro da çalıştırmak için assembly dili kullanmak zorunda kaldı.


4
OP RAM'den bahsetmiyor, program alanından bahsediyor. Atari 2600'deki program alanı, RIOT çipinde değil kartuşta . 2600, banka değiştirme olmadan 4 kB'ye kadar program ROM'larını destekledi. (Ve bazı ticari kartuşlar vermedi ! Banka geçiş yapmak) için PIC12F örneğin gelince, en got OP sen yendi: PIC10F20x serisi cihazlar SRAM 16 veya 24 bayt var.
Warren Young,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.