Search code examples
c++avrattiny

Attiny85 PINB is randomly blinking


I`m trying to figure out how to work with attiny85 and I stuck with an issue.

I use rgb led strip to indicate bits (1 pixel - 1 bit, I found it very convenient). All the code is:

#define F_CPU 8388608UL // 8MH

#include <avr/io.h>
#include <util/delay.h>


#define LED PB4


void setBitHigh(short int pin) {
    PORTB |= _BV(pin); // 1 tactDuration = 125*10-9sec
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");

    PORTB &= ~_BV(pin); // 1 tactDuration
    asm("nop");
    asm("nop");
}

void setBitLow(short int pin) {
    PORTB |= _BV(pin); // 1 tactDuration
    asm("nop");
    asm("nop");

    PORTB &= ~_BV(pin); // 1 tactDuration
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
    asm("nop");
}

void trueByte(short int pin, short int intensity) {
    for (int i = 7; i >= 0; i--) {
        intensity & _BV(i) ? setBitHigh(pin) : setBitLow(pin);
    }
}
void falseByte(short int pin) {
    for (int i = 0; i < 8; i++) {
        setBitLow(pin);
    }
}

void setPixel(short int pin, short int r, short int g, short int b) {
    g > 0 ? trueByte(pin, g) : falseByte(pin);
    r > 0 ? trueByte(pin, r) : falseByte(pin);
    b > 0 ? trueByte(pin, b) : falseByte(pin);
}


void indicate(int data) { 
    int tmp = data;
    for (int i = 0; i < 8; i++) {
        int intensity = (tmp & _BV(i)) > 0 ? 10 : 0;

        setPixel(LED, intensity, 0, 0);
    }
}

void blink(short int times) {
    for (short int i = 0; i < times; i++) {
        indicate(255);
        _delay_ms(200);
        indicate(0);
        _delay_ms(200);
    }
}

int main() {
    DDRB = 0x00 | _BV(LED);
    PORTB = 0x00;

    _delay_ms(1000);
    blink(3);
    _delay_ms(1000);


    while(true) {
        indicate(PINB);
        _delay_ms(50);
    }

    return 0;
}

I expected the PINB indicator to be 0(no light at the strip), but it is blinking with some pattern I can not recognise familiar, but I see it cyclic. Only first 4 bits periodically became 1.

As you can see, I use PB4 only for LED... PB0-3 are free (not connected at all)

I will be glad to any ideas or tips, ty.


Solution

  • This problem does not concern sw but hw. This is the normal behavior of an unconnected input pin. An unconnected input pin behaves unpredictably. The inputs must be driven by some signal or pulled with resistors to VCC or GND. Pull Up can be done with internal resistors. In your program, simply set PORTB to 0x0F

    int main() {
        DDRB = 0x00 | _BV(LED);
        PORTB = 0x0F;
    

    See DS how MCU ports work

    If you want PB0-3 to be 0, you have to pull down with external resistors (10kΩ or similar) to GND.