Errors using OUT in AVR-GCC

Go To Last Post
17 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I'm using some old code to make an led blink to hopefully light an 8x8 led matrix. I'm attempting in in avr assembly, but have issues with the "OUT DDRB, R16" type lines. Keep getting an error that a constant is required. 

 

#define __SFR_OFFSET 0
;#include "config.inc"

        .section .text
        .global     main
        .extern     delay          
        .org        0x0000

main:
        ; set up the stack
        ;ldi         r28, (RAMEND & 0x00ff)
        ;ldi         r29, (RAMEND >> 8)
        ;out         _SPH, r29
        ;out         _SPL, r28
	;SET ALL PORTB FOR OUTPUT
	;LDI 	R16, 0b1111_1111
	;WRITE 1s TO DIRECTION REGS
	;OUT 	DDRB, R16          



        ; initilaize the chip for blinking
        call        init      

        ; enter the blink loop
loop:      call        toggleon	;on
        call        delay	
	call	    delay	
	call        delay	
	call	    delay	
	call        delay	
	call	    delay	
	call	    toggleoff	;off
	call	    delay	
	call        delay       
	call        delay	
	call	    delay	
	call        delay	
	call	    delay	
	call	    toggleon	;on
	call        delay	
	call	    delay	
	call        delay	
	call	    delay	
	call	    delay	
	call	    delay	
	call 	    toggleoff  	;off
	call	    delay	
	call	    delay       
	call	    delay	
	rjmp        loop

init:   
	;SET ALL PORTB FOR OUTPUT
	LDI 	R16, 0b11111111
	;WRITE 1s TO DIRECTION REGS
	OUT	DDRB, R16
	;eor         r1, r1                  ; zero out the r1 register
        ;out         SREG, r1               ; initialize the status reg
        ;ldi         r24, 0x80
        ;sts         CLKPR, r24              ; allow access to clock setup
        ;sts         CLKPR, r1               ; run at full speed
        
        ; set up the LED port
        ;sbi         LED_DIR, LED_PIN        ; set LED pin to output
        ;cbi         LED_PORT, LED_PIN       ; start with the LED off
        ret

toggleon:
        ;in          r24, LED_PORT           ; get current bits
        ;ldi         r25, (1 << LED_PIN)     ; LED is pin 5		        
	;eor         r24, r25                ; flip the bit
        ;out         LED_PORT, r24           ; write the bits back
	LDI R16, 0b11111111   ;SET ALL PINS HIGH
	STS PORTB_OUT, R16             ;WRITE TO PORT B, TURNS THE PINS ON        
	ret

toggleoff:
	LDI R16, 0b00000000   ;SET ALL PINS LOW
	STS DDRB_OUT, R16             ;WRITE 0s TO DIRECTION REGS
	ret

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you using Atmel's assembler or avr-gcc's? In either case, things like DDRB need to be defined somewhere. How you get those definitions depends on which assembler you are using. You also need to tell us which AVR you are using.

Regards,
Steve A.

The Board helps those that help themselves.

Last Edited: Fri. Jul 31, 2015 - 05:21 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That makes sense. I'm using avr-gcc with the uno, atmega328p.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you using Atmel's assembler or avr-gcc's?

The mention of __SFR_OFFSET at the top would seem to imply that it is avr-as. (same for .global)

 

You appear to have "half the solution" there. The easy way to use things like DDRB, PORTB and so on in avr-as code is, indeed, to define __SFR_OFFSET to 0. But the thing it applies to are the definitions in <avr/io.h> so you need to include that too.

 

If I first try you r code exactly as it is now I see:

$ avr-gcc -mmcu=atmega16 avr.S -o avr.elf
avr.S: Assembler messages:
avr.S:57: Error: constant value required

Line 57 that it refers to here is the first:

	OUT	DDRB, R16

Now if I edit the top of the code to change:

