Làm thế nào bất cứ ai cũng có thể sử dụng một vi điều khiển chỉ có 384 byte bộ nhớ chương trình?


67

Ví dụ: PIC10F200T

Hầu như bất kỳ mã nào bạn viết sẽ lớn hơn thế, trừ khi đó là một chip mục đích duy nhất. Có cách nào để tải thêm bộ nhớ chương trình từ bộ nhớ ngoài hay không? Tôi chỉ tò mò, tôi không thấy làm thế nào điều này có thể rất hữu ích ... nhưng nó phải như vậy.


6
Có rất nhiều ứng dụng cho các bộ vi điều khiển nhỏ, từ bộ tạo tín hiệu chuyên dụng, đến bộ chuyển đổi giao thức, đến "nút" trong một hệ thống điều khiển lớn hơn, v.v., v.v.,
Dave Tweed

13
Chà, một chương trình chơi cờ mất 672 byte nên không tốt. vi.wikipedia.org/wiki/1K_ZX_Chess
John Burton

8
Dưới đây là một số ví dụ về những gì có thể được thực hiện với các chương trình nhỏ (dưới 256 byte).
hammar

9
Ý bạn là gì, "trừ khi nó là chip đơn mục đích"? Phần lớn các hệ thống nhúng là mục đích duy nhất.
Jeanne Pindar

6
Quay trở lại trường đại học, tôi đã xây dựng một chương trình đèn giao thông đầy đủ chức năng cho một máy tính 8085/8155 (tối đa 256 byte) tôi lắp ráp. Nó có các nút đi bộ và một số cảm biến sẽ mô phỏng sự hiện diện của một chiếc xe.
Zoredache

Câu trả lời:


133

Các em, hãy ra khỏi bãi cỏ của tôi!

384 byte có nhiều không gian để tạo ra thứ gì đó khá phức tạp trong trình biên dịch chương trình.

Nếu bạn tìm hiểu lại lịch sử cho đến khi máy tính có kích thước của một căn phòng, bạn sẽ tìm thấy một số kỳ công nghệ thuật thực sự tuyệt vời được thực hiện trong <1k.

Ví dụ, đọc Câu chuyện kinh điển của Mel - Một lập trình viên thực sự . Phải thừa nhận rằng, những kẻ đó có 4096 từ để ghi nhớ, những kẻ ngoại đạo suy đồi.

Ngoài ra, hãy xem một số cuộc thi demoscene cũ trong đó thử thách là điều chỉnh "phần giới thiệu" vào phần mềm khởi động của đĩa mềm, mục tiêu điển hình là 4k hoặc 40k và thường quản lý để bao gồm âm nhạc và hoạt hình.

Chỉnh sửa để thêm : Hóa ra bạn có thể triển khai máy tính khoa học 100 đô la đầu tiên trên thế giới trong 320 từ.

Chỉnh sửa cho giới trẻ 'uns:

  • Đĩa mềm = đĩa mềm.
  • Bootblock = khu vực đầu tiên của đĩa mềm đọc khi khởi động.
  • Demoscene = các cuộc thi lập trình giữa các nhóm hacker.
  • Trình biên dịch = cách lập trình ưa thích của một thiết bị nếu bạn quá mềm để sử dụng 8 công tắc bật tắt và nút "lưu trữ".

4
Bảng điều khiển trò chơi Atari 2600 chỉ có 4KB dung lượng lưu trữ trong các hộp trò chơi ROM (mặc dù một số trò chơi đã vượt qua giới hạn này bằng cách sử dụng chuyển đổi ngân hàng để truy cập nhiều hơn 4K).
Johnny

1
Cách đây một lần, tôi đã tạo ra một tiếng chim hót khá thực tế (đủ để mọi người tìm kiếm con chim chứ không phải nghi ngờ máy tính), nhưng điều đó (nhưng không phải là mã ngẫu nhiên giữ cho nó không phát ra âm thanh giống hệt nhau mỗi lần) khoảng 384 byte và tôi có các hạn chế bổ sung không có địa chỉ có thể ghi và byte không được phép trong nhị phân.
Loren Pechtel

