Как можно использовать микроконтроллер, имеющий только 384 байта памяти программ?


67

Например, PIC10F200T

Практически любой код, который вы пишете, будет больше этого, если только это не чип специального назначения. Есть ли способ загрузить больше памяти программы из внешнего хранилища или что-то? Мне просто любопытно, я не понимаю, как это может быть очень полезно ... но это должно быть.


6
Существует множество приложений для крошечных микроконтроллеров, от генераторов сигналов специального назначения, до преобразователей протоколов, до «узлов» в более крупной системе управления и т. Д. И т. Д.,
Дейв Твид

13
Ну, программа игры в шахматы занимает 672 байта, так что это не хорошо. en.wikipedia.org/wiki/1K_ZX_Chess
Джон Бертон,

8
Вот несколько примеров того, что можно сделать с помощью крошечных программ (менее 256 байт).
Хаммар

9
Что вы имеете в виду, "если это не единственная цель чип"? Большинство встроенных систем имеют одно назначение.
Жанна Пиндар

6
Еще в колледже я собрал полнофункциональную программу светофора для компьютера 8085/8155 (максимум 256 байт), который я собрал. У него были кнопки для ходьбы и некоторые датчики, которые имитировали бы присутствие автомобиля.
Zoredache

Ответы:


133

Вы, дети, сойдите с моей лужайки!

384 байта - это достаточно места для создания чего-то достаточно сложного в ассемблере.

Если вы вернетесь назад к истории, когда компьютеры были размером с комнату, вы обнаружите некоторые действительно удивительные художественные умения, выполненные в <1k.

Например, прочитайте классическую историю Мел - Настоящий программист . По общему признанию, у тех парней было 4096 слов памяти, чтобы играть с декадентскими неверными.

Также посмотрите на некоторые из старых конкурсов демосцены, где задача заключалась в том, чтобы вставить «вступление» в загрузочный блок дискеты, типичные цели - 4 или 40 тысяч, и обычно им удается включать музыку и анимацию.

Редактировать, чтобы добавить : Оказывается, вы можете реализовать первый в мире научный калькулятор за 100 долларов за 320 слов.

Отредактируйте для молодых 'uns:

  • Дискета = дискета
  • Bootblock = 1 сектор чтения дискеты при загрузке.
  • Демосцена = соревнования по программированию среди хакерских групп.
  • Ассемблер = модный способ программирования устройства, если вы слишком мягки, чтобы использовать 8 тумблеров и кнопку «сохранить».

4
Игровая консоль Atari 2600 имела только 4 КБ памяти в игровых картриджах ПЗУ (хотя некоторые игры обошли это ограничение, используя переключение банков для доступа к более чем 4 КБ).
Джонни

1
Несколько лет назад я сделал довольно реалистичный птичий щебет (достаточно, чтобы люди искали птицу, а не подозревали компьютер), кишки которой (но не случайный код, который мешал бы ему издавать точно один и тот же звук каждый раз) дребезжали бы примерно в 384 байта, и у меня были дополнительные ограничения на отсутствие записываемых адресов, и нулевой байт не был разрешен в двоичном файле.
Лорен Печтел

2
Мне нужно больше вылезать, вспомнил об этом в былые времена
Джон U

7
+1 для "Истории Мела". Одна из величайших вещей, которые я читал всю неделю.
Джастин,

1
@JohnU: Первые несколько игр на Atari 2600 были 2K. Многие разработчики никогда не создавали игр, которые выходили за рамки 4K, потому что хотя 8K-чипы были доступны (а некоторые компании просто использовали половину 4K-чипа), добавляя переключение банков на карту с помощью стандартного (active-low-select-select). Чип увеличил количество опорных фишек с одного до трех.
суперкат

59

Микроконтроллеры достаточно дешевы, так что их часто используют для выполнения действительно простых вещей, которые в прошлые годы, скорее всего, делались бы с дискретной логикой. Действительно простые вещи. Например, может потребоваться, чтобы устройство включало выход на одну секунду каждые пять секунд, точнее, чем это мог бы сделать таймер 555.

  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

Это было бы реальным, пригодным для использования приложением, содержащим менее 32 слов (48 байт) пространства кода Можно было бы легко добавить несколько опций, чтобы иметь несколько опций синхронизации входов / выходов и при этом иметь достаточно места, чтобы сэкономить, но даже если бы весь чип был именно таким, как показано выше, он все равно мог бы быть дешевле и проще, чем любая альтернатива, использующая дискретный логика. Кстати, clrwdtинструкции можно было бы перенести в подпрограмму, но это сделало бы вещи менее надежными. Как написано, даже если сбой приводит к повреждению стека адреса возврата, сторожевой таймер не получит питание, пока выполнение не вернется в основной цикл. Если этого не произойдет, сторожевой таймер сбросит микросхему через пару секунд.