#define __SFR_OFFSET 0
;#include "config.inc"

        .section .text

to be:

#define __SFR_OFFSET 0
#include <avr/io.h>

        .section .text

I get:

~$ avr-gcc -mmcu=atmega16 avr.S -o avr.elf
/tmp/cckR5KHv.o: In function `loop':
(.text+0x8): undefined reference to `delay'
/tmp/cckR5KHv.o: In function `loop':
(.text+0xc): undefined reference to `delay'
/tmp/cckR5KHv.o: In function `loop':
(.text+0x10): undefined reference to `delay'
/tmp/cckR5KHv.o: In function `loop':
(.text+0x14): undefined reference to `delay'
/tmp/cckR5KHv.o: In function `loop':
(.text+0x18): undefined reference to `delay'
/tmp/cckR5KHv.o:(.text+0x1c): more undefined references to `delay' follow
/tmp/cckR5KHv.o: In function `toggleon':
(.text+0x74): undefined reference to `PORTB_OUT'
/tmp/cckR5KHv.o: In function `toggleoff':
(.text+0x7c): undefined reference to `DDRB_OUT'
collect2: ld returned 1 exit status

Sure that is more errors but they are completely explainable. In my compilation I don't have a file providing delay: and I don't have the first idea what PORTB_OUT and DDRB_OUT are ?!?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well, I can guess what PORTB_OUT and DDRB_OUT are.

 

The real mystery is :   WHY USE ASSEMBLER?

 

The C compiler will generate perfectly good code.    And you will probably understand what is going on.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have it working in C. I have to write it in assembly though.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I fixed the delay issue and the PORTB_OUT issues. I was trying to correct the OUT constant variable issues I was having and one way I had found was using STS and PORTB_OUT. I had no clue that was for the Atmel assembler. 

 

Getting the following error now! May have something to do with the interrupt table previously mentioned. 

 

/usr/lib/gcc/avr/4.8.2/../../../avr/lib/avr5/crtm328p.o: In function `__bad_interrupt':
../../../../crt1/gcrt1.S:195: undefined reference to `main'
collect2: error: ld returned 1 exit status

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jlach9 wrote:

I have it working in C. I have to write it in assembly though.

 

Why?  

 

This seems a pointless exercise.    However the general principle of writing a sequence in C and optimising in ASM is useful:  

Capture the temporary .s file.    Edit it as a permanent .S file.    Add the .S file to your C or C++ project.    Comment out the original C sequence.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's for an assembly language class. Only had three lectures on arduinos. First three labs were given to us by the instructor. This one has us writing assembly language for an 8x8 led. Regular assembly language programs are easy now, but the avr stuff is hard. I guess my c code didn't work. It's modified arduino ide code that is actually running fine on the arduino. Running gcc -S project.c gives me errors about OUTPUT and HIGH being undeclared.

unsigned char bigHeart[] = {
    0x66,
    0xFF,
    0xFF,
    0xFF,
    0x7E,
    0x3C,
    0x00
};


//byte smallHeart[] = {
 //B00000000,
 ///B00000000,
 //B00010100,
 //B00111110,
 ///B00111110,
 //B00011100,
 //B00001000,
 //B00000000};


const int columnPins[] = { 2, 3, 4, 5, 6, 7, 8, 9};
const int rowPins[] = { 10,11,12,15,16,17,18,19};


void setup() {
int i; 
for (i = 0; i < 8; i++)
 {
 ;pinMode(rowPins[i], OUTPUT); // make all the LED pins outputs
 ;pinMode(columnPins[i], OUTPUT);
 ;digitalWrite(columnPins[i], HIGH); // disconnect column pins from Ground
 }
}



void loop() {
 int pulseDelay = 800 ; // milliseconds to wait between beats
 //show(smallHeart, 80); // show the small heart image for 100 ms
 show(bigHeart, 160); // followed by the big heart for 200ms
 delay(pulseDelay); // show nothing between beats
}


// routine to show a frame of an image stored in the array pointed to by the image parameter.
// the frame is repeated for the given duration in milliseconds
void show( byte * image, unsigned long duration)
{
 unsigned long start = millis(); // begin timing the animation
 while (start + duration > millis()) // loop until the duration period has passed
 {
 for(int row = 0; row < 8; row++)
 {
 digitalWrite(rowPins[row], HIGH); // connect row to +5 volts
 for(int column = 0; column < 8; column++)
 {
 boolean pixel = bitRead(image[row],column);
 if(pixel == 1)
 {
 digitalWrite(columnPins[column], LOW); // connect column to Gnd
 }
 delayMicroseconds(300); // a small delay for each LED
 digitalWrite(columnPins[column], HIGH); // disconnect column from Gnd
 }
 digitalWrite(rowPins[row], LOW); // disconnect LEDs
 }
 }
}

So frustrating. 20 of the 27 enrolled dropped the class. 

 

 

finallyasm.c: In function ‘setup’:
finallyasm.c:33:22: error: ‘OUTPUT’ undeclared (first use in this function)
  pinMode(rowPins[i], OUTPUT); // make all the LED pins outputs
                      ^
finallyasm.c:33:22: note: each undeclared identifier is reported only once for each function it appears in
finallyasm.c:35:30: error: ‘HIGH’ undeclared (first use in this function)
  digitalWrite(columnPins[i], HIGH); // disconnect column pins from Ground
                              ^
finallyasm.c: At top level:
finallyasm.c:51:12: error: unknown type name ‘byte’
 void show( byte * image, unsigned long duration)

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It does not surprise me that 20 out of 27 have abandoned the class.
Some teachers delight in making things difficult and frustrating. Of course this may help students to be realistic about their career choice and academic ability.

It sems crazy to discourage students that have a genuine interest. It also seems crazy to produce a set of students that have never got any practical projects completed. After all, a student who can create a robust working Arduino program from scratch is a lot more useful to an employer than someone who can save 10 cycles in an ASM sequence but the complete program does not work.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Getting the following error now! May have something to do with the interrupt table previously mentioned. 

Just sit and look at what the error is actually telling you:

../../../../crt1/gcrt1.S:195: undefined reference to `main'