2
Tôi cần phải ra ngoài nhiều hơn, ghi nhớ điều này từ ngày trước - trình bảo vệ màn hình trong 368 byte: aminet.net/package/util/blank/368blanker
John U

7
+1 cho "Câu chuyện về Mel". Một trong những điều tuyệt vời nhất mà tôi đã đọc cả tuần.
Justin

1
@ John: Vài trò chơi đầu tiên trên Atari 2600 đều là 2K. Nhiều nhà phát triển không bao giờ thiết kế bất kỳ trò chơi nào vượt quá 4K, bởi vì mặc dù chip 8K có giá cả phải chăng (và xe của một số công ty chỉ sử dụng một nửa chip 4K) thêm chuyển đổi ngân hàng sang thẻ bằng cách sử dụng tiêu chuẩn (chọn chip thấp hoạt động) chip tăng số lượng chip hỗ trợ từ một lên ba.
supercat

59

Vi điều khiển đủ rẻ đến mức chúng thường được sử dụng để làm những việc thực sự đơn giản mà trong những năm qua nhiều khả năng sẽ được thực hiện với logic rời rạc. Những điều thực sự đơn giản. Ví dụ, người ta có thể muốn một thiết bị bật đầu ra trong một giây cứ sau 5 giây, chính xác hơn là có thể thực hiện được một bộ đếm thời gian 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

Đó sẽ là một ứng dụng thực tế, có thể sử dụng được, với ít hơn 32 từ (48 byte) không gian mã. Người ta có thể dễ dàng thêm một vài tùy chọn để có một số tùy chọn điều khiển thời gian chân I / O và vẫn còn nhiều chỗ trống, nhưng ngay cả khi tất cả các con chip đã làm chính xác những gì được hiển thị ở trên, nó vẫn có thể rẻ hơn và dễ dàng hơn bất kỳ thay thế nào sử dụng rời rạc logic VCL. BTW, các clrwdthướng dẫn có thể được chuyển vào chương trình con, nhưng làm như vậy sẽ khiến mọi thứ trở nên kém mạnh mẽ hơn. Như đã viết, ngay cả khi trục trặc khiến ngăn xếp địa chỉ trả về bị hỏng, bộ giám sát sẽ không được cung cấp cho đến khi thực thi trở lại vòng lặp chính. Nếu điều đó không bao giờ xảy ra, cơ quan giám sát sẽ thiết lập lại chip sau vài giây.


9
Thành thật mà nói, bạn có thể tối ưu hóa mã của mình một chút, làm gương xấu cho trẻ em - 5 cuộc gọi riêng biệt để chờ1sec ??? Trung tâm! ;)
John U

9
@ John: FYI, mã sử dụng các cuộc gọi riêng biệt bởi vì nếu nó sử dụng bộ đếm đếm bằng 0 và số đếm bị trục trặc, vòng lặp có thể chạy 255 lần thay vì bốn lần, trong khi cho bộ theo dõi một lần mỗi giây. Mặc dù có thể bảo vệ chống lại điều đó bằng cách kiểm tra trên mỗi vòng lặp xem số đếm có nằm trong phạm vi hay không, mã để thực hiện điều đó kết thúc phức tạp hơn năm cuộc gọi và năm clrwdthướng dẫn. Đây không phải là sự sắp xếp bộ đếm hoàn toàn không an toàn nhất có thể, nhưng một số xem xét được đưa ra cho các vấn đề an toàn (ví dụ như tránh clrwdttrong chương trình con).
supercat

10
@ coder543: Trong trường hợp không có những thứ như tiếng ồn cung cấp điện, thì không. Mặt khác, ở những bộ phận không có máy dò màu nâu, có thể xảy ra tất cả những điều điên rồ nếu VDD rơi xuống mức giữa điện áp hoạt động tối thiểu và mặt đất, và sau đó tăng trở lại bình thường. Nhìn chung, mọi người nên cố gắng đảm bảo rằng bất kỳ trạng thái nào mà thiết bị có thể tự tìm lại sẽ trở lại bình thường trong một khoảng thời gian hợp lý. Hai giây hoặc lâu hơn để cơ quan giám sát đá vào có thể là không thể tránh khỏi, nhưng bốn phút để một bộ đếm bị trục trặc đạt đến số 0 có thể là một chút nhiều.
supercat

