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

Например, PIC10F200T

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

65 голосов | спросил coder543 1 Maypm13 2013, 19:12:47

11 ответов


131

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

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

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

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

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

Изменить для добавления . Оказывается, вы можете реализовать первый в мире калькулятор стоимостью $ 100 в 320 словах.

Изменить для молодого пользователя:

  • Floppy = гибкий диск.
  • Bootblock = 1-й сектор дискеты, прочитанный при загрузке.
  • Demoscene = соревнования по программированию среди групп хакеров.
  • Assembler = фантастический способ программирования устройства, если вы слишком мягки, чтобы использовать 8 тумблеров и кнопку «store».
ответил John U 1 Maypm13 2013, 20:29:59
56

Микроконтроллеры достаточно дешевы, что они часто используются, чтобы делать действительно простые вещи, которые в прошлые годы, скорее всего, были бы сделаны с дискретной логикой. Действительно простые вещи. Например, может потребоваться, чтобы устройство включало вывод в течение одной секунды каждые пять секунд, точнее, чем таймер 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 байт) пространства кода. Можно было бы легко добавить несколько опций, чтобы иметь некоторые опции управления синхронизацией ввода-вывода и все еще иметь много места, чтобы сэкономить, но даже если бы весь чип сделал именно то, что показано выше, он все равно может быть дешевле и проще, чем любая альтернатива с использованием дискретных логика. BTW, команды clrwdt могут быть перемещены в подпрограмму, но это сделает вещи менее надежными. Как написано, даже если сбой приводит к повреждению стека обратного адреса, сторожевой таймер не будет получать питание до тех пор, пока выполнение не вернется в основной цикл. Если этого не произойдет, сторожевой таймер сбросит чип через пару секунд.

ответил supercat 1 Maypm13 2013, 19:27:56
26

"ТОЛЬКО" 384 байта?

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

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

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

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

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

ответил Richard T 3 Mayam13 2013, 00:51:08
20

Вы можете использовать это для очень маленьких приложений (например, начало отложенного PSU , 555 замена таймера ,

ответил Renan 1 Maypm13 2013, 19:19:10
17

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

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


Вот код, который я сделал для моего водяного датчика воды. Я использовал pic10f220 , так как у него есть модуль ADC, он имеет ту же память, что и 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.

ответил scrafy 2 Mayam13 2013, 01:21:07
16

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

ответил Mark Harrison 2 Mayam13 2013, 05:56:35
13

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

Таким образом, я потратил немало времени на изучение и понимание фазового освещения, использующего симисторы, и программирование 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 . Кстати, я никогда не показывал это своему учителю, но в конечном итоге сделал ряд осветительных установок для своего друга-ди-джея.

ответил Adam Davis 2 Maypm13 2013, 18:42:01
12

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

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

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

ответил lyndon 1 Maypm13 2013, 21:37:59
5

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

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

ответил Keelan 1 Maypm13 2013, 19:21:47
4

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

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

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

ответил Warren Young 4 Jpm1000000pmSun, 04 Jan 2015 16:14:31 +030015 2015, 16:14:31
0

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

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

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

ответил cowboydan 4 Jpm1000000pmSun, 04 Jan 2015 17:43:44 +030015 2015, 17:43:44

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132