So it is looking for a function/entry point called "main:". This seems curious because in the first code you posted you have:

#define __SFR_OFFSET 0

        .section .text
        .global     main
        .extern     delay          
        .org        0x0000

main:
        ; initilaize the chip for blinking
        call        init      

As far as I know that *should* provide a function called main: that is callable from the C provided startup code.

 

If I take your original code, correct those STS and PORTB_OUT and DDRB_OUT and provide a dummy delay: routine I get this:

$ cat avr.S
#define __SFR_OFFSET 0
#include <avr/io.h>

        .section .text
        .global     main
        .extern     delay          
        .org        0x0000

main:
        ; initilaize the chip for blinking
        call        init      

        ; enter the blink loop
loop:      call        toggleon	;on
        call        delay	
	call	    delay	
	call        delay	
	call	    delay	
	call        delay	
	call	    delay	
	call	    toggleoff	;off
	call	    delay	
	call        delay       
	call        delay	
	call	    delay	
	call        delay	
	call	    delay	
	call	    toggleon	;on
	call        delay	
	call	    delay	
	call        delay	
	call	    delay	
	call	    delay	
	call	    delay	
	call 	    toggleoff  	;off
	call	    delay	
	call	    delay       
	call	    delay	
	rjmp        loop

init:   
	;SET ALL PORTB FOR OUTPUT
	LDI 	R16, 0b11111111
	;WRITE 1s TO DIRECTION REGS
	OUT	DDRB, R16
        ret

toggleon:
	LDI R16, 0b11111111   ;SET ALL PINS HIGH
	OUT PORTB, R16             ;WRITE TO PORT B, TURNS THE PINS ON        
	ret