10
@ coder543, chúng xảy ra thường xuyên hơn ở một bản demo quan trọng hơn bạn muốn tin. Kiểu suy nghĩ này cũng được yêu cầu khi xây dựng những thứ được nhúng sâu mà không có cách nào để gọi trợ giúp hoặc báo cáo lỗi. Hoặc không thể truy cập (nghĩ biển sâu hoặc không gian bên ngoài) ngay cả khi một lỗi đã được chú ý.
RBerteig

6
@ John: Tôi đã chú ý đến nó, nhưng hình dung rằng việc giải thích lý do tại sao tôi viết mã như tôi có thể hữu ích. Tình cờ, tôi cũng đang cố gắng chỉ ra rằng các tác vụ nhỏ có thể phù hợp với bộ xử lý nhỏ ngay cả khi chúng không được tối ưu hóa hoàn hảo.
supercat

26

"CHỈ" 384 byte?

Quay trở lại vào ban ngày, tôi có công việc viết toàn bộ hệ điều hành (một mình) cho một máy tính chuyên dụng phục vụ cho ngành công nghiệp quản lý tàu, đường ống và nhà máy lọc dầu. Sản phẩm đầu tiên của công ty là 6800 dựa trên và đang được nâng cấp lên 6809 và họ muốn có một hệ điều hành mới đi cùng với 6809 để họ có thể loại bỏ chi phí cấp phép của hệ điều hành gốc. Họ cũng đã tăng kích thước của rom boot lên 64 byte, tăng từ 32. Nếu tôi nhớ lại chính xác - đó là khoảng 33 năm trước! - Tôi đã thuyết phục các kỹ sư cung cấp cho tôi 128 byte để tôi có thể đưa trình điều khiển thiết bị của toàn bộ hệ điều hành lên rom và do đó làm cho toàn bộ thiết bị trở nên đáng tin cậy và linh hoạt hơn. Cái này bao gồm:

  • Trình điều khiển bàn phím với phím gỡ lỗi
  • Trình điều khiển video
  • Trình điều khiển ổ đĩa và hệ thống tệp thô sơ (Motorola "định dạng abloader", IIRC), với khả năng tích hợp để xử lý bộ nhớ "đánh dấu" như thể nó là không gian đĩa rất nhanh.
  • Trình điều khiển Modem (họ có FSK ngược, vì vậy các modem này chỉ nói chuyện với nhau)

Vâng, tất cả những thứ này đều như xương trần, và được tối ưu hóa bằng tay để loại bỏ mọi chu kỳ ngoại lai, nhưng hoàn toàn có thể phục vụ và đáng tin cậy. Có, tôi đã chuyển tất cả các byte đó vào các byte có sẵn - ồ, nó CSONG thiết lập xử lý ngắt, các ngăn xếp khác nhau và khởi tạo hệ điều hành thời gian thực / đa tác vụ, nhắc người dùng về các tùy chọn khởi động và khởi động hệ thống.

Một người bạn của tôi vẫn còn liên kết với công ty (người kế nhiệm của nó) đã nói với tôi vài năm trước rằng mã của tôi vẫn đang phục vụ!

Bạn có thể thực hiện RẤT NHIỀU với 384 byte ...


2
bạn nói boot rom và bạn đề cập đến việc di chuyển trình điều khiển lên rom boot ... điều này cho tôi biết rằng đã có phương tiện lưu trữ thứ cấp. Trong cuộc thảo luận này, chúng tôi đã xác định rằng bạn không thể tải mã từ bộ nhớ ngoài trên PIC này.
coder543

5
@ coder543 Điều đó không đúng: 384 byte là đủ để làm khá nhiều việc! Câu hỏi ban đầu giống như một lời phàn nàn rằng 384 không đủ để làm bất cứ điều gì hữu ích - nó nhiều hơn tôi cần - rất nhiều - để cung cấp tất cả các thành phần cơ bản của hệ điều hành đa tác vụ thời gian thực ...
Richard T

21

