SlideShare una empresa de Scribd logo
1 de 20
Embedded JavaScript
Mikrocontroller programmieren… mit JavaScript?!
Jens Siebert (@jens_siebert)
WebMontag Kassel, 11. Juni 2018
https://www.slideshare.net/JensSiebert1
Mikrocontroller
Embedded Programmierung bisher…
Embedded Programmierung bisher…
Embedded Programmierung bisher…
#define XTAL (12000000UL) /* Oscillator frequency */
#define OSC_CLK ( XTAL) /* Main oscillator frequency */
#define RTC_CLK ( 32000UL) /* RTC oscillator frequency */
#define IRC_OSC ( 4000000UL) /* Internal RC oscillator
frequency */
/* F_cco0 = (2 * M * F_in) / N */
#define __M (((PLL0CFG_Val ) & 0x7FFF) + 1)
#define __N (((PLL0CFG_Val >> 16) & 0x00FF) + 1)
#define __FCCO(__F_IN) ((2ULL * __M * __F_IN) / __N)
#define __CCLK_DIV (((CCLKCFG_Val ) & 0x00FF) + 1)
/* Determine core clock frequency according to settings */
#if (PLL0_SETUP)
#if ((CLKSRCSEL_Val & 0x03) == 1)
#define __CORE_CLK (__FCCO(OSC_CLK) / __CCLK_DIV)
#elif ((CLKSRCSEL_Val & 0x03) == 2)
#define __CORE_CLK (__FCCO(RTC_CLK) / __CCLK_DIV)
#else
#define __CORE_CLK (__FCCO(IRC_OSC) / __CCLK_DIV)
#endif
#else
#if ((CLKSRCSEL_Val & 0x03) == 1)
#define __CORE_CLK (OSC_CLK / __CCLK_DIV)
#elif ((CLKSRCSEL_Val & 0x03) == 2)
#define __CORE_CLK (RTC_CLK / __CCLK_DIV)
#else
#define __CORE_CLK (IRC_OSC / __CCLK_DIV)
#endif
#endif
uint32_t SystemCoreClock = __CORE_CLK;/*!< System Clock Frequency (Core Clock)*/
void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */
{
/* Determine clock frequency according to clock register values */
if (((LPC_SC->PLL0STAT >> 24) & 3) == 3) { /* If PLL0 enabled and connected */
switch (LPC_SC->CLKSRCSEL & 0x03) {
case 0: /* Int. RC oscillator => PLL0 */
case 3: /* Reserved, default to Int. RC */
SystemCoreClock = (IRC_OSC *
((2ULL * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /
(((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1) /
((LPC_SC->CCLKCFG & 0xFF)+ 1));
break;
case 1: /* Main oscillator => PLL0 */
SystemCoreClock = (OSC_CLK *
((2ULL * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /
(((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1) /
((LPC_SC->CCLKCFG & 0xFF)+ 1));
break;
case 2: /* RTC oscillator => PLL0 */
SystemCoreClock = (RTC_CLK *
((2ULL * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) /
(((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1) /
((LPC_SC->CCLKCFG & 0xFF)+ 1));
break;
}
}
else {
switch (LPC_SC->CLKSRCSEL & 0x03) {
case 0: /* Int. RC oscillator => PLL0 */
case 3: /* Reserved, default to Int. RC */
SystemCoreClock = IRC_OSC / ((LPC_SC->CCLKCFG & 0xFF)+ 1);
break;
case 1: /* Main oscillator => PLL0 */
SystemCoreClock = OSC_CLK / ((LPC_SC->CCLKCFG & 0xFF)+ 1);
break;
case 2: /* RTC oscillator => PLL0 */
SystemCoreClock = RTC_CLK / ((LPC_SC->CCLKCFG & 0xFF)+ 1);
break;
}
}
}
Embedded Programmierung bisher…
#include <stdint.h>
#include "LPC17xx.h“
#define CLOCK_SETUP 1
#define SCS_Val 0x00000020
#define CLKSRCSEL_Val 0x00000001
#define PLL0_SETUP 1
#ifdef MCB1700
# define PLL0CFG_Val 0x00050063
# define PLL1_SETUP 1
# define PLL1CFG_Val 0x00000023
# define CCLKCFG_Val 0x00000003
# define USBCLKCFG_Val 0x00000000
#else
# define PLL0CFG_Val 0x0000000B
# define PLL1_SETUP 0
# define PLL1CFG_Val 0x00000000
# define CCLKCFG_Val 0x00000002
# define USBCLKCFG_Val 0x00000005
#endif
#define PCLKSEL0_Val 0x00000000
#define PCLKSEL1_Val 0x00000000
#define PCONP_Val 0x042887DE
#define CLKOUTCFG_Val 0x00000000
#define FLASH_SETUP 1
#define FLASHCFG_Val 0x0000303A
#define CHECK_RANGE(val, min, max) ((val < min) || (val > max))
#define CHECK_RSVD(val, mask) (val & mask)
if (CHECK_RSVD((SCS_Val), ~0x00000030))
#error "SCS: Invalid values of reserved bits!"
#endif
#if (CHECK_RANGE((CLKSRCSEL_Val), 0, 2))
#error "CLKSRCSEL: Value out of range!"
#endif
#if (CHECK_RSVD((PLL0CFG_Val), ~0x00FF7FFF))
#error "PLL0CFG: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((PLL1CFG_Val), ~0x0000007F))
#error "PLL1CFG: Invalid values of reserved bits!"
#endif
#if (PLL0_SETUP) /* if PLL0 is used */
#if (CCLKCFG_Val < 2) /* CCLKSEL must be greater then 1 */
#error "CCLKCFG: CCLKSEL must be greater then 1 if PLL0 is used!"
#endif
#endif
#if (CHECK_RANGE((CCLKCFG_Val), 2, 255))
#error "CCLKCFG: Value out of range!"
#endif
#if (CHECK_RSVD((USBCLKCFG_Val), ~0x0000000F))
#error "USBCLKCFG: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((PCLKSEL0_Val), 0x000C0C00))
#error "PCLKSEL0: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((PCLKSEL1_Val), 0x03000300))
#error "PCLKSEL1: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((PCONP_Val), 0x10100821))
#error "PCONP: Invalid values of reserved bits!"
#endif
#if (CHECK_RSVD((CLKOUTCFG_Val), ~0x000001FF))
#error "CLKOUTCFG: Invalid values of reserved bits!"
#endif
/* Flash Accelerator Configuration ------------------------*/
#if (CHECK_RSVD((FLASHCFG_Val), ~0x0000F07F))
#error "FLASHCFG: Invalid values of reserved bits!"
#endif
Embedded Programmierung bisher…
void SystemInit (void)
{
#if (CLOCK_SETUP) /* Clock Setup */
LPC_SC->SCS = SCS_Val;
if (LPC_SC->SCS & (1 << 5)) { /* If Main Oscillator is enabled */
while ((LPC_SC->SCS & (1<<6)) == 0);/* Wait for Oscillator to be ready */
}
LPC_SC->CCLKCFG = CCLKCFG_Val; /* Setup Clock Divider */
/* Periphral clock must be selected before PLL0 enabling and connecting
* - according errata.lpc1768-16.March.2010 -
*/
LPC_SC->PCLKSEL0 = PCLKSEL0_Val; /* Peripheral Clock Selection */
LPC_SC->PCLKSEL1 = PCLKSEL1_Val;
#if (PLL0_SETUP)
LPC_SC->CLKSRCSEL = CLKSRCSEL_Val; /* Select Clock Source for PLL0 */
LPC_SC->PLL0CFG = PLL0CFG_Val; /* configure PLL0 */
LPC_SC->PLL0FEED = 0xAA;
LPC_SC->PLL0FEED = 0x55;
LPC_SC->PLL0CON = 0x01; /* PLL0 Enable */
LPC_SC->PLL0FEED = 0xAA;
LPC_SC->PLL0FEED = 0x55;
while (!(LPC_SC->PLL0STAT & (1<<26)));/* Wait for PLOCK0 */
LPC_SC->PLL0CON = 0x03; /* PLL0 Enable & Connect */
LPC_SC->PLL0FEED = 0xAA;
LPC_SC->PLL0FEED = 0x55;
while (!(LPC_SC->PLL0STAT & ((1<<25) | (1<<24))));/* Wait for PLLC0_STAT & PLLE0_STAT */
#endif
#if (PLL1_SETUP)
LPC_SC->PLL1CFG = PLL1CFG_Val;
LPC_SC->PLL1FEED = 0xAA;
LPC_SC->PLL1FEED = 0x55;
LPC_SC->PLL1CON = 0x01; /* PLL1 Enable */
LPC_SC->PLL1FEED = 0xAA;
LPC_SC->PLL1FEED = 0x55;
while (!(LPC_SC->PLL1STAT & (1<<10)));/* Wait for PLOCK1 */
LPC_SC->PLL1CON = 0x03; /* PLL1 Enable & Connect */
LPC_SC->PLL1FEED = 0xAA;
LPC_SC->PLL1FEED = 0x55;
while (!(LPC_SC->PLL1STAT & ((1<< 9) | (1<< 8))));/* Wait for PLLC1_STAT & PLLE1_STAT */
#else
LPC_SC->USBCLKCFG = USBCLKCFG_Val; /* Setup USB Clock Divider */
#endif
LPC_SC->PCONP = PCONP_Val; /* Power Control for Peripherals */
LPC_SC->CLKOUTCFG = CLKOUTCFG_Val; /* Clock Output Configuration */
#endif
#if (FLASH_SETUP == 1) /* Flash Accelerator Setup */
LPC_SC->FLASHCFG = (LPC_SC->FLASHCFG & ~0x0000F000) | FLASHCFG_Val;
#endif
}
Embedded Programmierung bisher…
- Volle Kontrolle über Hardware
- Teure (Entwicklungs-)Hardware
- Spezialwissen
- Für Hobbyanwender kaum geeignet
Die Revolution: Arduino!
Die Revolution: Arduino!
- Preiswerte Hardware
- Viel (preiswerte) Peripherie inkl. Bibliotheken verfügbar
- Für Hobbyanwender/Quereinsteiger/Rapid Prototyping gut geeignet
- Kein Debugger 
Und JavaScript?
Espruino
Espruino
- Preiswerte Hardware
- Viel (preiswerte) Peripherie inkl.
Bibliotheken verfügbar
- Für Hobbyanwender/Quereinsteiger/Rapid
Prototyping gut geeignet
- Debugger verfügbar 
Demo Time!
Beispiel: Temperatur
function onTimer() {
// Messwert vom Temperatursensor auslesen
var t = E.getTemperature().toFixed(1);
// Backbuffer loeschen
g.clear();
// Kleine Schriftart für die Titelzeile auswaehlen
g.setFontBitmap();
// Titelzeile zeichnen
g.drawString("Temperature:");
// Grosse Schriftart für den Messwert auswaehlen
g.setFontVector(40);
// Messwert zentriert zeichnen, 10px Abstand vom oberen Rand
g.drawString(t, (g.getWidth() - g.stringWidth(t))/2, 10);
// Backbuffer auf Display darstellen
g.flip();
}
// Messwert und Display-Inhalt alle zwei Sekunden aktualisieren
setInterval(onTimer,2000);
// Initiale Darstellung des Messwertes
onTimer();
Beispiel: Luftfeuchtigkeit
// I2C-Schnittstelle konfigurieren
I2C1.setup( {scl: A5, sda: A4 } );
// HTU21D-Modul laden und über I2C-Schnittstelle verbinden
var htu = require('HTU21D').connect( I2C1 );
function onTimer() {
// Messwert vom Luftfeuchtesensor auslesen
var t = htu.readHumidity().toFixed(1);
// Backbuffer loeschen
g.clear();
// Kleine Schriftart für die Titelzeile auswaehlen
g.setFontBitmap();
// Titelzeile zeichnen
g.drawString("Humidity:");
// Grosse Schriftart für den Messwert auswaehlen
g.setFontVector(40);
// Messwert zentriert zeichnen, 10px Abstand vom oberen Rand
g.drawString(t, (g.getWidth() - g.stringWidth(t))/2, 10);
// Backbuffer auf Display darstellen
g.flip();
}
// Messwert und Display-Inhalt alle zwei Sekunden aktualisieren
setInterval(onTimer,2000);
// Initiale Darstellung des Messwertes
onTimer();
Beispiel: Bluetooth LE
// I2C-Schnittstelle konfigurieren
I2C1.setup( {scl: A5, sda: A4 } );
// HTU21D-Modul laden und über I2C-Schnittstelle verbinden
var htu = require('HTU21D').connect( I2C1 );
// Verfuegbare BLE Services und Charakteristiken bekannt machen
NRF.setServices({
// Envrionmental Sensing Service konfigurieren
0x181A: {
// Temperatur Charakteristik konfigurieren
0x2A6E: {
readable: true,
notify: true,
writeable: false,
value: new Int16Array([E.getTemperature() * 100]).buffer
},
// Luftfeuchte Charakteristik konfigurieren
0x2A6F: {
readable: true,
notify: true,
writeable: false,
value: new Uint16Array([htu.readHumidity() * 100]).buffer
}
}
// Envrionmental Sensing Service bekannt machen
}, {advertise: ['0x181A']});
// Messwerte erfassen und Benachrichtigungen versenden
function onTimer() {
NRF.updateServices({
// Envrionmental Sensing Service aktualisieren
0x181A: {
// Temperatur Charakteristik aktualisieren
0x2A6E: {
value: new Int16Array([E.getTemperature() * 100]).buffer,
notify: true
},
// Luftfeuchte Charakteristik aktualisieren
0x2A6F: {
value: new Uint16Array([htu.readHumidity() * 100]).buffer,
notify: true
}
}
});
}
NRF.on('connect', function(addr) {
// Messwert aktualisieren und uebermitteln
setInterval(onTimer, 2000);
// Initiale Uebermittlung des Messwertes
onTimer();
});
Beispiel: Bluetooth LE
Literatur
Vielen Dank!
https://www.espruino.com
https://www.espruino.com/Pixl.js
Tessel: https://www.tessel.io
Neonious: https://www.neonious.com
Slides: https://www.slideshare.net/JensSiebert1
Twitter: @jens_siebert

Más contenido relacionado

La actualidad más candente

Devirtualizing FinSpy
Devirtualizing FinSpyDevirtualizing FinSpy
Devirtualizing FinSpy
jduart
 
CODING IN ARDUINO
CODING IN ARDUINOCODING IN ARDUINO
CODING IN ARDUINO
S Ayub
 
Assembly language
Assembly languageAssembly language
Assembly language
bryle12
 
망고100 보드로 놀아보자 15
망고100 보드로 놀아보자 15망고100 보드로 놀아보자 15
망고100 보드로 놀아보자 15
종인 전
 

La actualidad más candente (20)

[2012 CodeEngn Conference 06] pwn3r - Secuinside 2012 CTF 예선 문제풀이
[2012 CodeEngn Conference 06] pwn3r - Secuinside 2012 CTF 예선 문제풀이[2012 CodeEngn Conference 06] pwn3r - Secuinside 2012 CTF 예선 문제풀이
[2012 CodeEngn Conference 06] pwn3r - Secuinside 2012 CTF 예선 문제풀이
 
FPGA Tutorial - LCD Interface
FPGA Tutorial - LCD InterfaceFPGA Tutorial - LCD Interface
FPGA Tutorial - LCD Interface
 
Uart
UartUart
Uart
 
Implementing Lightweight Networking
Implementing Lightweight NetworkingImplementing Lightweight Networking
Implementing Lightweight Networking
 
Devirtualizing FinSpy
Devirtualizing FinSpyDevirtualizing FinSpy
Devirtualizing FinSpy
 
Implementation of the ZigBee ZCL Reporting Configuration Features
Implementation of the ZigBee ZCL Reporting Configuration FeaturesImplementation of the ZigBee ZCL Reporting Configuration Features
Implementation of the ZigBee ZCL Reporting Configuration Features
 
UART MCU
UART MCUUART MCU
UART MCU
 
Troubleshooting Linux Kernel Modules And Device Drivers
Troubleshooting Linux Kernel Modules And Device DriversTroubleshooting Linux Kernel Modules And Device Drivers
Troubleshooting Linux Kernel Modules And Device Drivers
 
No instrumentation Golang Logging with eBPF (GoSF talk 11/11/20)
No instrumentation Golang Logging with eBPF (GoSF talk 11/11/20)No instrumentation Golang Logging with eBPF (GoSF talk 11/11/20)
No instrumentation Golang Logging with eBPF (GoSF talk 11/11/20)
 
Sysprog 12
Sysprog 12Sysprog 12
Sysprog 12
 
Sysprog 12
Sysprog 12Sysprog 12
Sysprog 12
 
Handling Asynchronous Events in MCUs
Handling Asynchronous Events in MCUsHandling Asynchronous Events in MCUs
Handling Asynchronous Events in MCUs
 
CODING IN ARDUINO
CODING IN ARDUINOCODING IN ARDUINO
CODING IN ARDUINO
 
SFO15-202: Towards Multi-Threaded Tiny Code Generator (TCG) in QEMU
SFO15-202: Towards Multi-Threaded Tiny Code Generator (TCG) in QEMUSFO15-202: Towards Multi-Threaded Tiny Code Generator (TCG) in QEMU
SFO15-202: Towards Multi-Threaded Tiny Code Generator (TCG) in QEMU
 
Assembly language
Assembly languageAssembly language
Assembly language
 
망고100 보드로 놀아보자 15
망고100 보드로 놀아보자 15망고100 보드로 놀아보자 15
망고100 보드로 놀아보자 15
 
Network security Lab manual
Network security Lab manual Network security Lab manual
Network security Lab manual
 
Exception handling in Pipelining in COA
Exception handling in Pipelining in COAException handling in Pipelining in COA
Exception handling in Pipelining in COA
 
Verifikation - Metoder og Libraries
Verifikation - Metoder og LibrariesVerifikation - Metoder og Libraries
Verifikation - Metoder og Libraries
 
FINISHED_CODE
FINISHED_CODEFINISHED_CODE
FINISHED_CODE
 

Similar a Embedded JavaScript

Mango64 u boot 업데이트 하기
Mango64 u boot 업데이트 하기Mango64 u boot 업데이트 하기
Mango64 u boot 업데이트 하기
종인 전
 
Crash_Report_Mechanism_In_Tizen
Crash_Report_Mechanism_In_TizenCrash_Report_Mechanism_In_Tizen
Crash_Report_Mechanism_In_Tizen
Lex Yu
 
GPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMPGPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMP
Miller Lee
 
What will be quantization step size in numbers and in voltage for th.pdf
What will be quantization step size in numbers and in voltage for th.pdfWhat will be quantization step size in numbers and in voltage for th.pdf
What will be quantization step size in numbers and in voltage for th.pdf
SIGMATAX1
 
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
Teddy Hsiung
 
# peripheral registers .equ PWR_BASE0x40007000 .equ PWR_CR0x00 .docx
# peripheral registers  .equ PWR_BASE0x40007000    .equ PWR_CR0x00  .docx# peripheral registers  .equ PWR_BASE0x40007000    .equ PWR_CR0x00  .docx
# peripheral registers .equ PWR_BASE0x40007000 .equ PWR_CR0x00 .docx
mayank272369
 
#include avrinterrupt.h The global interrupt flag is maintained.pdf
#include avrinterrupt.h The global interrupt flag is maintained.pdf#include avrinterrupt.h The global interrupt flag is maintained.pdf
#include avrinterrupt.h The global interrupt flag is maintained.pdf
arasanlethers
 
please show elegoo arduino board setup using a passive buzzer- heres t.pdf
please show elegoo arduino board setup using a passive buzzer- heres t.pdfplease show elegoo arduino board setup using a passive buzzer- heres t.pdf
please show elegoo arduino board setup using a passive buzzer- heres t.pdf
admin463580
 
Troubleshooting linux-kernel-modules-and-device-drivers-1233050713693744-1
Troubleshooting linux-kernel-modules-and-device-drivers-1233050713693744-1Troubleshooting linux-kernel-modules-and-device-drivers-1233050713693744-1
Troubleshooting linux-kernel-modules-and-device-drivers-1233050713693744-1
Jagadisha Maiya
 

Similar a Embedded JavaScript (20)

Linux Timer device driver
Linux Timer device driverLinux Timer device driver
Linux Timer device driver
 
Linux Serial Driver
Linux Serial DriverLinux Serial Driver
Linux Serial Driver
 
Microkernel Development
Microkernel DevelopmentMicrokernel Development
Microkernel Development
 
Mango64 u boot 업데이트 하기
Mango64 u boot 업데이트 하기Mango64 u boot 업데이트 하기
Mango64 u boot 업데이트 하기
 
ARM® Cortex™ M Bootup_CMSIS_Part_2_3
ARM® Cortex™ M Bootup_CMSIS_Part_2_3ARM® Cortex™ M Bootup_CMSIS_Part_2_3
ARM® Cortex™ M Bootup_CMSIS_Part_2_3
 
PIC and LCD
PIC and LCDPIC and LCD
PIC and LCD
 
Crash_Report_Mechanism_In_Tizen
Crash_Report_Mechanism_In_TizenCrash_Report_Mechanism_In_Tizen
Crash_Report_Mechanism_In_Tizen
 
GPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMPGPU Programming on CPU - Using C++AMP
GPU Programming on CPU - Using C++AMP
 
What will be quantization step size in numbers and in voltage for th.pdf
What will be quantization step size in numbers and in voltage for th.pdfWhat will be quantization step size in numbers and in voltage for th.pdf
What will be quantization step size in numbers and in voltage for th.pdf
 
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
ExperiencesSharingOnEmbeddedSystemDevelopment_20160321
 
hdl timer ppt.pptx
hdl timer ppt.pptxhdl timer ppt.pptx
hdl timer ppt.pptx
 
RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析
RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析
RISC-V : Berkeley Boot Loader & Proxy Kernelのソースコード解析
 
rrxv6 Build a Riscv xv6 Kernel in Rust.pdf
rrxv6 Build a Riscv xv6 Kernel in Rust.pdfrrxv6 Build a Riscv xv6 Kernel in Rust.pdf
rrxv6 Build a Riscv xv6 Kernel in Rust.pdf
 
# peripheral registers .equ PWR_BASE0x40007000 .equ PWR_CR0x00 .docx
# peripheral registers  .equ PWR_BASE0x40007000    .equ PWR_CR0x00  .docx# peripheral registers  .equ PWR_BASE0x40007000    .equ PWR_CR0x00  .docx
# peripheral registers .equ PWR_BASE0x40007000 .equ PWR_CR0x00 .docx
 
Embedded systems design @ defcon 2015
Embedded systems design @ defcon 2015Embedded systems design @ defcon 2015
Embedded systems design @ defcon 2015
 
Berkeley Packet Filters
Berkeley Packet FiltersBerkeley Packet Filters
Berkeley Packet Filters
 
#include avrinterrupt.h The global interrupt flag is maintained.pdf
#include avrinterrupt.h The global interrupt flag is maintained.pdf#include avrinterrupt.h The global interrupt flag is maintained.pdf
#include avrinterrupt.h The global interrupt flag is maintained.pdf
 
Lampiran 1.programdocx
Lampiran 1.programdocxLampiran 1.programdocx
Lampiran 1.programdocx
 
please show elegoo arduino board setup using a passive buzzer- heres t.pdf
please show elegoo arduino board setup using a passive buzzer- heres t.pdfplease show elegoo arduino board setup using a passive buzzer- heres t.pdf
please show elegoo arduino board setup using a passive buzzer- heres t.pdf
 
Troubleshooting linux-kernel-modules-and-device-drivers-1233050713693744-1
Troubleshooting linux-kernel-modules-and-device-drivers-1233050713693744-1Troubleshooting linux-kernel-modules-and-device-drivers-1233050713693744-1
Troubleshooting linux-kernel-modules-and-device-drivers-1233050713693744-1
 

Más de Jens Siebert

Más de Jens Siebert (19)

WebAssembly
WebAssemblyWebAssembly
WebAssembly
 
Embedded Rust
Embedded RustEmbedded Rust
Embedded Rust
 
Embedded Rust
Embedded RustEmbedded Rust
Embedded Rust
 
Microservices mit Rust
Microservices mit RustMicroservices mit Rust
Microservices mit Rust
 
Backend-Services mit Rust
Backend-Services mit RustBackend-Services mit Rust
Backend-Services mit Rust
 
TinyML – Machine Learning für eingebettete Systeme
TinyML – Machine Learning für eingebettete SystemeTinyML – Machine Learning für eingebettete Systeme
TinyML – Machine Learning für eingebettete Systeme
 
Deep Learning mit TensorFlow.js
Deep Learning mit TensorFlow.jsDeep Learning mit TensorFlow.js
Deep Learning mit TensorFlow.js
 
Chatbots bauen mit dem Microsoft Bot Framework
Chatbots bauen mit dem Microsoft Bot FrameworkChatbots bauen mit dem Microsoft Bot Framework
Chatbots bauen mit dem Microsoft Bot Framework
 
Integrating The Things Network Applications with Azure IoT Services
Integrating The Things Network Applications with Azure IoT ServicesIntegrating The Things Network Applications with Azure IoT Services
Integrating The Things Network Applications with Azure IoT Services
 
GraphQL
GraphQLGraphQL
GraphQL
 
Windows 10 IoT Core
Windows 10 IoT CoreWindows 10 IoT Core
Windows 10 IoT Core
 
Microsoft Bot Framework (Node.js Edition)
Microsoft Bot Framework (Node.js Edition)Microsoft Bot Framework (Node.js Edition)
Microsoft Bot Framework (Node.js Edition)
 
Microsoft Bot Framework (.NET Edition)
Microsoft Bot Framework (.NET Edition)Microsoft Bot Framework (.NET Edition)
Microsoft Bot Framework (.NET Edition)
 
Electron
ElectronElectron
Electron
 
Windows 10 IoT Core
Windows 10 IoT CoreWindows 10 IoT Core
Windows 10 IoT Core
 
Physical Web
Physical WebPhysical Web
Physical Web
 
Windows 10 IoT Core
Windows 10 IoT CoreWindows 10 IoT Core
Windows 10 IoT Core
 
TypeScript
TypeScriptTypeScript
TypeScript
 
TypeScript
TypeScriptTypeScript
TypeScript
 

Último

CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
Health
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
mohitmore19
 

Último (20)

How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...How to Choose the Right Laravel Development Partner in New York City_compress...
How to Choose the Right Laravel Development Partner in New York City_compress...
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) SolutionIntroducing Microsoft’s new Enterprise Work Management (EWM) Solution
Introducing Microsoft’s new Enterprise Work Management (EWM) Solution
 
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
The Guide to Integrating Generative AI into Unified Continuous Testing Platfo...
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
Direct Style Effect Systems -The Print[A] Example- A Comprehension AidDirect Style Effect Systems -The Print[A] Example- A Comprehension Aid
Direct Style Effect Systems - The Print[A] Example - A Comprehension Aid
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 

Embedded JavaScript

  • 1. Embedded JavaScript Mikrocontroller programmieren… mit JavaScript?! Jens Siebert (@jens_siebert) WebMontag Kassel, 11. Juni 2018 https://www.slideshare.net/JensSiebert1
  • 5. Embedded Programmierung bisher… #define XTAL (12000000UL) /* Oscillator frequency */ #define OSC_CLK ( XTAL) /* Main oscillator frequency */ #define RTC_CLK ( 32000UL) /* RTC oscillator frequency */ #define IRC_OSC ( 4000000UL) /* Internal RC oscillator frequency */ /* F_cco0 = (2 * M * F_in) / N */ #define __M (((PLL0CFG_Val ) & 0x7FFF) + 1) #define __N (((PLL0CFG_Val >> 16) & 0x00FF) + 1) #define __FCCO(__F_IN) ((2ULL * __M * __F_IN) / __N) #define __CCLK_DIV (((CCLKCFG_Val ) & 0x00FF) + 1) /* Determine core clock frequency according to settings */ #if (PLL0_SETUP) #if ((CLKSRCSEL_Val & 0x03) == 1) #define __CORE_CLK (__FCCO(OSC_CLK) / __CCLK_DIV) #elif ((CLKSRCSEL_Val & 0x03) == 2) #define __CORE_CLK (__FCCO(RTC_CLK) / __CCLK_DIV) #else #define __CORE_CLK (__FCCO(IRC_OSC) / __CCLK_DIV) #endif #else #if ((CLKSRCSEL_Val & 0x03) == 1) #define __CORE_CLK (OSC_CLK / __CCLK_DIV) #elif ((CLKSRCSEL_Val & 0x03) == 2) #define __CORE_CLK (RTC_CLK / __CCLK_DIV) #else #define __CORE_CLK (IRC_OSC / __CCLK_DIV) #endif #endif uint32_t SystemCoreClock = __CORE_CLK;/*!< System Clock Frequency (Core Clock)*/ void SystemCoreClockUpdate (void) /* Get Core Clock Frequency */ { /* Determine clock frequency according to clock register values */ if (((LPC_SC->PLL0STAT >> 24) & 3) == 3) { /* If PLL0 enabled and connected */ switch (LPC_SC->CLKSRCSEL & 0x03) { case 0: /* Int. RC oscillator => PLL0 */ case 3: /* Reserved, default to Int. RC */ SystemCoreClock = (IRC_OSC * ((2ULL * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) / (((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1) / ((LPC_SC->CCLKCFG & 0xFF)+ 1)); break; case 1: /* Main oscillator => PLL0 */ SystemCoreClock = (OSC_CLK * ((2ULL * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) / (((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1) / ((LPC_SC->CCLKCFG & 0xFF)+ 1)); break; case 2: /* RTC oscillator => PLL0 */ SystemCoreClock = (RTC_CLK * ((2ULL * ((LPC_SC->PLL0STAT & 0x7FFF) + 1))) / (((LPC_SC->PLL0STAT >> 16) & 0xFF) + 1) / ((LPC_SC->CCLKCFG & 0xFF)+ 1)); break; } } else { switch (LPC_SC->CLKSRCSEL & 0x03) { case 0: /* Int. RC oscillator => PLL0 */ case 3: /* Reserved, default to Int. RC */ SystemCoreClock = IRC_OSC / ((LPC_SC->CCLKCFG & 0xFF)+ 1); break; case 1: /* Main oscillator => PLL0 */ SystemCoreClock = OSC_CLK / ((LPC_SC->CCLKCFG & 0xFF)+ 1); break; case 2: /* RTC oscillator => PLL0 */ SystemCoreClock = RTC_CLK / ((LPC_SC->CCLKCFG & 0xFF)+ 1); break; } } }
  • 6. Embedded Programmierung bisher… #include <stdint.h> #include "LPC17xx.h“ #define CLOCK_SETUP 1 #define SCS_Val 0x00000020 #define CLKSRCSEL_Val 0x00000001 #define PLL0_SETUP 1 #ifdef MCB1700 # define PLL0CFG_Val 0x00050063 # define PLL1_SETUP 1 # define PLL1CFG_Val 0x00000023 # define CCLKCFG_Val 0x00000003 # define USBCLKCFG_Val 0x00000000 #else # define PLL0CFG_Val 0x0000000B # define PLL1_SETUP 0 # define PLL1CFG_Val 0x00000000 # define CCLKCFG_Val 0x00000002 # define USBCLKCFG_Val 0x00000005 #endif #define PCLKSEL0_Val 0x00000000 #define PCLKSEL1_Val 0x00000000 #define PCONP_Val 0x042887DE #define CLKOUTCFG_Val 0x00000000 #define FLASH_SETUP 1 #define FLASHCFG_Val 0x0000303A #define CHECK_RANGE(val, min, max) ((val < min) || (val > max)) #define CHECK_RSVD(val, mask) (val & mask) if (CHECK_RSVD((SCS_Val), ~0x00000030)) #error "SCS: Invalid values of reserved bits!" #endif #if (CHECK_RANGE((CLKSRCSEL_Val), 0, 2)) #error "CLKSRCSEL: Value out of range!" #endif #if (CHECK_RSVD((PLL0CFG_Val), ~0x00FF7FFF)) #error "PLL0CFG: Invalid values of reserved bits!" #endif #if (CHECK_RSVD((PLL1CFG_Val), ~0x0000007F)) #error "PLL1CFG: Invalid values of reserved bits!" #endif #if (PLL0_SETUP) /* if PLL0 is used */ #if (CCLKCFG_Val < 2) /* CCLKSEL must be greater then 1 */ #error "CCLKCFG: CCLKSEL must be greater then 1 if PLL0 is used!" #endif #endif #if (CHECK_RANGE((CCLKCFG_Val), 2, 255)) #error "CCLKCFG: Value out of range!" #endif #if (CHECK_RSVD((USBCLKCFG_Val), ~0x0000000F)) #error "USBCLKCFG: Invalid values of reserved bits!" #endif #if (CHECK_RSVD((PCLKSEL0_Val), 0x000C0C00)) #error "PCLKSEL0: Invalid values of reserved bits!" #endif #if (CHECK_RSVD((PCLKSEL1_Val), 0x03000300)) #error "PCLKSEL1: Invalid values of reserved bits!" #endif #if (CHECK_RSVD((PCONP_Val), 0x10100821)) #error "PCONP: Invalid values of reserved bits!" #endif #if (CHECK_RSVD((CLKOUTCFG_Val), ~0x000001FF)) #error "CLKOUTCFG: Invalid values of reserved bits!" #endif /* Flash Accelerator Configuration ------------------------*/ #if (CHECK_RSVD((FLASHCFG_Val), ~0x0000F07F)) #error "FLASHCFG: Invalid values of reserved bits!" #endif
  • 7. Embedded Programmierung bisher… void SystemInit (void) { #if (CLOCK_SETUP) /* Clock Setup */ LPC_SC->SCS = SCS_Val; if (LPC_SC->SCS & (1 << 5)) { /* If Main Oscillator is enabled */ while ((LPC_SC->SCS & (1<<6)) == 0);/* Wait for Oscillator to be ready */ } LPC_SC->CCLKCFG = CCLKCFG_Val; /* Setup Clock Divider */ /* Periphral clock must be selected before PLL0 enabling and connecting * - according errata.lpc1768-16.March.2010 - */ LPC_SC->PCLKSEL0 = PCLKSEL0_Val; /* Peripheral Clock Selection */ LPC_SC->PCLKSEL1 = PCLKSEL1_Val; #if (PLL0_SETUP) LPC_SC->CLKSRCSEL = CLKSRCSEL_Val; /* Select Clock Source for PLL0 */ LPC_SC->PLL0CFG = PLL0CFG_Val; /* configure PLL0 */ LPC_SC->PLL0FEED = 0xAA; LPC_SC->PLL0FEED = 0x55; LPC_SC->PLL0CON = 0x01; /* PLL0 Enable */ LPC_SC->PLL0FEED = 0xAA; LPC_SC->PLL0FEED = 0x55; while (!(LPC_SC->PLL0STAT & (1<<26)));/* Wait for PLOCK0 */ LPC_SC->PLL0CON = 0x03; /* PLL0 Enable & Connect */ LPC_SC->PLL0FEED = 0xAA; LPC_SC->PLL0FEED = 0x55; while (!(LPC_SC->PLL0STAT & ((1<<25) | (1<<24))));/* Wait for PLLC0_STAT & PLLE0_STAT */ #endif #if (PLL1_SETUP) LPC_SC->PLL1CFG = PLL1CFG_Val; LPC_SC->PLL1FEED = 0xAA; LPC_SC->PLL1FEED = 0x55; LPC_SC->PLL1CON = 0x01; /* PLL1 Enable */ LPC_SC->PLL1FEED = 0xAA; LPC_SC->PLL1FEED = 0x55; while (!(LPC_SC->PLL1STAT & (1<<10)));/* Wait for PLOCK1 */ LPC_SC->PLL1CON = 0x03; /* PLL1 Enable & Connect */ LPC_SC->PLL1FEED = 0xAA; LPC_SC->PLL1FEED = 0x55; while (!(LPC_SC->PLL1STAT & ((1<< 9) | (1<< 8))));/* Wait for PLLC1_STAT & PLLE1_STAT */ #else LPC_SC->USBCLKCFG = USBCLKCFG_Val; /* Setup USB Clock Divider */ #endif LPC_SC->PCONP = PCONP_Val; /* Power Control for Peripherals */ LPC_SC->CLKOUTCFG = CLKOUTCFG_Val; /* Clock Output Configuration */ #endif #if (FLASH_SETUP == 1) /* Flash Accelerator Setup */ LPC_SC->FLASHCFG = (LPC_SC->FLASHCFG & ~0x0000F000) | FLASHCFG_Val; #endif }
  • 8. Embedded Programmierung bisher… - Volle Kontrolle über Hardware - Teure (Entwicklungs-)Hardware - Spezialwissen - Für Hobbyanwender kaum geeignet
  • 10. Die Revolution: Arduino! - Preiswerte Hardware - Viel (preiswerte) Peripherie inkl. Bibliotheken verfügbar - Für Hobbyanwender/Quereinsteiger/Rapid Prototyping gut geeignet - Kein Debugger 
  • 13. Espruino - Preiswerte Hardware - Viel (preiswerte) Peripherie inkl. Bibliotheken verfügbar - Für Hobbyanwender/Quereinsteiger/Rapid Prototyping gut geeignet - Debugger verfügbar 
  • 15. Beispiel: Temperatur function onTimer() { // Messwert vom Temperatursensor auslesen var t = E.getTemperature().toFixed(1); // Backbuffer loeschen g.clear(); // Kleine Schriftart für die Titelzeile auswaehlen g.setFontBitmap(); // Titelzeile zeichnen g.drawString("Temperature:"); // Grosse Schriftart für den Messwert auswaehlen g.setFontVector(40); // Messwert zentriert zeichnen, 10px Abstand vom oberen Rand g.drawString(t, (g.getWidth() - g.stringWidth(t))/2, 10); // Backbuffer auf Display darstellen g.flip(); } // Messwert und Display-Inhalt alle zwei Sekunden aktualisieren setInterval(onTimer,2000); // Initiale Darstellung des Messwertes onTimer();
  • 16. Beispiel: Luftfeuchtigkeit // I2C-Schnittstelle konfigurieren I2C1.setup( {scl: A5, sda: A4 } ); // HTU21D-Modul laden und über I2C-Schnittstelle verbinden var htu = require('HTU21D').connect( I2C1 ); function onTimer() { // Messwert vom Luftfeuchtesensor auslesen var t = htu.readHumidity().toFixed(1); // Backbuffer loeschen g.clear(); // Kleine Schriftart für die Titelzeile auswaehlen g.setFontBitmap(); // Titelzeile zeichnen g.drawString("Humidity:"); // Grosse Schriftart für den Messwert auswaehlen g.setFontVector(40); // Messwert zentriert zeichnen, 10px Abstand vom oberen Rand g.drawString(t, (g.getWidth() - g.stringWidth(t))/2, 10); // Backbuffer auf Display darstellen g.flip(); } // Messwert und Display-Inhalt alle zwei Sekunden aktualisieren setInterval(onTimer,2000); // Initiale Darstellung des Messwertes onTimer();
  • 17. Beispiel: Bluetooth LE // I2C-Schnittstelle konfigurieren I2C1.setup( {scl: A5, sda: A4 } ); // HTU21D-Modul laden und über I2C-Schnittstelle verbinden var htu = require('HTU21D').connect( I2C1 ); // Verfuegbare BLE Services und Charakteristiken bekannt machen NRF.setServices({ // Envrionmental Sensing Service konfigurieren 0x181A: { // Temperatur Charakteristik konfigurieren 0x2A6E: { readable: true, notify: true, writeable: false, value: new Int16Array([E.getTemperature() * 100]).buffer }, // Luftfeuchte Charakteristik konfigurieren 0x2A6F: { readable: true, notify: true, writeable: false, value: new Uint16Array([htu.readHumidity() * 100]).buffer } } // Envrionmental Sensing Service bekannt machen }, {advertise: ['0x181A']}); // Messwerte erfassen und Benachrichtigungen versenden function onTimer() { NRF.updateServices({ // Envrionmental Sensing Service aktualisieren 0x181A: { // Temperatur Charakteristik aktualisieren 0x2A6E: { value: new Int16Array([E.getTemperature() * 100]).buffer, notify: true }, // Luftfeuchte Charakteristik aktualisieren 0x2A6F: { value: new Uint16Array([htu.readHumidity() * 100]).buffer, notify: true } } }); } NRF.on('connect', function(addr) { // Messwert aktualisieren und uebermitteln setInterval(onTimer, 2000); // Initiale Uebermittlung des Messwertes onTimer(); });
  • 20. Vielen Dank! https://www.espruino.com https://www.espruino.com/Pixl.js Tessel: https://www.tessel.io Neonious: https://www.neonious.com Slides: https://www.slideshare.net/JensSiebert1 Twitter: @jens_siebert

Notas del editor

  1. ARM 32-bit Cortex-M4 CPU with FPU, up to 84 MHz, up to 512 Kbytes of Flash memory, up to 96 Kbytes of SRAM, 146 μA/MHz (Run), 2.4 μA (Standby)