toggleoff:
	LDI R16, 0b00000000   ;SET ALL PINS LOW
	OUT DDRB, R16             ;WRITE 0s TO DIRECTION REGS
	ret

delay:
	; add something here
	ret
$ avr-gcc -mmcu=atmega16 avr.S -o avr.elf
$ 

As you can see, for me that built without any error at all. What are you doing differently?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That did build. How does one go about taking care of LOW, HIGH, and OUTPUT being undeclared when disassembling c code? 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

As in, how would I disassemble this? 

 

/*
 * Show messages on an 8x8 led matrix,
 * scrolling from right to left.
 *
 * Uses FrequencyTimer2 library to
 * constantly run an interrupt routine
 * at a specified frequency. This
 * refreshes the display without the
 * main loop having to do anything.
 *
 */
 
#include <FrequencyTimer2.h>
 
#define SPACE { \
    {0, 0, 0, 0, 0, 0, 0, 0},  \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0}, \
    {0, 0, 0, 0, 0, 0, 0, 0} \
}
 
#define H { \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 1, 1, 1, 1, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}  \
}
 
#define E  { \
    {0, 1, 1, 1, 1, 1, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 1, 1, 1, 1, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 1, 1, 1, 1, 1, 0}  \
}
   
#define L { \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 0, 0}, \
    {0, 1, 1, 1, 1, 1, 1, 0}  \
}
 
#define O { \
    {0, 0, 0, 1, 1, 0, 0, 0}, \
    {0, 0, 1, 0, 0, 1, 0, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 1, 0, 0, 0, 0, 1, 0}, \
    {0, 0, 1, 0, 0, 1, 0, 0}, \
    {0, 0, 0, 1, 1, 0, 0, 0}  \
}
 
byte analogPin = 5;
byte col = 0;
byte leds[8][8];
 
// pin[xx] on led matrix connected to nn on Arduino (-1 is dummy to make array start at pos 1)
int pins[17]= {-1, 5, 4, 3, 2, 14, 15, 16, 17, 13, 12, 11, 10, 9, 8, 7, 6};
 
// col[xx] of leds = pin yy on led matrix
int cols[8] = {pins[13], pins[3], pins[4], pins[10], pins[06], pins[11], pins[15], pins[16]};
 
// row[xx] of leds = pin yy on led matrix
int rows[8] = {pins[9], pins[14], pins[8], pins[12], pins[1], pins[7], pins[2], pins[5]};
 
const int numPatterns = 6;
byte patterns[numPatterns][8][8] = {
  H,E,L,L,O,SPACE
};
 
int pattern = 0;
 
void setup() {
  // sets the pins as output
  for (int i = 1; i <= 16; i++) {
    pinMode(pins[i], OUTPUT);
  }
 
  // set up cols and rows
  for (int i = 1; i <= 8; i++) {
    digitalWrite(cols[i - 1], LOW);
  }
 
  for (int i = 1; i <= 8; i++) {
    digitalWrite(rows[i - 1], LOW);
  }
 
  clearLeds();
 
  // Turn off toggling of pin 11
  FrequencyTimer2::disable();
  // Set refresh rate (interrupt timeout period)
  FrequencyTimer2::setPeriod(2000);
  // Set interrupt routine to be called
  FrequencyTimer2::setOnOverflow(display);
 
  setPattern(pattern);
}
 
void loop() {
    pattern = ++pattern % numPatterns;
    slidePattern(pattern, 60);
}
 
void clearLeds() {
  // Clear display array
  for (int i = 0; i < 8; i++) {
    for (int j = 0; j < 8; j++) {
      leds[i][j] = 0;
    }
  }
}
 
void setPattern(int pattern) {
  for (int i = 0; i < 8; i++) {
    for (int j = 0; j < 8; j++) {
      leds[i][j] = patterns[pattern][i][j];
    }
  }
}
 