Bạn có thể sử dụng điều này cho các ứng dụng rất nhỏ (ví dụ: khởi động PSU bị trì hoãn , thay thế bộ hẹn giờ 555 , điều khiển dựa trên triac , nhấp nháy LED, v.v.) với dấu chân nhỏ hơn bạn cần với cổng logic hoặc bộ hẹn giờ 555.


3
Tôi chỉ nhận thấy rằng hai ví dụ đầu tiên là từ chính Stack! chơi tốt
coder543

9
+1 để đề cập đến dấu chân. Đôi khi kích thước là tất cả.
embed.kyle

17

Tôi đã thiết kế một cảm biến độ ẩm cho các nhà máy theo dõi lượng nước mà cây có và nhấp nháy đèn LED nếu cây cần nước. Bạn có thể làm cho cảm biến tìm hiểu loại cây và do đó thay đổi cài đặt của nó trong khi chạy. Nó phát hiện điện áp thấp trên pin. Tôi đã hết flash và ram nhưng đã có thể viết mọi thứ bằng mã C để làm cho sản phẩm này hoạt động hoàn hảo.

Tôi đã sử dụng pic10f mà bạn đề cập.


Đây là mã tôi đã tạo cho Bộ cảm biến nước thực vật của mình. Tôi đã sử dụng pic10f220 vì nó có mô-đun ADC, nó có cùng bộ nhớ với pic10f200, tôi sẽ cố gắng tìm sơ đồ vào ngày mai.

Mã này bằng tiếng Tây Ban Nha, nhưng nó rất đơn giản và nên dễ hiểu. Khi Pic10F thức dậy từ chế độ ngủ, nó sẽ thiết lập lại để bạn phải kiểm tra xem đó là PowerUp hay thiết lập lại và hành động tương ứng. Các thiết lập nhà máy được giữ trong ram vì nó không bao giờ thực sự tắt.

C CHÍNH

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

CHÍNH H.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

Hãy cho tôi biết nếu bạn có câu hỏi, tôi sẽ cố gắng trả lời dựa trên những gì tôi nhớ. Tôi đã mã hóa điều này vài năm trước để không kiểm tra kỹ năng mã hóa của mình, chúng đã được cải thiện :).

Lưu ý cuối cùng. Tôi đã sử dụng trình biên dịch Hi-Tech C.


3
Tôi thực sự rất thú vị khi đọc cách bạn làm điều này. Bạn đã có bất kỳ ghi chú nào trong khi bạn đang làm điều đó mà bạn không muốn chia sẻ trên web?
RhysW

1
Xin chào RhysW, tôi tin rằng tôi vẫn còn mã. Nó thực sự đơn giản. Tôi có thể gửi cho bạn mã của tôi nếu bạn quan tâm. Cho tôi biết. Mạch tôi thiết kế rất đơn giản và mát mẻ, chỉ có 3 điện trở, một mosfet kênh p (để bảo vệ pin đảo ngược) nắp 100nF và đèn LED. Tôi sử dụng và diode bên trong pic10f để sử dụng làm tài liệu tham khảo cho việc đo pin và để giữ cho số đọc ADC không đổi.
scrafy

1
Nghe có vẻ như một dự án gọn gàng. Có bất kỳ cơ hội nào bạn có thể đăng chi tiết ở đây (hoặc ít nhất là đăng chúng ở đâu đó và liên kết với chúng)?
Ilmari Karonen

1
Xin chào Xin vui lòng, nếu bạn có điều gì đó để thêm vào câu trả lời, hãy sử dụng liên kết "chỉnh sửa" thay vì đăng câu trả lời mới, vì trang web này sử dụng biểu quyết và không hoạt động như một diễn đàn.
clabacchio

16

Một điều mà tôi chưa từng thấy đề cập: Bộ vi điều khiển mà bạn đề cập chỉ có 0,34 đô la mỗi chiếc với số lượng 100. Vì vậy, đối với các sản phẩm sản xuất hàng loạt giá rẻ, có thể có ý nghĩa đối với sự cố mã hóa thêm do một đơn vị hạn chế như vậy. Điều tương tự có thể áp dụng cho kích thước hoặc tiêu thụ năng lượng.


