Problema 1
Un interruptor está conectado al pin PB1 y un led al PIN PB5, hacer un programa en ASM
que lee el estado del interruptor y envía este estado a un led:
1) Primero todo en C
2) usando inline Assembler
int buttonState = 0;
void setup()
{
pinMode(9, INPUT);
pinMode(13, OUTPUT);
}
void loop()
{
buttonState = digitalRead(9);
if (buttonState == HIGH) {
digitalWrite(13, HIGH);
} else {
digitalWrite(13, LOW);
}
delay(20);
}
Parte inline asm
int buttonState = 0;
void setup()
{
asm volatile
(
"ldi r16,0x20\n"
"out 0x04,r16\n"
);
void loop()
{
buttonState = digitalRead(9);
if (buttonState == HIGH) {
digitalWrite(13, HIGH);
} else {
digitalWrite(13, LOW);
}
delay(20);
}
Se puede cambiar mas funciones a assembler, ver problema 3
Problema 2
Escribir un programa que sustrae dos números de 16 bits x2762-x1296
R26 = 62
R27 = 27
La diferencia va en los registros 26 y 27 siendo R26 el byte inferior
Usando ASM
volatile uint16_t result;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
asm (
"LDI r26, 62 \n"
"LDI r27, 27 \n"
"LDI r28, 0x96 \n"
"LDI r29, 0x12 \n"
"SUB r26,r28 \n"
"SUB r27,r29 \n"
"mov r0, r26 \n"
"mov r1, r27 \n"
: "+a" (result): );
Serial.print(result);
void loop() {
// put your main code here, to run repeatedly:
Nota, esta solución tiene un error para mostrar los resultados
Problema 3
Hacer un programa que cambie de estado todos los pines del puerto B de la tarjeta Arduino
UNO (pines 8-13) de manera secuencial.
1) Todo en C
2) Usando ASM
Solución en C
void setup()
{
pinMode(13, OUTPUT);
pinMode(12, OUTPUT);
pinMode(11, OUTPUT);
pinMode(10, OUTPUT);
pinMode(9, OUTPUT);
pinMode(8, OUTPUT);
void loop()
{
digitalWrite(13, HIGH);
digitalWrite(12, HIGH);
digitalWrite(11, HIGH);
digitalWrite(10, HIGH);
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
delay(1000); // Wait for 1000 millisecond(s)
digitalWrite(13, LOW);
digitalWrite(12, LOW);
digitalWrite(11, LOW);
digitalWrite(10, LOW);
digitalWrite(9, LOW);
digitalWrite(8, LOW);
delay(1000); // Wait for 1000 millisecond(s)
}
Solución usando ASM
volatile uint8_t BitMask = 0b00111111;
void setup()
{
asm volatile
(
"ldi r16,0b00111111\n"
"out 0x04,r16\n"
);
void loop()
{
asm volatile (
"in r18, %0 \n"
"or r18, %1 \n"
"out %0, r18 \n"
:: "I" (_SFR_IO_ADDR(PORTB)), "r" (BitMask): "r18" );
delay(1000);
asm volatile (
"in r18, %0 \n"
"eor %1, %2 \n"
"and r18, %1 \n"
"out %0, r18 \n"
:: "I" (_SFR_IO_ADDR(PORTB)), "r" (BitMask), "r" (0xff)
);
delay(1000);
}