void slidePattern(int pattern, int del) {
  for (int l = 0; l < 8; l++) {
    for (int i = 0; i < 7; i++) {
      for (int j = 0; j < 8; j++) {
        leds[j][i] = leds[j][i+1];
      }
    }
    for (int j = 0; j < 8; j++) {
      leds[j][7] = patterns[pattern][j][0 + l];
    }
    delay(del);
  }
}
 
// Interrupt routine
void display() {
  digitalWrite(cols[col], LOW);  // Turn whole previous column off
  col++;
  if (col == 8) {
    col = 0;
  }
  for (int row = 0; row < 8; row++) {
    if (leds[col][7 - row] == 1) {
      digitalWrite(rows[row], LOW);  // Turn on this led
    }
    else {
      digitalWrite(rows[row], HIGH); // Turn off this led
    }
  }
  digitalWrite(cols[col], HIGH); // Turn whole column on at once (for equal lighting times)
  delayMicroseconds(900);  // Delay so that on times are longer than off time = brighter leds
}

 

Only errors are 

scroll.c: In function ‘setup’:
scroll.c:11:25: error: ‘OUTPUT’ undeclared (first use in this function)
     pinMode(rowPins[i], OUTPUT);  
                         ^
scroll.c:11:25: note: each undeclared identifier is reported only once for each function it appears in
scroll.c:12:30: error: ‘HIGH’ undeclared (first use in this function)
     digitalWrite(rowPins[i], HIGH);
                              ^
scroll.c:14:33: error: ‘LOW’ undeclared (first use in this function)
     digitalWrite(columnPins[i], LOW);   
                                 ^
scroll.c: In function ‘loop’:
scroll.c:20:30: error: ‘LOW’ undeclared (first use in this function)
     digitalWrite(rowPins[y], LOW);
                              ^
scroll.c:22:36: error: ‘HIGH’ undeclared (first use in this function)
       digitalWrite (columnPins[x], HIGH);
                                    ^

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The code you are trying to build comes from Arduino. One of the "hidden" header files that Arduino includes is:

 

/Program Files/Arduino/hardware/arduino/avr/cores/Arduino.h

 

That file includes:

#define HIGH 0x1
#define LOW  0x0

#define INPUT 0x0
#define OUTPUT 0x1
#define INPUT_PULLUP 0x2

That should resolve the symbols you are missing. When the code will build try adding -save-temps and look at the .s file that gets created.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I started AVR Studio 6.2 on my Windows machine. Clicked on File>>New>>Project, selected New Projec>>Assembler then selected the mega328P for the chip.

I went to this page: http://www.instructables.com/id/Command-Line-Assembly-Language-Programming-for-Ard-2/[1]and copied the code from step 3 into the editor into Studio. I commented out the two rcall delay lines in the blink loop.

I went to Menu: Build>>Build Solution. I got a "Build succeeded." message. Looking good!

I went to Menu: Debug>>Windows and selected I/O View. A window popped up. I clicked on the I/OPORTD selection to expand it. At the bottom of the window the contents of registers PIND, DDRD and PORTD are displayed.

I went to Menu: Debug and selected "Start debugging and break" The simulator jumped into the code window and the I pressed F11 (the step into key) and watched how the highlighted line increments. Take a look what happens to PORTD and PIND when you get into the blink loop.

Modify the code to do what you want from there. I think that should get you going.

EDIT: Just to make sure everything works I modified the code to blink all of PORTB so you can see how it's done.

Good Luck.

 

 

/*
 * AssemblerApplication2.asm
 *
 *  Created: 7/31/2015 6:25:07 AM
 */ 

.nolist
.include "./m328Pdef.inc"
.list

;==============
; Declarations:

.def temp = r16
.def overflows = r17