2
Đó chính xác là suy nghĩ đầu tiên của tôi. Ngoài ra: Nếu tôi sẽ là một người khởi nghiệp với một ý tưởng gọn gàng, nhưng chỉ mất vài trăm đô la, những thứ như thế này có thể có nghĩa là sự khác biệt giữa công việc trở lại công việc hàng ngày và công việc hàng ngày.
phresnel

14

Khi tôi học cấp ba, tôi có một giáo viên khăng khăng rằng làm mờ ánh sáng là một nhiệm vụ quá khó đối với một học sinh như tôi để giải quyết.

Do đó, tôi đã dành khá nhiều thời gian để tìm hiểu và hiểu về việc làm mờ ánh sáng theo pha bằng cách sử dụng triacs và lập trình 16C84 từ vi mạch để thực hiện chiến công này. Tôi đã kết thúc với mã lắp ráp này:

'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

Tất nhiên, bạn cần sửa đổi điều này cho chip mà bạn đề cập và có thể thêm một thói quen nối tiếp giá rẻ cho đầu vào vì chip của bạn không có cổng rộng 8 bit để nghe, nhưng ý tưởng là một công việc có vẻ phức tạp có thể được thực hiện với rất ít mã - bạn có thể ghép mười bản sao của chương trình trên vào 10F200.

Bạn có thể tìm thêm thông tin dự án trên trang Light Dinkle của tôi . Ngẫu nhiên tôi chưa bao giờ trình bày điều này với giáo viên của mình, nhưng cuối cùng lại làm một số giàn đèn cho người bạn DJ của tôi.


12

Chà, nhiều năm trước tôi đã viết một bộ điều khiển nhiệt độ với I / O nối tiếp (đập vào I / O nối tiếp vì MCU không có UART) và một trình thông dịch lệnh đơn giản để nói chuyện với bộ điều khiển. MCU là một chiếc Motorola (nay là Freescale) MC68HC705K1 có bộ nhớ chương trình 504 byte (OTPROM) và khoảng 32 byte RAM. Không ít như PIC bạn tham khảo, nhưng tôi nhớ có một số ROM còn sót lại. Tôi vẫn còn một vài đơn vị lắp ráp còn lại, 17 năm sau; muốn mua một cái không?

Vì vậy, yeah, nó có thể được thực hiện, ít nhất là trong lắp ráp.

Trong mọi trường hợp, gần đây tôi đã viết các chương trình C rất đơn giản có thể phù hợp với 384 byte khi được tối ưu hóa. Không phải mọi thứ đều yêu cầu phần mềm lớn, phức tạp.


5

Bạn có thể viết một đèn LED nhấp nháy với bộ nhớ chương trình 384 byte và hơn thế nữa.

Theo tôi biết, không thể mở rộng bộ nhớ chương trình bằng chip ngoài (trừ khi bạn đang xây dựng trình thông dịch ASM đầy đủ trong 384 byte , sẽ chậm). Có thể mở rộng bộ nhớ dữ liệu bằng chip ngoài (EEPROM, SRAM).


1
Sẽ không khó để xây dựng một trình giả lập máy Turing trong 384 byte ...
Chris Stratton

@ChrisStratton Tôi có nghĩa là một thông dịch viên đầy đủ, do đó, 'bộ nhớ chương trình mở rộng' sẽ có các tính năng như bình thường.

Vâng, đó là những gì tôi đề xuất một phương tiện thực hiện chặt chẽ. Phần còn lại chỉ là thiết kế trình biên dịch ...
Chris Stratton

7
Nếu một người muốn logic chương trình được lưu trữ trong EEPROM bên ngoài, cố gắng mô phỏng tập lệnh PIC sẽ không phải là hướng đi. Một cách tiếp cận tốt hơn sẽ là thiết kế một tập lệnh được tối ưu hóa để sử dụng với máy ảo; thật vậy, đó là cách tiếp cận mà Parallax đã thực hiện với "STAMP cơ bản" của họ trong những năm 1990. Đó là một PIC có 3072 byte không gian mã, được ghép nối với một chip EEPROM nối tiếp.
supercat

