๐Ÿ‡ฎ๐Ÿ‡น IT ๐Ÿ‡ฌ๐Ÿ‡ง EN

28BYJ-48 + ULN2003
in pure AVR assembly

The backbone: sequential steps, no fluff.

๐Ÿง  Imagine a wardrobe with many numbered drawers (0x04, 0x05, 0x06...). Each drawer has 8 switches (bits 7...0).

The microcontroller can only: turn on (SBI) or turn off (CBI) these switches. When you turn on switch 5 of drawer 0x05, pin D13 lights up. When you turn on switches 0-3 of the same drawer, the motor takes one step.

No magic: it's just a wardrobe with drawers and switches. The names DDRB, PORTB are just labels we humans attached. The chip only sees the numbers.

Registers 7 6 5 4 3 2 1 0
0x0D (0x2D)Reservedโ€“โ€“โ€“โ€“โ€“โ€“โ€“โ€“
0x0C (0x2C)Reservedโ€“โ€“โ€“โ€“โ€“โ€“โ€“โ€“
0x0B (0x2B)PORTDPORTD7PORTD6PORTD5PORTD4PORTD3PORTD2PORTD1PORTD073
0x0A (0x2A)DDRDDDD7DDD6DDD5DDD4DDD3DDD2DDD1DDD073
0x09 (0x29)PINDPIND7PIND6PIND5PIND4PIND3PIND2PIND1PIND073
0x08 (0x28)PORTCโ€“PORTC6PORTC5PORTC4PORTC3PORTC2PORTC1PORTC073
0x07 (0x27)DDRCโ€“DDC6DDC5DDC4DDC3DDC2DDC1DDC073
0x06 (0x26)PINCโ€“PINC6PINC5PINC4PINC3PINC2PINC1PINC073
0x05 (0x25)PORTBPORTB7PORTB6PORTB5PORTB4PORTB3PORTB2PORTB1PORTB072
0x04 (0x24)DDRBDDB7DDB6DDB5DDB4DDB3DDB2DDB1DDB072
0x03 (0x23)PINBPINB7PINB6PINB5PINB4PINB3PINB2PINB1PINB072
0x02 (0x22)Reservedโ€“โ€“โ€“โ€“โ€“โ€“โ€“โ€“
0x01 (0x21)Reservedโ€“โ€“โ€“โ€“โ€“โ€“โ€“โ€“
0x00 (0x20)Reservedโ€“โ€“โ€“โ€“โ€“โ€“โ€“โ€“
๐Ÿง  Reality: The microcontroller only sees the numbers (0x04, 0x05...). We humans gave names like DDRB, PORTB.
๐Ÿ“ฆ step 0

Materials & wiring

  • Arduino Uno / Nano (ATmega328P)
  • ULN2003 driver module
  • 28BYJ-48 stepper motor (5V)
  • Dupont wires
  • External 5V power supply (recommended)

Wiring

D8PORTB0ULN2003 IN1
D9PORTB1ULN2003 IN2
D10PORTB2ULN2003 IN3
D11PORTB3ULN2003 IN4
5V-module power
GND-common ground

Note: D8-D11 are bits 0-3 of PORTB register (0x05).

โšก step 1

LED D13 (test)

The built-in LED D13 is on bit 5 of PORTB (0x05).

; set PB5 as OUTPUT (DDRB 0x04 bit5) sbi 4, 5 ; turn LED on (PORTB 0x05 bit5) sbi 5, 5 loop: rjmp loop
๐Ÿ”ง step 2

Configure D8-D11 as OUTPUT

; DDRB (0x04) bits 0-3 = 1 sbi 4, 0 sbi 4, 1 sbi 4, 2 sbi 4, 3

Test module LEDs (optional):

; PORTB (0x05) bits 0-3 = 1 sbi 5, 0 sbi 5, 1 sbi 5, 2 sbi 5, 3
โฑ๏ธ step 3

Delay with r16, r17, r18

wait: ldi r16, 0xFF ldi r17, 0xFF ldi r18, 0x04 ; change this for speed loop_w: dec r16 brne loop_w dec r17 brne loop_w dec r18 brne loop_w ret
๐Ÿ”„ step 4

Full-step sequence

; step 1 (D8) sbi 5, 0 cbi 5, 1 cbi 5, 2 cbi 5, 3 rcall wait ; step 2 (D9) cbi 5, 0 sbi 5, 1 cbi 5, 2 cbi 5, 3 rcall wait ; step 3 (D10) cbi 5, 0 cbi 5, 1 sbi 5, 2 cbi 5, 3 rcall wait ; step 4 (D11) cbi 5, 0 cbi 5, 1 cbi 5, 2 sbi 5, 3 rcall wait
๐Ÿ step 5

Complete program

; === stepper-motor.asm === .org 0x60 ; DDRB output (0x04) sbi 4, 0 sbi 4, 1 sbi 4, 2 sbi 4, 3 loop: ; step 1 sbi 5, 0 cbi 5, 1 cbi 5, 2 cbi 5, 3 rcall wait ; step 2 cbi 5, 0 sbi 5, 1 cbi 5, 2 cbi 5, 3 rcall wait ; step 3 cbi 5, 0 cbi 5, 1 sbi 5, 2 cbi 5, 3 rcall wait ; step 4 cbi 5, 0 cbi 5, 1 cbi 5, 2 sbi 5, 3 rcall wait rjmp loop wait: ldi r16, 0xFF ldi r17, 0xFF ldi r18, 0x04 loop_w: dec r16 brne loop_w dec r17 brne loop_w dec r18 brne loop_w ret

Upload at costycnc.it/avr1/compiler.html โ†’ motor spins.

๐Ÿง  step 6

Going further