9
Честно говоря, вы могли бы немного оптимизировать свой код, подав плохой пример детям - 5 отдельных вызовов wait1sec ??? Мот! ;)
Джон У

9
@JohnU: к вашему сведению, код использует отдельные вызовы, потому что если бы он использовал счетчик с нулевым счетчиком и счетчик сбился, цикл мог бы выполняться 255 раз, а не четыре, при подаче сторожевого таймера один раз в секунду. Хотя можно было бы защититься от этого, проверяя в каждом цикле, находится ли счетчик в диапазоне, код, который должен это сделать, оказывается более сложным, чем пять вызовов и пять clrwdtинструкций. Это не самое безотказное устройство счетчика, но некоторые вопросы уделяются безопасности (например, избегание clrwdtподпрограммы).
суперкат

10
@ coder543: При отсутствии таких вещей, как шум источника питания, не очень. С другой стороны, в деталях без детектора отключения возможно возникновение всевозможных сумасшедших событий, если VDD падает до уровня между минимальным рабочим напряжением и землей, а затем возвращается к нормальному состоянию. Как правило, следует стараться обеспечить, чтобы любое состояние, в котором может оказаться устройство, вернулось к нормальному состоянию за разумный период времени. Примерно две секунды для включения сторожевого таймера могут быть неизбежны, но четыре минуты для сбитого счетчика до нуля могут быть немного больше.
суперкат

10
@ coder543, они происходят чаще на важной демонстрации, чем вы хотите верить. Такое мышление также необходимо при создании глубоко укоренившихся вещей, у которых нет средств для вызова помощи или сообщения об ошибке. Или недоступны (подумайте о глубоком море или космосе), даже если ошибка действительно была замечена.
RBerteig

6
@JohnU: я это заметил, но подумал, что объяснение, почему я написал код так, как я сделал, может быть полезным. Кстати, я также пытался показать, что небольшие задачи могут уместиться в небольшом процессоре, даже если они не полностью оптимизированы.
суперкат

26

«ТОЛЬКО» 384 байта?

Еще в тот день у меня была работа над написанием целой операционной системы (для меня самой) для специализированного компьютера, который обслуживал судостроительную, трубопроводную и нефтеперерабатывающую промышленность. Первый такой продукт компании был основан на 6800 и обновлялся до 6809, и они хотели, чтобы новая ОС соответствовала 6809, чтобы они могли исключить затраты на лицензию исходной операционной системы. Они также увеличили размер загрузочного диска до 64 байт, по сравнению с 32. Если я правильно помню - это было около 33 лет назад! - Я убедил инженеров выдать мне 128 байтов, чтобы я мог поставить драйверы всей операционной системы на диск и, таким образом, сделать все устройство более надежным и универсальным. Это включало:

  • Драйвер клавиатуры с ключом debounce
  • Видеодрайвер
  • Драйвер дисковода и элементарная файловая система (Motorola «abloader format», IIRC) со встроенной возможностью обрабатывать «накопленную» память так, как если бы это было действительно очень быстрое дисковое пространство.
  • Драйвер модема (они получили FSK задом наперед, поэтому эти модемы только общались друг с другом)

Да, все они были настолько просты, насколько это возможно, и были оптимизированы вручную, чтобы удалить каждый посторонний цикл, но отлично работоспособны и надежны. Да, я включил все это в доступные байты - о, он также настроил обработку прерываний, различные стеки и инициализировал операционную систему реального времени / многозадачность, запросил у пользователя параметры загрузки и загрузил систему.

Мой друг, который все еще связан с компанией (ее преемник), сказал мне несколько лет назад, что мой код все еще работает!

Вы можете сделать много с 384 байтами ...


2
вы говорите «boot rom» и упоминаете о перемещении драйверов на «boot rom» ... это указывает на то, что был доступен дополнительный носитель данных. В этом обсуждении мы уже определили, что вы не можете загрузить код из внешнего хранилища на этом PIC.
coder543

5
@ coder543 Это упускает из виду: 384 байта достаточно, чтобы сделать довольно много! Первоначальный вопрос звучал как жалоба на то, что 384 было недостаточно для того, чтобы сделать что-то полезное - это было больше, чем мне было нужно - НАМНОГО больше - чтобы обеспечить все основные компоненты многозадачной операционной системы реального времени ...
Ричард Т

21

Вы можете использовать это для очень небольших приложений (например, отсрочка запуска блока питания , замена таймера 555 , управление на основе симистора , мигание светодиода и т. Д.) С меньшей занимаемой площадью, чем при использовании логических вентилей или таймера 555.


