Questa pagina spiega il funzionamento di uno strumento didattico scritto in HTML e JavaScript per programmare il microcontrollore Atmega328 (ad esempio quello di Arduino Uno) usando il linguaggio assembler e la Web Serial API.
La pagina presenta una textarea per inserire istruzioni assembler, due bottoni (per compilare e flashare il microcontrollore e per tradurre la pagina) e un'area di log per mostrare messaggi e stati.
<textarea id="input">sbi 4,5 sbi 5,5</textarea> <button id="compileBtn">Compila e Flash</button> <pre id="log"></pre>
Il microcontrollore interpreta le istruzioni assembler come codici macchina (opcode) a 16 bit. Il codice fa così:
sbi (Set Bit) e cbi (Clear Bit):
const opcodeMap = {
sbi: 0x9A00,
cbi: 0x9800,
};
mnemonico registro,bit (es. sbi 5,5).opcode = opcodeBase | (registro << 3) | bit
sbi 5,5:
0x9A00 | (5 << 3) | 5 = 0x9A00 | 0x28 | 0x05 = 0x9A2DIl microcontrollore viene programmato scrivendo pagine di memoria flash di 128 byte (64 istruzioni da 2 byte ciascuna). Il codice crea un buffer Uint8Array di 128 byte in cui inserisce le istruzioni codificate.
function createFlashPageMultiple(instructions) {
const buffer = new Uint8Array(128);
for (let i = 0; i < instructions.length && i < 64; i++) {
buffer[i * 2] = instructions[i] & 0xFF;
buffer[i * 2 + 1] = (instructions[i] >> 8) & 0xFF;
}
return buffer;
}
La comunicazione con il microcontrollore avviene usando la Web Serial API del browser e il protocollo di programmazione STK500.
SYNC (0x30 0x20) 3 volte per sincronizzarsi con il bootloader.
async function flashPage(port, buffer) {
const writer = port.writable.getWriter();
const reader = port.readable.getReader();
await sleep(1500); // attesa reset
for (let i = 0; i < 3; i++) {
await writer.write(Uint8Array.from([0x30, 0x20]));
await reader.read();
}
await writer.write(Uint8Array.from([0x50, 0x20]));
await reader.read();
await writer.write(Uint8Array.from([0x55, 0x80, 0x00, 0x20]));
await reader.read();
await writer.write(Uint8Array.from([0x64, 0x00, 0x80, 0x46]));
await writer.write(buffer);
await writer.write(Uint8Array.of(0x20));
await reader.read();
await writer.write(Uint8Array.from([0x51, 0x20]));
await reader.read();
writer.releaseLock();
reader.releaseLock();
}
Quando premi il bottone:
Questo strumento è un esempio semplice e didattico per capire:
Puoi usare e modificare questo codice per imparare e sperimentare la programmazione embedded da browser, senza tool esterni.