3
BTW, một lưu ý bổ sung về tem BASIC: nó được giới thiệu vào thời điểm các bộ vi điều khiển dựa trên flash hoặc EEPROM tương đối hiếm, nhưng chip EEPROM nối tiếp có giá khá rẻ. Đối với các ứng dụng không cần nhiều tốc độ, một micro mã cố định có phần EEPROM nối tiếp sẽ rẻ hơn so với EEPROM có kích thước tương đương hoặc micro dựa trên flash. Thiết kế của BASIC Stamp sẽ không có ý nghĩa ngày hôm nay, nhưng nó khá thực tế khi được giới thiệu.
supercat

4

Nó thực sự tồi tệ hơn bạn nghĩ. Trang Mouser được liên kết của bạn gây nhầm lẫn khi nó chỉ định bộ xử lý này có 384 byte bộ nhớ chương trình. Các PIC10F200 thực sự có 256 12-bit từ bộ nhớ chương trình.

Vì vậy, bạn có thể làm gì với điều đó? Tập lệnh PIC 12 bit được các thiết bị PIC10F20 x sử dụng là tất cả các hướng dẫn một từ, vì vậy sau khi bạn trừ một vài hướng dẫn để thiết lập bộ xử lý, bạn sẽ có đủ không gian cho một chương trình khoảng 250 bước. Thế là đủ cho rất nhiều ứng dụng. Tôi có thể có thể viết một bộ điều khiển máy giặt trong loại không gian đó, ví dụ.

Tôi chỉ xem qua các trình biên dịch PIC C có sẵn và có vẻ như khoảng một nửa trong số họ thậm chí sẽ không thử phát mã cho PIC10F200. Những người có thể đưa ra rất nhiều mã soạn sẵn đến mức bạn chỉ có thể viết một đèn LED ở khoảng trống còn lại. Bạn thực sự muốn sử dụng ngôn ngữ lắp ráp với bộ xử lý như vậy.


Bạn nói đúng về 256 từ hướng dẫn. Trên thực tế, một trong số chúng được sử dụng với hằng số hiệu chuẩn dao động, vì vậy bạn nhận được 255 hướng dẫn có thể sử dụng. Ngoài ra, 10F200 không sử dụng tập lệnh 14 bit PIC 16 thông thường. Nó sử dụng tập lệnh PIC 12 12 bit. Tuy nhiên, tôi đồng ý với cơ sở cơ bản của bạn. Tôi đã thực hiện rất nhiều điều hữu ích với PIC 10F200. +1
Olin Lathrop

@OlinLathrop: Tôi đã làm rõ câu trả lời. Tôi đã nhận được thuật ngữ PIC16 từ trang 51 của bảng dữ liệu , nhưng tôi đã quyết định rõ ràng hơn khi chỉ tham khảo "tập lệnh 12 bit". Tiền tố một phần không phải là một hướng dẫn đáng tin cậy cho tập lệnh được sử dụng.
Warren Young

0

vẫy cây gậy của tôi trong ngày của tôi, chúng tôi đã phải khắc bit của chúng tôi ra khỏi cát!

Năm 1976 (hoặc gần đó), hệ thống Atari 2600 VCS là một trong những "nền tảng trò chơi video" phổ biến nhất thời bấy giờ. Trong đó, bộ vi xử lý (MOSTEK 6507) chạy ở tốc độ ~ 1 MHz và có **** 128 byte RAM **.

Một ví dụ thứ hai mà tôi nhớ về một vi điều khiển có RAM cực kỳ hạn chế (~ 128 byte) là PIC12F được sử dụng trên bộ chuyển đổi DC-DC. Micro này cũng phải sử dụng ngôn ngữ lắp ráp để chạy.


4
OP không nói về RAM, anh ấy nói về không gian chương trình. Không gian chương trình trong Atari 2600 nằm trong hộp mực, không phải trong chip RIOT . 2600 ROM chương trình được hỗ trợ lên tới 4 kiB mà không cần chuyển đổi ngân hàng. (Và một số hộp mực thương mại đã thực hiện chuyển đổi ngân hàng!) Đối với ví dụ PIC12F của bạn, OP đã giúp bạn đánh bại: các thiết bị dòng PIC10F20x có 16 hoặc 24 byte SRAM.
Warren Young
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.