3
Я только заметил, что эти первые два примера были из самого стека! отлично сработано.
coder543

9
+1 за упоминание следа. Иногда размер это все.
embedded.kyle

17

Я разработал датчик влажности для растений, который отслеживает количество воды, которое есть у растения, и мигает светодиодом, если растению нужна вода. Вы можете заставить датчик узнать тип растения и, таким образом, изменить его настройки во время работы. Он обнаруживает низкое напряжение на батарее. У меня закончились флэш-память и оперативная память, но я смог написать все на С-коде, чтобы этот продукт работал безупречно.

Я использовал pic10f, который вы упомянули.


Вот код, который я сделал для моего датчика растительной воды. Я использовал pic10f220, так как у него есть модуль АЦП, он имеет ту же память, что и у pic10f200, я постараюсь найти схему завтра.

Код написан на испанском языке, но он очень прост и должен быть легко понят. Когда Pic10F выйдет из спящего режима, он будет сброшен, поэтому вам нужно проверить, было ли это PowerUp или сбросом, и действовать соответственно. Урегулирование завода держится в поршне, так как оно никогда не выключается.

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

Дайте мне знать, если у вас есть вопросы, я постараюсь ответить на основании того, что я помню. Я кодировал это несколько лет назад, так что не проверяйте мои навыки кодирования, они улучшились :).

Последнее замечание Я использовал компилятор Hi-Tech C.


3
На самом деле мне было бы очень интересно прочитать, как ты это сделал. Делали ли вы какие-либо заметки, когда делали это, и не хотели бы делиться ими в сети?
RhysW

1
Привет RhysW, я думаю, у меня все еще есть код. Это было действительно просто на самом деле. Я мог бы выслать вам мой код, если вы заинтересованы. Дайте мне знать. Схема, которую я разработал, очень простая и крутая, всего 3 резистора, один p-канальный MOSFET (для защиты батареи от обратного хода), крышка 100 нФ и светодиод. Я использую и внутренний диод в pic10f, чтобы использовать его как эталон для измерения батареи и поддерживать постоянные показания АЦП.
scrafy

1
Это звучит как аккуратный проект. Есть ли шанс, что вы могли бы опубликовать детали здесь (или, по крайней мере, опубликовать их где-нибудь и дать ссылку на них)?
Илмари Каронен

1
Привет скрэфи! Пожалуйста, если у вас есть что добавить к ответу, используйте ссылку "изменить" вместо публикации нового ответа, так как этот сайт использует голосование и не работает как форум.
Клабаккио

16

Одна вещь, о которой я не упомянул: упомянутый вами микроконтроллер стоит всего $ 0,34 каждый в количестве 100. Поэтому для дешевых продуктов массового производства может иметь смысл пойти на дополнительные проблемы с кодированием, вызванные таким ограниченным модулем. То же самое может относиться к размеру или потребляемой мощности.


2
Это была моя первая мысль. Кроме того: если бы я был стартапом с аккуратной идеей, но потерял бы всего несколько сотен долларов, подобные вещи могут означать разницу между возвращением на работу и уходом с работы.
Френель

14

Когда я учился в старшей школе, у меня был учитель, который настаивал на том, что затемнение света было слишком трудной задачей для такого ученика, как я.

Поэтому я потратил немало времени на изучение и понимание фазового затемнения света с помощью триаков и программирования 16C84 из микрочипа для выполнения этого подвига. Я закончил с этим кодом сборки:

'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

Конечно, вам нужно изменить это для упомянутого чипа и, возможно, добавить дешевую последовательную подпрограмму для ввода, поскольку у вашего чипа нет 8-битного порта для прослушивания, но идея в том, что, казалось бы, сложная работа может быть сделано очень мало кода - вы можете разместить десять экземпляров вышеупомянутой программы в 10F200.

Вы можете найти больше информации о проекте на моей странице Light Dimming . Между прочим, я никогда не показывал это своему учителю, но в итоге сделал несколько осветительных установок для моего друга ди-джея.


12

Ну, много лет назад я написал контроллер температуры с последовательным вводом / выводом (битовый последовательный ввод / вывод, потому что у MCU не было UART) и простой интерпретатор команд для общения с контроллером. MCU был Motorola (теперь Freescale) MC68HC705K1, который имел колоссальные 504 байта памяти программ (OTPROM) и около 32 байтов оперативной памяти. Не так мало, как PIC, на который вы ссылаетесь, но я помню, что осталось немного ROM. У меня еще осталось несколько собранных узлов, 17 лет спустя; хочешь купить?