.org 0x0000              ; memory (PC) location of reset handler
rjmp Reset               ; jmp costs 2 cpu cycles and rjmp costs only 1
                         ; so unless you need to jump more than 8k bytes
                         ; you only need rjmp. Some microcontrollers therefore only 
                         ; have rjmp and not jmp
.org 0x0020              ; memory location of Timer0 overflow handler
rjmp overflow_handler    ; go here if a timer0 overflow interrupt occurs 

;============

Reset: 
   ldi temp,  0b00000101
   out TCCR0B, temp      ; set the Clock Selector Bits CS00, CS01, CS02 to 101
                         ; this puts Timer Counter0, TCNT0 in to FCPU/1024 mode
                         ; so it ticks at the CPU freq/1024
   ldi temp, 0b00000001
   sts TIMSK0, temp      ; set the Timer Overflow Interrupt Enable (TOIE0) bit 
                         ; of the Timer Interrupt Mask Register (TIMSK0)

   sei                   ; enable global interrupts -- equivalent to "sbi SREG, I"

   clr temp
   out TCNT0, temp       ; initialize the Timer/Counter to 0

   sbi DDRD, 4           ; set PD4 to output

   ldi temp,  0b11111111 ; going to set PORTB to outputs
   out DDRB, temp        ; it"s outputs
;======================
; Main body of program:

blink:
   ldi temp, 0b11111111
   out PORTB, temp
   sbi PORTD, 4          ; turn on LED on PD4
   ;rcall delay           ; delay will be 1/2 second
   ldi temp, 0b00000000
   out PORTB, temp
   cbi PORTD, 4          ; turn off LED on PD4
   ;rcall delay           ; delay will be 1/2 second
   rjmp blink            ; loop back to the start

delay:
   clr overflows         ; set overflows to 0 
   sec_count:
     cpi overflows,30    ; compare number of overflows and 30
   brne sec_count        ; branch to back to sec_count if not equal 
   ret                   ; if 30 overflows have occured return to blink

overflow_handler: 
   inc overflows         ; add 1 to the overflows variable
   cpi overflows, 61     ; compare with 61
   brne PC+2             ; Program Counter + 2 (skip next line) if not equal
   clr overflows         ; if 61 overflows occured reset the counter to zero
   reti                  ; return from interrupt

 

Last Edited: Fri. Jul 31, 2015 - 06:00 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Finally getting somewhere with C code! 

 

#include <avr/io.h>
#include <util/delay.h>
 
#define BLINK_DELAY_MS 1000
 
int main (void)
{
 
 DDRB |= _BV(DDB5);		/* set pin 5 of PORTB for output*/
 DDRB |= _BV(DDB3);   		/* set pin 5 of PORTB for output arduino pin 11*/  
 DDRD |= _BV(DDD6);		/* set pin 6 of PORTD for output  arduino pin 6*/
 DDRB |= _BV(DDB2);		/* set pin 2 of PORTB for output  arduino pin 10*/ 	


while(1) {
  /* set pin 5 high to turn led on */
  PORTB |= _BV(PORTB5);
  _delay_ms(BLINK_DELAY_MS);

  PORTB |= _BV(PORTB3);
  _delay_ms(BLINK_DELAY_MS);

  PORTD |= _BV(PORTD6);
  _delay_ms(BLINK_DELAY_MS);
 
  PORTB |= _BV(PORTB2);
  _delay_ms(BLINK_DELAY_MS);


  /* set pin 5 low to turn led off */
  PORTB &= ~_BV(PORTB5);
  _delay_ms(BLINK_DELAY_MS);

  PORTB &= ~_BV(PORTB3);
  _delay_ms(BLINK_DELAY_MS);

  PORTD &= ~_BV(PORTD6);
  _delay_ms(BLINK_DELAY_MS);

  PORTB &= ~_BV(PORTB2);
  _delay_ms(BLINK_DELAY_MS);


THis is lighting up 3 pins for me!

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Apparently this is only a single LED at a time. Any idea how to light up a column?