Так что да, это можно сделать, по крайней мере, в сборе.

В любом случае, я недавно написал очень простые программы на Си, которые при оптимизации могли бы уместиться в 384 байта. Не все требует большого, сложного программного обеспечения.


5

Вы можете написать мигающий светодиод с 384 байтами памяти программ и даже больше.

Насколько я знаю, невозможно расширить память программы внешним чипом (если только вы не строите полный интерпретатор ASM в 384 байта , что будет медленно). Можно расширить память данных с помощью внешнего чипа (EEPROM, SRAM).


1
Нетрудно построить симулятор машины Тьюринга в 384 байта ...
Крис Страттон

@ChrisStratton Я имел в виду полный переводчик, чтобы «расширенная память программ» имела те же функции, что и обычные.

Да, это то, что я предложил средство жесткой реализации. Все остальное - просто дизайн компилятора ...
Крис Страттон

7
Если кто-то хочет, чтобы программная логика была сохранена во внешней EEPROM, попытка эмулировать набор команд PIC не была бы подходящим способом. Лучшим подходом было бы разработать набор инструкций, оптимизированный для использования с виртуальной машиной; действительно, именно такой подход Параллакс использовал в своей «Базовой марки» в 1990-х годах. Это была PIC с 3072 байтами кодового пространства в сочетании с последовательным чипом EEPROM.
суперкат

3
Кстати, еще одно замечание о марке BASIC: она была введена в то время, когда микроконтроллеры на базе флэш-памяти или на основе EEPROM были сравнительно редкими, но серийные микросхемы EEPROM были довольно дешевыми. Для приложений, которым не нужна большая скорость, микросхема с фиксированным кодом с последовательной частью EEPROM будет дешевле, чем микросхема EEPROM сопоставимого размера или микропрограмма на основе флэш-памяти. Дизайн BASIC Stamp сегодня не будет иметь смысла, но он был довольно практичным, когда он был представлен.
суперкат

4

Это на самом деле хуже, чем вы думаете. Ваша связанная страница Mouser сбивает с толку вопросы, когда она определяет этот процессор как имеющий 384 байта памяти программ. PIC10F200 на самом деле имеет 256 12-битных слов памяти программ.

Итак, что вы можете сделать с этим? Все 12-битные инструкции PIC, используемые устройствами PIC10F20 x, представляют собой инструкции, состоящие из одного слова, поэтому после того, как вы вычтете несколько инструкций для настройки процессора, у вас останется достаточно места для программы длиной около 250 шагов. Этого достаточно для многих приложений. Я мог бы, например, написать контроллер стиральной машины в таком месте.

Я только что просмотрел доступные компиляторы PIC C, и похоже, что около половины из них даже не будут пытаться выдавать код для PIC10F200. Те, которые, вероятно, выдают так много стандартного кода, что вы можете только написать светодиодный индикатор в оставшееся место. Вы действительно хотите использовать ассемблер с таким процессором.


Вы правы насчет 256 инструкций. На самом деле один из них используется с постоянной калибровки генератора, поэтому вы получаете 255 полезных инструкций. Кроме того, 10F200 не использует обычный 14-битный набор команд PIC 16. Он использует 12-битный набор команд PIC 12. Тем не менее, я согласен с вашими основными предпосылками. Я сделал много полезных вещей с PIC 10F200. +1
Олин Латроп

@OlinLathrop: я уточнил ответ. Я получил термин PIC16 на странице 51 таблицы данных , но я решил, что более просто сослаться на «12-битный набор инструкций». Префикс детали не является надежным руководством к используемому набору инструкций.
Уоррен Янг

0

размахивая тростью в наше время, мы должны были вытравить свои кусочки из песка!

В 1976 году (или около того) система Atari 2600 VCS была одной из самых популярных «игровых платформ» того времени. В нем микропроцессор (MOSTEK 6507) работал на частоте ~ 1 МГц и имел **** 128 байт ОЗУ **.

Второй пример, который я помню о микроконтроллере с чрезвычайно ограниченным объемом ОЗУ (~ 128 байт), был PIC12F, используемый в преобразователе постоянного тока. Этот микро также должен был использовать язык ассемблера, чтобы бежать вообще.


4
ОП не говорит об оперативной памяти, он говорит о программном пространстве. Пространство программы в Atari 2600 находится в картридже, а не в чипе RIOT . 2600 поддерживаемых программных ПЗУ до 4 КБ без переключения банков. (И некоторые коммерческие картриджи делали банковские смены!) Что касается вашего примера PIC12F, операционная система вас одолела: устройства серии PIC10F20x имеют либо 16, либо 24 байта SRAM.
Уоррен Янг
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.